Category Archives: CDK

aws-cdk template porting migration tips

AWS-CDK Migration Tips

When migrating to a new framework there are going to be some working pains. This is just a collection of frustrations that I encountered while adopting aws-cdk. I did some research prior and found the article “Hey CDK, how can I migrate my existing CloudFormation templates?” by Philipp Garbe and the “core module AWS CDK” documentation most helpful in thinking about migrating initially.

Import Immutable Roles

Use the mutable flag when importing existing roles with Role.fromRoleArn() otherwise the precision of the aws-cdk may lead to the dreaded “Maximum policy size of 10240 bytes” error. Eventually aws-cdk issue #4465 will be fixed and we will welcome the precise IAM policies the CDK generates.

The maximum policy size error was most often encountered on CodePipeline deploy roles where we had a large number of independent artifacts deploying CloudFormations.

Explicit to_string() in python

Having to explicitly call the core.Fn.get_att(‘Foo’, ‘Bar’).to_string() operator instead of using a str() for f'{var}’ style tripped me up.

I noticed in my IDE that the signature called for a string (thanks types!) so I tried:

str(core.Fn.get_att('Foo','Bar'))

and

f'{core.Fn.get_att('Foo','Bar')}'

but because only __repr__ is defined in the python interface I got an ugly object name when I expected __str__ to be implemented. I overlooked the to_string(), which is a pretty common method for many object oriented languages, as I expected the class to behave more pythonically.

Beware of Copy Paste / Naming

Name a stack the same as another? You get a diff but if you aren’t paying attention you’ll blow away a stack before realizing it. Also you end up with the old stack as well not updated because of this config SNAFU.

Import Pains

CfnImport is great for importing old CloudFormations but the stack is immutable upon import. Any changes to the stack must happen prior to making the call. We leaned on PyYAML but then had to undo a few of the niceties of only processing the template with AWS based systems.

Intrinsic Function Shortcuts

For example all bang, “!” ie “!Ref” or “!Sub”, references need to be updated to be the full function command, ie “Ref:” and “Fn::Sub:”.

Attributeerror: ‘datetime.date’

IAM Policy Documents specifying the Version unquoted instead of as a string, ie Version: 2012-10-17 instead of Version: ‘2012-10-17’, will have the cdk synth command greet them with following obscure error.

This error also occurs on AWSTemplateFormatVersion blocks so beware.

 AttributeError: 'datetime.date' object has no attribute '__jsii__type__'.

Example CfnImport

Here is an example of using the CfnImport to inject parameters into a traditional template and then load it into the CDK stack.


import yaml
from aws_cdk import core
class RawStack(core.Stack):
def __init__(self, scope: core.Construct, name: str, template_path: str, wrapped_parameters=None,
**kwargs) -> None:
"""import a stack off a path and munge in ssm variables if desired
:param template_path: path to raw stack being imported
:param wrapped_parameters: map of Parameter keys and default values
:param kwargs: all the stack stuff
"""
super().__init__(scope=scope, name=name, **kwargs)
if not wrapped_parameters:
wrapped_parameters = {}
template_path = Path(template_path)
with open(template_path, 'r') as f:
template = yaml.load(f, Loader=yaml.SafeLoader)
if project_name:
for pk, pv in template['Parameters'].items():
if 'Default' in pv:
if pk in wrapped_parameters:
template['Parameters'][pk]['Default'] = wrapped_parameters[pk]
elif pv['Default'] == "":
template['Parameters'][pk]['Type'] = 'AWS::SSM::Parameter::Value<String>'
template['Parameters'][pk]['Default'] = str(pk)
else:
if pk in wrapped_parameters:
template['Parameters'][pk]['Default'] = wrapped_parameters[pk]
else:
template['Parameters'][pk]['Type'] = 'AWS::SSM::Parameter::Value<String>'
template['Parameters'][pk]['Default'] = str(pk)
core.CfnInclude(self, 'RawStack', template=template)

view raw

raw_stack.py

hosted with ❤ by GitHub

raw_stack.py gist link

 

AWS CDK CLI can only be used with apps created by CDK error

I upgraded my AWS CDK to 1.10.1 today because it prompted me via:

**************************************************
*** Newer version of CDK is available [1.10.0] ***
*** Upgrade recommended                        ***
**************************************************

After doing the upgrade via

npm install -i -g aws-cdk

I went to do a cdk ls or cdk diff and was greeted with the error:

CDK CLI can only be used with apps created by CDK >= 1.10.0

Googling around wasn’t too helpful but finally I figured out that it was complaining that my python dependencies  had the old aws-cdk libraries installed.

A quick

rm -r .env/
python -m venv .env
pip install -r requirements.txt

And I was back in business

cdk ls
integration-pipeline