You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Terragrunt和OpenTofu扮演角色时遭遇403访问拒绝错误

问题:Terragrunt执行terragrunt apply时S3创建报错AccessDenied

我通过角色扮演部署资源,执行terragrunt apply时遇到AccessDenied错误,无法创建S3桶。已确认被扮演的角色附加了AdministratorAccess策略,且通过AWS CLI测试过角色扮演功能正常。

报错信息

│ Error: creating Amazon S3 (Simple Storage) Bucket (<bucket-name>): AccessDenied: Access Denied
│       status code: 403, request id: xxxxxxx, host id: xxxx
│ 
│   with module.s3_bucket.aws_s3_bucket.this[0],
│   on .terraform/modules/s3_bucket/main.tf line 25, in resource "aws_s3_bucket" "this":
│   25: resource "aws_s3_bucket" "this" {
│ 
╵

我的Terragrunt配置片段

remote_state {
  backend = "s3"
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite_terragrunt"
  }
  config = {
    bucket = "terraform-state-bucket"

    skip_bucket_ssencryption       = true
    skip_bucket_root_access        = true
    skip_bucket_enforced_tls       = true

    key = "${path_relative_to_include()}/terraform.tfstate"
    region         = "${local.region.aws_region}"
    encrypt        = true
    dynamodb_table = "terraform-state-locks"

    assume_role = {
      role_arn = "<redacted>"
      session_name = "<redacted>"
      external_id = "<redacted>"
    }
  }
}

generate "provider" {
  path = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents = <<EOF
provider "aws" {
  alias  = "origin"
  region = "${local.region.aws_region}"
  allowed_account_ids = ["${local.account.account_id}"]
  assume_role {
    role_arn     = "<redacted>"
    session_name = "<redacted>"
    external_id  = "<redacted>"
  }
}

EOF
}

使用版本:OpenTofu 1.6.0,Terragrunt 0.54.12


问题分析与解决

你的Terragrunt配置存在关键遗漏:生成的AWS provider设置了alias = "origin",但S3桶模块并未指定使用这个带别名的provider。

Terraform模块默认会使用无别名的默认provider,而你没有定义默认provider,导致系统尝试用本地AWS CLI的默认凭证(而非你要扮演的角色)创建S3桶,最终触发AccessDenied错误。

两种解决方法

  1. 移除provider别名,设为默认provider
    修改generate "provider"部分的配置,去掉alias = "origin":
generate "provider" {
  path = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents = <<EOF
provider "aws" {
  region = "${local.region.aws_region}"
  allowed_account_ids = ["${local.account.account_id}"]
  assume_role {
    role_arn     = "<redacted>"
    session_name = "<redacted>"
    external_id  = "<redacted>"
  }
}
EOF
}
  1. 模块调用时显式指定provider别名
    在调用s3_bucket模块的代码中,添加provider绑定:
module "s3_bucket" {
  # 保持原有模块配置不变
  providers = {
    aws = aws.origin
  }
}

额外检查点

  • 确认remote_state和provider中的assume_role使用的是同一个角色ARN,避免跨角色权限冲突
  • 检查S3桶名是否符合AWS命名规则,是否已被其他账户占用(极少数情况下重名也会导致类似403错误)

内容的提问来源于stack exchange,提问作者Joey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:05:17