Skip to content

Instantly share code, notes, and snippets.

@omaciel
Created March 10, 2014 15:35
Show Gist options
  • Save omaciel/9467264 to your computer and use it in GitHub Desktop.
Save omaciel/9467264 to your computer and use it in GitHub Desktop.
import errno
import os
import socket
import sys
import time
from boto import ec2
# -----------------------------------------------------------------------------
# AMI definitions
# -----------------------------------------------------------------------------
VERSIONS = ('5.5', '5.6', '5.7', '5.8', '5.9',
'6.0', '6.1', '6.2', '6.3', '6.4')
ARCHITECTURES = ('32bit', '64bit')
REGIONS = (
'us-east-1',
'us-west-1',
'us-west-2',
'eu-west-1',
'ap-southeast-1',
'ap-southeast-2',
'ap-northeast-1',
'sa-east-1',
)
REGIONS_NAMES = (
'US East N. Virginia',
'US West N. California',
'US West Oregon',
'EU Ireland',
'APAC Singapore',
'APAC Sydney',
'Japan Tokyo',
'S. America Sao Paulo',
)
AMI_IDS_64 = (
# 5.5
('ami-eb84ed82', 'ami-bd96b9f8', 'ami-efc051df', 'ami-23273657',
'ami-bc135dee', 'ami-6d3dad57', 'ami-3ddd543c', 'ami-6466bc79'),
# 5.6
('ami-f383ea9a', 'ami-0598b740', 'ami-3dde4f0d', 'ami-2b3e2f5f',
'ami-b0145ae2', 'ami-b73bab8d', 'ami-b1cb42b0', 'ami-ac60bab1'),
# 5.7
('ami-83573eea', 'ami-e19cb3a4', 'ami-3fd9480f', 'ami-dd3829a9',
'ami-c4165896', 'ami-4939a973', 'ami-8d32bc8c', 'ami-0663b91b'),
# 5.8
('ami-a3563fca', 'ami-4d9bb408', 'ami-6fd9485f', 'ami-a13b2ad5',
'ami-b01658e2', 'ami-9339a9a9', 'ami-6f33bd6e', 'ami-4063b95d'),
# 5.9
('ami-cf5b32a6', 'ami-859bb4c0', 'ami-87d948b7', 'ami-f13a2b85',
'ami-72175920', 'ami-d539a9ef', 'ami-1130be10', 'ami-9263b98f'),
# 6.0
('ami-09680160', 'ami-6381ae26', 'ami-5fd2436f', 'ami-3d0c1d49',
'ami-1a1a5448', 'ami-4536a67f', 'ami-a528a6a4', 'ami-ca6fb5d7'),
# 6.1
('ami-956a03fc', 'ami-d381ae96', 'ami-fbd243cb', 'ami-cb0c1dbf',
'ami-d21a5480', 'ami-f336a6c9', 'ami-5129a750', 'ami-106cb60d'),
# 6.2
('ami-876c05ee', 'ami-4d80af08', 'ami-2fd5441f', 'ami-190f1e6d',
'ami-981a54ca', 'ami-6d37a757', 'ami-9526a894', 'ami-546cb649'),
# 6.3
('ami-a35a33ca', 'ami-ef99b6aa', 'ami-55df4e65', 'ami-393f2e4d',
'ami-2a145a78', 'ami-db3aaae1', 'ami-fbc940fa', 'ami-4860ba55'),
# 6.4
('ami-a25415cb', 'ami-6283a827', 'ami-b8a63b88', 'ami-75342c01',
'ami-80bbf3d2', 'ami-1d62f027', 'ami-5769f956', 'ami-fd73d7e0'),
)
AMI_IDS_32 = (
# 5.5
('ami-d987eeb0', 'ami-3b95ba7e', 'ami-09c35239', 'ami-b92938cd',
'ami-6e105e3c', 'ami-933dada9', 'ami-1bdc551a', 'ami-a866bcb5'),
# 5.6
('ami-4185ec28', 'ami-db98b79e', 'ami-b3de4f83', 'ami-9b3e2fef',
'ami-26155b74', 'ami-e53babdf', 'ami-6bcc456a', 'ami-fe60bae3'),
# 5.7
('ami-75aac31c', 'ami-079ab542', 'ami-91db4aa1', 'ami-4d3d2c39',
'ami-2a175978', 'ami-213aaa1b', 'ami-b330beb2', 'ami-dc63b9c1'),
# 5.8
('ami-7badc412', 'ami-8b9ab5ce', 'ami-cddb4afd', 'ami-7f3c2d0b',
'ami-e81759ba', 'ami-733aaa49', 'ami-7f31bf7e', 'ami-fe63b9e3'),
# 5.9
('ami-23acc54a', 'ami-7b99b63e', 'ami-e1dc4dd1', 'ami-e13c2d95',
'ami-78145a2a', 'ami-b13aaa8b', 'ami-2dc9402c', 'ami-0e60ba13'),
# 6.0
('ami-7768011e', 'ami-2380af66', 'ami-4bd5447b', 'ami-830f1ef7',
'ami-0a1b5558', 'ami-9937a7a3', 'ami-a325aba2', 'ami-9a6cb687'),
# 6.1
('ami-196a0370', 'ami-fd80afb8', 'ami-edd544dd', 'ami-dd0e1fa9',
'ami-941b55c6', 'ami-d537a7ef', 'ami-cf20aece', 'ami-de6cb6c3'),
# 6.2
('ami-d96c05b0', 'ami-5b9fb01e', 'ami-19d44529', 'ami-6f31201b',
'ami-7e18562c', 'ami-2338a819', 'ami-ad3ab4ac', 'ami-1c6db701'),
# 6.3
('ami-a35c35ca', 'ami-4598b700', 'ami-f5df4ec5', 'ami-cb3f2ebf',
'ami-e2145ab0', 'ami-1f3bab25', 'ami-b5c841b4', 'ami-9860ba85'),
# 6.4
('ami-7e175617', 'ami-4a83a80f', 'ami-baa63b8a', 'ami-8b332bff',
'ami-9cbbf3ce', 'ami-957eecaf', 'ami-bb68f8ba', 'ami-c373d7de'),
)
# -----------------------------------------------------------------------------
# Get configuration from environment
# -----------------------------------------------------------------------------
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
BUILD_USER_ID = os.environ.get('BUILD_USER_ID', 'unknown')
INSTANCE_NAME = os.environ.get('INSTANCE_NAME', '{now}-{username}-{os}-{arch}')
INSTANCE_ARCHITECTURE = os.environ.get('INSTANCE_ARCHITECTURE',
ARCHITECTURES[-1])
INSTANCE_DISK_SIZE = os.environ.get('INSTANCE_DISK_SIZE', 6)
INSTANCE_KEY_NAME = os.environ.get('INSTANCE_KEY_NAME')
INSTANCE_REGION = os.environ.get('INSTANCE_REGION', REGIONS_NAMES[0])
INSTANCE_SECURITY_GROUPS = os.environ.get('INSTANCE_SECURITY_GROUPS')
INSTANCE_TYPE = os.environ.get('INSTANCE_TYPE', 't1.micro')
RHEL_VERSION = os.environ.get('RHEL_VERSION', VERSIONS[-1])
VERSION_INDEX = VERSIONS.index(RHEL_VERSION)
REGION_INDEX = REGIONS_NAMES.index(INSTANCE_REGION)
REGION_ID = REGIONS[REGION_INDEX]
if INSTANCE_ARCHITECTURE == '32bit':
AMI_ID = AMI_IDS_32[VERSION_INDEX][REGION_INDEX]
else:
AMI_ID = AMI_IDS_64[VERSION_INDEX][REGION_INDEX]
try:
INSTANCE_DISK_SIZE = abs(int(INSTANCE_DISK_SIZE))
except ValueError:
INSTANCE_DISK_SIZE = 6
INSTANCE_NAME = INSTANCE_NAME.format(arch=INSTANCE_ARCHITECTURE,
now=int(time.time()),
os='rhel%s' % RHEL_VERSION,
username=BUILD_USER_ID)
if INSTANCE_SECURITY_GROUPS is None:
INSTANCE_SECURITY_GROUPS = []
else:
INSTANCE_SECURITY_GROUPS = [group.strip() for group in
INSTANCE_SECURITY_GROUPS.split(',')]
# -----------------------------------------------------------------------------
# Validate configuration
# -----------------------------------------------------------------------------
if AWS_ACCESS_KEY_ID is None or AWS_SECRET_ACCESS_KEY is None:
print 'AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY not provided'
sys.exit(1)
if INSTANCE_KEY_NAME is None:
print 'INSTANCE_KEY_NAME not provided'
sys.exit(1)
# -----------------------------------------------------------------------------
# Process user data
# -----------------------------------------------------------------------------
if RHEL_VERSION in VERSIONS and float(RHEL_VERSION) >= 6.4:
USER_DATA = """#!/bin/bash -ex
echo "ssh-dss AAAAB3NzaC1kc3MAAACBAP2+EVkCT6dJzwL5LFDX0ACzbtlDasmpXbC5dpPNiWmADfdpRdDjWtVA/xjbSOT5tTuLr5fi6cQ2VMLNgVoQUT7tlPAJJU5Z7BngR6CkmonSlczLWbqyJVxg7At/o/kzzYFLE+i1+ReGlXasv4kOlPxhwhqm/wO0hzdImcc866qfAAAAFQDZ8h1+tp6S6KkAahfQUBfgrYhXZQAAAIBJUgNuQZw4ZJ81CPmYDkkYrGbMKxlPn7p/Mycxz+pZi6GbLuaY8rzbhiwS1JcOpUKuB0r4PX6qUoQvhRYZdhfaSEGX81K/3EGpjbzvcFSXa/8ymCcvw9oDoFFV6HWtWxEbjmy9kGrmHMeyFfFAK/tvNbwxDnn2usA4P7UX2NrqUgAAAIEAoVFEn7VZOn7mZZGkBa9Zrtm4AOQEbqd03UoYE1til96Z0Hja8rs6ilqYwuT57VzoePh2uIPfCgzeUxQ+RDjku3YLBsMNRwz3yS49iNiRWF1PAfqscLYyHAFPvvxDE1D/5dHtQGkad618nepycGf+cuSNzZjJdbbbT+qDCm+K6PY= [email protected]" >> /home/ec2-user/.ssh/authorized_keys
sed -i.old "s/Defaults requiretty/#Defaults requiretty/" /etc/sudoers
""" # noqa
else:
USER_DATA = None
# -----------------------------------------------------------------------------
# Provision the instance
# -----------------------------------------------------------------------------
dev_sda1 = ec2.blockdevicemapping.BlockDeviceType()
dev_sda1.size = INSTANCE_DISK_SIZE
bdm = ec2.blockdevicemapping.BlockDeviceMapping()
bdm['/dev/sda1'] = dev_sda1
print 'Connecting to EC2...'
connection = ec2.connect_to_region(REGION_ID)
reservation = connection.run_instances(
AMI_ID,
block_device_map=bdm,
instance_type=INSTANCE_TYPE,
key_name=INSTANCE_KEY_NAME,
security_groups=INSTANCE_SECURITY_GROUPS,
user_data=USER_DATA)
instance = reservation.instances[0]
print 'Waiting running',
sys.stdout.flush()
while instance.state == 'pending':
time.sleep(5)
print '.',
sys.stdout.flush()
instance.update()
if instance.state == 'running':
instance.add_tag('Name', INSTANCE_NAME)
instance.add_tag('createdby', BUILD_USER_ID)
# Wait until sshd is ready or fail after 10 attempts
print '\nWaiting instance to finish boot...'
sys.stdout.flush()
attempts = 0
can_connect = False
while attempts < 10 and not can_connect:
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(60)
s.connect((instance.public_dns_name, 22))
s.close()
can_connect = True
except socket.error, e:
s.close()
if (e.errno != errno.ECONNREFUSED and
not isinstance(e, socket.timeout)):
raise e
attempts += 1
time.sleep(10)
print '\nInstance provisioned'
print '--------------------'
print 'User: %s' % 'ec2-user'
print 'Public DNS: %s' % instance.public_dns_name
print 'Name: %s' % INSTANCE_NAME
print 'RHEL version: %s' % RHEL_VERSION
print 'Architecture: %s' % INSTANCE_ARCHITECTURE
print 'Disk size: %s' % INSTANCE_DISK_SIZE
print 'Key name: %s' % INSTANCE_KEY_NAME
print 'Region: %s' % INSTANCE_REGION
print 'Security groups: %s' % ', '.join(INSTANCE_SECURITY_GROUPS)
print 'Type: %s' % INSTANCE_TYPE
print 'ssh -i /path/to/%s.pem ec2-user@%s' % (INSTANCE_KEY_NAME,
instance.public_dns_name)
if not can_connect:
print '\nWARNING: could not check ssh connection to the instance'
else:
print '\nInstance not running. Instance state: %s' % instance.state
sys.exit(1)
@blvd20
Copy link

blvd20 commented Mar 10, 2014

can't understand it now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment