17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

目次

1. はじめに

本記事では、AWS IAM Identity Center を特定の事業部において導入し、Terraform による構成管理と委任運用を開始した例を紹介します。

対象読者

  • IAMユーザーからの移行を検討している方
  • Identity Center を一部組織から段階的に導入したい方
  • Identity Center の構成管理を Terraform で行いたい方
  • Identity Center の委任運用に興味がある方

本記事で扱う範囲と前提

  • AWS Organizations 配下にあるマルチアカウント環境を前提としています
  • IdP 連携などは扱わず、Identity Center 本体の構成にフォーカスします
  • Terraform による構成管理・委任運用の設計を含みます

このような前提のもと、
まずは1事業部でのスモールスタートとしてどのように導入・運用を始めたかをご紹介します。

2. 導入の経緯と構成の考え方

なぜ IAM Identity Center を導入したのか

私が所属する事業部では、サービスや環境ごとに複数の AWS アカウントを保有し、
それぞれのアカウントで個別に IAM ユーザーを作成・運用していました。

このような構成には以下のような課題がありました:

  • 開発者がアカウントごとに認証情報を管理・切り替える必要がある
  • IAM ユーザーの管理がアカウント単位で分散し、統制が取りづらい

こうした課題を解決するために、Identity Center を用いた「一元的な認証・認可の管理」を目指すことにしました。


全社展開ではなくスモールスタートを選んだ理由

Identity Center は非常に便利なサービスですが、以下のような理由でいきなり全社導入するのは現実的ではありませんでした:

  • IAM 管理が各事業部に委任されており、全体で調整するには時間と合意形成が必要
  • 各事業部によってAWSアカウント数・運用体制に差があり、導入インセンティブが不透明

そのため、まずは自部門での導入・運用実績を作るというアプローチを選択しました。


スモールスタートにおける構成方針

本導入では、以下の方針で構成を設計・運用しました:

  • 他の事業部の将来的な導入を妨げない構成にする
    将来的に他事業部が導入をしようとした際に、共存できる構成を意識しました

  • 既存の運用フローは大きく変更しない
    元々、弊社のIAMユーザーは、

    1. 社内ワークフローで全体の管理部門が申請を承認
    2. 管理部門から依頼を受けた各事業部の管理者が、実際のユーザー・権限付与・削除の作業を実施

    という流れでの管理を行っていました。
    この流れをドラスティックに変更しようとすると他事業部で導入しようとした場合の阻害要因となりうるので、権限申請やアカウント管理の体制はこれまで通り、全体の管理部門および各事業部の委任された管理者による運用の継続を想定する方向としました。

3. Identity Center 導入の流れ

ここでは、スモールスタートでIdentity Centerを導入するにあたって実施したステップを紹介します。
全体としては、以下のような順序で進めました。


Step1. 管理部門への協力要請

Identity Centerの導入には、AWS Organizationsの操作や管理アカウントでの作業が必要なため、全社のAWS運用を担っている管理部門に協力を依頼しました。

  • 導入の背景と目的を説明
  • 想定している構成の図や導入イメージを共有
  • 必要な操作権限(組織設定や委任設定)について事前にすり合わせ

image.png


Step2. AWS Organizations の「すべての機能」の有効化

Identity Center を利用するには、AWS Organizations において「すべての機能」が有効になっている必要があります。
弊社ではもともと請求統合の目的で Organizations を利用していたため、「すべての機能」は未有効の状態でした。

今回の導入に際し、以下のような対応を管理部門に実施いただきました:

管理アカウントで「すべての機能」を有効化

  • 以下のようなアカウントに対し、個別にログインし「招待の承諾」操作を実施:
    • Organizations 利用開始前に作成された AWS アカウント
    • 後から組織に追加された AWS アカウント

🙏 管理部門の方に奔走いただき、多大なご協力をいただきました。

🔗 参考ドキュメント:

Step3. Identity Center の有効化と委任

Identity Center の有効化は、AWS Organizations の管理アカウントから行います。
加えて、管理アカウント以外のAWSアカウントを「委任された管理者」を指定することで、他の AWS アカウントに運用を委任することができます。

今回は、以下のような対応を管理部門に実施いただきました:

  • Identity Center 用の専用アカウントを新たに作成
  • 管理アカウントにて Identity Center を有効化
  • 上記アカウントを「委任された管理者」として登録
  • 委任されたアカウントに必要な IAM 権限を付与し、以降の運用を移譲

委任設定の実施理由

委任設定は必須ではありませんが、以下の意図で採用しました:

  • 管理アカウントへの依存を最小限にしたかった(セキュリティ・統制の観点から)
  • 現場に近い事業部の委任された管理者が自律的に運用できる構成にしたかった

Step4. 動作検証とTerraform化(詳細は別セクション)

Identity Centerの基本的な構成(ユーザー・グループ・許可セット・アカウント割り当て)を手動で検証し、
その後、Terraformによる構成管理に移行しました。

導入初期の構成は変更が発生しやすく、運用負荷を抑えるためにも以下の理由で IaC 管理を導入しました:

  • 組織変更やポリシー設計の見直しに備え、再構築が容易な状態を保ちたかった
  • 将来的な他事業部の導入に備え、構成の移植性と保守性を高めたかった
  • 初回のユーザーアカウント作成作業を手作業でするのがだるかった

Terraform の詳細は別章にて紹介します。

Terraform による Identity Center の構成管理


Step5. 既存IAMユーザーの移行対応

移行対象ユーザーの整理と新しいログイン手順の展開を行いました。

  • 各 AWS アカウントの IAM ユーザー・グループを抽出して、現状を棚卸し
  • Identity Center の構成に合わせてグループや権限を再編成
  • ログインや AWS CLI 利用の手順書を作って、ユーザーに展開

こちらの作業はGitHub Copilot(Claude Sonnet 4)に依頼してやってもらいました。
一時的な中間CSV生成など、ワンショットで使い捨てのスクリプトを5本くらい書いてもらってます。
スクリプトで荒く対応しつつ、必要なところは手で補正しながら仕上げました。
(地味ですが、一番面倒だったかもしれません。)

※注意
Terraformでユーザー作っても招待メールが送信されないです。
コンソールで再検証メールを送信するか、OTPを有効にすると思います。
今回は再検証メールの送信で対応しました。

🔗 参考ドキュメント:
【AWS IAM Identity Center 小ネタ】APIで作成したユーザーにメールでOTP(ワンタイムパスワード)を送るようにする

このような流れで、まずは自分の所属する事業部でIdentity Centerを利用開始しました。


Step6. 【今後の予定】IAMユーザーの削除・(任意で)他事業部での導入

Identity Centerベースでの運用が安定した段階で、既存のIAMユーザー・アクセスキーの削除も予定しています。
一定期間は併存運用とし、運用安定後に削除を進める予定です。

また、今後他事業部での導入ニーズが出た場合には、伴走サポート等で対応できればと思います。
社内で導入したい方がいれば、お気軽にお声がけください。


4. Terraform による Identity Center の構成管理

ここからは、実際に作成した Terraform によるIdentity Centerのコード管理について紹介します。

Terraform には、Identity Center 用のモジュール(例:aws-ia/iam-identity-center)も用意されていますが、今回は以下の理由から 自前でモジュールを構築 することにしました:

  • 委任管理など、柔軟な制御が必要だったがモジュールの取り回しが悪そうだった
  • 難易度自体は高くなく、シンプルな構成であれば比較的すぐ作成可能だったため

実際のコードの8割以上は GitHub Copilot(Claude Sonnet 4)に書いてもらいました。
(他の業務もあったので正確な時間は不明ですが、コーディングに割いた工数は大体1~2日ぐらいです。プロンプトエンジニアリングに慣れた方であれば、もっと短時間で完成できるのだと思います。Claude Code Maxプランとかも使ってみたいですね。)

構成の設計にあたっては、以下の記事を参考にさせていただきました:

🔗 参考記事:
AWS IAM Identity Center の権限設定をセルフサービス化しました(mixi Tech Blog)

補足

記載したコードについて

本章で登場するディレクトリ構成やサンプルコードは、主要な構成ファイル(main.tf や設定ファイル)に絞って抜粋を掲載しています。
実際の構成ではoutputs.tf などその他の設定ファイルも含まれますが、煩雑さを避けるため省略しています。
(ロジックに絡む部分はできるだけ含めるようにはしています。)

管理対象外のリソース

以下のリソースについては、Terraformの管理対象外としています。

  • AWS「管理アカウント」に対して適用する許可セットとそのアカウント割り当て

これはIdentityCenter用AWSアカウントから操作が出来ない為になります。

4.1 ディレクトリ構成と管理単位

Terraform の構成では、責務の分離管理権限の境界の明確化を重視しました。

identity_center_terraform/
├── components/
│   ├── 00_user_and_groups/       # 全体管理:ユーザー・グループ
│   ├── 01_idc_admin_delegations/ # 全体管理:委任設定
│   └── 10_org_a_grants/          # 開発組織:組織Aの権限設定
├── modules/                      # 再利用モジュール群
│   ├── common/
│   ├── permission_set/
│   └── user/
└── .github/
    └── CODEOWNERS               # コンポーネント単位の承認制御

components/ ディレクトリ

components/ 配下は、以下のようにディレクトリを分割しています。

  • 00_user_and_groups/
    ユーザー・グループの作成と管理を行う 全体管理用 のコンポーネントです

  • 01_idc_admin_delegations/
    委任された管理者への許可セット割り当てなど、管理部門→組織の管理者への委任設定を行います

  • 10_org_a_grants/
    組織Aにおける 許可セット定義と割当 を管理するディレクトリです。
    他の組織でも同様の構成を追加する想定です(例: 20_org_b_grants/ など)

「全体管理者」と「各組織の管理者」 で管理・承認する範囲を分離するようにしています。

承認権限の分離と CODEOWNERS の活用

構成単位ごとにディレクトリを分けたことで、GitHub 上でも CODEOWNERS を使って責任範囲の明確化を実現しています。

💡 GitHub の CODEOWNERS 機能を使うと、該当ディレクトリの Pull Request に対して、 指定ユーザーまたはチームのレビュー・承認を必須にできます

.github/CODEOWNERS
# 00_user_and_groups、01_idc_admin_delegations配下は管理部門メンバーの承認を必要とする
/components/00_user_and_groups/       @org-admin-member
/components/01_idc_admin_delegations/ @org-admin-member

# 10_org_a_grants配下は 組織Aのメンバーの承認での変更を許可する
/components/10_org_a_grants/          @org-a-member

このように定義することで、全体管理に関わる設定(ユーザー作成や委任設定)は管理部門のみが承認可能とし、
事業部の委任された管理者は自組織の権限設定にのみ責任を持てるようにしています。


modules/ ディレクトリ

共通ロジックや再利用される構成は、以下のように モジュールとして整理 しています。

  • common/
    Identity Center 本体の ARN や ID など、全体共通で利用する値を共有するモジュールです

  • permission_set/
    許可セット(Permission Set)を定義・作成するモジュールです。
    マネージドポリシー/インラインポリシーの両方に対応しています

  • user/
    ユーザーの作成と、ユーザーをグループへ割り当てる処理を含んだモジュールです

4.2 モジュールの定義

modules/common

Identity Center 本体(インスタンスID / ARN)など、Terraform 外部で手動作成された値を参照するためのモジュールです。

output.tf

output "identity_store_id" {
  description = "Identity Store ID"
  value       = "<identity_store_id>"
}

output "sso_instance_arn" {
  description = "SSO Instance ARN"
  value       = "arn:aws:sso:::instance/ssoins-<sso_instance_id>"
}

output "sso_instance_id" {
  description = "SSO Instance ID"
  value       = "ssoins-<sso_instance_id>"
}

modules/permission_set/

Permission Set(許可セット) を定義・作成するためのモジュールです。

許可セットにはマネージドポリシー・カスタマー管理ポリシー・インラインポリシーをアタッチ出来るのですが、カスタマー管理ポリシーは各AWSアカウントに対して事前にIAMポリシーを定義する必要があり、ほとんどのユースケースでは代わりにインラインポリシーを利用することが推奨されています。
そのため、マネージドポリシーとインラインポリシーをアタッチできるようにしています。

main.tf

resource "aws_ssoadmin_permission_set" "this" {
  instance_arn     = var.sso_instance_arn
  name             = var.name
  description      = var.description
  session_duration = var.session_duration
}

# Managed policy attachments
resource "aws_ssoadmin_managed_policy_attachment" "this" {
  for_each = toset(var.managed_policy_arns)

  instance_arn       = var.sso_instance_arn
  permission_set_arn = aws_ssoadmin_permission_set.this.arn
  managed_policy_arn = each.value
}

# Inline policy
resource "aws_ssoadmin_permission_set_inline_policy" "this" {
  count = var.inline_policy != "" ? 1 : 0

  instance_arn       = var.sso_instance_arn
  permission_set_arn = aws_ssoadmin_permission_set.this.arn
  inline_policy      = var.inline_policy
}

modules/user/

Identity Center における ユーザーの作成グループへの所属設定 をあわせて行うモジュールです。
1ユーザーに対して複数グループへの割当を同時に定義できます。

main.tf

resource "aws_identitystore_user" "this" {
  identity_store_id = var.identity_store_id

  display_name = "${var.given_name} ${var.family_name}" #手動で作成した場合と合わせる
  user_name    = var.email

  name {
    given_name  = var.given_name
    family_name = var.family_name
  }

  emails {
    value   = var.email
    type    = "work"
    primary = true
  }
}

# Create group memberships for this user
resource "aws_identitystore_group_membership" "this" {
  for_each = var.groups

  identity_store_id = var.identity_store_id
  group_id          = each.value.group_id
  member_id         = aws_identitystore_user.this.user_id
}

4.3 ユーザーとグループの管理(全体管理)

ユーザーおよびグループの管理は、components/00_user_and_groups/ にて行っています。
アカウント作成・削除などの会社全体での運用を管理部門が担う想定で設計されています。

将来的にIdP連携で自動管理される可能性も考慮し、ユーザーとグループは1つのコンポーネントでまとめて管理しています。

※おそらくAWS側はIdP連携で全体管理するという思想のため、ユーザーとグループにはタグ付けたり出来ないです。そのため、IAMポリシーでリソース制御は難しく、あくまで組織全体のリソースとして管理する必要があります。(一人が複数の組織にまたがって所属するみたいなケースもよくあるので当たり前といえば当たり前ですが)
Attribute-Based Access Controlが代替的に使えそうですが、カオスになるので今回は見送りました。

ファイル構成

components/00_user_and_groups/
├── config/
│   ├── users.yaml
│   └── groups.yaml
├── locals.tf
└── main.tf
...(他にoutputs.tf なども含まれます)

サンプルコード

ユーザーとグループは管理対象が多くなりそうなので、設定ファイルから読み込めるようにしました。

locals.tf
locals {
  # YAMLファイルからユーザー定義を読み込み
  users = yamldecode(file("${path.module}/config/users.yaml")).users
  # YAMLファイルからグループ定義を読み込み
  groups = yamldecode(file("${path.module}/config/groups.yaml")).groups
}

config/groups.yaml
groups:
  OrgA-Admins:
    description: "組織A管理者グループ"
  ServiceA-Developers:
    description: "サービスA開発者グループ"
  ServiceB-Viewers:
    description: "サービスB閲覧者グループ"
config/users.yaml
users:
  #Govtech事業本部 開発部 SRE課
  "sato@example.com":
    family_name: "佐藤"
    given_name: "太郎"
    groups:
      - "OrgA-Admins"
  "suzuki@example.com":
    family_name: "鈴木"
    given_name: "一郎"
    groups:
      - "ServiceA-Developers"
      - "ServiceB-Viewers"
main.tf
# グループ作成
resource "aws_identitystore_group" "this" {
  for_each = local.groups

  identity_store_id = module.common.identity_store_id
  #グループ名を変更したいケースが組織の変更に伴いそこそこありそうなので、display_nameを設定できるようにしておく
  display_name = lookup(each.value, "display_name", each.key)
  description  = each.value.description
}

# ユーザー作成・グループ割り当て
module "users" {
  source = "../../modules/user"

  for_each = local.users

  identity_store_id = module.common.identity_store_id
  email             = each.key
  given_name        = each.value.given_name
  family_name       = each.value.family_name
  groups = {
    for group_name in each.value.groups : group_name => {
      group_id = aws_identitystore_group.this[group_name].group_id
    }
  }
}

4.4 委任の管理(全体管理)

委任管理はcomponents/01_idc_admin_delegations/で行っています。
Identity Center 専用アカウント上に定義され、各開発組織の管理者に限定された権限を付与します。

具体的には:

  • 各開発組織の管理者に対する Permission Set(許可セット) の定義
  • 上記の許可セットのグループへの割り当て(委任)

を実施しています。

ファイル構成

components/
└── 01_idc_admin_delegations/      
    ├── main.tf                     
    ├── locals.tf                   
    ├── template/
    │   └── inline_policy.json.tftpl  # IAMポリシーのテンプレート(タグ制約)
...(他にdata.tf なども含まれます)

サンプルコード抜粋

locals.tf

locals {
  session_duration = "PT1H" # デフォルトのセッション期間(1時間)
  identity_center_account_id = "123456789000" # Identity Centerアカウント

  # 委任する開発組織ごとに設定
  organizations = {
    "org_a" = {
      organization_tag = "OrgA" #組織Aのタグ
      #組織Aの管理対象AWSアカウント
      accounts = {
        "service_a_dev"     = "123456789001"
        "service_a_prd"     = "123456789002"
        "service_b_stg"     = "123456789003"
        "service_b_prd"     = "123456789004"
      }
    }
  }
}

委任された管理者向けの許可セットと、IdentityCenterアカウントへの割り当て定義をしています。
参照系のマネージドポリシーとは別に委任された管理者向けのポリシーを付与して変更操作を制御しています。

main.tf

# Common module for shared resources
module "common" {
  source = "../../modules/common"
}

#委任された組織Aの管理者用のPermission Setを定義
module "org_a_identity_center_admin_access_permission_set" {
  source = "../../modules/permission_set"

  sso_instance_arn = module.common.sso_instance_arn
  name             = "OrgA-IdentityCenterAdminAccess"
  description      = "Identity Center Admin Access for OrgA"
  session_duration = local.session_duration
  managed_policy_arns = [
    data.aws_iam_policy.s3_full_access.arn, #Terraform操作時のRemote State管理の為
    data.aws_iam_policy.iam_read_only_access.arn, #マネージポリシ-の参照権限
    data.aws_iam_policy.sso_read_only_access.arn, #IdentityCenterのアカウントアクセス許可周りの参照権限
    data.aws_iam_policy.sso_directory_read_only_access.arn, #IdentityCenterのユーザー・グループ周りの参照権限
  ]
  inline_policy = templatefile("${path.module}/template/inline_policy.json.tftpl", {
    sso_instance_id  = module.common.sso_instance_id
    organization_tag = local.organizations.org_a.organization_tag
    account_arns = jsonencode(
      [for account_id in values(local.organizations.org_a.accounts) : "arn:aws:sso:::account/${account_id}"]
    )
  })
}
# 組織Aの管理者グループへの権限割り当て
resource "aws_ssoadmin_account_assignment" "org_a_admins_account_assignment" {

  instance_arn = module.common.sso_instance_arn

  principal_id   = data.terraform_remote_state.users_and_groups.outputs.groups["OrgA-Admins"]
  principal_type = "GROUP"

  permission_set_arn = module.org_a_identity_center_admin_access_permission_set.permission_set_arn

  target_id   = local.identity_center_account_id
  target_type = "AWS_ACCOUNT"
}

委任された管理者の IAM ポリシーに関する補足

委任された各開発組織の管理者が所属組織内に閉じた範囲で Identity Center の管理操作を行えるように、IAM Identity Center におけるタグベースモデルを採用しました。
Permission Setリソースにタグを付与し、委任された管理者が扱える範囲をIAM ポリシー内のタグ条件で制限する方式です。

参考にさせていただいた記事は以下になります。

🔗 参考記事:

委任された管理者が明示的に許可される操作:

  • 自組織(のタグ)で管理する許可セットの作成・更新・削除
  • 任意のグループ(またはユーザー)に対して、
    自組織が管理するAWS アカウントへの、自組織(のタグ)で管理する許可セットを割り当て
  • 再検証メールの送信(これは管理部門の負担削減の為に付けてます)

目的としては、各開発組織が自身の要件に応じて、開発者に必要な権限を柔軟に割り当てられるようにすることです。

委任された管理者が暗黙的に禁止される操作:

  • ユーザー・グループ自体の管理
  • 他の組織が管理するPermission Setの変更
  • 他の組織が管理するAWSアカウントへの割り当て操作

この制約により、組織間での操作干渉を防ぎつつ、各組織の自律性を維持出来る設計としています。

具体的にはIAMポリシーで、

  • 許可セット関連ActionのCondition句で自組織のタグに制限
  • アカウント割り当て関連Actionのリソースを自組織のAWSアカウントに制限

することで実現しています。

IAMポリシー例
inline_policy.json.tftpl
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sso:CreatePermissionSet",
                "sso:UpdatePermissionSet",
                "sso:DeletePermissionSet",
                "sso:TagResource",
                "sso:PutInlinePolicyToPermissionSet",
                "sso:DeleteInlinePolicyFromPermissionSet",
                "sso:AttachManagedPolicyToPermissionSet",
                "sso:DetachManagedPolicyFromPermissionSet",
                "sso:CreateAccountAssignment",
                "sso:DeleteAccountAssignment",
                "sso:ProvisionPermissionSet"
            ],
            "Resource": [
                "arn:aws:sso:::instance/${sso_instance_id}"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "sso:CreatePermissionSet"
            ],
            "Resource": "arn:aws:sso:::permissionSet/${sso_instance_id}/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/Organization": "${organization_tag}"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "sso:UpdatePermissionSet",
                "sso:DeletePermissionSet",
                "sso:ProvisionPermissionSet",
                "sso:PutInlinePolicyToPermissionSet",
                "sso:DeleteInlinePolicyFromPermissionSet",
                "sso:TagResource",
                "sso:AttachManagedPolicyToPermissionSet",
                "sso:DetachManagedPolicyFromPermissionSet",
                "sso:CreateAccountAssignment",
                "sso:DeleteAccountAssignment"
            ],
            "Resource": "arn:aws:sso:::permissionSet/${sso_instance_id}/*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Organization": "${organization_tag}"
                }
            }
        },
        {
            "Effect": "Allow",
            "Action": [
                "sso:CreateAccountAssignment",
                "sso:DeleteAccountAssignment",
                "sso:ProvisionPermissionSet"
            ],
            "Resource": ${account_arns}
        },
        {
            "Effect": "Allow",
            "Action": [
                "sso-directory:VerifyEmail"
            ],
            "Resource": "*"
        }
    ]
}

4.5 組織単位での許可セットと割り当ての管理(委任先)

開発組織ごとに、委任された管理者が該当組織における許可セットとアカウント割り当ての定義を管理する想定です。

Ex. components/10_org_a_grants/

01_idc_admin_delegationsで委任を受けたユーザーが、

  • 組織別の許可セットの定義
  • 任意のグループに対して、自組織が管理するAWS アカウントに自組織の許可セットを割り当て

を実施します。

ファイル構成

components/
└── 10_org_a_grants/                     
    ├── main.tf                           # アカウント割当の定義
    ├── locals.tf                         # 組織Aの設定(アカウントID、組織タグなど)
    ├── permission_set.tf                 # Permission Set の作成処理
    └── providers.tf                      # Provider の定義(組織タグの付与)
...(他にdata.tf なども含まれます)

サンプルコード

アカウント割り当ても数が多くなるので管理用の設定ファイルを用意する形で対応しました。

config/group_permissions.yaml
group_account_access:
  OrgA-Admins:
    accounts:
      searvice-a-dev:
        - org_a_administrator_access
        - org_a_readonly_access
      searvice-a-prd:
        - org_a_administrator_access
        - org_a_readonly_access
      service-b-stg:
        - org_a_administrator_access
        - org_a_readonly_access
      service-b-prd:
        - org_a_administrator_access
        - org_a_readonly_access
  ServiceA-Developers:
      searvice-a-dev:
        - org_a_power_user_access
        - org_a_readonly_access
      searvice-a-prd:
        - org_a_readonly_access

割り当てを実施している箇所です。
どのグループに、どのアカウントの、どの許可セットを割り当てるか
を設定ファイルを元に作成します。

main.tf
# Common module for shared resources
module "common" {
  source = "../../modules/common"
}


# 利用範囲が限定的かつ、設定値ではないのでmain.tf上で定義
locals {
  # グループごとのアカウントアクセス定義(YAMLから読み込み)
  group_account_access = yamldecode(file("${path.module}/config/group_permissions.yaml")).group_account_access

  # グループ・アカウント・権限の組み合わせをマップ形式で作成(for_eachで使用するため)
  ## Terraformでは多重ループはネイティブ対応していないので、flattenを噛ませてリストを平坦化してマップに変換
  group_account_permission_map = {
    for combo in flatten([
      for group_name, group_config in local.group_account_access : [
        for account_name, permissions in group_config.accounts : [
          for permission_module in permissions : {
            key               = "${group_name}-${account_name}-${permission_module}"
            group_name        = group_name
            account_name      = account_name
            account_id        = local.all_org_a_aws_accounts[account_name]
            permission_module = permission_module
          }
        ]
      ]
    ]) : combo.key => combo
  }

  # Permission Set ARNのマップ
  permission_set_arns = {
    for key, module_instance in module.permission_sets :
    key => module_instance.permission_set_arn
  }
}

# 設定ファイルに従い、グループ・アカウント・権限の組み合わせを作成
resource "aws_ssoadmin_account_assignment" "group_account_assignments" {
  for_each = local.group_account_permission_map

  instance_arn = module.common.sso_instance_arn

  principal_id   = data.terraform_remote_state.users_and_groups.outputs.groups[each.value.group_name]
  principal_type = "GROUP"

  permission_set_arn = local.permission_set_arns[each.value.permission_module]

  target_id   = each.value.account_id
  target_type = "AWS_ACCOUNT"
}

該当組織における許可セットの作成です。
許可セットも複数作成しますが、許可セットの数は全体でクォーターが設定されているので乱立はさせないでほしいという意図もあり、あえて設定ファイル化はしていないです。(上限に達することはまずないと思いますが)

IAM アイデンティティセンターのクォータと制限

permission_set.tf

# 例:IP制限のインラインポリシーを定義
data "aws_iam_policy_document" "ip_restrict" {
  # 特定のIP以外からのアクセスを拒否
  statement {
    effect    = "Deny"
    actions   = ["*"]
    resources = ["*"]

    condition {
      test     = "NotIpAddress"
      variable = "aws:SourceIp"
      values   = local.allowed_ips
    }
  }
}

locals {
  # Permission Set定義
  permission_sets = {
    org_a_administrator_access = {
      name                = "OrgA-AdministratorAccess"
      description         = "AdministratorAccess of OrgA"
      session_duration    = "PT1H"
      managed_policy_arns = [data.aws_iam_policy.administrator_access.arn]
      inline_policy       = data.aws_iam_policy_document.ip_restrict.json
    }
    org_a_power_user_access = {
      name             = "OrgA-PowerUserAccess"
      description      = "PowerUserAccess of OrgA"
      session_duration = local.default_session_duration
      managed_policy_arns = [data.aws_iam_policy.power_user_access.arn]
      inline_policy = data.aws_iam_policy_document.ip_restrict.json
    }
    org_a_read_only_access = {
      name                = "OrgA-ReadOnlyAccess"
      description         = "ReadOnlyAccess of OrgA"
      session_duration    = local.default_session_duration
      managed_policy_arns = [data.aws_iam_policy.read_only_access.arn]
      inline_policy       = data.aws_iam_policy_document.ip_restrict.json
    }
  }

}

# 動的にPermission Setを生成
## モジュール名を共通化することで、accountの割当時に動的にpermission_setを選択できるようにしている
module "permission_sets" {
  for_each = local.permission_sets
  source   = "../../modules/permission_set"

  sso_instance_arn    = module.common.sso_instance_arn
  name                = each.value.name
  description         = each.value.description
  session_duration    = each.value.session_duration
  managed_policy_arns = each.value.managed_policy_arns
  inline_policy       = each.value.inline_policy
}

デフォルトタグでタグをつけるようにしています。
委任管理側で許可されたタグのみを付与することができ、これを元に変更操作の権限が制御されます。

providers.tf

provider "aws" {
  region  = "ap-northeast-1"
  profile = "identity-center"
  #タグ
  default_tags {
    tags = {
      Organization = local.organization
    }
  }
}

5. おわりに

今回は、自分が所属する事業部で IAM Identity Center を導入してみた話と、その構成をまとめてみました。

対象範囲を狭めたことで、とりあえずの導入まではテンポよくこぎつけることが出来ました。
(とはいえ後で怒られないように出来るだけ意識する必要はありました。後でスクラップ&ビルドする羽目にならなければ嬉しいです。)

Identity Centerの構成は、どの単位で責任を分けるかが肝になるので、
そこは会社の規模感とか運用体制にあわせてチューニングする必要があると感じました。

今回はあくまで「まず自分の事業部で導入してみる」というフェーズだったので、まだ全社展開までは見据えていません。
実際に他の事業部が導入するとなった場合は、管理部門の負荷にならないようCICDでの変更反映もする必要がありそうです。
ただ、導入の障壁はかなり下がった印象があり、次に困ってる事業部があれば「これそのまま使えば大体いけるよ」と言える状態にはなったかなと思っています。

同じような構成を検討されている方のヒントになればうれしいです 🙌

17
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?