Example #1
0
def deploy(ami_id):
    """
    Deploys an AMI as an auto-scaling group (ASG) to AWS.

    Arguments:
        ami_id(str): AWS AMI ID

    Returns:
        dict(str, str, dict): Returns a dictionary with the keys:
            'ami_id' - AMI id used to deploy the AMI
            'current_asgs' - Lists of current active ASGs, keyed by cluster.
            'disabled_asgs' - Lists of current inactive ASGs, keyed by cluster.

    Raises:
        TimeoutException: When the task to bring up the new instance times out.
        BackendError: When the task to bring up the new instance fails.
        ASGDoesNotExistException: If the ASG being queried does not exist.
    """
    LOG.info("Processing request to deploy {}.".format(ami_id))

    # Pull the EDP from the AMI ID
    edp = ec2.edp_for_ami(ami_id)

    # These are all autoscaling groups that match the tags we care about.
    existing_edp_asgs = ec2.asgs_for_edp(edp, filter_asgs_pending_delete=False)

    # Find the clusters for all the existing ASGs.
    existing_clustered_asgs = clusters_for_asgs(existing_edp_asgs)
    LOG.info("Deploying to cluster(s) {}".format(existing_clustered_asgs.keys()))

    # Create a new ASG in each cluster.
    new_clustered_asgs = defaultdict(list)
    for cluster in existing_clustered_asgs:
        try:
            newest_asg = new_asg(cluster, ami_id)
            new_clustered_asgs[cluster].append(newest_asg)
        except:
            msg = "ASG creation failed for cluster '{}' but succeeded for cluster(s) {}."
            msg = msg.format(cluster, new_clustered_asgs.keys())
            LOG.error(msg)
            raise

    new_asgs = [asgs[0] for asgs in new_clustered_asgs.values()]
    LOG.info("New ASGs created: {}".format(new_asgs))
    ec2.wait_for_in_service(new_asgs, 300)
    LOG.info("New ASGs healthy: {}".format(new_asgs))

    LOG.info("Enabling traffic to new ASGs for the {} cluster(s).".format(existing_clustered_asgs.keys()))
    success, enabled_asgs, disabled_asgs = _red_black_deploy(dict(new_clustered_asgs), existing_clustered_asgs)
    if not success:
        raise BackendError("Error performing red/black deploy - deploy was unsuccessful. "
                           "enabled_asgs: {} - disabled_asgs: {}".format(enabled_asgs, disabled_asgs))

    LOG.info("Woot! Deploy Done!")
    return {'ami_id': ami_id, 'current_asgs': enabled_asgs, 'disabled_asgs': disabled_asgs}
Example #2
0
def deploy(ami_id):
    """
    Deploys an AMI as an auto-scaling group (ASG) to AWS.

    Arguments:
        ami_id(str): AWS AMI ID

    Returns:
        dict(str, str, dict): Returns a dictionary with the keys:
            'ami_id' - AMI id used to deploy the AMI
            'current_asgs' - Lists of current active ASGs, keyed by cluster.
            'disabled_asgs' - Lists of current inactive ASGs, keyed by cluster.

    Raises:
        TimeoutException: When the task to bring up the new instance times out.
        BackendError: When the task to bring up the new instance fails.
        ASGDoesNotExistException: If the ASG being queried does not exist.
    """
    LOG.info("Processing request to deploy {}.".format(ami_id))

    # Pull the EDP from the AMI ID
    edp = ec2.edp_for_ami(ami_id)

    # These are all autoscaling groups that match the tags we care about.
    existing_edp_asgs = ec2.asgs_for_edp(edp, filter_asgs_pending_delete=False)

    # Find the clusters for all the existing ASGs.
    existing_clustered_asgs = clusters_for_asgs(existing_edp_asgs)
    LOG.info("Deploying to cluster(s) {}".format(existing_clustered_asgs.keys()))

    # Create a new ASG in each cluster.
    new_clustered_asgs = defaultdict(list)
    for cluster in existing_clustered_asgs:
        try:
            newest_asg = new_asg(cluster, ami_id)
            new_clustered_asgs[cluster].append(newest_asg)
        except:
            msg = "ASG creation failed for cluster '{}' but succeeded for cluster(s) {}."
            msg = msg.format(cluster, new_clustered_asgs.keys())
            LOG.exception(msg)
            raise

    new_asgs = [asgs[0] for asgs in new_clustered_asgs.values()]
    LOG.info("New ASGs created: {}".format(new_asgs))
    ec2.wait_for_in_service(new_asgs, 300)
    LOG.info("New ASGs healthy: {}".format(new_asgs))

    LOG.info("Enabling traffic to new ASGs for the {} cluster(s).".format(existing_clustered_asgs.keys()))
    success, enabled_asgs, disabled_asgs = _red_black_deploy(dict(new_clustered_asgs), existing_clustered_asgs)
    if not success:
        raise BackendError("Error performing red/black deploy - deploy was unsuccessful. "
                           "enabled_asgs: {} - disabled_asgs: {}".format(enabled_asgs, disabled_asgs))

    LOG.info("Woot! Deploy Done!")
    return {'ami_id': ami_id, 'current_asgs': enabled_asgs, 'disabled_asgs': disabled_asgs}
Example #3
0
 def test_wait_for_in_service(self):
     create_asg_with_tags("healthy_asg", {"foo": "bar"})
     self.assertEqual(None, ec2.wait_for_in_service(["healthy_asg"], 2))
Example #4
0
 def test_wait_for_in_service(self):
     create_asg_with_tags("healthy_asg", {"foo": "bar"})
     self.assertEqual(None, ec2.wait_for_in_service(["healthy_asg"], 2))