如何通过boto3创建EC2 Instance Profile实现EBS操作与S3访问无凭证
错误根因
你当前配置的IAM权限策略只覆盖了EC2实例类资源的授权,ec2:AttachVolume/ec2:DetachVolume属于跨资源操作,需要同时对EC2实例和目标EBS卷两类资源授予操作权限,缺少EBS卷的资源授权直接导致权限校验失败。
完整配置方案
基础无限制版本(允许操作所有EBS卷+所有S3资源)
直接替换你代码中的policy_document部分即可:
policy_document = dict( Version = '2012-10-17', Statement = [ # EBS挂载卸载权限 dict( Effect = 'Allow', Action = [ 'ec2:AttachVolume', 'ec2:DetachVolume', 'ec2:DescribeVolumes' # 建议加上,方便实例查询可用卷 ], Resource = [ 'arn:aws:ec2:*:*:instance/*', 'arn:aws:ec2:*:*:volume/*' ], ), # S3全操作权限 dict( Effect = 'Allow', Action = 's3:*', Resource = '*' ) ] )
注意:DescribeVolumes类的只读操作属于AWS全局操作,不需要指定Resource,直接加在Action列表即可
带前缀限制的优化版本
Condition字段为非必填项,仅用于精细化权限控制,如果你需要限制只能操作名称带特定前缀的资源,可以参考以下配置(示例前缀为myteam-):
policy_document = dict( Version = '2012-10-17', Statement = [ # 限制仅能挂载名称前缀为myteam-的EBS卷 dict( Effect = 'Allow', Action = [ 'ec2:AttachVolume', 'ec2:DetachVolume' ], Resource = [ 'arn:aws:ec2:*:*:instance/*', 'arn:aws:ec2:*:*:volume/*' ], Condition = { "StringLike": { "aws:ResourceTag/Name": "myteam-*" } } ), dict( Effect = 'Allow', Action = 'ec2:DescribeVolumes', Resource = '*' ), # 限制仅能操作名称前缀为myteam-的S3桶 dict( Effect = 'Allow', Action = 's3:*', Resource = [ 'arn:aws:s3:::myteam-*', 'arn:aws:s3:::myteam-*/*' ] ) ] )
附加验证步骤
实例启动后可以先执行aws sts get-caller-identity验证角色是否正常生效,如果返回的ARN包含你创建的角色名称,说明凭证下发正常。如果仍然报错,检查以下两点:
- 实例配置文件创建后需要等待10-30秒的全局传播时间,刚创建就启动实例可能出现权限未生效的问题
- 私有网络内的实例需要配置EC2和S3的VPC端点,否则无法访问AWS服务接口
内容的提问来源于stack exchange,提问作者Vadim Kantorov
相关产品推荐
相关产品推荐

