Created
January 14, 2014 06:39
-
-
Save chhibber/8414119 to your computer and use it in GitHub Desktop.
AWS Bootstrapping Cloudformation
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/python | |
# __author__ = 'sono' | |
import boto | |
import boto.cloudformation | |
import boto.rds | |
import json | |
import yaml | |
import os | |
from configobj import ConfigObj | |
from argparse import ArgumentParser | |
from time import sleep | |
from fabric.colors import green as _green, yellow as _yellow | |
import hipchat | |
def arguments(): | |
# Instantiate options parser and add our options | |
# for command line arguments | |
parser = ArgumentParser() | |
parser.add_argument('-C', '--createstack') | |
parser.add_argument('-D', '--deletestack') | |
parser.add_argument('-c', '--configfile') | |
parser.add_argument('-r', '--region') | |
return vars(parser.parse_args()) | |
def get_stack_config(configFile, stackName): | |
stackYanl = [] | |
dir = os.path.dirname(__file__) | |
filename = os.path.join(dir, "config/" + configFile) | |
print filename | |
f = open(filename) | |
stackYaml = yaml.load (f) | |
f.close() | |
return stackYaml[stackName] | |
def get_db_snapshot(rdsconn): | |
snapshots = rdsconn.get_all_dbsnapshots() | |
# Looks for all staging snapshots and put in a new dictionary | |
# composed snapshot ID and snapshot creation time | |
snaps = {} | |
snapsDateTime = [] | |
print "Unordered list of " + environment + " snapshots" | |
for snap in snapshots: | |
if environment in snap.id: | |
snaps[snap.snapshot_create_time] = str(snap.id) | |
snapsDateTime.append(snap.snapshot_create_time) | |
print snap.snapshot_create_time + ":::" + snap.id | |
print "\n\n" | |
snapsByDate = sorted(snapsDateTime, reverse=True) | |
print "List of Snapshots by date" | |
for snapTime in snapsByDate: | |
print snapTime + " :: " + snaps[snapTime] | |
print "\n\n" | |
numOfSnaps = len(snapsByDate) | |
# If we have more then 10 snapshots, delete the older ones | |
if numOfSnaps > 11: | |
print _yellow("Deleting old snapshots (We keep 10)") | |
for x in range (11, numOfSnaps): | |
print "Deleting:" + snapsByDate[x] + " :: " + snaps[snapsByDate[x]] | |
try: | |
rdsconn.delete_dbsnapshot(snaps[snapsByDate[x]]) | |
except boto.exception.BotoServerError, e: | |
print e.error_message | |
print "\n\n" | |
print "Latest " + environment + " snapshot: " + snaps[snapsByDate[0]] | |
return snaps[snapsByDate[0]] | |
def cfn_to_string(cfnTemplate): | |
with open (cfnTemplate, "r") as myFile: | |
cfnJsonString = myFile.read().replace('\n','') | |
return cfnJsonString | |
def create_stack(cfnconn, stackname, cfnTemplateBody, cfnParameters, environment): | |
try: | |
stackid = cfnconn.create_stack( | |
stackname, | |
template_body = cfnTemplateBody, | |
parameters = cfnParameters, | |
tags = { 'Env' : environment } | |
) | |
sleep(5) | |
return stackid | |
except boto.exception.BotoServerError, e: | |
print "Error: " + e.error_message | |
exit() | |
def delete_stack(cfnconn, stackname): | |
try: | |
cfnconn.delete_stack(stackname) | |
except boto.exception.BotoServerError, e: | |
print e.error_message | |
# | |
# Build a parameter list for cloud formation stack | |
# Right now this consists of: | |
# VPC - Connect to AWS and get the ID based off the name of vpc | |
# ASGAZ - defined set of availability zones specified in yaml config file | |
# ASGVPCZoneID - need to connect to AWS and build a string | |
# based on private subnet names | |
# cidr - Address block assigned to the VPC | |
def get_vpc_params(cfnconn, stackConfig, stackName): | |
print "get_vpc_params - Starting" | |
# | |
# Grab all outputs from our VPC and add them to the parameters list. | |
# It is required that the VPC output all required information | |
vpcParams = [] | |
if stackConfig['vpc'] == 'root': | |
return vpcParams | |
stackResources = cfnconn.describe_stack_resources(stackConfig['vpc']) | |
print "get_vpc_params - check stack resources and check for required parameters..." | |
for sr in stackResources: | |
if sr.logical_resource_id in stackConfig['requiredParameters']: | |
vpcParams.append((str(sr.logical_resource_id ), str(sr.physical_resource_id))) | |
for reqs in stackConfig['requiredParameters']: | |
try: | |
reqs in stackResources | |
except: | |
print reqs + " not in the VPC Parameters list " + stackResources | |
exit() | |
return vpcParams | |
if __name__ == '__main__': | |
args = arguments() | |
print "Main - Starting" | |
hipster = hipchat.HipChat(token='YOURTOKEN') | |
hipsterRoomID = 'Development Notifications' | |
hipsterFrom = 'AWS ROBOT' | |
# | |
# Connect to AWS cloudformation service | |
# | |
# cfnconn = boto.connect_cloudformation() | |
cfnconn = boto.cloudformation.connect_to_region(args['region']) | |
# | |
# Delete Stack and exit program | |
# | |
if not args['createstack'] and args['deletestack']: | |
stackName = args['deletestack'] | |
delete_stack(cfnconn, stackName) | |
hipsterMessage = "Deleting Stack" + stackName + "..." | |
hipster.message_room(hipsterRoomID, hipsterFrom, hipsterMessage) | |
exit() | |
configFile = args['configfile'] | |
stackName = args['createstack'] | |
stackConfig = get_stack_config(configFile, stackName) | |
print stackConfig | |
environment = stackConfig['environment'] | |
cfn = stackConfig['cfnTemplate'] | |
cfnParameters = [] | |
# Load our CFN Template as json string | |
cfnTemplateBody = cfn_to_string(cfn) | |
# Set our Parameters for the template | |
cfnParameters = get_vpc_params(cfnconn, stackConfig, stackName) | |
print "\n\n Cloud Formation Params: " | |
print cfnParameters | |
print "\n" | |
# Get our DB Snapshot | |
if stackConfig['dbSnapshot']: | |
rdsconn = boto.rds.connect_to_region(args['region']) | |
dbSnapshot = get_db_snapshot(rdsconn) | |
cfnParameters.append( ('DBSnapshot', dbSnapshot) ) | |
print cfnParameters | |
print "" | |
if args['createstack']: | |
hipsterMessage = "Creating Stack " + stackName + "..." | |
hipster.message_room(hipsterRoomID, hipsterFrom, hipsterMessage) | |
print(_green("Creating stack " + stackName + "...")) | |
stackid = create_stack(cfnconn, stackName, cfnTemplateBody, cfnParameters, environment) | |
cfnStack = cfnconn.describe_stacks(stackid) | |
while cfnStack[0].stack_status == "CREATE_IN_PROGRESS": | |
sleep(25) | |
cfnEvents = cfnconn.describe_stack_events(stackid) | |
cfnStack = cfnconn.describe_stacks(stackid) | |
hipsterMessage = "Stack status: " + cfnStack[0].stack_status + " " + cfnEvents[0].resource_type + "::" + cfnEvents[0].logical_resource_id | |
hipster.message_room(hipsterRoomID, hipsterFrom, hipsterMessage) | |
print (_yellow("Stack status: " + cfnStack[0].stack_status + " " + cfnEvents[0].resource_type + "::" + cfnEvents[0].logical_resource_id)) | |
cfnStack = cfnconn.describe_stacks(stackid) | |
hipsterMessage = "Stack status: " + cfnStack[0].stack_status | |
hipster.message_room(hipsterRoomID, hipsterFrom, hipsterMessage) | |
print (_green("Stack status: " + cfnStack[0].stack_status)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment