Question

I'm attempting to create an instance in another region, but I get this error:

AWS Error Code: InvalidParameterCombination, AWS Error Message: VPC security groups may not be used for a non-VPC launch

Here is the code I'm executing.

RunInstancesRequest instancereq = new RunInstancesRequest();

instancereq.setInstanceType("m3.medium");
instancereq.setImageId("ami-37b1b45e");
instancereq.setMinCount(1);
instancereq.setMaxCount(1);

ArrayList<String> secgroup = new ArrayList<String>();        
instancereq.setKeyName("testkey");          
secgroup.add("testdefault");          
instancereq.setSecurityGroups(secgroup);

instancereq.setPlacement(getAzPlacement());        
RunInstancesResult instanceresult = ec2.runInstances(instancereq);

I've also tried, instead of using the name "testdefault", using the actual groupid (sg-########), but I'll get an error saying that security group doesn't exist (which is wrong, it does). Which, based on the API doc, if using a non-default VPC, you should pass the actual groupid but I'll get an error like this:

InvalidGroup.NotFound, AWS Error Message: The security group 'sg-########' does not exist

If I use "default" as the setSecurityGroups it will use the default VPC. It just doesn't seem like like the groupid I'm passing, despite it being accurate.

Also, if I comment out the setSecurityGroups code, and use setSubnetId instead and pass the subnet id, it will create the instance just fine, but it goes into the "default" security group, not "testdefault" like I want.

All I'm trying to accomplish is creating an instance and having it use the already existing VPC group.

Was it helpful?

Solution

My Answer will focus on below statement:

All I'm trying to accomplish is creating an instance and having it use the already existing VPC group.

So, as I understand, you want to launch an instance in a non-default VPC and assign it an existing VPC security group to it.

I am not a java guy, but I could do what you wanted in ruby as below.

require 'aws-sdk-core'
Aws.config = {
  :access_key_id => "my_access_key",
  :secret_access_key => "my_secret_key",
  :region => 'us-west-2'
}

ec2 = Aws::EC2.new

ec2.run_instances(
    min_count: 1,
    max_count: 1,
    image_id: 'ami-8635a9b6',
    instance_type: 't1.micro',
    placement: {
      availability_zone: 'us-west-2a'
    },
    network_interfaces: [
      {
        subnet_id: 'subnet-e881bd63',
        groups: ['sg-fd53bf5e'],
        device_index: 0,
        associate_public_ip_address: true
      }
    ],
    key_name: 'my-key'
).each do |resp|
  resp.instances.each do |x|
    puts x.instance_id
  end
end

Although this is a Ruby code, it is pretty straight forward and should give you some clear hints on how to go about doing it in Java as all these AWS SDKs are polling the same web service APIs.

I guess, the things that you should be concentrating in above code is:

  :region => 'us-west-2'

and

placement: {
  availability_zone: 'us-west-2a'
},
network_interfaces: [
  {
    subnet_id: 'subnet-e881bd63',
    groups: ['sg-fd53bf5e'],
    device_index: 0,
    associate_public_ip_address: true
  }
],
  1. Make sure you explicitly specify the region.
  2. Check how I have defined the subnet ID and security group ID. This code will launch my EC2 instance in subnet-e881bd63 of my VPC and will apply VPC security group ID sg-fd53bf5e to its 0th network interface. Besides, it will also assign a public IP address to my instance. (by default, it will not assign a public IP address when you launch instances in VPC).
  3. FYI. When you launch instances in VPC, you must provide Security group ID instead of security group name.

OTHER TIPS

This same error occurs using the command line program so I'm adding a separate answer helped by QuickNull. Simply make sure you specify the security group and subnet. For example:

aws ec2 run-instances --image-id ami-XXXXXXXX --count 1 --instance-type t1.micro --key-name XXXXXXXX --security-group-ids sg-XXXXXXXX --subnet-id subnet-XXXXXXXX

You can't specify security group names for VPC launch (setSecurityGroups). For a non-default VPC, you must use security group IDs instead. See EC2 run-instances page (withSecurityGroupIds , or --security-group-ids from CLI).

When you specify a security group for a nondefault VPC to the CLI or the API actions, you must use the security group ID and not the security group name to identify the security group.

See: Security Groups for EC2-VPC

Related:

Thanks to @slayedbylucifer for his ruby code, here's the java solution for reference:

// Creates an instance in the specified subnet of a non-default VPC and using the
// security group with id sg-1234567
ec2.runInstances(new RuntInstancesRequest()
    ...
    .withSubnetId("subnet-1234abcd")
    .withSecurityGroupIds("sg-1234567"));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top