CloudVE/cloudbridge

Possibility to launch instances with public IPs

selshowk opened this issue · 7 comments

Assigning a public IP directly to an instance is simpler than using a floating IP (e.g. elastic IPs in AWS have stringent limits).

On AWS it seems like we can launch an instance with a public IP simply by setting a flag in thenetwork section of "create_instances" boto call. I'm not sure if GCP or Azure have similar flags but it would be useful to be able to pass in this flag either directly in the InstanceService.create() function or via a kwarg that's passed through by the AWS implementation (and maybe the others). This is done for e.g. the iam_instance_profile now. Is there a reason not to do this or would there be a better way to do it?

@afgane @almahmoud Any thoughts on this issue?

Here is a working minimal modification for the instance create function in AWS provider. In this case implementation I use a flag to determine whether to use a public IP but it could, in principle, be in the kwargs:

def create(self, label, image, vm_type, subnet,
           key_pair=None, vm_firewalls=None, user_data=None,
           launch_config=None, 
           associate_public_ip = False,
           **kwargs):
    AWSInstance.assert_valid_resource_label(label)
    image_id = image.id if isinstance(image, MachineImage) else image
    vm_size = vm_type.id if \
        isinstance(vm_type, VMType) else vm_type
    subnet = (self.provider.networking.subnets.get(subnet)
              if isinstance(subnet, str) else subnet)
    zone_name = self.provider.zone_name
    key_pair_name = key_pair.name if isinstance(
        key_pair,
        KeyPair) else key_pair
    if launch_config:
        bdm = self._process_block_device_mappings(launch_config)
    else:
        bdm = None

    subnet_id, zone_id, vm_firewall_ids = \
        self._resolve_launch_options(subnet, zone_name, vm_firewalls)

    placement = {'AvailabilityZone': zone_id} if zone_id else None
    network_interfaces = [{
            'DeviceIndex': 0,
            'SubnetId' : f"{subnet_id}",
            'Groups': vm_firewall_ids,
            'AssociatePublicIpAddress': True,
            'DeleteOnTermination': True,
        }] if associate_public_ip else None
    # if using a network interface we don't set subnet or groups
    if network_interfaces:
        vm_firewall_ids = None
        subnet_id = None
    inst = self.svc.create(
        'create_instances',
        ImageId=image_id,
        MinCount=1,
        MaxCount=1,
        KeyName=key_pair_name,
        SecurityGroupIds=vm_firewall_ids or None,
        UserData=str(user_data) or None,
        InstanceType=vm_size,
        Placement=placement,
        BlockDeviceMappings=bdm,
        SubnetId=subnet_id,
        IamInstanceProfile=kwargs.pop('iam_instance_profile', None),
        NetworkInterfaces=network_interfaces
    )
    if inst and len(inst) == 1:
        # Wait until the resource exists
        # pylint:disable=protected-access
        inst[0]._wait_till_exists()
        # Tag the instance w/ the name
        inst[0].label = label
        return inst[0]
    raise ValueError(
        'Expected a single object response, got a list: %s' % inst)

I've skimmed the azure implementation and I think a similar thing can be accomplished by setting a public ip in the nic_params as done e.g. here. Though from that link it seems the address might have to be created manually for azure.

@selshowk I'm not sure we'll be able to introduce a top level parameter, since it probably won't be possible to make this work in a cloud-independent way. In the MS sample you sent for example, there's logic for manually creating a public ip. OpenStack's public ip assignment is network dependent, and the standard way is to use a floating ip.

We'd be happy to accept to a PR through kwargs for AWS though. (in the same way that iam_instance_profile is handled)

Ok, I am currently implementing a multi-cloud solution using cloudbridge and will try to provide PRs for the above functionality as I figure out how/if its possible for each provider.

@selshowk Is this still an issue?

I haven't generated a PR yet and the functionality is not yet there so not sure. Feel free to keep/close it as you like.

@selshowk No worries, take your time. I'll keep this open and we can include this in a patch release.