Example #1
0
    def create(self):
        launch_config = self.get_or_create_launch_config()
        subnet_ids = [
            subnet for subnet in subnets.get(
                platform="public" if self.public else self.platform,
                region=self.region)
        ]
        if self.public:
            try:
                subnet_ids.remove(
                    'subnet-0c9eea65'
                )  # RIDICULOUS HARDCODED FIX (3 SUBNETS PUBLIC)
            except ValueError:
                pass

        autoscale_group = autoscale.AutoScalingGroup(
            name=self.scale_name,
            launch_config=launch_config,
            availability_zones=self.availability_zones,
            desired_capacity=self.desired_capacity,
            min_size=self.minimum,
            max_size=self.maximum,
            termination_policies=['OldestInstance'],
            load_balancers=[self.elb],
            vpc_zone_identifier=','.join(subnet_ids),
            connection=self.connection)

        self.connection.create_auto_scaling_group(autoscale_group)
        self.create_notifications()

        return autoscale_group
Example #2
0
def get_asg_instance_ids(region):
    asg_conn = autoscale.connect_to_region(region)
    launch_config = autoscale.LaunchConfiguration(name='test_lc')
    asg_conn.create_launch_configuration(launch_config)
    asg = autoscale.AutoScalingGroup(
        name='test_asg',
        min_size=3,
        max_size=3,
        launch_config=launch_config,
    )
    asg_conn.create_auto_scaling_group(asg)
    asg = asg_conn.get_all_groups([asg.name])[0]
    instance_ids = [instance.instance_id for instance in asg.instances]
    return instance_ids
Example #3
0
def update(name,
           launch_config_name,
           availability_zones,
           min_size,
           max_size,
           desired_capacity=None,
           load_balancers=None,
           default_cooldown=None,
           health_check_type=None,
           health_check_period=None,
           placement_group=None,
           vpc_zone_identifier=None,
           tags=None,
           termination_policies=None,
           suspended_processes=None,
           scaling_policies=None,
           region=None,
           key=None,
           keyid=None,
           profile=None):
    '''
    Update an autoscale group.

    CLI example::

        salt myminion boto_asg.update myasg mylc '["us-east-1a", "us-east-1e"]' 1 10 load_balancers='["myelb", "myelb2"]' tags='[{"key": "Name", value="myasg", "propagate_at_launch": True}]'
    '''

    conn = _get_conn(region, key, keyid, profile)
    if not conn:
        return False, 'Failed to connect to AWS'
    if isinstance(availability_zones, string_types):
        availability_zones = json.loads(availability_zones)
    if isinstance(load_balancers, string_types):
        load_balancers = json.loads(load_balancers)
    if isinstance(vpc_zone_identifier, string_types):
        vpc_zone_identifier = json.loads(vpc_zone_identifier)
    if isinstance(tags, string_types):
        tags = json.loads(tags)
    # Make a list of tag objects from the dict.
    _tags = []
    if tags:
        for tag in tags:
            try:
                key = tag.get('key')
            except KeyError:
                log.error('Tag missing key.')
                return False, 'Tag {0} missing key'.format(tag)
            try:
                value = tag.get('value')
            except KeyError:
                log.error('Tag missing value.')
                return False, 'Tag {0} missing value'.format(tag)
            propagate_at_launch = tag.get('propagate_at_launch', False)
            _tag = autoscale.Tag(key=key,
                                 value=value,
                                 resource_id=name,
                                 propagate_at_launch=propagate_at_launch)
            _tags.append(_tag)
    if isinstance(termination_policies, string_types):
        termination_policies = json.loads(termination_policies)
    if isinstance(suspended_processes, string_types):
        suspended_processes = json.loads(suspended_processes)
    try:
        _asg = autoscale.AutoScalingGroup(
            connection=conn,
            name=name,
            launch_config=launch_config_name,
            availability_zones=availability_zones,
            min_size=min_size,
            max_size=max_size,
            desired_capacity=desired_capacity,
            load_balancers=load_balancers,
            default_cooldown=default_cooldown,
            health_check_type=health_check_type,
            health_check_period=health_check_period,
            placement_group=placement_group,
            tags=_tags,
            vpc_zone_identifier=vpc_zone_identifier,
            termination_policies=termination_policies)
        _asg.update()
        # Seems the update call doesn't handle tags, so we'll need to update
        # that separately.
        if _tags:
            conn.create_or_update_tags(_tags)
        # update doesn't handle suspended_processes either
        # Resume all processes
        _asg.resume_processes()
        # suspend any that are specified. Note that the boto default of empty
        # list suspends all; don't do that.
        if suspended_processes is not None and len(suspended_processes) > 0:
            _asg.suspend_processes(suspended_processes)
        log.info('Updated ASG {0}'.format(name))
        # ### scaling policies
        # delete all policies, then recreate them
        for policy in conn.get_all_policies(as_group=name):
            conn.delete_policy(policy.name, autoscale_group=name)
        _create_scaling_policies(conn, name, scaling_policies)
        return True, ''
    except boto.exception.BotoServerError as e:
        log.debug(e)
        msg = 'Failed to update ASG {0}'.format(name)
        log.error(msg)
        return False, str(e)
Example #4
0
def create(name,
           launch_config_name,
           availability_zones,
           min_size,
           max_size,
           desired_capacity=None,
           load_balancers=None,
           default_cooldown=None,
           health_check_type=None,
           health_check_period=None,
           placement_group=None,
           vpc_zone_identifier=None,
           tags=None,
           termination_policies=None,
           suspended_processes=None,
           scaling_policies=None,
           region=None,
           key=None,
           keyid=None,
           profile=None):
    '''
    Create an autoscale group.

    CLI example::

        salt myminion boto_asg.create myasg mylc '["us-east-1a", "us-east-1e"]' 1 10 load_balancers='["myelb", "myelb2"]' tags='[{"key": "Name", value="myasg", "propagate_at_launch": True}]'
    '''
    conn = _get_conn(region, key, keyid, profile)
    if not conn:
        return False
    if isinstance(availability_zones, string_types):
        availability_zones = json.loads(availability_zones)
    if isinstance(load_balancers, string_types):
        load_balancers = json.loads(load_balancers)
    if isinstance(vpc_zone_identifier, string_types):
        vpc_zone_identifier = json.loads(vpc_zone_identifier)
    if isinstance(tags, string_types):
        tags = json.loads(tags)
    # Make a list of tag objects from the dict.
    _tags = []
    if tags:
        for tag in tags:
            try:
                key = tag.get('key')
            except KeyError:
                log.error('Tag missing key.')
                return False
            try:
                value = tag.get('value')
            except KeyError:
                log.error('Tag missing value.')
                return False
            propagate_at_launch = tag.get('propagate_at_launch', False)
            _tag = autoscale.Tag(key=key,
                                 value=value,
                                 resource_id=name,
                                 propagate_at_launch=propagate_at_launch)
            _tags.append(_tag)
    if isinstance(termination_policies, string_types):
        termination_policies = json.loads(termination_policies)
    if isinstance(suspended_processes, string_types):
        suspended_processes = json.loads(suspended_processes)
    try:
        _asg = autoscale.AutoScalingGroup(
            name=name,
            launch_config=launch_config_name,
            availability_zones=availability_zones,
            min_size=min_size,
            max_size=max_size,
            desired_capacity=desired_capacity,
            load_balancers=load_balancers,
            default_cooldown=default_cooldown,
            health_check_type=health_check_type,
            health_check_period=health_check_period,
            placement_group=placement_group,
            tags=_tags,
            vpc_zone_identifier=vpc_zone_identifier,
            termination_policies=termination_policies,
            suspended_processes=suspended_processes)
        conn.create_auto_scaling_group(_asg)
        # create scaling policies
        _create_scaling_policies(conn, name, scaling_policies)
        log.info('Created ASG {0}'.format(name))
        return True
    except boto.exception.BotoServerError as e:
        log.debug(e)
        msg = 'Failed to create ASG {0}'.format(name)
        log.error(msg)
        return False
Example #5
0
def update(name,
           launch_config_name,
           availability_zones,
           min_size,
           max_size,
           desired_capacity=None,
           load_balancers=None,
           default_cooldown=None,
           health_check_type=None,
           health_check_period=None,
           placement_group=None,
           vpc_zone_identifier=None,
           tags=None,
           termination_policies=None,
           suspended_processes=None,
           scaling_policies=None,
           scheduled_actions=None,
           notification_arn=None,
           notification_types=None,
           region=None,
           key=None,
           keyid=None,
           profile=None):
    '''
    Update an autoscale group.

    CLI example::

        salt myminion boto_asg.update myasg mylc '["us-east-1a", "us-east-1e"]' 1 10 load_balancers='["myelb", "myelb2"]' tags='[{"key": "Name", value="myasg", "propagate_at_launch": True}]'
    '''

    conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
    conn3 = _get_conn_autoscaling_boto3(region=region,
                                        key=key,
                                        keyid=keyid,
                                        profile=profile)
    if not conn:
        return False, "failed to connect to AWS"
    if isinstance(availability_zones, six.string_types):
        availability_zones = json.loads(availability_zones)
    if isinstance(load_balancers, six.string_types):
        load_balancers = json.loads(load_balancers)
    if isinstance(vpc_zone_identifier, six.string_types):
        vpc_zone_identifier = json.loads(vpc_zone_identifier)
    if isinstance(tags, six.string_types):
        tags = json.loads(tags)
    if isinstance(termination_policies, six.string_types):
        termination_policies = json.loads(termination_policies)
    if isinstance(suspended_processes, six.string_types):
        suspended_processes = json.loads(suspended_processes)
    if isinstance(scheduled_actions, six.string_types):
        scheduled_actions = json.loads(scheduled_actions)

    # Massage our tagset into  add / remove lists
    # Use a boto3 call here b/c the boto2 call doeesn't implement filters
    current_tags = conn3.describe_tags(Filters=[{
        'Name': 'auto-scaling-group',
        'Values': [name]
    }]).get('Tags', [])
    current_tags = [{
        'key': t['Key'],
        'value': t['Value'],
        'resource_id': t['ResourceId'],
        'propagate_at_launch': t.get('PropagateAtLaunch', False)
    } for t in current_tags]
    add_tags = []
    desired_tags = []
    if tags:
        tags = __utils__['boto3.ordered'](tags)
        for tag in tags:
            try:
                key = tag.get('key')
            except KeyError:
                log.error('Tag missing key.')
                return False, "Tag {0} missing key".format(tag)
            try:
                value = tag.get('value')
            except KeyError:
                log.error('Tag missing value.')
                return False, "Tag {0} missing value".format(tag)
            propagate_at_launch = tag.get('propagate_at_launch', False)
            _tag = {
                'key': key,
                'value': value,
                'resource_id': name,
                'propagate_at_launch': propagate_at_launch
            }
            if _tag not in current_tags:
                add_tags.append(_tag)
            desired_tags.append(_tag)
    delete_tags = [t for t in current_tags if t not in desired_tags]

    retries = 30
    while True:
        try:
            _asg = autoscale.AutoScalingGroup(
                connection=conn,
                name=name,
                launch_config=launch_config_name,
                availability_zones=availability_zones,
                min_size=min_size,
                max_size=max_size,
                desired_capacity=desired_capacity,
                load_balancers=load_balancers,
                default_cooldown=default_cooldown,
                health_check_type=health_check_type,
                health_check_period=health_check_period,
                placement_group=placement_group,
                tags=add_tags,
                vpc_zone_identifier=vpc_zone_identifier,
                termination_policies=termination_policies)
            if notification_arn and notification_types:
                conn.put_notification_configuration(_asg, notification_arn,
                                                    notification_types)
            _asg.update()
            # Seems the update call doesn't handle tags, so we'll need to update
            # that separately.
            if add_tags:
                log.debug('Adding/updating tags from ASG: {}'.format(add_tags))
                conn.create_or_update_tags(
                    [autoscale.Tag(**t) for t in add_tags])
            if delete_tags:
                log.debug('Deleting tags from ASG: {}'.format(delete_tags))
                conn.delete_tags([autoscale.Tag(**t) for t in delete_tags])
            # update doesn't handle suspended_processes either
            # Resume all processes
            _asg.resume_processes()
            # suspend any that are specified.  Note that the boto default of empty
            # list suspends all; don't do that.
            if suspended_processes is not None and len(
                    suspended_processes) > 0:
                _asg.suspend_processes(suspended_processes)
            log.info('Updated ASG {0}'.format(name))
            # ### scaling policies
            # delete all policies, then recreate them
            for policy in conn.get_all_policies(as_group=name):
                conn.delete_policy(policy.name, autoscale_group=name)
            _create_scaling_policies(conn, name, scaling_policies)
            # ### scheduled actions
            # delete all scheduled actions, then recreate them
            for scheduled_action in conn.get_all_scheduled_actions(
                    as_group=name):
                conn.delete_scheduled_action(scheduled_action.name,
                                             autoscale_group=name)
            _create_scheduled_actions(conn, name, scheduled_actions)
            return True, ''
        except boto.exception.BotoServerError as e:
            if retries and e.code == 'Throttling':
                log.debug('Throttled by AWS API, retrying in 5 seconds...')
                time.sleep(5)
                retries -= 1
                continue
            log.error(e)
            msg = 'Failed to update ASG {0}'.format(name)
            log.error(msg)
            return False, str(e)
Example #6
0
def create(name,
           launch_config_name,
           availability_zones,
           min_size,
           max_size,
           desired_capacity=None,
           load_balancers=None,
           default_cooldown=None,
           health_check_type=None,
           health_check_period=None,
           placement_group=None,
           vpc_zone_identifier=None,
           tags=None,
           termination_policies=None,
           suspended_processes=None,
           scaling_policies=None,
           scheduled_actions=None,
           region=None,
           notification_arn=None,
           notification_types=None,
           key=None,
           keyid=None,
           profile=None):
    '''
    Create an autoscale group.

    CLI example::

        salt myminion boto_asg.create myasg mylc '["us-east-1a", "us-east-1e"]' 1 10 load_balancers='["myelb", "myelb2"]' tags='[{"key": "Name", value="myasg", "propagate_at_launch": True}]'
    '''
    conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
    if isinstance(availability_zones, six.string_types):
        availability_zones = salt.utils.json.loads(availability_zones)
    if isinstance(load_balancers, six.string_types):
        load_balancers = salt.utils.json.loads(load_balancers)
    if isinstance(vpc_zone_identifier, six.string_types):
        vpc_zone_identifier = salt.utils.json.loads(vpc_zone_identifier)
    if isinstance(tags, six.string_types):
        tags = salt.utils.json.loads(tags)
    # Make a list of tag objects from the dict.
    _tags = []
    if tags:
        for tag in tags:
            try:
                key = tag.get('key')
            except KeyError:
                log.error('Tag missing key.')
                return False
            try:
                value = tag.get('value')
            except KeyError:
                log.error('Tag missing value.')
                return False
            propagate_at_launch = tag.get('propagate_at_launch', False)
            _tag = autoscale.Tag(key=key,
                                 value=value,
                                 resource_id=name,
                                 propagate_at_launch=propagate_at_launch)
            _tags.append(_tag)
    if isinstance(termination_policies, six.string_types):
        termination_policies = salt.utils.json.loads(termination_policies)
    if isinstance(suspended_processes, six.string_types):
        suspended_processes = salt.utils.json.loads(suspended_processes)
    if isinstance(scheduled_actions, six.string_types):
        scheduled_actions = salt.utils.json.loads(scheduled_actions)
    retries = 30
    while True:
        try:
            _asg = autoscale.AutoScalingGroup(
                name=name,
                launch_config=launch_config_name,
                availability_zones=availability_zones,
                min_size=min_size,
                max_size=max_size,
                desired_capacity=desired_capacity,
                load_balancers=load_balancers,
                default_cooldown=default_cooldown,
                health_check_type=health_check_type,
                health_check_period=health_check_period,
                placement_group=placement_group,
                tags=_tags,
                vpc_zone_identifier=vpc_zone_identifier,
                termination_policies=termination_policies,
                suspended_processes=suspended_processes)
            conn.create_auto_scaling_group(_asg)
            # create scaling policies
            _create_scaling_policies(conn, name, scaling_policies)
            # create scheduled actions
            _create_scheduled_actions(conn, name, scheduled_actions)
            # create notifications
            if notification_arn and notification_types:
                conn.put_notification_configuration(_asg, notification_arn,
                                                    notification_types)
            log.info('Created ASG %s', name)
            return True
        except boto.exception.BotoServerError as e:
            if retries and e.code == 'Throttling':
                log.debug('Throttled by AWS API, retrying in 5 seconds...')
                time.sleep(5)
                retries -= 1
                continue
            log.error(e)
            msg = 'Failed to create ASG %s', name
            log.error(msg)
            return False