MFA認証が有効な環境でAssume RoleしてTerraform実行する方法をまとめてみた[AWS]

2024.05.10

TerraformのAWS Providerは現時点(2024/4時点)で、MFAトークンの対話型認証はサポートされていません。

IAMユーザーでMFA認証が有効になっている環境では、IAMロールを引き受けるAWS CLIの名前付きプロファイルを指定して、Terraformを実行するとエラーになってしまいます。

~/.aws/config

[profile myprofile]
output=json
region=ap-northeast-1
role_arn=arn:aws:iam::01234567890:role/<IAMロール名>
mfa_serial=arn:aws:iam::12345678901:mfa/<IAMユーザ名>
$ export AWS_PROFILE="myprofile"
$ terraform plan
Planning failed. Terraform encountered an error while generating this plan.

╷
│ Error: assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.
│ 
│   with provider["registry.terraform.io/hashicorp/aws"],
│   on main.tf line 10, in provider "aws":
│   10: provider "aws" {

Issueのコメントにある通り、この方法の解決策はいくつかあります。

このブログでは各方法について説明します。

結論

主に以下の方法があります。

  1. AWS CLI 名前付きプロファイル
  2. AWS CLI 名前付きプロファイル + AWS認証情報管理/補助ツール
  3. AWS CLIで一時的な認証情報を生成

個人的には、「方法1: AWS CLI 名前付きプロファイル」がおすすめです。

AWS CLIで完結するため、他ツールのインストールやスクリプトの用意が不要で、セットアップのハードルが低いからです。

既に何らかのAWS認証情報管理/補助ツールを利用している場合は、「方法2: AWS CLI 名前付きプロファイル + AWS認証情報管理/補助ツール利用(aws-valut,aws-mfa,aswrap等)」。

スクリプトを作って独自の処理を実施したり、.aws/configの記述を減らしたい場合は、「方法3:AWS CLIで一時的な認証情報を生成(aws sts assume-role)」がおすすめです。

MFA認証が有効な環境でAssume RoleしてTerraformを実行する方法

方法1: AWS CLI 名前付きプロファイル(credential_process = aws configure export-credentials)

おそらく、一番手軽な方法です。

この方法は、通常のプロファイルとTerraform用のプロファイルを用意します。

通常のプロファイルから認証情報を取得して、Terraform用のプロファイルにセットします。

設定方法

以下の内容を~/.aws/configに記載します。

~/.aws/config

[profile myprofile]
output=json
region=ap-northeast-1
role_arn=arn:aws:iam::01234567890:role/<IAMロール名>
mfa_serial=arn:aws:iam::12345678901:mfa/<IAMユーザ名>

[profile myprofile-tf]
credential_process = aws configure export-credentials --profile myprofile

Terraform CLIは以下で実行できます。

$ export AWS_PROFILE="myprofile-tf"
$ terraform plan # MFA認証のコードが求められる

参考

方法2: AWS CLI 名前付きプロファイル + AWS認証情報管理/補助ツール(aws-valut,aws-mfa,aswrap等)

使い慣れたAWS認証情報管理/補助ツールがある場合は、この方法が手軽だと思います。

設定方法

aws-vaultを例に設定方法を紹介します。

aws-vaultをインストールし、セットアップします。

その後、以下の内容を~/.aws/configに記載します。

~/.aws/config

[profile default]
mfa_serial=arn:aws:iam::12345678901:mfa/<IAMユーザー名>
output=json
region=ap-northeast-1

[profile common]
credential_process=aws-vault --prompt terminal export default --duration 12h --format=json

[myprofile]
source_profile=common
role_arn=arn:aws:iam::01234567890:role/<IAMロール名>
role_session_name=terraform
region=ap-northeast-1
output=json

Terraform CLIは以下で実行できます。

$ export AWS_PROFILE="myprofile"
$ terraform plan
# 以下の方法も可能
$ aws-vault exec myprofile -- terraform plan

参考

方法3:AWS CLIで一時的な認証情報を生成(aws sts assume-role)

AWS CLIで一時的な認証情報を取得することが可能です。

コマンドが長くなりがちなため、スクリプトを用意することをおすすめします。 (具体的なスクリプトは、「参考」をご確認ください。)

スクリプト次第ですが、.aws/configの記述量を少なくできます。

設定方法

~/.aws/config

[profile default]
output=json
region=ap-northeast-1
$ aws sts assume-role \
  --role-arn          arn:aws:iam::01234567890:role/<IAMロール名> \
  --role-session-name terraform \
  --duration-second   900 \
  --profile           default \
  --serial-number     arn:aws:iam::12345678901:mfa/<IAMユーザー名> \ # MFAデバイスのARN
  --token-code        123456 # MFAで発行されるトークン
# AWS認証情報が出力される
$ export AWS_ACCESS_KEY_ID=<AWSアクセスキーID>
$ export AWS_SECRET_ACCESS_KEY=<AWSシークレットアクセスキー>
$ export AWS_SESSION_TOKEN=<AWSセッショントークン>
$ terraform plan

参考

番外編: AWS IAM Identity Center

IAMユーザーを使わないパターンですが、番外編でAWS IAM Identity Centerを使うパターンです。

~/.aws/config

[sso-session my-sso]
sso_region = ap-northeast-1
sso_start_url = https://d-XXXXXXXX.awsapps.com/start/#

[profile my-profile]
sso_session = my-sso
sso_account_id = 1234567890
sso_role_name = AdministratorAccess
$ aws sso login --sso-session my-sso
$ export AWS_PROFILE="my-profile"
$ terraform plan

aws sso loginのタイミングでMFA認証が行われます。

MFA認証問題のために、上記で紹介した対策を取らなくていいですし、~/.aws/configの記述量も少ないです。

Organizationsを利用していてアカウント数も多い場合は、IAM Identity Center導入もご検討ください。

おわりに

Terraformとタイトルにつけていますが、MFAトークンの対話型認証に対応していないツール全般で使えるはずです。

MFA認証が有効な環境でAssume Roleする際に困っている方の助けになれば幸いです。

以上、AWS事業本部の佐藤(@chari7311)でした。