Terraform 未部署到多个帐户

Terraform not deploying into multiple accounts

我在 terraform/terragrunt 部署到多个帐户时遇到问题。我想在我的 "master" 帐户中管理 DNS 和 KMS,并将其他一切部署到我的 dev/uat/prod 环境中。

我使用提供商配置了多个 AWS 账户。一个是通过 terragrunt 自动创建的,另一个是在我的 main.tf 文件中创建的。

我尝试了很多不同的方法来让它发挥作用。为两个提供者设置别名,只为一个提供者设置一个别名,并从等式中完全删除 terragrunt。在每种情况下,terraform 都应用于我的 "master" 帐户的所有资源..

下面是我的代码示例:

  backend = "s3"
#   generate = {
#       path = "backend.tf"
#       if_exists = "overwrite"
#   }
  config = {
    bucket                  = "arm-terraform-state"
    key                     = "${path_relative_to_include()}/terraform.tfstate"
    region                  = "us-west-2"
    dynamodb_table          = "arm-terraform-state-lock"
  }
  generate = {
    path = "backend.tf"
    if_exists = "overwrite_terragrunt"
  }
}
generate "provider" {
  path = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents = <<EOF
provider "aws" {
  alias                   = "main"
  region                  = "${local.aws_region}"
  profile                 = "${local.account}"
}
EOF
}
locals {
    region_vars = read_terragrunt_config(find_in_parent_folders("region.hcl"))
    account_vars = read_terragrunt_config(find_in_parent_folders("account.hcl"))
    aws_region   = local.region_vars.locals.aws_region
    account = local.account_vars.locals.aws_profile
}

以上是我的 Terragrunt 代码。 这是我的模块:

resource "aws_iam_role_policy" "logging_role_policy" {
  provider = aws.main
  name = format("aws-sftp-logging-policy-%s-%s",var.product_name,var.env)

  role= aws_iam_role.logging_role.id

  policy = data.aws_iam_policy_document.sftp_logging.json
}
############
# Route 53 #
############
resource "aws_route53_record" "sftp_record" {
  provider = aws.master
  zone_id = data.aws_route53_zone.facteus.zone_id
  name = format("%s-%s",var.product_name,var.env)
  type = "CNAME"
  ttl = "30"
  records = [aws_transfer_server.aws_transfer_service.endpoint]
}

您应该首先创建一个反映您所需帐户结构的目录结构。根据你的问题,听起来你可能想要这样的东西:

├── dev
│   ├── terragrunt.hcl
│   └── us-east-1
├── master
│   ├── _global
│   │   └── dns
│   ├── terragrunt.hcl
│   └── us-east-1
│       └── kms
├── prod
│   ├── terragrunt.hcl
│   └── us-east-1
└── uat
    ├── terragrunt.hcl
    └── us-east-1

这里的master账号有两个其他人没有的目录:

  1. _global/dns - 由于 AWS 中的 Route 53 是一个全球实体(而非区域),您不希望将其嵌套在 us-east-1 下。它仅存在于 master 帐户中,因为您声明要从主机控制 DNS。 (我还建议将其命名为 route53 而不是 dns,但我离题了。)

  2. us-east-1/kms - 这包含 KMS 配置,也仅适用于 master.

现在,在 master/terragrunt.hcl 中设置您的 remote_state 配置:

remote_state {
  backend = "s3"
  config = {
    encrypt        = true
    bucket         = "master-terraform-state" # Just for example - must be a globally unique
    key            = "${path_relative_to_include()}/terraform.tfstate"
    region         = "us-east-1"
    dynamodb_table = "terraform-locks"
  }
}

您还可以选择包含 iam_role attribute

iam_role = "arn:aws:iam::ACCOUNT_ID:role/ROLE_NAME"

请注意,这是可选的,因为您也可以使用主帐户的凭据简单地执行 Terragrunt,或者您可以使用 --terragrunt-iam-role CLI 选项,或者您可以设置 TERRAGRUNT_IAM_ROLE env var .在所有情况下,您将使用具有主帐户权限的角色执行 terragrunt。

现在,对于 dev/uat/prod 个帐户,您可以使用类似的 remote_state 配置,为每个帐户替换不同的存储桶名称。然后,您可以使用适合每个账户的 IAM 角色,方法是在每个账户的 terragrunt.hcl 中将其定义为 iam_role,或者使用我提到的其他方法。

TL;DR 您不需要为此生成提供程序,也不需要在提供程序配置中命名配置文件。您只需为每个账户使用正确的 IAM 角色执行 terragrunt。 Terragrunt 将在调用 Terraform 之前承担该角色。将提供程序配置放入您的 Terraform 模块中,关闭配置文件。