In the AWS CDK, what does the `cdk synth` command actually do, and what does it leave behind in the cdk.out directory?
answer
- your program runs, a template comes out
- output directory, not a deployment
- one template per stack, plus a manifest
- cdk.out is the cloud assembly
- loops resolve before CloudFormation sees anything
basics
~10 scdk synth runs your CDK program and writes a cloud assembly into cdk.out: one CloudFormation template per stack, asset manifests, and staged asset files. It deploys nothing and changes no AWS resources.
solid answer
~40 s`cdk synth` is the synthesis step. The CLI runs the `app` command from cdk.json — your TypeScript, Python, Java or Go program — and every construct you instantiated renders itself into CloudFormation. The result is a **cloud assembly**: a directory, `cdk.out` by default, holding `<StackName>.template.json` for each stack, a `manifest.json` describing the stacks and their target environments, `<StackName>.assets.json` listing file and image assets, `tree.json`, and the staged `asset.<hash>` files themselves. With a single stack the template is also printed to stdout. Nothing is deployed — synthesis produces an artifact. That artifact is what CI passes around: you can synthesize once and later run `cdk deploy --app cdk.out` against exactly the assembly you reviewed. Your loops and conditionals do not survive into the template; only their result does.
code
bash · 3 linescdk synth --quiet
ls cdk.out
# cdk.out manifest.json tree.json MyStack.assets.json MyStack.template.jsongo deeper
Be able to say plainly that cdk synth runs your program and writes CloudFormation templates into cdk.out, and that it deploys nothing. Knowing where to open the generated template is half the value.
Explain the cloud assembly's contents — template per stack, manifest, asset manifest, staged assets — and that your language's control flow is evaluated during synthesis, so only its result reaches the template.
Show why the cloud assembly is the right CI artifact: synthesize once, publish cdk.out, and deploy that same assembly into each environment so the reviewed output is the deployed output.
Frame synthesis as the boundary between a program and a declarative artifact, and own the consequences: reproducible builds, what determinism you can promise reviewers, and where the organization pins that artifact in its delivery flow.
## What synthesis actually is The CDK is not a template language with extra syntax. A CDK app is an ordinary program in a general-purpose language, and running it is the whole point of `cdk synth`. The CLI reads `cdk.json`, finds the `app` entry (something like `"app": "npx ts-node --prefer-ts-exts bin/app.ts"`), and executes it as a subprocess. Your program constructs an `App`, adds one or more `Stack`s to it, and adds constructs to those stacks — building an in-memory tree. At the end, `app.synth()` walks that tree, asks each construct to render itself, and writes the result to disk. What each construct renders is CloudFormation. A high-level construct may expand into many resources, IAM policies and log groups; a low-level `Cfn*` resource maps to exactly one. Either way the output is plain CloudFormation JSON — there is no CDK runtime in AWS, and nothing in the deployed account knows your app was written in TypeScript. ## What lands in cdk.out The directory the CLI writes is called a *cloud assembly*, and it is a self-describing artifact: ``` cdk.out/ cdk.out # marks the directory, with the assembly schema version manifest.json # the stacks, their environments, and their dependencies tree.json # the construct tree, used by tooling MyStack.template.json # one CloudFormation template per stack MyStack.assets.json # the file and image assets this stack needs asset.3f9c.../ # staged asset content, named by content hash ``` Every stack in the app gets its own template file, regardless of how many you asked for on the command line. `manifest.json` is what tells the CLI which account and region each stack targets and in what order dependent stacks must go out. ## Your code runs now, not at deploy time This is the point juniors most often miss. A `for` loop that creates ten buckets produces ten `AWS::S3::Bucket` resources in the template — there is no loop in the template, because the loop already ran on your laptop. An `if` on an environment name picks a branch at synthesis time and the other branch simply does not exist in the output. Anything you want CloudFormation itself to decide at deploy time has to be expressed as CloudFormation constructs, not as language constructs. Values that genuinely are not known until deploy — the ARN of a resource being created in this very deployment, for example — appear in the template as *tokens*: opaque placeholder strings during synthesis that render into CloudFormation references in the output. That is why printing such a value in your program shows something like `${Token[TOKEN.42]}` rather than a real ARN. ## Why the artifact matters Because synthesis is deterministic and local, the cloud assembly is a reviewable, storable build output. A pipeline typically synthesizes once, publishes `cdk.out` as a build artifact, and every later stage deploys *that* assembly with `cdk deploy --app cdk.out` instead of re-running the program. That removes a whole class of surprises where the code drifted, a dependency resolved differently, or a lookup returned something new between the review and the deploy. `cdk.out` is a build output and belongs in `.gitignore`. You regenerate it; you never hand-edit it. If you find yourself wanting to edit the template, that is a signal to reach for an escape hatch in the program instead, so the change survives the next synth. ## What synth does not do It does not create, modify or delete anything in AWS — you can run it with no credentials at all, unless your app performs environment lookups that need to call AWS. It does not ask CloudFormation whether the template is acceptable, so an invalid property value, a service quota, or a name collision surfaces later during deploy, not here. It does not compare against what is deployed — that is `cdk diff`. And it does not publish assets; it only *stages* them into `cdk.out` and records their hashes, leaving the upload to deploy time. The practical takeaway for an interview: synth is "run my program, get templates". Everything that touches AWS happens afterwards.
- If I never run cdk synth and go straight to cdk deploy, does synthesis still happen?Yes. `cdk deploy` synthesizes first and then deploys the resulting assembly, so running `cdk synth` separately is only about seeing the output. The exception is when you point the CLI at an assembly that already exists: `cdk deploy --app cdk.out` skips running your program and deploys exactly what is on disk, which is how pipelines guarantee that the reviewed artifact is the deployed one.
- Should cdk.out be committed to the repository?No — it is a build output, regenerated on every synth, and it is in the default `.gitignore` a new project ships with. Committing it invites someone to edit a template by hand, and that edit vanishes on the next synthesis. If you need the exact artifact later, publish `cdk.out` from CI as a build artifact rather than into git.
saying these in an interview costs you the question
- Says cdk synth contacts AWS and creates resources
- Thinks synth is a syntax transform that keeps loops in the template
- Believes you must run synth manually before every deploy
- Expects cdk synth to validate the template against the CloudFormation service
- Treats cdk.out as source to be committed and hand-edited