Hello all!
Welcome to the next issue of the Tidy Cloud AWS bulletin! In this issue, I mostly cover a few tips around AWS CDK, plus labs for the well-architected framework.
Enjoy!
Hunting down unsupported AWS CDK
On March 9th I received a bunch of emails from AWS, all with essentially the same content.
[Action required] AWS CDK v1 End-of-Support June 1, 2023
The email points out that AWS CDK v1 reaches end of support on June 1st 2023, and there are stacks which have been deployed with AWS CDK v1 on the account the email was targeted for.
It continued to list a handful of stack ids (not stack names, that would be too useful...) for stacks that were deployed using AWS CDK v1, and needed an upgrade.
They also mentioned a tool called awscdk-v1-stack-finder, which also can find v1 stacks. I took this tool for a spin. It is a tool written in Typescript and can be installed using npm. Source code is available at https://github.com/cdklabs/awscdk-v1-stack-finder.
You might not need to have that permanently installed, so it is also fine to just run it via
npx awscdk-v1-stack-finder
This assumes you have set up credentials for the target account, via environment variables. You can also run it by specifying an explicit AWS profile. The tools go through pretty much all regions, and check all CloudFormation stacks in these regions. It will detect which stacks have been deployed with AWS CDK v1 by checking metadata in the CloudFormation stacks.
The output is better than the email, since it includes stack id info including region, stack name and also which specific CDK version had been used. It also detects more stacks than what is mentioned in the emails. Looking at the code, it seems it handles multiple metadata formats, while the email only included stacks for one of these formats.
If you have many stacks in an account, expect the tool to take a fair amount of time to execute...
Anyway, using this tool is definitely more useful than just taking the minimal information AWS provided in their emails.
Patching incorrect CDK constructs
This is a small tip, with an example from a case I had to do recently. The current (v2.69.0) aws_redshift
module in AWS CDK does not have any higher level constructs, only the ones that directly map to CloudFormation resources.
If you want to encrypt a Redshift cluster with your own KMS encryption key, you need to set the KmsKeyId
property in the corresponding resource. Contrary to what the name implies, it is not the KMS key id you should set there, but the KMS key ARN.
There is also an experimental module for higher-level constructs for Redshift, aws_redshift_alpha
. The Cluster
construct there takes a parameter encryption_key
as input, which is an IKey
. This is all good, except that in the version that I use, it only extracted the KMS key id, not the KMS key ARN. Also, since I use a cross-account KMS key in this case, the KMS key id would never be enough, since the key is in a different account.
You can patch around this type of bug, though. The main underlying resource of a higher-level construct is usually the corresponding CloudFormation resource. So in this case, it is pretty straightforward to overwrite the KmsKeyId
to have the proper value. See the code snippet below. The self.cluster
variable refers to an instance of the Cluster construct, and encryption_key
is a variable referencing a construct with the aws_kms.IKey interface.
# Workaround that CDK does not set the proper KMS key ARN
cluster_resource: aws_redshift.CfnCluster = self.cluster.node.default_child
cluster_resource.kms_key_id = encryption_key.key_arn
All constructs have a node property, which contains dependencies and children in the resource graph for that construct. The defaultChild
refers to the underlying main CloudFormation-level resource construct. Since it is a 1-to-1 mapping to the corresponding CloudFormation resource, you can just set the KmsKeyId
property to the desired value.
This type of workaround worked fine, and the cluster could be set up properly.
AWS CDK StackSets
One feature of CloudFormation which has no direct match in other infrastructure-as-code tools is StackSets. One reason for this is that is aspecific feature of CloudFormation that is very tied to how AWS organises its infrastructure - it would not really make much sense on other cloud providers.
A StackSet is a feature that allows you to deploy a CloudFormation template, the same CloudFormation template, to multiple AWS accounts and regions in one operation. This can typically deploy some shared baseline used across many accounts in an organisation. If the AWS accounts belong to an AWS Organisation, these stack sets can also be automatically deployed if new accounts are added to an organisation.
Before, you have been forced to use CloudFormation to take advantage of stack sets. Now the CDK team at AWS has made a construct library (still experimental though) that allows you to set up StackSets with AWS CDK stacks instead, using CDK code.
I am working with projects where we more or less need to use stack sets, and this looks a promising enhancement to that type of work. I am thrilled if I do not need to write CloudFormation directly!
GitHub repository for CDK StackSets construct library
Ensure your code for Amazon Web Services is secure and follows the recommended guidelines.
The CDK team at AWS has published a construct library named cdk-nag, which is inspired by a different tool called cfn-nag. This solution examines for security flaws and follows recommended guidelines.
You can find cdk-nag in GitHub and on Construct Hub
There are a few predefined rule packs, called NagPacks:
- AWS solutions
- HIPAA security
- NIST 800-53 rev 4
- NIST 800-53 rev 5
- PCI DSS 3.2.1
It is also possible to define your own rule packs. You can configure if rules shall trigger error or warning, and you can suppress individual rules if needed.
Here is an example code snippet with AWS CDK (in Python), where the AWS solutions NagPack applies to all stacks in the CDK app. However, for the data lake stack, two of the rules are suppressed and do not trigger warning or error. In these cases, a reason must also be given.
It is also possible to ignore suppressions conditionally for different reasons. I think cdk-nag is a nice option to include. It is fairly easy to get started, but there may be some effort to get a solution to a good place, if it has not been nagged from the start.
NagSuppressions.add_stack_suppressions(datalake_stack, [
{
‘id’: ‘AwsSolutions-SMG4’,
‘reason’: ‘Redshift Serverless does not support secret manager secrets with rotation currently’
},
{
‘id’: ‘AwsSolutions-L1’,
‘reason’: ‘xyz-cdk has dependencies that were not working with versions newer than Python 3.8, as of December 2022’
}
])
Aspects.of(app).add(AwsSolutionsChecks())
app.synth()
Well-architected labs
The AWS well-architected framework is a set of rules and recommendations for creating and running solutions for AWS.
The framework itself does not provide all the details on how to implement recommendations and practices. One approach to help on the way in that regard is the well-architected labs. It is a website with several labs covering the different pillars of the well-architected framework, and with different levels of difficulty/previous knowledge for the labs.
I think the idea is very nice, although many of the labs heavily use the AWS console unfortunately, and others make use of CloudFormation. Still, you should be able to find useful labs, even if not everyone may apply to your use cases.
You can find older bulletins and more at Tidy Cloud AWS. You will also find other useful articles around AWS automation and infrastructure-as-software.
Until next time,
/Erik
Top comments (0)