Refreshing AWS Autoscaling With Lambdas

Wouter van der Meulen
Wouter van der Meulen
Nov 5 2021
Posted in Engineering & Technology

A guide to running AWS Instance Refresh using Lambdas

Refreshing AWS Autoscaling With Lambdas

In my previous blog post, I talked about automatically building Packer configurations with CodePipeline. In this post, we'll expand on that by connecting the successful build to a Lambda function that will refresh an Autoscaling Group with the new AMI.

Prerequisites

This post will focus on setting up a Lambda function and connecting it to the success message of the CodePipeline build. It will assume you have knowledge of setting up an EC2 Launch Template and Autoscaling Groups.

What you will need in order to implement this guide.

  • a CodePipeline that builds a new AMI
  • a Launch Template using the AMI
  • a Autoscaling Group implementing that Launch Template

Setting up a Lambda

This example Lambda is really basic. It doesn't do anything more than look for the new AMI based on the Name tag you have given it. After that, it creates a new Launch Template using the new AMI ID and runs the start_instance_refresh function on the Autoscaling Group.

Please note that the Autoscaling Group should be configured to use the latest Launch Template:

require 'aws-sdk-ec2'
require 'aws-sdk-autoscaling'
require 'json'

def lambda_handler(event=nil, context=nil)
  # Initialize required clients
  ec2 = Aws::EC2::Client.new
  auto_scaling = Aws::AutoScaling::Client.new

  # Search for AMI's with our name
  images = ec2.describe_images(
    owners: ['self'],
    filters: [
      {
        name: "tag:Name",
        values: [ENV['AMI_NAME']]
      },
  ])

  # Select the latest AMI
  latest_image =  images.images.sort_by(&:creation_date).last

  # Create a new template
  template = ec2.create_launch_template_version(
    launch_template_id: ENV['LAUNCHTEMPLATE'],
    source_version: "$Latest",
    version_description: "Latest AMI, from Lambda",
    launch_template_data: {
        image_id: latest_image.image_id
    }
  )

  # Start instance refresh on Autoscaling group
  auto_scaling.start_instance_refresh({
    auto_scaling_group_name: ENV['AUTOSCALE_GROUP_NAME'],
    preferences: {
      instance_warmup: 400,
      min_healthy_percentage: 50,
    },
  })

end

As for the ENV variables in the script, define those in the Lambda's configuration tab:

Setting up notifications

To connect the CodePipeline to Lambda we'll need CodePipeline to notify an SNS topic.

First off, create a new Notification Rule in the CodePipeline:

The only event we're interested in is the succeeded pipeline:

To make things easy, let AWS create a new SNS topic for you:

On the Lambda configuration page, add a Trigger on the newly created SNS topic. This automatically adds a subscription to the SNS topic:

And there you have it. The Lambda is triggered anytime the Pipeline has run successfully and will update the LaunchTemplate and refresh the AutoScaling group for you. This means that your instances will automatically be updated to the latest AMI when they are ready.

As always, you can find us available, for any question you might have, via our Support Channel.

Keep up-to-date with the latest news