This is the AWS CDK v2 Developer Guide. The older CDK v1 entered maintenance on June 1, 2022 and ended support on June 1, 2023.
Working with the AWS CDK in Python
Python is a fully-supported client language for the AWS Cloud Development Kit (AWS CDK) and is considered stable. Working with the AWS CDK in
Python uses familiar tools, including the standard Python implementation (CPython), virtual environments with
virtualenv
,and the Python package installerpip
.The modules comprising the AWS Construct
Library are distributed viapypi.orgsnake_case
method names).
You can use any editor or IDE. Many AWS CDK developers useVisual Studio
Code
Topics
Get started with Python
To work with the AWS CDK, you must have an AWS account and credentials and have installed Node.js and the AWS CDK Toolkit. SeeGetting started with the AWS CDK.
Python AWS CDK applications require Python 3.6 or later. If you don't already have it installed,download a compatible versionyum
,apt
,etc.). Mac
users may be interested inHomebrew
Note
Third-party language deprecation: language version is only supported until its EOL (End Of Life) shared by the vendor or community and is subject to change with prior notice.
The Python package installer,pip
,and virtual environment manager,virtualenv
,are also
required. Windows installations of compatible Python versions include these tools. On Linux,pip
and
virtualenv
may be provided as separate packages in your package manager. Alternatively, you may install
them with the following commands:
python -m ensurepip --upgrade python -m pip install --upgrade pip python -m pip install --upgrade virtualenv
If you encounter a permission error, run the above commands with the--user
flag so that the modules
are installed in your user directory, or usesudo
to obtain the permissions to install the modules
system-wide.
Note
It is common for Linux distros to use the executable namepython3
for Python 3.x, and have
python
refer to a Python 2.x installation. Some distros have an optional package you can install that
makes thepython
command refer to Python 3. Failing that, you can adjust the command used to run your
application by editingcdk.json
in the project's main directory.
Note
On Windows, you may want to invoke Python (andpip) using thepy
executable, the>Python launcher for
Windows
If typingpythonat the command line results in a message about installing Python from the Windows Store, even after installing a Windows version of Python, open Windows' Manage App Execution Aliases settings panel and turn off the two App Installer entries for Python.
Creating a project
You create a new AWS CDK project by invokingcdk init
in an empty directory. Use the
--language
option and specifypython
:
mkdir my-project cd my-project cdk init app --language python
cdk init
uses the name of the project folder to name various elements of the
project, including classes, subfolders, and files. Hyphens in the folder name are converted to underscores. However,
the name should otherwise follow the form of a Python identifier; for example, it should not start with a number or
contain spaces.
To work with the new project, activate its virtual environment. This allows the project's dependencies to be installed locally in the project folder, instead of globally.
source.venv/bin/activate
Note
You may recognize this as the Mac/Linux command to activate a virtual environment. The Python templates include a
batch file,source.bat
,that allows the same command to be used on Windows. The traditional Windows
command,.\venv\Scripts\activate
,works, too.
If you initialized your AWS CDK project using CDK Toolkit v1.70.0 or earlier, your virtual environment is in the
.env
directory instead of.venv
.
Important
Activate the project's virtual environment whenever you start working on it. Otherwise, you won't have access to the modules installed there, and modules you install will go in the Python global module directory (or will result in a permission error).
After activating your virtual environment for the first time, install the app's standard dependencies:
python -m pip install -r requirements.txt
Managing AWS Construct Library modules
Use the Python package installer,pip,to install and update AWS Construct Library modules for use by your apps, as well as other packages you need.pipalso installs the dependencies for those modules automatically. If your system does not recognizepipas a standalone command, invoke pipas a Python module, like this:
python -m pip
PIP-COMMAND
Most AWS CDK constructs are inaws-cdk-lib
.Experimental modules are in separate modules named like
aws-cdk.
.The service name includes an
awsprefix. If you're unsure of a module's name,search for it at PyPISERVICE-NAME
.alpha
python -m pip install aws-cdk.aws-codestar-alpha
Some services' constructs are in more than one namespace. For example, besidesaws-cdk.aws-route53
,
there are three additional Amazon Route 53 namespaces, namedaws-route53-targets
,
aws-route53-patterns
,andaws-route53resolver
.
Note
ThePython edition of the CDK API Referencealso shows the package names.
The names used for importing AWS Construct Library modules into your Python code look like the following.
import aws_cdk.aws_s3 as s3 import aws_cdk.aws_lambda as lambda_
We recommend the following practices when importing AWS CDK classes and AWS Construct Library modules in your applications. Following these guidelines will help make your code consistent with other AWS CDK applications as well as easier to understand.
-
Generally, import individual classes from top-level
aws_cdk
.from aws_cdk import App, Construct
-
If you need many classes from the
aws_cdk
,you may use a namespace alias ofcdk
instead of importing individual classes. Avoid doing both.import aws_cdk as cdk
-
Generally, import AWS Construct Libraries using short namespace aliases.
import aws_cdk.aws_s3 as s3
After installing a module, update your project'srequirements.txt
file, which lists your
project's dependencies. It is best to do this manually rather than usingpip freeze
.pip
freeze
captures the current versions of all modules installed in your Python virtual environment, which can be
useful when bundling up a project to be run elsewhere.
Usually, though, yourrequirements.txt
should list only top-level dependencies (modules that
your app depends on directly) and not the dependencies of those libraries. This strategy makes updating your
dependencies simpler.
You can editrequirements.txt
to allow upgrades; simply replace the==
preceding
a version number with~=
to allow upgrades to a higher compatible version, or remove the version
requirement entirely to specify the latest available version of the module.
Withrequirements.txt
edited appropriately to allow upgrades, issue this command to upgrade
your project's installed modules at any time:
pip install --upgrade -r requirements.txt
Managing dependencies in Python
In Python, you specify dependencies by putting them inrequirements.txt
for applications or
setup.py
for construct libraries. Dependencies are then managed with the PIP tool. PIP is
invoked in one of the following ways:
pip
command
options
python -m pipcommand
options
Thepython -m pipinvocation works on most systems;piprequires that PIP's executable be on the system path. Ifpipdoesn't work, try replacing it withpython -m pip.
Thecdk init --language pythoncommand creates a virtual environment for your new project. This
lets each project have its own versions of dependencies, and also a basicrequirements.txt
file.
You must activate this virtual environment by runningsource.venv/bin/activateeach time you begin
working with the project. On Windows, run.\venv\Scripts\activateinstead
CDK applications
The following is an examplerequirements.txt
file. Because PIP does not have a
dependency-locking feature, we recommend that you use the == operator to specify exact versions for all dependencies,
as shown here.
aws-cdk-lib==2.14.0 aws-cdk.aws-appsync-alpha==2.10.0a0
Installing a module withpip installdoes not automatically add it to
requirements.txt
.You must do that yourself. If you want to upgrade to a later version of a
dependency, edit its version number inrequirements.txt
.
To install or update your project's dependencies after creating or editingrequirements.txt
,
run the following:
python -m pip install -r requirements.txt
Tip
Thepip freezecommand outputs the versions of all installed dependencies in a format that
can be written to a text file. This can be used as a requirements file withpip install -r
.
This file is convenient for pinning all dependencies (including transitive ones) to the exact versions that you
tested with. To avoid problems when upgrading packages later, use a separate file for this, such as
freeze.txt
(notrequirements.txt
). Then, regenerate it when you upgrade
your project's dependencies.
Third-party construct libraries
In libraries, dependencies are specified insetup.py
,so that transitive dependencies are
automatically downloaded when the package is consumed by an application. Otherwise, every application that wants to
use your package needs to copy your dependencies into theirrequirements.txt
.An example
setup.py
is shown here.
from setuptools import setup setup( name='my-package', version='0.0.1', install_requires=[ 'aws-cdk-lib==2.14.0', ], ... )
To work on the package for development, create or activate a virtual environment, then run the following command.
python -m pip install -e.
Although PIP automatically installs transitive dependencies, there can only be one installed copy of any one package. The version that is specified highest in the dependency tree is selected; applications always have the last word in what version of packages get installed.
AWS CDK idioms in Python
Language conflicts
In Python,lambda
is a language keyword, so you cannot use it as a name for the AWS Lambda construct
library module or Lambda functions. The Python convention for such conflicts is to use a trailing underscore, as in
lambda_
,in the variable name.
By convention, the second argument to AWS CDK constructs is namedid
.When writing your own stacks and
constructs, calling a parameterid
"shadows" the Python built-in functionid()
,which
returns an object's unique identifier. This function isn't used very often, but if you should happen to need it in
your construct, rename the argument, for exampleconstruct_id
.
Arguments and properties
All AWS Construct Library classes are instantiated using three arguments: thescopein which the construct is being defined (its parent in the construct tree), anid,and props,a bundle of key/value pairs that the construct uses to configure the resources it creates. Other classes and methods also use the "bundle of attributes" pattern for arguments.
scopeandidshould always be passed as positional arguments, not keyword arguments, because their names change if the construct accepts a property namedscopeor id.
In Python, props are expressed as keyword arguments. If an argument contains nested data structures, these are expressed using a class which takes its own keyword arguments at instantiation. The same pattern is applied to other method calls that take a structured argument.
For example, in a Amazon S3 bucket'sadd_lifecycle_rule
method, thetransitions
property is
a list ofTransition
instances.
bucket.add_lifecycle_rule( transitions=[ Transition( storage_class=StorageClass.GLACIER, transition_after=Duration.days(10) ) ] )
When extending a class or overriding a method, you may want to accept additional arguments for your own purposes
that are not understood by the parent class. In this case you should accept the arguments you don't care about using
the**kwargs
idiom, and use keyword-only arguments to accept the arguments you're interested in. When
calling the parent's constructor or the overridden method, pass only the arguments it is expecting (often just
**kwargs
). Passing arguments that the parent class or method doesn't expect results in an
error.
class MyConstruct(Construct): def __init__(self, id, *, MyProperty=42, **kwargs): super().__init__(self, id, **kwargs) #...
A future release of the AWS CDK could coincidentally add a new property with a name you used for your own property. This won't cause any technical issues for users of your construct or method (since your property isn't passed "up the chain," the parent class or overridden method will simply use a default value) but it may cause confusion. You can avoid this potential problem by naming your properties so they clearly belong to your construct. If there are many new properties, bundle them into an appropriately-named class and pass it as a single keyword argument.
Missing values
The AWS CDK usesNone
to represent missing or undefined values. When working with
**kwargs
,use the dictionary'sget()
method to provide a default value if a property is
not provided. Avoid usingkwargs[...]
,as this raisesKeyError
for missing values.
encrypted = kwargs.get( "encrypted" ) # None if no property "encrypted" exists encrypted = kwargs.get( "encrypted", False) # specify default of False if property is missing
Some AWS CDK methods (such astryGetContext()
to get a runtime context value) may return
None
,which you will need to check explicitly.
Using interfaces
Python doesn't have an interface feature as some other languages do, though it does haveabstract base classes
To indicate that a class implements a particular interface, you can use the@jsii.implements
decorator:
from aws_cdk import IAspect, IConstruct import jsii @jsii.implements(IAspect) class MyAspect(): def visit(self, node: IConstruct) -> None: print( "Visited", node.node.path)
Type pitfalls
Python uses dynamic typing, where all variables may refer to a value of any type. Parameters and return values may be annotated with types, but these are "hints" and are not enforced. This means that in Python, it is easy to pass the incorrect type of value to a AWS CDK construct. Instead of getting a type error during build, as you would from a statically-typed language, you may instead get a runtime error when the JSII layer (which translates between Python and the AWS CDK's TypeScript core) is unable to deal with the unexpected type.
In our experience, the type errors Python programmers make tend to fall into these categories.
-
Passing a single value where a construct expects a container (Python list or dictionary) or vice versa.
-
Passing a value of a type associated with a layer 1 (
CfnXxxxxx
) construct to a L2 or L3 construct, or vice versa.
The AWS CDK Python modules do include type annotations, so you can use tools that support them to help with types.
If you are not using an IDE that supports these, such asPyCharm
Synthesizing and deploying
Thestacksdefined in your AWS CDK app can be synthesized and deployed individually or together using the commands below. Generally, you should be in your project's main directory when you issue them.
-
cdk synth
:Synthesizes a AWS CloudFormation template from one or more of the stacks in your AWS CDK app. -
cdk deploy
:Deploys the resources defined by one or more of the stacks in your AWS CDK app to AWS.
You can specify the names of multiple stacks to be synthesized or deployed in a single command. If your app defines only one stack, you do not need to specify it.
cdk synth # app defines single stack cdk deploy Happy Grumpy # app defines two or more stacks; two are deployed
You may also use the wildcards * (any number of characters) and? (any single character) to identify stacks by pattern. When using wildcards, enclose the pattern in quotes. Otherwise, the shell may try to expand it to the names of files in the current directory before they are passed to the AWS CDK Toolkit.
cdk synth "Stack?" # Stack1, StackA, etc. cdk deploy "*Stack" # PipeStack, LambdaStack, etc.
Tip
You don't need to explicitly synthesize stacks before deploying them;cdk
deploy
performs this step for you to make sure your latest code gets deployed.
For full documentation of thecdk
command, seeAWS CDK Toolkit (cdk command).