The code for this project is located on my Github: beanstalk-rds-cdk-sampleapp
When developing an application that you want to get deployed to the cloud quickly, one option would be to use Elastic Beanstalk. The Beanstalk platform handles your deployment’s provisioning, load balancing, scaling, and application health monitoring.
There may be other services you’re interested in stacking, such as RDS or an Elastic Load Balancer. Since you’re developing this stack on AWS, and will likely transition away from Beanstalk in the future for production, it would be good practice to get started with the Cloud Development Kit (CDK). This way you will have a good foundation for developing and deploying a wide range of services on AWS.
Cloud Development Kit (CDK)
CDK is an open-source software development framework to define your cloud application resources using popular programming languages, such as Python, Go, and Java. You define your architecture in your favorite programming languages, and the CDK engine outputs, or synthesizes your code to Cloudformation templates. You get the best of both worlds.
You get to benefit from the programming language’s expressive nature and functionality, such as objects, loops, and conditions. If your application were written in Python, it would make sense to write your CDK constructs in Python. This way you could integrate Python classes created for your application into your CDK application code to help bootstrap the application for deployment.
You also have the benefit of being able to version control your CDK code, just as you would if writing Cloudformation templates directly.
There are a few command-line tools and libraries you will need to install on your local system to get up and running. Obviously, you could install these in a Docker container, but that’s out of scope for this article.
- AWS CLI
- AWS Account configured with appropriate permissions to deploy your services and create CloudFormation stacks
- AWS CDK toolkit
- Python (since this article focuses on CDK w/ Python)
Normally, you will initialize a working directory by:
cdk init sample-app --language python in the directory. As this will generate some scaffolding to help develop your CDK code.
But if you’re using my Github app as a starting point, you can just git pull my repo.
CDK in Python is similar to writing an application in Python, meaning it’s best practice to use something like virtrualenv to manage Python libraries with Pip. Most Python CDK projects should make installing the required CDK libraries and constructs easy with Pip.
For my sample CDK project that deploys Elastic Beanstalk, MySQL RDS, and an Application Load Balancer, we have three main files. In order of execution:
This is the main file that gets executed when you run any of the CDK commands. Therefore, it should import and include all of the CDK constructs, Python libraries, and Stacks to run your code. It’s the file that connects everything together. I’ve also added some variables that will be shared between stacks.
This stack takes the tedious, but important task of configuring your VPC, including subnets, route tables, and security groups, and expresses it into easy-to-read code that you can replicate and reuse. Since some of this information will be used in the next stack that’s in a separate file, I made sure to pass references to objects when needed.
For example, for a few subnets, and the VPC itself I pass the reference to a variable to be used with certain Beanstalk construct options that expect them. Until CDK creates the VPC, you won’t know what the VPC ID is, but by passing the reference to the object you won’t need to.
Starts off with some basic settings for launching the RDS service, along with generating a secure password and storing it in Secrets Manager.
Behind the scenes, when you bootstrap the CDK app into your region it creates and manages an S3 bucket used for storing files it uses. We can leverage this when uploading our application in a zip file to load into Beanstalk. The code I have expects a properly structured zip file to be one level up from the main app.py.
Most of this code uses Level 1 (low-level) CDK constructs, this is because it allows for more flexibility where needed.
As you’ll soon find out, Elastic Beanstalk makes a lot of assumptions about your application environment, which is fine because its job is to quickly deploy your application. But if you’re sitting down to write CDK code for your deployment, you might as well add a few lines to fine-tune it to fit your needs. There is a long list of options you can customize with Beanstalk.
The last few lines are important and depend on the application you want to deploy. So be sure to set the appropriate Beanstalk platform
This should set you off to a nice start with your first CDK app. The one thing the code doesn’t handle is making use of the database password stored in Secrets Manager. Beanstalk doesn’t directly support pulling from Secrets Manager at the time of this writing, however, there are a handful of ways to go about it.
One way, though one I wouldn’t recommend for production, is to use environmental variables. However, the cleartext password will appear in console logs. A better way would be to use ebextensions, and use AWS CLI (get-secret-value). Depending on the actual application you’re deploying, you can use the AWS SDK and pull the secret that way.
Elastic Beanstalk is a good way to get your application deployed, but for a more scalable and flexible solution you may want to consider Elastic Container Service. So in my next article I’m going to discuss deploying an ECS/Fargate, DynamoDB stack for your application.