amazon-web-services - Terraform 未部署到多个帐户中
问题描述
我在将 terraform/terragrunt 部署到多个帐户时遇到问题。我想在我的“主”帐户中管理 DNS 和 KMS,并将其他所有内容部署到我的 dev/uat/prod 环境中。
我已经使用提供商配置了多个 AWS 账户。一个是通过 terragrunt 自动创建的,另一个是在我的 main.tf 文件中创建的。
我已经尝试了许多不同的方法来让它发挥作用。为这两个提供者设置别名,只为一个提供者设置别名,并从等式中完全删除 terragrunt。在每种情况下,terraform 都将应用于我的“主”帐户以获取所有资源。
下面是我的代码示例:
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
账号有两个其他人没有的目录:
_global/dns
- 由于 AWS 中的 Route 53 是一个全局实体(不是区域性的),因此您不想将其嵌套在us-east-1
. 它只存在于master
帐户中,因为您声明要从 master 控制 DNS。(我也建议命名它route53
而不是dns
,但我离题了。)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
属性:
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 角色,方法是在每个账户中定义它iam_role
,terragrunt.hcl
或者通过我提到的其他方法。
TL;DR 您不需要为此生成提供程序,也不需要在提供程序配置中命名配置文件。您只需为每个账户使用正确的 IAM 角色执行 terragrunt。Terragrunt 将在调用 Terraform 之前担任该角色。将提供程序配置放在 Terraform 模块中,关闭配置文件。
推荐阅读
- react-native - 现有应用程序最佳实践中的 React Native 集成
- html - autocomplete=new-password 并让他们通过再次输入密码来确认
- go - Go 锁定一片结构
- python-3.x - db2 python [处理失败]
- javascript - Express req.files 总是返回空白 [object]
- subdomain - 在 cpanel 中为我的子域创建一个单独的目录
- python - 如何显示随着烧瓶和python不断变化的变量?
- javascript - 会话在锚标记中不起作用
- php - PHP在不同的键上推送相同的数据
- javascript - 如何将php结果传递给javascript图表