CloudFormation 模板中未解析的参数存储 SecureString 动态引用

Unresolved Parameter Store SecureString dynamic reference in CloudFormation template

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

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

假设存储在 SSM Parameter Store 中的现有 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 就会抱怨:

The parameter MasterUserPassword is not a valid password because it is longer than 64 characters. (Service: AmazonRedshift; Status Code: 400; Error Code: InvalidParameterValue; Request ID: 7be9bd43-2927-11e9-aa88-29bbdcae859e)

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

The parameter MasterUserPassword is not a valid password. Only printable ASCII characters except for '/', '@', '"', ' ', '\', ''' may be used. (Service: AmazonRedshift; Status Code: 400; Error Code: InvalidParameterValue)

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

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

The parameter MasterUserPassword must contain at least 1 upper case letter. (Service: AmazonRedshift; Status Code: 400; Error Code: InvalidParameterValue; Request ID: 90a263bd-2929-11e9-80c0-ffcecf297c44)


最后,尽管在模板中使用基本的短非斜线 Parameter name 允许堆栈完成 Update 操作 dynamic reference仍然不会发生 因为实际使用的值被提供给参数名称而不是由此引用的值,例如 MyRedshiftMasterUserPassword 而不是 Abcd2019.

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

已打开 AWS 支持案例,请求针对 CloudFormation 的这种特殊奇怪行为提供指导。

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

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

  1. Get the 'MasterUserPassword' for Redshift from input parameter with property NoEcho set to true. NoEcho property allows you to mask the password value and you don't need to store the password in a template file. However, each time you update the stack you need to enter the password as input parameter. For your reference, below code snippet will be useful.

第二个选项,更通用:

  1. Define a Lambda backed Custom Resource in your template file, which queries the SSM service and returns the password to CloudFormation. In this scenario, You need to write a Custom Code for lambda function which uses AWS GetParameter API call to retrieve the value of SSM Secure String Parameter and returns the decrypted value to CloudFormation.

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