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のコメントにある通り、この方法の解決策はいくつかあります。
このブログでは各方法について説明します。
結論
主に以下の方法があります。
- AWS CLI 名前付きプロファイル
- AWS CLI 名前付きプロファイル + AWS認証情報管理/補助ツール
- 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)でした。