Introduction
We will cover How To Setup AWS Lambda Using AWS CDK Python.
Did you know that AWS CDK is a programmers entry point to DevOps?
I will break this review in the following sections:
- Why setting up an AWS Lambda using CDK is helpful
- Walk through step by step on How To Setup AWS Lambda Using AWS CDK Python
I have been using this code successfully on all my Python AWS CDK deployments to launch new Lambda Functions.
Going to keep things simple and straight to the point on how to get up and running in less than 5 minutes.
All source found in this guide can be found in the GitHub repo here.
Why Should You Use AWS CDK Python To Setup A Lambda vs Terraform
There are several reasons as to why you may want to use AWS CDK Python to deploy your Lambdas, I will list them below and see if one of them suits your needs or you find yourself still needing to do that.
- You do not want to learn Terraform and have already background in Python
- You are from a programming background rather than DevOps so programming makes more sense to you
- The descriptive format of Terraform can be confusing sometimes
- You have conditional and business logic on how you want to deploy your Lambdas and when
- You want to do a lot of Dynamic work such as destroying creating Lambdas inside your existing code base that’s already written in Python (essentially extending an existing project to include DevOps work on it)
If any of the above reasons is you then keep reading and I’ll help you get started and going super fast.
How To Setup AWS CDK Python Environment
I have written a detailed step by step guide here which you can follow and get up and running in less than a few minutes. Please follow this before proceeding into writing code. If you already have AWS CDK setup in your system there’s no need to do this.
How To Setup AWS CDK With Python
How To Setup AWS Lambda Using AWS CDK Python
Now that we have the environment all setup we will do the following:
- Create a new project
- Initialize our Environment file
- Write the Code that Sets up our Stack
Create New AWS CDK Python Lambda Project
If followed the previous guide and want to re-use the project you have created that’s fine. We will be doing a slight twist to this here and basically initializing it with a different name since it’s going to be dedicated for an AWS Lambda creation using AWS CDK Python.
To avoid repeating the steps here we simply use the name lambda_deploy. If everything went well you should have ended up with the following file structure as shown below.
$ ls -al drwxr-xr-x 12 user staff 384 Feb 22 14:47 .git -rw-r--r-- 1 user staff 119 Feb 22 14:47 .gitignore drwxr-xr-x 6 user staff 192 Feb 22 14:47 .venv -rw-r--r-- 1 user staff 1658 Feb 22 14:47 README.md -rw-r--r-- 1 user staff 955 Feb 22 14:47 app.py -rw-r--r-- 1 user staff 780 Feb 22 14:47 cdk.json drwxr-xr-x 4 user staff 128 Feb 22 14:47 lambda_deploy -rw-r--r-- 1 user staff 14 Feb 22 14:47 requirements-dev.txt -rw-r--r-- 1 user staff 47 Feb 22 14:47 requirements.txt -rw-r--r-- 1 user staff 437 Feb 22 14:47 source.bat drwxr-xr-x 4 user staff 128 Feb 22 14:47 tests
Setting Up AWS Environment Credentials
In order to do this I have made a detailed guide which you can find here:
Boto3 Session: Setup Profile, Create, Close and Mock sessions
You can follow the steps listed above to add a new iam user and configure your .env file accordingly.
The permission you want to use is the following in this case:
Other than the change above you can follow the guide as is to initialize the AWS SDK permissions. Do note you may not need the Lambda permission this is only if you plan to using the same user to programmatic upload new code or changes to Lambda the Administrator permission supersedes it here.
Once this is done you also need to setup your credentials sections in your config, in this example I will be using a profile named test_deploy_lambda.
The typical values such as the secret key and access keys need to be entered. Mine looks something like this:
$ cat credentials [test_deploy_lambda] aws_access_key_id=YOUR ID aws_secret_access_key=YOUR KEY aws_default_region=us-east-1 $ cat config [test_deploy_lambda] region=us-east-1
Modifying The AWS CDK Environment File
Besides that we need to add two more attributes to our AWS CDK environment file and those are related to the CDK.
More specifically this would look like this:
CDK_DEFAULT_ACCOUNT=YOURACCOUNT CDK_DEFAULT_REGION=us-east-1
Make sure to replace the CDK_DEFAULT_ACCOUNT and CDK_DEFAULT region accordingly with your information which you can retrieve from the AWS console.
How To Synthesize And Deploy/Bootstrap Your Lambda Using AWS CDK Python
The final step is to basically run our code to:
- Synthesize
- Bootstrap
- Deploy
How To Synthesize Your AWS Lambda Using AWS CDK Python
The first step as mentioned above is to Synthesize your environment with code.
This can be done in three steps:
- Modify the app.py initialization file
- Create a sample Lambda file
- Write the code to deploy the Lambda we created
How To Modify app.py To Initialize AWS CDK
Lets examine the code that implements this.
#!/usr/bin/env python3 import os from dotenv import load_dotenv # load our env file print ('Loading env file') load_dotenv() import aws_cdk as cdk from lambda_deploy.lambda_deploy_stack import LambdaDeployStack # initialize cdk_env with variables from env file print ('Creating environment') cdk_env = cdk.Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'), region=os.getenv('CDK_DEFAULT_REGION')) # get app handler for cdk print ('Getting App handler') app = cdk.App() # describe our stack print ('Describing lambda stack') LambdaDeployStack( app, "LambdaDeployStack", env=cdk_env ) # synthesize it print ('Synthesizing stack') app.synth()
As noted we are using python-dotenv to load the environment variables we had created previously in this guide. This is to let the CDK know where we will be deploying our code. Also we will be naming in our case the stack LambdaDeployStack.
And to test it out we run the synthesize command:
$ cdk synthesize Loading env file Creating environment Getting App handler Describing lambda stack Synthesizing stack Resources: UnbiasedCoderLambdaServiceRole5BCB1ECB: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com Version: "2012-10-17" ManagedPolicyArns: - Fn::Join: - "" - - "arn:" - Ref: AWS::Partition - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Metadata: aws:cdk:path: LambdaDeployStack/Unbiased-Coder-Lambda/ServiceRole/Resource UnbiasedCoderLambdaD21DE2C2: Type: AWS::Lambda::Function Properties: Code: S3Bucket: cdk-hnb659fds-assets-ACCOUNT-us-east-1 S3Key: d7f827a081dcf499398ebf8912a02cc8dfdc96ba6ca4c036a6451f58db65c1eb.zip Role: Fn::GetAtt: - UnbiasedCoderLambdaServiceRole5BCB1ECB - Arn Handler: lambda_handler.handler Runtime: python3.9 DependsOn: - UnbiasedCoderLambdaServiceRole5BCB1ECB Metadata: aws:cdk:path: LambdaDeployStack/Unbiased-Coder-Lambda/Resource aws:asset:path: asset.d7f827a081dcf499398ebf8912a02cc8dfdc96ba6ca4c036a6451f58db65c1eb.zip aws:asset:is-bundled: false aws:asset:property: Code CDKMetadata: Type: AWS::CDK::Metadata Properties: Analytics: v2:deflate64:H4sIAAAAAAAA/zWMQQ6CMBBFz8K+HcGuXIqJa4MHIEOpOBbahGljTMPdbTGu3p/38+cIjYK6wjdLPVo50wDpHlBbkVWfZlyGESFdo9OBvBOXh/vnTRAukDo/m6ILN8GqR2YTGM4F+YY2amtCi5zrXeb/E7lpHxn2cdW5uX3C07uDghM0dfViIrlGF2gx0P34BdI/UwyrAAAA Metadata: aws:cdk:path: LambdaDeployStack/CDKMetadata/Default Parameters: BootstrapVersion: Type: AWS::SSM::Parameter::Value<String> Default: /cdk-bootstrap/hnb659fds/version Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip] Rules: CheckBootstrapVersion: Assertions: - Assert: Fn::Not: - Fn::Contains: - - "1" - "2" - "3" - "4" - "5" - Ref: BootstrapVersion AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
This creates the pre-step for deployment.
Create Sample Lambda Handler For AWS CDK
The next step is to define a simple lambda and pack it into a zip file that we will later be loading as a resource into our AWS infrastructure.
In order to do this we will be using the following AWS Lambda function that simply returns success 200 with a message we define.
def handler(event, context): tmsg = 'Hello from AWS Lambda Deployed Using AWS CDK Written By Unbiased Coder' print (tmsg) return { 'statusCode': 200, 'body': tmsg }
One thing to note is that you will need to create a zip file containing the AWS lambda handler code. In Mac/Linux you can do this using the built in command.
$ zip lambda_deploy/lambda_handler.zip lambda_deploy/lambda_handler.py $ ls -al lambda_deploy/lambda_handler.zip -rw-r--r-- 1 user staff 334 Feb 22 17:04 lambda_deploy/lambda_handler.zip
How To Implement Code To Describe AWS Lambda Using AWS Python CDK
The final step we need to do is to implement the code that will be deploying our AWS Lambda.
from aws_cdk import ( Stack, aws_lambda, ) from constructs import Construct class LambdaDeployStack(Stack): """ Simple Stack to Deploy an AWS Lambda Using CDK Args: Stack (AWS Stack): Deploys an AWS Lambda Function """ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) aws_lambda.Function( self, 'Unbiased-Coder-Lambda', handler = 'lambda_handler.handler', runtime = aws_lambda.Runtime.PYTHON_3_9, code = aws_lambda.Code.from_asset('lambda_deploy/lambda_handler.zip'))
A few notes in the code above:
- The handler you specify must match the one in the file (the one in the GitHub repo is already defined as is)
- You can use any Python Runtime you prefer in this case I used Python 3.9
- Finally the location of the zip should exist as we created it earlier, this will get uploaded into the Lambda function
How To Bootstrap Your AWS Lambda Using AWS CDK Python
The next step in the process is starting to bootstrap the AWS Lambda using our AWS CDK Python code that we wrote earlier in this guide.
$ cdk bootstrap --profile test_deploy_lambda Loading env file Creating environment Getting App handler Describing lambda stack Synthesizing stack ⏳ Bootstrapping environment aws://ACCOUNT/us-east-1... Trusted accounts for deployment: (none) Trusted accounts for lookup: (none) Using default execution policy of 'arn:aws:iam::aws:policy/AdministratorAccess'. Pass '--cloudformation-execution-policies' to customize. CDKToolkit: creating CloudFormation changeset... ✅ Environment aws://ACCOUNT/us-east-1 bootstrapped.
As it can be seen above the bootstrapping was successful. If you are following the code from the Github repo you should be good.
How To Deploy Your AWS Lambda Using AWS CDK Python
The final step is to actually deploy our code into the AWS Stack. This is a lengthy process and syncs all the changes you made in your code to the AWS server infrastructure.
To do this run the cdk deploy command as shown below.
$ cdk deploy --profile test_deploy_lambda Loading env file Creating environment Getting App handler Describing lambda stack Synthesizing stack ✨ Synthesis time: 3.32s This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬──────────────────────────────────────────┬────────┬────────────────┬──────────────────────────────┬───────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼──────────────────────────────────────────┼────────┼────────────────┼──────────────────────────────┼───────────┤ │ + │ ${Unbiased-Coder-Lambda/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │ └───┴──────────────────────────────────────────┴────────┴────────────────┴──────────────────────────────┴───────────┘ IAM Policy Changes ┌───┬──────────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼──────────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${Unbiased-Coder-Lambda/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │ └───┴──────────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)? y LambdaDeployStack: deploying... [0%] start: Publishing d7f827a081dcf499398ebf8912a02cc8dfdc96ba6ca4c036a6451f58db65c1eb:033533902081-us-east-1 [50%] success: Published d7f827a081dcf499398ebf8912a02cc8dfdc96ba6ca4c036a6451f58db65c1eb:033533902081-us-east-1 [50%] start: Publishing 2cfee3bddd3535ecae8a9c4856e4bf87c86c59dd77e3884b3d420a548e0b977c:033533902081-us-east-1 [100%] success: Published 2cfee3bddd3535ecae8a9c4856e4bf87c86c59dd77e3884b3d420a548e0b977c:033533902081-us-east-1 LambdaDeployStack: creating CloudFormation changeset... ✅ LambdaDeployStack ✨ Deployment time: 82.08s Stack ARN: arn:aws:cloudformation:us-east-1:ACCOUNT:stack/LambdaDeployStack/3ae94740-93f5-11ec-bd56-0e1cc3882b05 ✨ Total time: 85.4s
As it can be seen above the LambdaDeployStack was successfully deployed.
In order to do an extra check and verify everything works we need to visit the AWS console and see if our Lambda was created.
To do this navigate into the AWS Lambda section and we should see our Lambda.
As it can be seen the AWS CDK has picked a random name extension based on the prefix we provided which was Lambda Deploy Stack.
If we examine the contents of this we will see the Sample Lambda code we created earlier in this guide.
The code is identical to what we had in our sample code earlier.
Just to test it out we can also execute a run for it. Before that simply create an empty test event in the AWS console putting {} is fine in this case.
When we execute we see the output below:
The return status runs as expected so our Lambda has been successfully deployed and executed.
How To Destroy Your AWS Lambda Using AWS CDK Python
As a bonus we will go over how to clean up and destroy any resources you setup in your infrastructure up to now.
To do that CDK offers a very simple destroy command which basically will remove everything we added.
If we were to execute this would look like this:
$ cdk destroy --profile test_deploy_lambda Loading env file Creating environment Getting App handler Describing lambda stack Synthesizing stack Are you sure you want to delete: LambdaDeployStack (y/n)? y LambdaDeployStack: destroying... ✅ LambdaDeployStack: destroyed
AWS CDK goes into our AWS infrastructure and deletes everything that it had previously created.
In order to verify this we go also in our AWS console and see if the Lambda is gone.
An updated view looks like this:
It must be noted here that the user you created earlier and associated roles to it will not be deleted. This is something we did outside this context and you will have to navigate to the iam section and delete the user manually.
Conclusion
We were able to successfully show you How To Setup AWS Lambda Using AWS CDK Python and why you may want to use it over using Terraform.
If you found this useful and you think it may have helped you please drop me a cheer below I would appreciate it.
If you have any questions, comments please post them below or send me a note on my twitter. I check periodically and try to answer them in the priority they come in. Also if you have any corrections please do let me know and I’ll update the article with new updates or mistakes I did.
Do you find dynamically creating Lambdas necessary?
I have had a few projects in the past that required me adding and creating resources dynamically. AWS CDK was the answer to these so I’ve used it when needed. If I’m just creating a Lambda as part of a static system I prefer to use vanilla terraform scripts.
If you would like to find more DevOps and to setup specific AWS resources please check the articles below: