Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Blue Green Deploys with Terraform

Terraform Blue-Green Deploy example

Note: Use Terraform Modules as functions!!!

This will allow you to create a "networking" module, and use those outputs to populate the security groups, access zones, and subnet id's for your other modules.

Using autoscaling groups with a fixed size will protect you from AWs bugs or instance outages. This way an instance that dies, will be replaced so you always maintain the expected amount of instances for that service.

Workflow:

Given that 'blue-ami-id' = 2; green-ami-id = 1; blue-nodes = 3; and green-nodes = 0

  • Create a new AMI using Packer (pretend this has an ami-id = 3
  • Update green-ami-id to equal 3
  • Slowly scale up green-nodes, using green-nodes as a canary for the new service version
  • Once health checks (whatever user requires: consul, sensu, nagios, etc) pass
  • Slowly scale down blud-nodes to 0.

If everything checks out, you've just rolled instances with Terraform using a Blue-Green deploy!

// Note: Actual filepath for this file would be './awesome-service/main.tf'
variable "security_group" { }
variable "vpc_id" { }
variable "azs" { }
variable "subnet_ids" { }
variable "ami_blue" { }
variable "ami_green" { }
variable "nodes_blue" { }
variable "nodes_green" { }
// BLUE Resources
resource "aws_launch_configuration" "awesome-service-blue" {
image_id = "${var.ami_blue}"
instance_type = "t2.small"
key_name = "${var.key_name}"
security_groups = ["${var.security_group}"]
}
resource "aws_autoscaling_group" "awesome-service-blue" {
name = "awesome-service-blue - ${aws_launch_configuration.awesome-service-blue.name}"
launch_configuration = "${aws_launch_configuration.awesome-service-blue.name}"
desired_capacity = "${var.nodes_blue}"
min_size = "${var.nodes_blue}"
max_size = "${var.nodes_blue}"
availability_zones = ["${split(",", var.azs)}"]
vpc_zone_identifier = ["${split(",", var.subnet_ids)}"]
}
// Green Resources
resource "aws_launch_configuration" "awesome-service-green" {
image_id = "${var.ami_green}"
instance_type = "t2.small"
key_name = "${var.key_name}"
security_groups = ["${var.security_group}"]
}
resource "aws_autoscaling_group" "awesome-service-green" {
name = "awesome-service-green - ${aws_launch_configuration.awesome-service-green.name}"
launch_configuration = "${aws_launch_configuration.awesome-service-green.name}"
desired_capacity = "${var.nodes_green}"
min_size = "${var.nodes_green}"
max_size = "${var.nodes_green}"
availability_zones = ["${split(",", var.azs)}"]
vpc_zone_identifier = ["${split(",", var.subnet_ids)}"]
}
module "my-awesome-service" {
source = "./awesome-service
ami_blue = "<blue_ami_id>"
ami_green = "<green_ami_id>"
nodes_blue = <number_of_blue_nodes>
nodes_green = <number_of_green_nodes>
azs = "${var.azs}" // Use an output from another module for this
subnet_ids = "${var.subnet_ids}" // Use an output from another module for this
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment