<?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>Forem: Alex Raileanu</title>
    <description>The latest articles on Forem by Alex Raileanu (@raileanualex03).</description>
    <link>https://forem.com/raileanualex03</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%2F1772390%2F1afbf7da-d1b6-4202-899c-9b54be6d0c64.jpg</url>
      <title>Forem: Alex Raileanu</title>
      <link>https://forem.com/raileanualex03</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/raileanualex03"/>
    <language>en</language>
    <item>
      <title>Working with AWS DSQL and Lambda: First Part - Setup of the project</title>
      <dc:creator>Alex Raileanu</dc:creator>
      <pubDate>Tue, 10 Jun 2025 14:55:16 +0000</pubDate>
      <link>https://forem.com/aws-builders/working-with-aws-dsql-and-lambda-first-part-setup-of-the-project-209m</link>
      <guid>https://forem.com/aws-builders/working-with-aws-dsql-and-lambda-first-part-setup-of-the-project-209m</guid>
      <description>&lt;p&gt;Not long ago, I was exploring Amazon Aurora DSQL, AWS's newest distributed SQL database built specifically for serverless workloads. Unlike traditional databases that require constant maintenance, Aurora DSQL scales automatically and only charges for what you use - making it a perfect match for Lambda functions.&lt;/p&gt;

&lt;p&gt;When you think &lt;strong&gt;serverless&lt;/strong&gt; databases, DynamoDB probably comes to mind first — and for good reason. It's been the go-to NoSQL solution for serverless applications for years. But now we can finally consider relational databases in a truly serverless context too. Aurora DSQL brings the familiarity of SQL and relational data modeling to the serverless world, without the overhead of managing database instances or worrying about scaling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Welcome&lt;/strong&gt; to the first installment in a three-part series where I'll build a serverless backend using Amazon Aurora DSQL, AWS Lambda, AWS CDK, and GitHub Actions. &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%2F3801q0z4uhn0lrxpa48q.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%2F3801q0z4uhn0lrxpa48q.png" alt="Diagram" width="494" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What will this first article cover?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Project Setup&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’ll learn how to initialize and organize your serverless backend project, including setting up your repository and preparing the necessary files and folders for a smooth development workflow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AWS CDK for Infrastructure&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This article walks you through using AWS CDK to define your cloud infrastructure as code. You’ll see how to use CDK constructs (especially L1 for Aurora DSQL, where applicable) to provision resources such as Lambda functions and Aurora DSQL clusters, and how to structure your CDK stack for maintainability and scalability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Lambda and DSQL Connectivity&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’ll discover how to establish secure connectivity between AWS Lambda and Amazon Aurora DSQL. This includes configuring IAM roles and policies to allow Lambda to interact with the DSQL Data API, and setting up environment variables or secrets for secure database access.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Code Snippets – Step-by-Step&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Practical, actionable code examples are provided at each stage. You’ll see how to write CDK stacks, define Lambda functions, and connect them to DSQL, making it easy to follow along and adapt the approach to your own projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Open Source Repository&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The article references an open-source repository, allowing you to review the complete project structure, clone the code, and experiment with the setup yourself. This ensures transparency and makes it easy to check or extend the approach.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1:
&lt;/h3&gt;

&lt;p&gt;Here’s how I like to organize the project&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%2F7ztnsdzni5c6q9ro2zrm.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%2F7ztnsdzni5c6q9ro2zrm.png" alt="Structure" width="800" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;infra/ – Contains all CDK-related infrastructure code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;service/ – Your Lambda source code goes here.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;.github/ - The GitHub Actions workflows go here.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This approach usually empowers me to easily separate infrastructure from business logic and isolate the pipeline related actions as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also - I like to structure the infrastructure in stacks based on their domain. I found it useful as the project kept on growing.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2:
&lt;/h3&gt;

&lt;p&gt;Now let's jump into the details of working with AWS CDK and AWS DSQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Since AWS DSQL has been recently released, the only Constructs that are available are L1 Constructs which are automatically generated. I will adjust this article &amp;amp; open-source repository as the AWS DSQL support becomes more widely adopted in the CDK world.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class StorageStack extends cdk.Stack {
    dsqlCluster: cdk.CfnResource;
    dsqlClusterArn: string;
    dsqlClusterEndpoint: string;

    constructor(scope: constructs.Construct, id: string, props: cdk.StackProps) {
        super(scope, id, props);

        // Create DSQL cluster using native CloudFormation resource
        this.dsqlCluster = new cdk.CfnResource(this, 'DSQLCluster', {
            type: 'AWS::DSQL::Cluster',
            properties: {
                DeletionProtectionEnabled: true,
                Tags: [
                    {
                        Key: 'Project',
                        Value: 'aws-dsql-demo'
                    }
                ]
            }
        });

        this.dsqlClusterArn = this.dsqlCluster.getAtt('ResourceArn').toString();
        this.dsqlClusterEndpoint = `${this.dsqlCluster.getAtt('Identifier').toString()}.dsql.${this.region}.on.aws`;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3:
&lt;/h3&gt;

&lt;p&gt;Moving further to the Lambda layer, I will need to ensure it has the correct permissions to be able to connect to the DSQL Cluster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface FunctionsStackProps extends cdk.StackProps {
    label: {
        id: string;
    },
    domainName: string;
    dsqlClusterEndpoint: string;
    dsqlClusterArn: string;
}

export class FunctionsStack extends cdk.Stack {
    generateGameLambda: lambda.Function;

    constructor(scope: constructs.Construct, id: string, props: FunctionsStackProps) {
        super(scope, `${id}-functions-stack`, props);

        // Create Lambda role with DSQL permissions
        const lambdaRole = new iam.Role(this, 'DSQLLambdaRole', {
            assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
            managedPolicies: [
                iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'),
            ]
        });

        // Add DSQL permissions
        lambdaRole.addToPolicy(new iam.PolicyStatement({
            effect: iam.Effect.ALLOW,
            actions: [
                'dsql:DbConnect',
                'dsql:ExecuteStatement',
                'dsql:DbConnectAdmin',
            ],
            resources: [props.dsqlClusterArn]
        }));

        this.generateGameLambda = new nodeLambda.NodejsFunction(this, 'GenerateGameLambda', {
            entry: './service/generate-game/Handler.ts',
            runtime: lambda.Runtime.NODEJS_20_X,
            role: lambdaRole,
            environment: {
                DSQL_ENDPOINT: props.dsqlClusterEndpoint
            }
        });
    }
}

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

&lt;/div&gt;



&lt;p&gt;I also added the DSQL_ENDPOINT as an environment variable to easily adapt it dynamically when creating a new infrastructure without any manual changes to the Lambda.&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%2F4hosg5bnb14um5nyczch.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%2F4hosg5bnb14um5nyczch.png" alt="Cloudformation" width="800" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4:
&lt;/h3&gt;

&lt;p&gt;One important part of working with Aurora DSQL in Lambda is managing the database connection efficiently. Since Lambdas are ephemeral and scale rapidly, you want to avoid repeatedly initializing database connections which can be expensive and slow.&lt;/p&gt;

&lt;p&gt;Here, we create a DatabaseService class that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Caches the TypeORM DataSource connection so it’s initialized only once per Lambda container lifecycle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Uses the DsqlSigner from &lt;code&gt;@aws-sdk/dsql-signer&lt;/code&gt; to generate secure, temporary authentication tokens to connect to the database without storing passwords.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Leverages TypeORM’s DataSource for managing your entities and database interactions with familiar ORM patterns. We will dive deeper in the second article of the series to explain more on the TypeORM integration.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "reflect-metadata";
import { DataSource } from "typeorm";
import { DsqlSigner } from "@aws-sdk/dsql-signer";
import { Game } from "../models/Game";

export class DatabaseService {
    private static dataSource: DataSource;

    private static async getAuthToken(host: string): Promise&amp;lt;string&amp;gt; {
        const signer = new DsqlSigner({
            hostname: host,
            region: process.env.AWS_REGION || 'eu-west-2'
        });

        return await signer.getDbConnectAdminAuthToken();
    }

    static async initialize(): Promise&amp;lt;DataSource&amp;gt; {
        if (!DatabaseService.dataSource) {
            const host = process.env.DSQL_ENDPOINT || '';

            DatabaseService.dataSource = new DataSource({
                type: "postgres",
                host: host,
                port: 5432,
                username: 'admin',
                password: await DatabaseService.getAuthToken(host),
                database: "postgres",
                ssl: {
                    rejectUnauthorized: true
                },
                synchronize: true,
                logging: true,
                entities: [Game]
            });

            // Initialize connection to postgres database
            await DatabaseService.dataSource.initialize();
        }

        return DatabaseService.dataSource;
    }

    static async saveGame(game: Partial&amp;lt;Game&amp;gt;): Promise&amp;lt;Game&amp;gt; {
        const dataSource = await DatabaseService.initialize();
        const gameRepository = dataSource.getRepository(Game);

        const newGame = gameRepository.create(game);
        return await gameRepository.save(newGame);
    }
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5:
&lt;/h3&gt;

&lt;p&gt;Creating the Handler for the Lambda&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function handler(event: APIGatewayProxyEvent, context: Context): Promise&amp;lt;APIGatewayProxyResult&amp;gt; {
    console.log(event, context);
    await DatabaseService.initialize();

    try {
        // Generate a random game
        const gameData = generateRandomGame();

        // Save it to the database
        const savedGame = await DatabaseService.saveGame(gameData);

        return {
            statusCode: 200,
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                message: 'Game generated and saved successfully',
                game: savedGame
            })
        };
    } catch (error) {
        console.error('Error generating game:', error);
        return {
            statusCode: 500,
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                message: 'Failed to generate and save game',
                error: error instanceof Error ? error.message : String(error)
            })
        };
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the response at the API level here.&lt;br&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%2Fsc82mf72ak9u5regjzp7.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%2Fsc82mf72ak9u5regjzp7.png" alt="API Response" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Manual debugging
&lt;/h3&gt;

&lt;p&gt;You can even connect to the Database directly using the AWS Console.&lt;/p&gt;

&lt;p&gt;Go to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search AWS DSQL.&lt;/li&gt;
&lt;li&gt;Select your cluster.&lt;/li&gt;
&lt;li&gt;Press on Connect &amp;gt; Open in Cloudshell.&lt;/li&gt;
&lt;li&gt;Connect as admin &amp;gt; Press Run script.&lt;/li&gt;
&lt;li&gt;And you're live -&amp;gt; You can directly run SQL Queries.&lt;/li&gt;
&lt;/ul&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%2Fdaruhi5nh2pvrzpbuhu5.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%2Fdaruhi5nh2pvrzpbuhu5.png" alt="SQL Query Response" width="800" height="128"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Achievements in this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set up a clean, scalable project structure separating infrastructure, service code, and CI/CD workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provisioned an Amazon Aurora DSQL cluster and Lambda functions using AWS CDK, leveraging L1 constructs for the new DSQL resource.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configured IAM roles and permissions enabling Lambda to securely connect and execute SQL commands on Aurora DSQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implemented an efficient Lambda database connection pattern using TypeORM with AWS DsqlSigner to generate secure temporary auth tokens.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created a Lambda handler that generates and saves data to Aurora DSQL, exposing it via an API Gateway endpoint secured by an api key.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the upcoming articles, you’ll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement business logic with TypeORM entities and migrations&lt;/li&gt;
&lt;li&gt;Expose multiple operations on these TypeORM entities via API Gateway, including how to add an effective caching mechanism to improve performance and reduce latency.&lt;/li&gt;
&lt;li&gt;Benefits of using AWS DSQL and best practices for efficient &amp;amp; performant infrastructure.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Open Source Repository: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/raileanualex/aws-dsql-demo" rel="noopener noreferrer"&gt;https://github.com/raileanualex/aws-dsql-demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/aurora-dsql/latest/userguide/programming-with.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/aurora-dsql/latest/userguide/programming-with.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/aws-samples/aurora-dsql-samples" rel="noopener noreferrer"&gt;https://github.com/aws-samples/aurora-dsql-samples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>awsdsql</category>
      <category>awslambda</category>
      <category>cdk</category>
    </item>
    <item>
      <title>Smooth AWS Local Development with Localstack, AWS CDK and Typescript</title>
      <dc:creator>Alex Raileanu</dc:creator>
      <pubDate>Tue, 08 Apr 2025 12:25:18 +0000</pubDate>
      <link>https://forem.com/aws-builders/smooth-aws-local-development-with-localstack-aws-cdk-and-typescript-36no</link>
      <guid>https://forem.com/aws-builders/smooth-aws-local-development-with-localstack-aws-cdk-and-typescript-36no</guid>
      <description>&lt;p&gt;Working with AWS services in real applications is amazing — until you realize how often you need to deploy even for the smallest change. While the cloud offers incredible scalability and flexibility, &lt;strong&gt;local development&lt;/strong&gt; still feels like an afterthought in many serverless workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this matters?
&lt;/h3&gt;

&lt;p&gt;In smaller teams, this might not seem like a huge issue — you deploy, test, and move on. But as the team grows and the codebase gets more complex, the friction starts to add up. Waiting for CloudFormation to deploy changes or running integration tests against actual &lt;strong&gt;AWS&lt;/strong&gt; infrastructure can slow down development significantly and make rapid iteration much harder.&lt;/p&gt;

&lt;h3&gt;
  
  
  How can this be solved?
&lt;/h3&gt;

&lt;p&gt;Not long ago, I stumbled upon a podcast episode about LocalStack v4, and it got me curious. I'd heard of LocalStack before but never gave it a proper try — so I figured, why not?&lt;/p&gt;

&lt;p&gt;A couple of commands later, I had my entire &lt;strong&gt;AWS CDK project&lt;/strong&gt; running locally. Lambda, API Gateway, DynamoDB — all spun up on my machine, no cloud deploys needed. It was surprisingly smooth.&lt;/p&gt;

&lt;p&gt;What really stood out was how little effort it took. I didn’t have to rewrite anything in my CDK code. LocalStack just worked. It felt like I finally had a proper local dev setup for the cloud — fast, easy to debug, and perfect for experimenting without worrying about breaking something in the real AWS environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to setup your local environment in less than 5 minutes?
&lt;/h3&gt;

&lt;p&gt;Before diving in, here’s a quick look at the tech stack I was using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js with TypeScript&lt;/li&gt;
&lt;li&gt;AWS CDK for infrastructure-as-code&lt;/li&gt;
&lt;li&gt;A serverless architecture using Lambda, API Gateway, DynamoDB and IAM.&lt;/li&gt;
&lt;/ul&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%2F0nqdrozayr6f8mvvulmf.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%2F0nqdrozayr6f8mvvulmf.png" alt="Architecture" width="670" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If that sounds familiar, you're in luck — getting this running locally with LocalStack was way easier than I expected.&lt;/p&gt;

&lt;p&gt;Step 1: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install Local Stack
&lt;code&gt;brew install localstack/tap/localstack-cli&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login to the localstack account and export the token.
&lt;code&gt;export LOCALSTACK_AUTH_TOKEN="&amp;lt;value&amp;gt;"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 3: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure it is correctly installed
&lt;code&gt;localstack --version&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 4:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start localstack
&lt;code&gt;localstack start&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 5: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install dependencies needed for CDK globally
&lt;code&gt;npm install -g aws-cdk-local aws-cdk&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 6:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify installation
&lt;code&gt;cdklocal --version&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 7: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure that your CDK application is not using hardcoded AWS Account or Region. You should use the Environment Variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 8:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the &lt;strong&gt;cdklocal&lt;/strong&gt; scripts in &lt;strong&gt;package.json&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"local-deploy": "cdklocal deploy --all",
"local-synth": "cdklocal synth",
"local-bootstrap": "cdklocal bootstrap"`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 9:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;npm run local-synth&lt;/code&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%2F201c91s1b1vui7ut32p6.png" alt="Output" width="800" height="349"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 10:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;npm run local-bootstrap&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2F7v4hh4ke6tczb0c9xmks.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%2F7v4hh4ke6tczb0c9xmks.png" alt="Output" width="800" height="122"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 11:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;npm run local-deploy&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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%2Facvm2b5l5f5gus9wc6sp.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%2Facvm2b5l5f5gus9wc6sp.png" alt="Output" width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 12:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open localstack browser and check created resources: &lt;a href="https://app.localstack.cloud/inst/default/resources" rel="noopener noreferrer"&gt;https://app.localstack.cloud/inst/default/resources&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&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%2Fa6djzf2zv0im5bj1gcum.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%2Fa6djzf2zv0im5bj1gcum.png" alt="Demo" width="800" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 13:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You can check the Cloudformation stacks and the resources created and start already testing the application.&lt;br&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%2Fhha4nrsrepviwctpizij.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%2Fhha4nrsrepviwctpizij.png" alt="Demo" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can literally test the API Gateway Endpoint as if it was deployed and see the Cloudwatch logs for that.&lt;br&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%2Fjarvo9jszi8nehtyumdc.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%2Fjarvo9jszi8nehtyumdc.png" alt="Demo" width="800" height="235"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I was able to trigger the API using Postman&lt;br&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%2F5utxla8d7qbs8c3wc1hb.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%2F5utxla8d7qbs8c3wc1hb.png" alt="Postman" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important Note&lt;/strong&gt;: The recommendation from LocalStack is to delete the stacks and re-create them instead of updating them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Personal thoughts
&lt;/h3&gt;

&lt;p&gt;Local development for AWS has always felt like something you just had to live without — but with tools like LocalStack, that's no longer the case. Whether you're working solo or in a larger team, being able to test and &lt;strong&gt;iterate quickly&lt;/strong&gt; without deploying to the cloud is a game changer.&lt;/p&gt;

&lt;p&gt;I was &lt;strong&gt;genuinely impressed&lt;/strong&gt; by how smooth the experience was — and I’ll definitely be including LocalStack in more of my AWS workflows moving forward.&lt;/p&gt;

&lt;p&gt;Give it a shot and let me know how it goes!&lt;/p&gt;

&lt;p&gt;References:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.localstack.cloud/getting-started/" rel="noopener noreferrer"&gt;https://docs.localstack.cloud/getting-started/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/raileanualex/serverless-api" rel="noopener noreferrer"&gt;https://github.com/raileanualex/serverless-api&lt;/a&gt; [ Basic similar setup as reference ]&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=vVUBnXD6eto" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=vVUBnXD6eto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>typescript</category>
      <category>cloud</category>
    </item>
  </channel>
</rss>
