Skip to content

Module Structure

terraform-aws-arc-iam-identity-center

Latest Release Last Updated Terraform GitHub Actions

Quality gate

Introduction

SourceFuse's AWS Reference Architecture (ARC) Terraform module facilitates the management of a comprehensive, reusable Terraform module for provisioning and managing AWS IAM Identity Center (AWS SSO) resources following AWS and Terraform best practices.

Features

  • Identity Center Management: Create or reference existing Identity Center instances
  • Permission Sets: Support for AWS managed, customer managed, and inline policies
  • Account Assignments: Flexible user/group to account/OU assignments
  • Identity Store: Optional user and group management
  • Conditional Resources: Smart resource creation based on input variables
  • AWS Best Practices: Follows naming conventions, tagging, and least-privilege principles

Requirements

Name Version
terraform >= 1.3
aws >= 5.0

Usage

Quick Start - Basic Setup

provider "aws" {
  region = var.region
}

variable "region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

module "aws_sso" {
  source = "sourcefuse/arc-iam-identity-center/aws"

  # Identity Center Configuration (optional - auto-discovers if not provided)
  identity_center_instance_arn = "arn:aws:sso:::instance/ssoins-1234567890abcdef"

  # Permission Sets
  permission_sets = {
    "AdminAccess" = {
      description      = "Full administrative access"
      session_duration = "PT8H"
      aws_managed_policies = [
        "arn:aws:iam::aws:policy/AdministratorAccess"
      ]
    }
    "ReadOnlyAccess" = {
      description      = "Read-only access across AWS services"
      session_duration = "PT4H"
      aws_managed_policies = [
        "arn:aws:iam::aws:policy/ReadOnlyAccess"
      ]
    }
  }

  # Create Groups
  identity_store_groups = {
    "Admins" = {
      display_name = "Administrators"
      description  = "System administrators"
    }
    "Developers" = {
      display_name = "Developers"
      description  = "Development team"
    }
  }

  # Account Assignments
  account_assignments = {
    "admins-full-access" = {
      permission_set_name = "AdminAccess"
      principal_type      = "GROUP"
      principal_id        = "Admins"
      target_type         = "AWS_ACCOUNT"
      target_id          = "123456789012"
    }
    "devs-readonly" = {
      permission_set_name = "ReadOnlyAccess"
      principal_type      = "GROUP"
      principal_id        = "Developers"
      target_type         = "AWS_ACCOUNT"
      target_id          = "123456789012"
    }
  }

  tags = {
    Environment = "production"
    Project     = "identity-management"
    Owner       = "platform-team"
  }
}

For the most intuitive experience, use our complete-user-group-management structure where everything about each user is defined in one place:

provider "aws" {
  region = var.region
}

variable "region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

module "aws_sso" {
  source = "sourcefuse/arc-iam-identity-center/aws"

  identity_center_instance_arn = "arn:aws:sso:::instance/ssoins-1234567890abcdef"

  # Permission Sets with clear descriptions
  permission_sets = {
    "FullAdmin" = {
      description      = "FULL ADMIN - Complete AWS access (use with caution)"
      session_duration = "PT2H"
      aws_managed_policies = ["arn:aws:iam::aws:policy/AdministratorAccess"]
    }
    "Developer" = {
      description      = "DEVELOPER - Can create/modify most resources except IAM"
      session_duration = "PT8H"
      aws_managed_policies = ["arn:aws:iam::aws:policy/PowerUserAccess"]
    }
    "ReadOnly" = {
      description      = "READ ONLY - Can view all resources but cannot modify"
      session_duration = "PT12H"
      aws_managed_policies = ["arn:aws:iam::aws:policy/ReadOnlyAccess"]
    }
  }

  # Users with groups and direct assignments in one place
  identity_store_users = {
    "john.manager" = {
      user_name    = "john.manager"
      display_name = "John Manager"
      given_name   = "John"
      family_name  = "Manager"
      email        = "john.manager@company.com"
      title        = "Engineering Manager"

      # Groups this user belongs to
      groups = ["Managers"]

      # Direct assignments (optional)
      direct_assignments = []
    }

    "alice.developer" = {
      user_name    = "alice.developer"
      display_name = "Alice Developer"
      given_name   = "Alice"
      family_name  = "Developer"
      email        = "alice.developer@company.com"
      title        = "Senior Software Engineer"

      # Groups this user belongs to
      groups = ["SeniorDevelopers"]

      # Additional direct access beyond group permissions
      direct_assignments = [
        {
          permission_set = "Developer"
          account_id     = "111111111111"  # Production account
          reason         = "Senior dev needs prod deployment access"
        }
      ]
    }
  }

  # Groups
  identity_store_groups = {
    "Managers" = {
      display_name = "Managers"
      description  = "Engineering and team managers"
    }
    "SeniorDevelopers" = {
      display_name = "Senior Developers"
      description  = "Experienced developers with advanced permissions"
    }
  }

  # Group-based account assignments
  account_assignments = {
    "managers-admin-prod" = {
      permission_set_name = "FullAdmin"
      principal_type      = "GROUP"
      principal_id        = "Managers"
      target_type         = "AWS_ACCOUNT"
      target_id          = "111111111111"
    }
    "senior-devs-dev-access" = {
      permission_set_name = "Developer"
      principal_type      = "GROUP"
      principal_id        = "SeniorDevelopers"
      target_type         = "AWS_ACCOUNT"
      target_id          = "222222222222"
    }
  }

  tags = {
    Environment = "multi-account"
    Project     = "arc"
    Owner       = "platform-team"
  }
}

Advanced Setup with Custom Policies

provider "aws" {
  region = var.region
}

variable "region" {
  description = "AWS region"
  type        = string
  default     = "us-east-1"
}

module "aws_sso" {
  source = "sourcefuse/arc-iam-identity-center/aws"

  identity_center_instance_arn = "arn:aws:sso:::instance/ssoins-1234567890abcdef"

  # Advanced permission sets with all policy types
  permission_sets = {
    "DataScientist" = {
      description      = "Data science and analytics access"
      session_duration = "PT12H"

      # AWS Managed Policies
      aws_managed_policies = [
        "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess",
        "arn:aws:iam::aws:policy/AmazonSageMakerReadOnly"
      ]

      # Customer Managed Policies (must exist in your account)
      customer_managed_policies = [
        {
          name = "DataLakeAccess"
          path = "/data-science/"
        }
      ]

      # Inline Policy for specific permissions
      inline_policy = jsonencode({
        Version = "2012-10-17"
        Statement = [
          {
            Effect = "Allow"
            Action = [
              "sagemaker:CreateNotebookInstance",
              "sagemaker:StartNotebookInstance"
            ]
            Resource = "*"
            Condition = {
              StringEquals = {
                "aws:RequestedRegion" = ["us-east-1", "us-west-2"]
              }
            }
          }
        ]
      })

      # Permission Boundary for security
      permissions_boundary = {
        customer_managed_policy_reference = {
          name = "DataScientistBoundary"
          path = "/boundaries/"
        }
      }
    }
  }

  # Rest of configuration...
  identity_store_groups = {
    "DataScience" = {
      display_name = "Data Science Team"
      description  = "Data scientists and ML engineers"
    }
  }

  account_assignments = {
    "datascience-prod" = {
      permission_set_name = "DataScientist"
      principal_type      = "GROUP"
      principal_id        = "DataScience"
      target_type         = "AWS_ACCOUNT"
      target_id          = "111111111111"
    }
  }

  tags = {
    Environment = "production"
    Project     = "advanced-sso"
    Owner       = "data-team"
  }
}

Examples

The examples/ directory contains several complete use cases:

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Run validation: make validate
  5. Submit a pull request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Requirements

Name Version
terraform >= 1.5.0
aws >= 5.0, < 7.0

Providers

Name Version
aws 4.67.0

Modules

No modules.

Resources

Name Type
aws_identitystore_group.main resource
aws_identitystore_group_membership.main resource
aws_identitystore_user.main resource
aws_ssoadmin_account_assignment.main resource
aws_ssoadmin_application.main resource
aws_ssoadmin_application_assignment.main resource
aws_ssoadmin_customer_managed_policy_attachment.customer_managed resource
aws_ssoadmin_managed_policy_attachment.aws_managed resource
aws_ssoadmin_permission_set.main resource
aws_ssoadmin_permission_set_inline_policy.inline resource
aws_ssoadmin_permissions_boundary_attachment.boundary resource
aws_ssoadmin_instances.existing data source

Inputs

Name Description Type Default Required
account_assignments Map of account assignments to create
map(object({
permission_set_name = string
principal_type = string
principal_id = string
target_type = string
target_id = string
}))
{} no
application_assignments Map of application assignments to create
map(object({
application_name = string
principal_type = string
principal_id = string
}))
{} no
applications Map of applications to create
map(object({
name = string
description = optional(string, "")
application_provider_arn = string
portal_options = optional(object({
sign_in_options = optional(object({
origin = string
application_url = optional(string)
}))
visibility = optional(string, "ENABLED")
}))
tags = optional(map(string), {})
}))
{} no
group_memberships Map of group memberships to create
map(object({
group_name = string
user_name = string
}))
{} no
identity_center_instance_arn ARN of existing Identity Center instance (optional - will auto-discover if not provided) string null no
identity_store_groups Map of Identity Store groups to create
map(object({
display_name = string
description = optional(string, "")
}))
{} no
identity_store_users Map of Identity Store users to create
map(object({
user_name = string
display_name = optional(string)
given_name = string
family_name = string
email = string
locale = optional(string, "en-US")
nickname = optional(string)
timezone = optional(string, "UTC")
title = optional(string)
groups = optional(list(string), [])
direct_assignments = optional(list(object({
permission_set = string
account_id = string
reason = optional(string, "")
})), [])
}))
{} no
name_prefix Prefix for resource names string "" no
name_suffix Suffix for resource names string "" no
permission_sets Map of permission sets to create
map(object({
description = optional(string, "")
session_duration = optional(string, "PT1H")
relay_state = optional(string)
aws_managed_policies = optional(list(string), [])
customer_managed_policies = optional(list(object({
name = string
path = optional(string, "/")
})), [])
inline_policy = optional(string)
permissions_boundary = optional(object({
customer_managed_policy_reference = optional(object({
name = string
path = optional(string, "/")
}))
managed_policy_arn = optional(string)
}))
tags = optional(map(string), {})
}))
{} no
tags A map of tags to assign to all resources map(string) {} no

Outputs

Name Description
account_assignments Map of created account assignments
application_assignments Map of created application assignments
applications Map of created applications
identity_center_instance_arn ARN of the Identity Center instance
identity_store_groups Map of created Identity Store groups
identity_store_id ID of the Identity Store
identity_store_users Map of created Identity Store users
permission_sets Map of created permission sets

Development

Prerequisites

Configurations

  • Configure pre-commit hooks
    pre-commit install
    
  • Configure golang deps for tests
    go get github.com/gruntwork-io/terratest/modules/terraform
    go get github.com/stretchr/testify/assert
    

Git commits

while Contributing or doing git commit please specify the breaking change in your commit message whether its major,minor or patch

For Example

git commit -m "your commit message #major"
By specifying this , it will bump the version and if you dont specify this in your commit message then by default it will consider patch and will bump that accordingly

Authors

This project is authored by: - SourceFuse