У меня есть 8 AWS учетных записей, которые я перевожу на terraform'd. Медленный процесс импорта существующего ресурса в файл состояния, завершение определения до тех пор, пока план не станет пустым. Долгое время, но процесс работает.
Один из рекомендуемых методов - не допускать файл состояния в репозиторий, поэтому я держу состояние в S3 (с блокировкой в DynamoDB).
Локально, с моей настройкой файла ~/.aws/credentials
для всех учетных записей, я могу запускать terraform локально и все состояния go в корзину. Но это потому, что я использую profile="management"
в своем файле backend.tf.
Я хочу переместить терраформирование в наш конвейер, поэтому наличие нескольких общих учетных данных не очень удобно. Мы можем предоставить AWS_ACCESS_KEY, AWS_SECRET_ACCESS_KEY и AWS_DEFAULT_REGION в качестве переменных среды в конвейере. Для учетной записи управления это работает нормально, поэтому у нас теперь есть конвейеры, выполняющие развертывание, и мы рады.
Мы не можем использовать несколько envvars, поскольку Terraform не допускает никаких переменных в определении бэкэнда.
Итак, я пытаюсь понять, как «поделиться» доступом к файлу состояния и заблокировать его.
Я думаю (и я, вероятно, ошибаюсь), но идея «терраформирования» Роль », существующая в учетной записи управления, которая позволяет назначенным пользователям иметь возможность предполагать, что роль и взаимодействовать с государством, кажется разумным путем к go. Но я не понимаю.
Так что вы можете рассмотреть то, что у меня есть, указать мне правильное направление или, пожалуйста, помочь мне исправить это.
Итак, Файл 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 (запускает наши конвейеры и другие непроизводственные задачи).
Рабочий бэкэнд .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"
I ' Я пытался использовать учетные данные управления в 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 для роли - это тот, который отображается в консоли управления для роли. Роль говорит, что учетная запись devops (4xxxxx) разрешена. Так что я в тупике.
Буду признателен за любую помощь.