Skip to main content

AWS IAM Identity Center Terraform Module

Derived from aws-ia/terraform-aws-iam-identity-center v1.0.4 (Apache-2.0). See NOTICE.

Features

  • Dynamic User Creation
  • Dynamic Group Creation
  • Dynamic Group Membership Creation
  • Dynamic Permission Set Creation
  • Dynamic Account Assignment Creation
  • Dynamic Reference of Existing Users
  • Dynamic Reference of Existing Groups
  • AWS Managed Policy Support
  • Customer Managed Policy Support
  • Dynamic Application Creation (with Portal Options, Users and Groups assignments and Assignments Access Scopes configuration)

Important

  • Locals are used to allow for global changes to multiple account assignments. If hard coding the account ids for your account assignments, you would need to change them in every place you want to reference the value. To simplify this, we recommend storing your desired account ids in local values. See the examples directory for more information and sample code.
  • When using Customer Managed Policies with account assignments, you must ensure these policies exist in all target accounts before using the module. Failure to do this will cause deployment errors because IAM Identity Center will attempt to reference policies that do not exist.
  • The names of your object(s) (e.g. the groups or users you wish to create or reference) are used to reference them elsewhere within the module, such as referencing groups you wish to add users to, or permission sets you wish to use with your account assignments. While the names of these objects can be anything since they are just local references to the each object, ensure you reference the string exactly (case-sensitive) when using elsewhere in the module.
    • However, for the actual names of the existing groups, users, etc. these must match exactly as they appear in your AWS IAM Identity Center configuration. This is because for these resources, a data source is being used to fetch information about the existing resource using a filter on the name.
    • To simplify this and prevent confusion, we recommend using the same name for the object as the resource itself. See the following for an example:
  sso_groups = {
Admin : {
group_name = "Admin"
group_description = "Admin IAM Identity Center Group"
},
}

// Create desired USERS in IAM Identity Center
sso_users = {
nuzumaki : {
group_membership = ["Admin",]
user_name = "nuzumaki"
given_name = "Naruto"
family_name = "Uzumaki"
email = "[email protected]"
},
}

// Create desired Applications in IAM Identity Center
sso_applications = {
FirstApplication : {
application_provider_arn = "arn:aws:sso::aws:applicationProvider/custom"
description = "I am the First Application"
name = "FirstApplication"
portal_options = {
sign_in_options = {
application_url = "http://example.com"
origin = "APPLICATION"
}
visibility = "ENABLED"
}
status = "ENABLED"
assignment_required = true
assignments_access_scope = [
{
authorized_targets = ["FirstApplication"]
scope = "sso:account:access"
}
]
group_assignments = ["Dev"]
user_assignments = ["nuzumaki"]
}
}

The object/principal names are referenced throughout the module. Failure to follow this guidance may lead to unintentional errors such as the following:

Error: Invalid index

│ on ../../main.tf line 141, in resource "aws_identitystore_group_membership" "sso_group_membership":
│ 141: member_id = (contains(local.this_users, each.value.user_name) ? aws_identitystore_user.sso_users[each.value.user_name].user_id : data.aws_identitystore_user.existing_sso_users[each.value.user_name].id)
│ ├────────────────
│ │ aws_identitystore_user.sso_users is object with 2 attributes
│ │ each.value.user_name is "nuzumaki"

│ The given key does not identify an element in this collection value.

To resolve this, ensure your object and principal names are the same (case-sensitive) and re-run terraform plan and terraform apply.

Basic Usage - Create Users and Groups with AWS Managed Policies

// This is a template file for a basic deployment.
// Modify the parameters below with actual values

module "aws-iam-identity-center" {
source = "aws-ia/iam-identity-center/aws"

// Create desired GROUPS in IAM Identity Center
sso_groups = {
Admin : {
group_name = "Admin"
group_description = "Admin IAM Identity Center Group"
},
Dev : {
group_name = "Dev"
group_description = "Dev IAM Identity Center Group"
},
QA : {
group_name = "QA"
group_description = "QA IAM Identity Center Group"
},
Audit : {
group_name = "Audit"
group_description = "Audit IAM Identity Center Group"
},
}

// Create desired USERS in IAM Identity Center
sso_users = {
nuzumaki : {
group_membership = ["Admin", "Dev", "QA", "Audit"]
user_name = "nuzumaki"
given_name = "Naruto"
family_name = "Uzumaki"
email = "[email protected]"
},
suchiha : {
group_membership = ["QA", "Audit"]
user_name = "suchiha"
given_name = "Sasuke"
family_name = "Uchiha"
email = "[email protected]"
},
}

// Create permissions sets backed by AWS managed policies
permission_sets = {
AdministratorAccess = {
description = "Provides AWS full access permissions.",
session_duration = "PT4H", // how long until session expires - this means 4 hours. max is 12 hours
aws_managed_policies = ["arn:aws:iam::aws:policy/AdministratorAccess"]
tags = { ManagedBy = "Terraform" }
},
ViewOnlyAccess = {
description = "Provides AWS view only permissions.",
session_duration = "PT3H", // how long until session expires - this means 3 hours. max is 12 hours
aws_managed_policies = ["arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"]
tags = { ManagedBy = "Terraform" }
},
CustomPermissionAccess = {
description = "Provides CustomPoweruser permissions.",
session_duration = "PT3H", // how long until session expires - this means 3 hours. max is 12 hours
aws_managed_policies = [
"arn:aws:iam::aws:policy/ReadOnlyAccess",
"arn:aws:iam::aws:policy/AmazonS3FullAccess",
]
inline_policy = data.aws_iam_policy_document.CustomPermissionInlinePolicy.json

// Only either managed_policy_arn or customer_managed_policy_reference can be specified.
// Before using customer_managed_policy_reference, first deploy the policy to the account.
// Don't in-place managed_policy_arn to/from customer_managed_policy_reference, delete it once.
permissions_boundary = {
// managed_policy_arn = "arn:aws:iam::aws:policy/PowerUserAccess"

customer_managed_policy_reference = {
name = "ExamplePermissionsBoundaryPolicy"
// path = "/"
}
}
tags = { ManagedBy = "Terraform" }
},
}

// Assign users/groups access to accounts with the specified permissions
account_assignments = {
Admin : {
principal_name = "Admin" # name of the user or group you wish to have access to the account(s)
principal_type = "GROUP" # principal type (user or group) you wish to have access to the account(s)
principal_idp = "INTERNAL" # type of Identity Provider you are using. Valid values are "INTERNAL" (using Identity Store) or "EXTERNAL" (using external IdP such as EntraID, Okta, Google, etc.)
permission_sets = ["AdministratorAccess", "ViewOnlyAccess"] # permissions the user/group will have in the account(s)
account_ids = [ # account(s) the group will have access to. Permissions they will have in account are above line
"111111111111", // replace with your desired account id
"222222222222", // replace with your desired account id
]
},
Audit : {
principal_name = "Audit"
principal_type = "GROUP"
principal_idp = "INTERNAL"
permission_sets = ["ViewOnlyAccess"]
account_ids = [
"111111111111",
"222222222222",
]
},
}

}

Basic Usage - Create Applications and assign to Users and Groups

  // Create desired Applications in IAM Identity Center
sso_applications = {
FirstApplication : {
application_provider_arn = "arn:aws:sso::aws:applicationProvider/custom"
description = "I am the First Application"
name = "FirstApplication"
portal_options = {
sign_in_options = {
application_url = "http://example.com"
origin = "APPLICATION"
}
visibility = "ENABLED"
}
status = "ENABLED"
assignment_required = true
assignments_access_scope = [
{
authorized_targets = ["FirstApplication"]
scope = "sso:account:access"
}
]
group_assignments = ["Dev"]
user_assignments = ["nuzumaki"]
}
}

Contributing

See the CONTRIBUTING.md file for information on how to contribute.

Requirements

Requirements

NameVersion
terraform>= 1.11.0
aws>= 6.28, < 7.0

Providers

Providers

NameVersion
aws>= 6.28, < 7.0

Resources

Resources

NameType
aws_identitystore_group.sso_groupsresource
aws_identitystore_group_membership.sso_group_membershipresource
aws_identitystore_group_membership.sso_group_membership_existing_google_sso_usersresource
aws_identitystore_user.sso_usersresource
aws_ssoadmin_account_assignment.account_assignmentresource
aws_ssoadmin_application.sso_appsresource
aws_ssoadmin_application_access_scope.sso_apps_assignments_access_scoperesource
aws_ssoadmin_application_assignment.sso_apps_groups_assignmentsresource
aws_ssoadmin_application_assignment.sso_apps_users_assignmentsresource
aws_ssoadmin_application_assignment_configuration.sso_apps_assignments_configsresource
aws_ssoadmin_customer_managed_policy_attachment.pset_customer_managed_policyresource
aws_ssoadmin_instance_access_control_attributes.sso_access_control_attributesresource
aws_ssoadmin_managed_policy_attachment.pset_aws_managed_policyresource
aws_ssoadmin_permission_set.psetresource
aws_ssoadmin_permission_set_inline_policy.pset_inline_policyresource
aws_ssoadmin_permissions_boundary_attachment.pset_permissions_boundary_aws_managedresource
aws_ssoadmin_permissions_boundary_attachment.pset_permissions_boundary_customer_managedresource
aws_identitystore_group.existing_sso_groupsdata source
aws_identitystore_user.existing_google_sso_usersdata source
aws_identitystore_user.existing_sso_usersdata source
aws_organizations_organization.organizationdata source
aws_ssoadmin_instances.sso_instancedata source
aws_ssoadmin_permission_set.existing_permission_setsdata source

Inputs

Inputs

NameDescriptionTypeDefaultRequired
account_assignmentsList of maps containing mapping between user/group, permission set and assigned accounts list. See account_assignments description in README for more information about map values.
map(object({
principal_name = string
principal_type = string
principal_idp = string # acceptable values are either "INTERNAL" or "EXTERNAL"
permission_sets = list(string)
account_ids = list(string)
}))
\{\}no
config_pathPath to YAML configuration directory for APRA CPS 234 audit trail. When set, reads permission_sets.yaml and account_assignments.yaml from this directory, merged with HCL variable values (YAML values take precedence).string""no
default_tagsTags applied to all permission sets. Overrides module defaults. Required keys when non-empty: CostCenter, Project, Environment, DataClassification.map(string){}no
enable_organizations_lookupEnable Organizations data source for account-name-to-ID resolution. Set false for standalone accounts or when all account_assignments use 12-digit account IDs.booltrueno
existing_google_sso_usersNames of the existing Google users that you wish to reference from IAM Identity Center.
map(object({
user_name = string
group_membership = optional(list(string), null) // only used if your IdP only syncs users, and you wish to manage which groups they should go in
}))
\{\}no
existing_permission_setsNames of the existing permission_sets that you wish to reference from IAM Identity Center.
map(object({
permission_set_name = string
}))
\{\}no
existing_sso_groupsNames of the existing groups that you wish to reference from IAM Identity Center.
map(object({
group_name = string
}))
\{\}no
existing_sso_usersNames of the existing users that you wish to reference from IAM Identity Center.
map(object({
user_name = string
group_membership = optional(list(string), null) // only used if your IdP only syncs users, and you wish to manage which groups they should go in
}))
\{\}no
permission_setsPermission Sets that you wish to create in IAM Identity Center. This variable is a map of maps containing Permission Set names as keys. See permission_sets description in README for information about map values.any{}no
sso_applicationsList of applications to be created in IAM Identity Center
map(object({
name = string
application_provider_arn = string
description = optional(string)
portal_options = optional(object({
sign_in_options = optional(object({
application_url = optional(string)
origin = string
}))
visibility = optional(string)
}))
status = string # acceptable values are "ENABLED" or "DISABLED"
client_token = optional(string)
tags = optional(map(string))
assignment_required = bool # Resource: aws_ssoadmin_application_assignment_configuration
assignments_access_scope = optional(
list(object({
authorized_targets = optional(list(string)) # List of application names
scope = string
}))
) # Resource: aws_ssoadmin_application_access_scope
group_assignments = optional(list(string)) # Resource aws_ssoadmin_application_assignment, keeping it separated for groups
user_assignments = optional(list(string)) # Resource aws_ssoadmin_application_assignment, keeping it separated for users
}))
\{\}no
sso_groupsNames of the groups you wish to create in IAM Identity Center.
map(object({
group_name = string
group_description = optional(string, null)
}))
\{\}no
sso_instance_access_control_attributesList of attributes for access control. This is used to create the enable and use attributes for access control.
list(object({
attribute_name = string
source = set(string)
}))
[]no
sso_usersNames of the users you wish to create in IAM Identity Center.
map(object({
display_name = optional(string)
user_name = string
# NOTE: Empty list [] is intentionally valid — represents a standalone user
# without group assignments (e.g. service accounts, direct permission set users).
# A validation requiring length > 0 would be a BREAKING CHANGE for existing consumers.
group_membership = list(string)
# Name
given_name = string
middle_name = optional(string, null)
family_name = string
name_formatted = optional(string)
honorific_prefix = optional(string, null)
honorific_suffix = optional(string, null)
# Email
email = string
email_type = optional(string, null)
is_primary_email = optional(bool, true)
# Phone Number
phone_number = optional(string, null)
phone_number_type = optional(string, null)
is_primary_phone_number = optional(bool, true)
# Address
country = optional(string, null)
locality = optional(string, null)
address_formatted = optional(string)
postal_code = optional(string, null)
is_primary_address = optional(bool, true)
region = optional(string, null)
street_address = optional(string, null)
address_type = optional(string, null)
# Additional
user_type = optional(string, null)
title = optional(string, null)
locale = optional(string, null)
nickname = optional(string, null)
preferred_language = optional(string, null)
profile_url = optional(string, null)
timezone = optional(string, null)
}))
\{\}no

Outputs

Outputs

NameDescription
account_assignment_dataTuple containing account assignment data
config_pathPath to YAML configuration directory for APRA CPS 234 audit trail
identity_store_idThe ID of the Identity Store
permission_set_arnsA map of permission set name to ARN
principals_and_assignmentsMap containing account assignment data
sso_applications_arnsA map of SSO Applications ARNs created by this module
sso_applications_group_assignmentsA map of SSO Applications assignments with groups created by this module
sso_applications_user_assignmentsA map of SSO Applications assignments with users created by this module
sso_groups_idsA map of SSO groups ids created by this module
sso_instance_arnThe ARN of the SSO instance
sso_users_idsA map of SSO user IDs created by this module