infra/modules/lambda/ecs-unprotect-lambda/index.py (54 lines of code) (raw):
from __future__ import print_function
import boto3
import logging
import os
logging.basicConfig()
logger = logging.getLogger()
logger.setLevel(logging.INFO)
# Establish boto3 session
session = boto3.session.Session()
logger.debug("Session is in region %s ", session.region_name)
ecsClient = session.client(service_name='ecs')
asgClient = session.client('autoscaling')
clusterName = os.getenv('ECS_CLUSTER_NAME', 'teamcity-sandbox')
asgGroupName = os.getenv('ASG_GROUP_NAME', 'teamcity-sandbox-ecs-asg')
def env_to_num(env, default):
try:
return int(os.getenv(env, default))
except ValueError:
return default
retainInstances = env_to_num('RETAIN_INSTANCES',0)
def lambda_handler(event, context):
logger.info("Start lambda function")
# Get list of container instance IDs from the clusterName
clusterListResp = ecsClient.list_container_instances(cluster=clusterName)
# Get list of describe container instances from the clusterName
descrInsts = ecsClient.describe_container_instances(
cluster=clusterName,
containerInstances=clusterListResp['containerInstanceArns'],
)
# Get ARN list of instances without any tasks
idleInstances = []
for containerInstance in descrInsts['containerInstances']:
runTask = containerInstance['runningTasksCount']
pendTask = containerInstance['pendingTasksCount']
ec2InstanceId = containerInstance['ec2InstanceId']
status = containerInstance['status']
logger.debug("Instance %s has %s tasks" , ec2InstanceId, runTask + pendTask)
if status == 'ACTIVE' and runTask + pendTask == 0:
idleInstances.append(containerInstance)
logger.info("Cluster %s has %s idle instances", clusterName, len(idleInstances))
# Save idle instance
idleInstances = idleInstances[retainInstances:]
# Delete instance protection for autoscaling group
for containerInstance in idleInstances:
logger.info("Unprotect instances %s", containerInstance['ec2InstanceId'])
# Make API calls to set DRAINING and unset ScaleIn protection
try:
response = ecsClient.update_container_instances_state(
cluster=clusterName,
containerInstances=[containerInstance['containerInstanceArn']],
status='DRAINING'
)
logger.debug("Response received from update_container_instances_state %s",response)
response = asgClient.set_instance_protection(
InstanceIds=[containerInstance['ec2InstanceId']],
AutoScalingGroupName=asgGroupName,
ProtectedFromScaleIn=False
)
logger.debug("Response received from set_instance_protection %s",response)
except Exception, e:
logger.error(str(e))