Sharing CloudWatch metrics cross-account (part 1)
Using CDK CLI via Docker container as shown in the previous post.
Define stack in app.py
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import os
from aws_cdk import aws_iam
import aws_cdk
class CloudWatchSharingStack(aws_cdk.Stack):
def __init__(self, trusted_account_ids: [str], **kwargs) -> None:
super().__init__(**kwargs)
aws_iam.Role(
scope=self,
id="Role",
role_name='CloudWatch-CrossAccountSharingRole',
assumed_by=aws_iam.CompositePrincipal(
*(aws_iam.AccountPrincipal(account_id) for account_id in trusted_account_ids)
),
description="A role for sharing CloudWatch metrics across accounts",
managed_policies=[
aws_iam.ManagedPolicy.from_aws_managed_policy_name(name) for name in (
'CloudWatchReadOnlyAccess',
'CloudWatchAutomaticDashboardsAccess',
'AWSXrayReadOnlyAccess',
)
],
)
app = aws_cdk.App()
CloudWatchSharingStack(
scope=app,
id="CloudWatchSharingStack",
stack_name="CloudWatchSharingStack",
env=aws_cdk.Environment(
account=os.environ['CDK_DEFAULT_ACCOUNT'],
region=os.environ['CDK_DEFAULT_REGION'],
),
trusted_account_ids=['123456789012'],
)
app.synth()
and create a Makefile
:
1
2
3
4
5
6
7
8
9
10
11
clean:
rm -rf cdk.out
rm -rf venv
venv:
cdk.sh -c 'python -m venv venv && venv/bin/pip install -U pip'
cdk.sh -c 'venv/bin/pip install aws-cdk-lib constructs'
echo "$$(yq -Moj '.app = "venv/bin/python app.py"' cdk.json)" > cdk.json
synth: venv
cdk synth | yq -P
The following cdk.json
would also work in our case:
1
2
3
{
"app": "venv/bin/python app.py"
}
Now synth the template:
1
make clean synth
Locking dependencies is a good idea for a more complex or regularly-updated stack, in requirements.txt
:
aws-cdk-lib==2.131.0
constructs>=10.0.0,<11.0.0
To make inspections work in PyCharm, one could create a host venv and use it for interpreter
1
2
3
4
5
6
7
venv_host:
python -m venv venv_host
venv_host/bin/pip install -U pip
venv_host/bin/pip install -r requirements.txt
...:
cdk.sh -c 'venv/bin/pip install -r requirements.txt'
Using CDK context to pass a list of trusted accounts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from aws_cdk import aws_iam
import aws_cdk
class CloudWatchSharingStack(aws_cdk.Stack):
def __init__(self, **kwargs):
super().__init__(**kwargs)
aws_iam.Role(
scope=self,
id="Role",
role_name='CloudWatch-CrossAccountSharingRole',
assumed_by=aws_iam.CompositePrincipal(
*(
aws_iam.AccountPrincipal(account_id)
for account_id in self.node.get_context("TrustedAccountIds").split(',')
)
),
description="A role for sharing CloudWatch metrics across accounts",
managed_policies=[
aws_iam.ManagedPolicy.from_aws_managed_policy_name(name) for name in (
'CloudWatchReadOnlyAccess',
'CloudWatchAutomaticDashboardsAccess',
'AWSXrayReadOnlyAccess',
)
],
)
app = aws_cdk.App()
CloudWatchSharingStack(
scope=app,
id="CloudWatchSharingStack",
stack_name="CloudWatchSharingStack",
)
app.synth()
Example:
1
cdk synth CloudWatchSharingStack --context TrustedAccountIds="123456789012"
Now, make it deploy:
1
2
3
4
5
6
7
8
9
10
PROFILE = my-profile
TRUSTED = 123,456
CONTEXT = 'TrustedAccountIds=${TRUSTED}'
synth: venv
rm -rf cdk.out
cdk synth CloudWatchSharingStack --context ${CONTEXT}
deploy: venv
aws-vault exec ${PROFILE} -- cdk deploy CloudWatchSharingStack --context ${CONTEXT}
This post is licensed under CC BY 4.0 by the author.