Terraform を使って AWS Organizations 管理外の複数アカウントの IAM ロールを作成・運用する

はじめに
AWS には複数のアカウントを一括管理するための AWS Organizations 等のサービスがありますが、自身の組織外のアカウントなど、AWS Organizations での管理が難しいアカウントを利用していることもあります。
そのようなアカウントが複数ある中で、共通する IAM ロールの権限やポリシーを一括で作成・管理しなければならない場合、各アカウントに個別でログインして作成を行うと時間がかかったり、設定に不備が生じたりすることがあります。
そこで今回は AWS Organizations 等で管理されていない複数のアカウントを対象に、IAM ロールを例として IaC ツールである Terraform で一括作成・運用を行う方法をご紹介します。
下記は簡単なイメージ図です。

対象アカウントの config 設定と Terraform の初期設定
まず Terraform の実行環境で、作業対象の各アカウントにログインできるよう設定を行います。
対象アカウントの数だけ、AWS の config ファイルにプロファイルを設定します。
以下は SSO を利用したプロファイルの設定例です。
IAM ユーザーや IAM ロールを使用している場合は、適宜設定してください。
プロファイル 設定例
[profile AAAA] sso_start_url = https://****************.awsapps.com/start/# sso_region = XX-XXXXXXXX-X sso_account_id = XXXXXXXXXXX sso_role_name = XXXXXXXXXXXXXXX region = XX-XXXXXXXX-X [profile BBBB] sso_start_url = https://****************.awsapps.com/start/# sso_region = XX-XXXXXXXX-X sso_account_id = XXXXXXXXXXX sso_role_name = XXXXXXXXXXXXXXX region = XX-XXXXXXXX-X
Terraform を使った方法となるため、実行環境に Terraform がインストールされている必要があります。
まだインストールされていない場合は、事前に Terraform をインストールして実行環境を整えてください。
今回は IAM ロール作成をメインに記載するため、Terraform のインストール、設定手順は割愛します。
provider の設定
この記事では、全てのアカウントで同一の権限を持つ場合の設定例を記載します。
また、初回設定だけでなく後からアカウントを追加することも想定し、IAM ロールの設定をモジュール化して各アカウントに適用する構成とします。
Terraform フォルダー構成
terraform
├ provider.tf … 各アカウントのプロバイダー設定ファイル
├ iam_module.tf … IAM ロール作成モジュール呼び出しファイル
└ modules
└ ope_role
└ main.tf … IAM ロール作成モジュールファイル
AWS の config 設定と Terraform の実行環境を整えたら、Terraform の provider 設定コードを作成します。
provider は各アカウント分を用意する必要があるため、先ほど設定した config の数だけ provider 設定を provider.tf に記載します。
それぞれの設定では、使用するプロバイダーを識別する alias、Terraform の操作先リージョン、対象アカウント ID、使用するプロファイルを指定します。
provider.tf
provider "aws" {
alias = "AAAA_alias"
region = "XX-XXXXXXXX-X"
allowed_account_ids = ["XXXXXXXXXXX"]
profile = "AAAA"
}
provider "aws" {
alias = "BBBB_alias"
region = "XX-XXXXXXXX-X"
allowed_account_ids = ["XXXXXXXXXXX"]
profile = "BBBB"
}
IAM ロールモジュールの作成
provider.tf に provider を記載したら、次はモジュールとなる IAM ロールの設定を作成します。
modules/ope_role/ ディレクトリを作成し、その配下に main.tf を作成します。
main.tf には、各アカウントに作成する IAM ロールの設定コードを記載します。
main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
resource "aws_iam_role" "iam_test_role" {
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::XXXXXXXXXXXXXX:root"
}
Action = "sts:AssumeRole"
}]
})
force_detach_policies = false
max_session_duration = 3600
name = "IAM_Test_Role"
path = "/"
tags = {}
}
resource "aws_iam_role_policy_attachment" "test_role_EC2ReadOnlyAccess" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
role = aws_iam_role.iam_test_role.name
}
resource "aws_iam_role_policy_attachment" "test_role_S3ReadOnlyAccess" {
policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
role = aws_iam_role.iam_test_role.name
}
上記はサンプルの IAM ロールと、そのロールへのポリシーアタッチを定義したコードです。
Principalについてはログイン元の情報を記載しますので、必要なログイン元情報を設定します。
信頼ポリシーには Principal としてスイッチ元の AWS アカウントを設定しており、AWS 管理ポリシーの AmazonEC2ReadOnlyAccess・AmazonS3ReadOnlyAccess の 2 つを作成したロールにアタッチしていますが、こちらは必要なIAM ロールの設定を記述してください。
尚、モジュールの呼び出しについては後述のモジュール呼び出しで設定を行いますが、基本的にモジュールフォルダ内のtfファイルを全て読み込みます。
そのため今回はmain.tfにIAM ロールとアタッチの設定を同じファイルに記載していますが、ファイルを分けて記述することも可能です。
モジュール呼び出しファイルの作成
provider 設定ファイルと IAM ロールモジュールを作成したら、各 provider がモジュールを呼び出す iam_module.tf を作成します。
iam_module.tf
module "ope_role_AAAA" {
source = "./modules/ope_role"
providers = {
aws = aws.AAAA_alias
}
}
module "ope_role_BBBB" {
source = "./modules/ope_role"
providers = {
aws = aws.BBBB_alias
}
}
source にはモジュールのディレクトリパスを指定します。ディレクトリを指定した場合、配下のすべての .tf ファイルが読み込まれます。
今回の例では main.tf のみに全ての設定を記載していますが、IAM ロールへのポリシーアタッチ設定を別途管理したい場合は、ファイルを分割して設定することも可能です。
providers ブロックには、操作対象の AWS アカウントを示すために aws キーと、対応する provider の alias を指定します。
Terraform の初期化と実行
3 つのファイルを作成したら、モジュールを読み込ませるために terraform init を実行して初期化します。
初期化が完了したら terraform plan を実行してエラーの有無と実行内容を確認し、問題がなければ terraform apply を実行して IAM ロールを作成します。
作成以降の管理について
本作業で作成した IAM ロールは、Terraform による IaC 管理が可能です。そのため、全アカウントに構築された IAM ロールの設定変更やポリシーのアタッチ・デタッチについても、Terraform コードを変更するだけで一括で反映できます。
またモジュールによる管理のため、新規アカウントを追加する場合は以下の 3 つの作業を行うだけで、同じ IAM ロール設定を展開できます。
- config へのプロファイル追加
provider.tfへの provider 追加iam_module.tfへのモジュール呼び出し追加
既存のロールを管理する場合やアカウントごとに設定を変える場合
今回は新規 IAM ロールの作成例を紹介しましたが、すでにアカウントに IAM ロールが存在しており Terraform で管理したい場合は、import ブロックを使うことで Terraform 管理下に取り込むことができます。
import
import {
provider = aws.CCCC_alias
to = aws_iam_role.cccc_account_role
id = "CCCC_Account_Role"
}
import {
provider = aws.CCCC_alias
to = aws_iam_role_policy_attachment.cccc_ec2readonly
id = "CCCC_Account_Role/arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
}
追加アカウント「CCCC」の config と provider を追加した後、上記のように作成済みの IAM ロールとアタッチ済みポリシーを import することで、既存の IAM ロールを Terraform で管理できるようになります。
ただし、この方法ではモジュールでの管理ではなく個別管理となります。
共通モジュールで管理したい場合は、モジュール呼び出しまで設定した状態で以下のように記述することで、同じモジュールでの管理が可能です。
import(モジュールに追加)
module "ope_role_CCCC" {
source = "./modules/ope_role"
providers = {
aws = aws.CCCC_alias
}
}
import {
to = module.ope_role_CCCC.aws_iam_role.iam_test_role
id = "CCCC_Account_Role"
}
ただし、既存リソースの設定がモジュールの定義と異なる場合は差分が発生するため、
差分をモジュールに合わせて反映するか、個別に修正する必要があります。
まとめ
このように、AWS Organizations で管理されていない複数の AWS アカウントに対しても、Terraform を活用することで共通のIAM ロールを一括で作成・管理することが可能です。
一方で複数アカウントへ同時にリソースを操作できるということは、万が一トラブルが発生した際の影響範囲も大きくなります。
実行元アカウントの運用や terraform plan による事前確認を徹底するなど、慎重な運用を心がけてください。
Recommends
こちらもおすすめ
-
Oracle を BYOL で使う時の AWS 仮想コアの話
2015.7.15
Special Topics
注目記事はこちら
データ分析入門
これから始めるBigQuery基礎知識
2024.02.28

AWSの料金が 10 %割引になる!
『AWSの請求代行リセールサービス』
2024.07.16