This is how I deploy multiple AWS environments using python cdk.
If you decided to use cdk and haven't implemented it already, you can start here: (https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html)
- making text bold is not working as expected. If you know how to fix it, please let me know.
I assume you know the basics, explained in these aws docs.
First, let's see how we implement a single stack (single deployment environment).
The files structure should look similar to this:
MyProject
│
└───cdk_folder
└───cdk_folder
│ | __init__.py
│ | my_cdk_stack.py
└───tests ... (folder)
└───.venv ... (folder)
└───cdk.out ... (folder)
| cdk.json
| app.py
We will look at the files MyProject/cdk_folder/cdk_folder/my_cdk_stack.py and app.py
The my_cdk_stack.py will define the stack contents. In this example will create an SQS queue:
import aws_cdk
from aws_cdk import (
Stack,
aws_sqs as _sqs,
)
from constructs import Construct
class MyCdkStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
my_queue = _sqs.Queue(self, f'SQSMyQueue', queue_name='my_queue')
app.py:
import aws_cdk as cdk
from cdk_folder.my_cdk_stack import MyCdkStack
app = cdk.App()
MyCdkStack(app, 'MyCdkStack' env=cdk.Environment(account=<account id>, region=<region>))
app.synth()
now you can run the commands as explained in the docs (cdk synth and/or cdk deploy) after you have run cdk bootstrap.
Now let's say you want a production environment and a test environment, each accessing a different database and have its own api gateway and labmda function for example.
We can create another stack in app.py:
import aws_cdk as cdk
from cdk_folder.my_cdk_stack import MyCdkStack
app = cdk.App()
**MyCdkStack(app, 'MyCdkStackProd' env=cdk.Environment(account=<account id>, region=<region>))
MyCdkStack(app, 'MyCdkStackTest' env=cdk.Environment(account=<account id>, region=<region>))**
app.synth()
You'd probably want each environment to be different in some ways - the lambda functions to access a different database, have a different domain for cloud front distribution and so on.
For this, you can add parameters to your stack (or wrap all of them in one object):
from my_cdk_stack.py:
from aws_cdk.aws_lambda_python_alpha import PythonFunction
from aws_cdk import (
Stack,
aws_cloudfront as _cloud_front,
aws_secretsmanager as _secretmanager,
)
class MyStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **env_name: str, rds_password_secret_arn: str, db_endpoint: str**, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
rds_secret = _secretmanager.Secret.from_secret_attributes(self, f'{construct_id}-
RdsCredentialsSecret', secret_complete_arn=rds_password_secret_arn)
common_environment_vars = {
'rds_credentials': rds_password_secret_arn,
'db_endpoint': db_endpoint,
'region': self.region
}
lambda_login = PythonFunction(
self,
f'{construct_id}-LoginHandler',
function_name=f'MyCdkStack{env_name}-LoginHandler',
entry='../server',
runtime=_lambda.Runtime.PYTHON_3_8,
handler='login',
index='auth.py',
environment=common_environment_vars
)
_cloud_front.Distribution(self, f'{construct_id}-AppDistribution', default_behavior=_cloud_front.BehaviorOptions(
origin=... viewer_protocol_policy=_cloud_front.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,),
domain_names=[
f'app.{env_name}.your_domain.com' # or whatever you need based on {env_name}
],
default_root_object='index.html')
and the app.py file:
import aws_cdk as cdk
from cdk_folder.my_cdk_stack import MyCdkStack
app = cdk.App()
MyCdkStack(app, '**MyCdkStackProd**' env=cdk.Environment(account=<account id>, region=<**region1**>),
**db_endpoint=<db_endpoint1>, rds_password_secret_arn=<secret_arn1>**
)
MyCdkStack(app, '**MyCdkStackTest**' env=cdk.Environment(account=<account id>, region=<**region2**>),
**db_endpoint=<db_endpoint2>, rds_password_secret_arn=<secret_arn2>**
)
app.synth()
I use different regions, so for the test environment I can choose the cheapest region for my use case, and also I can easily switch between environments in the AWS console by switching the regions in the console. You will need to bootstrap each region:
"cdk bootstrap aws://ACCOUNT-NUMBER-1/REGION-1 aws://ACCOUNT-NUMBER-2/REGION-2 ..."
(from ) (ACCOUNT-NUMBER-1 can be the same as ACCOUNT-NUMBER-2).
Top comments (0)