Streamlining AWS SSO in Complex Multi-Account Environments

Transitioning to Automated SSO: A Comprehensive Guide to Moving Away from Manual SSO Creation in AWS

GirishCodeAlchemy
8 min readJan 22, 2024

Introduction

In today’s dynamic landscape of cloud infrastructure, managing access and authentication across multiple AWS accounts can be a challenging task. As organizations scale their presence on the AWS cloud, the need for a robust Single Sign-On (SSO) solution becomes increasingly evident. This blog aims to delve into the details of AWS SSO automation, offering insights into efficiently orchestrating user access in complex multi-account environments. We will delve into the challenges of manual SSO creation and present a comprehensive guide on transitioning to an automated approach, providing a roadmap for enhancing security, scalability, and overall operational efficiency.

Challenges of Manual SSO Creation:

  1. Tedious User Access Configuration:
    Manually configuring individual user access across multiple AWS accounts is a time-consuming and labor-intensive task.
  2. Potential for Human Errors:
    The manual nature of SSO creation introduces the risk of human errors in permission assignments, leading to security vulnerabilities and compliance concerns.
  3. Inefficiencies in Permission Management:
    Managing permissions manually can result in inefficiencies, as each user and group may have unique configurations that must be meticulously handled.
  4. Operational Overhead:
    The manual approach adds operational overhead, requiring significant time and effort to ensure accurate and consistent SSO configurations across accounts.
  5. Limitations in Scalability:
    As organizations expand their AWS footprint, the limitations of manual SSO creation become more apparent, hindering scalability and adaptability to evolving infrastructure needs.
  6. Security Concerns:
    Manual processes increase the risk of security vulnerabilities, as errors in permission assignments may lead to unauthorized access and potential data breaches.
  7. Complexity with Growing AWS Presence:
    The challenges amplify as the AWS presence grows, making manual SSO creation increasingly complex and prone to inconsistencies.

The Road to Automation:

Automating AWS SSO processes not only addresses the challenges posed by manual configurations but also brings forth a range of benefits. A well-implemented automation strategy enhances security by enforcing consistent access policies and reduces the risk of human errors in permission assignments. Scalability is significantly improved, allowing organizations to seamlessly adapt to the evolving demands of their cloud infrastructure. Additionally, the time and effort saved through automation can be redirected towards more strategic initiatives, fostering innovation and agility.

Key Components of AWS SSO Automation:

  1. Terraform Infrastructure as Code (IaC): Leveraging Terraform, an IaC tool, facilitates the codification of AWS SSO configurations. This not only streamlines the provisioning of SSO resources but also ensures version-controlled, repeatable, and auditable infrastructure changes.
  2. AWS SSO Terraform Module: Introducing the GirishCodeAlchemy AWS SSO Terraform Module, now available on the Terraform Registry. Designed to simplify the orchestration of AWS SSO resources, this module empowers your environment with the flexibility to manage multiple hierarchies seamlessly. Easily provision and configure AWS SSO components, including identity store, users, groups, and permissions, using this modular and user-friendly solution.

Prerequisites

Before diving into the automation process, ensure you have the following prerequisites:

  • Identity Store configured
  • Relevant AWS accounts and permission sets defined

Terraform Setup

We’ll use Terraform for this automation. Ensure you have Terraform installed, and set up your project directory.

Terraform Module Usage:

Simplify your AWS SSO implementation with the GirishCodeAlchemy/sso-module/aws Terraform Module. Use the provided example configuration to get started:

data "aws_ssoadmin_instances" "ssoadmin" {
# Retrieve information about existing SSO instances, if needed.
}

module "sso" {
source = "GirishCodeAlchemy/sso-module/aws"
version = "1.0.0"
identity_store_ids = data.aws_ssoadmin_instances.ssoadmin.identity_store_ids
ssoadmin_instance_arns = data.aws_ssoadmin_instances.ssoadmin.arns
sso_user_configmap = var.sso_user_configmap
sso_groups_configmap = var.sso_groups_configmap
sso_permissionsets_configmap = var.sso_permissionsets_configmap
sso_account_configmap = var.sso_account_configmap
}

Variables Configuration Examples:
The GirishCodeAlchemy AWS SSO Terraform Module includes a set of variables for configuring users, groups, permission sets, and accounts. Here are some examples to guide you through the configuration process:

  • identity_store_ids
identity_store_ids = ["d-dssdaa"] # data.aws_ssoadmin_instances.ssoadmin.identity_store_id
ssoadmin_instance_arns = ["arn:aws:sso:::instance/ssoins-xxxxxxxxxx"] # data.aws_ssoadmin_instances.ssoadmin.arns
  • sso_user_configmap
sso_user_configmap = {
girish1 = {
display_name = "Girish V"
user_name = "girish1"
given_name = "Girish"
family_name = "V"
email = "girish1@example.com"
},
girish2 = {
display_name = "Girish V"
user_name = "girish2"
given_name = "Girish"
family_name = "V"
email = "girish2@example.com"
}
}
  • sso_groups_configmap
sso_groups_configmap = {
"L1-devops-group" = {
display_name = "L1-devops-group"
description = "This is AWS L1 Devops Group"
users = ["girish1", "girish2"]
},
"L1-Admin-group" = {
display_name = "L1-Admin-group"
description = "This is AWS L1 Admin Group"
users = ["girish1"]
}
}
  • sso_permissionsets_configmap
sso_permissionsets_configmap = {
"SSM-Admin-permissionset" = {
name = "SSM-Admin-permissionset"
description = "Sample Admin permissionset"
managed_policy_arns = [
"arn:aws:iam::aws:policy/AmazonEC2FullAccess",
"arn:aws:iam::aws:policy/job-function/ViewOnlyAccess",
]
inline_policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:*",
],
"Resource": "*"
}
]
}
EOF
},
"SSM-testing-permissionset" = {
name = "SSM-testing-permissionset"
description = "Sample testing permissionset"
managed_policy_arns = ["arn:aws:iam::aws:policy/AmazonEC2FullAccess"]
inline_policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation"
],
"Resource": "arn:aws:s3:::*"
}
]
}
EOF
}
}
  • sso_account_configmap
sso_account_configmap = {
"1xxxxxxxx" = {
users = {
girishcodealchemy = {
username = "girishcodealchemy",
permissionset = [
"SSM-testing-permissionset",
"SSM-Admin-permissionset"
]
}
}
groups = {
L1devopsgroup = {
groupname = "L1-devops-group",
permissionset = [
"SSM-testing-permissionset",
"SSM-Admin-permissionset"
]
}
}
},
"2xxxxxxxx" = {
users = {
girishcodealchemy = {
username = "girishcodealchemy",
permissionset = [
"SSM-testing-permissionset"
]
}
}
groups = {
L1devopsgroup = {
groupname = "L1-devops-group",
permissionset = ["SSM-testing-permissionset"]
},
L1AdminGroup = {
groupname = "L1-Admin-group",
permissionset = ["SSM-Admin-permissionset"]
}
}
}
}

Terraform Plan and Apply

Users Created

Groups and Members Created

Permission Sets Created

Mapped Users , Groups & Permission sets to the Accounts

Implementation Resources:

A Guide for Creating Resources from Scratch

Setting up AWS SSO automation from scratch involves creating necessary resources using Terraform. This guide outlines the steps to implement your own AWS SSO solution.

  1. AWS Identity Store User Configuration
    Automate the creation and configuration of AWS Identity Store users using the aws_identitystore_user resource. This resource creates a user in the AWS Identity Store. The user’s display name, username, given name, family name, and email are all configurable.

Define user configurations in the sso_user_configmapvariable. The example code snippet illustrates the Terraform implementation

#Terraform code for AWS SSO Users

resource "aws_identitystore_user" "aws_user" {
for_each = var.sso_user_configmap
identity_store_id = element(var.identity_store_ids, 0)

display_name = each.value.display_name
user_name = each.value.user_name

name {
given_name = each.value.given_name
family_name = each.value.family_name
}

emails {
primary = true
value = each.value.email
}

lifecycle {
ignore_changes = [
name,
emails,
]
}
}

2. AWS Identity Store Group Configuration:
Start by defining AWS Identity Store groups and their memberships. Use the aws_identitystore_group and aws_identitystore_group_membership resources to create the necessary group structures

Define group and member configurations in the sso_groups_configmapvariable. The example code snippet showcases the Terraform implementation:

#Terraform code for AWS SSO Groups and Membership

resource "aws_identitystore_group" "aws_group" {
for_each = var.sso_groups_configmap
identity_store_id = element(var.identity_store_ids, 0)
display_name = each.value.display_name
description = each.value.description
}

resource "aws_identitystore_group_membership" "example" {
for_each = { for identity in local.flattened_groups : "${identity.group_key}-${identity.user_key}" => identity }
identity_store_id = element(var.identity_store_ids, 0)
group_id = aws_identitystore_group.aws_group[each.value.group_key].group_id
member_id = aws_identitystore_user.aws_user[each.value.user_key].user_id
}

3. AWS SSO Admin Permission Sets:
Define AWS SSO permission sets that align with your organization’s access policies. Use aws_ssoadmin_permission_set aws_ssoadmin_permission_set_inline_policy and aws_ssoadmin_managed_policy_attachment resources.

Define Permission Set , Inline policy and managed_policy in the sso_permissionsets_configmapvariable.
The example code snippet showcases the Terraform implementation:

#Terraform code for AWS SSO Admin Permission Set

resource "aws_ssoadmin_permission_set" "permissionset" {
for_each = var.sso_permissionsets_configmap
name = each.value.name
description = each.value.description
instance_arn = tolist(var.ssoadmin_instance_arns)[0]
}

resource "aws_ssoadmin_permission_set_inline_policy" "inline_policy" {
for_each = var.sso_permissionsets_configmap
inline_policy = each.value.inline_policy
instance_arn = tolist(var.ssoadmin_instance_arns)[0]
permission_set_arn = aws_ssoadmin_permission_set.permissionset[each.key].arn
}
resource "aws_ssoadmin_managed_policy_attachment" "managed_policy_attachment" {
for_each = { for i in local.flattened_managed_policy_attachments : "${i.permission_set_name}-${i.managed_policy_arn}" => i }
instance_arn = tolist(var.ssoadmin_instance_arns)[0]
managed_policy_arn = each.value.managed_policy_arn
permission_set_arn = aws_ssoadmin_permission_set.permissionset[each.value.permission_set_name].arn

depends_on = [aws_ssoadmin_account_assignment.sso_account_user, aws_ssoadmin_account_assignment.sso_account_group, ]
}

[NOTE] Adding an explicit dependency on the account assignment resource will allow the managed policy attachment to be safely destroyed prior to the removal of the account assignment.

4. AWS SSO Admin Account Assignment:
Automate the assignment of AWS SSO permission sets to groups or users across multiple accounts using aws_ssoadmin_account_assignment.

Define Users, Groups, list of permission sets mapped in the sso_account_configmapvariable.
The example code snippet showcases the Terraform implementation:

#Terraform code for AWS SSO Admin Account Assignment

resource "aws_ssoadmin_account_assignment" "sso_account_user" {
for_each = { for config in local.flatten_user_configurations : "${config.account}.${config.username}.${config.permissionset}" => config }

instance_arn = tolist(var.ssoadmin_instance_arns)[0]
target_id = each.value.account
target_type = "AWS_ACCOUNT"
principal_id = data.aws_identitystore_user.aws_user["${each.value.account}.${each.value.username}"].user_id
principal_type = "USER"
permission_set_arn = data.aws_ssoadmin_permission_set.aws_user_permissionset[each.key].arn
}

resource "aws_ssoadmin_account_assignment" "sso_account_group" {
for_each = { for config in local.flatten_group_configurations : "${config.account}.${config.groupname}.${config.permissionset}" => config }

instance_arn = tolist(var.ssoadmin_instance_arns)[0]
target_id = each.value.account
target_type = "AWS_ACCOUNT"
principal_id = data.aws_identitystore_group.aws_group["${each.value.account}.${each.value.groupname}"].group_id
principal_type = "GROUP"
permission_set_arn = data.aws_ssoadmin_permission_set.aws_group_permissionset[each.key].arn
}

Conclusion

Automating AWS SSO configurations for complex multi-account environments brings efficiency and consistency to access management. This blog post provided a basic guide using Terraform. Tailor these configurations to fit your organization’s specific requirements and enjoy a streamlined AWS SSO experience.

🚀 Stay tuned for more empowering insights into the world of cloud infrastructure management. Happy SSO automating! 🌐

--

--