IAM Identity Center account assignments for Terraform member accounts
Once sandbox and development member accounts exist in AWS Organizations (for example from Terraform as in a companion article on that layout), they do not automatically appear in the AWS access portal. IAM Identity Center (successor to AWS SSO) shows an account only when there is an account assignment: a user or group mapped to a permission set in that account. This guide explains that model and shows a compact Terraform pattern: look up the SSO instance, resolve an existing permission set and group by name, and create aws_ssoadmin_account_assignment for each member account. It assumes a Control Tower–friendly landing zone where Identity Center is already enabled in the organization management account; it does not rehash Organizations account creation itself.
1. Overview
- Problem: New member accounts have root users and OrganizationAccountAccessRole, but directory users do not see the accounts in the access portal until assignments exist.
- Approach: Terraform calls SSO Admin and Identity Store in the region where Identity Center is enabled, then creates one assignment per account (sandbox and dev) for the same group and permission set.
-
How this article reads: The Terraform below uses fixed illustration values (region, permission set name, group display name) and no
count, toggles, orpreconditionblocks so the flow is easy to scan. In a real repo you usually add variables, optionalcount, and guardrails; a short note after the snippet calls that out. - Scope: Group principals and an existing permission set by name; creating permission sets or SCIM groups is out of scope here.
2. Prerequisites
- IAM Identity Center enabled in the org (management account or documented delegated admin); you know the region where the portal was turned on (often the home region you use for admin work).
- At least one permission set already defined (for example
AdministratorAccessorAWSPowerUserAccess) and one group with a known display name in the Identity Center directory. - Terraform 1.5+ and hashicorp/aws provider 5.x (examples below use patterns compatible with that stack).
- The IAM principal that runs Terraform must be allowed SSO Admin and Identity Store actions used by the provider (see §6). The same principal typically already has Organizations access if this module also manages accounts.
- Member account ids from Terraform outputs (or the console) for sandbox and dev.
Background: IAM Identity Center and Terraform aws_ssoadmin_account_assignment.
3. How the portal decides what to list
Flow (ASCII):
User opens access portal URL
|
v
IAM Identity Center ---- evaluates ----> Account assignments
(directory + permission sets) (group X + permission set P + account A)
|
v
User sees account tiles only where an assignment exists for that user or their groups
Account assignment ties three things together: principal (here a group), permission set (IAM role shape in the target account), and target (AWS account id). Without that row, the account stays invisible in the portal for directory users even if the account is healthy in Organizations.
4. Terraform shape
SSO Admin and Identity Store APIs are invoked in the region where IAM Identity Center is enabled. The snippet uses an aliased provider with a literal region so it is obvious what to change first if your portal runs elsewhere (for example us-east-1).
Replace for your org: ap-southeast-2, AdministratorAccess, AWSControlTowerAdmins, and ensure aws_organizations_account.sandbox_1 / dev_1 match your module (or substitute 12-digit account ids).
provider "aws" {
alias = "identity_center"
region = "ap-southeast-2"
}
data "aws_ssoadmin_instances" "this" {
provider = aws.identity_center
}
data "aws_ssoadmin_permission_set" "assignment" {
provider = aws.identity_center
instance_arn = one(data.aws_ssoadmin_instances.this.arns)
name = "AdministratorAccess"
}
data "aws_identitystore_group" "assignment" {
provider = aws.identity_center
identity_store_id = one(data.aws_ssoadmin_instances.this.identity_store_ids)
alternate_identifier {
unique_attribute {
attribute_path = "DisplayName"
attribute_value = "AWSControlTowerAdmins"
}
}
}
resource "aws_ssoadmin_account_assignment" "sandbox_1" {
provider = aws.identity_center
instance_arn = one(data.aws_ssoadmin_instances.this.arns)
permission_set_arn = data.aws_ssoadmin_permission_set.assignment.arn
principal_id = data.aws_identitystore_group.assignment.group_id
principal_type = "GROUP"
target_id = aws_organizations_account.sandbox_1.id
target_type = "AWS_ACCOUNT"
}
resource "aws_ssoadmin_account_assignment" "dev_1" {
provider = aws.identity_center
instance_arn = one(data.aws_ssoadmin_instances.this.arns)
permission_set_arn = data.aws_ssoadmin_permission_set.assignment.arn
principal_id = data.aws_identitystore_group.assignment.group_id
principal_type = "GROUP"
target_id = aws_organizations_account.dev_1.id
target_type = "AWS_ACCOUNT"
}
principal_type can be USER if you resolve a user and pass that principal id instead; groups are a common default for team access.
Production note: Real modules usually parameterize the region, permission set name, and group display name (for example with variables), and sometimes wrap assignments in count or use lifecycle.precondition so you never plan with an empty group name or enable SSO changes by mistake. The literal version above is only for reading the happy path.
5. IAM permissions for the Terraform principal
Your role or user needs API access for read paths (instance, permission set, group lookup) and write paths (CreateAccountAssignment, DeleteAccountAssignment on destroy). Typical action families include SSO Admin (sso:ListInstances, sso:DescribePermissionSet, sso:CreateAccountAssignment, …) and Identity Store (identitystore:GetGroupId, identitystore:DescribeGroup, …). Tighten ARNs and actions in a real policy; start from the Terraform plan error messages if something is missing.
6. Summary: Copy-paste
After pasting the resources into your root module and fixing the illustration strings:
export AWS_PROFILE=YourManagementProfile
terraform plan
terraform apply
Confirm in IAM Identity Center → Multi-account permissions → AWS accounts (wording varies by console revision) that assignments exist for sandbox and dev. Ask a member of the group to open the access portal and verify two new account tiles (after propagation, which can take a short time).
7. Troubleshooting
-
AccessDeniedonsso:ListInstances: The caller’s policy omits SSO Admin permissions, or Terraform is using the wrong region for the aliased provider. -
GetGroupIdvalidation / empty attribute:attribute_valuefor the group was empty or wrong; set it to the exact display name from IAM Identity Center → Groups. -
Permission set not found: The
nameinaws_ssoadmin_permission_setdoes not match any permission set name in your directory (names are not always identical to AWS managed policy names in the console). - Group not found / ambiguous display name: DisplayName must be unique enough for the lookup; prefer the exact string from Groups in the console.
- Account still missing in portal: Assignment targets the wrong account id; user is not in the assigned group; or propagation not finished yet.
Top comments (0)