Terraform не может выполнять роли с включенным MFA - PullRequest
0 голосов
/ 20 сентября 2018

У меня ужасное время, когда Terraform берет на себя роль IAM с другой учетной записью, требующей MFA.Вот мои настройки

AWS Config

[default]
region = us-west-2
output = json

[profile GEHC-000]
region = us-west-2
output = json

....

[profile GEHC-056]
source_profile = GEHC-000
role_arn = arn:aws:iam::~069:role/hc/hc-master
mfa_serial = arn:aws:iam::~183:mfa/username
external_id = ~069

AWS Credentials

[default]
aws_access_key_id = xxx
aws_secret_access_key = xxx


[GEHC-000]
aws_access_key_id = same as above
aws_secret_access_key = same as above

Политики, назначенные пользователю IAM

Политика STS

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AssumeRole",
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/hc/hc-master"
            ]
        }
    ]
}

Политика пользователя

{
    "Statement": [
        {
            "Action": [
                "iam:*AccessKey*",
                "iam:*MFA*",
                "iam:*SigningCertificate*",
                "iam:UpdateLoginProfile*",
                "iam:RemoveUserFromGroup*"
            ],
            "Effect": "Allow",
            "Resource": [
                "arn:aws:iam::~183:mfa/${aws:username}",
                "arn:aws:iam::~183:mfa/*/${aws:username}",
                "arn:aws:iam::~183:mfa/*/*/${aws:username}",
                "arn:aws:iam::~183:mfa/*/*/*${aws:username}",
                "arn:aws:iam::~183:user/${aws:username}",
                "arn:aws:iam::~183:user/*/${aws:username}",
                "arn:aws:iam::~183:user/*/*/${aws:username}",
                "arn:aws:iam::~183:user/*/*/*${aws:username}"
            ],
            "Sid": "Write"
        },
        {
            "Action": [
                "iam:*Get*",
                "iam:*List*"
            ],
            "Effect": "Allow",
            "Resource": [
                "*"
            ],
            "Sid": "Read"
        },
        {
            "Action": [
                "iam:CreateUser*",
                "iam:UpdateUser*",
                "iam:AddUserToGroup"
            ],
            "Effect": "Allow",
            "Resource": [
                "*"
            ],
            "Sid": "CreateUser"
        }
    ],
    "Version": "2012-10-17"
}

Принудительная политика MFA

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "BlockAnyAccessOtherThanAboveUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": "iam:*",
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}

main.tf

provider "aws" {
  profile                 = "GEHC-056"
  shared_credentials_file = "${pathexpand("~/.aws/config")}"
  region                  = "${var.region}"
}

data "aws_iam_policy_document" "test" {
  statement {
    sid    = "TestAssumeRole"
    effect = "Allow"

    actions = [
      "sts:AssumeRole",
    ]

    principals = {
      type = "AWS"

      identifiers = [
        "arn:aws:iam::~183:role/hc-devops",
      ]
    }

    sid    = "BuUserTrustDocument"
    effect = "Allow"

    principals = {
      type = "Federated"

      identifiers = [
        "arn:aws:iam::~875:saml-provider/ge-saml-for-aws",
      ]
    }

    condition {
      test     = "StringEquals"
      variable = "SAML:aud"
      values   = ["https://signin.aws.amazon.com/saml"]
    }
  }
}

resource "aws_iam_role" "test_role" {
  name               = "test_role"
  path               = "/"
  assume_role_policy = "${data.aws_iam_policy_document.test.json}"
}

Получение идентификатора вызывающего абонента

bash-4.4$ aws --profile GEHC-056 sts get-caller-identity
Enter MFA code for arn:aws:iam::772660252183:mfa/503072343:
{
  "UserId": "AROAIWCCLC2BGRPQMJC7U:botocore-session-1537474244",
  "Account": "730993910069",
  "Arn": "arn:aws:sts::730993910069:assumed-role/hc-master/botocore-session-1537474244"
}

И ошибка:

bash-4.4$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


Error: Error refreshing state: 1 error(s) occurred:

* provider.aws: Error creating AWS session: AssumeRoleTokenProviderNotSetError: assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.

1 Ответ

0 голосов
/ 21 сентября 2018

Terraform в настоящее время не поддерживает запрос маркера MFA при запуске, поскольку он предназначен для запуска в менее интерактивном режиме, насколько это возможно, и, очевидно, потребуется значительная доработка структуры поставщика для поддержки этой конфигурации интерактивного поставщика,Это обсуждается в этом выпуске .

. Как уже упоминалось в этом выпуске, лучше всего использовать некую форму сценария / инструмента, которая уже выполняет свою роль до запуска Terraform.

Я лично использую AWS-Vault и написал небольшой скрипт оболочки shim, на который я ссылаюсь с terraform (и другие вещи, такие как aws, которые я хочу использовать AWS-Vaultзахватить учетные данные для), который определяет, как он вызывается, находит «настоящий» двоичный файл, используя which -a, а затем использует exec AWS-Vault для запуска целевой команды с указанными учетными данными.

Мой сценарий выглядитнапример:

#!/bin/bash

set -eo pipefail

# Provides a shim to override target executables so that it is executed through aws-vault
# See https://github.com/99designs/aws-vault/blob/ae56f73f630601fc36f0d68c9df19ac53e987369/USAGE.md#overriding-the-aws-cli-to-use-aws-vault for more information about using it for the AWS CLI.

# Work out what we're shimming and then find the non shim version so we can execute that.
# which -a returns a sorted list of the order of binaries that are on the PATH so we want the second one.
INVOKED=$(basename $0)
TARGET=$(which -a ${INVOKED} | tail -n +2 | head -n 1)

if [ -z ${AWS_VAULT} ]; then
    AWS_PROFILE="${AWS_DEFAULT_PROFILE:-read-only}"
    (>&2 echo "Using temporary credentials from ${AWS_PROFILE} profile...")

    exec aws-vault exec "${AWS_PROFILE}" --assume-role-ttl=60m -- "${TARGET}" "$@"
else
    # If AWS_VAULT is already set then we want to just use the existing session instead of nesting them
    exec "${TARGET}" "$@"
fi

Он будет использовать профиль в вашем файле ~/.aws/config, который соответствует установленной вами переменной среды AWS_DEFAULT_PROFILE, по умолчанию используется профиль read-only, который может или не может быть полезнымпо умолчанию для вас.Это гарантирует, что AWS-Vault берет на себя роль IAM, захватывает учетные данные и устанавливает их в качестве переменных среды для целевого процесса.

Это означает, что для Terraform ему выдаются полномочия через переменные среды иэто просто работает.

...