如何从CodePipeline访问SSM参数并在CloudFormation步骤中覆盖samTemplate参数
我来帮你梳理这两个问题的解决方案,都是AWS CI/CD里很常见的场景:
CodePipeline本身没法直接读取SSM参数,通常有两种实用的实现方式,取决于你后续要怎么使用这些参数:
通过CodeBuild中间步骤获取参数
这是最灵活的方式,适合需要在构建/打包阶段使用参数的场景:- 给CodeBuild的服务角色添加SSM读取权限,示例策略如下:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ssm:GetParameter", "ssm:GetParameters"], "Resource": "arn:aws:ssm:你的AWS区域:你的账号ID:parameter/你的参数路径/*" } ] } - 在CodeBuild的
buildspec.yml里用AWS CLI拉取参数,比如:# 获取单个加密参数(自动解密)并保存到文件 aws ssm get-parameter --name "/my/app/db-password" --with-decryption --query "Parameter.Value" --output text > db-pass.txt # 获取多个参数并保存为JSON aws ssm get-parameters --names "/my/app/api-url" "/my/app/env" --query "Parameters[*].{Name:Name,Value:Value}" --output json > params.json
拉取到的参数可以直接在后续构建步骤中使用,比如传递给打包脚本、生成配置文件等。
- 给CodeBuild的服务角色添加SSM读取权限,示例策略如下:
在CloudFormation部署动作中直接引用
如果你的Pipeline下一步是部署CloudFormation/SAM模板,不需要提前把参数拉出来,可以直接在部署动作的参数配置里引用SSM参数。比如参数值填{{resolve:ssm:/my/app/api-url:1}},其中:1是参数版本(可选,用latest可以取最新版本),CloudFormation会自动帮你拉取对应参数值。
SAM模板本质是CloudFormation的扩展,所以可以直接结合CloudFormation的参数覆盖机制和SSM引用实现需求,步骤如下:
先在SAM模板中定义好参数
比如你的samTemplate.yaml里有这些参数定义:Parameters: DatabasePassword: Type: String Description: 数据库访问密码 NoEcho: true # 隐藏控制台输出,适合敏感信息 ApiEndpoint: Type: String Description: 后端API服务端点在CodePipeline的CloudFormation动作中配置参数覆盖
打开你的CodePipeline,找到CloudFormation部署的那个动作,进入编辑页面:- 在参数配置区域,给每个需要覆盖的SAM参数设置值为SSM参数的引用格式:
- 对于
DatabasePassword,值填{{resolve:ssm:/my/app/db-password:1}}(如果是SecureString类型,CloudFormation会自动解密,前提是执行角色有对应权限) - 对于
ApiEndpoint,值填{{resolve:ssm:/my/app/api-url:latest}}
- 对于
- 在参数配置区域,给每个需要覆盖的SAM参数设置值为SSM参数的引用格式:
确保权限配置正确
给CodePipeline执行CloudFormation动作的服务角色(或者CloudFormation的执行角色)添加必要权限:{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["ssm:GetParameter", "ssm:GetParameters"], "Resource": [ "arn:aws:ssm:你的区域:你的账号ID:parameter/my/app/db-password", "arn:aws:ssm:你的区域:你的账号ID:parameter/my/app/api-url" ] }, // 如果参数用自定义KMS密钥加密,需要添加Decrypt权限 { "Effect": "Allow", "Action": "kms:Decrypt", "Resource": "arn:aws:kms:你的区域:你的账号ID:key/你的KMS密钥ID" } ] }可选:用CodeBuild做预处理(更灵活的场景)
如果需要批量替换、做逻辑判断或者修改模板内容,可以在Pipeline里加一个CodeBuild步骤,读取SSM参数后直接修改SAM模板的参数默认值,再传递给后续的CloudFormation动作。示例脚本:# 读取SSM参数 API_ENDPOINT=$(aws ssm get-parameter --name "/my/app/api-url" --query "Parameter.Value" --output text) # 替换SAM模板中的参数默认值 sed -i "s/Default:.*ApiEndpoint/Default: '$API_ENDPOINT'/" samTemplate.yaml
内容的提问来源于stack exchange,提问作者user1584120

