我有8个AWS帐户,我要将其迁移为地形。将现有资源导入状态文件、完成定义直到计划为空的缓慢过程。长篇大论,但这是一个正在发挥作用的过程。
建议的做法之一是将状态文件排除在repo之外,因此我将状态保存在S3中(在DynamoDB中锁定(。
在本地,通过为所有帐户设置~/.aws/credentials
文件,我可以在本地运行terraform,所有状态都进入bucket。但这是因为我在backend.tf文件中使用了profile="management"
。
我想把地形改造转移到我们的管道中,所以让多个共享证书四处浮动并不好。我们可以在管道中提供AWS_ACCESS_KEY、AWS_SECRET_ACCESS_KEY和AWS_DEFAULT_REGION作为环境变量。对于管理帐户来说,这很好,所以我们现在有管道进行部署,我们很高兴。
我们不能使用多个envvars,因为Terraform不允许在后端定义中使用任何变量。
因此,我试图找出如何"共享"对状态文件的访问并锁定。
我认为(我可能错了(,但管理账户中存在的"地形化角色"的想法,允许指定用户承担该角色并与国家互动,似乎是一种明智的做法。但我不明白。
所以,你能不能回顾一下我所掌握的,给我指一个正确的方向,或者,很好地,请帮我解决这个问题。
因此,管理状态.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"
}
因此,在现在尝试让它像在管道中一样工作时,我隐藏了管理和devops帐户的~/.aws/credentials
条目,并使用envvarsAWS_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 = "..."
这起到了作用,所以现在取消证书。
我原以为我可以为地形角色添加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(。所以我被难住了。
如有任何帮助,我们将不胜感激。
我的解决方案基于根帐户不能承担角色的新知识。
因此,管理帐户需要一个用户(Terraformer(。此用户的策略允许其承担OrganizationAccountAccessRole的devops角色,以及访问管理帐户中与状态相关的资源。
此用户用于将地形应用于非管理帐户。
对我来说简单多了。