Created
September 1, 2016 15:23
-
-
Save charlesmims/e92a12d1d53ac54485ccd74620e7a6a3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# @charlesmims 2015 | |
# Maintains a number of coreOS hosts running in ec2. Can be used to scale up by increasing NUM_NODES, | |
# but in present state will not scale down cleanly. | |
import boto.ec2 | |
import time | |
from os import environ | |
from collections import defaultdict | |
from jinja2 import Template | |
import sys | |
ACCESS = environ['AWS_KEY'] | |
SECRET = environ['AWS_SECRET'] | |
if len(sys.argv) > 1: | |
TOKEN = sys.argv[1] | |
print "using token %s" % TOKEN | |
else: | |
TOKEN = environ['ELK_TOKEN'] | |
print "using ELK_TOKEN %s" % TOKEN | |
REGION = environ['ELK_REGION'] | |
AMI = environ['ELK_AMI'] | |
KEY = environ['ELK_KEY'] | |
TYPE = environ['ELK_TYPE'] | |
GROUPS = [environ['ELK_GROUP']] | |
SUBNET_ID = environ['ELK_SUBNET'] | |
NUM_NODES = int(environ['ELK_NUM_NODES']) | |
DISK = environ['ELK_DISK'] | |
# block device mapping stuff for creating instance with larger EBS drive than default | |
dev_xvda = boto.ec2.blockdevicemapping.BlockDeviceType() | |
dev_xvda.size = DISK # size in Gigabytes | |
bdm = boto.ec2.blockdevicemapping.BlockDeviceMapping() | |
bdm['/dev/xvda'] = dev_xvda | |
# template stuff for rendering cloud init user data | |
cloud_config = """#cloud-config | |
hostname: coreos{{ instance_num }} | |
coreos: | |
etcd2: | |
name: coreos{{ instance_num }} | |
discovery: https://discovery.etcd.io/{{ token }} | |
# multi-region and multi-cloud deployments need to use $public_ipv4 | |
advertise-client-urls: "http://$private_ipv4:2379" | |
initial-advertise-peer-urls: "http://$private_ipv4:2380" | |
listen-client-urls: "http://0.0.0.0:2379,http://0.0.0.0:4001" | |
listen-peer-urls: "http://$private_ipv4:2380,http://$private_ipv4:7001" | |
units: | |
- name: etcd2.service | |
command: start | |
- name: fleet.service | |
command: start | |
""" | |
template = Template(cloud_config) | |
# establish connection to ec2 | |
print "connecting to aws..." | |
conn = boto.ec2.connect_to_region(REGION, aws_access_key_id=ACCESS, aws_secret_access_key=SECRET) | |
# get the currently running instances tagged with Name: coreos* | |
print "getting coreos instances... ", | |
instance_tags = [] | |
reservations = conn.get_all_instances(filters={'tag:Name':'coreos*','instance_state_name':'running'}) | |
for reservation in reservations: | |
instance = reservation.instances[0] | |
instance_tag = instance.tags['Name'] | |
instance_tags.append(instance_tag) | |
print len(instance_tags), "of", NUM_NODES, "found" | |
if len(instance_tags) < NUM_NODES: | |
print "launching %i ec2 instances..." % (NUM_NODES - len(instance_tags)) | |
# take list of instance tags down to just numbers so we can compare it against a range | |
instance_tags.sort() | |
instance_numbers = [int(x.split('coreos')[1]) for x in instance_tags] | |
# compare it against a range | |
missing_instance_numbers = [] | |
for n in range(NUM_NODES): | |
if n not in instance_numbers: | |
missing_instance_numbers.append(n) | |
# print "missing nodes:", missing_instance_numbers | |
# launch new instances | |
for num in missing_instance_numbers: | |
reservation = conn.run_instances(image_id=AMI, key_name=KEY, instance_type=TYPE, security_group_ids=GROUPS, subnet_id=SUBNET_ID, | |
block_device_map=bdm, user_data=template.render(token=TOKEN, instance_num=num)) | |
instance = reservation.instances[0] | |
status = instance.update() | |
if status == 'terminated': | |
print instance.state_reason['message'] | |
while status == 'pending': | |
time.sleep(10) | |
status = instance.update() | |
if status == 'running': | |
print "coreos%s running" % num | |
tagged = 0 | |
while tagged == 0: | |
try: | |
instance.add_tag('Name', 'coreos%s' % num) | |
print "tagged instance coreos%s" % num | |
tagged = 1 | |
except: | |
time.sleep(5) | |
print 'coreos%s started at %s' % (num, instance.private_ip_address) | |
else: | |
print('Instance status: ' + status) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment