/** * For every NIC creates the {@link InstanceNetworkInterfaceSpecification NIC spec} that should * be created by AWS during provisioning. */ private DeferredResult<AWSInstanceContext> createNicSpecs(AWSInstanceContext context) { /* * Important AWS note: When you add a second network interface, the AWS can no longer * auto-assign a public IPv4 address. You will not be able to connect to the instance over * IPv4 unless you assign an Elastic IP address to the primary network interface (eth0). You * can assign the Elastic IP address after you complete the Launch wizard. * * http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/MultipleIP.html */ // For now create InstanceNetworkInterfaceSpecification _ONLY_ for primary NIC. // Other NICs are just _IGNORED_. AWSNicContext primaryNic = getPrimaryNic(); if (primaryNic != null) { // For now if not specified default to TRUE! if (primaryNic.nicStateWithDesc.description.assignPublicIpAddress == null) { primaryNic.nicStateWithDesc.description.assignPublicIpAddress = Boolean.TRUE; } primaryNic.nicSpec = new InstanceNetworkInterfaceSpecification() .withDeviceIndex(primaryNic.nicStateWithDesc.deviceIndex) .withSubnetId(primaryNic.subnet.getSubnetId()) .withPrivateIpAddress(primaryNic.nicStateWithDesc.address) .withAssociatePublicIpAddress( primaryNic.nicStateWithDesc.description.assignPublicIpAddress); if (primaryNic.securityGroupIds.isEmpty()) { primaryNic.nicSpec.withGroups( AWSUtils.getOrCreateDefaultSecurityGroup(this.amazonEC2Client, primaryNic)); } else { primaryNic.nicSpec.withGroups(primaryNic.securityGroupIds); } } return DeferredResult.completed(context); }
/** * Creates an instance network interface specification based on the specified instance template. * * @param template the instance template * @return instance network interface specification */ private InstanceNetworkInterfaceSpecification getInstanceNetworkInterfaceSpecification( EC2InstanceTemplate template) { InstanceNetworkInterfaceSpecification network = new InstanceNetworkInterfaceSpecification() .withDeviceIndex(0) .withSubnetId(template.getSubnetId()) .withGroups(template.getSecurityGroupIds()) .withDeleteOnTermination(true) .withAssociatePublicIpAddress(associatePublicIpAddresses); LOG.info(">> Network interface specification: {}", network); return network; }
@Override public List<SpotInstanceRequest> call() { LaunchSpecification spec = new LaunchSpecification(); spec.withInstanceType(this.instanceTemplate.getInstanceType()); spec.withImageId(this.instanceTemplate.getAmiId()); InstanceNetworkInterfaceSpecification nic = new InstanceNetworkInterfaceSpecification(); nic.withDeviceIndex(0); // select a subnet at random nic.withSubnetId(randomSubnet()); nic.withAssociatePublicIpAddress(this.instanceTemplate.isAssignPublicIp()); nic.withGroups(this.instanceTemplate.getSecurityGroupIds()); spec.withNetworkInterfaces(nic); spec.withKeyName(this.instanceTemplate.getKeyPair()); spec.withIamInstanceProfile( new IamInstanceProfileSpecification().withArn(this.instanceTemplate.getIamInstanceProfileARN())); spec.withUserData(this.instanceTemplate.getEncodedUserData()); spec.withEbsOptimized(this.instanceTemplate.isEbsOptimized()); RequestSpotInstancesRequest spotRequest = new RequestSpotInstancesRequest().withInstanceCount(this.count) .withType(SpotInstanceType.Persistent).withSpotPrice(this.bidPrice).withLaunchSpecification(spec); RequestSpotInstancesResult result = getClient().getApi().requestSpotInstances(spotRequest); List<String> spotRequestIds = result.getSpotInstanceRequests().stream() .map(SpotInstanceRequest::getSpotInstanceRequestId).collect(Collectors.toList()); if (!this.instanceTemplate.getTags().isEmpty()) { tagRequests(spotRequestIds); } return awaitSpotRequests(spotRequestIds); }
@Override public List<Instance> call() { RunInstancesRequest request = new RunInstancesRequest(); request.withInstanceType(this.instanceTemplate.getInstanceType()); request.withImageId(this.instanceTemplate.getAmiId()); InstanceNetworkInterfaceSpecification nic = new InstanceNetworkInterfaceSpecification(); nic.withDeviceIndex(0); // select a subnet at random nic.withSubnetId(randomSubnet()); nic.withAssociatePublicIpAddress(this.instanceTemplate.isAssignPublicIp()); nic.withGroups(this.instanceTemplate.getSecurityGroupIds()); request.withNetworkInterfaces(nic); request.withKeyName(this.instanceTemplate.getKeyPair()); request.withIamInstanceProfile( new IamInstanceProfileSpecification().withArn(this.instanceTemplate.getIamInstanceProfileARN())); request.withUserData(this.instanceTemplate.getEncodedUserData()); request.withEbsOptimized(this.instanceTemplate.isEbsOptimized()); request.withMinCount(this.count).withMaxCount(this.count); if (!this.instanceTemplate.getTags().isEmpty()) { TagSpecification tagSpecifications = new TagSpecification().withResourceType(ResourceType.Instance); tagSpecifications.withTags(tags()); request.withTagSpecifications(tagSpecifications); } RunInstancesResult result = getClient().getApi().runInstances(request); List<Instance> launchedInstances = result.getReservation().getInstances(); List<String> instanceIds = launchedInstances.stream().map(Instance::getInstanceId).collect(Collectors.toList()); return awaitInstances(instanceIds); }
/** * Get the effective list of AWS NIC Specs that should be created during VM provisioning. */ public List<InstanceNetworkInterfaceSpecification> getAWSNicSpecs() { return this.nics.stream() .map(nic -> nic.nicSpec) .collect(Collectors.toList()); }
/** * Builds a {@code RunInstancesRequest} starting from a template and a virtual instance ID. * Instances will be tagged as they're created. * * @param template the instance template * @param virtualInstanceId the virtual instance IDs * @param userDefinedTags user defined tags to attach to the instance */ @SuppressWarnings("ConstantConditions") private RunInstancesRequest newRunInstancesRequest(EC2InstanceTemplate template, String virtualInstanceId, List<Tag> userDefinedTags) { String image = template.getImage(); String type = template.getType(); InstanceNetworkInterfaceSpecification network = getInstanceNetworkInterfaceSpecification(template); List<BlockDeviceMapping> deviceMappings = getBlockDeviceMappings(template); LOG.info(">> Instance request type: {}, image: {}", type, image); List<Tag> tags = ec2TagHelper.getInstanceTags(template, virtualInstanceId, userDefinedTags); List<TagSpecification> tagSpecifications = Lists.newArrayList( new TagSpecification().withTags(tags).withResourceType(ResourceType.Instance), new TagSpecification().withTags(tags).withResourceType(ResourceType.Volume)); RunInstancesRequest request = new RunInstancesRequest() .withImageId(image) .withInstanceType(type) .withMaxCount(1) .withMinCount(1) .withClientToken(UUID.randomUUID().toString()) .withNetworkInterfaces(network) .withTagSpecifications(tagSpecifications) .withBlockDeviceMappings(deviceMappings) .withEbsOptimized(template.isEbsOptimized()); if (template.getIamProfileName().isPresent()) { request.withIamInstanceProfile(new IamInstanceProfileSpecification() .withName(template.getIamProfileName().get())); } if (template.getKeyName().isPresent()) { request.withKeyName(template.getKeyName().get()); } Placement placement = null; if (template.getAvailabilityZone().isPresent()) { placement = new Placement().withAvailabilityZone(template.getAvailabilityZone().get()); } if (template.getPlacementGroup().isPresent()) { placement = (placement == null) ? new Placement().withGroupName(template.getPlacementGroup().get()) : placement.withGroupName(template.getPlacementGroup().get()); } placement = (placement == null) ? new Placement().withTenancy(template.getTenancy()) : placement.withTenancy(template.getTenancy()); request.withPlacement(placement); Optional<String> userData = template.getUserData(); if (userData.isPresent()) { request.withUserData(userData.get()); } return request; }
/** * Builds a {@code RequestSpotInstancesRequest}. * * @return the {@code RequestSpotInstancesRequest} */ @VisibleForTesting protected RequestSpotInstancesRequest newRequestSpotInstanceRequest(String virtualInstanceId) { String image = template.getImage(); String type = template.getType(); InstanceNetworkInterfaceSpecification network = getInstanceNetworkInterfaceSpecification(template); List<BlockDeviceMapping> deviceMappings = getBlockDeviceMappings(template); LaunchSpecification launchSpecification = new LaunchSpecification() .withImageId(image) .withInstanceType(type) .withNetworkInterfaces(network) .withBlockDeviceMappings(deviceMappings) .withEbsOptimized(template.isEbsOptimized()); if (template.getIamProfileName().isPresent()) { launchSpecification.withIamInstanceProfile(new IamInstanceProfileSpecification() .withName(template.getIamProfileName().get())); } if (template.getKeyName().isPresent()) { launchSpecification.withKeyName(template.getKeyName().get()); } SpotPlacement placement = null; if (template.getAvailabilityZone().isPresent()) { placement = new SpotPlacement().withAvailabilityZone(template.getAvailabilityZone().get()); } if (template.getPlacementGroup().isPresent()) { placement = (placement == null) ? new SpotPlacement().withGroupName(template.getPlacementGroup().get()) : placement.withGroupName(template.getPlacementGroup().get()); } launchSpecification.withPlacement(placement); Optional<String> userData = template.getUserData(); if (userData.isPresent()) { launchSpecification.withUserData(userData.get()); } LOG.info(">> Spot instance request type: {}, image: {}", type, image); RequestSpotInstancesRequest request = new RequestSpotInstancesRequest() .withSpotPrice(template.getSpotBidUSDPerHour().get().toString()) .withLaunchSpecification(launchSpecification) .withInstanceCount(1) .withClientToken(determineClientToken(virtualInstanceId, requestExpirationTime.getTime())) .withValidUntil(requestExpirationTime); Optional<Integer> blockDurationMinutes = template.getBlockDurationMinutes(); if (blockDurationMinutes.isPresent()) { request.withBlockDurationMinutes(blockDurationMinutes.get()); } return request; }
public void sortInstanceNetworkInterfaceSpecification(InstanceNetworkInterfaceSpecification inis) { Collections.sort(inis.getGroups()); Collections.sort(inis.getPrivateIpAddresses(), new PrivateIpAddressSpecificationComparator()); }