Skip to content

Instantly share code, notes, and snippets.

@chhibber
Created January 14, 2014 06:39
Show Gist options
  • Save chhibber/8414119 to your computer and use it in GitHub Desktop.
Save chhibber/8414119 to your computer and use it in GitHub Desktop.
AWS Bootstrapping Cloudformation
#!/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