Amazon Web Services (AWS CodeDeploy): Auto Assignment of Elastic IP to green/blue deployment fleet replacement instances.

With a blue/green deployment, you provision a new set of instances on which CodeDeploy installs the latest version of your application. CodeDeploy then reroutes load balancer traffic from an existing set of instances running the previous version of your application to the new set of instances running the latest version. After traffic is rerouted to the new instances, the existing instances can be terminated. Blue/green deployments allow you to test the new application version before sending production traffic to it. If there is an issue with the newly deployed application version, you can roll back to the previous version faster than with in-place deployments. Additionally, the instances provisioned for the blue/green deployment will reflect the most up-to-date server configurations since they are new.

Problem with Blue/Green deployment is that once the fleet is replaces, if you had any EIP attached to the older instances, you have to manually reattch them to the new fleet. Here’s how it can be automated.

Before we start you need to have the following information ready.

  • Note the CodePipeline and CodeDeploy ID and Name
  • List Elastic IP addresses IDs i.e. eipalloc-0ff4f997b4cf990bd

Steps

Step 1: Create and IAM role with the following permissions to be used with Lambda function.

  • CodeDeploy
  • ListDeploymentInstances
  • GetDeploymentInstance
  • BatchGetDeploymentInstances
  • EC2
  • DescribeAddresses
  • AssociateAddress
  • DisassociateAddress

Here’s the policy document.

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"codedeploy:GetDeploymentInstance",
"ec2:DisassociateAddress",
"ec2:DescribeAddresses",
"codedeploy:ListDeploymentInstances",
"codedeploy:BatchGetDeploymentInstances",
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}

Step 2 : Create Lambda function with the following code associate the above role to the lambda function.

Note : Make sure to change the eip_list

import json
import boto3
import re
import sys, traceback
def lambda_handler(event, context):
print(event)
try:
eip_list = ["eipalloc-0ff4f997b4cf99dbd", "eipalloc-07e14e6c1ed2cazf4", "eipalloc-03af9573f88548zda"]
if event.get('detail'):
deployment_id = event.get('detail').get('deploymentId')
application_name = event.get('detail').get('application')
state = event.get('detail').get('state')
notification_type = event.get('detail-type')
if deployment_id and \
state == 'SUCCESS' and \
application_name == 'prodCodeDeploy' and \
notification_type == "CodeDeploy Deployment State-change Notification":
client = boto3.client('codedeploy')
ec2_client = boto3.client('ec2')
response = client.list_deployment_instances(deploymentId=deployment_id)
print('--------------list_deployment_instances response')
print(response)
if response.get('instancesList'):
instance_details = client.batch_get_deployment_instances(
deploymentId=deployment_id,
instanceIds=response.get('instancesList')
)
index = 0
for instance in instance_details['instancesSummary']:
if instance['instanceType'] == 'Green':
instance_id = re.findall(r'i-.[a-z0-9]*', instance['instanceId'])[0]
print("InstanceId="+instance_id+" and EIP id="+eip_list[index])
response = ec2_client.associate_address(
AllocationId=eip_list[index],
InstanceId=instance_id,
AllowReassociation=True,
DryRun=False,
)
print('--------------associate_address response')
print(response)
index += 1
return {
"statusCode": 200,
"body": json.dumps('IP Reassociation Successful')
}
except Exception as e:
traceback.print_exc()
return {
"statusCode": 400,
"body": json.dumps('IP Reassociation Failed')
}

Step 3: Create a CloudWatch EventsRule to trigger the lambda function.

  • Open AWS Console and goto CloudWatch.
  • From left pane select Events -> Rules
  • In the Event Source, select Event Pattern
  • Service Name : Select CodeDeploy
  • Event Type : State Change
  • Select Specific Detail Type(s) and Select CodeDeploy Deployment State-change Notification below.
  • Select Specific State(s) and Select SUCCESS
  • Select Specific application and select your CodeDeploy application from the list.
  • Select Any Deployment Group
  • The JSON config file should look like this.
{
"source": [
"aws.codedeploy"
],
"detail-type": [
"CodeDeploy Deployment State-change Notification"
],
"detail": {
"state": [
"SUCCESS"
],
"application": [
"<CodeDeploy App Name>"
]
}
}
  • On the Right section Targets select Lambda Function
  • Select the function we created as part of Step 2.
  • Click on Configure Details/Save and you are done.

Now you will never have to worry about attaching EIPs to you instances as part of blue green deployment.