使用Terraform配置S3 Outposts访问点策略时遇Access Denied错误
解决S3 Outposts访问点Terraform策略配置Access Denied问题
问题描述
使用Terraform单独创建S3 Outposts访问点后关联权限策略时,出现Access Denied错误,但通过AWS控制台可正常更新策略,且将策略嵌入访问点创建代码时能正常执行。
报错的代码示例
resource "aws_s3_access_point" "op_access_point" { bucket = aws_s3control_bucket.bucket_name.arn name = var.access_point_name vpc_configuration { vpc_id = var.vpc_id } } resource "aws_s3control_access_point_policy" "accesspoint_policy" { access_point_arn = aws_s3_access_point.access_point.arn policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Action = [ "s3-outposts:*" ] Principal = { AWS = "*" } Resource = [ "${aws_s3_access_point.access_point.arm}" ] }] }) }
错误信息
Error: creating S3 Access Point (arn:aws:s3-outposts:us-west-2:404372770:outpost/op-6a30c66a/accesspoint/new_accesspoint) Policy: AccessDenied: Access Denied │ status code: 403, request id: 7f-3672-4563-83ff-8b5ergf7, host id: sdoZ+j1yWfNSF+MvDnN08+aAMl
可行的嵌入策略代码示例
resource "aws_s3_access_point" "op_access_point" { bucket = aws_s3control_bucket.bucket_name.arn name = var.access_point_name policy = jsonencode({ Version = "2008-10-17" Statement = [{ Effect = "Allow" Action = "s3-outposts:*" Principal = { AWS = format("arn:aws:iam::%s:root", data.aws_caller_identity.current.account_id) } Resource = [format("arn:aws:s3-outposts:%s:%s:outpost/%s/accesspoint/%s", data.aws_region.current.name, data.aws_caller_identity.current.account_id, var.outpost_id, var.access_point_name)] }] }) vpc_configuration { vpc_id = var.vpc_id } }
错误原因分析
- 资源引用与拼写错误:代码中存在两处关键错误:
- 访问点资源引用错误:
aws_s3_access_point.access_point.arn应为aws_s3_access_point.op_access_point.arn(资源名定义为op_access_point) - ARN拼写错误:策略中的
arm是笔误,正确应为arn
- 访问点资源引用错误:
- 权限时序问题:单独创建策略资源时,访问点的初始权限可能限制了后续的策略更新操作;而嵌入策略创建访问点是一次性操作,AWS的权限检查逻辑更宽松,避免了时序性的权限冲突
- 策略版本兼容性:S3 Outposts部分场景对策略版本有特定要求,嵌入代码中使用的
2008-10-17版本更适配Outposts资源
解决方案
方案1:修正代码中的引用与拼写错误
将错误的资源引用和拼写修正后,重新执行Terraform:
resource "aws_s3_access_point" "op_access_point" { bucket = aws_s3control_bucket.bucket_name.arn name = var.access_point_name vpc_configuration { vpc_id = var.vpc_id } } resource "aws_s3control_access_point_policy" "accesspoint_policy" { # 修正资源引用 access_point_arn = aws_s3_access_point.op_access_point.arn policy = jsonencode({ Version = "2012-10-17" Statement = [{ Effect = "Allow" Action = [ "s3-outposts:*" ] Principal = { AWS = "*" } Resource = [ # 修正ARN拼写错误 "${aws_s3_access_point.op_access_point.arn}" ] }] }) }
方案2:使用嵌入策略的创建方式(推荐)
直接将策略嵌入aws_s3_access_point资源中创建,这是AWS官方推荐的S3 Outposts访问点创建方式,能避免单独更新策略时的权限问题,同时保证配置的原子性。
方案3:为Terraform执行身份补充权限
确保执行Terraform的IAM身份拥有s3-outposts:PutAccessPointPolicy权限,权限策略示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3-outposts:PutAccessPointPolicy", "Resource": "arn:aws:s3-outposts:<你的区域>:<你的账号ID>:outpost/<你的Outpost ID>/accesspoint/<访问点名称>" } ] }
额外注意事项
- S3 Outposts访问点策略的
Resource字段必须指定完整的访问点ARN,不建议使用通配符,避免权限过度开放 - 可以通过Terraform输出验证ARN正确性:
output "access_point_arn" { value = aws_s3_access_point.op_access_point.arn } - 避免使用
Principal = { AWS = "*" }这类过于宽松的权限配置,建议限制到特定IAM用户、角色或账号,提升资源安全性
内容的提问来源于stack exchange,提问作者mebb
相关产品推荐
相关产品推荐

