# AutoScalingInstanceRefresh in CloudFormation: Pattern Teardown

The integration of Instance Refresh as a native CloudFormation update policy closes an operational gap that forced teams to orchestrate AMI deployments outside the IaC lifecycle. In this article, I dissect the pattern's anatomy, its real failure modes, and when it is — and is not — the right choice for high-criticality environments.

- URL: https://fernando.moretes.com/blog/autoscalinginstancerefresh-no-cloudformation-dissecando-o-padrao-amazon-ec2-a

- Markdown: https://fernando.moretes.com/blog/autoscalinginstancerefresh-no-cloudformation-dissecando-o-padrao-amazon-ec2-a/article.md?lang=en

- Published: 2026-07-30T09:03:21.031Z

- Category: AI & Agents

- Tags: ec2-auto-scaling, cloudformation, instance-refresh, deployment-patterns, iac, reliability, financial-grade, devops

- Reading time: 9 min

- Source: [Amazon EC2 Auto Scaling now supports Instance Refresh in CloudFormation](https://aws.amazon.com/about-aws/whats-new/2026/07/ec2-auto-scaling-instance-refresh-cloudformation)

---

For years, updating instances in an Auto Scaling Group via CloudFormation meant choosing between two evils: `AutoScalingRollingUpdate` — rigid, checkpoint-free, blind to application alarms — or orchestrating Instance Refresh outside the stack, breaking IaC atomicity and creating silent drift. As of July 2026, `AutoScalingInstanceRefresh` as a native update policy resolves that problem. But "resolves" does not mean "use without thinking". This is a pattern teardown.

## The Problem This Pattern Solves

Consider the typical EC2 fleet lifecycle in a financial environment: the security team publishes a new hardened AMI with critical CVE patches, and the platform team needs to propagate that AMI to all production ASGs with zero downtime, auditable rollback, and without violating availability SLOs. Before this integration, the real workflow looked like this: CloudFormation would update the Launch Template or Launch Configuration, but the `AutoScalingRollingUpdate` policy had no visibility into CloudWatch alarms and no support for checkpoints with bake time. The alternative was triggering Instance Refresh via CLI or SDK in a separate pipeline — which created a state where the CloudFormation stack was "green" but running instances still used the old AMI. That drift between declared state and real state is a serious compliance risk in regulated environments like PCI-DSS and SOC 2.

The compounded problem was rollback: with `AutoScalingRollingUpdate`, a stack rollback did not revert already-replaced instances. With Instance Refresh outside the stack, rollback was manual and lacked traceability in Change Management. The new `AutoScalingInstanceRefresh` policy addresses both: the refresh is triggered automatically when properties requiring instance replacement change in the stack, and rollback is handled by the CloudFormation stack rollback itself — keeping declarative state as the single source of truth.

## AutoScalingInstanceRefresh Lifecycle in CloudFormation

Full flow from IaC change to rollback, showing checkpoints, alarms, and the launch-before-terminate strategy

### 🛠️ IaC / CI-CD

- Git Commit AMI / LT change (ci)
- CloudFormation Stack Update (ci)

### 🔄 Instance Refresh Engine

- AutoScalingInstanceRefresh UpdatePolicy (compute)
- Launch-Before- Terminate (compute)
- ReplaceRootVolume (in-place) (storage)
- Checkpoint + Bake Time (compute)

### 📊 Observability / Gates

- CloudWatch Alarm (abort condition) (security)
- ELB Health Check (in-service gate) (network)

### ✅ / ↩️ Outcome

- Stack UPDATE_COMPLETE All instances refreshed (compute)
- CFN Stack Rollback Previous LT restored (ci)

### Flows

- git -> cfn: push / pipeline
- cfn -> policy: detects property change
- policy -> lbt: default strategy
- policy -> rrv: in-place strategy
- lbt -> chk: after % of instances
- chk -> alarm: evaluates alarms during bake time
- elb -> lbt: health gate
- alarm -> success: alarms OK
- alarm -> rollback: alarm triggered → abort
- rollback -> cfn: stack reverts previous LT

## Pattern Anatomy: What Actually Happens Under the Hood

When CloudFormation detects a change in properties requiring instance replacement — such as `ImageId` in the Launch Template or `InstanceType` — and the stack is configured with `AutoScalingInstanceRefresh`, it delegates the replacement process to the Auto Scaling Instance Refresh engine instead of managing instance lifecycle directly. This is an important architectural distinction: CloudFormation becomes an intent orchestrator, not a replacement executor.

The Instance Refresh engine supports two main strategies in this integration. The first is `Launch-Before-Terminate` (LBT): new instances are launched and validated as `InService` in the target group before old ones are terminated. This requires temporary additional capacity — typically 10% to 100% above `DesiredCapacity`, configurable via `MinHealthyPercentage` and `MaxHealthyPercentage`. For fleets with large instances (r6i.8xlarge, for example), the cost of that extra capacity during refresh needs to be planned. The second strategy is `ReplaceRootVolume`, announced in November 2025, which replaces the instance's root volume without terminating it — useful when the instance's ephemeral state (long TCP connections, warm caches) has a high reconstruction cost.

Checkpoints with bake time are the most valuable gate mechanism: you define progress percentages (e.g., 20%, 50%, 100%) and a `BakeTimeSeconds` at each checkpoint. During bake time, the refresh pauses and evaluates CloudWatch alarms configured as abort conditions. If any configured alarm is in `ALARM` state, the Instance Refresh is aborted and CloudFormation initiates a stack rollback — restoring the previous Launch Template as declared state. ASG scaling policies and health checks remain active throughout the process, meaning load-reactive auto scaling continues functioning even during the refresh.

## Comparison: ASG Update Policies in CloudFormation
| Criterion | Criterion | AutoScalingRollingUpdate | AutoScalingReplacingUpdate | AutoScalingInstanceRefresh (new) |
| --- | --- | --- | --- | --- |
| Checkpoints with bake time | ❌ Not supported | ❌ Not supported | ✅ Supported | — |
| CloudWatch alarms as gate | ❌ Not supported | ❌ Not supported | ✅ Automatic abort | — |
| Launch-Before-Terminate | Partial (MinInstancesInService) | ❌ Recreates entire ASG | ✅ Native and configurable | — |
| Scaling policies active during update | ⚠️ May conflict | ❌ ASG recreated | ✅ Remain active | — |
| Replace Root Volume (in-place) | ❌ Not supported | ❌ Not supported | ✅ Supported | — |
| Rollback via CFN stack | ⚠️ Partial (does not revert already-replaced instances) | ✅ Recreates previous ASG | ✅ Integrated stack rollback | — |
| Extra capacity cost | Low (batch size) | High (duplicated ASG) | Medium (configurable by %) | — |

## When to Use This Pattern: The Context That Justifies the Choice

This pattern is the right choice when three conditions overlap: (1) the EC2 fleet is fully managed via CloudFormation as the source of truth, (2) the update process needs observable quality gates — error rate alarms, P99 latency, application health checks — before progressing, and (3) rollback needs to be auditable and traceable in the same Change Management system that records the IaC change.

In the financial context, this translates directly to AMI patch pipelines for transaction processing fleets, high-throughput SQS queue workers, or batch instances running nightly reconciliation jobs. In these cases, `BakeTimeSeconds` at each checkpoint is not bureaucracy — it is the time needed for business metrics like transaction approval rate or message throughput to stabilize before continuing the rollout. A reasonable value for financial production environments is 300-600 seconds per checkpoint, with alarms based on custom metrics published via `PutMetricData`.

The `ReplaceRootVolume` strategy deserves special attention for instances with valuable ephemeral state: L2 cache servers that take 15-20 minutes to warm up, or instances with persistent database connection pools that have measurable reconnection costs. In that case, replacing only the root volume — preserving the instance, its IP, its connections, and its in-memory state — significantly reduces the operational impact of patching. The trade-off is that you do not get the guarantee of a completely clean environment that instance replacement provides, which may be relevant for compliance in some frameworks.

## Anti-Patterns: When This Mechanism Will Work Against You

- **Using without abort alarms configured**: The core value of `AutoScalingInstanceRefresh` is the ability to stop automatically when business metrics degrade. Configuring the policy without `AlarmSpecification` is equivalent to doing a blind rolling update — you lose the pattern's differentiator and still carry the additional complexity.
- **Applying to ASGs with `DesiredCapacity` = 1**: With a single instance, any refresh strategy requiring healthy instances before terminating old ones will block indefinitely or force a downtime window. For singletons, use Blue/Green with two ASGs or accept an explicit maintenance window.
- **Confusing stack rollback with rollback of already-live instances**: CloudFormation rollback restores declared state (Launch Template, ASG configurations), but instances that were already successfully replaced before the abort are not automatically reverted to the previous AMI. Rollback prevents more instances from being updated, but the fleet state may be mixed.
- **Using `ReplaceRootVolume` for kernel patches or updates requiring reboot**: The in-place strategy replaces the volume but does not restart the instance by default. If the patch requires a reboot to take effect (kernel updates, drivers), you will have instances with the new volume but running the old kernel in memory — an inconsistent state that is hard to detect without explicit instrumentation.
- **Ignoring cost impact on large fleets with `launch-before-terminate`**: On a fleet of 200 r6i.4xlarge instances with `MaxHealthyPercentage` of 110%, you will have up to 20 extra instances running simultaneously during the refresh. At ~$1.01/hour per instance, this can represent $20/hour in additional cost. For refreshes taking 4-6 hours on large fleets, the cost needs to be planned and approved.
- **Using this pattern as a Blue/Green substitute for application deploys**: Instance Refresh is an infrastructure update mechanism (AMI, instance type, launch configuration). For application code deploys on EC2 fleets, Blue/Green with two ASGs and an ALB still offers cleaner isolation, granular traffic shifting, and instant rollback. Mixing the two contexts creates operational confusion.

## Reference Design for Financial Environments: Concrete Configuration

For a typical financial environment — transaction processing worker fleet, 99.9% availability SLO, deploy window approved by the Change Advisory Board — the configuration I would use for `AutoScalingInstanceRefresh` as an update policy combines the following elements:

**Strategy**: `Launch-Before-Terminate` with `MinHealthyPercentage: 90` and `MaxHealthyPercentage: 110`. This ensures at least 90% of nominal capacity is always available and limits extra capacity to 10% — a reasonable trade-off between refresh speed and cost.

**Checkpoints**: Three checkpoints at 25%, 50%, and 100% of the fleet, with `BakeTimeSeconds: 300` at each. Abort alarms should include: (1) a composite alarm of P99 transaction API latency above 500ms for 3 consecutive 60-second periods, (2) ALB 5xx error rate above 0.5% for 2 periods, and (3) a custom business alarm based on `PutMetricData` monitoring the transaction approval rate — the most important one, because it is the only one that captures silent application failures that do not manifest as HTTP errors.

**IAM**: The CloudFormation role needs `autoscaling:StartInstanceRefresh`, `autoscaling:DescribeInstanceRefreshes`, and `autoscaling:CancelInstanceRefresh`. Use an `aws:ResourceTag` condition to restrict the action to ASGs tagged `Environment: production` only — preventing an accidental change in a dev stack from triggering a production refresh.

**Observability**: Configure an EventBridge rule on `EC2 Auto Scaling` events of type `EC2 Instance Refresh Status Change` to send notifications to the operations channel and record in the Change Management system. This closes the audit loop: the IaC change, refresh progress, and final outcome are all traceable without manual intervention.

**Encryption**: If the new AMI uses a different KMS key than the previous AMI (annual key rotation, for example), ensure the instance profile has `kms:Decrypt` and `kms:GenerateDataKey` for the new key before starting the refresh — otherwise, new instances will fail to boot and the refresh will abort after exhausting retries, potentially leaving the fleet in a mixed state.

## AWS Well-Architected Lens

- **security**: CloudFormation integration keeps least privilege centralized: the CFN role is the only principal that needs Instance Refresh permissions. Combine with SCPs that deny `autoscaling:StartInstanceRefresh` for any principal other than the CloudFormation role in production accounts. Validate the new AMI's KMS key before deploy to avoid silent boot failures.
- **reliability**: Checkpoints with bake time and abort alarms transform the deploy into a continuous verification process, not a leap of faith. Keeping scaling policies active during refresh ensures the ASG continues responding to load spikes even during the update — eliminating the vulnerability window that existed with `AutoScalingReplacingUpdate`.
- **performance**: The `ReplaceRootVolume` strategy preserves warm caches and persistent connections, reducing the performance impact of patching on instances with valuable ephemeral state. For high-throughput fleets, calibrate `InstanceWarmupSeconds` to the application's real warm-up time — underestimates cause false positives in health checks and abort the refresh prematurely.

> **Calibrate `InstanceWarmupSeconds` with real data, not intuition:** The most common mistake I see in Instance Refresh implementations is setting `InstanceWarmupSeconds` to an arbitrary value (300 seconds is the default that appears in documentation examples). In practice, measure your application's real warm-up time: from the moment the instance is marked `InService` in the target group to when it reaches nominal throughput. Do this with per-instance `RequestCount` metrics in the ALB. If the real warm-up is 180 seconds but you configured 60, the Instance Refresh will consider the instance ready before it actually is — and abort alarms will fire at the next checkpoint, causing an abort that seems inexplicable without this instrumentation.

## What This Integration Does Not Solve: Pattern Boundaries

It is important to be honest about what this pattern does not do, especially to prevent teams from adopting it with wrong expectations. First, `AutoScalingInstanceRefresh` is not an application deployment mechanism. It operates at the infrastructure layer — AMI, instance type, launch configuration. If you need code deployments with granular traffic shifting (e.g., 5% → 25% → 100% with Canary analysis), CodeDeploy with `AllAtOnce`, `HalfAtATime`, or custom strategies is still the right tool, possibly in conjunction with Instance Refresh for the AMI layer.

Second, CloudFormation-integrated rollback is not instantaneous. Stack rollback initiates cancellation of the ongoing Instance Refresh, but already-successfully-replaced instances are not automatically reverted. In a scenario where 40% of the fleet was updated before the abort, you will have 40% of instances running the new AMI and 60% running the old one — a mixed state that can be problematic for applications that are not compatible with mixed versions. This is fundamentally different from Blue/Green, where rollback is a load balancer weight change.

Third, this pattern assumes CloudFormation is the source of truth for the ASG. In organizations where the ASG is partially managed via console, CLI, or external automations (emergency scaling scripts, for example), declared state may diverge from real state, and rollback behavior becomes unpredictable. Before adopting this pattern, ensure the ASG has drift detection enabled and that organizational policies prevent changes outside IaC.

Finally, the integration does not address the coordination problem between multiple ASGs that form a service. If you have an API server ASG and a worker ASG that need to be updated in a coordinated manner (e.g., new internal protocol version), `AutoScalingInstanceRefresh` on each independent stack does not guarantee ordering. For that case, Step Functions orchestrating multiple sequential stack updates is still the correct pattern.

> **Curator's Note:** In practice, what I would do immediately is migrate all AMI patch pipelines that currently trigger Instance Refresh via CLI outside CloudFormation to this new policy — the gain in traceability and rollback atomicity alone justifies the change. What I would not do is abandon custom business alarms in favor of only infrastructure health checks: in financial environments, an instance can be 'healthy' from the ELB's perspective and still process transactions with a high error rate due to a specific bug in the new AMI. The lesson I learned the hard way is that underestimated `InstanceWarmupSeconds` is the biggest cause of false aborts — measure before configuring, without exception.

## Verdict: Adopt with Deliberate Configuration

The `AutoScalingInstanceRefresh` as a native CloudFormation update policy is a genuine evolution for teams managing EC2 fleets via IaC. It closes the gap between declared state and real state that existed when Instance Refresh was orchestrated externally, and adds quality gates — checkpoints, bake time, abort alarms — that `AutoScalingRollingUpdate` never had. For financial environments with strict SLOs and auditability requirements, this integration is the correct way to patch AMIs in production.

The caveat is that the pattern's value is proportional to the quality of the configured abort alarms. Without well-calibrated business alarms, you have a more complex rolling update. With well-calibrated business alarms — transaction approval rate, P99 latency, message throughput — you have a deploy with continuous verification that can defend itself. Invest time in instrumentation before trusting the rollback mechanism.

Do not use this pattern as a Blue/Green substitute when instant rollback is a non-negotiable requirement, when multiple ASGs need to be coordinated, or when the ASG is not managed exclusively via CloudFormation. In those cases, the additional complexity of Blue/Green is justified by the isolation it provides.

**Rating:** Adote com configuração deliberada / Adop

## References

- [AWS What's New: EC2 Auto Scaling Instance Refresh in CloudFormation (Jul 29, 2026)](https://aws.amazon.com/about-aws/whats-new/2026/07/ec2-auto-scaling-instance-refresh-cloudformation)
- [CloudFormation UpdatePolicy Attribute — AutoScalingInstanceRefresh](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-updatepolicy.html#cfn-attributes-updatepolicy-instancerefresh)
- [AWS What's New: EC2 Auto Scaling Root Volume Replacement via Instance Refresh (Nov 2025)](https://aws.amazon.com/about-aws/whats-new/2025/11/amazon-ec2-auto-scaling-root-volume-replacement/)
- [EC2 Auto Scaling — Elastic Load Balancing Integration](https://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-load-balancer.html)
- [AWS What's New: Instance Refresh for Standby and Scale-In Protected Instances (Feb 2023)](https://aws.amazon.com/about-aws/whats-new/2023/02/amazon-ec2-auto-scaling-instance-refresh-standby-scale-in-protected-ec2/)
- [AWS Well-Architected Framework — Reliability Pillar](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/welcome.html)
