【问题标题】:Unresolved Parameter Store SecureString dynamic reference in CloudFormation templateCloudFormation 模板中未解析的 Parameter Store SecureString 动态引用
【发布时间】:2023-03-20 17:15:01
【问题描述】:

根据 AWS,当使用 CloudFormation 部署需要机密(即密码或类似内容)的基础设施时,一种流行的解决方案是使用来自 SSM 的 Parameter Store 的 SecureStrings。

但是,尽管存在CFN documentation describing step-by-step how to use the Dynamic References within the CFN templates,但我无法设法利用 SecureStrings 的实际值。

假设存储在 SSM 参数存储中的现有 SecureString 的以下 JSON 表示:

{
  "MyRedshiftMasterUserPassword": {
    "value": "Abcd2019",
    "type": "SecureString"
  }
}

以及文档中所述使用它的 YAML CFN 模板:

Resources
  Redshift:
    Type: 'AWS::Redshift::Cluster'
    Properties:
      NodeType: dc2.large
      NumberOfNodes: !Ref RedshiftNodes
      ClusterType: multi-node
      AutomatedSnapshotRetentionPeriod: !Ref AutomatedSnapshotRetentionPeriod
      DBName: datawarehouse_v1
      MasterUsername: !Ref RedshiftMasterUsername
      MasterUserPassword: '{{resolve:ssm-secure:MyRedshiftMasterUserPassword:1}}'

上述解决方案不起作用,所以要么我错误地定义了模板,要么没有正确实现对这个功能的支持,考虑到它来自 AWS,这对我来说似乎很奇怪。

特别是,我遇到了以下错误,这些错误都以UPDATE_FAILED 堆栈结尾:

  1. 只要要解析的引用参数名称足够长,CloudFormation 就会抱怨:

参数 MasterUserPassword 不是有效密码,因为它超过 64 个字符。 (服务:AmazonRedshift;状态码:400;错误码:InvalidParameterValue;请求 ID:7be9bd43-2927-11e9-aa88-29bbdcae859e)

  1. 此外,尽管特别提到斜杠可以在模板引用中使用,例如/infrastructure/datawarehouse/redshift/MyRedshiftMasterUserPassword 发出以下错误:

参数 MasterUserPassword 不是有效密码。只能使用除 '/'、'@'、'"'、''、'\'、''' 之外的可打印 ASCII 字符。(服务:AmazonRedshift;状态代码:400;错误代码:InvalidParameterValue)

因此,作为结果引用的 SecureString 似乎与 SSM ParameterStore 层次结构(带有斜杠的参数)不兼容。

  1. 此外,从参数名称中删除任何先前报告的无效字符,然后它会抱怨以下内容:

参数 MasterUserPassword 必须至少包含 1 个大写字母。 (服务:AmazonRedshift;状态代码:400;错误代码:InvalidParameterValue;请求 ID:90a263bd-2929-11e9-80c0-ffcecf297c44)


最后,虽然在模板中使用基本的短非斜线Parameter name 允许堆栈完成更新操作动态引用仍然不会发生为实际使用的值是提供的 Parameter Name 而不是 this 引用的值,例如 MyRedshiftMasterUserPassword 而不是 Abcd2019

我知道 AWS Secrets Manager 也可以使用,但它不是免费的。

【问题讨论】:

  • 您如何验证实际值是参数名称而不是值?此外,您指定的错误不是参数名称,而是值和“Abcd2019”似乎正确。我已经成功地使用了securestring,就像你介绍的那样,所以它看起来确实是正确的。您是否尝试使用诸如 boto3 之类的 SDK 来检索它?
  • 我通过尝试连接到 Redshift 集群验证了最终使用的值,因为它只使用名称进行身份验证,而不是作为密码的值。实际上,SecureString 'Abcd2019' 是一个有效的密码,但由于它最终使用的是名称而不是值,因此它无法满足约束,因此会出错。
  • 您能否验证这两个 aws 命令的值:aws ssm get-parameter --name MyRedshiftMasterUserPassword 和 aws ssm get-parameter --name MyRedshiftMasterUserPassword --with-decryption?因为否则它对我来说看起来不错。
  • 刚刚检查了执行awscli命令的返回值,结果成功解析。

标签: amazon-web-services amazon-cloudformation aws-parameter-store


【解决方案1】:

已向 AWS 提出支持案例,请求就 CloudFormation 的这种特殊奇怪行为提供指导。

根据支持团队的说法,实际上这确实是 CloudFormation 服务的一个已知错误,但没有估计修复时间。 SSM Parameter Store SecureString 参数在 RedshiftMasterUserPassword 属性的特定情况下用作动态引用时的解析,尽管文档中已引用,但未正确解析,而是使用了参数名称。

或者,他们在问题得到解决的同时提供了 2 种解决方法:

  1. 从属性NoEcho 设置为true 的输入参数获取Redshift 的“MasterUserPassword”。 NoEcho 属性允许您屏蔽密码值,并且您不需要将密码存储在模板文件中。但是,每次更新堆栈时,都需要输入密码作为输入参数。供您参考,下面的代码 sn-p 会很有用。

第二种选择,更通用:

  1. 在您的模板文件中定义一个Lambda backed Custom Resource,它会查询 SSM 服务并将密码返回给 CloudFormation。在这种情况下,您需要为 lambda 函数编写一个自定义代码,该函数使用 AWS GetParameter API call 来检索 SSM 安全字符串参数的值并将解密后的值返回给 CloudFormation。

其他支持的动态引用属性似乎工作正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 2021-06-07
    • 1970-01-01
    • 2012-01-19
    • 2020-07-30
    相关资源
    最近更新 更多