AWS Cloud Operations Blog

How to deploy CDK v2 to an account that requires boundary policies

Samuel Passman (spssmn, DevOps Consultant), James Dadd (jdaddaws, Infrastructure Architecture Consultant), Asad Syed (asadsy, DevOps Consultant), and Joseph Brian (jkbrian, Senior Engagement Manager) all with ProServe Globals Team.

The AWS Cloud Development Kit (AWS CDK) is an open-source framework that simplifies working with cloud resources using familiar programming languages: C#, TypeScript, Java, Python, and Go (in developer preview).

To deploy AWS CDK apps into an AWS environment (a combination of an AWS account and region), AWS CDK provisions some initial resources in the target AWS environment to facilitate the deployment. This process is called bootstrapping and may involve provisioning of resources. This would include an Amazon Simple Storage Service (Amazon S3) bucket for storing files, and AWS Identity and Access Management (IAM) roles that grant permissions needed to perform deployments.

AWS CDK bootstrapping assumes that the AWS role has all of the necessary permissions to create the initial resources. But this isn’t always the case, as organizations may enforce the attachment of an IAM permissions boundary policy to all roles in an AWS account. By default, the AWS CDK bootstrapping process creates IAM roles without any boundary policies and, if the boundary policy attachment is enforced, then the bootstrapping process fails.

This post describes a solution that helped us workaround this IAM boundary policy issue and enabled AWS CDK v2 to successfully bootstrap a new environment.

The problem

The challenge we faced was deploying AWS CDK v2 into an AWS account where a boundary policy was required to be attached to all created IAM users and roles. In our case, this was enforced by a conditional statement in the permissions policy for the federated single sign-on role that we were using to deploy AWS CDK. There are other methods of enforcement, and this workaround should be applicable in all cases.

The problem occurs because AWS CDK v2 creates five IAM roles used for different purposes (deployment, lookup, file publishing, image publishing, and AWS CloudFormation execution).

CloudFormationExecutionRole API: iam:AttachRolePolicy User:
arn:aws:sts::12345678912:assumed-role/XXXXXX/***
is not authorized to perform: iam:AttachRolePolicy on resource:
role cdk-hnb659fds-cfn-exec-role-12345678912-us-west-1 with an explicit deny

Solution overview

AWS CDK v1 supports two bootstrapping templates: legacy and modern. On the other hand, AWS CDK v2 only supports the modern template. The modern template creates additional resources over and above the legacy template in targeted accounts, as described above. Although the modern template improves the security of AWS CDK, it can also create problems in accounts with IAM boundary policies that restrict the creation of certain resources.

The solution exports the AWS CDK bootstrap template, which is a standard CloudFormation YAML file. Then, the template is modified to add the missing configuration. Then, AWS CDK is bootstrapped using this modified template.

This solution is written in Python. However, it can be used for any AWS CDK project, as it only modifies the output from the cdk bootstrap —show-template command.

Walkthrough

The overall workaround process follows three steps:

  1. Export the AWS CDK bootstrap template
  2. Update the AWS CDK bootstrap template
  3. Bootstrap AWS CDK using the modified template

Here is the link to the GitHub repo.

Prerequisites

For this walkthrough, you should have the following prerequisites:

  • An AWS account and credentials to a role with the required permissions to deploy and update CloudFormation stacks – see here for a detailed guide.
  • The AWS CDK toolkit installed as described in this guide.

Export the AWS CDK bootstrap template

  • Open a terminal window
  • Run the following command:
cdk bootstrap --show-template > bootstrap-template.yaml

This will export the template to the root folder of the project. If you wish to export to another location, then change the path to one of your choice.

Update the AWS CDK bootstrap template

  • Download/clone the repository attached to this guide.
  • Open a terminal window.
  • Set up a supported Python virtual environment and install PyYAML via pip. Use this link to help identify a suitable version.
  • Run the following script, replacing update_cdk_bootstrap_template.py to the path where you downloaded the code attached to this guide, and pass the ARN of the boundary policy that you want to apply to the roles created by AWS CDK as follows:
python update_cdk_bootstrap_template.py bootstrap-template.yaml \
"arn:aws:iam::123456789123:policy/PERMISSIONS-BOUNDARY-NAME"

This will update the bootstrap-template.yaml with the boundary policy passed into the script.

Bootstrap CDK using the modified template

  • To bootstrap with the updated template, run the following command:
cdk bootstrap --template bootstrap-template.yaml

Identifying any policies that are disallowed by the boundary policy

If you’re still unable to bootstrap with a permissions error, it’s likely that the CloudFormation template contains a policy that isn’t allowed at a Service Control Policy level. To check this, you must communicate with your administrator of the AWS account that you’re trying to bootstrap to see which policies aren’t allowed.

Conclusion

This post describes a solution that helped us work around an IAM boundary policy issue and enabled AWS CDK v2 to successfully bootstrap into a new account. The solution exports the AWS CDK bootstrap template, modifies the template to add the missing configuration, and then bootstraps using this modified template.

AWS CDK is an open source framework. Community contributions and pull requests are welcomed (see CONTRIBUTING.md). GitHub is the best way to raise bug reports, feature requests, documentation issues, or seek guidance.

Other useful resources:

API Reference and Developer Guide
• The AWS CDK hub cdk.dev
• Search or ask questions on Stack Overflow with the tag aws-cdk

About the authors:

James Dadd

James Dadd is an Infrastructure Architecture consultant with AWS ProServe. When not writing infrastructure automation code, you’ll find him running, riding a bike or dreaming about sailing over the horizon.

Samuel Passman

Samuel is a DevOps Consultant with Professional Services at Amazon Web Services. He specializes in designing and implementing solutions for global energy customers. During his free time Samuel enjoys spending time at the seaside, long walks and watching Formula 1.

Asad Syed

Asad Syed is a DevOps Architect with AWS ProServe. He works with customers to modernize their applications & processes. Outside of work, he’s usually hanging around in one of the beach volleyball courts or bouldering halls, in Berlin.

Joseph Brian

Joe Brian is a Senior Engagement Manager with AWS ProServe who specialises in leading complex cloud transformations. Outside of work his passions are surfing and closely following the England rugby team.