Ctrl K
ComunidadGuías…

da-cli

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env python

# Before running this script, make sure boto3 is installed:
# sudo apt-get install python-boto3
# or
# sudo pip install boto3

keyPair = 'ec2.pem'
serviceApp = 'app'
serviceBackend = 'backend'
targetGroupWeb = 'web'
targetGroupWebSocket = 'websocket'
targetGroupRedirect = 'http-redirect'
autoScalingGroup = 'docassembleAsg'

import boto3
import time
import sys
import copy

def available_instances():
    instances = list()
    statuses = ec2.describe_instance_status()
    for status in statuses['InstanceStatuses']:
        if status['InstanceStatus']['Status'] == 'ok' and status['SystemStatus']['Status'] == 'ok':
            instances.append(status['InstanceId'])
    return instances

def instances_for_service(service):
    instances = list()
    for taskarn in ecs.list_tasks(serviceName=service).get('taskArns', list()):
        for item in ecs.describe_tasks(tasks=[taskarn]).get('tasks', list()):
            for instance in ecs.describe_container_instances(containerInstances=[item['containerInstanceArn']]).get('containerInstances', list()):
                instances.append(instance['ec2InstanceId'])
    return instances

def get_target_groups():
    result = {}
    for tg in elb.describe_target_groups().get('TargetGroups', list()):
        result[tg['TargetGroupName']] = tg['TargetGroupArn']
    return result

def get_registered_targets(targetgroup):
    instances = list()
    for target in elb.describe_target_health(TargetGroupArn=targetgroup).get('TargetHealthDescriptions', list()):
        instances.append(target['Target']['Id'])
    return instances

def get_service_status(servicename):
    return ecs.describe_services(services=[servicename])['services'][0]

def update_desired_count(service, desired_count):
    ecs.update_service(service=service, desiredCount=int(desired_count))
    while True:
        result = get_service_status(service)
        if result['desiredCount'] != result['runningCount']:
            time.sleep(2)
        else:
            break

def fix_registered_instances():
    target_groups_arns = get_target_groups()
    web_servers = get_registered_targets(target_groups_arns[targetGroupWeb])
    web_sockets_servers = get_registered_targets(target_groups_arns[targetGroupWebSocket])
    for server in web_servers:
        if server not in web_sockets_servers:
            elb.register_targets(TargetGroupArn=target_groups_arns[targetGroupWebSocket], Targets=[{'Id': server}])
    http_servers = get_registered_targets(target_groups_arns[targetGroupRedirect])
    for server in web_servers:
        if server not in http_servers:
            elb.register_targets(TargetGroupArn=target_groups_arns[targetGroupRedirect], Targets=[{'Id': server}])

def start_up(the_count=1):
    the_count = int(the_count)
    print "Creating EC2 instances"
    update_ec2_instances(the_count + 1)
    print "Updating backend count"
    update_desired_count(serviceBackend, 1)
    print "Updating app count"
    update_desired_count(serviceApp, the_count)
    print "Waiting for targets to be registered"
    target_groups_arns = get_target_groups()
    while True:
        web_servers = get_registered_targets(target_groups_arns[targetGroupWeb])
        if len(web_servers) >= the_count:
            break
        time.sleep(2)
    print "Registering targets for target group " + str(targetGroupWebSocket)
    fix_registered_instances()

def shut_down():
    print "Updating app count"
    update_desired_count(serviceApp, 0)
    print "Updating backend count"
    update_desired_count(serviceBackend, 0)
    print "Terminating EC2 instances"
    update_ec2_instances(0)

def connect_string(service):
    for instance_id in instances_for_service(service):
        print "ssh -i " + keyPair + " ec2-user@" + ec2.describe_instances(InstanceIds=[instance_id])['Reservations'][0]['Instances'][0]['PublicDnsName']

def update_ec2_instances(desired_count):
    autoscale.set_desired_capacity(AutoScalingGroupName=autoScalingGroup, DesiredCapacity=int(desired_count))
    while True:
        result = autoscale.describe_auto_scaling_groups(AutoScalingGroupNames=[autoScalingGroup])['AutoScalingGroups'][0]
        if result['DesiredCapacity'] != len(result['Instances']):
            time.sleep(2)
        else:
            break
    while True:
        if len(available_instances()) < int(desired_count):
            time.sleep(2)
        else:
            break

def shutdown_unused_ec2_instances():
    all_instances = available_instances()
    used_instances = list()
    used_instances.extend(instances_for_service(serviceBackend))
    used_instances.extend(instances_for_service(serviceApp))
    for instance in all_instances:
        if instance in used_instances:
            continue
        autoscale.terminate_instance_in_auto_scaling_group(InstanceId=instance, ShouldDecrementDesiredCapacity=True)
    while True:
        result = autoscale.describe_auto_scaling_groups(AutoScalingGroupNames=[autoScalingGroup])['AutoScalingGroups'][0]
        if result['DesiredCapacity'] != len(result['Instances']):
            time.sleep(2)
        else:
            break

dispatch = {'shutdown_unused_ec2_instances': shutdown_unused_ec2_instances, 'update_ec2_instances': update_ec2_instances, 'connect_string': connect_string, 'shut_down': shut_down, 'start_up': start_up, 'fix_registered_instances': fix_registered_instances, 'update_desired_count': update_desired_count}

arguments = copy.deepcopy(sys.argv)

this_file = arguments.pop(0)

def error_message():
    print "usage: " + str(this_file) + " <command>\nThe <command> can be one of: " + ', '.join(dispatch.keys())

if len(arguments) == 0:
    error_message()
    sys.exit(1)

command = arguments.pop(0)
if command not in dispatch:
    error_message()
    sys.exit(1)

ec2 = boto3.client('ec2')
ecs = boto3.client('ecs')
elb = boto3.client('elbv2')
autoscale = boto3.client('autoscaling')

dispatch[command](*arguments)