AssumeRoleを使用したTerraformのセキュアなプロビジョニングを試す
これからやること
↑の「S3とか」をTerraformで構築するところまで試します。
用意するもの
- 以下をインストール済みのWSL2
- AWS CLI(v2以降)
- aws-vault(v6以降)
- Terraform(v0.15以降)
- 以下の名前のようなAWSアカウントを2つ(Control TowerとかOrganizationsとかで用意)
- assume-role
- target1
user
部分を各人の名前に読み替える)
1. 「assume_role_user」を作成 (これ以降、
↑の赤枠部分が対象です。
①. 「assume-role」アカウントのIAMユーザー作成画面にアクセス
IAMユーザーを作成可能な権限で「assume-role」アカウントにログイン(AWS SSOなどで)。IAMユーザーの管理画面でユーザー追加ボタンをクリックします。
②. IAMユーザーの基本設定
以下のような設定にします。
- ユーザー名:assume_role_user
- AWS認証情報タイプを選択:アクセスキー
③. IAMユーザーのアクセス権限
「既存のポリシーを直接アタッチ」をクリックし、ポリシー作成ボタンをクリックします。
以下のようなJSON、名前は「assume_role」でポリシーを作成します。(タグや説明はお好みで追加)
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "*"
}
}
IAMユーザーのアクセス権限設定の画面に戻り、更新ボタンを押して先ほど作成したポリシーを選択します。
④. IAMユーザーを作成しクレデンシャル情報を取得
タグなどはお好みで追加しIAMユーザーを作成します。
その後表示された画面で「assume_role_user」のクレデンシャル情報が記載されたcsvファイルをダウンロードしておきます。
⑤. MFAを有効化
IAMユーザーの管理画面で「assume_role_user」のMFAを有効化します。
名前は「user」で作成し、作成後に発行されるシリアル番号をメモしておきます。
2. 「assume_role_target1」を作成
↑の赤枠部分が対象です。
①. 「target」アカウントのIAMロール作成画面にアクセス
IAMロールを作成可能な権限で「target」アカウントにログイン(AWS SSOなどで)。IAMロールの管理画面でロール作成ボタンをクリックします。
②. IAMロールのカスタム信頼ポリシー
信頼されたエンティティは「カスタム信頼ポリシー」を選択し、以下のような設定にします。
以下が設定の詳細についてです。
- 「1. Add actions for STS」では以下のアクションを追加
- TagSession
- SetSourceIdentity
- 「2. プリンシパルを追加する」では以下を設定
- プリンシパルタイプ:IAM users
- ARN
- {Account}:「assume-role」アカウントのアカウント番号
- {UserName}:assume_role_user
- 「3. 条件を追加する (オプション)」では以下を設定
- 条件キー:aws:MultiFactorAuthPresent
- 修飾子:デフォルト
- 演算子:Bool
- 値:true
③. IAMロールの許可ポリシー
ここでTerraformで扱いたいリソースの許可ポリシーを選択します。今回は試しにS3バケットを構築するので、「AmazonS3FullAccess」を選択します。
④. IAMロールを作成しARNを取得
名前は「assume_role_target1」でIAMロールを作成します。(タグや説明はお好みで追加)
その後、IAMロールの管理画面で「assume_role_target1」のARNをメモしておきます。
3. AssumeRoleを使用したTerraformでS3バケットをプロビジョニング
↑の赤枠部分が対象です。
①. 「assume-role-user」プロファイルを設定
ローカルPCに戻り
aws-vault add assume-role-user
といったコマンドで「assume-role-user」プロファイルを設定します。
(aws-vault
の詳しい使い方についてはこちら)
クレデンシャル情報は1-④でダウンロードした「assume_role_user」のcsvファイルを参照し設定します。
~/.aws/config
に設定を追記
②. 以下コマンドの2項目を読み替えて実行し、~/.aws/config
に設定を追記します。
- {MfaSerialNumber}:1-⑤でメモしたMFAのシリアル番号
- {AssumeRoleArn}:2-④でメモした「assume_role_target1」のARN
cat << 'EOS' >> ~/.aws/config
[profile common]
source_profile = assume-role-user
region=ap-northeast-1
output=json
mfa_serial={MfaSerialNumber}
role_session_name=user
[profile assume-role-target1]
include_profile=common
role_arn={AssumeRoleArn}
EOS
③. 「assume-role-target1」プロファイルを使用してセッションを確立する
以下コマンドを実行することで「assume-role-target1」プロファイルを使用したセッションを確立することが可能です。コマンド実行の際にはMFAコードの入力が求められます。1-⑤で設定したMFAデバイスを使用し、MFAコード入力してセッションを確立します。
aws-vault exec assume-role-target1
④. 「target」アカウントにS3バケットをプロビジョニングする
例えば以下のようなTerraformのコードを用意します。
terraform {
required_version = "1.3.6"
required_providers {
aws = {
source = "hashicorp/aws"
version = "4.46.0"
}
}
}
provider "aws" {
region = "ap-northeast-1"
default_tags {
tags = {
Name = "example"
}
}
}
### ==================================================
resource "aws_s3_bucket" "assume-role-target1-example" {
bucket = "assume-role-target1-example"
force_destroy = true
}
あとはS3バケット名が既に使用されているものでなければ、terraform apply
でプロビジョニングが実行可能となります。「target」アカウントにS3バケットが作成されているのを確認したらterraform destroy
でS3バケットを削除するのを忘れないようにします。
さいごに
説明を少なくするためにIAMユーザーに直接ポリシーをアタッチしたりしましたが、実際にはIAMグループにポリシーをアタッチして、Terraformを扱う人用のユーザーをそのグループに追加していくみたいな運用がいいと思います。
また、~/.aws/config
に別のAWSアカウント用プロファイルを追加する際も「common」プロファイルを継承してrole_arn
だけ追記するみたいな設定でOKです。
個人的に今まで後回しにしていたAssumeRole運用の理解が出来てよかったです。これから本当にやりたかったTerragruntの導入に着手していこうと思います。
参考URL
Discussion