In the AWS CDK, what are an App, a Stack and a Construct, and which of the three corresponds to something AWS actually creates when you deploy?
answer
- root, unit, building block
- only one layer is deployable
- one instance equals one CloudFormation stack
- the App is never deployed
- synth writes one template per stack
basics
~20 sConstructs are the composable building blocks of the tree; a Stack is the deployment unit that synthesizes into exactly one CloudFormation stack; the App is the root object holding every stack. Only stacks become real AWS deployments.
solid answer
~50 sAn AWS CDK program builds a tree of **constructs** — objects constructed with `(scope, id, props)`, where `scope` is the parent. Two nodes in that tree have special meaning. `App` is the root you create first and never deploy directly. `Stack` is the boundary where the description becomes deployable: one `Stack` instance synthesizes into exactly one CloudFormation template and deploys as exactly one CloudFormation stack, in one account and one region. Everything else is a construct that contributes resources to whichever stack it is scoped under. `cdk synth` walks the tree and writes a cloud assembly — one template per stack, in `cdk.out`. After that, AWS only ever sees CloudFormation; the App, the classes and the construct tree are gone. That is why stack boundaries are an architectural decision: the stack is the unit of deploy, of rollback and of resource limits.
code
typescript · 16 linesimport * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
class StorageStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);
new s3.Bucket(this, 'Data', { versioned: true });
}
}
const app = new cdk.App();
const env = { account: '111122223333', region: 'eu-west-1' };
new StorageStack(app, 'Storage', { env });
new StorageStack(app, 'StorageBackup', { env: { ...env, region: 'eu-central-1' } });
app.synth();go deeper
Be able to name the three layers in order and say plainly that the Stack is the one that becomes a CloudFormation stack in AWS. Know that you run cdk deploy against a stack name, not against the app.
Explain what synthesis produces — a cloud assembly with one template per stack — and that AWS never sees your constructs. Be ready to say where env attaches and why one app can span accounts and regions.
Justify a stack split on lifecycle, blast radius and resource limits rather than on code tidiness, and explain why frequently deployed services should not share a stack with long-lived networking.
Own the estate shape: how many stacks per service, which boundaries teams can deploy independently, and the tradeoff between few large stacks with simple wiring and many small stacks with more inter-stack coupling.
## Three layers, one tree An AWS CDK program is not a script that calls AWS APIs. It is a program that builds an in-memory tree of objects and then prints CloudFormation. The nodes of that tree are **constructs**: objects whose constructor signature is `(scope, id, props)`, where `scope` is the parent construct. A construct by itself creates nothing in AWS — it is a piece of a description. Two constructs carry special meaning. **`Stack`** is the boundary at which description turns into a deployable artifact. One `Stack` instance synthesizes into exactly one CloudFormation template and is deployed as exactly one CloudFormation stack, into one AWS account and one region. **`App`** is the root. You create it first, scope your stacks to it, and never deploy it — there is no AWS object called an App. ```typescript const app = new cdk.App(); const env = { account: '111122223333', region: 'eu-west-1' }; new NetworkStack(app, 'Network', { env }); new ServiceStack(app, 'Service', { env }); app.synth(); ``` ## What synthesis produces `cdk synth` walks the tree, lets each construct contribute CloudFormation resources to the stack it lives under, and writes a **cloud assembly**: a directory (`cdk.out` by default) containing one template file per stack plus metadata the CLI uses. From that moment on, AWS sees only CloudFormation. Your classes, your loops, your `if` statements and the construct tree itself do not exist at deploy time — they ran already, during synthesis, on your machine or your build runner. This is the reason the question has exactly one answer: the Stack is the thing AWS creates. `cdk deploy Network` calls CloudFormation with the template that stack produced. ## Why the Stack boundary is the one that matters Because a stack is the CloudFormation unit, it is simultaneously the unit of several things you care about: - **Deployment.** `cdk deploy Service` deploys one stack; `cdk deploy --all` deploys every stack in the app. `cdk list` shows you the names. - **Rollback and blast radius.** A failed update rolls that stack back. Resources in a different stack are untouched. - **Limits.** CloudFormation caps the number of resources in a single stack, so a large estate has to be split. - **Lifecycle.** A VPC that changes twice a year and a service that deploys twice a day do not belong in the same stack, because every deploy of the fast-moving thing puts the slow-moving thing into an update. So splitting an app into stacks is an architectural decision, not code tidying. The rule of thumb is: things that must deploy together and roll back together go in one stack; things with independent lifecycles go in separate stacks. Constructs are the opposite — they are free to reorganise. Wrapping several resources in your own construct class does not create a new deployment unit; those resources still belong to whichever stack the construct is scoped under. Composition is a code-structure tool; stacks are a deployment tool. ## Where the environment attaches `env` — the account and region a stack targets — is a property of a **Stack**, not of the App and not of an individual construct. Two stacks in one app can target two different accounts, or two regions, because each one becomes its own CloudFormation stack in its own environment. This is also why an App is not "an account": one app routinely spans several. Between App and Stack there is an optional layer, `Stage`: a group of stacks you can instantiate more than once, typically once per environment. `App` is itself a subclass of `Stage`, which is why stages nest naturally under it. ## What candidates get wrong The two common errors are collapsing the layers in either direction. One is treating the App as the deployable thing ("the app is my CloudFormation stack"), which makes stack boundaries look like folders and leads to one enormous stack. The other is imagining that each construct maps to a stack, which makes the resource limit and rollback behaviour incomprehensible. A third, subtler error is believing the CDK talks to AWS while your code runs. It does not — apart from synth-time context lookups, the CDK's entire job is to emit templates, and every deployment decision is CloudFormation's.
- If you instantiate a construct but it is not scoped under any stack, what gets deployed?Nothing. Only constructs in a stack's scope contribute resources to a template. Most higher-level constructs resolve their stack internally via `Stack.of(this)` and fail at synthesis time if there is no stack ancestor, so the mistake usually shows up as a synth error rather than a silent omission.
- What is a Stage, and where does it sit relative to App and Stack?A `Stage` is a composable group of stacks that can be instantiated more than once — typically once per environment — and it synthesizes into its own cloud assembly. It sits between the App and the stacks. `App` is itself a subclass of `Stage`, which is why a stage nests under an app naturally.
- How does the CDK CLI decide which stacks to deploy?`cdk list` enumerates the stacks in the synthesized assembly by their construct path. You then name one (`cdk deploy Service`), pass a glob, or use `--all`. The CLI orders deployments by the dependencies between stacks, so a producer stack goes before a stack that references it.
The App is the build; the constructs are source files and functions; the Stack is the artifact that actually gets shipped and can be rolled back on its own.
saying these in an interview costs you the question
- Says one App equals one CloudFormation stack
- Thinks every construct becomes its own stack
- Assumes all stacks in an app must deploy together
- Says a Stack maps to an AWS account, not a CloudFormation stack
- Believes the CDK calls AWS resource APIs directly at runtime