← 技術情報一覧へ戻る
技術解説

TerraformによるIAM一括管理 ─ ロール集約とポリシー設計の実践

  • AWS
  • IAM
  • Terraform
  • セキュリティ
  • IaC

プロジェクトで使用するIAMロール・ポリシー・ユーザー・グループをTerraformで一括管理する設計パターンを解説する。 マネージドポリシーとインラインポリシーの使い分け、AWSクォータを踏まえた設計判断を紹介する。

ページ構成

  1. IAM一括管理の動機と設計方針
  2. 管理対象
  3. ポリシー設計:マネージドポリシー vs インラインポリシーの使い分け
  4. IAMクォータ比較表
  5. IAMユーザー管理と認証情報の安全な格納
  6. まとめ

1. IAM一括管理の動機と設計方針

課題:IAMロールの散逸

プロジェクトが成長するにつれ、ECS、Lambda、CodeBuild、EC2など各サービスごとにIAMロールが必要になる。 これらを各リソース定義の近くに個別作成すると、以下の問題が生じる。

  • ロールの全体像が見えない: どのロールが存在し、何の権限を持つか把握しづらい
  • 命名規則の不統一: 作成者・タイミングによって命名がばらつく
  • 権限の重複・過剰付与: 似たポリシーが複数箇所で定義され、棚卸しが困難
  • 変更時の影響範囲が不明: ポリシー変更がどのサービスに影響するか追跡しにくい

設計方針:一箇所に集約

プロジェクトで使用するIAMロールを 一箇所のTerraformファイルに集約 する。

infrastructure/
└── environments/
    └── prod/
        └── iam.tf   ← 全ロールを宣言的に定義

これにより得られるメリット:

  • 一覧性: 1ファイルを見れば、環境内の全IAMロール・ポリシー・ユーザーが把握できる
  • 命名の統一: {prefix}-iam-{name}-{env} の命名規則を自動適用
  • レビューの容易さ: IAM変更は必ずこのファイルに集約されるため、PRレビューで権限変更を見落としにくい
  • 棚卸しの簡素化: Terraformのstateと宣言を突き合わせることで、不要ロールの検出が容易

2. 管理対象

一括管理の対象とするIAMリソースは以下の通り。

リソース種別説明
IAM Roleサービスロール(ECS, Lambda, EC2, CodeBuild等)
IAM Policyカスタムマネージドポリシー
IAM Role Policy Attachmentロールへのポリシーアタッチ
IAM Instance ProfileEC2用インスタンスプロファイル
IAM Userプログラマティック/コンソールユーザー
IAM Groupユーザーグループ

ロール定義では、AssumeRoleを許可するサービスを宣言的に指定する。

サービスAssumeRole Principal用途
ECS Taskecs-tasks.amazonaws.comECSタスク実行
Lambdalambda.amazonaws.comLambda関数実行
EC2ec2.amazonaws.comEC2インスタンス
CodeBuildcodebuild.amazonaws.comCodeBuildプロジェクト
EventBridgeevents.amazonaws.comEventBridgeルール
Schedulerscheduler.amazonaws.comEventBridge Scheduler

AWS以外のPrincipal(クロスアカウントのIAMロール等)からのAssumeRoleが必要な場合は、カスタムのAssumeRoleステートメントで柔軟に対応する。

3. ポリシー設計:マネージドポリシー vs インラインポリシーの使い分け

基本方針

一括管理で アタッチするポリシーは汎用的なものだけ に限定する。

具体的には以下の2種類のみ:

  1. AWSマネージドポリシー(例: AmazonECSTaskExecutionRolePolicy
  2. リソースが * のカスタムポリシー(例: logs:CreateLogGroup に対して resource = ["*"]

なぜ汎用ポリシーだけなのか

IAMの一括管理はインフラの初期構築フェーズで適用される。この時点では、具体的なリソースARN(S3バケット名、RDSクラスターARN等)がまだ確定していない場合がある。

そのため:

  • 汎用ポリシー → 一括管理で事前にアタッチ
  • 限定的なアクセス許可(特定ARNへのアクセス等) → リソース作成時にインラインポリシーで追加

インラインポリシーによる詳細権限の追加

リソースを作成するタイミングで、そのリソースへのアクセス権をインラインポリシーとしてロールに追加する。

# S3バケット作成時に、ECSタスクロールへのアクセス権をインラインポリシーで付与
resource "aws_iam_role_policy" "ecs_task_s3_access" {
  name = "s3-app-bucket-access"
  role = module.iam.iam_roles["ecs_task"].name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = ["s3:GetObject", "s3:PutObject"]
        Resource = ["${aws_s3_bucket.app.arn}/*"]
      }
    ]
  })
}

この方式のメリット:

  • マネージドポリシーアタッチ数の上限を回避: マネージドポリシーのアタッチ上限に縛られず、詳細な権限を追加できる
  • リソースとポリシーの近接性: 権限の定義がリソース定義の近くにあるため、「何のために」が明確
  • 最小権限の実現: 具体的なARNを指定できるため、resource = ["*"] を避けられる
  • ライフサイクルの一致: リソース削除時にインラインポリシーも自然に削除対象になる

4. IAMクォータ比較表

IAMロールに対するポリシーの上限値を以下に整理する。

項目デフォルト上限最大(引き上げ後)備考
マネージドポリシー(ロールあたり)1025Service Quotasから引き上げ申請可能
マネージドポリシー(ユーザーあたり)1020Service Quotasから引き上げ申請可能
マネージドポリシー(グループあたり)1010引き上げ不可
インラインポリシー(ロールあたり)個数上限なし-合計サイズ上限: 10,240文字
インラインポリシー(ユーザーあたり)個数上限なし-合計サイズ上限: 2,048文字
インラインポリシー(グループあたり)個数上限なし-合計サイズ上限: 5,120文字
カスタムマネージドポリシー(アカウントあたり)1,50010,000Service Quotasから引き上げ申請可能

インラインポリシーは個数の上限はないが、エンティティあたりの合計ポリシーサイズ(文字数)に上限がある。ホワイトスペースはカウントされない。

出典: IAM and AWS STS quotas - AWS Identity and Access Management

設計上のポイント

マネージドポリシーのアタッチ上限(デフォルト10、最大25)は、サービスが増えると容易に到達する。 一方、インラインポリシーは 個数制限がなく、合計サイズ(ロールの場合10,240文字) が上限となる。

この特性を活かし:

  • 汎用的な権限 → マネージドポリシーとしてアタッチ(上限枠を消費するが、再利用性が高い)
  • リソース固有の権限 → インラインポリシーで追加(上限枠を消費せず、詳細に設定可能)

という使い分けにより、マネージドポリシーの上限を超えて詳細な権限設定が可能になる。

5. IAMユーザー管理と認証情報の安全な格納

課題:認証情報の散逸

IAMユーザーを作成すると、認証情報(アクセスキーまたはパスワード)が生成される。 この認証情報をどこに保存するかが明確でないと、以下の問題が生じる。

  • Terraformの出力やコンソール画面に平文で表示され、Slackやメールで共有される
  • 保存先が担当者ごとにバラバラになり、棚卸し不能になる
  • 「認証情報はどこにありますか?」という監査時の質問に即答できない
  • 退職・異動時に、どの認証情報を無効化すべきか追跡できない

設計方針:作成と同時に安全な格納先へ自動振り分け

IAMユーザーの作成と同時に、認証情報を用途に応じた格納先に自動的に保存する。 terraform output に認証情報の平文は出力されず、格納先のARNまたはパス名だけが出力される。

認証タイプ別の動作

認証タイプ用途生成されるもの格納先取得方法
アクセスキーCI/CD、プログラマティックアクセスAccess Key ID + Secret Access KeySecrets Manageraws secretsmanager get-secret-value
コンソールAWSマネジメントコンソールアクセス初回パスワード(変更必須)SSM Parameter Store (SecureString)aws ssm get-parameter --with-decryption

6. まとめ

設計判断内容
ロールの集約管理全IAMロールを1ファイルに集約し、一覧性とレビュー容易性を確保
汎用ポリシーのみ一括アタッチAWSマネージドポリシーまたは resource = ["*"] のポリシーのみを一括管理で設定
限定権限はインラインポリシーリソース作成時にインラインポリシーで追加し、マネージドポリシー上限を回避
認証情報の安全な管理アクセスキーはSecrets Manager、コンソール認証情報はSSM Parameter Storeに自動格納
宣言的なAssumeRoleサービス名リストまたはカスタムステートメントで柔軟に対応