AWS Cloud Operations & Migrations Blog

How SMBs can deploy a multi-account environment quickly using AWS Organizations and AWS CloudFormation StackSets

Small and Medium Businesses (SMBs) need to operate with high availability and mitigate security risks while keeping costs low. An AWS multi-account environment with workload isolation, robust access control, cost visualization, and integrated security mechanisms can help SMBs build a platform to support growth. SMBs want to deploy a multi-account environment on AWS quickly and securely to maximize the benefits of cloud.

Last year we published the Multi-account strategy for small and medium businesses blog post that delved into why SMBs should build a multi-account cloud environment, and the AWS best practices for setting one up. In this blog post, we will walk through the setup of a simple, secure, and scalable multi-account environment built using AWS Organizations and AWS IAM Identity Center, and deployed using AWS CloudFormation templates. Using the solution in this blog post, SMBs can deploy a multi-account environment in as little as 30 minutes to streamline their AWS infrastructure. With the right foundation in place, SMBs can easily leverage security and governance services and features to manage their environment at scale, and lower their administrative burden.

If you’d like to set up and manage your multi-account environment with prescriptive guidance, you can also consider AWS Control Tower.

Solution Overview

AWS Organizations implements a hierarchical account structure with a single management account and member accounts. It allows you to implement workload isolation, centralize monitoring and centrally manage security policies. It also enables access to a large number of security services from AWS that integrate with AWS Organizations to efficiently manage your security posture without a dedicated security expert.  AWS IAM Identity Center allows you to manage workforce access to your multi-account environment. It is a flexible solution that can be used to connect your existing identity source or help you create users in AWS.

When the AWS CloudFormation template is deployed, the resultant set up will be as shown in the Image 1.

Image 1: Sample multi-account environment deployed with the CloudFormation StackSet

Image 1: Sample multi-account environment deployed with the CloudFormation StackSet

Deployment Steps

The deployment will be performed in 3 steps:

  1. First, we will deploy an AWS CloudFormation template to setup an organization, and necessary resources.
  2. Then we will manually enable AWS IAM Identity Center for our organization.
  3. Finally, we will update the CloudFormation template in step 1 to associate the organization with IAM Identity Center instance created in step 2.

Prerequisite

When setting up a multi-account environment we recommend that

  • You create a new, empty AWS account to be your management account, where you will deploy the AWS CloudFormation StackSet that will create the multi-account environment.
  • Use an alias or group email id to set up the management account.
  • Do not use an email address associated with an individual as it can cause issues if that person leaves the organization.
  • Ensure you activate MFA for your root user.
  • If you have any existing workload accounts, you can invite them to join as member accounts once you set up your organization.

Walkthrough

In the solution discussed in this blog post, you will deploy a CloudFormation StackSet template (CFN template) to spin up a lean AWS Organizations following AWS best practice guidance. We will also provide other recommendations that you need to set up outside of this template.

Deploy the AWS Organizations with the CFN template

To bootstrap your AWS Organizations in your new account, deploy the template.yml. This template takes the following parameters

  • pSSOInstanceId: Leave this blank for now. We’ll set up IAM Identity Center for single sign-on in a later step.
  • pDeveloperPrefix: Used for naming self-service IAM roles and CloudFormation stacks in member accounts. Defaults to app.
  • pCloudFormationRoleName: IAM Role used by CloudFormation to deploy stacks in member accounts. Defaults to CloudFormationRole.
  • pRegions: Regions in which to deploy the StackSets. Defaults to us-east-1. Include any regions you plan to use.
  • pSandboxOuName: A name for the sandbox OU. Defaults to Sandbox.
  • pSecurityOuName: A name for the security OU. Defaults to Security_Prod.

To deploy this template, perform the following steps

  1. Download the AWS Serverless Application Model (AWS SAM) CLI.
  2. Download (or clone) the sample code from GitHub and extract it to your local machine.
  3. Open a command prompt (terminal) and navigate to the folder where you extracted the template.
  4. Type the following commands into the command prompt to deploy the template
    1. sam build
    2. sam deploy –guided
  5. Provide the necessary parameter values when prompted to do so.
Configuring SAM deploy
======================

	Looking for config file [samconfig.toml] :  Not found

	Setting default arguments for 'sam deploy'
	=========================================
	Stack Name [sam-app]: orgs-landing-zone         
	AWS Region [us-east-1]: 
	Parameter pSSOInstanceId []: 
	Parameter pDeveloperPrefix [app]: 
	Parameter pCloudFormationRoleName [CloudFormationRole]: 
	Parameter pServiceCatalogRoleName [ServiceCatalogRole]: 
	Parameter pRegions [us-east-1]: 
	Parameter pSandboxOuName [Sandbox]: 
	Parameter pSecurityOuName [Security_Prod]: 
	#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
	Confirm changes before deploy [y/N]: Y
	#SAM needs permission to be able to create roles to connect to the resources in your template
	Allow SAM CLI IAM role creation [Y/n]: n
	Capabilities [['CAPABILITY_IAM']]: CAPABILITY_IAM CAPABILITY_NAMED_IAM
	#Preserves the state of previously provisioned resources when an operation fails
	Disable rollback [y/N]: 
	Save arguments to configuration file [Y/n]: Y
	SAM configuration file [samconfig.toml]: 
	SAM configuration environment [default]: 

	Looking for resources needed for deployment:

	Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xxxxx
	A different default S3 bucket can be set in samconfig.toml and auto resolution of buckets turned off by setting resolve_s3=False

	Saved arguments to config file
	Running 'sam deploy' for future deployments will use the parameters saved above.
	The above parameters can be changed by modifying samconfig.toml
	Learn more about samconfig.toml syntax at 
	https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html

	Uploading to orgs-landing-zone/66d3b72997392f1cb0f3ead0403ef73b.template  8211 / 8211  (100.00%)
	Uploading to orgs-landing-zone/5239f483e06131395374666a28dd7de3.template  2306 / 2306  (100.00%)

	Deploying with following values
	===============================
	Stack name                   : orgs-landing-zone
	Region                       : us-east-1
	Confirm changeset            : True
	Disable rollback             : False
	Deployment s3 bucket         : aws-sam-cli-managed-default-samclisourcebucket-1lim3572df7mn
	Capabilities                 : ["CAPABILITY_IAM"]
	Parameter overrides          : {"pSSOInstanceId": "", "pDeveloperPrefix": "app", "pCloudFormationRoleName": "CloudFormationRole", "pServiceCatalogRoleName": "ServiceCatalogRole", "pRegions": "us-east-1", "pSandboxOuName": "Sandbox", "pSecurityOuName": "Security_Prod"}
	Signing Profiles             : {}

Initiating deployment
=====================

	Uploading to orgs-landing-zone/8739f2afa93889f043e0b22ec8b67db0.template  18132 / 18132  (100.00%)


Waiting for changeset to be created..

CloudFormation stack changeset
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Operation                                  LogicalResourceId                          ResourceType                               Replacement                              
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+ Add                                      rEmergencyAccessGroup                      AWS::IAM::Group                            N/A                                      
+ Add                                      rEmergencyAccessOpsPolicy                  AWS::IAM::UserPolicy                       N/A                                      
+ Add                                      rEmergencyAccessOpsUser                    AWS::IAM::User                             N/A                                      
+ Add                                      rEmergencyAccessReadOnlyPolicy             AWS::IAM::UserPolicy                       N/A                                      
+ Add                                      rEmergencyAccessReadOnlyUser               AWS::IAM::User                             N/A                                      
+ Add                                      rExceptionsOu                              AWS::Organizations::OrganizationalUnit     N/A                                      
+ Add                                      rInfrastructureOu                          AWS::Organizations::OrganizationalUnit     N/A                                      
+ Add                                      rNonProdOu                                 AWS::Organizations::OrganizationalUnit     N/A                                      
+ Add                                      rOrganizationPolicy                        AWS::Organizations::ResourcePolicy         N/A                                      
+ Add                                      rOrganization                              AWS::Organizations::Organization           N/A                                      
+ Add                                      rParameterStackSet                         AWS::CloudFormation::StackSet              N/A                                      
+ Add                                      rProdOu                                    AWS::Organizations::OrganizationalUnit     N/A                                      
+ Add                                      rRoleStackSet                              AWS::CloudFormation::StackSet              N/A                                      
+ Add                                      rSandboxOu                                 AWS::Organizations::OrganizationalUnit     N/A                                      
+ Add                                      rSecurityOu                                AWS::Organizations::OrganizationalUnit     N/A                                      
+ Add                                      rSecurityPolicy                            AWS::Organizations::Policy                 N/A                                      
+ Add                                      rWorkloadsOu                               AWS::Organizations::OrganizationalUnit     N/A                                      
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------


Changeset created successfully. arn:aws:cloudformation:us-east-1:123456789012:changeSet/samcli-deploy1712626973/c7592650-1e2d-4c48-883d-d28695e9a59d


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: Y

At a broader level, the template.yml deploys an organizational structure as depicted in the Image 2.

Image 2: Organizational structure deployed by template.yml

Image 2: Organizational structure deployed by template.yml

Let’s now discuss the organizational elements created using the template.yml in detail.

Foundational OUs

Foundational OUs host accounts which host resources that provide shared services like Security and Infrastructure for your organization. There is no technical difference between these OUs and the others, it’s just a logical distinction based on their intended content.

  • The Security OU will contain accounts hosting your security services. This will typically include an account to centralize logs from across your organization, and another for centralizing security tooling to give you organization-wide visibility into your security posture and compliance status. Access to this OU should be restricted to the team responsible for your cloud security.
  • The Infrastructure OU is intended for accounts hosting other shared services like Networking, DevOps, Image factory amongst others. Access to this OU should be restricted to your cloud operations team.

Workloads OUs

The Workloads OU is where your applications will live. Under the workloads OUs are nested the Non-Prod OU and the Prod OU. As the name suggests the Non-Prod OU hosts all non-production account and the Prod OU hosts all production accounts.

If you have existing accounts containing workloads, you can invite them into your AWS Organizations and then move them to the suitable OU. Segregating OUs in this manner allows you to test infrastructure changes such as those in service control policies (SCPs) in lower environment (ex: test) before pushing them to production.

For day to day operations, resource provisioning in workloads account should be infrastructure as code CI/CD pipelines. This will not only prevent drift due to manual changes made through the console in your applications but also facilitate consistent deployments across environments . In the template.yml, we have configured appropriate permissions to use AWS Proton for deploying your workloads. AWS Proton is a service designed to allow creation, sharing and reuse of infrastructure as code templates for serverless and container based workloads, along with their CI/CD tooling. The permissions granted for AWS Proton are given as an example and can be replaced with permissions required by your developer tooling of choice.

Sandbox OU

The Sandbox OU will provide your builders with an environment with fewer constraints, giving them freedom to experiment without putting production workloads at risk. You may allow your builders to use new services in this OU for experimentation.

Controls

The template.yml defines a single service control policy (SCP), attached at the root of the organization, which implements some fundamental constraints on all of the member accounts

  • Denying all root actions.
  • Preventing member accounts leaving the organization.
  • It also defines an AWS Organizations Resource Policy which grants all of the member accounts the ability to retrieve information about the organization they belong to.

IAM roles

IAM roles are deployed to all member accounts in the organization from a CloudFormation StackSet (AWSPlatform-BASELINE-ROLES) in the management account. The Arn and Name of these roles are available as Stack outputs in the member accounts.

service role for CloudFormation has the AdministratorAccess managed policy attached but is also constrained by a permissions boundary intended to allow developers to deploy and manage resources from commonly used developer services as well as IAM roles and policies via CloudFormation without permitting privilege escalation.

Miscellaneous

Finally, an AWS CloudFormation StackSet (AWSPlatform-BASELINE-PARAMETERS) is deployed to the management account, which pushes out some useful AWS Systems Manager Session Manager (SSM) Parameter Store parameters to all member accounts in the AWS Organizations, such as

  • /platform/org/OrganizationId
  • /platform/iam/CloudFormationRole
  • /platform/iam/CloudFormationRoleArn

For example, you may want to restrict access to reading logs from your centralized logging Amazon Simple Storage Service (Amazon S3) bucket (Name: centralized-logs) to only accounts in your organization (Org ID: o-xxxxxxxxxxx). You can achieve this easily using the SSM parameter /platform/org/OrganizationId which contains your organization ID.

{
  "Version": "2012-10-17",
  "Statement": {
    "Sid": "AllowOrgWideRead",
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::centralized-logs/*",
    "Condition": {
      "StringEquals": {
        "aws:PrincipalOrgID": "{{resolve:ssm:/platform/org/OrganizationId}}"
      }
    }
  }
}

Enable IAM Identity Center for single sign-on for the workforce in your organization

We recommend you use AWS IAM Identity Center to provide workforce access for your organization. It provides secure single sign-on, centralized identity management, and access control, reducing IT overhead for SMBs with limited resources while improving security and productivity.

Moreover AWS IAM Identity Center provides short lived temporary credentials to allow federated user access to AWS accounts instead of using the long-lived credentials associated with an IAM user. This is a security best practice to curtail unauthorized access to your resources.

It isn’t currently possible to enable Identity Center via API so we can’t automate this step with the CloudFormation template yet.

Since you already deployed the template.yml and your AWS Organizations is now configured, you can log in to your management account as the root user and manually enable Identity Center.

You can get your Identity Center Instance ID from the Identity Center console as shown in the Image 3.

Image 3: IAM Identity Center Settings page

Image 3: IAM Identity Center Settings page

We will now update the existing CloudFormation stack with the Instance ID value from AWS IAM Identity Center. From the command prompt, run the command sam deploy –parameter-overrides pSSOInstanceId=ssoins-XXXXXX.

AWS IAM Identity Center Permission Sets

You will now have a collection of Identity Center PermissionSets that can be associated with your federated users in member accounts. These cover four common personas.

  • AccountManager allows full access to Billing and Cost Management tooling, using the Billing managed policy, for your FinOps team.
  • Support allows support teams to audit and troubleshoot in production accounts using the AWSBillingReadOnlyAccess, ViewOnlyAccess, and AWSSupportAccess managed policies. It also has an inline policy defining additional permissions to PassRole for CloudFormation, provide access to ssh into EC2 instances through SSM and perform some administrative functions on stacks.
  • Developer is the PermissionSet which will be used by your builders. This also has AWSBillingReadOnlyAccess, ViewOnlyAccess, and AWSSupportAccess managed policies. This PermissionSet should include any access your builders will need for their deployment tooling. In this case, we are granting AWSProtonDeveloperAccess to create and deploy AWS Proton services. In addition, DeveloperAccess includes an inline policy allowing use of CloudFormation for stacks under your specified developer prefix namespace and ability to create an S3 bucket for their CloudFormation templates and upload templates into that bucket. It also allows developers to pass the CloudFormationRole, created by the template, to CloudFormation. This role allows developers broad deployment permissions via CloudFormation but constrained by a PermissionsBoundary to prevent privilege escalation.

For builders to use the DeveloperAccess permission set, they must adhere to specific guidelines. Developer created CloudFormation stack names must begin with the pDeveloperPrefix value provided in the template (defaults to app). An example CloudFormation stack name could be app-users-service. Builders also have the ability to create IAM roles in their own CloudFormation, as long as the IAM role path begins with the same prefix (app/MyLambdaRole is a valid path and role name).  The DeveloperBoundary IAM permission boundary policy includes an overly permissive list of services to allow your builders access to. By default, the template includes

Sid: OverlyPermissiveAllowedServices
Effect: Allow
Action:
  - "lambda:*"
   - "apigateway:*"
  - "events:*"
  - "s3:*"
  - "cloudwatch:*"
   - "logs:*"
Resource: "*"

This allows access to AWS Lambda, Amazon API Gateway, Amazon EventBridge, Amazon S3, Amazon CloudWatch, and Amazon CloudWatch Logs. The permission boundary doesn’t grant access to these services, it only allows a builder to make use of these services within their own templates. You can customize this list of services to the recommended (or approved) services you want builders to use within your company.

Here’s an example to help you understand how to use the ShellAccess permission set and SSM to gain shell access to the EC2 instance in a private subnet.

# Configure the AWS CLI to access IAM Identity Center (one-time setup)
aws configure sso
# Login using the profile defined above
aws login sso --profile <my_profile_name>
# Start a new SSM session to the EC2 instance
aws --profile <my_profile_name> ssm start-session target <ec2_instance_id> --document-name SSM-SessionManagerRunShell

Conclusion

This blog post provides SMBs with a simple yet robust baseline AWS Organizations structure with OUs, roles, service control policies in line with AWS best practices; all set up using Infrastructure as Code (IaC) in as little as 30 minutes. We also set up an IAM Identity Center instance to provide workforce access for this organization. With this multi-account environment set up, SMBs are now set up with a strong foundation and have central governance, compliance, and security controls across their AWS environment to meet the challenges of their evolving business needs.

To further improve your operations and security posture you can leverage AWS services like AWS Config, AWS Security Hub, AWS Systems Manager, and AWS Control Tower that integrate with AWS Organizations. We recommend you take a free, self-paced security training to learn more.

To build on top of this lean multi-account environment, read the whitepaper Organizing Your AWS Environment Using Multiple Accounts. Additionally, check out how to establish your initial foundation with AWS Control Tower, a managed service that can help you set up your initial multi-account environment on AWS.

To learn how to scale globally and improve reliability, read how Clearwater Analytics were able to successfully grow and manage 200% more resources using AWS Organizations and other services.

We can’t wait to see what you build next!

About the authors

Alex Torres

Alex Torres is a Senior Solutions Architect working with customers on the Media and Entertainment industry. He has worked with hundreds of customers worldwide building their cloud foundational environments and platforms, architecting new workloads, and creating governance strategy for their cloud environments. In his free time, he enjoys rainy days, playing videogames, walks in the mountain with his dogs, and nice cup of dry cappuccino.

Caroline Johnston

Caroline is a Senior Technical Account Manager at AWS. Originally from the UK, she is now based in Wellington, NZ. She holds a PhD in Bioinformatics and her roles before joining AWS include building bioinformatics tools for neuroscientists and running a high performance compute cluster. These days she works with Public Sector organisations to help them operate successfully on AWS.

Justin Plock

Justin is a Principal Solutions Architect at AWS, focused on startups. He regularly meets with founders to help them build securely and can meet industry regulations. Prior to AWS, he was a Director of Cloud Enablement at a large insurance carrier and a Director of Engineering at a cybersecurity startup.

Nivedita Tripathi

Nivedita Tripathi is a Sr. Product Manager, GTM for AWS Organizations. Her focus is on assisting customers with building and scaling their cloud infrastructure across multiple accounts, while utilizing security and governance best practices. Besides her passion for technology, Nivedita enjoys music, traveling the world, and spending time with her family.

Siddhesh Jog

Siddhesh is a Senior Solutions Architect at AWS. He has worked in multiple industries in a wide variety of roles and is passionate about all things technology. He has architected and operated cloud environments for heavily regulated enterprises as well as fast paced startups. At AWS, Siddhesh is most excited about helping customers transition to cloud successfully and enabling them to host a secure, cost efficient, and easy to use cloud environment.