MFA認証が有効な環境でAssume RoleしてTerraform実行する方法をまとめてみた[AWS]
TerraformのAWS Providerは現時点(2024/4時点)で、MFAトークンの対話型認証はサポートされていません。
IAMユーザーでMFA認証が有効になっている環境では、IAMロールを引き受けるAWS CLIの名前付きプロファイルを指定して、Terraformを実行するとエラーになってしまいます。
[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
に記載します。
[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
に記載します。
[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
の記述量を少なくできます。
設定方法
[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を使うパターンです。
[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)でした。