如何在CloudFormation用户数据中使用AWS Parameter Store SecureString
在CloudFormation UserData中调用Parameter Store SecureString的正确方式
先给你逐个拆解你试的四种方法:
- 方法1(用Map):可行,但你应该是嵌套语法或UserData的Base64编码没处理对。Map本身是合法的写法,但要注意CFN函数的层级关系,不能乱嵌套。
- 方法2(给解析表达式加引号):完全不可行。CFN的内置函数(比如
!GetParameter)一旦被引号包裹,就会被当成纯字符串,不会触发解析,自然会把表达式原封不动写入文件。 - 方法3(设为CFN参数默认值):不可行。CFN参数的默认值必须是静态常量,不支持动态引用(包括从Parameter Store取值的函数),这个思路走不通。
- 方法4(直接在!Sub中写解析表达式):可行,但你没搞对嵌套逻辑。!Sub里不能直接写函数调用,得把函数的结果作为变量传入,或者在Sub内部正确嵌套函数调用。
正确实现示例
关键注意点:
- 获取SecureString时,必须指定
WithDecryption: true,否则拿到的是加密后的乱码。 - UserData必须用
!Base64编码,内部用!Sub来拼接包含密钥的脚本。
写法1:直接在UserData中嵌套函数调用
Resources: MyEC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-xxxxxx # 替换成你的AMI ID InstanceType: t2.micro IamInstanceProfile: !Ref MyInstanceProfile # 必须有ssm:GetParameter权限的角色 UserData: !Base64 !Sub | #!/bin/bash # 直接在Sub中嵌套GetParameter获取解密后的密码 DB_PASSWORD="${!GetParameter: Name: /myapp/db/password WithDecryption: true }" # 将密码写入应用配置文件 echo "db_password = $DB_PASSWORD" >> /etc/myapp/config.ini # 重启应用服务 systemctl restart myapp.service
写法2:用动态引用(更简洁)
如果你的CFN模板版本支持动态引用(大部分现代区域都支持),可以用这种更简单的写法:
Resources: MyEC2Instance: Type: AWS::EC2::Instance Properties: ImageId: ami-xxxxxx InstanceType: t2.micro IamInstanceProfile: !Ref MyInstanceProfile UserData: !Base64 !Sub | #!/bin/bash # 动态引用会自动解密SecureString DB_PASSWORD="{{resolve:ssm-secure:/myapp/db/password:1}}" echo "db_password = $DB_PASSWORD" >> /etc/myapp/config.ini systemctl restart myapp.service
注:动态引用里的
:1是参数的版本号,根据你的实际情况调整,也可以省略(默认取最新版本)。
踩坑提醒
- 必须给EC2实例绑定的IAM角色添加
ssm:GetParameter权限,否则会因权限不足获取失败。 - 如果Parameter Store的参数设置了资源策略,要确保允许该IAM角色访问。
- 不要在CFN参数的默认值里写
!GetParameter或动态引用,参数默认值只能是静态值。
内容的提问来源于stack exchange,提问作者Fat Monk
相关产品推荐
相关产品推荐

