Automatically configuring AWS GovCloud Accounts

This technical article will walk through a CloudFormation template that will create a Step Function that creates AWS GovCloud accounts with AWS Organizations and automatically links them. Our end goal is to simply submit a JSON package like this:

{
  "email": "some-email@example.com",
  "name": "The Account Name"
}

And generate the AWS Organization and link them. This is a rather manual process if you do it by hand.

This CloudFormation template provides two main components:

  1. A configured S3 bucket and KMS key that enable child AWS Organizations to pull from the bucket
  2. A Step Function that automatically creates and links AWS organizations

This script is intended for creating AWS GovCloud accounts, but can be modified for creating standard AWS accounts. Note, this will create the requisite commercial AWS accounts that GovCloud accounts are tied to.

We have included this notice because this CloudFormation template is deployed into the root AWS GovCloud account you own.

The files can be found here (https://cdn.monkton.io/share/mcm-creator-1.0.zip)

Setting up your commercial AWS Account

To deploy this, we need an IAM credential within the root AWS Commercial account. This IAM credential should have access to create AWS Organizations.

We will call this user the org-creator account. Note, we recommend you vet your IAM credentials correctly.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "organizations:CreateGovCloudAccount",
                "organizations:CreateAccount",
                "organizations:DescribeCreateAccountStatus"
            ],
            "Resource": "*"
        }
    ]
}

You will need to store the IAM credentials for later use when you run your CloudFormation template.

Bucket Setup

In your root AWS GovCloud account, create a new S3 bucket (You obviously need a unique name), for this walk through we will call it the account-creator bucket—obviously create a KMS key to protect them.

Under account-creator, create the folder structure bootstrap-mcm/cloudformation/1.0, where the latest segment is a version identifier for the CloudFormation templates.

Upload the yaml and zip files to the bootstrap-mcm/cloudformation/1.0 folder.

Retrieve the URL for the mcm-core-root.yaml file so we can use that to run the CloudFormation script.

IAM

Next, you will need to create a IAM user within the root AWS GovCloud account to deploy with the CLI. For purposes of this walkthrough, grant the user Admin access (trim down permissions). Create a profile in your ~/.aws/credentials file that you can reference in the script.

Deploy Template

Before creating the template, generate a unique 10 character phrase (This must be all lowercase, no special characters, numbers and letters only!). This will be used as "magic" to create some unique resource names names. The Organization Identifier below should come from the AWS GovCloud Organization identifier.

Create a bash file with the following commands:

#!/bin/sh
set -e

AWS_REGION="us-east-1"

STACK_NAME=$1
FORCED_PROFILE="--profile profile-aws-production-gov"
CF_BUCKET_NAME="account-creator"
CF_BUCKET_VERSION="1.0"
CF_REGION="us-gov-west-1"
IAM_REGION="us-east-1"

aws cloudformation create-stack \
    --stack-name "$STACK_NAME" \
    --template-url "https://${CF_BUCKET_NAME}.s3.${CF_REGION}.amazonaws.com/bootstrap-mcm/cloudformation/${CF_BUCKET_VERSION}/mcm-core-root.yaml" \
    --parameters \
        ParameterKey=parBucketMagic,ParameterValue="abcdefghij" \
        ParameterKey=parMonktonFormationS3Bucket,ParameterValue="${CF_BUCKET_NAME}" \
        ParameterKey=parMonktonFormationS3BucketRegion,ParameterValue="${CF_REGION}" \
        ParameterKey=parMonktonFormationVersion,ParameterValue="${CF_BUCKET_VERSION}" \
        ParameterKey=parInvokeLambdaIAMAccess,ParameterValue="IAM_KEY" \
        ParameterKey=parInvokeLambdaIAMRegion,ParameterValue="$IAM_REGION" \
        ParameterKey=parInvokeLambdaIAMSecret,ParameterValue="IAM_SECRET_KEY" \
        ParameterKey=parOrganizationIdentifier,ParameterValue="ORG_IDENTIFIER" \
        ParameterKey=parOrganizationRoleName,ParameterValue="DESIRED_ROLE_NAME" \
    --capabilities CAPABILITY_AUTO_EXPAND CAPABILITY_IAM \
    --region $CF_REGION $FORCED_PROFILE
    

Create an account

In the Console, browse to step functions, execute the step function and use the following JSON:

{
  "email": "some-email@example.com",
  "name": "The Account Name"
}

Services Used

This script leverages the following AWS services:

  • Lambda
  • Step Functions
  • IAM Roles
  • KMS
  • S3
  • Secrets Manager