Skip to content

Instantly share code, notes, and snippets.

@rubenmromero
Last active November 18, 2025 12:36
Show Gist options
  • Select an option

  • Save rubenmromero/865655a42824698d084c724268dc8581 to your computer and use it in GitHub Desktop.

Select an option

Save rubenmromero/865655a42824698d084c724268dc8581 to your computer and use it in GitHub Desktop.
Terraform :: EC2 instance replacement with no downtime
locals {
hostname = "foo-service"
}
resource "aws_route53_zone" "primary" {
name = "example.com"
}
resource "aws_instance" "foo" {
. . .
. . .
# Enable IMDSv2
metadata_options {
http_tokens = "required"
}
tags = {
Name = local.hostname
terraform = "True"
}
lifecycle {
create_before_destroy = true
}
}
# Gate that enforces a wait before old instance is destroyed
resource "time_sleep" "foo_destroy_instance_gate" {
# Sleep happens on destroy of the old gate
destroy_duration = "190s"
lifecycle {
# Required to create the new EC2 instance before starting the replacement of this resource
create_before_destroy = true
# Recreate the gate whenever the instance is replaced
replace_triggered_by = [aws_instance.foo.id]
}
depends_on = [aws_instance.foo]
}
# Gate that enforces a wait before DNS record is updated
resource "time_sleep" "foo_update_dns_gate" {
# Sleep happens on create of the new gate
create_duration = "150s"
lifecycle {
# Required to create the new EC2 instance before starting the replacement of this resource
create_before_destroy = true
# Recreate the gate whenever the instance is replaced
replace_triggered_by = [aws_instance.foo.id]
}
depends_on = [aws_instance.foo]
}
resource "aws_route53_record" "foo" {
name = "${local.hostname}.${aws_route53_zone.primary.name}"
type = "A"
ttl = 30
zone_id = aws_route53_zone.primary.zone_id
records = [aws_instance.foo.public_ip]
# Enforce that DNS record is not updated until
# foo_update_dns_gate is replaced
depends_on = [time_sleep.foo_update_dns_gate]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment