Customising AWS Control Tower with CfCT
If you missed the previous posts on Deploying a Landing Zone with AWS Control Tower or you’ve not had much experience with the service, I’d recommend going back through and reading those firstly before continuing.
- Part 1 - Deploying AWS Control Tower
- Part 2 - AWS Control Tower Post Configuration Tasks focusing on Organisational Structure and Guardrails
- Part 3 - AWS Control Tower Post Configuration Tasks focusing on IAM Identity Center and Provisioning New AWS Accounts
In this post, I’m going to walkthrough how you can start customising Control Tower using the Security Reference Architecture (SRA). The SRA utilises Customisations for Control Tower (CfCT) which deploys a DevOps pipeline that works with CloudFormation templates and Control Tower lifecycle events.
By no means is this the only way of customising the Landing Zone that Control Tower deploys but its my personal preference, as this was also how the previous version of AWS Landing Zones was based upon and therefore I’m more familiar with its setup and configuration. It does have some drawbacks though, in that it is only single threaded and therefore slow in large environments. There are alternatives though including:
Why would I want to customise Control Tower?
I think the easiest way to answer this question is simply because whilst Control Tower provides the foundations for a Well-Architected Multi-Account Landing Zone, it’s not completely perfect.
In terms of AWS Services, Control Tower is still in it infancy and whilst AWS are constantly adding new functionality and guardrails; there are still some basic best practices that aren’t there natively. For example, in my previous post, I mentioned that AWS Config doesn’t get configured in the Management Account but it is in every other Member AWS Account.
On the other hand, the majority of organisations need to tailor the Landing Zone to meet there specific security and governance requirements. Therefore the reality is that there is no one size fits all, but there are synergies between them.
Enable Trusted Access for CloudFormation StackSets in AWS Organizations
I personally didn’t need to do this since Control Tower had already enabled this for me, however it’s worth double checking just to play safe.
- Login to the AWS Management Console using an Account with administrative permissions and navigate to the AWS Organizations Console. This should be done within the Management Account.
- Click Services.
- Scroll down to CloudFormation StackSets and check that its Trusted Access is set to Access enabled. If not, then Click CloudFormation StackSets and then Click Enable trusted access.
Configure an AWS CLI Profile to the Management Account
- Establish an AWS CLI Profile to the Management Account with administrative credentials via the AWS CLI using either a Command Prompt or from Powershell:
aws configure sso
- In the SSO start URL, type the URL of the SSO Login page. For example., https://d-1234567890.awsapps.com/start This can be found by logging into the IAM Identity Center Console and looking for the AWS access portal URL in the Settings.
- In the SSO Region, type the AWS Region that was used for the Home Region when deploying Control Tower. For example., eu-west-2
A Web Browser will then Open prompting for Login Credentials if you’re not already logged in.
- Login with your Username and Password.
- Click Allow.
- Select the AWS Management Account using the cursor keys.
- Press Return for the default client Region and the default output format.
- For the Profile name use something memorable as this can be anything. For example., ct-mgmt
Deploying the SRA Common Pre-Requisites
There are a few things that we need installed on our local device as a pre-cursor for this part including Git, Bash Shell (which in my case I needed to install GitBash for Windows), the AWS CLI v2 and 7-Zip. Since I’m running a Windows Device the instructions will be based on that.
- Clone the SRA Source Files from GitHub via either a Command Prompt or from Powershell:
git clone https://github.com/aws-samples/aws-security-reference-architecture-examples.git .
Now that we have the SRA source files locally we need to start creating some CloudFormation Stacks in our Management Account using the YAML templates within the source. These templates setup the functionality for SRA to work before we even install the Customisations for Control Tower solution.
- Launch the sra-common-prerequisites-staging-s3-bucket.yaml via the AWS CLI using either a Command Prompt or from Powershell:
aws cloudformation deploy --template-file /aws_sra_examples/solutions/common/common_prerequisites/templates/sra-common-prerequisites-staging-s3-bucket.yaml --stack-name sra-common-prerequisites-staging-s3-bucket --capabilities CAPABILITY_NAMED_IAM --profile ct-mgmt
- Package and upload all the SRA Solutions to the Staging S3 Bucket via GitBash:
sh ./aws_sra_examples/utils/packaging_scripts/stage_solution.sh --profile ct-mgmt
- Launch the sra-common-prerequisites-management-account-parameters.yaml via the AWS CLI using either a Command Prompt or from Powershell:
aws cloudformation deploy --template-file /aws_sra_examples/solutions/common/common_prerequisites/templates/sra-common-prerequisites-management-account-parameters.yaml --stack-name sra-common-prerequisites-management-account-parameters --capabilities CAPABILITY_NAMED_IAM --profile ct-mgmt
- Launch the sra-common-prerequisites-main-ssm.yaml via the AWS CLI using either a Command Prompt or from Powershell:
aws cloudformation deploy --template-file /aws_sra_examples/solutions/common/common_prerequisites/templates/sra-common-prerequisites-main-ssm.yaml --stack-name sra-common-prerequisites-main-ssm --capabilities CAPABILITY_NAMED_IAM --profile ct-mgmt
Deploy the Customisations for Control Tower Solution
The team at AWS that have developed the SRA utilised Customisations for Control Tower (CfCT) as the delivery mechanism for there customisations but since they don’t maintain that solution itself, it’s strongly recommended to check the current version of CfCT here prior to launching the CloudFormation Template.
You may find that you wish to edit sra-common-cfct-setup-main.yaml to reflect the following change instead:
# TemplateURL: !Sub https://${pSRAStagingS3BucketName}.s3.${AWS::Region}.${AWS::URLSuffix}/${pSRASolutionName}/templates/customizations-for-aws-control-tower.template
TemplateURL: https://s3.amazonaws.com/solutions-reference/customizations-for-aws-control-tower/latest/custom-control-tower-initiation.template
The architecture that is deployed by CfCT is shown below.
- Launch the sra-common-cfct-setup-main.yaml via the AWS CLI using either a Command Prompt or from Powershell:
aws cloudformation deploy --template-file /aws_sra_examples/solutions/common/common_cfct_setup/templates/sra-common-cfct-setup-main.yaml --stack-name sra-common-cfct-setup-main --capabilities CAPABILITY_NAMED_IAM --profile ct-mgmt
What Customisations should I make?
This is always very subjective and there are many things that may factor into the answer. That being said here is my personal list in no particular order and best of all it’s all included within the SRA Source Files with the exceptions of the SCPs. There are also other CloudFormation Templates available within the SRA source files that could be used or alternatively you may wish to create your own.
CloudFormation
- Enable Config in the Management Account
- Enable CloudTrail Organizational Trail for Data Events
- Enable EC2 Default EBS Encryption
- Configure a Hardened IAM Account Password Policy
- Enable S3 Block Public Access at the Account Level
- Configure AWS Account Alternate Contacts
- Enable IAM Access Analyzer and Configure for Delegated Administration
- Enable GuardDuty and Configure for Delegated Administration
- Enable Macie and Configure for Delegated Administration
- Enable Security Hub and Configure for Delegated Administration
Service Control Policies
- Prevent Accounts from Leaving the Organisation
- Prevent the Disabling of any Security Tooling
- Prevent IAM User Creation
Time to Customise our Control Tower Setup
This section will go through customising Control Tower based on my own personal recommendation
- Install the git-remote-codecommit module via either a Command Prompt or Powershell.
pip install git-remote-codecommit
- Clone the CodeCommit repository that is deployed by CfCT via either a Command Prompt or Powershell.
git clone codecommit://sra-mgmt@custom-control-tower-configuration custom-control-tower-configuration
Note: You’ll need to ensure that you use the name of you AWS CLI profile prior to the @
as shown in the example above.
-
Within your IDE of choice, under the custom-control-tower-configuration folder delete the example-configuration folder.
-
Under the custom-control-tower-configuration fodler create 3 new folders named parameters, policies and templates.
- Copy the following files from the SRA source files to custom-control-tower-configuration\templates.
- sra-account-alternate-contacts-main-ssm.yaml
- sra-cloudtrail-org-main-ssm.yaml
- sra-config-management-account-main-ssm.yaml
- sra-ec2-default-ebs-encryption-main-ssm.yaml
- sra-guardduty-org-main-ssm.yaml
- sra-iam-access-analyzer-main-ssm.yaml
- sra-iam-password-policy-main-ssm.yaml
- sra-macie-org-main-ssm.yaml
- sra-securityhub-org-main-ssm.yaml
- Copy the following files from the SRA source files to custom-control-tower-configuration\parameters.
- sra-account-alternate-contacts-main-ssm.json
- sra-cloudtrail-org-main-ssm.json
- sra-config-management-account-main-ssm.json
- sra-ec2-default-ebs-encryption-main-ssm.json
- sra-guardduty-org-main-ssm.json
- sra-iam-access-analyzer-main-ssm.json
- sra-iam-password-policy-main-ssm.json
- sra-macie-org-main-ssm.json
- sra-s3-block-account-public-access-main-ssm.json
- sra-securityhub-org-main-ssm.json
- Amend the values as required in each of the JSON files above to customise the configuration of each of the different templates. For example., IAM Password Policy configuration will be defined in the sra-iam-password-policy-main-ssm.json.
- Create scp-prevent-accounts-leaving-org.json in custom-control-tower-configuration\policies and paste in the below contents.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PreventMemberLeavingOrg",
"Effect": "Deny",
"Action": [
"organizations:LeaveOrganization"
],
"Resource": "*",
"Condition": {
"ArnNotLike": {
"aws:PrincipalARN": [
"arn:aws:iam::*:role/AWSControlTowerExecution"
]
}
}
}
]
}
- Create scp-prevent-disabling-security-tooling.json in custom-control-tower-configuration\policies and paste in the below contents.
{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"PreventDisablingSecurityHub",
"Effect":"Deny",
"Action":[
"securityhub:DeleteInvitations",
"securityhub:DisableSecurityHub",
"securityhub:DisassociateFromMasterAccount",
"securityhub:DeleteMembers",
"securityhub:DisassociateMembers"
],
"Resource":"*",
"Condition":{
"ArnNotLike":{
"aws:PrincipalARN":[
"arn:aws:iam::*:role/AWSControlTowerExecution"
]
}
}
},
{
"Sid":"PreventDisablingGuardDuty",
"Effect":"Deny",
"Action":[
"guardduty:DeleteDetector",
"guardduty:DeleteInvitations",
"guardduty:DeleteIPSet",
"guardduty:DeleteMembers",
"guardduty:DeleteThreatIntelSet",
"guardduty:DisassociateFromMasterAccount",
"guardduty:DisassociateMembers",
"guardduty:StopMonitoringMembers"
],
"Resource":"*",
"Condition":{
"ArnNotLike":{
"aws:PrincipalARN":[
"arn:aws:iam::*:role/AWSControlTowerExecution"
]
}
}
},
{
"Sid":"PreventDisablingMacie",
"Effect":"Deny",
"Action":[
"macie2:DisassociateFromMasterAccount",
"macie2:DisableOrganizationAdminAccount",
"macie2:DisableMacie",
"macie2:DeleteMember"
],
"Resource":"*",
"Condition":{
"ArnNotLike":{
"aws:PrincipalARN":[
"arn:aws:iam::*:role/AWSControlTowerExecution"
]
}
}
},
{
"Sid":"PreventDisablingAccessAnalyzer",
"Effect":"Deny",
"Action":[
"access-analyzer:DeleteAnalyzer"
],
"Resource":"*",
"Condition":{
"ArnNotLike":{
"aws:PrincipalARN":[
"arn:aws:iam::*:role/AWSControlTowerExecution"
]
}
}
}
]
}
- Create scp-prevent-iam-users-creation.json in custom-control-tower-configuration\policies and paste in the below contents.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PreventIAMUserCreation",
"Effect": "Deny",
"Action": [
"iam:CreateUser",
"iam:CreateAccessKey"
],
"Resource": [
"*"
],
"Condition": {
"ArnNotLike": {
"aws:PrincipalARN": [
"arn:aws:iam::*:role/AWSControlTowerExecution"
]
}
}
}
]
}
- Modify the contents of manifest.yaml as per below.
---
#Default region for deploying Custom Control Tower: Code Pipeline, Step functions, Lambda, SSM parameters, and StackSets
region: eu-west-2
version: 2021-03-15
# Control Tower Custom Resources (Service Control Policies or CloudFormation)
resources:
# -----------------------------------------------------------------------------
# Account Alternate Contacts
# -----------------------------------------------------------------------------
- name: sra-account-alternate-contacts-main-ssm
resource_file: templates/sra-account-alternate-contacts-main-ssm.yaml
parameter_file: parameters/sra-account-alternate-contacts-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# Config Management Account
# -----------------------------------------------------------------------------
- name: sra-config-management-account-main-ssm
resource_file: templates/sra-config-management-account-main-ssm.yaml
parameter_file: parameters/sra-config-management-account-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# Organization CloudTrail
# -----------------------------------------------------------------------------
- name: sra-cloudtrail-org-main-ssm
resource_file: templates/sra-cloudtrail-org-main-ssm.yaml
parameter_file: parameters/sra-cloudtrail-org-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# S3 Block Account Public Access Solution
# -----------------------------------------------------------------------------
- name: sra-s3-block-account-public-access-main-ssm
resource_file: templates/sra-s3-block-account-public-access-main-ssm.yaml
parameter_file: parameters/sra-s3-block-account-public-access-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# EC2 Default EBS Encryption Solution
# -----------------------------------------------------------------------------
- name: sra-ec2-default-ebs-encryption-main-ssm
resource_file: templates/sra-ec2-default-ebs-encryption-main-ssm.yaml
parameter_file: parameters/sra-ec2-default-ebs-encryption-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# IAM Password Policy
# -----------------------------------------------------------------------------
- name: sra-iam-password-policy-main-ssm
resource_file: templates/sra-iam-password-policy-main-ssm.yaml
parameter_file: parameters/sra-iam-password-policy-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# IAM Access Analyzer Solution
# -----------------------------------------------------------------------------
- name: sra-iam-access-analyzer-main-ssm
resource_file: templates/sra-iam-access-analyzer-main-ssm.yaml
parameter_file: parameters/sra-iam-access-analyzer-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# Organization GuardDuty
# -----------------------------------------------------------------------------
- name: sra-guardduty-org-main-ssm
resource_file: templates/sra-guardduty-org-main-ssm.yaml
parameter_file: parameters/sra-guardduty-org-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# Organization SecurityHub
# -----------------------------------------------------------------------------
- name: sra-securityhub-org-main-ssm
resource_file: templates/sra-securityhub-org-main-ssm.yaml
parameter_file: parameters/sra-securityhub-org-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# Organization Macie
# -----------------------------------------------------------------------------
- name: sra-macie-org-main-ssm
resource_file: templates/sra-macie-org-main-ssm.yaml
parameter_file: parameters/sra-macie-org-main-ssm.json
deploy_method: stack_set
deployment_targets:
accounts:
- CT Management
# -----------------------------------------------------------------------------
# SCP Prevent Member Account Leaving Organization
# -----------------------------------------------------------------------------
- name: scp-prevent-accounts-leaving-org
description: "This SCP prevents users or roles in any affected account from leaving AWS Organizations, either directly as a command or through the console."
resource_file: policies/scp-prevent-accounts-leaving-org.json
deploy_method: scp
deployment_targets:
organizational_units:
- Root
# -----------------------------------------------------------------------------
# SCP Prevent Creation IAM Users
# -----------------------------------------------------------------------------
- name: scp-prevent-iam-users-creation
description: "This SCP restricts IAM principals from creating new IAM users or IAM Access Keys in an AWS account."
resource_file: policies/scp-prevent-iam-users-creation.json
deploy_method: scp
deployment_targets:
organizational_units:
- Root
- Commit the files that we’ve previously just copied, modified and deleted to CodeCommit via either a Command Prompt or Powershell.
git add .
git commit -m "Committing Changes"
git push
This will now trigger the DevOps Pipeline and assuming that no issues have occurred will show as Succeeded.
Hope this helps and enables you to customise your own Control Tower Environments.