<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rony Tesler</title>
    <description>The latest articles on DEV Community by Rony Tesler (@ronyt).</description>
    <link>https://dev.to/ronyt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1185784%2Ff73664df-e70a-41c2-bfb7-bf0dc4131866.png</url>
      <title>DEV Community: Rony Tesler</title>
      <link>https://dev.to/ronyt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ronyt"/>
    <language>en</language>
    <item>
      <title>Deploy multiple AWS environments using cdk (python).</title>
      <dc:creator>Rony Tesler</dc:creator>
      <pubDate>Sun, 15 Oct 2023 20:29:35 +0000</pubDate>
      <link>https://dev.to/ronyt/deploy-multiple-aws-environments-using-cdk-python-44hd</link>
      <guid>https://dev.to/ronyt/deploy-multiple-aws-environments-using-cdk-python-44hd</guid>
      <description>&lt;p&gt;This is how I deploy multiple AWS environments using python cdk.&lt;br&gt;
If you decided to use cdk and haven't implemented it already, you can start here: (&lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html"&gt;https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html&lt;/a&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;making text bold is not working as expected. If you know how to fix it, please let me know.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I assume you know the basics, explained in these aws docs.&lt;br&gt;
First, let's see how we implement a single stack (single deployment environment).&lt;br&gt;
The files structure should look similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    MyProject
    │    
    └───cdk_folder   
        └───cdk_folder
        │     |  __init__.py
        │     | my_cdk_stack.py   
        └───tests ... (folder)
        └───.venv ... (folder)
        └───cdk.out ... (folder)
        |   cdk.json
        |   app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will look at the files &lt;code&gt;MyProject/cdk_folder/cdk_folder/my_cdk_stack.py&lt;/code&gt; and &lt;code&gt;app.py&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The my_cdk_stack.py will define the stack contents. In this example will create an SQS queue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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) -&amp;gt; None:
        super().__init__(scope, construct_id, **kwargs)
        my_queue = _sqs.Queue(self, f'SQSMyQueue', queue_name='my_queue')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;app.py:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import aws_cdk as cdk
from cdk_folder.my_cdk_stack import MyCdkStack
app = cdk.App()
MyCdkStack(app, 'MyCdkStack' env=cdk.Environment(account=&amp;lt;account id&amp;gt;, region=&amp;lt;region&amp;gt;))
app.synth()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now you can run the commands as explained in the docs (cdk synth and/or cdk deploy) after you have run cdk bootstrap.&lt;/p&gt;

&lt;p&gt;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.&lt;br&gt;
We can create another stack in app.py:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import aws_cdk as cdk
from cdk_folder.my_cdk_stack import MyCdkStack
app = cdk.App()
**MyCdkStack(app, 'MyCdkStackProd' env=cdk.Environment(account=&amp;lt;account id&amp;gt;, region=&amp;lt;region&amp;gt;))
MyCdkStack(app, 'MyCdkStackTest' env=cdk.Environment(account=&amp;lt;account id&amp;gt;, region=&amp;lt;region&amp;gt;))**
app.synth()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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.&lt;br&gt;
For this, you can add parameters to your stack (or wrap all of them in one object):&lt;br&gt;
from my_cdk_stack.py:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;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) -&amp;gt; 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')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and the app.py file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import aws_cdk as cdk
from cdk_folder.my_cdk_stack import MyCdkStack
app = cdk.App()
MyCdkStack(app, '**MyCdkStackProd**' env=cdk.Environment(account=&amp;lt;account id&amp;gt;, region=&amp;lt;**region1**&amp;gt;),
**db_endpoint=&amp;lt;db_endpoint1&amp;gt;, rds_password_secret_arn=&amp;lt;secret_arn1&amp;gt;**
)
MyCdkStack(app, '**MyCdkStackTest**' env=cdk.Environment(account=&amp;lt;account id&amp;gt;, region=&amp;lt;**region2**&amp;gt;),
**db_endpoint=&amp;lt;db_endpoint2&amp;gt;, rds_password_secret_arn=&amp;lt;secret_arn2&amp;gt;**
)
app.synth()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;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:&lt;br&gt;
"&lt;code&gt;cdk bootstrap aws://ACCOUNT-NUMBER-1/REGION-1 aws://ACCOUNT-NUMBER-2/REGION-2 ...&lt;/code&gt;"&lt;br&gt;
(from &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html"&gt;&lt;/a&gt;) (&lt;code&gt;ACCOUNT-NUMBER-1&lt;/code&gt; can be the same as &lt;code&gt;ACCOUNT-NUMBER-2&lt;/code&gt;).&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
