def cfn_update(test=False): """ Update the AWS cloudformation stack. """ _validate_fabric_env() stack_name = get_stack_name(new=False) cfn_config = get_config(called_by_cfn_create=True) cfn = get_connection(Cloudformation) # Get online template response = cfn.conn_cfn.get_template(stack_name) body = response['GetTemplateResponse']['GetTemplateResult']['TemplateBody'] new_body = cfn_config.process_update(body) x = raw_input( "Are you sure you want to update the stack {}!? (y/n)\n".format( stack_name)) if x not in ['y', 'Y', 'Yes', 'yes']: sys.exit(1) rc = cfn.update(stack_name, cfn_config.process_update(body)) if not rc: logger.critical( "cfn_update: please check the logs for BotoServerError criticals") logger.critical( "cfn_update: this usually happens when cfn_update is ran but no changes are needed" ) return tail(cfn, stack_name) return True
def cfn_create(test=False): """ Create the AWS cloudformation stack. Using the configuration files, a full cloudformation specification will be generated and used to create a stack on AWS. """ _validate_fabric_env() stack_name = get_stack_name(new=True) cfn_config = get_config(called_by_cfn_create=True) cfn = get_connection(Cloudformation) if test: print cfn_config.process() return # Upload any SSL certs that we may need for the stack. if 'ssl' in cfn_config.data: print green("Uploading SSL certificates to stack") iam = get_connection(IAM) iam.upload_ssl_certificate(cfn_config.ssl(), stack_name) # Useful for debug # print cfn_config.process() # Inject security groups in stack template and create stacks. try: stack = cfn.create(stack_name, cfn_config.process(), tags=get_cloudformation_tags()) except Exception: # cleanup ssl certificates if any if 'ssl' in cfn_config.data: print red("Deleting SSL certificates from stack") iam.delete_ssl_certificate(cfn_config.ssl(), stack_name) import traceback cfn_delete(True) abort( red("Failed to create: {error}".format( error=traceback.format_exc()))) print green("\nSTACK {0} CREATING...\n").format(stack_name) if not env.blocking: print 'Running in non blocking mode. Exiting.' sys.exit(0) tail(cfn, stack_name) stack_evt = cfn.get_last_stack_event(stack) if stack_evt.resource_status == 'CREATE_COMPLETE': print green('Successfully built stack {0}.'.format(stack)) else: # So delete the SSL cert that we uploaded if 'ssl' in cfn_config.data: iam.delete_ssl_certificate(cfn_config.ssl(), stack_name) abort('Failed to create stack: {0}'.format(stack)) return True
def cfn_create(test=False): """ Create the AWS cloudformation stack. Using the configuration files, a full cloudformation specification will be generated and used to create a stack on AWS. """ stack_name = get_stack_name(new=True) cfn_config = get_config() cfn = get_connection(Cloudformation) if test: print cfn_config.process() return # Upload any SSL certs that we may need for the stack. if "ssl" in cfn_config.data: print green("Uploading SSL certificates to stack") iam = get_connection(IAM) iam.upload_ssl_certificate(cfn_config.ssl(), stack_name) # Useful for debug # print cfn_config.process() # Inject security groups in stack template and create stacks. try: stack = cfn.create(stack_name, cfn_config.process(), tags=get_cloudformation_tags()) except: # cleanup ssl certificates if any if "ssl" in cfn_config.data: print red("Deleting SSL certificates from stack") iam.delete_ssl_certificate(cfn_config.ssl(), stack_name) import traceback abort(red("Failed to create: {error}".format(error=traceback.format_exc()))) print green("\nSTACK {0} CREATING...\n").format(stack_name) if not env.blocking: print "Running in non blocking mode. Exiting." sys.exit(0) tail(cfn, stack_name) stack_evt = cfn.get_last_stack_event(stack) if stack_evt.resource_status == "CREATE_COMPLETE": print "Successfully built stack {0}.".format(stack) else: # So delete the SSL cert that we uploaded if "ssl" in cfn_config.data: iam.delete_ssl_certificate(cfn_config.ssl(), stack_name) abort("Failed to create stack: {0}".format(stack))
def cfn_delete(force=False, pre_delete_callbacks=None): """ Delete the AWS Cloudformation stack Deletes the stack and the associated SSL certificates Args: force(bool): True to destroy the stack without any further input, False to require confirmation before deletion pre_delete_callbacks(list of callables): callable to invoke before trying to run the DeleteStack call. Each callback is called with kwargs of ``stack_name``, and ``config``. (Python only, not setable from command line) """ stack_name = get_stack_name() if not force: x = raw_input("Are you really sure you want to blow away the whole stack for {}!? (y/n)\n".format(stack_name)) if x not in ["y", "Y", "Yes", "yes"]: sys.exit(1) cfn_config = get_config() cfn = get_connection(Cloudformation) if pre_delete_callbacks is not None: for callback in pre_delete_callbacks: callback(stack_name=stack_name, config=cfn_config) print green("\nSTACK {0} DELETING...\n").format(stack_name) cfn.delete(stack_name) if not env.blocking: print "Running in non blocking mode. Exiting." sys.exit(0) # Wait for stacks to delete print "Waiting for stack to delete." tail(cfn, stack_name) if cfn.stack_missing(stack_name): print green("Stack successfully deleted") else: print red("Stack deletion was unsuccessfull") if "ssl" in cfn_config.data: iam = get_connection(IAM) iam.delete_ssl_certificate(cfn_config.ssl(), stack_name)
def cfn_delete(force=False, pre_delete_callbacks=None): """ Delete the AWS Cloudformation stack for inactive stacks Delete DNS records for active stacks Deletes the stack and the associated SSL certificates Args: force(bool): True to destroy the stack without any further input, False to require confirmation before deletion pre_delete_callbacks(list of callables): callable to invoke before trying to run the DeleteStack call. Each callback is called with kwargs of ``stack_name``, and ``config``. (Python only, not setable from command line) """ stack_name = get_stack_name() if not force: x = raw_input( "Are you really sure you want to blow away the whole stack for {}!? (y/n)\n" .format(stack_name)) if x not in ['y', 'Y', 'Yes', 'yes']: sys.exit(1) cfn_config = get_config() cfn = get_connection(Cloudformation) if pre_delete_callbacks is not None: for callback in pre_delete_callbacks: callback(stack_name=stack_name, config=cfn_config) r53_conn = get_connection(R53) elb = get_first_public_elb() stack_id = stack_name.split('-')[-1] zone_name = get_zone_name() zone_id = get_zone_id() if not isactive(): # delete inactive stack stack_tag = get_env_tag() logger.info("Deleting '%s' inactive stack '%s'...".format( stack_tag, stack_name)) print green("\nSTACK {0} DELETING...\n").format(stack_name) # delete Alias and TXT records txt_tag_record = get_tag_record_name(stack_tag) r53_conn.delete_record(zone_name, zone_id, elb, stack_id, stack_tag, txt_tag_record) # Wait for stacks to delete print 'Waiting for stack to delete.' cfn.delete(stack_name) if not env.blocking: print 'Running in non blocking mode. Exiting.' sys.exit(0) tail(cfn, stack_name) if cfn.stack_missing(stack_name): print green("Stack successfully deleted") else: print red("Stack deletion was unsuccessful") return False # cleanup ssl if exists # currently we read ssl from configuration file instead of from AWS # this can cause some mismatch when local config file has been changed.s try: iam = get_connection(IAM) iam.delete_ssl_certificate(cfn_config.ssl(), stack_name) except AttributeError, boto.exception: print green("ssl did not exist")
def cfn_delete(force=False, pre_delete_callbacks=None): """ Delete the AWS Cloudformation stack for inactive stacks Delete DNS records for active stacks Deletes the stack and the associated SSL certificates Args: force(bool): True to destroy the stack without any further input, False to require confirmation before deletion pre_delete_callbacks(list of callables): callable to invoke before trying to run the DeleteStack call. Each callback is called with kwargs of ``stack_name``, and ``config``. (Python only, not setable from command line) """ stack_name = get_stack_name() if not force: x = raw_input("Are you really sure you want to blow away the whole stack for {}!? (y/n)\n".format(stack_name)) if x not in ['y', 'Y', 'Yes', 'yes']: sys.exit(1) cfn_config = get_config() cfn = get_connection(Cloudformation) if pre_delete_callbacks is not None: for callback in pre_delete_callbacks: callback(stack_name=stack_name, config=cfn_config) r53_conn = get_connection(R53) stack_id = stack_name.split('-')[-1] stack_tag = 'active' if isactive() else get_env_tag() zone_id = get_zone_id() zone_name = get_zone_name() try: txt_tag_record = get_tag_record_name(stack_tag) print green("\nDELETING TXT RECORDS {}-{}...\n".format(txt_tag_record, zone_name)) r53_conn.delete_txt_record(zone_name, zone_id, txt_tag_record) except boto.route53.exception.DNSServerError: pass for elb in get_all_elbs(): logger.info("Deleting '{}-{}' from '{}' ({})...".format(elb, stack_id, zone_name, zone_id)) try: print green("\nDELETING Alias RECORDS {}-{}-{}...\n".format(elb, stack_id, zone_name)) r53_conn.delete_alias_record(zone_name, zone_id, elb, stack_id, stack_tag) except boto.route53.exception.DNSServerError: pass if not isactive(): print green("\nSTACK {0} DELETING...\n").format(stack_name) logger.info("Deleting inactive stack '{}' ({})...".format(stack_name, stack_tag)) try: txt_arn_record = 'deployarn.{0}.{1}.{2}'.format(stack_tag, env.environment, env.application) txt_record_name = '{}.{}'.format(txt_arn_record, zone_name) txt_record_value = '"{}"'.format(r53_conn.get_record(zone_name, zone_id, txt_arn_record, 'TXT')) logger.info("Deleting '{}' from '{}' ({}) ...".format(txt_arn_record, zone_name, zone_id)) r53_conn.delete_dns_record(zone_id, txt_record_name, 'TXT', txt_record_value) except boto.route53.exception.DNSServerError: pass print "Waiting for stack '{}' to be deleted...".format(stack_name) cfn.delete(stack_name) if env.blocking: try: tail(cfn, stack_name) except boto.exception.BotoServerError as e: if e.code == 'ValidationError': pass raise e else: print 'Running in an non-blocking mode.' if cfn.stack_missing(stack_name): print green("Stack '{}' successfully deleted.".format(stack_name)) else: print red("Failed to delete stack '{}' successfully.".format(stack_name)) return False try: iam = get_connection(IAM) iam.delete_ssl_certificate(cfn_config.ssl(), stack_name) except AttributeError, boto.exception: print green("SSL certificate was already deleted.") except KeyError: print green("SSL does not exist in cloudformation configuration file")