示例#1
0
    def build_vpc(self, cidrblock):
        """Build VPC"""
        self.log.emit('creating vpc ({}, {})'.format(self.vpc_name, cidrblock))
        vpc = self.boto.ec2.create_vpc(CidrBlock = cidrblock)

        self.log.emit('tagging vpc (Name:{})'.format(self.vpc_name), 'debug')
        update_tags(vpc, Name = self.vpc_name)

        self.log.emit('modifying vpc for dns support', 'debug')
        vpc.modify_attribute(EnableDnsSupport={'Value': True})
        self.log.emit('modifying vpc for dns hostnames', 'debug')
        vpc.modify_attribute(EnableDnsHostnames={'Value': True})

        igw_name = 'igw-' + self.vpc_name
        self.log.emit('creating internet_gateway ({})'.format(igw_name))
        gw = self.boto.ec2.create_internet_gateway()
        self.log.emit('tagging gateway (Name:{})'.format(igw_name), 'debug')
        update_tags(gw, Name = igw_name)

        self.log.emit('attaching igw to vpc ({})'.format(igw_name))
        vpc.attach_internet_gateway(
            DryRun=False,
            InternetGatewayId=gw.id,
            VpcId=vpc.id,
        )
示例#2
0
    def build_vpc(self, cidrblock):
        """Build VPC"""
        self.log.emit('creating vpc ({}, {})'.format(self.vpc_name, cidrblock))
        vpc = self.boto.ec2.create_vpc(CidrBlock = cidrblock)

        self.log.emit('tagging vpc (Name:{})'.format(self.vpc_name), 'debug')
        update_tags(vpc, Name = self.vpc_name)

        self.log.emit('modifying vpc for dns support', 'debug')
        vpc.modify_attribute(EnableDnsSupport={'Value': True})
        self.log.emit('modifying vpc for dns hostnames', 'debug')
        vpc.modify_attribute(EnableDnsHostnames={'Value': True})

        igw_name = 'igw-' + self.vpc_name
        self.log.emit('creating internet_gateway ({})'.format(igw_name))
        gw = self.boto.ec2.create_internet_gateway()
        self.log.emit('tagging gateway (Name:{})'.format(igw_name), 'debug')
        update_tags(gw, Name = igw_name)

        self.log.emit('attaching igw to vpc ({})'.format(igw_name))
        vpc.attach_internet_gateway(
            DryRun=False,
            InternetGatewayId=gw.id,
            VpcId=vpc.id,
        )
示例#3
0
 def tag_instance_name(self, instance):
     """Accept a EnrichedInstance, objects create tags."""
     msg = 'tagging instance {} (Name:{})'
     h = '{}-{}-{}'
     hostname = h.format(self.evpc.name, instance.role, instance.id_human)
     self.log.emit(msg.format(instance.identity, hostname))
     update_tags(instance, Name=hostname)
示例#4
0
    def route_tables(self, route_cfg):
        """Build route_tables defined in config"""
        for rt_name, data in route_cfg.items():
            longname = '{}-{}'.format(self.evpc.name, rt_name)
            route_table = self.evpc.get_route_table(longname)
            if route_table is None:
                self.log.emit('creating route_table ({})'.format(longname))
                if data.get('main', False) == True:
                    route_table = self.evpc.get_main_route_table()
                else:
                    route_table = self.evpc.create_route_table()
                self.log.emit('tagging route_table (Name:{})'.format(longname), 'debug')
                update_tags(route_table, Name = longname)

            # TODO: move to separate method ...
            # gatewayId, natGatewayId, networkInterfaceId, vpcPeeringConnectionId or instanceId
            # add routes to route_table defined in configuration.
            for route in data.get('routes', []):
                destination, target = route
                self.log.emit('adding route {} to route_table ({})'.format(route, longname))
                if target.lower() == 'internet_gateway':
                    # this is ugly but we assume only one internet gateway.
                    route_table.create_route(
                        DestinationCidrBlock = destination,
                        GatewayId = list(self.evpc.internet_gateways.all())[0].id,
                    )
示例#5
0
    def subnets(self, subnet_cfg):
        """Build subnets defined in config."""
        sizes = sorted([x['size'] for x in subnet_cfg.values()])
        cidrs = allocate(self.evpc.cidr_block, sizes)

        azones = self.evpc.azones

        subnets = {}
        for size, cidr in zip(sizes, cidrs):
            subnets.setdefault(size, []).append(cidr)

        for name, sn in subnet_cfg.items():
            longname = '{}-{}'.format(self.evpc.name, name)
            az_letter = sn.get('availability_zone', None)
            if az_letter is not None:
                az_name = self.evpc.region_name + az_letter
            else:
                az_index = int(name.split('-')[-1]) - 1
                az_name = azones[az_index]

            cidr = subnets[sn['size']].pop()
            self.log.emit('creating subnet {} in {}'.format(cidr, az_name))
            subnet = self.evpc.create_subnet(
                          CidrBlock = str(cidr),
                          AvailabilityZone = az_name
            )
            self.log.emit('tagging subnet (Name:{})'.format(longname), 'debug')
            update_tags(
                subnet,
                Name = longname,
                description = sn.get('description', ''),
            )
            # Modifying the subnet's public IP addressing behavior.
            if sn.get('public', False) == True:
                subnet.map_public_ip_on_launch = True
示例#6
0
 def tag_instance_name(self, instance):
     """Accept a EnrichedInstance, objects create tags."""
     msg = 'tagging instance {} (Name:{})'
     h = '{}-{}-{}'
     hostname = h.format(self.evpc.name, instance.role, instance.id_human)
     self.log.emit(msg.format(instance.identity, hostname))
     update_tags(instance, Name = hostname)
示例#7
0
    def subnets(self, subnet_cfg):
        """Build subnets defined in config."""
        sizes = sorted([x['size'] for x in subnet_cfg.values()])
        cidrs = allocate(self.evpc.cidr_block, sizes)

        azones = self.evpc.azones

        subnets = {}
        for size, cidr in zip(sizes, cidrs):
            subnets.setdefault(size, []).append(cidr)

        for name, sn in subnet_cfg.items():
            longname = '{}-{}'.format(self.evpc.name, name)
            az_letter = sn.get('availability_zone', None)
            if az_letter is not None:
                az_name = self.evpc.region_name + az_letter
            else:
                az_index = int(name.split('-')[-1]) - 1
                az_name = azones[az_index]

            cidr = subnets[sn['size']].pop()
            self.log.emit('creating subnet {} in {}'.format(cidr, az_name))
            subnet = self.evpc.create_subnet(CidrBlock=str(cidr),
                                             AvailabilityZone=az_name)
            self.log.emit('tagging subnet (Name:{})'.format(longname), 'debug')
            update_tags(
                subnet,
                Name=longname,
                description=sn.get('description', ''),
            )
            # Modifying the subnet's public IP addressing behavior.
            if sn.get('public', False) == True:
                subnet.map_public_ip_on_launch = True
示例#8
0
 def tag_instances(self, role_name, instances):
     """Accept a list of EnrichedInstance, objects create tags."""
     msg = 'tagging instance {} (Name:{}, role:{})'
     for instance in instances:
         h = '{}-{}-{}'
         hostname = h.format(self.evpc.name, role_name, instance.id_human)
         self.log.emit(msg.format(instance.identity, hostname, role_name))
         update_tags(instance, Name = hostname, role = role_name)
示例#9
0
 def tag_instances(self, role_name, instances):
     """Accept a list of EnrichedInstance, objects create tags."""
     msg = 'tagging instance {} (Name:{}, role:{})'
     for instance in instances:
         h = '{}-{}-{}'
         hostname = h.format(self.evpc.name, role_name, instance.id_human)
         self.log.emit(msg.format(instance.identity, hostname, role_name))
         update_tags(instance, Name = hostname, role = role_name)
示例#10
0
    def build_vpc(self, cidrblock):
        """Build VPC"""
        self.log.emit('creating vpc ({}, {})'.format(self.vpc_name, cidrblock))
        vpc = self.boto.ec2.create_vpc(CidrBlock = cidrblock)

        self.log.emit('tagging vpc (Name:{})'.format(self.vpc_name), 'debug')
        update_tags(vpc, Name = self.vpc_name)

        self.log.emit('modifying vpc for dns support', 'debug')
        vpc.modify_attribute(EnableDnsSupport={'Value': True})
        self.log.emit('modifying vpc for dns hostnames', 'debug')
        vpc.modify_attribute(EnableDnsHostnames={'Value': True})
示例#11
0
    def build_vpc(self, cidrblock):
        """Build VPC"""
        self.log.emit('creating vpc ({}, {})'.format(self.vpc_name, cidrblock))
        vpc = self.boto.ec2.create_vpc(CidrBlock=cidrblock)

        self.log.emit('tagging vpc (Name:{})'.format(self.vpc_name), 'debug')
        update_tags(vpc, Name=self.vpc_name)

        self.log.emit('modifying vpc for dns support', 'debug')
        vpc.modify_attribute(EnableDnsSupport={'Value': True})
        self.log.emit('modifying vpc for dns hostnames', 'debug')
        vpc.modify_attribute(EnableDnsHostnames={'Value': True})
示例#12
0
    def build_internet_gateway(self):
        """Build and attach Internet Gateway to VPC."""
        igw_name = "igw-" + self.evpc.name
        self.log.emit("creating internet_gateway ({})".format(igw_name))
        gw = self.boto.ec2.create_internet_gateway()
        self.log.emit("tagging gateway (Name:{})".format(igw_name), "debug")
        update_tags(gw, Name=igw_name)

        self.log.emit("attaching igw to vpc ({})".format(igw_name))
        self.evpc.attach_internet_gateway(
            DryRun=False, InternetGatewayId=gw.id, VpcId=self.evpc.id
        )
示例#13
0
 def dhcp_options(self, dhcp_options_cfg):
     """Creates DHCP Options Set and associates with VPC"""
     for dhcp_name, data in dhcp_options_cfg.items():
         longname = '{}-{}'.format(self.evpc.name, dhcp_name)
         self.log.emit('creating DHCP Options Set {}'.format(longname))
         dhcp_options_id = self.evpc.create_dhcp_options(data)
         # associate DHCP Options with VPC
         self.log.emit('associating DHCP Options {} ({}) with VPC {}'.format(longname, dhcp_options_id, self.vpc_name))
         self.evpc.associate_dhcp_options(
             DhcpOptionsId=dhcp_options_id
         )
         self.evpc.reload()
         update_tags(self.evpc.dhcp_options, Name=longname)
示例#14
0
 def route_tables(self, route_cfg):
     """Build route_tables defined in config"""
     for rt_name, data in route_cfg.items():
         longname = "{}-{}".format(self.evpc.name, rt_name)
         route_table = self.evpc.get_route_table(longname)
         if route_table is None:
             self.log.emit("creating route_table ({})".format(longname))
             if data.get("main", False) == True:
                 route_table = self.evpc.get_main_route_table()
             else:
                 route_table = self.evpc.create_route_table()
             self.log.emit("tagging route_table (Name:{})".format(longname), "debug")
             update_tags(route_table, Name=longname)
示例#15
0
 def route_tables(self, route_cfg):
     """Build route_tables defined in config"""
     for rt_name, data in route_cfg.items():
         longname = '{}-{}'.format(self.evpc.name, rt_name)
         route_table = self.evpc.get_route_table(longname)
         if route_table is None:
             self.log.emit('creating route_table ({})'.format(longname))
             if data.get('main', False) == True:
                 route_table = self.evpc.get_main_route_table()
             else:
                 route_table = self.evpc.create_route_table()
             self.log.emit('tagging route_table (Name:{})'.format(longname), 'debug')
             update_tags(route_table, Name = longname)
示例#16
0
    def build_vpc(self, cidrblock="172.31.0.0/16", tenancy="default"):
        """Build VPC"""
        msg_vpc = "creating vpc ({}, {}) with {} tenancy"
        self.log.emit(msg_vpc.format(self.vpc_name, cidrblock, tenancy))

        vpc = self.boto.ec2.create_vpc(CidrBlock=cidrblock, InstanceTenancy=tenancy)

        self.log.emit("tagging vpc (Name:{})".format(self.vpc_name), "debug")
        update_tags(vpc, Name=self.vpc_name)

        self.log.emit("modifying vpc for dns support", "debug")
        vpc.modify_attribute(EnableDnsSupport={"Value": True})
        self.log.emit("modifying vpc for dns hostnames", "debug")
        vpc.modify_attribute(EnableDnsHostnames={"Value": True})
示例#17
0
    def create_dhcp_options(self, dhcp_configurations):
        """Creates and return a new dhcp_options set."""
        response = self.boto.ec2_client.create_dhcp_options(
                     DhcpConfigurations = dhcp_configurations
                   )

        dhcp_options_id = nested_lookup('DhcpOptionsId', response)[0]
        dhcp_options = self._get_dhcp_options_from_id(dhcp_options_id)

        self.log.emit('tagging dhcp_options (Name:{})'.format(self.evpc.name), 'debug')
        update_tags(dhcp_options, Name = self.evpc.name)

        self.log.emit('associating dhcp_options to {}'.format(self.evpc.name))
        dhcp_options.associate_with_vpc(VpcId = self.evpc.id)
示例#18
0
    def security_groups(self, security_group_cfg):
        """Build Security Groups defined in config."""

        for sg_name, rules in security_group_cfg.items():
            sg = self.evpc.get_security_group(sg_name)
            if sg is not None:
                continue
            longname = "{}-{}".format(self.evpc.name, sg_name)
            self.log.emit("creating security_group {}".format(longname))
            security_group = self.evpc.create_security_group(
                GroupName=longname, Description=longname
            )
            self.log.emit("tagging security_group (Name:{})".format(longname), "debug")
            update_tags(security_group, Name=longname)
示例#19
0
 def route_tables(self, route_cfg):
     """Build route_tables defined in config"""
     for name, data in route_cfg.items():
         longname = '{}-{}'.format(self.evpc.name, name)
         route_table = self.evpc.get_route_table(longname)
         if route_table is None:
             self.log.emit('creating route_table ({})'.format(longname))
             if data.get('main', False) == True:
                 route_table = self.evpc.get_main_route_table()
             else:
                 route_table = self.evpc.create_route_table()
             self.log.emit('tagging route_table (Name:{})'.format(longname),
                           'debug')
             update_tags(route_table, Name=longname)
示例#20
0
    def build_internet_gateway(self):
        """Build and attach Internet Gateway to VPC."""
        igw_name = 'igw-' + self.evpc.name
        self.log.emit('creating internet_gateway ({})'.format(igw_name))
        gw = self.boto.ec2.create_internet_gateway()
        self.log.emit('tagging gateway (Name:{})'.format(igw_name), 'debug')
        update_tags(gw, Name = igw_name)

        self.log.emit('attaching igw to vpc ({})'.format(igw_name))
        self.evpc.attach_internet_gateway(
            DryRun=False,
            InternetGatewayId=gw.id,
            VpcId=self.evpc.id,
        )
示例#21
0
    def create_dhcp_options(self, dhcp_configurations):
        """Creates and return a new dhcp_options set."""
        response = self.boto.ec2_client.create_dhcp_options(
            DhcpConfigurations=dhcp_configurations)

        dhcp_options_id = nested_lookup('DhcpOptionsId', response)[0]
        dhcp_options = self._get_dhcp_options_from_id(dhcp_options_id)

        self.log.emit('tagging dhcp_options (Name:{})'.format(self.evpc.name),
                      'debug')
        update_tags(dhcp_options, Name=self.evpc.name)

        self.log.emit('associating dhcp_options to {}'.format(self.evpc.name))
        dhcp_options.associate_with_vpc(VpcId=self.evpc.id)
示例#22
0
    def tags(self, tag_cfg):
        reserved_tags = [
            'Name', 'role', 'aws:autoscaling:groupName', 'key_pairs',
            'private_hosted_zone_id', 'vpc_name'
        ]
        safe_tags = {}
        for key, value in tag_cfg.items():
            if key not in reserved_tags:
                safe_tags[key] = str(value)

        taggable_resources = self.evpc.taggable_resources
        for resource in taggable_resources:
            if safe_tags:
                self.log.emit('tagging {} with {} ...'.format(
                    resource, safe_tags))
                update_tags(resource, **safe_tags)
示例#23
0
    def security_groups(self, security_group_cfg):
        """Build Security Groups defined in config."""

        for sg_name, rules in security_group_cfg.items():
            sg = self.evpc.get_security_group(sg_name)
            if sg is not None:
                continue
            longname = '{}-{}'.format(self.evpc.name, sg_name)
            self.log.emit('creating security_group {}'.format(longname))
            security_group = self.evpc.create_security_group(
                GroupName   = longname,
                Description = longname,
            )
            self.log.emit(
                'tagging security_group (Name:{})'.format(longname), 'debug'
            )
            update_tags(security_group, Name = longname)
示例#24
0
    def build_vpc(self, cidrblock='172.31.0.0/16', tenancy='default'):
        """Build VPC"""
        msg_vpc = 'creating vpc ({}, {}) with {} tenancy'
        self.log.emit(msg_vpc.format(self.vpc_name, cidrblock, tenancy))

        vpc = self.boto.ec2.create_vpc(
            CidrBlock=cidrblock,
            InstanceTenancy=tenancy,
        )

        self.log.emit('tagging vpc (Name:{})'.format(self.vpc_name), 'debug')
        update_tags(vpc, Name=self.vpc_name)

        self.log.emit('modifying vpc for dns support', 'debug')
        vpc.modify_attribute(EnableDnsSupport={'Value': True})
        self.log.emit('modifying vpc for dns hostnames', 'debug')
        vpc.modify_attribute(EnableDnsHostnames={'Value': True})
示例#25
0
    def tags(self, tag_cfg):
        reserved_tags = [
            "Name",
            "role",
            "aws:autoscaling:groupName",
            "key_pairs",
            "private_hosted_zone_id",
            "vpc_name",
        ]
        safe_tags = {}
        for key, value in tag_cfg.items():
            if key not in reserved_tags:
                safe_tags[key] = str(value)

        taggable_resources = self.evpc.taggable_resources
        for resource in taggable_resources:
            if safe_tags:
                self.log.emit("tagging {} with {} ...".format(resource, safe_tags))
                update_tags(resource, **safe_tags)
示例#26
0
    def subnets(self, subnet_cfg):
        """Build subnets defined in config."""
        sizes = sorted([x['size'] for x in subnet_cfg.values()])
        cidrs = allocate(self.evpc.cidr_block, sizes)

        azones = self.evpc.azones

        subnets = {}
        for size, cidr in zip(sizes, cidrs):
            subnets.setdefault(size, []).append(cidr)

        for sn_name in sorted(subnet_cfg):
            sn = subnet_cfg[sn_name]
            longname = '{}-{}'.format(self.evpc.name, sn_name)
            az_letter = sn.get('availability_zone', None)
            if az_letter is not None:
                az_name = self.evpc.region_name + az_letter
            else:
                az_index = int(sn_name.split('-')[-1]) - 1
                az_name = azones[az_index]

            cidr = subnets[sn['size']].pop(0)
            self.log.emit('creating subnet {} in {}'.format(cidr, az_name))
            subnet = self.evpc.create_subnet(CidrBlock=str(cidr),
                                             AvailabilityZone=az_name)
            self.log.emit('tagging subnet (Name:{})'.format(longname), 'debug')
            update_tags(
                subnet,
                Name=longname,
                description=sn.get('description', ''),
            )

            if sn.get('public', False) == True:
                # Modify the subnet's public IP addressing behavior.
                msg_mod = 'modifying subnet to map public IPs on instance launch ({})'
                self.log.emit(msg_mod.format(longname))
                self.boto.ec2_client.modify_subnet_attribute(
                    SubnetId=subnet.id,
                    MapPublicIpOnLaunch={'Value': True},
                )
示例#27
0
 def _update_key_pairs_tag(self, key_names):
     update_tags(self.evpc, key_pairs=",".join(key_names))
示例#28
0
 def tag_instance_volumes(self, instance):
     """Accept an EnrichedInstance, tag all attached volumes."""
     msg = 'tagging volumes for instance {} (Name:{})'
     for volume in instance.volumes.all():
         self.log.emit(msg.format(instance.identity, instance.identity))
         update_tags(volume, Name = instance.identity)
示例#29
0
    def instance_role(self, role_name, role_data, desired_count):

        if role_data.get('autoscaling', False) == True:
            # exit early if this instance_role is autoscaling.
            return []

        self.log.emit('creating role: {}'.format(role_name))
        ami = self.amis[role_data['ami']][self.evpc.region_name]

        key_pair = self.evpc.key_pair.get_key_pair(
                       role_data.get('key_pair', 'default')
                   )

        security_groups = map(
            self.evpc.get_security_group,
            role_data.get('security_groups', [])
        )

        subnets = map(
            self.evpc.get_subnet,
            role_data.get('subnets', [])
        )

        if len(subnets) == 0:
            self.log.emit(
                'no subnets found for role: {}'.format(role_name), 'warning'
            )
            # exit early.
            return None

        # sort by subnets by amount of instances, smallest first.
        subnets = sorted(
                      subnets,
                      key = lambda sn : collection_len(sn.instances),
                  )

        # determine the count of this role's existing instances.
        # Note: we look for role in all subnets, not just the listed subnets.
        existing_count = len(self.evpc.get_role(role_name))

        if existing_count >= desired_count:
            # for now we exit early, maybe terminate extras...
            self.log.emit('{} {}'.format(existing_count, desired_count), 'debug')
            return None

        # determine count of additional instances needed to reach desired_count.
        needed_count      = desired_count - existing_count
        needed_per_subnet = desired_count / len(subnets)
        needed_remainder  = desired_count % len(subnets)

        block_device_map = get_block_device_map_from_role_config(role_data)

        role_instances = []

        kwargs = {
          'ImageId'             : ami,
          'InstanceType'        : role_data.get('instance_type'),
          'KeyName'             : key_pair.name,
          'SecurityGroupIds'    : get_ids(security_groups),
          'BlockDeviceMappings' : block_device_map,
          'UserData'            : role_data.get('userdata', ''),
          'IamInstanceProfile'  : {},
        }

        profile_name = role_data.get('instance_profile_name', None)
        if profile_name:
            kwargs['IamInstanceProfile'] = { 'Name' : profile_name }

        for subnet in subnets:
            # ensure Run_Instance_Idempotency.html#client-tokens
            kwargs['ClientToken'] = str(uuid4())

            # figure out how many instances this subnet needs to create ...
            existing_in_subnet = len(self.evpc.get_role(role_name, subnet.instances.all()))
            count = needed_per_subnet - existing_in_subnet

            if needed_remainder != 0:
                needed_remainder -= 1
                count += 1

            if count == 0:
                # skip this subnet, it doesn't need to launch any instances.
                continue

            subnet_name = make_tag_dict(subnet)['Name']
            msg = '{} instances of role {} launching into {} subnet'
            self.log.emit(msg.format(count, role_name, subnet_name))

            # create a batch of instances in subnet!
            kwargs['MinCount'] = kwargs['MaxCount'] = count
            instances = self._create_instances(subnet, **kwargs)

            # accumulate all new instances into a single list.
            role_instances += instances

        # add role tag to each instance.
        for instance in role_instances:
            update_tags(instance, role = role_name)
示例#30
0
    def instance_role(self, role_name, role_data, desired_count):

        if role_data.get("autoscaling", False) == True:
            # exit early if this instance_role is autoscaling.
            return None

        self.log.emit("creating role: {}".format(role_name))
        ami = self.amis[role_data["ami"]][self.evpc.region_name]

        key_pair = self.evpc.key_pair.get_key_pair(role_data.get("key_pair", "default"))

        security_groups = map_filter_false(
            self.evpc.get_security_group, role_data.get("security_groups", [])
        )

        subnets = map_filter_false(self.evpc.get_subnet, role_data.get("subnets", []))

        if len(subnets) == 0:
            self.log.emit("no subnets found for role: {}".format(role_name), "warning")
            # exit early.
            return None

        # sort by subnets by amount of instances, smallest first.
        subnets = sorted(subnets, key=lambda sn: collection_len(sn.instances))

        # determine the count of this role's existing instances.
        # Note: we look for role in all subnets, not just the listed subnets.
        existing_count = len(self.evpc.get_role(role_name))

        if existing_count >= desired_count:
            # for now we exit early, maybe terminate extras...
            msg = "skipping role: {} (existing_count {} is greater than or equal to {})"
            self.log.emit(msg.format(role_name, existing_count, desired_count), "debug")
            return None

        # determine count of additional instances needed to reach desired_count.
        needed_count = desired_count - existing_count
        needed_per_subnet = desired_count / len(subnets)
        needed_remainder = desired_count % len(subnets)

        block_device_map = get_block_device_map_from_role_config(role_data)

        role_instances = []

        kwargs = {
            "ImageId": ami,
            "InstanceType": role_data.get("instance_type"),
            "KeyName": key_pair.name,
            "SecurityGroupIds": get_ids(security_groups),
            "BlockDeviceMappings": block_device_map,
            "UserData": role_data.get("userdata", ""),
            "IamInstanceProfile": {},
        }

        profile_name = role_data.get("instance_profile_name", None)
        if profile_name:
            kwargs["IamInstanceProfile"] = {"Name": profile_name}

        private_ip_address = role_data.get("private_ip_address", None)
        if private_ip_address:
            kwargs["PrivateIpAddress"] = private_ip_address

        for subnet in subnets:
            # ensure Run_Instance_Idempotency.html#client-tokens
            kwargs["ClientToken"] = str(uuid4())

            # figure out how many instances this subnet needs to create ...
            existing_in_subnet = len(
                self.evpc.get_role(role_name, subnet.instances.all())
            )
            count = needed_per_subnet - existing_in_subnet

            if needed_remainder != 0:
                needed_remainder -= 1
                count += 1

            if count == 0:
                # skip this subnet, it doesn't need to launch any instances.
                continue

            subnet_name = make_tag_dict(subnet)["Name"]
            msg = "{} instances of role {} launching into {} subnet"
            self.log.emit(msg.format(count, role_name, subnet_name))

            # create a batch of instances in subnet!
            kwargs["MinCount"] = kwargs["MaxCount"] = count
            instances = self._create_instances(subnet, **kwargs)

            # accumulate all new instances into a single list.
            role_instances += instances

        # add role tag to each instance.
        for instance in role_instances:
            update_tags(instance, role=role_name)
示例#31
0
 def tag_instance_volumes(self, instance):
     """Accept an EnrichedInstance, tag all attached volumes."""
     msg = 'tagging volumes for instance {} (Name:{})'
     for volume in instance.volumes.all():
         self.log.emit(msg.format(instance.identity, instance.identity))
         update_tags(volume, Name=instance.identity)
示例#32
0
    def instance_role(self, role_name, role_data, desired_count):

        if role_data.get('autoscaling', False) == True:
            # exit early if this instance_role is autoscaling.
            return None

        self.log.emit('creating role: {}'.format(role_name))
        ami = self.amis[role_data['ami']][self.evpc.region_name]

        key_pair = self.evpc.key_pair.get_key_pair(
            role_data.get('key_pair', 'default'))

        security_groups = map_filter_false(
            self.evpc.get_security_group, role_data.get('security_groups', []))

        subnets = map_filter_false(self.evpc.get_subnet,
                                   role_data.get('subnets', []))

        if len(subnets) == 0:
            self.log.emit('no subnets found for role: {}'.format(role_name),
                          'warning')
            # exit early.
            return None

        # sort by subnets by amount of instances, smallest first.
        subnets = sorted(
            subnets,
            key=lambda sn: collection_len(sn.instances),
        )

        # determine the count of this role's existing instances.
        # Note: we look for role in all subnets, not just the listed subnets.
        existing_count = len(self.evpc.get_role(role_name))

        if existing_count >= desired_count:
            # for now we exit early, maybe terminate extras...
            msg = 'skipping role: {} (existing_count {} is greater than or equal to {})'
            self.log.emit(msg.format(role_name, existing_count, desired_count),
                          'debug')
            return None

        # determine count of additional instances needed to reach desired_count.
        needed_count = desired_count - existing_count
        needed_per_subnet = desired_count / len(subnets)
        needed_remainder = desired_count % len(subnets)

        block_device_map = get_block_device_map_from_role_config(role_data)

        role_instances = []

        kwargs = {
            'ImageId': ami,
            'InstanceType': role_data.get('instance_type'),
            'KeyName': key_pair.name,
            'SecurityGroupIds': get_ids(security_groups),
            'BlockDeviceMappings': block_device_map,
            'UserData': role_data.get('userdata', ''),
            'IamInstanceProfile': {},
        }

        profile_name = role_data.get('instance_profile_name', None)
        if profile_name:
            kwargs['IamInstanceProfile'] = {'Name': profile_name}

        for subnet in subnets:
            # ensure Run_Instance_Idempotency.html#client-tokens
            kwargs['ClientToken'] = str(uuid4())

            # figure out how many instances this subnet needs to create ...
            existing_in_subnet = len(
                self.evpc.get_role(role_name, subnet.instances.all()))
            count = needed_per_subnet - existing_in_subnet

            if needed_remainder != 0:
                needed_remainder -= 1
                count += 1

            if count == 0:
                # skip this subnet, it doesn't need to launch any instances.
                continue

            subnet_name = make_tag_dict(subnet)['Name']
            msg = '{} instances of role {} launching into {} subnet'
            self.log.emit(msg.format(count, role_name, subnet_name))

            # create a batch of instances in subnet!
            kwargs['MinCount'] = kwargs['MaxCount'] = count
            instances = self._create_instances(subnet, **kwargs)

            # accumulate all new instances into a single list.
            role_instances += instances

        # add role tag to each instance.
        for instance in role_instances:
            update_tags(instance, role=role_name)
示例#33
0
 def _update_key_pairs_tag(self, key_names):
     update_tags(self.evpc, key_pairs = ','.join(key_names))