Automating AWS account bootstrapping with AWS-CDK.

Andrew Frazer
3 min readJul 11, 2022

--

Introduction

AWS Control Tower is used to manage and orchestrate multiple accounts in different organizational units under a single root account. For many organisations, a multi-account structure can help meet the unique needs of each application team or business group. Out of the box, Control Tower helps enforce security and logging configurations, allowing for consistent application of corporate policy, while still giving each team access to work in their environments. There is no free lunch of course, and while multi-account structures improve security, they can increase the management overhead, so are a low hanging target for automation.

Beyond the standard configuration of a new account, Customizations for AWS Control Tower (CfCT) allow for deploying additional configurations in accounts using CloudFormation Stack Sets. AWS has also developed a terraform solution to do a similar thing. In this blog we explore extending the idea of Customizations using AWS-CDK, to dynamically deploy configurations which is helpful when CDK is the tool of choice.

The approach

When an account is created with Control Tower, an event is emitted by event-bridge. If an event bridge rule is created that matches that event, it can be used to trigger a codebuild job, that can do a variety of tasks such as cdk bootstrapping the new account, and then publishing cdk apps to the new account so with only a few actions the account is ready to use.

At the time of writing using cdk to actually create the accounts, in a truly dev-ops way is still in development, this approach only considers what happens after the account is created.

A link to all the code is a the bottom of this blog , this should be modified for your environments. It should be deployed in the master account of your organisation. Its important to note that this is an example only, you need to do some work to make it work in YOUR environment.

This solution revolves around a few infrastructure components.

A rule to match the event with a target for the event rule. The target will be a lambda function that will process the event information, creating a codebuild spec file, and invoking the codebuild. ( Codebuild is being used to do all the things that you would just do by hand.. ) The SQS queue is there to help us find things if it goes wrong. And there are a few permissions to add..

We create an S3assest to provide as an input to the Codebuild. We place all our cdk apps that we want to deploy in the bootstraptemplates folder.

The interesting work happens in our lambda. The observant will notice the lambda is in python and and cdk in typescript. Of course you can use use typescript, but the preference was to use python/boto3 as its synchronous nature is trivial.

The CDK app, passes some environment variables to the lambda. These along with the event information that comes from the event bridge rule, are used to create a buildspec for the codebuild.

The code at line 29, exports to the AWS CLI defaults credentials for the new account. Note it will use the Control Tower role that has already been created. This gives us access to deploy what we want.

At line 40, we have codebuild, create and synth a cdk project, that we will extract a cloud formation file from. While we could have just used a standard ‘cdk deploy’ command, we are wanting to make a minor change to the stack. We want to tag every resource that the cdkbootstrap stack, so we can protect it with a Service Control Policy. ( SCP ). Aspects provide a great way to manipulate a stack, including one that is just a cloud formation include.

We then loop through the list of regions we want to bootstrap, and create commands for the buildspec.

After we have bootstrapped the new account we are able to deploy any cdk app we want to the new account. In this case, we simply want to deploy a few administrative roles, which can be assumed by IAM or SSO users. What you deploy is restricted only by your imagination.

We then assemble our codebuild spec, and convert it to YAML ( codebuild requires it in YAML ).

In the process of developing this solution, it was discovered that bootstrapping a new account via cloudformation was only possible, if the SSM parameter has already been set. ( See github issue ). In order to make this work, we are setting the ssm parameter.

The lambda then invokes the codebuild job.

All the code is downloadable from raindancers github repo.
https://github.com/raindancers/cdkbootstrapper

--

--