SMARTCAMP Engineer Blog

スマートキャンプ株式会社(SMARTCAMP Co., Ltd.)のエンジニアブログです。業務で取り入れた新しい技術や試行錯誤を知見として共有していきます。

TerraformをMFA & Assume Roleな環境でも実行 - aws-vaultでやってみた

f:id:yuma124:20190313095704p:plain

Terraform 0.12がbetaになりワクワクしていたら、それより前にTerraformのAWS Providerの2.0.0がリリースされていたことに気づいて焦る笹原です。

いきなりですが、AWSを使う際に、多要素認証(MFA)をかけるのは必須ですよね!

また、IAM UserとしてログインするAWSアカウントから、Assume Roleして実際に作業するAWSアカウントに入ることも多くなっていると思います。

そういった環境だと、Assume RoleをするのにMFAを必須にすることもあると思います。

今回はそんなMFAをした上でAssume Roleする必要があるAWSアカウントでもTerraformを実行するために、aws-vaultを使った話をしようと思います!

背景

MFAをした上でAssume Roleする必要があるAWSアカウントでTerraformを実行することはTerraform上ではサポートされていません。

公式のドキュメントでMFAについて書いてあるものの、非推奨なTerraform Enterprise (Legacy)の機能です。

AWS Multi-Factor Authentication - Runs - Terraform Enterprise (legacy) - Terraform by HashiCorp

また、AWS ProviderのIssueもOpenなまま議論されており、Providerに対してインタラクティブな認証を提供する予定はないと言われています。

Doesn't ask MFA token code when using assume_role with MFA required · Issue #2420 · terraform-providers/terraform-provider-aws · GitHub

Issueの中で、MFA & Assume Roleな環境でTerraformを実行する方法が何個か紹介されています。

基本的には、AWS STSを利用してMFA & Assume Roleな環境への一時的なクレデンシャルを取得することになります。

そのうち、aws-vaultを使う方法が使いやすいなと感じたので紹介します!

aws-vaultとは

aws-vaultはAWSのAccess Keysをセキュアに保管するためのツールです。

github.com

MacのKeychainなどOSが提供するセキュアなキーストアにAccess Key IDとSecret Access Keyを保存しておき、実際に利用するときには、一時的なクレデンシャルを取得した上でshellに渡してくれます。

一時的なクレデンシャルの取得はAWS STSを利用して行ってくれるのですが、MFAやAssume Roleにも対応してくれています!

aws-vaultとTerraform

認証及びAssume Roleの手順を簡易的に図式化するとこんな感じです。

Access Keysの認証  ---->  MFAの認証  ---->  Assume Role

実際にMFA & Assume Roleな環境でaws-vaultとTerraformを利用するときに、それぞれの役割をどこまでにするかで2つ方法があります。

  • MFAまでをaws-vaultで、Assume RoleからはTerraformで行う
  • Assume Roleまで全てaws-vaultで行う

今回はAssume Roleまで全てをaws-vaultで行うようにしてみます。

aws-vaultの設定

まず、aws-vaultで一時的なクレデンシャルを取得できるようにしましょう

~/.aws/configはこんな感じになります。 defaultがIAM Userの存在するアカウント、mfaがMFA & Assume Roleで入ることになるアカウントです。

[default]
region=ap-northeast-1

[profile mfa]
region=ap-northeast-1
mfa_serial=arn:aws:iam::000000000001:mfa/sasahara
role_arn=arn:aws:iam::000000000002:role/Role
source_profile=default

aws-vaultを利用するので、 ~/.aws/credentials にAccess Keysを設定する必要はありません。

この状態でaws-vaultを使ってキーチェーンにAccess Keysを登録していきます。

$ aws-vault add default
Enter Access Key ID: AKXXXXXXXXXXXXXXXXXX
Enter Secret Access Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Added credentials to profile "default" in vault

これで、aws-vaultで一時的なクレデンシャルを取得する準備は整いました。

試しに、一時的なクレデンシャルを使ってawsコマンドを叩いてみましょう。

$ aws-vault exec mfa -- aws s3 ls
Enter token for arn:aws:iam::000000000001:mfa/sasahara: 000000
...

多要素認証のtokenの入力が求められるので入力すると、s3のバケット一覧が取得できますね!

Terraformの実行

TerraformのAWS Providerに関して必要な設定は以下です。

実行時の環境変数からクレデンシャル情報を取得するため、profileなどの指定は必要ありません。

provider "aws" {
  region = "${local.aws_region}"
  version = "~> 1.60.0"
}

実際に実行してみましょう。

$ aws-vault exec mfa -- terraform 
Enter token for arn:aws:iam::000000000001:mfa/sasahara: 000000

一時的なクレデンシャルの取得とshellへの受け渡しをaws-vaultがやってくれるので、簡単に実行できますね!

終わり

今回は、MFA & Assume Roleな環境でTerraformを実行することを目的としてaws-vaultを紹介しました。

aws-vaultはそれだけでなく、認証情報をセキュアに保管してくれるツールなので、Terraformを使わなくても入れて損はないと思います!