【发布时间】:2020-07-19 12:39:11
【问题描述】:
我有 8 个 AWS 帐户,我正在迁移它们以进行 terraform'd。将现有资源导入状态文件的缓慢过程,完成定义直到计划为空。长篇大论,但一个正在运行的过程。
推荐的做法之一是将状态文件保留在存储库之外,因此我将状态保存在 S3 中(在 DynamoDB 中锁定)。
在本地,通过为所有帐户设置我的~/.aws/credentials 文件,我可以在本地运行 terraform,所有状态都进入存储桶。但这是因为我在 backend.tf 文件中使用了profile="management"。
我想将地形改造移动到我们的管道中,因此让多个共享凭据四处浮动并不是很好。我们可以提供 AWS_ACCESS_KEY、AWS_SECRET_ACCESS_KEY 和 AWS_DEFAULT_REGION 作为管道中的环境变量。对于主帐户,这工作正常,所以我们现在有管道进行部署,我们很高兴。
我们不能使用多个环境变量,因为 Terraform 不允许在后端定义中使用任何变量。
所以我正在尝试研究如何“共享”对状态文件的访问并锁定。
我认为(而且我可能错了)但管理帐户中存在的“改造角色”的想法允许指定用户能够承担该角色并与国家互动似乎是明智的要走的路。但我没听懂。
那么请您回顾一下我所拥有的,指出我正确的方向,或者,请帮我解决这个问题。
所以,管理 state.tf 文件是(S3 存储桶和 DynamoDB 表资源被剪断)...
resource "aws_s3_bucket" "backend_remote" {
...
}
resource "aws_dynamodb_table" "backend_locks" {
...
}
data "aws_iam_policy_document" "terraforming_policy_document" {
statement {
sid = "TerraformingS3ListBucket"
effect = "Allow"
actions = [
"s3:ListBucket",
]
resources = [
aws_s3_bucket.backend_remote.arn,
]
}
statement {
sid = "TerraformingS3AccessObjects"
effect = "Allow"
actions = [
"s3:GetObject",
"s3:PutObject",
]
resources = [
"${aws_s3_bucket.backend_remote.arn}/*",
]
}
statement {
sid = "TerraformingHandleLocks"
effect = "Allow"
actions = [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem",
]
resources = [
aws_dynamodb_table.backend_locks.arn,
]
}
}
data "aws_iam_policy_document" "terraforming_assume_role_policy" {
statement {
sid = "TerraformingAssumeRolePolicy"
effect = "Allow"
actions = [
"sts:AssumeRole",
]
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::4[SNIPPED]:root"
]
}
}
}
resource "aws_iam_policy" "terraforming_policy" {
description = "Policy to allow terraform state files to be stored in S3 with locking managed in DynamoDB"
name = "TerraformingPolicy"
policy = data.aws_iam_policy_document.terraforming_policy_document.json
}
resource "aws_iam_role" "terraforming" {
assume_role_policy = data.aws_iam_policy_document.terraforming_assume_role_policy.json
description = "Role to allow terraform state files to be stored in S3 with locking managed in DynamoDB"
name = "Terraforming"
path = "/"
}
resource "aws_iam_role_policy_attachment" "terraforming_attachment_policy" {
policy_arn = aws_iam_policy.terraforming_policy.arn
role = aws_iam_role.terraforming.name
}
有了这个,我的管理 AWS 控制台显示了角色,一切看起来都很好。它显示了策略验证满意的策略。它显示受信任的帐户。
看起来一切正常。
现在转到 devops 帐户(运行我们的管道和其他非生产任务)。
工作的 backend.tf(使用~/.aws/credentials 中的共享凭据)看起来像这样...
terraform {
backend "s3" {
bucket = "management-state-bucket"
acl = "private"
encrypt = true
region = "eu-west-1"
dynamodb_table = "terraform_locks"
key = "devops.tfstate"
profile = "management"
}
所以,现在为了让它像在管道中一样工作,我隐藏了我的 ~/.aws/credentials 管理和 devops 帐户的条目,并使用 envvars AWS_ACCESS_KEY=AKIAIN... AWS_SECRET_ACCESS_KEY=... AWS_DEFAULT_REGION=eu-west-1 terraform ...
如果我还添加TF_LOG=trace,我可以看到正确的凭据提供程序正在发挥作用:2020/04/07 10:40:07 [INFO] AWS Auth provider used: "EnvProvider"
我尝试使用 devops.tf 中的管理凭据...
access_key = "AKIAJ5..."
secret_key = "..."
这行得通,所以现在摆脱凭据。
我原以为我可以为 terraforming 角色添加 role_arn 条目,但那不起作用。
role_arn = "arn:aws:iam::5[SNIPPED]:role/Terraforming"
2020/04/07 11:31:20 [INFO] AWS Auth provider used: "EnvProvider"
2020/04/07 11:31:20 [INFO] Attempting to AssumeRole arn:aws:iam::5[SNIPPED]:role/Terraforming (SessionName: "", ExternalId: "", Policy: "")
Error: The role "arn:aws:iam::5[SNIPPED]:role/Terraforming" cannot be assumed.
There are a number of possible causes of this - the most common are:
* The credentials used in order to assume the role are invalid
* The credentials do not have appropriate permission to assume the role
* The role ARN is not valid
角色的 ARN 是角色的管理控制台中显示的 ARN。 该角色表示允许使用 devops 帐户 (4xxxxx)。 所以我被难住了。
任何帮助将不胜感激。
【问题讨论】:
标签: amazon-web-services terraform terraform-provider-aws