Rolling update EC2 with Terraform

souzaxx profile image Lucas de Souza ・4 min read

This post is just an implementation of @endofcake's article. I'm going to show a real example on how to use the rolling update technique with EC2. If you want to get more background about the difference between Rolling Update and Blue/Green please check his post.


Extreme rolling techniques ahead. Proceed with caution.


Terraform can do Blue/Breen natively, just add create_before_destroy = true in the lifecycle block and the terraform will create the resource in a blue/green manner.

resource "azurerm_resource_group" "example" {
  # ...

  lifecycle {
    create_before_destroy = true
Fig.1 - Lifecycle block example.

In other to show this update I decided to create a really simple web page using Packer to create the images.

Speed things up with Packer

Before we dive into how to create rolling updates with terraform let's talk a little about Packer.

HashiCorp Packer aims to build automated machine images, which means, we can create scripts to configure images with our application inside, installing all the dependencies that our application needs.

In our example, we use Packer to build a very simple HTTP server. I created a simple script that will install Apache web server and create a web page with a specif background color ( you can choose the color, exciting isn't it? ).

To update the "version" of our application just change the color variable to any color of your preference. The default color of our web page is red.

variable "color" {
  default = "red"

I won't get into details of Packer in this post, but basically, Packer will create an EC2 instance, execute the scripts/basic-website.sh inside it, and take a snapshot of that instance, saving it as rolling_update_{{timestamp}}. The execution of this script is described in the provisioner block.

I know that isn't a good tutorial, but enough of Packer for now.


Rolling Update with Terraform

Well, here's the fun part. Terraform has no way to do this.


Terraform has no way to know if your application is alive nor to check what is the current version; because it was not built for this purpose.

Although we can configure health-checks on Targets Groups and Auto Scaling Groups, Terraform will not care if the application is healthy after finishing the apply phase.

In other to create the rolling update with Terraform we are going to use a little hack... We are going to use CloudFormation!


CloudFormation gives to Auto Scaling Group a really cool feature, the UpdatePolicy. This is a policy that is triggered every time that ASG is updated, which means if we launch a new version of a launch template we can trigger our ASG to update its instances.

We can take advantage of this CloudFormation automation and blend it into Terraform!


Ok, Lucas, @endofcake already explains all this to us.

Less talk and more code.


First, clone this git repository:

GitHub logo souzaxx / Rolling-Update-Terraform

Code example for RollingUpdate with Terraform and Packer

Create our first AMI going inside the packer folder.

cd packer
packer build .

Wait until the AMI is created

Alt Text

After that, go back to the root of the repository and apply the terraform.

cd ..
terraform init
terraform apply

To check that our web page is up and running gets the LoadBalancer DNS from Terraform output terraform output lb_dns and open it in your favorite browser or just curl it curl $(terraform output lb_dns).

Update the Image

In other to check the update progress, execute this loop in another terminal:

while true; do
curl $(terraform output lb_dns)
sleep 1

Now, create a new "version" of our application by choosing a color. You can overwrite the default variable passing -var 'color=green' into the packer CLI.

cd packer
packer build -var 'color=green' .

Wait for its completion and apply the terraform again:

cd ..
terraform apply

We can check that lauchconfiguration and cloudformation resources have changed.

Alt Text

Confirm the apply and check the curl loop to see the changes in realtime.



I hope this post was useful for your studies in Terraform and in my next post I want to show this process with a real application such as Consul.

Clean up

terraform destroy --auto-approve

and delete all the AMI created by Packer:
Alt Text

Thank you for your time and

Alt Text


Editor guide