如何配置Account B EC2的CodeDeploy代理跨角色访问Account A的S3存储桶
引言
Account-A- 该账号下存在一个S3存储桶(
sample-s3-bucket-in-account-a) - 该S3存储桶配置了使用
AWS KMS的服务端加密(SSE-KMS) - 使用的KMS密钥为
aws/s3(AWS托管密钥) - 该存储桶未配置任何存储桶策略
- 该账号下创建了一个IAM跨账号角色(
sample-cross-account-role-4-s3-access-in-account-a)- 信任实体为
Account-B(信任策略配置) - 权限策略允许对S3存储桶(
sample-s3-bucket-in-account-a)执行以下操作:s3:ListBuckets3:GetBucketLocations3:GetObject
- 信任实体为
- 该账号下存在一个S3存储桶(
Account-B- 该账号下存在一台EC2实例
- 该账号下存在IAM实例配置文件和对应角色(
sample-iam-role-4-ec2-in-account-b) - 该IAM实例配置文件拥有承担Account-A创建的跨账号角色
sample-cross-account-role-4-s3-access-in-account-a的权限 - 该IAM实例配置文件已绑定到上述EC2实例
已知事实
- 可以在Account-B的EC2实例上通过命令
aws sts assume-role --role-arn arn:aws:iam::[ACCOUNT-A]:role/sample-cross-account-role-4-s3-access-in-account-a --role-session-name s3-cross-account-access-session生成临时STS凭证,使用该凭证可以列出Account-A的S3存储桶中的对象 - 可以在
~/.aws/config文件中创建profile,在AWS CLI中使用该配置文件名即可访问Account-A的S3存储桶中的对象
遇到的问题
- 上述EC2实例上运行着
CodeDeploy代理 - 该
CodeDeploy代理使用AWS SDK for Ruby - 该
CodeDeploy代理以root权限运行 CodeDeploy代理内部默认通过sample-iam-role-4-ec2-in-account-b实例配置文件/角色获取STS凭证(调用地址:http://169.254.169.254/latest/meta-data/iam/security-credentials/sample-iam-role-4-ec2-in-account-b)- 该默认获取的临时STS凭证无法让
CodeDeploy代理下载Account-A的S3存储桶中的对象,日志报Access Denied错误 - 通过配置S3存储桶策略可以正常访问,但需求要求必须使用跨账号IAM角色实现访问
问题
如何配置运行在Account-B的EC2实例上的CodeDeploy代理,使其承担sample-cross-account-role-4-s3-access-in-account-a而非默认的sample-iam-role-4-ec2-in-account-b角色,实现跨账号访问S3存储桶?
解决方案
你可以根据运维场景选择以下两种方案实现需求:
方案一:修改root用户全局AWS配置
由于CodeDeploy代理以root权限运行,AWS SDK for Ruby会优先读取root用户的AWS配置:
- 切换到root用户,创建/编辑
/root/.aws/config文件,添加如下配置:
[default] role_arn = arn:aws:iam::[ACCOUNT-A的12位账号ID]:role/sample-cross-account-role-4-s3-access-in-account-a credential_source = Ec2InstanceMetadata
- 重启CodeDeploy代理使配置生效:
- Amazon Linux 2/CentOS 7+/Ubuntu等使用systemd的系统:
systemctl restart codedeploy-agent - 老旧的Amazon Linux 1系统:
service codedeploy-agent restart
该配置无需修改CodeDeploy本身的代码,SDK会自动使用实例元数据的凭证切换到指定的跨账号角色。
方案二:通过服务环境变量注入配置
如果不想修改全局AWS配置,可以直接修改CodeDeploy代理的启动环境变量:
- 编辑CodeDeploy的服务配置文件:
- 若为systemd管理的服务,编辑
/etc/systemd/system/codedeploy-agent.service,在[Service]段添加以下两行:
Environment=AWS_ROLE_ARN=arn:aws:iam::[ACCOUNT-A的12位账号ID]:role/sample-cross-account-role-4-s3-access-in-account-a Environment=AWS_CREDENTIAL_SOURCE=Ec2InstanceMetadata
- 重载配置并重启代理:
systemctl daemon-reload systemctl restart codedeploy-agent
补充验证与排查
配置完成后先切换到root用户执行aws s3 ls s3://sample-s3-bucket-in-account-a确认可以正常访问,再触发CodeDeploy部署验证。如果仍然报错,需要检查跨账号角色的权限策略是否添加了kms:Decrypt权限,因为S3存储桶使用了SSE-KMS加密,读取对象时需要对应KMS密钥的解密权限。
内容的提问来源于stack exchange,提问作者Sreenivas Reddy
相关产品推荐
相关产品推荐

