Repository: aws/aws-cli

Issue:
--associate-public-ip-address option with --security-group-ids
#501 #502

when I ran command with --subnet-id, it works fine but when I add --security-group-ids, it does not work.
It seems that same modifications are required.



Discussion:

Resolving patch:
diff --git a/awscli/customizations/ec2runinstances.py b/awscli/customizations/ec2runinstances.py
--- a/awscli/customizations/ec2runinstances.py
+++ b/awscli/customizations/ec2runinstances.py
@@ -79,22 +79,33 @@ def _check_args(parsed_args, **kwargs):
                 raise ValueError(msg)
 
 
-def _fix_subnet(operation, endpoint, params, **kwargs):
-    # If the user has supplied a --subnet-id option AND we also
-    # have inserted an AssociatePublicIpAddress into the network_interfaces
-    # structure, we need to move the subnetId value down into the
-    # network_interfaces structure or we will get a client error from EC2.
+def _fix_args(operation, endpoint, params, **kwargs):
+    # The RunInstances request provides some parameters
+    # such as --subnet-id and --security-group-id that can be specified
+    # as separate options only if the request DOES NOT include a
+    # NetworkInterfaces structure.  In those cases, the values for
+    # these parameters must be specified inside the NetworkInterfaces
+    # structure.  This function checks for those parameters
+    # and fixes them if necessary.
+    # NOTE: If the user is a default VPC customer, RunInstances
+    # allows them to specify the security group by name or by id.
+    # However, in this scenario we can only support id because
+    # we can't place a group name in the NetworkInterfaces structure.
     if 'network_interfaces' in params:
         ni = params['network_interfaces']
         if 'AssociatePublicIpAddress' in ni[0]:
             if 'subnet_id' in params:
                 ni[0]['SubnetId'] = params['subnet_id']
                 del params['subnet_id']
+            if 'security_group_ids' in params:
+                ni[0]['Groups'] = params['security_group_ids']
+                del params['security_group_ids']
+
 
 EVENTS = [
     ('building-argument-table.ec2.run-instances', _add_params),
     ('operation-args-parsed.ec2.run-instances', _check_args),
-    ('before-parameter-build.ec2.RunInstances', _fix_subnet),
+    ('before-parameter-build.ec2.RunInstances', _fix_args),
     ]
 
 


Test patch:
diff --git a/tests/unit/ec2/test_run_instances.py b/tests/unit/ec2/test_run_instances.py
--- a/tests/unit/ec2/test_run_instances.py
+++ b/tests/unit/ec2/test_run_instances.py
@@ -163,3 +163,31 @@ def test_subnet_alone(self):
         }
         self.assert_params_for_cmd(args_list, result)
 
+    def test_associate_public_ip_address_and_group_id(self):
+        args = ' --image-id ami-foobar --count 1 '
+        args += '--security-group-id sg-12345678 '
+        args += '--associate-public-ip-address --subnet-id subnet-12345678'
+        args_list = (self.prefix + args).split()
+        result = {
+            'NetworkInterface.1.DeviceIndex': '0',
+            'NetworkInterface.1.AssociatePublicIpAddress': 'true',
+            'NetworkInterface.1.SubnetId': 'subnet-12345678',
+            'NetworkInterface.1.SecurityGroupId.1': 'sg-12345678',
+            'ImageId': 'ami-foobar',
+            'MaxCount': '1',
+            'MinCount': '1'
+        }
+        self.assert_params_for_cmd(args_list, result)
+
+    def test_group_id_alone(self):
+        args = ' --image-id ami-foobar --count 1 '
+        args += '--security-group-id sg-12345678'
+        args_list = (self.prefix + args).split()
+        result = {
+            'SecurityGroupId.1': 'sg-12345678',
+            'ImageId': 'ami-foobar',
+            'MaxCount': '1',
+            'MinCount': '1'
+        }
+        self.assert_params_for_cmd(args_list, result)
+