0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

MFAやSwitch role(Assume role)使用環境下でTerraformを使うTips

Posted at

本記事は、こちらの記事のCross postです。


はじめに

Terraformは、インフラ構成をCodeで管理(IaC)したり、同様の環境を複数構築するのに便利なツールである。
しかし、Terraform用のCredentialを対象の各AWSアカウントから払い出せればスムーズだが、Security要件によってはそれが難しいケースもある。例えば、AWS ConsoleにLog-inするIAM Userを用いなければならなかったり、そのIAM UserにはMFAが義務付けられていたり、Switch role(Assume role)を用いてTerraformで使用するCredentialが無いアカウントに環境を構築しなければならないケースなどである。
このような少し複雑な構成の場合、Terraformの設定やApplyにはちょっとしたコツが必要となる。本記事では、そのようなTipsをまとめておきたい。

前提条件

今回は、以下のような構成おいて、TerraformでAWS Account B下に構築を行うことを想定する。

  • AWS Account Aについて、Terraform実行するIAM UserのCredentialが払い出されている
  • AWS Account BにはSwitch role(Assume role)用のRoleが設定されており、上記のAWS Account AのIAM UserからSwitch role(Assume role)できるようになっている
  • 上記のAWS Account AのIAM UserのCredentialにはMFAが設定されている

事前準備

設定方法

MFAを使うための方法

AWC Cli

.aws/config
[profile Account-A]
region = ap-northeast-1
output = text
mfa_serial = arn:aws:iam::123456789012:mfa/aws_cli

ポイントは、mfa_serialの部分。
ここに、Credential情報に紐づくMFAのARNを記述する。
ちなみに、本記事執筆時点では AWS CliのMFAにPassskeyは使用できない1ので、必ず認証アプリケーションを割り当てておく必要がある。

以下にSampleの設定ファイルを置いておく。
https://github.com/unitedstar-tech/common/blob/main/terraform_mfa/aws_config.sample

MFA使用環境下でTerraformを使う

結論から言うと、Terraform自体はMFAトークンによる対話型認証に対応していない。
そのため、AWS Cliのようにshared_config_filesの設定を用いてTerraformを利用することはできない。
そこで、Wrapper scriptを作成した。
https://github.com/unitedstar-tech/common/blob/main/terraform_mfa/terraform_mfa

Source

terraform_mfa.sh
#!/bin/bash
export LANG=C

# ARGS
MFA_ARN="arn:aws:iam::123456789012:mfa/aws_cli"
SRC_PROFILE="Account-A"
VALID_DURATION="14400"

check_opts=0
while getopts "m:t:h" opt
do
    case $opt in
        m)
            MFA_CODE=$OPTARG
            check_opts=`expr $check_opts + 1`;;
        t)
            TERRAFORM_MODE=$OPTARG
            check_opts=`expr $check_opts + 2`;;
        h)
            echo "Usage: $0 [-m MFA_CODE] [-t TERRAFORM_ARGS]"
            exit 0;;
        \?)
            echo "[WARNING] Usage: $0 [-m MFA_CODE] [-t TERRAFORM_ARGS]";;
    esac
done
if [ $check_opts -ne 3 ]
then
    echo -e "[ERROR] Missing required options\n\nUsage: $0 [-m MFA_CODE] [-t TERRAFORM_ARGS]\n-h to see Help"
    exit 1
fi

# Main
DATA=`aws sts get-session-token --serial-number $MFA_ARN --profile $SRC_PROFILE --duration-seconds $VALID_DURATION --token-code $MFA_CODE`
if [ $? -ne 0 ]
then
    echo "[ERROR] Invalid MFA code"
    exit 1
fi
ACCESS_KEY=`echo $DATA | awk '{print $2}'`
SECRET_ACCESS_KEY=`echo $DATA | awk '{print $4}'`
TOKEN=`echo $DATA | awk '{print $5}'`
export AWS_ACCESS_KEY_ID=$ACCESS_KEY
export AWS_SECRET_ACCESS_KEY=$SECRET_ACCESS_KEY
export AWS_SESSION_TOKEN=$TOKEN
terraform $TERRAFORM_MODE

具体的な方式としては、AWS Security Token Service(AWS STS)にMFA One-time codeとCredential情報を渡すことでIAMの一時的な認証情報(Token)を払い出し2、そのTokenを環境変数にSetして認証に用いることでTerraformがMFA One-time Codeの入力なしに実行することを可能としている。

Usage

e.g.
# terraform_mfa -t "plan -target=aws_vpc.vpc" -m <MFAのOne-time code>

Switch role(Assume role)を使うための方法

AWS Cli

.aws/config
[profile Account-A]
region = ap-northeast-1
output = text
mfa_serial = arn:aws:iam::123456789012:mfa/aws_cli
[profile Account-B]
role_arn = arn:aws:iam::987654321098:role/AWSAdministratorAccess
source_profile = Account-A
region = ap-northeast-1
output = text
mfa_serial = arn:aws:iam::123456789012:mfa/aws_cli

ポイントは、source_profileにSwitch role(Assume role)元のProfileを、role_arnにSwitch role(Assume role)先のRole arnを設定する。
source_profileにMFAが設定されている場合、Switch role(Assume role)先のEntryにも同様にmfa_serialを設定する必要がある。

Terraform

Source

まずは、Terraformを使うための設定を記述したTFファイル全文を掲載しておく。
ポイントとなる部分の解説は後述。

terraform.tf
terraform {
    required_version = ">= 1.10.5"
    required_providers {
        aws = {
        source = "hashicorp/aws"
        version = "~> 5.33.0"
        }
    }
    backend "s3" {
      bucket = "terraform-state-dev-987654321098-ap-northeast-1"
      key = "dev/terraform.tfstate"
      region = "ap-northeast-1"
      assume_role = {
        role_arn = "arn:aws:iam::987654321098:role/AWSAdministratorAccess"
      }
  }
}

provider "aws" {
  region = "ap-northeast-1"
  assume_role {
    role_arn = "arn:aws:iam::987654321098:role/AWSAdministratorAccess"
  }
}

provider "aws" {
  alias = "tokyo"
  region = "ap-northeast-1"
  assume_role {
    role_arn = "arn:aws:iam::987654321098:role/AWSAdministratorAccess"
  }
}

provider "aws" {
  alias = "osaka"
  region = "ap-northeast-3"
  assume_role {
    role_arn = "arn:aws:iam::987654321098:role/AWSAdministratorAccess"
  }

ポイントは、providerBlock.
ここに、assume_roleでSwitch role(Assume role)先のRoleのARNを記述する。

terraform.tf
provider "aws" {
  region = "ap-northeast-1"
  assume_role {
    role_arn = "arn:aws:iam::987654321098:role/AWSAdministratorAccess"
  }
}

tfstateをSwitch role(Assume role)先のS3に配置する

terraform.tf
    backend "s3" {
      bucket = "terraform-state-dev-987654321098-ap-northeast-1"
      key = "dev/terraform.tfstate"
      region = "ap-northeast-1"
      assume_role = {
        role_arn = "arn:aws:iam::987654321098:role/AWSAdministratorAccess"
      }

ポイントは、backendBlockのassume_roleセクション。
ここに、assume_roleでSwitch role(Assume role)先のRoleのARNを記述する。
なお、providerBlockと違い、backendBlockでは "assume_role"の後ろに"="が入ることに注意が必要。

終わりに

以上のように、TerraformでMFAやSwitch role(Assume role)を扱う方法や要点をまとめた。
Webで検索すると、aws-vaultを用いる方法なども頻繁に紹介されているが、passGnuPGと言った依存モジュールも導入する必要があり、やや煩雑である。
少し複雑な環境においてより手軽にTerraformで扱うために、本記事が参考になれば幸いである。

参考記事

  1. 2024年6月現在 AWS CLI の MFA デバイスとしてパスキーは使用できない

  2. IAMの一時的な認証情報

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?