<?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: Dakota Lewallen</title>
    <description>The latest articles on DEV Community by Dakota Lewallen (@therealdakotal).</description>
    <link>https://dev.to/therealdakotal</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%2F56949%2Fc232f55a-392e-49db-9213-cb266c2eeddb.jpg</url>
      <title>DEV Community: Dakota Lewallen</title>
      <link>https://dev.to/therealdakotal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/therealdakotal"/>
    <language>en</language>
    <item>
      <title>Configuring CI/CD For Your CDK Application, With CDK</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Tue, 01 Apr 2025 12:53:04 +0000</pubDate>
      <link>https://dev.to/aws-builders/configuring-cicd-for-your-cdk-application-with-cdk-1o0k</link>
      <guid>https://dev.to/aws-builders/configuring-cicd-for-your-cdk-application-with-cdk-1o0k</guid>
      <description>&lt;p&gt;As your project gains traction, it will likely exceed what is reasonable for manual CLI deployments. At this point, you’ll need to decide how to automate your deployments. Since CDK is a CloudFormation (or Terraform) synthesizer, setting up a process to accomplish this is fairly open-ended. All you really need is a compute space capable of running CLI commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  CDK Pipelines Construct
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;CDK Pipelines is an opinionated construct library. - the docs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m starting with this because it is what I personally have the most experience with, and is built by the CDK team. Bias aside, it has saved me from bad deployments a number of times and I do recommend it. But admittedly, it can be finicky sometimes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It’s included in the CDK library. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There is no need to install additional dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It’s maintained by the same team that maintains the rest of the library.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typical third-party library concerns aren’t relevant due to this being internal to the library.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;It is moderately easy to set up. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The most basic usage involves simply wrapping the necessary constructs around the stack you wish to deploy. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;It is native to AWS. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the end, it deploys CodeSuite services to perform the process.&lt;/li&gt;
&lt;li&gt;There is no need to cross lines between companies like you might with Github, CirceCI, or other CI/CD platforms.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;It’s slow to run.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compared to other processes, the time it takes for a commit to happen, the process to run, and the changes to get propagated is long.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;The Self Mutate step is a lynchpin and a black box.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is very frustrating to debug if something does go wrong on this step. There are common reasons that can be found via traditional things like “googling”. But when this step breaks, it’s usually not pleasant.&lt;/li&gt;
&lt;li&gt;Redeeming quality, you can disable it. I have not attempted a setup with it disabled. As 99.999% of the time, the step works no problem. But oh boy, that .001% of the time can be a doozy.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;It can be overkill for some uses.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you’re deploying a lambda or two, the setup for the Pipelines construct is small. But its output is significant by comparison.&lt;/li&gt;
&lt;li&gt;As I mentioned at the start, this is a tradeoff. If the project is destined to be much more than a lambda or two, this might only matter temporarily. But if the purpose is small, you may want to try an alternative process.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2u4fm50gmgj2ylqq1g7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff2u4fm50gmgj2ylqq1g7.png" alt="Example of a Pipeline implementation taken from the documentation." width="800" height="965"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Github Actions
&lt;/h2&gt;

&lt;p&gt;Going down this route can be an easy next step after outgrowing manual deployments. You can take whatever you were already doing, stick it in a YAML file, and call it a day.  But you’re essentially stepping back into older forms of IaC. If you’re versed in those tradeoffs, you’ll probably manage fine. If not, this might not be the route for your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Easy-as-pie setup&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Getting GitHub Actions running is as simple as adding a YAML file to your repo. In development, it’s hard to get much simpler than that.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Coexists with your code in Github&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An underrated point. Dramatically simplifies the reasoning process through what’s happening, when you can see the changes directly next to what’s happening.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Template files&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For most use cases, these are simpler to reason through than a coding language. And nowadays, they have quite a bit of extensibility, meaning they can grow as the project grows.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Template files&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;But not nearly as much as a coding language. Supporting the process with an interpreter or compiler vastly outperforms template files in terms of extensibility.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;External System&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It’s more challenging to integrate with other AWS services.&lt;/li&gt;
&lt;li&gt;Incur networking charges for moving information in and out of the AWS cloud. Along with other networking challenges you may face when dealing with VPCs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Security and Compliance are made more difficult.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Credentials to be managed&lt;/li&gt;
&lt;li&gt;External attack surface&lt;/li&gt;
&lt;li&gt;Less control over the build environment&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F099iqsrayicq3ix3ksk0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F099iqsrayicq3ix3ksk0.png" alt="Github actions example. Pulls source code in and runs cdk deploy." width="800" height="1037"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Roll your own CodePipeline
&lt;/h2&gt;

&lt;p&gt;For a smooth, refreshing blend of the previous two approaches. You can develop an in-house pipeline using the CodeSuite L3 constructs directly. This approach allows you to maintain everything in your AWS accounts while providing a smooth transition. The caveat with this one is, “With great power comes great responsibility”. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Contained within AWS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Allows you to use template files if you’d like. But does not require them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As you can see in the example below, you can build the buildspec in your language of choice. Or you can use the fromAsset or fromSourceFile APIs to pull a templated Buildspec from within the repo. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Can produce simple setups that run quickly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The keyword here is &lt;em&gt;can&lt;/em&gt;. Akin to Github Actions, you can start out by wrapping your manual process with a bash script and having CodeBuild run that. But whether or not it stays simple and fast is up to you.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Can handle performing tasks that the Pipeline constructs cannot&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;… very specifically it is not built to use CodeDeploy to deploy applications to instances, or deploy your custom-built ECR images to an ECS cluster directly&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You are responsible for a large amount of the process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS provides quite a few things, like build images, visualizations, and such. But most of the “important” details you will have to sort yourself. If you have strict compliance or regulations you have to adhere to, this might be a boon. If you don’t, this might be a burden.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Can hide complexity&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;It is possible to have a Source and a Build step and just stick everything in a bash file that the build step runs. Essentially allowing you to tuck away the meat of what’s going on.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktfxvd806gih6mhtpqjh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktfxvd806gih6mhtpqjh.png" alt="Code pipeline example." width="800" height="1558"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;One of the best reasons for going with CDK is its open-endedness and that doesn’t stop once you deploy. You can take your CDK code and deploy it where you like and how you like it. Adapting it to fit your needs.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cicd</category>
      <category>cdk</category>
    </item>
    <item>
      <title>Managing My AWS Certified Status</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Wed, 26 Feb 2025 17:00:00 +0000</pubDate>
      <link>https://dev.to/aws-builders/managing-my-aws-certified-status-463f</link>
      <guid>https://dev.to/aws-builders/managing-my-aws-certified-status-463f</guid>
      <description>&lt;h2&gt;
  
  
  Assessing where I stand
&lt;/h2&gt;

&lt;p&gt;As of writing this, I’ve managed to obtain the Cloud Practitioner and Certified Developer - Associate. Unfortunately, the last time I sat an exam was in November of 2022. Meaning if I would like to maintain my certified status, I’ll need to sit at least one exam before November of this year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why stay certified in the first place?
&lt;/h2&gt;

&lt;p&gt;There are simple things like the shiny badge, certified swag, and the certified lounge at Re:Invent. But personally I believe going through the process leads me to creating better solutions for my users. Getting certified through AWS goes beyond memorizing pricing models and feature lists. To score well on the exams, you have to spend time getting to know the services to their core. Understanding what they seek to accomplish for you and your users. Having this knowledge while developing solutions for people can be a massive difference maker.&lt;/p&gt;

&lt;h2&gt;
  
  
  What certs do I want/need to get?
&lt;/h2&gt;

&lt;p&gt;AWS maintains this very helpful page that lists what you would need to accomplish in order to maintain a given certification. While it looks very nice, I’ll save you the click and put the information relevant to my situation below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qyy7bk25fgckui6chyy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4qyy7bk25fgckui6chyy.png" alt="Table showing what I need to recertify. For the CCP, any exam will do. For the Dev Assoc. I'll need to retake it or a in-line harder exam." width="800" height="201"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on this, at a minimum, I would need to sit the Developer Associate exam again in order to maintain my two current certifications going into the future. &lt;/p&gt;

&lt;p&gt;But I’m not here to do the minimum. &lt;/p&gt;

&lt;p&gt;Therefore, my only option is to sit the DevOps - Professional exam 😁.&lt;/p&gt;

&lt;h2&gt;
  
  
  “But what about Gen AI” - you (probably)
&lt;/h2&gt;

&lt;p&gt;So if you haven’t been living under a rock, you’ve probably heard about Gen AI and tools like ChatGPT. Recently, AWS launched a foundational-level certification aptly named “AWS Certified AI Practitioner”. As someone who would like to consider themselves a “Full-Stack” developer. I imagine Gen AI will soon become a regular member of said stack. While I did get a crash course in the fundamentals this year while attending Re:Invent, I still lack the knowledge to honestly say, “I could build an app or feature from front to back that centers around Gen AI”.&lt;/p&gt;

&lt;p&gt;So, even before sitting the DevOps - Pro exam this year, I will obtain the AI Practitioner certification.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s a good goal, without a stretch goal?
&lt;/h2&gt;

&lt;p&gt;Who says the sky’s the limit? Not me! Because I’m also going to set a stretch goal of obtaining a third certification in 2025. The “AWS Certified Solutions Architect - Associate”. For some (looking at you golden jackets 😅) three certifications in a year might not be a stretch. But for me, it will be!&lt;/p&gt;

&lt;p&gt;Even beyond trying to set lofty goals, I do believe having a certification more focused on higher-level concepts of using AWS services would be beneficial, especially given that I’m already branching out with the AI practitioner certification. So, regardless of whether I can make it happen within the 2025 calendar year, I will be trying to sit this exam—just not before the other two.&lt;/p&gt;

&lt;h2&gt;
  
  
  So we’ve got goals. What’s the plan?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Study&lt;/li&gt;
&lt;li&gt;Practice&lt;/li&gt;
&lt;li&gt;Build&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For all three of these certifications, there’s a whole lot of information that is currently not in my head and will need to be there before I sit the exams. The solution for that is going through a series of courses made by a fellow member of the AWS community, Stephane Maarek. I’ve taken his courses for both of my existing certifications, so I trust his courses for these certifications will hold true. &lt;/p&gt;

&lt;p&gt;Additionally, I’ll be taking Jon Bonso's practice exams. Don’t get me wrong; you could likely pass the exam solely by taking a prep course. But the best way I’ve found to have the confidence to do something is by having already done it. So, pairing a course with taking a few well-made mock exams is how I’ve prepared in the past. If it’s not broke, don’t fix it.&lt;/p&gt;

&lt;p&gt;One final preparation step I’m taking is to build a ChatGPT-like product over the top of Bedrock, Amazon’s Gen AI wrapper service. This is an OSS project titled “My-SDC” (My Self Deployed Chat). The aim is to deliver the best of both worlds. Having the conversational interface of ChatGPT but adding enhanced capabilities that Bedrock provides, like the flexibility of model-switching.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is where we depart. For now.
&lt;/h2&gt;

&lt;p&gt;It is the beginning of a new year, and these are some lofty aspirations. I’ve put pen to paper and set a course forward. Check back here as the year goes on, and hopefully, come January of 2026, my chart will look a bit more like this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuim50vhkw29f8tp2b3y6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuim50vhkw29f8tp2b3y6.png" alt="Table showing five certifications. Cloud practitioner, Solutions Arch Associate, Dev Associate, DevOps Pro, and AI Practitioner" width="800" height="638"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscommunity</category>
      <category>certification</category>
      <category>career</category>
    </item>
    <item>
      <title>Save Time and Money by Shifting HIPAA Compliance Checks Left with CDK-Nag</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Sat, 15 Feb 2025 14:07:19 +0000</pubDate>
      <link>https://dev.to/aws-builders/save-time-and-money-by-shifting-hipaa-compliance-checks-left-with-cdk-nag-4ipf</link>
      <guid>https://dev.to/aws-builders/save-time-and-money-by-shifting-hipaa-compliance-checks-left-with-cdk-nag-4ipf</guid>
      <description>&lt;p&gt;&lt;a href="https://makingituptech.substack.com/p/using-cdk-nag-to-check-hipaa-compliance" rel="noopener noreferrer"&gt;&lt;em&gt;Originally published to: makingitup.substack.com&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With cdk-nag you can check your infrastructure before it’s deployed. Potentially preventing issues before they happen. Saving you time and money.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68q6pje8i2u72n38ma4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F68q6pje8i2u72n38ma4r.png" alt="Gif demonstrating how to add a rule check to your CDK application." width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://raw.githubusercontent.com/cdklabs/cdk-nag/HEAD/cdk_nag.gif" rel="noopener noreferrer"&gt;Credit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TL;DR: &lt;a href="https://github.com/IamFlowZ/shift-hipaa-left" rel="noopener noreferrer"&gt;Here’s a working repo with a sample configuration.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;The steps in this tutorial will assume you already have a CDK project made. If you don’t you can follow this guide from the docs or clone the sample repo from above.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Install cdk-nag
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;npm i cdk-nag&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Simple as.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Import and setup Rules and Packs
&lt;/h3&gt;

&lt;p&gt;In your root application file, you’ll need to import the packs and rules you’d like to have applied to your infrastructure. Once available, you hook the rules into your application by adding stack aspects.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Output issues in flatfile formats (Optional)
&lt;/h3&gt;

&lt;p&gt;It’s great that you can now check for issues. But unless you take the time to develop a system to bring these issues up and out, they will likely just be disregarded.&lt;/p&gt;

&lt;p&gt;To remedy this, you should either import the NagReportLogger provided as part of the cdk-nag project or develop your own. The logger they supply can output JSON or CSV, making it ideal for integrating with existing CI/CD systems. If this isn’t enough, they have a great guide on how to implement your own custom logger.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recap
&lt;/h2&gt;

&lt;p&gt;Fancy buzzwords aside. By including cdk-nag as part of your application, you can check for potential HIPAA violations as early as the code is written. Preventing the lengthy debug cycle of &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Write&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploy&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validate&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And reducing it to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Write&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The savings only begin there. Out of the box cdk-nag supplies rule packs for&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;NIST 800-53 rev 4&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NIST 800-53 rev 5 &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PCI DSS 3.2.1&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As well as the ability to build your own. &lt;/p&gt;

&lt;p&gt;Don’t want developers deploying g6e.24xlarge instances to run the latest LLM? You can write a rule for that. The abilities provided can have tremendous ROI with very little upfront investment. However, the ROI you could see by investing in engineering power to shape what your cloud can and cannot look like is vast.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>hipaa</category>
    </item>
    <item>
      <title>Re:Invent Reflections</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Fri, 13 Dec 2024 19:13:13 +0000</pubDate>
      <link>https://dev.to/aws-builders/reinvent-reflections-1mj8</link>
      <guid>https://dev.to/aws-builders/reinvent-reflections-1mj8</guid>
      <description>&lt;p&gt;Last year, I wrote &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Up until last week (as of 12/3/23) I would say I’ve been something of an AI pessimist. However, after getting hands-on with services like SageMaker, and Q, and seeing how products are starting to leverage it as part of their solutions, I’m starting to see where it could come into play.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Twelve months (and another Re:Invent) later, it's pretty easy to say Gen AI is at the forefront of software. I believe we were entering the frontier last year, and now we're beginning to see the first semblances of towns start to set up shop. The trailblazers are now beginning to bring products to the market that greatly simplify the deployment process of Gen AI applications. I expect this coming year to bring an onslaught of Gen AI products into the B2B and B2C spaces.&lt;/p&gt;




&lt;p&gt;Traditionally speaking, software systems are (for the most part) deterministic. You build a product that houses tools containing predefined, deterministic outcomes. Take reporting, for example. You probably collected data from sources on your customer's behalf, housed it in some persistence layer, and served tools to chop and slice the data in various manners back to them. Someone with that express purpose in mind is building all of that. Additionally, the user has to understand both the system you provide and the underlying concepts to truly be able to leverage it to its fullest extent.&lt;/p&gt;




&lt;p&gt;With Gen AI in the equation, we can now build systems that can take in the nearly infinite set of natural language communication possibilities and (hopefully) deliver the same breadth back to them. This removes the current bottleneck, which is the very narrow predetermined confines of the applications that we build today. I predict that in the wave of Gen AI products to come, the ones that carry this as a core tenant will be here for the long haul.&lt;/p&gt;

&lt;p&gt;The example of this I routinely saw given was&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you ask an LLM, “What is 1+1?” you might get five back. But ask it to help you plan your week in Cabo, and you’ll be amazed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;“1+1” has a very narrow predeterminable solution. Your week in Cabo does not.&lt;/p&gt;




&lt;p&gt;Continuing the line of thought from last year, you need to build your systems so they can fail gracefully. You have the pieces available; you just need to wire them together. As part of building an evolutionary product, you need to trust that you can step backward if you make a misstep. Doing so makes taking a misstep much less punishing and widens the range of possibilities you can explore.&lt;/p&gt;




&lt;p&gt;Gunnar Grosch shared a concept during his wonderful presentation: continuous configuration. My understanding is that within your application, you should have it routinely polling for configuration values and adapting to them as time goes on rather than the standard practice of redeploying. All this is made possible by managing your application, infrastructure, and configuration through CDK.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;If I had to draw a through line for all these ideas, Gen AI is broadening the possibilities regarding what software can deliver. “What points on the horizon are worth going to?” remains a question to be answered. However, the solutions that believe “Everything fails all the time” will most likely have the depth necessary to make it to the horizon.&lt;/p&gt;

&lt;p&gt;Looking forward to meeting you all out on the horizon.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>reflection</category>
      <category>reinvent</category>
    </item>
    <item>
      <title>How to Migrate From CodeCommit</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Fri, 09 Aug 2024 00:37:11 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-migrate-from-codecommit-3em1</link>
      <guid>https://dev.to/aws-builders/how-to-migrate-from-codecommit-3em1</guid>
      <description>&lt;h2&gt;
  
  
  ICYMI
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://x.com/jeffbarr/status/1818461689920344321" rel="noopener noreferrer"&gt;AWS recently announced&lt;/a&gt; that they will no longer be onboarding new customers for a number of services. Potentially one of the most painful being CodeCommit. While shuttering projects that aren't up to snuff isn't out of the ordinary, the suddenness with which they delivered this might be.&lt;/p&gt;

&lt;p&gt;Luckily for you, you found this article. Where I'm going to show you how to quickly and easily migrate your code away from CodeCommit and to another source control service provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Ensure you're setup with a source control provider. The most common choices on the market are &lt;a href="//github.com"&gt;Github&lt;/a&gt;, &lt;a href="//gitlab.com"&gt;GitLab&lt;/a&gt;, and &lt;a href="//bitbucket.com"&gt;BitBucket&lt;/a&gt;. At minimum you'll need to make an account with the provider of you're choice.&lt;/p&gt;

&lt;p&gt;Once you've completed that you'll need to make a repository with your new provider to house your code. Whichever provider you've chosen will have guides made that you can follow for this step. If you had any special repository configuration (e.g. branch protections) you may want to consider setting them up now.&lt;/p&gt;

&lt;p&gt;The only caveat I have to add here is to ensure you don't commit to the new repo. We will be migrating our branches and their history to the new provider. Committing to your new provider before migrating will almost certainly cause conflicts (particularly to your main/master branch).&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Before we get into the meat and potatoes, I want to outline our problems.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Moving all the contents of our repository from one remote repository to another&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;"moving house".&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Updating all local repositories to use the new remote&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Make sure all our friends know we've moved.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Updating automated systems to use the new remote&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Make sure the government knows we've moved.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As promised, &lt;a href="https://github.com/IamFlowZ/migrate-from-code-commit" rel="noopener noreferrer"&gt;I've made a repo with some shell scripts to help make this easier.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Moving House
&lt;/h3&gt;

&lt;p&gt;Now let's get down to business.&lt;/p&gt;

&lt;p&gt;To start ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;your CLI is in the cloned helper repo&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;you have the absolute path(s) of the repo(s) being moved&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;you have the url(s) of the new remote repo(s)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From there you can plug all the above into either&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nv"&gt;$:&lt;/span&gt; bash main.sh /full/path/to/repo &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newRemoteUrl&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newRemoteName&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if you have many repositories that need moved:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nv"&gt;$:&lt;/span&gt; bash many.sh &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newRemoteUrl&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newRemoteName&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure you answer &lt;code&gt;yes&lt;/code&gt; to both of the questions (pushing to the new remote and replacing &lt;code&gt;origin&lt;/code&gt; in your local repository.)&lt;/p&gt;

&lt;p&gt;This initial run of the scripts will add the new remote to your local repository and push your version of the history. It runs a &lt;code&gt;git fetch&lt;/code&gt; so it should be up-to-date as long as you have an active internet connection. You then will have the option to update your local repository's &lt;code&gt;origin&lt;/code&gt; remote to the new remote.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating Your Friends
&lt;/h3&gt;

&lt;p&gt;Now ensure everyone working on the repo(s) also updates their local. Make sure everyone pushes any branches that they may have worked stored on locally. Then have them copy the previous step with one change.&lt;/p&gt;

&lt;p&gt;Answering &lt;code&gt;no&lt;/code&gt; to the push question&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nv"&gt;$:&lt;/span&gt; bash main.sh /full/path/to/repo &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newRemoteUrl&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newRemoteName&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nv"&gt;$:&lt;/span&gt; bash many.sh &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newRemoteUrl&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;newRemoteName&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now on these later runs the script will add the new remote, but will not push to the new remote. Again as part of the script they can follow precedent and decide if they want the new remote to replace CodeCommit as &lt;code&gt;origin&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Updating the Authorities
&lt;/h3&gt;

&lt;p&gt;For this last step, you may be able to use the scripts I've provided, depending on your CI/CD architecture. But this bit likely will be out of scope and up to you to make the changes. If you run into issues, there are tons of amazing people who would love to help on&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="//repost.aws"&gt;re:Post&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://stackoverflow.com/collectives/aws" rel="noopener noreferrer"&gt;AWS StackOverflow Collective&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;code&gt;Support Center&lt;/code&gt; within your AWS account&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many other platform and tool specific forums&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Having to migrate Git providers can be an absolute nightmare with long tail consequences. Hopefully, with these scripts and the framework I've outlined you can make short work of what can be a daunting task.&lt;/p&gt;




&lt;p&gt;Best of luck and hope this helps!&lt;/p&gt;

&lt;p&gt;Find me on &lt;a href="https://hachyderm.io/@therealdakotal" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt; | &lt;a href="https://www.linkedin.com/in/dakota-lewallen/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/IamFlowZ" rel="noopener noreferrer"&gt;Github&lt;/a&gt; | &lt;a href="https://makingituptech.substack.com" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cicd</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>To Build or to Reuse? A CDK Question</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Thu, 11 Apr 2024 11:04:10 +0000</pubDate>
      <link>https://dev.to/aws-builders/to-build-or-to-reuse-a-cdk-question-3obl</link>
      <guid>https://dev.to/aws-builders/to-build-or-to-reuse-a-cdk-question-3obl</guid>
      <description>&lt;p&gt;Unless you are starting on a fresh application, the project you are working on will likely have resources already in use. One of the benefits of using CDK over other Infrastructure-as-Code tools is conditionals! Along with the ability to import resources via their ARN, we can create solutions that can use existing resources, or create new ones. This means we can deploy into both fresh and existing environments from the same codebase!&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;Let’s assume you have a CDK application made and have bootstrapped the target Region &amp;amp; Account. Starting with a new stack, we can begin to scaffold what we’ll need.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;constructs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Working backward, we’ll say our example use case is to add a new lambda that processes data once it’s dropped in a bucket. For deploying into production, the bucket is already in use and managed by another project. But for the testing environment, there is no bucket. So we will need to make one.&lt;/p&gt;

&lt;p&gt;To begin let’s add the lambda, as it’s a constant regardless of where it’s deployed. So the implementation is simple.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/aws-lambda-nodejs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;constructs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;bucketProcessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NodeJsFunction&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucketProcessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NodeJsFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy enough!&lt;/p&gt;

&lt;p&gt;Now onto the juicy stuff. We’ll add a property to the NewStackProps interface to have the bucket ARN supplied externally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/aws-lambda-nodejs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;constructs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Mark the property as optional, this way we can _optionall_ build the bucket if it's not supplied&lt;/span&gt;
  &lt;span class="nl"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;bucketProcessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NodeJsFunction&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// pull the arn out into a construct-scoped variable for later use.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bucketArn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Tip: For ultra clean code, you would want to add validation against this `bucketArn` string to confirm it is in fact an ARN. &lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucketProcessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NodeJsFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now armed with the knowledge of “Do we have an existing bucket”, we can either make a new one or reuse the old one&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/aws-lambda-nodejs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/aws-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;constructs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Mark the property as optional, this way we can _optionall_ build the bucket if it's not supplied&lt;/span&gt;
  &lt;span class="nl"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;bucketProcessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NodeJsFunction&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bucketArn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucketProcessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NodeJsFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromBucketArn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;importedBucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;createdBucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To wrap up, we’ll add a property to the stack so that the bucket can be referenced elsewhere in the CDK application and hook the lambda up to the bucket so it can process events.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/aws-lambda-nodejs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/aws-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;s3n&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib/aws-s3-notifications&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;constructs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Mark the property as optional, this way we can _optionall_ build the bucket if it's not supplied&lt;/span&gt;
  &lt;span class="nl"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;bucketProcessor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NodeJsFunction&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IBucket&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cm"&gt;/**
Use of the interface here is important. The `fromBucketArn` method returns an instance of the interface. But the new Bucket returns `s3.Bucket` which _implements_ the `IBucket` interface. So specificying the property as `IBucket` ensures that we can house _either_ the imported or created bucket. The tradeoff is that we lose access to some of the created buckets "fancier" features.
**/&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NewStackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bucketArn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucketProcessor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NodeJsFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromBucketArn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;importedBucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bucketArn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;createdBucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;EventType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OBJECT_CREATED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;s3n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LambdaDestination&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucketProcessor&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some/object/prefix/*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With CDK, it’s possible now more than ever to reuse infrastructure patterns across environments. No matter the state the target environment is in. I would even consider this the tip of the iceberg! To go even further, you could make a custom L3 construct containing the reuse-or-build logic to simplify the process further! The possibilities are endless!&lt;/p&gt;




&lt;p&gt;Find me on &lt;a href="https://linkedin.com/in/dakota-lewallen" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/iamflowz" rel="noopener noreferrer"&gt;Github&lt;/a&gt; | &lt;a href="https://hachyderm.io/@therealdakotal" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Multi-region Deployments with CDK</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Thu, 28 Mar 2024 11:32:51 +0000</pubDate>
      <link>https://dev.to/aws-builders/multi-region-deployments-with-cdk-4kfk</link>
      <guid>https://dev.to/aws-builders/multi-region-deployments-with-cdk-4kfk</guid>
      <description>&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/IamFlowZ" rel="noopener noreferrer"&gt;
        IamFlowZ
      &lt;/a&gt; / &lt;a href="https://github.com/IamFlowZ/multi-region-cdk-example" rel="noopener noreferrer"&gt;
        multi-region-cdk-example
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Companion repository for the Multi Region Deployments blog post
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Multi Region Stack Example&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This is an example of one way to deploy multiple Cloudformation stacks to different regions, without having forks within the code.&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/IamFlowZ/multi-region-cdk-exampledocs/Arch.drawio.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2FIamFlowZ%2Fmulti-region-cdk-exampledocs%2FArch.drawio.svg" alt="Example multi-region architecture"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After deployment has completed, you should find function urls listed in your CLI corresponding to the regions you deployed to. Opening them should respond with &lt;code&gt;Hello from ${region}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;cdk.json&lt;/code&gt; file tells the CDK Toolkit how to execute your app.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Credentials&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;By default this assumes you have an AWS profile configured, and will use the default account and region associated with it. The default is the account the credentials belong to and (typically) us-east-1.&lt;/p&gt;
&lt;p&gt;If you would like to target a specific account and environment, you can modify &lt;code&gt;bin/multi-region-example.ts&lt;/code&gt; to use either of the commented &lt;code&gt;env&lt;/code&gt; lines. One is for hard coding the other is for environment variables. You can &lt;a href="https://docs.aws.amazon.com/cdk/latest/guide/environments.html" rel="nofollow noopener noreferrer"&gt;learn more about CDK environments here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Useful commands&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;npm run build&lt;/code&gt;          compile typescript to…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/IamFlowZ/multi-region-cdk-example" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;From the second you deploy your resources into the AWS Cloud, you have access to a global computing network. Something unimaginable in the past and grossly underutilized even by today’s standards. In this article, I’ll show you two simple ways you can begin leveraging the power of global deployments with CDK.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;If you plan on following along, make sure you have completed these tasks.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installed the &lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Installed the &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/cli.html" rel="noopener noreferrer"&gt;CDK CLI&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Configured IAM credentials&lt;/li&gt;
&lt;li&gt;Bootstrapped at least two regions in an AWS account using the &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html" rel="noopener noreferrer"&gt;cdk bootstrap command&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Root Stack with Substacks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49nswh5k9wligjhzm268.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F49nswh5k9wligjhzm268.jpg" alt="Example architecture" width="681" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This design implements a “Root” stack that then deploys the subsequent region-specific stacks. The root stack will be deployed into the default region associated with the profile (us-east-1 unless specified). There are several things achieved with this.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We develop a clear hierarchy

&lt;ul&gt;
&lt;li&gt;The main benefit of this is dependency management since we create a clear route by which we can pass information both up and back down the tree&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We create a point of centralization that we can use to build dependencies that are used by many dependents

&lt;ul&gt;
&lt;li&gt;For example, if we have an SQS queue that is used globally within the application, we can build it in the root stack and pass it through to the props of the application stacks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;We have a “non-regional” stack to house global resources

&lt;ul&gt;
&lt;li&gt;Building on the last point, we have a stack that handles deploying for things that aren’t regional in AWS (IAM, S3, etc.). &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The stack itself is tied to a region, but there’s no reason that the resources the stack deploys also have to be tied to that region.&lt;/p&gt;

&lt;p&gt;Here is an example of the root stack taken from &lt;a href="https://github.com/IamFlowZ/multi-region-cdk-example/blob/main/lib/multi-region-example-stack.ts" rel="noopener noreferrer"&gt;here in the repository&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;constructs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app-stack/app-stack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MultiRegionExampleStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;us-east-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;eu-west-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="c1"&gt;// store the regional stacks in an object for debugging&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regionalStacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;regions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;accu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regionalStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AppStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;accu&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;regionalStack&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some caveats:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you’re familiar with &lt;a href="https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.NestedStack.html" rel="noopener noreferrer"&gt;the NestedStack construct&lt;/a&gt;, you are probably thinking “What a perfect use case!”. Sadly at the time of writing this, it seems that NestedStacks have to be deployed in the same region that the source stack is deployed in. I don’t believe this is a CDK limitation, but instead a CloudFormation one. &lt;a href="https://github.com/aws/aws-cdk/issues/26814" rel="noopener noreferrer"&gt;There is an open issue&lt;/a&gt; with some discussion around implementing this in CDK, however it does seem to be rather complicated. But hey if this is a blocker for you, get active and let them know!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another Cloudformation feature that is commonly used to solve this problem is &lt;a href="https://aws.amazon.com/about-aws/whats-new/2021/04/deploy-cloudformation-stacks-concurrently-across-multiple-aws-regions-using-aws-cloudformation-stacksets/" rel="noopener noreferrer"&gt;Stack Sets&lt;/a&gt;. At the time of writing this, there is no support out of the box in CDK. But there is a &lt;a href="https://github.com/cdklabs/cdk-stacksets" rel="noopener noreferrer"&gt;CDK Labs construct&lt;/a&gt; in the experimental phase you can try out. But per their readme, I would avoid getting overly tied to its implementation until it is generally released.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In theory, you shouldn’t need to reference values from an application stack deployed in Region A in an application stack deployed in Region B. As they are siblings, so dependencies should be managed via prop drilling. However reality is often finicky, so if you do end up in this situation, I would recommend storing the dependency value in ParameterStore and dynamically referencing it in the dependent stack. If you’d like to learn more, [I wrote a deep-dive here] that you may find useful.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Deploy the Stacks Directly
&lt;/h2&gt;

&lt;p&gt;For a more traditional IaC experience, we can remove the root stack. Opting to instead deploy the stacks directly. We do lose some of the “superpowers” the first option provides, with the benefit of having something simpler to reason about.&lt;/p&gt;

&lt;p&gt;There are two main options I’ve observed&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Instantiate your region-specific stack however many times you need in the /bin/app.ts file. You can find a full example &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/stack_how_to_create_multiple_stacks.html" rel="noopener noreferrer"&gt;here in the CDK docs&lt;/a&gt;. As well as &lt;a href="https://github.com/IamFlowZ/multi-region-cdk-example/tree/no-root-stack" rel="noopener noreferrer"&gt;this branch&lt;/a&gt; in the repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Instantiate your region-specific stack once in the /bin/app.ts file, and use the &lt;a href="https://github.com/IamFlowZ/multi-region-cdk-example/tree/no-root-stack" rel="noopener noreferrer"&gt;cdk deploy&lt;/a&gt; command to deploy it to the regions you desire. &lt;a href="https://github.com/IamFlowZ/multi-region-cdk-example/tree/no-root-stack-env-var" rel="noopener noreferrer"&gt;This branch&lt;/a&gt; has one approach you might take.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While this does supply you with a more traditional experience there are still benefits to using CDK, that you wouldn’t have access to otherwise.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Higher-level constructs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If like many others you are on a Serverless journey, you may be looking to migrate to Fargate. One of my personal favorites in the CDK library is the ApplicationLoadBalancedFargateService. It’s a mouthful because it does a lot for very little. In ~30 lines (or less) of code, it will deploy an ECS cluster, service, and task definition. As well as provide one-line APIs for wiring in the cluster, load balancer, and any VPC configuration you may need to do. All of this would be hundreds of lines of Cloudformation templating. &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Component libraries&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the standard library can’t meet your needs, &lt;a href="https://constructs.dev" rel="noopener noreferrer"&gt;constructs.dev&lt;/a&gt; is an open-source marketplace that houses thousands of constructs. Ranging from monitoring tools, linters, and everything else you can imagine codifying in the cloud.&lt;/li&gt;
&lt;li&gt;Not only are there public libraries, but you can also create centralization within your organization through private ones. Making it possible to standardize higher-level patterns in the cloud.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With CDK, it’s never been easier to duplicate resources into multiple AWS regions. You can bring your code closer to your customers and increase your fault tolerance with just a few clicks.&lt;/p&gt;

&lt;p&gt;Find me on &lt;a href="https://linkedin.com/in/dakota-lewallen" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/iamflowz" rel="noopener noreferrer"&gt;Github&lt;/a&gt; | &lt;a href="https://hachyderm.io/@therealdakotal" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>Three Tips for Writing CDK Tests</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Mon, 18 Mar 2024 12:25:22 +0000</pubDate>
      <link>https://dev.to/aws-builders/three-tips-for-writing-cdk-tests-53fk</link>
      <guid>https://dev.to/aws-builders/three-tips-for-writing-cdk-tests-53fk</guid>
      <description>&lt;h2&gt;
  
  
  1. Use the assertions module
&lt;/h2&gt;

&lt;p&gt;Something of a no-brainer, but use the tools you’re given! One of the best parts of the CDK library is the assertions module. It contains two sections. One for “fine-grained” assertions, like what you would write during unit testing. The other is for performing “snapshot” tests, in which you compare the new template against one that is already deployed. It’s a section of the library that can be easily missed but provides so much value when used correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Make any Nested Stacks easily accessible
&lt;/h2&gt;

&lt;p&gt;One of the benefits of using CDK is the ability to create declarative dependency trees. But, testing the implemented Nested Stacks can be tricky. One of the best ways I’ve found to simplify this is to add Nested Stacks as properties of the Stack class that handles deploying them. For example…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SubStack&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;substack-stack.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TopStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;     
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SubStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;substack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is pretty standard. While it is possible to test this, you can simplify the process by “stashing” a reference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SubStack&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;substack-stack.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TopStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   
  &lt;span class="nl"&gt;subStack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SubStack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;     
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SubStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;substack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now accessing this for fine-grained assertions can look like…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Capture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Match&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib/assertions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aws-cdk-lib&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TopStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;top-stack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;TopStack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;   
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;has the substack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;     
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;cdk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;      
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;topStack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TopStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;topStack&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;     
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;subStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;topStack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// we pull the substack through the property      &lt;/span&gt;

    &lt;span class="c1"&gt;// Pass the subStack to template.     &lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;subStack&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3.  Write your template to a file (sometimes)
&lt;/h2&gt;

&lt;p&gt;While writing assertions, you can find situations where the tests are failing for reasons that may not make sense. When this happens, one of the first things I will do is write the CloudFormation template out into a file. This way you can get a cold hard copy of what it is you are building in your hand. Rather than trying to parse through complex logs or mysterious error messages. Not a guarantee but often getting to see the complete output can solve many common testing pitfalls.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Testing is great! Testing your infrastructure… Even better! If you’re just getting started with CDK or if you’ve been around since the early days, I hope these tips can help you along your journey! If you have any tips you'd like to add, share them in the comments. Always looking to learn more!&lt;/p&gt;




&lt;p&gt;Find me on &lt;a href="https://www.linkedin.com/in/dakota-lewallen/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/IamFlowZ" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>testing</category>
      <category>learning</category>
    </item>
    <item>
      <title>Organize Your CDK lib Folder by Function Not Service</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Fri, 08 Mar 2024 14:40:53 +0000</pubDate>
      <link>https://dev.to/aws-builders/organize-your-cdk-lib-folder-by-function-not-service-28np</link>
      <guid>https://dev.to/aws-builders/organize-your-cdk-lib-folder-by-function-not-service-28np</guid>
      <description>&lt;h1&gt;
  
  
  Don’t: Organize Your CDK lib Folder by Service
&lt;/h1&gt;

&lt;p&gt;When working with IaC tools, it's standard to organize your work based on the service. You specify a service and then describe how you would like it configured. Carrying that pattern into CDK might look something like so.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2t75azmhuihvd2iht79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg2t75azmhuihvd2iht79.png" alt="An example of organizing the lib folder by service (lambda, sqs, s3, etc)" width="355" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first, this will feel great! Things are going great until you start to work on functionality across many services. At this point, changes will span many directories resulting in many CloudFormation stacks needing to be deployed.&lt;/p&gt;

&lt;h1&gt;
  
  
  Do: Organize Your CDK lib Folder by Function
&lt;/h1&gt;

&lt;p&gt;If we follow the principle of working backward, we’ll end up with a structure that more aligns with how we’re going to work in the future.&lt;/p&gt;

&lt;p&gt;Starting with our business use case. Let’s say you are going to receive flat files through an SFTP server from clients. You will need to perform some basic ETL processes to house it within your system. Instead of having a lambda folder, a step function folder, and an event bridge folder, you build a single &lt;code&gt;FlatFileHandler&lt;/code&gt; folder. With a single stack, that deploys the resources necessary to perform this function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjz5lpjce7umboo8oh2u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjz5lpjce7umboo8oh2u.png" alt="An example of organizing by function. Creating only a stack for this end goal and not per service." width="355" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now whenever work is needed on the flat file handling system, you can find everything you need in a singular place. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;One of the greatest strengths of CDK, is the ability to perform more complex organizational patterns for your resources. This is one example of a pattern that can be useful. Like anything that's in code, you're now free to organize as you see fit! If you find a more useful pattern, let the world know (me in particular 😉)!&lt;/p&gt;




&lt;p&gt;Find me on &lt;a href="https://linkedin.com/in/dakota-lewallen" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/iamflowz" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>devops</category>
    </item>
    <item>
      <title>CDK Dependency Strategies</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Tue, 12 Dec 2023 14:53:29 +0000</pubDate>
      <link>https://dev.to/therealdakotal/cdk-dependency-strategies-4e7g</link>
      <guid>https://dev.to/therealdakotal/cdk-dependency-strategies-4e7g</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally posted to &lt;a href="https://dakotalewallen.substack.com/p/cdk-dependency-strategies" rel="noopener noreferrer"&gt;dakotalewallen.substack.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This topic has been in my backlog to write about for a long time. I’ve had to sit with it for so long since I was “missing a piece of the puzzle.” But after attending Re:Invent this year I feel like I’ve got enough to share my thoughts. The topic is also surprisingly nuanced, so I figured laying some groundwork by describing the most common patterns would be a place to start.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Expanding the &lt;code&gt;props&lt;/code&gt; object&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is most commonly used as it’s one of the most natural dependency mechanisms in JavaScript. For a given stack or construct, it declares its need for something external. Then at runtime, you have to satisfy that need during the call to the constructor. You define this dependency by expanding the &lt;code&gt;props&lt;/code&gt; object which inherits from the &lt;code&gt;StackProps&lt;/code&gt; CDK class. There are two variations here.&lt;/p&gt;

&lt;p&gt;The first is simpler declaring a dependency for a specific L2 or L3 construct. This is where most applications start, and if you’re building a construct library as far as you need to go. However in the long run I’ve found this method to be taxing on the synth command, leading to circular dependency issues that can obstruct the project’s ability to build successfully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// myConstruct.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;MyConstructProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;someInstance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyConstruct&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Construct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;MyConstructProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;someInstance&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;securityGroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SecurityGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromSecurityGroupId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; SG&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sg-12345&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{...});&lt;/span&gt;
     &lt;span class="nx"&gt;someInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSecurityGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;securityGroup&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// somewhereElse.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MyConstruct&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./myConstruct&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;someInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;targetInstance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{...});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myConstruct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MyConstruct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mine&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;someInstance&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second variation of this dependency style involves building explicit dependency paths between the stacks that deploy resources. This does remove some of the “generic” functionality, meaning that we can’t receive any old EC2 instance anymore, instead, we have to receive one from somewhere specific within the application. Additionally, this will rely on there being at least one stack that orchestrates between the dependent and provider stacks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// orchestratorStack.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ProviderStack&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./providerStack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;DependentStack&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dependentStack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Orchestrator&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ProviderStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;provider&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dependent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DependentStack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dependent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// This next line is _vitally_ important. As it informs the build system that the provider stack has to be fully built prior to building the dependent. Omitting this line will lead to them being built in parallel which can lead to either circular dependencies or race conditions. Neither of which are fun to deal with.&lt;/span&gt;
    &lt;span class="c1"&gt;// See the docs below for more information (strongly suggest reading at least this section)&lt;/span&gt;
    &lt;span class="c1"&gt;// https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#construct-dependencies&lt;/span&gt;
    &lt;span class="nx"&gt;dependent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addDependency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// providerStack.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProviderStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;someInstance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;someInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Instance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;instance&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{...});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// dependentStack.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DependentStackProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;providerStack&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ProviderStack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DependentStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DependentStackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;providerStack&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;someInstance&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;providerStack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;securityGroup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ec2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SecurityGroup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromSecurityGroupId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;SG&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sg-12345&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{...});&lt;/span&gt;
    &lt;span class="nx"&gt;someInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addSecurityGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;securityGroup&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does have the drawback of not being as reusable. So for libraries, this approach would be a non-starter. However, working within the boundaries of a contained application can save lots of headaches and potentially even some build time.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using dynamic references via SecretsManager and ParamaterStore&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Going further down the rabbit hole, we move away from passing values around in memory during the synth and build steps, instead opting toward external services. Namely, SecretsManager and ParamterStore.&lt;/p&gt;

&lt;p&gt;To remove the need to pass the construct, let’s store the ARN in Parameter Store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// providerStack.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ProviderStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ourQueue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;sqs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;queue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{...});&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ssm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;StringParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;QueueArn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;allowedPattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;The queue ARN&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;parameterName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;QueueArnParameter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;stringValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ourQueue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queueArn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;tier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ssm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ParameterTier&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ADVANCED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now using CloudFormation dynamic references, let’s update the dependent code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// dependentStack.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DependentStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queueArn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CfnDynamicReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;CfnDynamicReferenceService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SSM&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ssm:QueueArnParameter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;targetQueue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sqs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromQueueArn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queueArn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ourRole&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;iam&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Role&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;
    &lt;span class="nx"&gt;targetQueue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grantReadWrite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ourRole&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have successfully decoupled the two resources within the codebase, by abstracting away the connection via ParameterStore and a dynamic reference. This would hopefully allow us to have more freedom to add and remove dependents without having to worry about maintaining a complex dependency tree within our typing system and instead opting to rely on an external system.&lt;/p&gt;

&lt;p&gt;Referencing secrets in Secrets Manager can be done in the same manner as Parameter Store, so rather than rehash that, I’ll leave you with some general advice. You can create your secrets in CDK. But you should never fill your secrets from within your CDK codebase. The docs for the Secret construct mention this outright. So just like with anything else, you should not be checking secret anything into your code base. Ever. Build it however, fill it manually and only load the value when you need it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// dependentStack.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DependentStack&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Stack&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Construct&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StackProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiSecret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CfnDynamicReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;CfnDynamicReferenceService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SECRETS_MANAGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ApiToken:SecretString&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lambda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lambda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NodeJsFuntion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myFunc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;
      &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;API_TOKEN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apiSecret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Likely over the life of your application, you’ll find your needs evolving from using the simpler methods at the beginning to the more complex ones as you progress. I am always an advocate for KISS (keep it stupid simple) for as long as possible. Only introducing complexity once it’s needed. So don’t feel you need to migrate everything as soon as possible. If what you have has been satisfactory up until now, it will likely be just as satisfactory tomorrow. Wait until you start to notice hot spots before starting to move things up in terms of complexity.&lt;/p&gt;




&lt;p&gt;Find me on &lt;a href="https://www.linkedin.com/in/dakota-lewallen/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/IamFlowZ" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>dependencies</category>
    </item>
    <item>
      <title>Split Horizon DNS in AWS Made Easy!</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Mon, 30 Jan 2023 12:13:19 +0000</pubDate>
      <link>https://dev.to/therealdakotal/split-horizon-dns-in-aws-made-easy-d0h</link>
      <guid>https://dev.to/therealdakotal/split-horizon-dns-in-aws-made-easy-d0h</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published to &lt;a href=""&gt;dakotalewallen.substack.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A few months ago, I deployed my first private hosted zone to Route 53. Unbeknownst to me, I had set up a &lt;a href="https://en.wikipedia.org/wiki/Split-horizon_DNS" rel="noopener noreferrer"&gt;split horizon DNS&lt;/a&gt; scenario. My public zone was routing calls to my load balancer correctly. But every time my resources deployed in the VPC called into the same domain, it would result in errors like...&lt;br&gt;
&lt;code&gt;getaddrinfo ENOTFOUND _domain_...&lt;/code&gt;&lt;br&gt;
I spun and thrashed and tried everything I could think of. Then after hours of debugging, while doing some "pair debugging" they made the suggestion that we duplicate the A record in the public zone into the private zone. Lo and behold problem is solved. So, if you have resources deployed to a VPC and a private zone attached to said VPC, and a public zone sharing the domain name. When your resources are all in the domain, it will use the private zone &lt;em&gt;and the private zone only&lt;/em&gt; for resolution. &lt;br&gt;
I spent some time learning and digging deeper into Route53 and DNS in general, to better understand the situation and why the solution was what it was. I found &lt;a href="https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zone-private-considerations.html#hosted-zone-private-considerations-split-view-dns" rel="noopener noreferrer"&gt;this article&lt;/a&gt; in the Route53 docs that explained almost the exact situation I was in. Considering how much I enjoy working with the &lt;a href="https://aws.amazon.com/cdk/" rel="noopener noreferrer"&gt;CDK&lt;/a&gt;, and how much I struggled with this DNS configuration. I figured what better way to improve my understanding than to build a solution, that hopefully will help others avoid the headache I went through.&lt;/p&gt;
&lt;h3&gt;
  
  
  Introducing...
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;aws-cdk-split-horizon-dns&lt;/code&gt; CDK construct!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SplitHorizonDns&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AliasTarget&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-cdk-split-horizon-dns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstTarget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AliasTarget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;8.8.8.8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;private&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bucketWebsite&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;s3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BucketWebsite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;bucketName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;exampleDomain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// www.example.com&lt;/span&gt;
  &lt;span class="na"&gt;publicReadAccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;websiteIndexDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;constructTarget&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AliasTarget&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BucketWebsiteTarget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bucketWebsite&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;public&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SplitHorizonDns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyDNS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;zoneName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;privateZoneVpcs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;vpc&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;constructTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;firstTarget&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pass it your domain name, any vpc's you want to be attached to the private zone, and a list of either resources or IPs you would like A records for, and boom. Pack it up and send it. For the resources, you can flag them as public, private, or both. And the rest is taken care of.&lt;br&gt;
This project is still early stages. So if you try it and have success. Let me know! Or if this manages to bring the whole house down, please also let me know! Future goals will depend pretty highly on what's demanded of the construct. I would imagine there will be some want for being able to specify the record type that gets created. As with this initial release it is limited to A records. Additionally, a point of configuration that will likely be added soon is the ability to set the TTL of the record.&lt;br&gt;
As of now, support for TypeScript is being tested. Python is included, but untested. If you want your stack included in the project, feel free to open an issue or PR &lt;a href="https://github.com/IamFlowZ/aws-cdk-split-horizon-dns" rel="noopener noreferrer"&gt;here in the repository&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Hope this helps!&lt;/p&gt;

&lt;p&gt;Find me on &lt;a href="https://mstdn.social/@therealdakotal" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt; | &lt;a href="https://www.linkedin.com/in/dakota-lewallen/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/IamFlowZ" rel="noopener noreferrer"&gt;Github&lt;/a&gt; | &lt;a href="https://dakotalewallen.substack.com" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>awscdk</category>
      <category>route53</category>
    </item>
    <item>
      <title>TIL: How to CDK Diff Your Entire App</title>
      <dc:creator>Dakota Lewallen</dc:creator>
      <pubDate>Fri, 13 Jan 2023 20:58:51 +0000</pubDate>
      <link>https://dev.to/therealdakotal/til-how-to-cdk-diff-your-entire-app-2p99</link>
      <guid>https://dev.to/therealdakotal/til-how-to-cdk-diff-your-entire-app-2p99</guid>
      <description>&lt;p&gt;If you use the &lt;a href="https://aws.amazon.com/cdk/" rel="noopener noreferrer"&gt;AWS CDK&lt;/a&gt; to deploy resources, you may also likely use the &lt;a href="https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.pipelines-readme.html" rel="noopener noreferrer"&gt;Pipelines construct&lt;/a&gt; to deploy. Let's say you do, and you run a &lt;code&gt;cdk diff&lt;/code&gt; against your app prior to committing. It's awfully disappointing as it will only show you changes to the encasing pipeline. &lt;br&gt;
  However thanks to this &lt;a href="https://stackoverflow.com/questions/75099227/using-cdk-diff-to-diff-resources-wrapped-in-a-pipeline/75100254#75100254" rel="noopener noreferrer"&gt;fantastic answer&lt;/a&gt; from @fedonev on StackOverflow, I learned that there is &lt;a href="https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-stacks" rel="noopener noreferrer"&gt;special syntax&lt;/a&gt; within the CDK CLI that allows you to wildcard the stack you would like a command to run against. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You may also use wildcards to specify IDs that match a pattern.&lt;br&gt;
    ? matches any single character&lt;br&gt;
    * matches any number of characters (* alone matches all stacks)&lt;br&gt;
    ** matches everything in a hierarchy&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  cdk diff '**'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will diff not only diff the pipeline stack, but all the stack's within your application. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ese8dujz0isy0lidcho.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ese8dujz0isy0lidcho.gif" alt="The more you know" width="305" height="185"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Find me on &lt;a href="https://mstdn.social/@therealdakotal" rel="noopener noreferrer"&gt;Mastodon&lt;/a&gt; | &lt;a href="https://www.linkedin.com/in/dakota-lewallen/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; | &lt;a href="https://github.com/IamFlowZ" rel="noopener noreferrer"&gt;Github&lt;/a&gt; | &lt;a href="https://dakotalewallen.substack.com" rel="noopener noreferrer"&gt;Substack&lt;/a&gt;&lt;/p&gt;

</description>
      <category>todayilearned</category>
      <category>aws</category>
      <category>cdk</category>
      <category>cloudformation</category>
    </item>
  </channel>
</rss>
