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
示例#2
0
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
示例#3
0
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))
示例#4
0
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)
示例#5
0
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")
示例#6
0
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")