Deploy and manage AWS Control Tower controls by using AWS CDK and AWS CloudFormation
Created by Iker Reina Fuente (AWS) and Ivan Girardi (AWS)
Code repository: aws-control-tower-controls-cdk | Environment: Production | Technologies: Security, identity, compliance; CloudNative; Infrastructure; Management & governance |
AWS services: AWS CloudFormation; AWS Control Tower; AWS Organizations; AWS CDK |
Summary
This pattern describes how to use AWS CloudFormation and AWS Cloud Development Kit (AWS CDK) to implement and administer preventive, detective, and proactive AWS Control Tower controls as infrastructure as code (IaC). A control (also known as a guardrail) is a high-level rule that provides ongoing governance for your overall AWS Control Tower environment. For example, you can use controls to require logging for your AWS accounts and then configure automatic notifications if specific security-related events occur.
AWS Control Tower helps you implement preventive, detective, and proactive controls that govern your AWS resources and monitor compliance across multiple AWS accounts. Each control enforces a single rule. In this pattern, you use a provided IaC template to specify which controls you want to deploy in your environment.
AWS Control Tower controls apply to an entire organizational unit (OU), and the control affects every AWS account within the OU. Therefore, when users perform any action in any account in your landing zone, the action is subject to the controls that govern the OU.
Implementing AWS Control Tower controls helps establish a strong security foundation for your AWS landing zone. By using this pattern to deploy the controls as IaC through CloudFormation and AWS CDK, you can standardize the controls in your landing zone and more efficiently deploy and manage them. This solution uses cdk_nag
To deploy AWS Control Tower controls as IaC, you can also use HashiCorp Terraform instead of AWS CDK. For more information, see Deploy and manage AWS Control Tower controls by using Terraform.
Target audience
This pattern is recommended for users who have experience with AWS Control Tower, CloudFormation, AWS CDK, and AWS Organizations.
Prerequisites and limitations
Prerequisites
Active AWS accounts managed as an organization in AWS Organizations and an AWS Control Tower landing zone. For instructions, see Create an account structure
(AWS Well-Architected Labs). AWS Command Line Interface (AWS CLI), installed and configured.
Node package manager (npm), installed and configured
for the AWS CDK. Prerequisites for AWS CDK.
Permissions to assume an existing AWS Identity and Access Management (IAM) role in a deployment account.
Permissions to assume an IAM role in the organization’s management account that that can be used to bootstrap AWS CDK. The role must have permissions to modify and deploy CloudFormation resources. For more information, see Bootstrapping in the AWS CDK documentation.
Permissions to create IAM roles and policies in the organization’s management account. For more information, see Permissions required to access IAM resources in the IAM documentation.
Apply the service control policy (SCP)-based control with the identifier CT.CLOUDFORMATION.PR.1. This SCP must be activated to deploy proactive controls. For instructions, see Disallow management of resource types, modules, and hooks within the AWS CloudFormation registry.
Limitations
This pattern provides instructions for deploying this solution across AWS accounts, from a deployment account to the organization’s management account. For testing purposes, you can deploy this solution directly in the management account, but instructions for this configuration are not explicitly provided.
Product versions
Python version 3.9 or later
npm version 8.9.0 or later
Architecture
Target architecture
This section provides a high-level overview of this solution and the architecture established by the sample code. The following diagram shows controls deployed across the various accounts in the OU.
AWS Control Tower controls are categorized according to their behavior and their guidance.
There are three primary types of control behaviors:
Preventive controls are designed to prevent actions from occurring. These are implemented with service control policies (SCPs) in AWS Organizations. The status of a preventive control is either enforced or not enabled. Preventive controls are supported in all AWS Regions.
Detective controls are designed to detect specific events when they occur and log the action in CloudTrail. These are implemented with AWS Config rules. The status of a detective control is either clear, in violation, or not enabled. Detective controls apply only in those AWS Regions supported by AWS Control Tower.
Proactive controls scan resources that would be provisioned by AWS CloudFormation and check whether they are compliant with your company policies and objectives. Resources that are not compliant will not be provisioned. These are implemented with AWS CloudFormation hooks. The status of a proactive control is PASS, FAIL, or SKIP.
Control guidance refers to the recommended practice for how to apply each control to your OUs. AWS Control Tower provides three categories of guidance: mandatory, strongly recommended, and elective. The guidance of a control is independent of its behavior. For more information, see Control behavior and guidance.
Tools
AWS services
AWS Cloud Development Kit (AWS CDK) is a software development framework that helps you define and provision AWS Cloud infrastructure in code. The AWS CDK Toolkit is the primary tool for interacting with your AWS CDK app.
AWS CloudFormation helps you set up AWS resources, provision them quickly and consistently, and manage them throughout their lifecycle across AWS accounts and Regions.
AWS Config provides a detailed view of the resources in your AWS account and how they’re configured. It helps you identify how resources are related to one another and how their configurations have changed over time.
AWS Control Tower helps you set up and govern an AWS multi-account environment, following prescriptive best practices.
AWS Organizations is an account management service that helps you consolidate multiple AWS accounts into an organization that you create and centrally manage.
Other tools
cdk_nag
is an open-source tool that uses a combination of rule packs to check AWS Cloud Development Kit (AWS CDK) applications for adherence to best practices. npm
is a software registry that runs in a Node.js environment and is used to share or borrow packages and manage deployment of private packages. Python
is a general-purpose computer programming language.
Code repository
The code for this pattern is available in the GitHub Deploy AWS Control Tower controls using AWS CDK
Best practices
Follow the principle of least-privilege (IAM documentation). The sample IAM policy and trust policy provided in this pattern include the minimum permissions required, and the AWS CDK stacks created in the management account are restricted by these permissions.
Follow the Best practices for AWS Control Tower administrators (AWS Control Tower documentation).
Follow the Best practices for developing and deploying cloud infrastructure with the AWS CDK (AWS CDK documentation).
When bootstrapping the AWS CDK, customize the bootstrap template to define policies and the trusted accounts that should have the ability to read and write to any resource in the management account. For more information, see Customizing bootstrapping.
Use code analysis tools, such as cfn_nag
, to scan the generated CloudFormation templates. The cfn-nag tool looks for patterns in CloudFormation templates that might indicate the infrastructure is not secure. You can also use cdk-nag to check your CloudFormation templates by using the cloudformation-include module.
Epics
Task | Description | Skills required |
---|---|---|
Create the IAM role in the management account. |
| DevOps engineer, General AWS |
Bootstrap AWS CDK. |
| DevOps engineer, General AWS, Python |
Clone the repository. | In a bash shell, enter the following command. This clones the Deploy AWS Control Tower controls using AWS CDK
| DevOps engineer, General AWS |
Edit the AWS CDK configuration file. |
|
Task | Description | Skills required |
---|---|---|
Assume the IAM role in the deployment account. | In the deployment account, assume the IAM role that has permissions to deploy the AWS CDK stacks in the management account. For more information about assuming an IAM role in the AWS CLI, see Use an IAM role in the AWS CLI. | DevOps engineer, General AWS |
Activate the environment. | If you are using Linux or MacOS:
If you are using Windows:
| DevOps engineer, General AWS |
Install the dependencies. | After the virtual environment is activated, enter the following command to run the install_deps.sh script. This script installs the required dependencies.
| DevOps engineer, General AWS, Python |
Deploy the stack. | Enter the following commands to synthesize and deploy the CloudFormation stack.
| DevOps engineer, General AWS, Python |
Related resources
AWS documentation
About controls (AWS Control Tower documentation)
Controls library (AWS Control Tower documentation)
AWS CDK Toolkit commands (AWS CDK documentation)
Deploy and manage AWS Control Tower controls by using Terraform (AWS Prescriptive Guidance)
Other resources
Additional information
Example constants.py file
The following is an example of an updated constants.py file.
ACCOUNT_ID = 111122223333 AWS_CONTROL_TOWER_REGION = us-east-2 ROLE_ARN = "arn:aws:iam::111122223333:role/CT-Controls-Role" GUARDRAILS_CONFIGURATION = [ { "Enable-Control": { "AWS-GR_ENCRYPTED_VOLUMES", ... }, "OrganizationalUnitIds": ["ou-1111-11111111", "ou-2222-22222222"...], }, { "Enable-Control": { "AWS-GR_SUBNET_AUTO_ASSIGN_PUBLIC_IP_DISABLED", ... }, "OrganizationalUnitIds": ["ou-2222-22222222"...], }, ]
IAM policy
The following sample policy allows the minimum actions required to enable or disable AWS Control Tower controls when deploying AWS CDK stacks from a deployment account to the management account.
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "controltower:EnableControl", "controltower:DisableControl", "controltower:GetControlOperation", "controltower:ListEnabledControls", "organizations:AttachPolicy", "organizations:CreatePolicy", "organizations:DeletePolicy", "organizations:DescribeOrganization", "organizations:DescribeOrganizationalUnit", "organizations:DetachPolicy", "organizations:ListAccounts", "organizations:ListAWSServiceAccessForOrganization", "organizations:ListChildren", "organizations:ListOrganizationalUnitsForParent", "organizations:ListParents", "organizations:ListPoliciesForTarget", "organizations:ListRoots", "organizations:UpdatePolicy", "ssm:GetParameters" ], "Resource": "*" } ] }
Trust policy
The following custom trust policy allows a specific IAM role in the deployment account to assume the IAM role in the management account. Replace the following:
<DEPLOYMENT-ACCOUNT-ID>
is the ID of the deployment account<DEPLOYMENT-ROLE-NAME>
is the name of the role in the deployment account that is allowed to assume the role in the management account
{ “Version”: “2012-10-17”, “Statement”: [ { “Effect”: “Allow”, “Principal”: { “AWS”: “arn:aws:iam::<DEPLOYMENT-ACCOUNT-ID>:role/<DEPLOYMENT-ROLE-NAME>” }, “Action”: “sts:AssumeRole”, “Condition”: {} } ] }