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

AWS环境下如何跨账号存储Terraform状态并执行资源变更

回答

1. 关于assume_role_policy_arns参数的填写说明

你目前存在参数认知误区:assume_role_policy_arns不是用来填写待代入角色ARN的,S3后端相关参数的作用分别是:

  • role_arn:跨账号访问S3时必填,填写Infrastructure Account(账号ID111)中,拥有S3状态桶读写、DynamoDB锁表读写权限的IAM角色ARN。Terraform操作状态文件时会先代入这个角色获取临时凭证。
  • assume_role_policy_arns:可选参数,仅当你需要给上述role_arn对应的临时会话附加权限边界、缩限默认权限时才需要填写,值为IAM策略的ARN列表;如果你不需要额外缩限权限,这个参数可以直接删除,不需要填任何值。

结合你使用AWS Control Tower + AWS SSO的场景,ControlTower为每个账号预置的SSO管理员角色ARN格式为:
arn:aws:iam::<账号ID>:role/aws-reserved/sso.amazonaws.com/<SSO部署区域>/AWSReservedSSO_AWSAdministratorAccess_<随机后缀>
你可以在登录SSO后,在IAM控制台的角色列表找到111账号下对应的管理员角色,复制ARN填入role_arn即可。不过最佳实践是不要直接用管理员角色操作状态文件,建议在111账号新建一个Terraform专用后端角色,仅授予状态桶和锁表的最小必要权限。

修正后的后端配置示例:

terraform {
  backend "s3" {
    bucket = "terraform-infrastructure"
    key    = "dev/sqs/terraform.tfstate"
    region = "us-east-1"
    # 替换为111账号下用于访问状态文件的角色ARN
    role_arn = "arn:aws:iam::111:role/aws-reserved/sso.amazonaws.com/us-east-1/AWSReservedSSO_AWSAdministratorAccess_xxxxxx"
    # 不需要权限缩限的话直接删掉assume_role_policy_arns配置即可
    # 建议搭配DynamoDB表开启状态锁,避免并发写冲突
    dynamodb_table = "terraform-state-lock"
    encrypt = true
  }

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

2. 关于S3额外配置的判断纠正

你的判断不完全正确,核心原因是Terraform操作S3状态文件的身份,和操作DEV账号资源的身份是完全独立的两套配置:

  • 如果你在S3后端块中明确配置了使用111账号内的角色访问S3桶(比如上面示例的role_arn填111账号内的角色),且该角色本身已经有S3桶的读写权限,那么确实不需要额外配置S3跨账号访问策略,因为这属于账号内角色访问同账号S3资源,默认权限足够。
  • 如果你没有配置后端的role_arn,误用了DEV账号(222)的角色身份去访问111账号的S3桶,那么S3默认会拒绝跨账号访问请求,这时候你必须给S3桶添加桶策略,明确允许222账号的对应角色执行s3:GetObject、s3:PutObject等状态操作必要的权限。

另外建议给状态S3桶做几个基础配置,符合ControlTower安全基线:

  • 开启版本控制,避免状态文件误删无法恢复
  • 开启SSE-KMS加密,保护状态文件里的敏感数据
  • 开启公共访问阻止,避免状态文件泄露
  • 搭配同区域DynamoDB表开启状态锁,避免多人同时执行Terraform导致状态文件损坏

3. 补充:AWS Provider配置建议

你当前的provider块只配置了允许的账号ID,还需要补充DEV账号对应的角色ARN,否则Terraform会默认用操作后端的身份去操作DEV账号的资源,会因为权限不足报错。修正后的provider配置示例:

provider "aws" {
  region = "us-east-1"
  allowed_account_ids = ["222"]
  # 替换为222账号下的SSO管理员角色ARN,或专用的Terraform资源操作角色ARN
  assume_role {
    role_arn = "arn:aws:iam::222:role/aws-reserved/sso.amazonaws.com/us-east-1/AWSReservedSSO_AWSAdministratorAccess_xxxxxx"
  }
}

执行Terraform操作前,你只需要通过aws sso login登录自己的SSO身份,该身份拥有两个账号的角色代入权限即可,Terraform会自动完成两次角色代入:先代入111账号的角色读写状态,再代入222账号的角色操作资源。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:24:14