Example #1
0
def update_infrastructure(stackname, skip=None, start=['ec2']):
    """Limited update of the Cloudformation template and/or Terraform template.

    Resources can be added, but most of the existing ones are immutable.

    Some resources are updatable in place.

    Moreover, we never add anything related to EC2 instances as they are
    not supported anyway (they will come up as part of the template
    but without any software being on it)

    Moreover, EC2 instances must be running while this is executed or their
    resources like PublicIP will be inaccessible.

    Allows to skip EC2, SQS, S3 updates by passing `skip=ec2\\,sqs\\,s3`

    By default starts EC2 instances but this can be avoid by passing `start=`"""

    skip = skip.split(",") if skip else []
    start = start.split(",") if isinstance(start, str) else start or []

    (pname, _) = core.parse_stackname(stackname)
    more_context = {}
    context, delta, current_context = cfngen.regenerate_stack(
        stackname, **more_context)

    if _are_there_existing_servers(current_context) and 'ec2' in start:
        core_lifecycle.start(stackname)
    LOG.info("Create: %s", pformat(delta.plus))
    LOG.info("Update: %s", pformat(delta.edit))
    LOG.info("Delete: %s", pformat(delta.minus))
    LOG.info("Terraform delta: %s", delta.terraform)

    # see: `buildercore.config.BUILDER_NON_INTERACTIVE` for skipping confirmation prompts
    utils.confirm(
        'Confirming changes to CloudFormation and Terraform templates?')

    context_handler.write_context(stackname, context)

    cloudformation.update_template(stackname, delta.cloudformation)
    terraform.update_template(stackname)

    # TODO: move inside bootstrap.update_stack
    # EC2
    if _are_there_existing_servers(context) and not 'ec2' in skip:
        # the /etc/buildvars.json file may need to be updated
        buildvars.refresh(stackname, context)
        update(stackname)

    # SQS
    if context.get('sqs', {}) and not 'sqs' in skip:
        bootstrap.update_stack(stackname, service_list=['sqs'])

    # S3
    if context.get('s3', {}) and not 's3' in skip:
        bootstrap.update_stack(stackname, service_list=['s3'])
Example #2
0
def _stack_diff(stackname):
    title("builder drift check")
    context, delta, current_context = cfngen.regenerate_stack(stackname)
    if any([delta.plus['Outputs'], delta.plus['Parameters'], delta.plus['Resources'],
            delta.edit['Outputs'], delta.edit['Resources'],
            delta.minus['Outputs'], delta.minus['Parameters'], delta.minus['Resources']]):
        description = "builder has found a difference between what was once generated and what is being generated now."
        solution = "./bldr update_infrastructure:%s" % (stackname,)
        return problem(description, solution)
    return success()
Example #3
0
def update_infrastructure(stackname, skip=None, start=['ec2']):
    """Limited update of the Cloudformation template and/or Terraform template.

    Resources can be added, but most of the existing ones are immutable.

    Some resources are updatable in place.

    Moreover, we never add anything related to EC2 instances as they are
    not supported anyway (they will come up as part of the template
    but without any software being on it)

    Moreover, EC2 instances must be running while this is executed or their
    resources like PublicIP will be inaccessible.

    Allows to skip EC2, SQS, S3 updates by passing `skip=ec2\\,sqs\\,s3`

    By default starts EC2 instances but this can be avoid by passing `start=`"""

    skip = skip.split(",") if skip else []
    start = start.split(",") if isinstance(start, str) else start or []

    (pname, _) = core.parse_stackname(stackname)
    more_context = {}
    context, delta, current_context = cfngen.regenerate_stack(stackname, **more_context)

    if _are_there_existing_servers(current_context) and 'ec2' in start:
        core_lifecycle.start(stackname)
    LOG.info("Create: %s", pformat(delta.plus))
    LOG.info("Update: %s", pformat(delta.edit))
    LOG.info("Delete: %s", pformat(delta.minus))
    LOG.info("Terraform delta: %s", delta.terraform)
    utils.confirm('Confirming changes to CloudFormation and Terraform templates?')

    context_handler.write_context(stackname, context)

    cloudformation.update_template(stackname, delta.cloudformation)
    terraform.update_template(stackname)

    # TODO: move inside bootstrap.update_stack
    # EC2
    if _are_there_existing_servers(context) and not 'ec2' in skip:
        # the /etc/buildvars.json file may need to be updated
        buildvars.refresh(stackname, context)
        update(stackname)

    # SQS
    if context.get('sqs', {}) and not 'sqs' in skip:
        bootstrap.update_stack(stackname, service_list=['sqs'])

    # S3
    if context.get('s3', {}) and not 's3' in skip:
        bootstrap.update_stack(stackname, service_list=['s3'])
Example #4
0
    def test_altconfig_name_preserved(self, *args):
        # create a random instance id for the 'dummy2' project and use the 'alt-config1' alt-config
        # see: fixtures/dummy2-project.json
        instance_id = base.generate_environment_name() # "luke-20191001045227-270172"
        stackname = generate_stack_from_input('dummy2', instance_id, alt_config='alt-config1') # "dummy2--luke-20191001045222-883274"

        # ensure alt-config is in there and correct
        current_context = context_handler.load_context(stackname)
        self.assertEqual('alt-config1', current_context['alt-config'])

        # skip calling update_infrastructure, we just want to test the diff with any changes
        new_context = cfngen.regenerate_stack(stackname)[0]

        # ensure the alt-config value is correct (it was previously the instance-id)
        self.assertEqual(current_context['alt-config'], new_context['alt-config'])
Example #5
0
def update_template(stackname):
    """Limited update of the Cloudformation template.

    Resources can be added, but most of the existing ones are immutable.

    Some resources are updatable in place.

    Moreover, we never add anything related to EC2 instances as they are
    not supported anyway (they will come up as part of the template
    but without any software being on it)

    Moreover, EC2 instances must be running while this is executed or their
    resources like PublicIP will be inaccessible"""

    (pname, _) = core.parse_stackname(stackname)
    more_context = cfngen.choose_config(stackname)

    context, delta_plus, delta_minus = cfngen.regenerate_stack(
        pname, **more_context)

    if context['ec2']:
        core_lifecycle.start(stackname)
    LOG.info("Create/update: %s", pformat(delta_plus))
    LOG.info("Delete: %s", pformat(delta_minus))
    utils.confirm(
        'Confirming changes to the stack template? This will rewrite the context and the CloudFormation template'
    )

    context_handler.write_context(stackname, context)

    if delta_plus['Resources'] or delta_plus['Outputs'] or delta_minus[
            'Resources'] or delta_minus['Outputs']:
        new_template = cfngen.merge_delta(stackname, delta_plus, delta_minus)
        bootstrap.update_template(stackname, new_template)
        # the /etc/buildvars.json file may need to be updated
        buildvars.refresh(stackname, context)
    else:
        # attempting to apply an empty change set would result in an error
        LOG.info("Nothing to update on CloudFormation")

    update(stackname)