Попытка централизовать состояния терраформ и путаница с принятием ролей и политик - PullRequest
1 голос
/ 07 апреля 2020

У меня есть 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) разрешена. Так что я в тупике.

Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 08 апреля 2020

Мое решение основано на новых знаниях о том, что root учетные записи не могут выполнять роли.

Итак, для учетной записи управления необходим пользователь (Terraformer). У этого пользователя есть политика, которая позволяет ему принимать роль devops в OrganizationAccountAccessRole, а также доступ к ресурсам, связанным с состоянием, в учетной записи управления.

Этот пользователь используется для применения terraform к учетным записям, не относящимся к управлению.

Намного проще.

...