CloudFormation模板中的未解决的参数存储SecureString动态参考

时间:2019-02-05 12:46:29

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

根据AWS,在使用CloudFormation部署需要机密(即密码或类似密码)的基础架构时,一种流行的解决方案是使用来自SSM的参数存储的SecureString。

但是,尽管已有CFN documentation describing step-by-step how to use the Dynamic References within the CFN templates,我还是无法利用SecureString的实际值。

假定存储在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允许堆栈完成 Update 操作动态引用仍然不会发生实际使用的是实际提供的参数值,而不是此参数所引用的值,例如MyRedshiftMasterUserPassword而不是Abcd2019

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

第二个选项,用途更广:

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

其他受支持的动态参考属性似乎可以正常工作。