0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS Organizations×Terraformで始めるマルチアカウント管理【SSO有効化編】

Last updated at Posted at 2025-09-08

この記事について

前回の記事では、Terraform で AWS Organizations の OU / アカウント / SCP を最小構成で一括構築し、今後のガバナンス基盤となる下地を整えました。
今回はその続編として、AWS IAM Identity Center(旧 AWS SSO)を Terraform で有効化し、権限セットの作成とアカウント割り当てまでを自動化します。

Organizations の状態ファイルを参照しつつ、SSO ユーザー・Permission Set をコードで管理することを目指します。

アーキテクチャ

Organization.png

ゴール(スクショ)

Identitiy Center.png

手順の流れ(ざっくり)

  1. Organizations 側で Service Access を有効化
    第一弾で sso.amazonaws.com を Service Access に含めている前提です。

  2. 手動で Identity Center インスタンスを作成
    AWS マネジメントコンソールの IAM Identity Center 画面で「今すぐ始める」をクリック。

  3. Identity Center ユーザーを作成(任意)
    aws_identitystore_user を作成し、(Organization/SSO/ssouser)ユーザー ID を取得。

  4. Permission Set を定義
    例: AdministratorAccess を 8 時間セッションで作成し、AWS 管理ポリシーをアタッチ。

  5. アカウント割り当て
    Organizations の remote state から取得したアカウント ID に対し、作成した Permission Set をユーザーへ割り当て。

  6. Terraform 実行

    terraform init && terraform apply
    
  7. AWS CLI で SSO ログイン確認

    aws sso login --profile <profile-name>
    

ディレクトリ構成

Organization/
├─ main.tf … Organizations 基盤(第一弾で構築済み)
└─ SSO/
    ├─ main.tf          # Permission Set とアカウント割り当て
    ├─ variable.tf      # 共通変数・remote state 設定
    ├─ provider.tf      # AWS Provider 設定
    ├─ backend.tf       # S3 バックエンド定義
    ├─ terraform.tfvars # サンプル変数ファイル
    └─ ssouser/         # Identity Center ユーザー作成用モジュール
        ├─ main.tf
        └─ terraform.tfvars

各種設定値

  • Permission Set

    • 名称: AdministratorAccess
    • セッション有効期限: 8 時間
    • 付与ポリシー: arn:aws:iam::aws:policy/AdministratorAccess
  • Organizations の状態ファイル参照

    • org_state_bucket
    • org_state_key
    • org_state_region
  • ユーザー ID

    • user_id を変数で受け取り、Permission Set の割り当てに利用
  • サンプル tfvars

    • 環境名・アプリ名・リージョン・共通タグを定義

Terraform 実装例

Organization/SSO

main.tf
data "terraform_remote_state" "org" {
  backend = "s3"
  config = {
    bucket = var.org_state_bucket
    key    = var.org_state_key
    region = var.org_state_region
  }
}
data "aws_ssoadmin_instances" "main" {}

locals {
  account_ids = merge(
    data.terraform_remote_state.org.outputs.member_account_ids,
    { security = data.terraform_remote_state.org.outputs.security_account_id }
  )
}

# SSOユーザにはAdministratorAccessを固定で与える(実務では必ず最小権限)
# セッション有効期限は 8時間
resource "aws_ssoadmin_permission_set" "admin" {
  name             = "AdministratorAccess"
  instance_arn     = data.aws_ssoadmin_instances.main.arns[0]
  session_duration = "PT8H"
}
# ポリシーをアタッチ
resource "aws_ssoadmin_managed_policy_attachment" "admin_attach" {
  instance_arn       = data.aws_ssoadmin_instances.main.arns[0]
  managed_policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
  permission_set_arn = aws_ssoadmin_permission_set.admin.arn
}
# アカウントにアタッチ
resource "aws_ssoadmin_account_assignment" "admin_assign" {
  for_each           = var.assigned_accounts
  instance_arn       = data.aws_ssoadmin_instances.main.arns[0]
  permission_set_arn = aws_ssoadmin_permission_set.admin.arn
  principal_type     = "USER"
  principal_id       = var.user_id
  target_type        = "AWS_ACCOUNT"
  target_id          = local.account_ids[each.key]
}
variable.tf
# metadata
variable "env" {
  type = string
  validation {
    condition     = can(regex("^(dev|stg|prod|sandbox)$", var.env))
    error_message = "env は dev|stg|prod|sandbox のいずれか。"
  }
}

variable "app_name" {
  type = string
  validation {
    condition     = can(regex("^[A-Za-z0-9_-]{3,32}$", var.app_name))
    error_message = "app_name は 3–32 文字の英数/ハイフン/アンダースコア。"
  }
}

variable "region" {
  type = string
  validation {
    condition     = can(regex("^[a-z]{2}-[a-z]+-\\d$", var.region))
    error_message = "region の形式が不正。例: ap-northeast-1"
  }
}

variable "tags" {
  description = "共通タグ(provider.default_tags とモジュールに渡す tags の両方で利用)"
  type        = map(string)
  default     = {}
}

# SSO
variable "org_state_bucket" {
  description = "Organizationのtfstateが保存されているバケット名"
  type        = string
}

variable "org_state_key" {
  description = "Organizationのtfstateが保存されているバケットのキー"
  type        = string
}

variable "org_state_region" {
  description = "Organizationのtfstateが保存されているリージョン"
  type        = string
}

variable "user_id" {
  description = "Identity Center ユーザーID"
  type        = string
}

variable "assigned_accounts" {
  type        = set(string)
  description = "管理権限セットを付与する論理アカウント名(例: dev, network, security)"
}

terraform.tfvars
# terraform.tfvars

# 環境(dev | stg | prod | sandbox)
env = "prod"

# アプリケーション名(3–32 文字、英数/ハイフン/アンダースコア)
app_name = "hogehoge"

# AWS リージョン(例: ap-northeast-1)
region = "ap-northeast-1"

# 共通タグ
tags = {
  Project = "hogehoge"
}

# Organization の tfstate 情報
org_state_bucket = "aws-remotebackend-bootstrap-tfstate-ap-northeast-1-111111111111" # マスク済み
org_state_key    = "state/organization/terraform.tfstate"
org_state_region = "ap-northeast-1"

# Identity Center ユーザーID(UUIDはマスク済み)
user_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

# 割り当て先アカウント(SSO使用アカウントを列挙)
assigned_accounts = ["dev", "network", "security"]

Organization/SSO/ssouser

main.tf
terraform {
  required_version = ">= 1.9.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.9"
    }
  }
}

provider "aws" {
  region = var.region
}

data "aws_ssoadmin_instances" "this" {}

variable "region" {
  description = "Identity Centerを有効化しているリージョン"
  type        = string
  default     = "ap-northeast-1"
}

variable "user" {
  description = "作成するIdentity Centerユーザー属性"
  type = object({
    user_name    = string           # 一意なユーザー名(例: taro.portfolio)
    given_name   = string           # 名
    family_name  = string           # 姓
    display_name = string           # 表示名
    email        = string           # メールアドレス(招待/通知に使用)
    phone        = optional(string) # 省略可
  })
  default = {
    user_name    = "taro.portfolio"
    given_name   = "Taro"
    family_name  = "Yamada"
    display_name = "Taro Yamada"
    email        = "taro@example.com"
    # phone      = "+81-90-1234-5678"
  }
}

resource "aws_identitystore_user" "this" {
  identity_store_id = data.aws_ssoadmin_instances.this.identity_store_ids[0]
  user_name         = var.user.user_name
  display_name      = var.user.display_name

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

  emails {
    value   = var.user.email
    primary = true
  }

  # phoneを指定したときだけ作成
  dynamic "phone_numbers" {
    for_each = try(var.user.phone, null) != null ? [var.user.phone] : []
    content {
      value = phone_numbers.value
      type  = "mobile"
    }
  }
}

output "identity_store_id" {
  value = data.aws_ssoadmin_instances.this.identity_store_ids[0]
}

output "user_id" {
  value = aws_identitystore_user.this.user_id
}

terraform.tfvars
region = "ap-northeast-1"

user = {
  user_name    = "example-user"          
  given_name   = "Taro"                  
  family_name  = "Yamada"                
  display_name = "Taro Yamada"           
  email        = "example-user@example.com"  
}

構築後の Terraform profile 設定

~/.aws/config に SSO プロファイルを設定します。

[default]
region = ap-northeast-1
output = json

[profile admin]
sso_session = hogehoge
sso_account_id = 111111111111         # 管理アカウントID
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

[profile security]
sso_session = hogehoge
sso_account_id = 222222222222         # セキュリティアカウントID
sso_role_name = AdministratorAccess
region = ap-northeast-1
output = json

[sso-session hogehoge]
sso_start_url = https://d-xxxxxxxxxx.awsapps.com/start  
sso_region = ap-northeast-1
sso_registration_scopes = sso:account:access

ログイン確認:

aws sso login --profile dev-admin

Terraform 実行時:

AWS_PROFILE=dev-admin terraform plan

運用上の注意

  • 最小権限の徹底
    サンプルでは AdministratorAccess を付与していますが、実運用では必要な権限だけを付与する Permission Set を作成してください。

  • Identity Center はリージョン単位
    SSO を有効化したリージョン以外では利用できません。

  • ユーザー管理
    aws_identitystore_user でメールや電話番号をコード化できますが、ID 連携(SAML/SCIM)する場合は外部 IdP 側の設定が必要です。

  • State 管理
    Organizations の状態ファイルを参照するため、var.org_state_bucket var.org_state_key var.org_state_regionの値は正確に設定してください

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?