Bootstrap a new AWS account
After this you can answer: What must exist before the very first deploy into a brand-new AWS account?
Picture it
Section titled “Picture it”flowchart TB O["owner's AWS login"] --> BS["pnpm infra:bootstrap"] BS --> T["14 targets: OIDC provider,<br/>2 roles + policies, 3 ECR repos,<br/>SSM parameters"] BS --> GH["GitHub: environment named after stack,<br/>variables, Pulumi token"] BS --> DNS["DNS records to add<br/>(certificate, DKIM)"] T --> CD["first CD run creates the rest"]How it works
Section titled “How it works”- Account and region. A wrong or expired login stops here.
- Stack and config. It uses an existing stack or creates one without changing your selected stack. Missing switches default to false; existing values stay unchanged.
- The 14 targets. A preview, your “y”, then an apply limited to those resources. An existing OIDC provider is imported, not created twice (an account may have only one per issuer).
- GitHub. The environment named after the stack, with you as a required reviewer, repository and environment variables, and the Pulumi token.
- DNS and checks. Records exist after the first CD run. Rerun the script to print certificate and DKIM records for Cloudflare and check DNS, SES, alerts, Lambda concurrency and CloudFront.
- Next steps. Commit config, push, approve CD. Complete DNS, then commit the switches on, approve CD again and set the app CNAME.
In MiniTickets
Section titled “In MiniTickets”| Target | Why CD needs it before its first run |
|---|---|
| OIDC provider, publish role + policy | publish logs in with it |
| deploy role + policy | deploy logs in and applies with it |
| 3 ECR repositories + lifecycle policies, worker pull policy | receive images, retain versions and allow Lambda pulls |
SSM image-tag, deployed-commit | deploy reads them before its first apply |
Reruns preserve config, preview AWS changes and reconcile GitHub settings after approval.
--dry-run makes no changes; it skips previews when the stack or required config is missing.
New accounts may have a Lambda concurrency limit of 10. Our queue triggers allow at most 7
concurrent invocations; other functions share the quota. CloudFront may require account verification;
that matters only with cdnEnabled: true.
See it in AWS
Section titled “See it in AWS”IAM → Identity providers and Roles (minitickets-dev-gh-*); ECR → Repositories; Systems Manager
→ Parameter Store.
aws iam list-open-id-connect-providers
scripts/infra-bootstrap.ts and the target list in scripts/bootstrap/targets.ts.
Break it
Section titled “Break it”| Symptom | Cause | Where to look |
|---|---|---|
| The first CD run fails at “Configure AWS credentials” | No OIDC provider or role in this account yet | IAM → Identity providers |
| Deploy: “Cannot read SSM … image-tag” | The parameters were not bootstrapped | Parameter Store |
| Alarm emails never arrive | The SNS email subscription was never confirmed | SNS → alerts topic |
Say it in an interview
Section titled “Say it in an interview”Follow-ups
Section titled “Follow-ups”Why limit the bootstrap apply to targets?
The first full apply should be CD’s, from the committed config. A full local apply could create billed resources from an uncommitted config that the next CD run then undoes.
What changes when the deploy role needs a new permission later?
Committing a permission does not grant it yet. If CD needs it before the new policy reaches AWS, the owner applies the targeted policy update first, then retries CD.
Why is the stack config committed before the first deploy?
The committed Pulumi.<stack>.yaml is what CD applies. Uncommitted switches exist on one laptop
only.
Advanced: Details: names
Stack-specific names come from infra/src/names.ts; GitHub variables supply them to CD. Repo
variables select one publishing account, so changing them redirects publishing for the whole repo.
Importing an existing OIDC provider makes this stack manage it. Deleting that shared provider
would also break other users; review that warning before importing.
Checkpoint
Section titled “Checkpoint”Answer these without scrolling up. If one feels hard, reread that section.
- Why can CD not create its own roles?
- Name the four groups of bootstrap targets.
- What makes the script safe to run again?
- Which two account limits does it check, and why?
- What does the owner do after the script?
Redraw it from memory: owner login → bootstrap (14 targets + GitHub + DNS + checks) → commit config → first CD run creates the rest
Try this: on the map, select the GitHub OIDC identity provider and see which roles trust it
Read this book online: https://book.theversehub.in/