Scripts and Commands
Scripts
The DLZ provides utility functions that abstract the complexity of common tasks such as bootstrapping accounts across regions, running CDK diff or deploy commands, setting cost allocation tags, and more.
These functions are exposed as static methods on the Scripts
class and can be executed outside the CDK application,
either manually or as part of a pipeline. The localProfile
property specifies the AWS CLI profile to use when
executing the scripts.
const dlz = new DataLandingZone(app, {... localProfile: 'YOUR_PROFILE,...});
dlz.DataLandingZone(app,...local_profile='YOUR_PROFILE',...);
Scripts permission
For most commands, such as diff
and deploy
, the AWS profile (localProfile
) used can operate with restricted permissions.
These scripts do not require full administrative access, allowing for a more restricted permissions model to
enhance security.
The bootstrap
script, however, requires elevated permissions. The specified profile must have administrative access
to the Management account and the ability to assume the AWSControlTowerExecution
role created by AWS
Control Tower. These permissions are highly privileged and should be handled with caution.
Usage
Usage is demonstrated below for both TypeScript and Python.
A complete example is available in the TypeScript Example GitHub Repo
The code snippets below are from:
There are many ways to run scripts in a TypeScript project. Here, we’ll explore a simple and straightforward approach.
Start by creating a scripts
directory at the root of your project, and add individual TypeScript files, each
containing the specific DLZ Scripts
you want to execute.
import { Scripts } from "aws-data-landing-zone";import { config } from "../bin/minimum_config";
(async () => { await (new Scripts()).boostrapAll(config);})();
You can run the script using npx ts-node
, which is typically included as a dev dependency in AWS CDK projects. To
simplify the process, add a corresponding script to your package.json
.
{ "scripts": { "bootstrap": "npx ts-node --prefer-ts-exts scripts/bootstrap.ts" }}
You can then execute the script with:
npm run bootstrap
The bootstrapAll
function reads the DLZ configuration,
including details such as AWS profiles, account IDs, and regions. It orchestrates the bootstrapping process for the
management, security audit, security log, and workload accounts, ensuring they all trust the Management account.
Available Scripts
boostrapAll(props: DataLandingZoneProps)
- Bootstraps all accounts (management, security audit, security log, and workload accounts) in all regions.diffAll(props: DataLandingZoneProps)
- Runscdk diff "**"
to show differences for all stacks across all accounts and regions.diffSelect(props: DataLandingZoneProps, id: string)
- Runscdk diff "${id}"
to show differences for a selected stack using its ID.deployAll(props: DataLandingZoneProps)
- Deploys all stacks in all accounts and regions usingcdk deploy "**"
.deploySelect(props: DataLandingZoneProps, id: string)
- Deploys a selected stack usingcdk deploy "${id}"
.configureCostAllocationTags(props: DataLandingZoneProps)
- Sets themandatoryTags
andadditionalMandatoryTags
properties as cost allocation tags.awsNuke(props: DataLandingZoneProps, relativeDir: string, awsNukeBinary: string, accountName: string, dryRun: boolean = true): Promise<void>;
Runs AWS Nuke on the specified account. If the account is in the Suspended OU, it will delete all resources but EXCLUDE the ControlTower and CDK Bootstrap resources. If the account is in the Workloads OU, it will additionally EXCLUDE the DLZ resources. Parameters:props
- The DLZ configuration.relativeDir
- The directory of the script, used to build the full path to the AWS Nuke binary.awsNukeBinary
- The path of the AWS Nuke binary, relative to therelativeDir
parameter.accountName
- The name of the account to run AWS Nuke on.dryRun
- The default istrue
, which will only show the resources that would be deleted. Set tofalse
to delete the resources.
More examples and pre-configured scripts are available in the
TypeScript Example GitHub Repo. These can
be copied and reused in your project. They contain pre-configured scripts for the most common stack
selecting ids for the diffSelect
and deploySelect
functions.
Refer to the Stack Patterns section for a full list of stack selecting IDs.
A complete example is available in the Python Example GitHub Repo
The code snippets below are from:
Here, we’ll explore a simple and straightforward approach to run the DLZ scripts in Python.
Start by creating a scripts
directory at the root of your project, and add individual Python files, each
containing the specific DLZ Scripts
you want to execute.
from aws_data_landing_zone import Scriptsfrom data_landing_zone_example_python.config_minimum import config
scripts = Scripts()scripts.deploy_all(props=config)
You can then execute the script with:
python scripts/bootstrap.py
The bootstrapAll
function reads the DLZ configuration,
including details such as AWS profiles, account IDs, and regions. It orchestrates the bootstrapping process for the
management, security audit, security log, and workload accounts, ensuring they all trust the Management account.
Available Scripts
boostrap_all(props: DataLandingZoneProps)
- Bootstraps all accounts (management, security audit, security log, and workload accounts) in all regions.diff_all(props: DataLandingZoneProps)
- Runscdk diff "**"
to show differences for all stacks across all accounts and regions.diff_select(props: DataLandingZoneProps, id: string)
- Runscdk diff "${id}"
to show differences for a selected stack using its ID.deploy_all(props: DataLandingZoneProps)
- Deploys all stacks in all accounts and regions usingcdk deploy "**"
.deploy_select(props: DataLandingZoneProps, id: string)
- Deploys a selected stack usingcdk deploy "${id}"
.configure_cost_allocation_tags(props: DataLandingZoneProps)
- Sets themandatoryTags
andadditionalMandatoryTags
properties as cost allocation tags.aws_nuke(props: DataLandingZoneProps, relative_dir: str, aws_nuke_binary: str, account_name: str, dry_run: bool = True) -> None:
Runs AWS Nuke on the specified account. If the account is in the Suspended OU, it will delete all resources but EXCLUDE the ControlTower and CDK Bootstrap resources. If the account is in the Workloads OU, it will additionally EXCLUDE the DLZ resources. Parameters:props
- The DLZ configuration.relative_dir
- The directory of the script, used to build the full path to the AWS Nuke binary.aws_nuke_binary
- The path of the AWS Nuke binary, relative to therelative_dir
parameter.account_name
- The name of the account to run AWS Nuke on.dry_run
- The default isTrue
, which will only show the resources that would be deleted. Set toFalse
to delete the resources.
More examples and pre-configured scripts are available in the
Python Example GitHub Repo. These can
be copied and reused in your project. They contain pre-configured scripts for the most common stack
selecting ids for the diffSelect
and deploySelect
functions.
Commands (manual)
The Scripts abstraction simplifies DLZ tasks and is recommended for most use cases. However, manual commands are detailed below for reference or troubleshooting purposes.
Bootstrap
Each account and region defined in the DLZ configuration must be CDK bootstrapped. This process is automated by the
boostrapAll
function. For manual execution, use the following steps:
Script replacements:
YOUR_PROFILE
- The AWS CLI profile to use. See required permission as mentioned in Scripts permission.MANAGMENT_ACCOUNT_ID
- The AWS Account ID of the management account. All other accounts will trust this account.SECURITY_LOG_ACCOUNT_ID
- The AWS Account ID of the security log account.SECURITY_AUDIT_ACCOUNT_ID
- The AWS Account ID of the security log account.GLOBAL_REGION
- The region where the management account is located.REGIONS
- The list of other regions to bootstrap.WORKLOAD_ACCOUNT_IDS
- The list of account IDs to bootstrap.
GLOBAL_REGION="GLOBAL_REGION"REGIONS=( "REGIONS")
ACCOUNTS=( "SECURITY_LOG_ACCOUNT_ID" "SECURITY_AUDIT_ACCOUNT_ID" "WORKLOAD_ACCOUNT_IDS")
cdk bootstrap --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess --profile $YOUR_PROFILE --tags Owner=infra --tags Project=dlz --tags Environment=dlz aws://$MANAGMENT_ACCOUNT_ID/$GLOBAL_REGION
for account in "${ACCOUNTS[@]}"; do
ROLE_ARN="arn:aws:iam::$account:role/AWSControlTowerExecution" SESSION_NAME="CDKBootstrap" ASSUME_ROLE_OUTPUT=$(aws sts assume-role --profile $YOUR_PROFILE --role-arn $ROLE_ARN --role-session-name $SESSION_NAME)
AWS_ACCESS_KEY_ID=$(echo $ASSUME_ROLE_OUTPUT | jq -r '.Credentials.AccessKeyId') AWS_SECRET_ACCESS_KEY=$(echo $ASSUME_ROLE_OUTPUT | jq -r '.Credentials.SecretAccessKey') AWS_SESSION_TOKEN=$(echo $ASSUME_ROLE_OUTPUT | jq -r '.Credentials.SessionToken') export AWS_ACCESS_KEY_ID export AWS_SECRET_ACCESS_KEY export AWS_SESSION_TOKEN
cdk bootstrap --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess --trust $MANAGMENT_ACCOUNT_ID --tags Owner=infra --tags Project=dlz --tags Environment=dlz aws://$account/$GLOBAL_REGION for region in "${REGIONS[@]}"; do cdk bootstrap --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess --trust $MANAGMENT_ACCOUNT_ID --tags Owner=infra --tags Project=dlz --tags Environment=dlz aws://$account/$region donedone
Diff
The cdk diff command compares the current state of stacks with the code definition.
This process is automated by the diffAll
and diffSelect
functions.
For manual execution, see the following examples:
Below are a few examples of how to run the diff command manually.
# To diff all the stacks in all accounts and regions.cdk diff "**" --profile YOUR_PROFILE# To diff all the stacks in all accounts and regions in the "root" phase.cdk diff "root--*" --exclusively --profile YOUR_PROFILE# To diff all the stacks in the workload phase of type development (specified in the config by type: DlzAccountType.DEVELOP)cdk diff "*_development--*_*" --exclusively --profile YOUR_PROFILE
Refer to the Stack Patterns section for a full list of stack selecting IDs.
Deploy
The CDK deploy command deploys the stacks defined in the CDK code.
This process is automated by the deployAll
and deploySelect
functions.
For manual execution, see the following examples:
# To deploy all the stacks in all accounts and regions.cdk deploy "**" --require-approval never --progress events --concurrency 10 --profile ct-sandbox-exported# To deploy all the stacks in all accounts and regions in the "root" phase.cdk deploy "root--*" --require-approval never --progress events --concurrency 10 --exclusively --profile ct-sandbox-exported# To deploy all the stacks in the workload phase of type development (specified in the config by type: DlzAccountType.DEVELOP)cdk deploy "*_development--*_*" --require-approval never --progress events --concurrency 10 --exclusively --profile ct-sandbox-exported
Refer to the Stack Patterns section for a full list of stack selecting IDs.
Configure Cost Allocation Tags
Manually set cost allocation tags for the Management account’s global region using the following script:
TAGS=("Tag1" "Tag2")TAGS_JSON=$(printf ',{"Key":"%s","Status":"ACTIVE"}' "${TAGS[@]}")TAGS_JSON="[${TAGS_JSON:1}]"aws ce update-cost-allocation-tags-status --cost-allocation-tags-statuses "$TAGS_JSON"
The configureCostAllocationTags
script sets the mandatoryTags
and additionalMandatoryTags
properties as cost allocation tags.