LoginSignup
8
5

More than 3 years have passed since last update.

terraform: AWS provider や s3 backend の設定に role の arn をハードコードせずに switch role や MFA 環境で実行する方法

Last updated at Posted at 2020-08-04

概要

terraform を MFA 認証有の IAM ユーザ権限で switch role しつつ実行するのに手間どったので、対応方法を記載しておきます。
実行時に使用する switch role 先の arn を aws provider や s3 backend 設定にハードコードすると簡単にできるらしいのですが、role は環境(開発/テスト/本番)依存するものなので、ハードコードしたくないですよね。

同じようなことで困っている人は世の中にそこそこいて、関連する issue がいくつか挙がっています。
その中で、terraform の開発者っぽい人が、"terraform は自動実行を意識しているので、MFA の one time password を interactive に入力するとか対応しねーんだよ!" と言っているコメントがあったので、それをヒントに workaround を調査しました。

MFA および switch role 環境の場合

事前の設定

~/.aws/config, credentials ファイルは通常通り設定済みとします。# mfa の記述をしないのがポイント

ポイントは以下です。

  • source profile のアカウントへのログインには MFA が必要
  • target profile のとこに MFA の設定は記述しない
~/.aws/config
[profile source]
output = json
region = ap-northeast-1

[profile target]
role_arn = <arn of role to switch>
source_profile = source
region = ap-northeast-1
# mfa の設定は記述しない
~/.aws/credentials
[source]
aws_access_key_id = <your access key id>
aws_secret_access_key = <your secret key>

jq コマンドをダウンロードして、path を通しておきます。

terraform 実行前に実行すること

ポイントは IAM 認証時に発行される session token を事前に取得して設定しておくことです。

コマンド
# 環境変数をクリアする。環境変数に認証情報が残っていると aws cli, sdk に(意図せずに)参照されてしまう。
unset AWS_SHARED_CREDENTIALS_FILE
unset AWS_ACCESS_KEY_ID
unset AWS_SECRET_ACCESS_KEY
unset AWS_SESSION_TOKEN
# token を取得する
export AWS_PROFILE=source # changeme
aws sts get-session-token --serial-number <your mfa device serial number> --token-code <one time code> > tmp.token
aws_access_key_id=`cat tmp.token| jq -r ".Credentials.AccessKeyId"`
aws_secret_access_key=`cat tmp.token| jq -r ".Credentials.SecretAccessKey"`
aws_session_token=`cat tmp.token| jq -r ".Credentials.SessionToken"`
# .aws/credentials ファイルとは別に credentials ファイルを作成し、terraform 実行時に参照する。
export AWS_SHARED_CREDENTIALS_FILE=tmp.credentials # 参照する credentials ファイルを変更する。
cat << EOF > $AWS_SHARED_CREDENTIALS_FILE
[source]
aws_session_token=$aws_session_token
aws_secret_access_key=$aws_secret_access_key
aws_access_key_id=$aws_access_key_id
EOF
export AWS_SDK_LOAD_CONFIG=1 # terraform AWS provider v3.0.0 以降は default 設定なので指定不要っぽい
export AWS_PROFILE=target # changeme

後は、通常通り terraform を実行できます。
AWS_SHARED_CREDENTIALS_FILE=tmp.credentials にて、session token が記載された credential ファイルを参照するようにしています。

MFA のない switch role 環境の場合

事前の設定

~/.aws/config, credentials ファイルは通常通り設定済みとします。

terraform 実行前に実行すること

コマンド
export AWS_SDK_LOAD_CONFIG=1 # terraform AWS provider v3.0.0 以降は default 設定なので指定不要っぽい
export AWS_PROFILE=target # changeme

後は、通常通り terraform を実行できます。

参考: 私が上記設定を試した terraform の構成

backend には s3 を用いています。

terraform.tf
terraform {
  required_version = ">= 0.12.26"
  backend "s3" {}
}

# Configure the AWS Provider
provider "aws" {
  version = ">= 2.62.0"
  region  = "ap-northeast-1"
}

backend.hcl は環境別に用意しています。

env/dev/backend.hcl
bucket   = <dev 用の bucket 名>
key      = "sample_terraform.tfstate"
region   = "ap-northeast-1"
encrypt  = true

terraform 実行コマンドは以下です。

terraform実行コマンド
ENV="dev"
export TF_DATA_DIR=./.terraform/$ENV
terraform init -backend-config=env/${ENV}/backend.hcl
terraform apply -var="env=${ENV}"

まとめ

こういうどーでもいいことで時間を使いたくないものですよね。
誰かのお役に立てばと思います。

もっと elegant な方法をご存知の方は教えてください。

8
5
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
8
5