identity-center-guide
sidebar_position: 2 title: Identity Center Guide description: Consumer deployment guide for the oceansoft/iam-identity-center/aws Terraform module with multi-account patterns and APRA CPS 234 compliance tags: [identity-center, guide, multi-account, APRA, CPS-234]
IAM Identity Center — Consumer Deployment Guide
Overview
The oceansoft/iam-identity-center/aws module provisions and manages AWS IAM Identity Center (SSO) resources for multi-account AWS Organizations. It manages 14 resource types across the full Identity Center lifecycle:
| Resource Category | Resource Types |
|---|---|
| Identity Store | Users, Groups, Group Memberships |
| Permission Sets | Permission Sets, AWS Managed Policy Attachments, Customer Managed Policy Attachments, Inline Policies, Permissions Boundaries (AWS + Customer) |
| Account Assignments | Account Assignments, Instance Access Control Attributes |
| Applications | Applications, Application Assignment Configurations, Application Access Scopes, Application Assignments |
Cost: $0/month — IAM Identity Center has no per-resource charges. You pay only for the AWS accounts you assign.
Registry: registry.terraform.io/modules/oceansoft/iam-identity-center/aws
Prerequisites
Before deploying this module:
- AWS Organizations must be enabled with your management account.
- IAM Identity Center must be enabled in
us-east-1(the service is global but delegates tous-east-1). Enable via the AWS Console: IAM Identity Center > Enable. - Terraform >= 1.11.0 — required for S3 native state locking and
tftest.hclsnapshot testing. - AWS Provider >= 6.28, < 7.0 — pinned per ADR-003.
- Caller must have
sso:*andidentitystore:*permissions in the management account.
Quick Start
Minimal configuration to create one group, one permission set, and one account assignment:
module "identity_center" {
source = "oceansoft/iam-identity-center/aws"
version = "~> 0.1"
sso_groups = {
platform_admins = {
group_name = "PlatformAdmins"
group_description = "Platform engineering team — full administrative access"
}
}
permission_sets = {
AdministratorAccess = {
description = "Full administrative access"
session_duration = "PT8H"
aws_managed_policies = [
"arn:aws:iam::aws:policy/AdministratorAccess"
]
tags = {
DataClassification = "restricted"
}
}
}
account_assignments = {
platform_admins_mgmt = {
principal_name = "PlatformAdmins"
principal_type = "GROUP"
principal_idp = "INTERNAL"
permission_sets = ["AdministratorAccess"]
account_ids = ["123456789012"]
}
}
default_tags = {
CostCenter = "platform"
Project = "landing-zone"
Environment = "prod"
DataClassification = "internal"
}
}
Multi-Account Patterns
3-Account Landing Zone
A minimal APRA-aligned landing zone with management, security, and workload accounts:
locals {
account_ids = {
management = "111111111111"
security = "222222222222"
workload = "333333333333"
}
}
module "identity_center" {
source = "oceansoft/iam-identity-center/aws"
version = "~> 0.1"
sso_groups = {
cloud_admins = { group_name = "CloudAdmins" }
security_team = { group_name = "SecurityTeam" }
developers = { group_name = "Developers" }
readonly_users = { group_name = "ReadOnlyUsers" }
}
permission_sets = {
AdministratorAccess = {
description = "Full admin — management account only"
session_duration = "PT4H"
aws_managed_policies = ["arn:aws:iam::aws:policy/AdministratorAccess"]
}
PowerUserAccess = {
description = "Power user — workload accounts"
session_duration = "PT8H"
aws_managed_policies = ["arn:aws:iam::aws:policy/PowerUserAccess"]
}
ReadOnlyAccess = {
description = "Read-only — all accounts"
session_duration = "PT12H"
aws_managed_policies = ["arn:aws:iam::aws:policy/ReadOnlyAccess"]
}
SecurityAudit = {
description = "Security audit — security account"
session_duration = "PT8H"
aws_managed_policies = ["arn:aws:iam::aws:policy/SecurityAudit"]
}
}
account_assignments = {
admins_management = {
principal_name = "CloudAdmins"
principal_type = "GROUP"
principal_idp = "INTERNAL"
permission_sets = ["AdministratorAccess"]
account_ids = [local.account_ids.management]
}
admins_workload = {
principal_name = "CloudAdmins"
principal_type = "GROUP"
principal_idp = "INTERNAL"
permission_sets = ["PowerUserAccess"]
account_ids = [local.account_ids.workload]
}
security_audit = {
principal_name = "SecurityTeam"
principal_type = "GROUP"
principal_idp = "INTERNAL"
permission_sets = ["SecurityAudit"]
account_ids = [local.account_ids.security, local.account_ids.management]
}
developers_workload = {
principal_name = "Developers"
principal_type = "GROUP"
principal_idp = "INTERNAL"
permission_sets = ["PowerUserAccess"]
account_ids = [local.account_ids.workload]
}
readonly_all = {
principal_name = "ReadOnlyUsers"
principal_type = "GROUP"
principal_idp = "INTERNAL"
permission_sets = ["ReadOnlyAccess"]
account_ids = values(local.account_ids)
}
}
default_tags = {
CostCenter = "platform"
Project = "landing-zone"
Environment = "prod"
DataClassification = "internal"
}
}
ABAC for Environment-Scoped Access
Use sso_instance_access_control_attributes to pass ABAC context from user attributes into session policies:
module "identity_center" {
source = "oceansoft/iam-identity-center/aws"
version = "~> 0.1"
sso_instance_access_control_attributes = [
{
attribute_name = "Environment"
source = ["$${path:enterprise.Environment}"]
},
{
attribute_name = "CostCenter"
source = ["$${path:enterprise.CostCenter}"]
}
]
# ... groups, permission_sets, account_assignments as above
}
ABAC attributes are injected into session tags. Use aws:PrincipalTag/Environment in IAM condition keys within inline or customer-managed policies to restrict access by environment.
YAML Configuration API
For APRA CPS 234 audit trails, the module supports a config_path variable pointing to a directory containing permission_sets.yaml and account_assignments.yaml. YAML values take precedence over HCL variable values on key collision.
Directory structure:
config/
permission_sets.yaml
account_assignments.yaml
permission_sets.yaml:
AdministratorAccess:
description: "Full administrative access"
session_duration: "PT4H"
aws_managed_policies:
- "arn:aws:iam::aws:policy/AdministratorAccess"
tags:
DataClassification: "restricted"
ReadOnlyAccess:
description: "Read-only access"
session_duration: "PT12H"
aws_managed_policies:
- "arn:aws:iam::aws:policy/ReadOnlyAccess"
tags:
DataClassification: "internal"
account_assignments.yaml:
admins_management:
principal_name: "CloudAdmins"
principal_type: "GROUP"
principal_idp: "INTERNAL"
permission_sets:
- "AdministratorAccess"
account_ids:
- "111111111111"
Enable YAML mode in HCL:
module "identity_center" {
source = "oceansoft/iam-identity-center/aws"
version = "~> 0.1"
config_path = "${path.module}/config"
default_tags = {
CostCenter = "platform"
Project = "landing-zone"
Environment = "prod"
DataClassification = "internal"
}
}
config_path must contain only alphanumeric characters, dots, underscores, hyphens, and forward slashes. The YAML files are read at plan time via Terraform's file() and yamldecode() functions — no external tooling required.
APRA CPS 234 Compliance
The module enforces the following controls relevant to APRA CPS 234 (Information Security):
| Control | Implementation |
|---|---|
| DataClassification tag | Required in default_tags. Validated at plan time — missing key causes terraform plan error. |
| Session duration | ISO 8601 format enforced (PT<n>H or PT<n>M). Invalid values fail at plan time. |
| Least privilege | Use ReadOnlyAccess as the baseline; escalate only with PowerUserAccess or AdministratorAccess for named groups. |
| Audit trail | config_path YAML API provides version-controlled, auditor-readable permission configuration outside HCL. |
| Tag inheritance | _effective_default_tags merges 5 canonical tags (CostCenter, Project, Environment, ServiceName, DataClassification) onto every permission set. |
Minimum default_tags for CPS 234 compliance:
default_tags = {
CostCenter = "platform" # maps to FOCUS ServiceCategory
Project = "landing-zone" # maps to FOCUS SubAccountName
Environment = "prod" # ABAC: environment scoping
DataClassification = "restricted" # CPS 234: mandatory for privileged access
}
HITL Gates
The following deployment steps require human-in-the-loop (HITL) approval due to blast radius or irreversibility:
| Gate | Action | Reason |
|---|---|---|
| G1: First deploy | terraform apply to management account | Creates SSO instance-level resources; affects all accounts in Org |
| G2: Permission set changes | Any terraform apply modifying aws_ssoadmin_permission_set.* | Active sessions may be invalidated |
| G3: Account assignment removal | Removing entries from account_assignments | Immediately revokes access for affected principals |
| G4: Break-glass review | Applying AdministratorAccess to any new account | Requires second approver (4-eyes principle) |
Deployment order (avoid dependency errors):
aws_ssoadmin_permission_set(permission sets)aws_ssoadmin_managed_policy_attachment/ inline / boundaryaws_ssoadmin_account_assignment(assign to accounts last)
Rollback procedure:
# Identify the last known-good state
terraform state list | grep account_assignment
# Remove a specific account assignment without destroying the permission set
terraform state rm 'module.identity_center.aws_ssoadmin_account_assignment.account_assignment["admins_management"]'
# Re-import if needed after manual console fix
terraform import 'module.identity_center.aws_ssoadmin_account_assignment.account_assignment["admins_management"]' \
"<instance_arn>,<permission_set_arn>,GROUP,<group_id>,<account_id>"
For full rollback: revert the account_assignments variable to the prior Git commit and run terraform apply. The for_each reconciliation removes excess assignments idempotently.