CDK App vs Template

A Short CDK App Compared with Its Synthesized Template

BookNest's CDK 24 app declares the catalog table and a function that counts its books (api/index.mjs runs a DynamoDB 24 Scan with Select: "COUNT"):

cdk/app.js: BookNest's table and counting function as CDK constructsJavaScript
const { App, Stack, RemovalPolicy } = require("aws-cdk-lib");
const dynamodb = require("aws-cdk-lib/aws-dynamodb");
const lambda = require("aws-cdk-lib/aws-lambda");
const app = new App();
const stack = new Stack(app, "BookNestCdk");
const table = new dynamodb.Table(stack, "Books", {
  partitionKey: { name: "id", type: dynamodb.AttributeType.NUMBER },
  billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
  removalPolicy: RemovalPolicy.DESTROY,
});
const countBooks = new lambda.Function(stack, "CountBooks", {
  runtime: lambda.Runtime.NODEJS_24_X,
  handler: "index.handler",
  code: lambda.Code.fromAsset("../api"),
  environment: { TABLE_NAME: table.tableName },
});
table.grantReadData(countBooks);

With version reporting and path metadata turned off in cdk.json, the 18 lines synthesize to 88 lines of YAML:

Synthesizing BookNestCdkShell
npx cdk synth
Output
...
  CountBooksServiceRoleDefaultPolicyACCBA433:
    Type: AWS::IAM::Policy
...
              - dynamodb:BatchGetItem
              - dynamodb:Query
              - dynamodb:GetItem
              - dynamodb:Scan
...
        S3Key: 59a93d081c20b196fca2937727fe33d1c8619a0e78b9f1a1d72618e3ff272b97.zip
...

Logical IDs carry a hash of the construct path, so renaming a construct replaces its resource (run cdk diff first). grantReadData wrote eight actions where the function needs only dynamodb:Scan, and the code became an S3 24 object named by its hash. This section used a second LocalStack 63,725 , l2-localstack on port 32566. cdklocal 305 refuses to start if AWS_ENDPOINT_URL is set without AWS_ENDPOINT_URL_S3:

Bootstrapping LocalStack, deploying BookNestCdk, and asking about ECRShell
export AWS_ENDPOINT_URL_S3=http://s3.localhost.localstack.cloud:32566
npx cdklocal bootstrap 2>&1 | tail -1
npx cdklocal deploy --require-approval never 2>&1 | grep '✅'
docker logs l2-localstack 2>&1 | grep -o 'Creating a Mock ECR.*' | fold -s -w 90
aws ecr describe-repositories 2>&1 | grep -o 'the ecr service[^,]*'
Output
✅  Environment aws://000000000000/us-east-1 bootstrapped.
✅  BookNestCdk
Creating a Mock ECR Repository for CloudFormation. This is only intended to be used for
allowing a successful CDK bootstrap and does not provision any underlying ECR repository.
the ecr service is not included within your LocalStack license

BookNestCdk is real: after one put-item, its function returned {"books":1}. But the bootstrap stack reported its ECR 24 repository CREATE_COMPLETE although 4.13.1 has no ECR, so container-image assets would fail to publish. On LocalStack, check resources through their own APIs, not the stack status.