The AMI Pin Is a Decision: Write It Down Before the Next Incident
A service is still launching from an AMI that predates the current launch template by two years. The instance type has changed, the security groups have changed, the user-data script has been rewritten twice. The AMI ID has not moved. Nobody on the current rotation remembers why, and the ticket that might have explained it was closed without a comment.
This is not a story about a bad AMI. It is a story about a missing decision record. The pin itself may be entirely correct. The problem is that the next engineer to touch the launch configuration has no way to tell whether moving the AMI is routine maintenance or a change that will break something they cannot see.
Why a ticket comment is not enough
An architectural decision record (ADR) is a short document that describes a choice the team makes about a significant aspect of the software architecture, including its context and its consequences. AWS Prescriptive Guidance defines it that way and notes that the structure focuses on the reason for the decision rather than how the team implemented it (AWS Prescriptive Guidance, ADR process). That distinction matters here. A ticket comment usually records the implementation — “pinned to ami-0abc because the build failed” — and loses the reason. Six months later, the build failure is gone and the reason is unrecoverable.
The same guidance says that at a minimum, each ADR should define the context of the decision, the decision itself, and the consequences for the project and its deliverables. That is a low bar. It is also exactly the bar a lean on-call team needs: three sections, one page, stored where the launch configuration lives.
What the AMI lifecycle actually does
Before writing the record, it helps to be precise about what a pin protects against and what it does not. AWS documents that deprecated AMIs are hidden from AMI listings by default, but existing users and launch services such as launch templates and Auto Scaling groups can continue to use a deprecated AMI by specifying its ID (Deprecate an Amazon EC2 AMI). Instances launched from an AMI that is later deprecated are not affected and can be stopped, started, and rebooted. Deprecation does not delete the AMI, and the owner continues to pay for its snapshots until the AMI is deregistered.
Two consequences follow. First, a pin can outlive the deprecation date silently, because the launch template keeps working. Second, the pin is not free: the snapshots behind the AMI remain billable until someone deregisters it. Neither fact tells you whether the pin is safe. Both facts belong in the record as review triggers.
An AMI is also specific to region, operating system, processor architecture, root volume type, and virtualization type (Amazon Machine Images in Amazon EC2). A pin that was correct in one region may not be portable to another without a copy step, and a pin that was correct for one instance family may not be valid for a replacement. The record should name the scope of the pin, not just the ID.
A minimal ADR skeleton for an AMI pin
The following template is deliberately short. It is meant to be written in the same pull request that changes the launch template, or in the same week the pin is discovered. It is not a design document.
# ADR-00X: Pin service-name to AMI ami-xxxxxxxxxxxxxxxxx
## Status
Proposed | Accepted | Superseded by ADR-00Y
## Date
YYYY-MM-DD
## Context
- Service: service-name (repo, environment, region)
- Launch mechanism: launch template lt-xxxx / Auto Scaling group asg-xxxx
- Current AMI: ami-xxxxxxxxxxxxxxxxx, created YYYY-MM-DD
- What forced the pin: (one or two sentences, specific)
- What was tried and rejected: (optional, one line each)
- What we do not know: (state it plainly)
## Decision
Launch service-name from ami-xxxxxxxxxxxxxxxxx in region rrrr.
Scope: launch template lt-xxxx only. Other services are not covered.
## Consequences
- Moving the AMI requires: (named check, named owner)
- If the AMI is deprecated: launch template continues to work; review still required
- Snapshot cost continues until deregistration
- Related runbook: (link)
- Related restore drill evidence: (link, if any)
## Review trigger
- AMI deprecation date: YYYY-MM-DD (from describe-images)
- Review owner: name or rotation
- Next review: YYYY-MM-DD or on trigger, whichever first
Two fields carry most of the weight. The context field is where the reason lives, and the review trigger field is what keeps the record from becoming archaeology. The rest is bookkeeping.
Keep the record honest about what it does not know
If the original reason for the pin is lost, say so in the context section. Write “the reason for the original pin is not recorded; this ADR captures the current state and schedules an investigation” rather than inventing a plausible cause. A record that admits ignorance is more useful than one that fabricates certainty, because the first review can then be scoped as an investigation rather than a ratification.
The same applies to resilience claims. A pinned AMI is not a backup, and a decision record is not a restore drill. If the service depends on a database, the record should link to the restore evidence separately rather than implying that the pin provides it. The recovery checklist is the right companion document for that side of the service; the ADR covers the image, not the data.
Proposed, accepted, superseded
AWS Prescriptive Guidance is explicit about lifecycle. When the team accepts an ADR, it becomes immutable. If new insights require a different decision, the team proposes a new ADR, and when the new one is accepted it supersedes the previous one. The best-practices page adds that the owner should change the old ADR’s status to Superseded, note the changes in the new ADR’s change history, and keep the old ADR in the decision log (Best practices for using ADRs).
For a small team, this means one rule: do not edit an accepted pin record to reflect a new AMI. Write a new record, mark the old one Superseded, and link them. The old record is the audit trail that explains why the service ran on an old image for as long as it did. Editing it destroys the only evidence a future reviewer would have.
The Proposed state is also useful. A pin written under incident pressure can be marked Proposed, reviewed in ten to fifteen minutes at the next team sync, and then accepted or reworked. The AWS guidance suggests that a dedicated reading slot of that length is usually enough for review. That is a realistic commitment for a team of two to fifteen engineers without a dedicated reliability function.
Review triggers drawn from AMI lifecycle signals
A review trigger should be tied to evidence the team can actually observe. Three signals are available from AWS documentation and the console:
- Deprecation date. The deprecation time is visible in the console and returned by
describe-imagesasDeprecationTime. If the field is empty, the AMI is not deprecated or is set to deprecate at a future date. The record should carry the date, not a vague “review periodically.” - Last-used check. AWS notes that AMIs not used recently to launch an instance might be good candidates for deprecation or deregistration, and points to a last-used check. A pin that has not launched an instance in a year is a different decision than one that launches every deploy.
- Failed restore or failed launch. If a restore drill or a canary launch from the pinned AMI fails, that is a review trigger regardless of the calendar.
These signals do not tell the team whether to move the AMI. They tell the team when to look. The decision record supplies the context for that look.
What the record should not pretend to know
A decision record is not a security assessment. It should not claim that a pinned AMI is compliant, supported, or safe. The retrieved AWS documentation describes deprecation and lifecycle mechanics; it does not establish that any particular pin is appropriate. If the team has a vulnerability scan or a patch-level inventory, link it. If not, say that the record does not cover it.
Nor should the record claim a maximum safe duration for a pin. No source supports a specific number, and inventing one would turn a useful document into a false assurance. The honest formulation is: the pin remains in place until a named trigger fires or a named owner reviews it, and the record states both.
A checklist to paste into the repo
The smallest sustainable version of this practice is a checklist in the repository that owns the launch template:
- Does an ADR exist for the current AMI pin? If not, write one this week using the skeleton above.
- Does the context section name the forcing reason, or state plainly that it is unknown?
- Does the decision section name the AMI ID, region, and launch mechanism scope?
- Does the consequences section link to the runbook and to any restore drill evidence?
- Does the review trigger carry a deprecation date and a named owner?
- When the pin changes, is the old ADR marked Superseded rather than edited?
None of this requires a new tool. A Markdown file in the same repository as the launch template, reviewed in the same pull request, is enough. The point is not ceremony. The point is that the next engineer to open the launch configuration can read one page and know whether they are doing maintenance or making a decision.
Questions that come up
Is an AMI pin an architectural decision?
AWS Prescriptive Guidance lists dependencies and construction techniques among the decisions that warrant an ADR. A base image is a dependency and a construction technique at once. Whether a team treats every pin as architecturally significant is a judgment call, but a pin that has survived multiple launch-template revisions and whose rationale is unknown is a reasonable candidate.
What if the team has no ADR process at all?
Start with one record for the pin that is currently causing the most uncertainty. The AWS guidance recommends storing ADRs in a central location, either a Git repository for versioning or a wiki for accessibility. For a small team, the repository that owns the launch template is usually the lowest-friction choice.
Does deprecation force a migration?
No. AWS documents that launch templates and Auto Scaling groups can continue to reference deprecated AMIs, and that instances launched from a deprecated AMI are not affected. Deprecation is a signal, not a deadline enforced by the platform. The record should treat it as a review trigger, not an automatic change.
Should the record include the AMI creation date and patch level?
Yes, where known. The creation date is available from the AMI metadata. Patch level is only meaningful if the team records it at build time; if it is not recorded, the context section should say so rather than guess. The record’s value depends on distinguishing what was observed from what was assumed.
How does this relate to backup and restore drills?
They are separate decisions with separate evidence. The AMI pin governs what software boots; the restore drill governs whether data can be recovered. Link them, but do not let one stand in for the other. A service can have a perfectly documented AMI pin and an untested restore path, or the reverse.
The pin will be revisited eventually, whether by a planned review or by an incident. The decision record determines which of those it is.