如何以特定用户身份运行AWS CLI命令?含用户创建与执行方法问询
听起来你现在的问题是要替换掉EC2实例角色的方式,改用一个专门的IAM用户来承担xrole执行部署命令,这样就不用给每个测试环境的EC2都分配xrole了对吧?我来一步步帮你解决这两个疑问:
要实现这个目标,需要完成两个关键配置:给IAM用户添加承担xrole的权限,同时修改xrole的信任策略允许该用户调用它。
第一步:创建IAM用户
在AWS控制台或者用AWS CLI创建一个专门的用户(比如命名为cf-deploy-svc-user),不需要直接给这个用户附加S3、CloudFormation等权限,只需要给它授权调用sts:AssumeRole的能力。第二步:给用户附加自定义IAM策略
创建一个策略文档,允许用户针对xrole执行sts:AssumeRole操作,示例策略如下(记得替换YOUR_ACCOUNT_ID为你的AWS账号ID):{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::YOUR_ACCOUNT_ID:role/xrole" } ] }将这个策略附加到你刚创建的IAM用户上。
第三步:修改xrole的信任策略
进入xrole的IAM配置页面,更新它的信任关系,添加允许该IAM用户承担角色的规则。如果需要保留原来EC2实例承担角色的权限,可以同时保留原来的Principal规则,示例信任策略:{ "Version": "2012-10-17", "Statement": [ // 保留原有的EC2实例角色信任规则(如果仍需支持EC2直接使用xrole) { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" }, // 添加新的IAM用户信任规则 { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::YOUR_ACCOUNT_ID:user/cf-deploy-svc-user" }, "Action": "sts:AssumeRole" } ] }
核心思路是:先用这个IAM用户的永久凭证调用aws sts assume-role获取临时凭证,然后用这些临时凭证来执行后续的AWS命令。下面分两种场景说明:
2.1 Jenkins Docker容器中的命令(aws cloudformation package 和 s3Upload())
在Jenkins中,推荐用Credentials插件管理用户的永久凭证,避免硬编码:
- 首先在Jenkins中添加该用户的AWS凭证(类型选择"AWS Credentials",填入用户的Access Key ID和Secret Access Key),给这个凭证设置一个唯一ID,比如
cf-deploy-user-creds。 - 在Jenkins Pipeline中,先获取临时凭证,再执行命令:
pipeline { agent { docker { image 'amazon/aws-cli:latest' } } stages { stage('Get Temporary Credentials') { steps { withAWS(credentials: 'cf-deploy-user-creds') { script { // 调用STS获取xrole的临时凭证 def stsOutput = sh( script: 'aws sts assume-role --role-arn arn:aws:iam::YOUR_ACCOUNT_ID:role/xrole --role-session-name jenkins-deploy-session', returnStdout: true ).trim() def stsJson = readJSON text: stsOutput // 将临时凭证设置为环境变量,后续命令自动读取 env.AWS_ACCESS_KEY_ID = stsJson.Credentials.AccessKeyId env.AWS_SECRET_ACCESS_KEY = stsJson.Credentials.SecretAccessKey env.AWS_SESSION_TOKEN = stsJson.Credentials.SessionToken } } } } stage('Package & Upload') { steps { // 执行cloudformation package,自动使用临时凭证 sh 'aws cloudformation package --template-file template.yml --s3-bucket YOUR_DEPLOY_BUCKET --output-template-file packaged.yml' // s3Upload插件会自动读取环境变量中的临时凭证 s3Upload( file: 'packaged.yml', bucket: 'YOUR_DEPLOY_BUCKET', path: 'cloudformation-templates/' ) } } } }
2.2 普通Docker容器中的命令(aws s3 cp 和 aws cloudformation deploy)
这里提供两种常用方式:
方式一:在宿主机获取临时凭证后传入容器(推荐)
先在宿主机上用用户的永久凭证获取临时凭证,再启动容器时传入这些凭证作为环境变量:
# 先设置用户的永久凭证(建议用aws configure配置,避免明文暴露) export AWS_ACCESS_KEY_ID=YOUR_USER_ACCESS_KEY export AWS_SECRET_ACCESS_KEY=YOUR_USER_SECRET_KEY # 获取xrole的临时凭证 STS_RESPONSE=$(aws sts assume-role --role-arn arn:aws:iam::YOUR_ACCOUNT_ID:role/xrole --role-session-name docker-deploy-session) TEMP_ACCESS_KEY=$(echo $STS_RESPONSE | jq -r '.Credentials.AccessKeyId') TEMP_SECRET_KEY=$(echo $STS_RESPONSE | jq -r '.Credentials.SecretAccessKey') TEMP_SESSION_TOKEN=$(echo $STS_RESPONSE | jq -r '.Credentials.SessionToken') # 启动容器执行s3 cp命令,传入临时凭证 docker run -e AWS_ACCESS_KEY_ID=$TEMP_ACCESS_KEY -e AWS_SECRET_ACCESS_KEY=$TEMP_SECRET_KEY -e AWS_SESSION_TOKEN=$TEMP_SESSION_TOKEN amazon/aws-cli:latest aws s3 cp ./local-source s3://YOUR_BUCKET/dest-path # 启动容器执行cloudformation deploy命令 docker run -e AWS_ACCESS_KEY_ID=$TEMP_ACCESS_KEY -e AWS_SECRET_ACCESS_KEY=$TEMP_SECRET_KEY -e AWS_SESSION_TOKEN=$TEMP_SESSION_TOKEN -v $(pwd):/workdir amazon/aws-cli:latest aws cloudformation deploy --template-file /workdir/packaged.yml --stack-name YOUR_TEST_STACK --region YOUR_REGION
方式二:在容器内部获取临时凭证
如果需要在容器内完成所有操作,可以将用户的凭证文件挂载到容器中,然后在容器内执行assume-role:
# 假设宿主机上的~/.aws/credentials文件已经配置了该用户的profile: # [cf-deploy-user] # aws_access_key_id = YOUR_USER_ACCESS_KEY # aws_secret_access_key = YOUR_USER_SECRET_KEY docker run -v ~/.aws/credentials:/root/.aws/credentials amazon/aws-cli:latest /bin/bash -c " # 用指定profile获取临时凭证 aws sts assume-role --profile cf-deploy-user --role-arn arn:aws:iam::YOUR_ACCOUNT_ID:role/xrole --role-session-name docker-deploy-session > sts.json # 设置临时凭证为环境变量 export AWS_ACCESS_KEY_ID=\$(jq -r '.Credentials.AccessKeyId' sts.json) export AWS_SECRET_ACCESS_KEY=\$(jq -r '.Credentials.SecretAccessKey' sts.json) export AWS_SESSION_TOKEN=\$(jq -r '.Credentials.SessionToken' sts.json) # 执行目标命令 aws s3 cp source s3://YOUR_BUCKET/dest aws cloudformation deploy --template-file packaged.yml --stack-name YOUR_TEST_STACK "
额外注意事项
- 临时凭证默认有效期为1小时,你可以通过
--duration-seconds参数调整(最长不能超过xrole配置的最大有效期,默认是12小时)。 - 确保xrole本身的权限已经覆盖了这4条命令所需的操作(S3读写、CloudFormation栈操作等),这部分你之前已经配置过,不需要修改。
- 绝对不要将IAM用户的Access Key和Secret Key硬编码在脚本或代码中,尽量用凭证管理工具(比如Jenkins Credentials)或者环境变量(非明文存储)来处理。
内容的提问来源于stack exchange,提问作者overexchange

