tfenv+aws-vault+direnv を組み合わせて Windows 上に Terraform の実行環境を構築する
概要
記事一覧はこちらです。
Windows 上に Terraform の実行環境を構築します。access key ID, secret access key は環境変数やテキストファイルに平文で設定・記述するのではなく Windows の資格情報マネージャーに登録します。また MFA を利用していなければ実行できないようにします。
- Terraform は exe を直接ダウンロードするのではなく tfenv を利用してインストールします。
- aws-vault を利用して access key ID, secret access key を Windows の資格情報マネージャーに登録します。
- access key ID, secret access key を発行する IAM ユーザには ReadOnlyAccess ポリシーだけ付与します。
- AdministratorAccess ポリシーを付与した IAM ロールを作成し、terraform 実行時にスイッチロールします。
- IAM ロールへスイッチロールできる IAM ユーザは IAM ポリシーで制限します。また MFA を利用していなければスイッチロールできないようにします。
- direnv をインストールして、ディレクトリ毎に実行する access key ID, secret access key(実際にはプロファイル)を切り替えられるようにします。
またタイトルには記述していませんが Git for Windows をインストールして git-cmd.exe+bash.exe が起動できることが前提です(tfenv のページに Windows (64bit) - only tested in git-bash - currently presumed failing due to symlink issues in git-bash
という記述があります)。この記事では git-cmd.exe+bash.exe を D:\git\git-cmd.exe --command=usr/bin/bash.exe -l -i
コマンドで起動しています。
参照したサイト・書籍
Terraform
https://www.terraform.io/tfutils/tfenv
https://github.com/tfutils/tfenv99designs/aws-vault
https://github.com/99designs/aws-vaultdirenv/direnv
https://github.com/direnv/direnvMFA 保護 API アクセスの設定
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_configure-api-require.html
目次
- tfenv と terraform をインストールする
- IAM ユーザと IAM ロールを作成する
- aws-vault をインストールして Windows の資格情報マネージャーに access key ID, secret access key を登録する
C:\Users\<ユーザ名>\.aws\config
に設定を追加する- direnv をインストールする
C:\Users\<ユーザ名>\.bashrc
に設定を追加する- ディレクトリに移動したら terraform 実行時に使用する aws の profile を自動で切り替えるよう設定する
- Windows の資格情報マネージャーに保存した access key ID, secret access key は
--no-session
オプション付きで aws-vault を実行すれば取得できる
手順
tfenv と terraform をインストールする
tfutils/tfenv の Releases ページ(https://github.com/tfutils/tfenv/releases)から Latest release のラベルが付いている v1.0.2 の「Source code(zip)」のリンクをクリックして tfenv-1.0.2.zip をダウンロードします。
ダウンロードが完了したら tfenv-1.0.2.zip を解凍し、フォルダ名を tfenv に変更後 D:\
の下に移動します。
環境変数 Path に D:\tfenv\bin\
を追加した後、git-cmd.exe+bash.exe を起動して tfenv
コマンドが実行できることを確認します。
以下のコマンドを実行して、terraform の最新バージョンを確認してからインストールします。
tfenv list-remote | head
tfenv install 0.12.19
tfenv list
terraform -version
コマンドを実行すると 0.12.19
が表示されます。
起動した git-cmd.exe+bash.exe を終了します。
IAM ユーザと IAM ロールを作成する
一時作業用の AdministratorAccess ポリシーを付与した IAM ユーザを作成して、access key ID, secret access key を発行します。
IAM ユーザと IAM ロールの作成には terraform を利用します。作業用に D:\work\
ディレクトリを新規作成します。その下に main.cf というファイルを新規作成して、以下の内容を記述します。
terraform { required_version = "0.12.19" } provider "aws" { region = "ap-northeast-1" } /////////////////////////////////////////////////////////////////////////////// // ReadOnlyUser // resource "aws_iam_user" "ReadOnlyUser" { name = "ReadOnlyUser" // MFAデバイスを登録していると削除できないので forace_destroy を true にしている force_destroy = true } resource "aws_iam_user_policy_attachment" "AttachReadOnlyAccessToReadOnlyUser" { user = aws_iam_user.ReadOnlyUser.name policy_arn = "arn:aws:iam::aws:policy/ReadOnlyAccess" } /////////////////////////////////////////////////////////////////////////////// // AdminRole // data "aws_iam_policy_document" "SwitchAdminRolePolicy" { statement { effect = "Allow" actions = ["sts:AssumeRole"] principals { type = "AWS" identifiers = [aws_iam_user.ReadOnlyUser.arn] } condition { test = "Bool" variable = "aws:MultiFactorAuthPresent" values = [true] } } } resource "aws_iam_role" "AdminRole" { name = "AdminRole" assume_role_policy = data.aws_iam_policy_document.SwitchAdminRolePolicy.json } resource "aws_iam_role_policy_attachment" "AdminRole" { role = aws_iam_role.AdminRole.name policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess" }
git-cmd.exe+bash.exe を起動した後、カレントディレクトリを D:\work\
に変更してから環境変数 AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY に AdministratorAccess ポリシーを付与した一時作業用の IAM ユーザの access key ID, secret access key を設定します。
terraform init
コマンドを実行してから、
terraform plan
→ terraform apply
コマンドを実行して IAM ユーザ(ReadOnlyUser)、IAM ロール(AdminRole)を作成します(画面キャプチャは terraform apply
の一部のみ)。
AWS マネジメントコンソールから一時作業用の IAM ユーザでサインインし、作成した IAM ユーザ(ReadOnlyUser)の「コンソールへのアクセスの有効化」「MFA デバイスの割り当て」「アクセスキーの作成」を行います(詳細な手順は省略します)。
MFA の ARN、access key ID, secret access key は後の設定で使用するのでメモしておきます。
作成した IAM ロール(AdminRole)のロール ARN も後の設定で使用するのでメモしておきます。
起動した git-cmd.exe+bash.exe を終了します。
一時作業用の IAM ユーザの access key ID, secret access key は削除します。一時作業用の IAM ユーザも不要なら削除します。
aws-vault をインストールして Windows の資格情報マネージャーに access key ID, secret access key を登録する
99designs/aws-vault の Releases ページ(https://github.com/99designs/aws-vault/releases)から Latest release のラベルが付いている v5.1.2 の「aws-vault-windows-386.exe」のリンクをクリックして aws-vault-windows-386.exe をダウンロードします。
D:\
の直下に aws-vault ディレクトリを作成し、ダウンロードした aws-vault-windows-386.exe を移動して aws-vault.exe にリネームします。
環境変数 Path に D:\aws-vault\
を追加した後、git-cmd.exe+bash.exe を起動して aws-vault
コマンドが実行できることを確認します。
aws-vault add ReadOnlyUser
コマンドを実行して IAM ユーザ(ReadOnlyUser)の access key ID, secret access key を Windows の資格情報マネージャーに登録します。
登録すると「資格情報マネージャー」の「Windows 資格情報」-「汎用資格情報」に aws-vault:aws-vault:ReadOnlyUser
が追加されます。
起動した git-cmd.exe+bash.exe を終了します。
C:\Users\<ユーザ名>\.aws\config
に設定を追加する
C:\Users\<ユーザ名>\.aws\config
をエディタで開いて aws-vault の Roles and MFA の記述を参考に設定を追加します。
[default] output=json region=ap-northeast-1 [profile ReadOnlyUser] mfa_serial = arn:aws:iam::123456789012:mfa/ReadOnlyUser [profile AdminRole] source_profile = ReadOnlyUser role_arn = arn:aws:iam::999999999999:role/AdminRole mfa_serial = arn:aws:iam::123456789012:mfa/ReadOnlyUser
aws-vault add ReadOnlyUser
コマンドを実行した時に[profile readonlyuser]
が追加されているので、readonlyuser
→ReadOnlyUser
に変更した後(IAM ユーザが大文字小文字を区別しないと知ったのはこのページを書いた後でした。。。)mfa_serial = ...
の行を追加します。[profile AdminRole]
の設定を追加します。mfa_serial = ...
はどちらにも ReadOnlyUser の MFA の ARN を記述します。
一旦ここで動作確認します。git-cmd.exe+bash.exe を起動してから aws-vault exec AdminRole -- aws s3 mb s3://<何か適当なBucket名>
を実行して S3 Bucket を作成してみます。
初回の実行時には MFA の token が求められますので MFA デバイスで確認して入力します。この時 temporary security credentials が取得されますので2回目以降のコマンド実行では token の入力は求められません。temporary security credentials の有効期限はデフォルトで 1時間です(一時的なセキュリティ認証情報のリクエスト に記載があります)。
取得された temporary security credentials も Windows の資格情報マネージャーに登録されます。
有効期限が切れるか、これを削除すると再び MFA の token が求められます。
temporary security credentials を Windows の資格情報マネージャーに保存したくない場合(コマンド実行時に都度 MFA の token を求めるようにしたい場合)には、--no-session
オプションを追加して aws-vault exec AdminRole --no-session -- aws s3 mb s3://<何か適当なBucket名>
のようにコマンドを実行します。
作成した S3 Bucket は削除します。
起動した git-cmd.exe+bash.exe を終了します。
direnv をインストールする
direnv/direnv の Releases ページ(https://github.com/direnv/direnv/releases)から Latest release のラベルが付いている v2.20.0 の「direnv.windows-amd64.exe」のリンクをクリックして direnv.windows-amd64.exe をダウンロードします。
D:\
の直下に direnv ディレクトリを作成し、ダウンロードした direnv.windows-amd64.exe を移動します(リネームはしません)。
C:\Users\<ユーザ名>\.bashrc
に設定を追加する
C:\Users\<ユーザ名>\.bashrc
をエディタで開いて設定を追加します。
# for direnv alias direnv="/d/direnv/direnv.windows-amd64.exe" _direnv_hook() { local previous_exit_status=$?; eval "$(MSYS_NO_PATHCONV=1 direnv export bash | sed 's|export PATH=|export _X_DIRENV_PATH=|g')"; if [ -n "$_X_DIRENV_PATH" ]; then _X_DIRENV_PATH=$(cygpath -p "$_X_DIRENV_PATH") export "PATH=$_X_DIRENV_PATH" unset _X_DIRENV_PATH fi return $previous_exit_status; }; if ! [[ "$PROMPT_COMMAND" =~ _direnv_hook ]]; then PROMPT_COMMAND="_direnv_hook;$PROMPT_COMMAND" fi # for aws-vault+terraform tf() { aws-vault exec $AWS_PROFILE -- bash -c "terraform $@" }
alias direnv="/d/direnv/direnv.windows-amd64.exe"
を追加します。_direnv_hook() { ... }
とif ! [[ "$PROMPT_COMMAND" =~ _direnv_hook ]]; then ... fi
を追加します。Setup に記載されている BASH 用のeval "$(direnv hook bash)"
の設定だと git-cmd.exe+bash.exe の環境で direnv のPATH_add
が実行された時にパスが正しく設定されないので、PATH gets mangled when using direnv from git-bash on Windows に記載されていたコードを設定しています。- aws-vault+terraform の実行用に
tf() { ... }
を追加します。環境変数 AWS_PROFILE に使用するプロファイルを設定してから、terraform apply
ならばtf apply
のようにterraform
→tf
に変更したコマンドを実行します。bash -c "terraform $@"
は aws-vault exec can not successfully run with eval を参考にしました。また動作確認等で素の terraform コマンドを使う分けたりする必要性を感じなければ、関数名をtf()
→terraform()
に変えても構いません。その場合 terraform コマンドを実行するとこの関数が実行されるようになります。
ディレクトリに移動したら terraform 実行時に使用する aws の profile を自動で切り替えるよう設定する
D:\work2\
を作成し、その下に .envrc と main.cf を作成して VPC を1つ作成してみます。
D:\work2\
を作成してから git-cmd.exe+bash.exe を起動してカレントディレクトリを D:\work2\
に変更します。touch .envrc
コマンドを実行して .envrc を作成してから、
以下の内容を記述します。
export AWS_PROFILE=AdminRole
main.tf を作成し、以下の内容を記述します。
terraform { required_version = "0.12.19" } provider "aws" { region = "ap-northeast-1" } resource "aws_vpc" "sample-vpc" { cidr_block = "10.0.0.0/16" enable_dns_hostnames = true tags = { Name = "sample-vpc" } }
direnv allow
コマンドを実行します。
tf init
コマンドを実行してから、
tf plan
→ tf apply
コマンドを実行すると VPC が作成されました。
tf destroy
コマンドを実行して作成した VPC を削除します。
.envrc を以下の内容に変更すると、
export AWS_PROFILE=ReadOnlyUser
tf apply
コマンドを実行してもエラーとなり VPC は作成できません。
Windows の資格情報マネージャーに保存した access key ID, secret access key は --no-session
オプション付きで aws-vault を実行すれば取得できる
Windows の資格情報マネージャーに保存された access key ID, secret access key を後から取得することはできないのか調べたところ、aws-vault exec ReadOnlyUser --no-session -- env | grep ^AWS
コマンドを実行すれば取得できます。
下の画像の例では、temporary security credentials ではなく ReadOnlyUser の access key ID, secret access key が表示されています。
IAM ユーザには極力権限を付与せず(ReadOnlyAccess ポリシーも外してよいかもしれません)、強い権限はスイッチロール先の IAM ロールに与える(MFA も有効にする)方が良さそうです。
履歴
2020/01/19
初版発行。