Repository: aws/aws-cli

Issue:
Cannot Revoke EC2 Security Group ICMP Rule That Was Added Via AWS Management Console
I made a test security group in the AWS EC2 Management Console with one rule: Inbound, Type: Custom ICMP Rule, Protocol: Echo Request, Source: Custom IP: 8.8.8.8.

Using the AWS CLI, I can see the rule, with ToPort and FromPort being different from each other

``` bash
aws --output json ec2 describe-security-groups --group-names testingicmp
```

``` json
{
    "SecurityGroups": [
        {
            "IpPermissionsEgress": [], 
            "Description": "Testing ICMP", 
            "IpPermissions": [
                {
                    "ToPort": -1, 
                    "IpProtocol": "icmp", 
                    "IpRanges": [
                        {
                            "CidrIp": "8.8.8.8/32"
                        }
                    ], 
                    "UserIdGroupPairs": [], 
                    "FromPort": 8
                }
            ], 
            "GroupName": "testingicmp", 
            "OwnerId": "618125783243", 
            "GroupId": "sg-5387753e"
        }
    ]
}
```

Both of these attempts return nothing and describing the security group again shows that it's still there.

``` bash
aws --output json ec2 revoke-security-group-ingress --group-name testingicmp --protocol icmp --port 8 --cidr 8.8.8.8/32
aws --output json ec2 revoke-security-group-ingress --group-name testingicmp --protocol icmp --port -1 --cidr 8.8.8.8/32
```

This one results in an error. I've pasted the debug from this further down.

``` bash
aws --output json ec2 revoke-security-group-ingress --group-name testingicmp --protocol icmp --from-port 8 --to-port -1 --cidr 8.8.8.8/32
```

```
A client error (InvalidParameterCombination) occurred when calling the RevokeSecurityGroupIngress operation: The parameter 'ipPermissions' may not be used in combination with 'fromPort'
```

If I try to add a similar rule, these return nothing.

``` bash
aws --output json ec2 authorize-security-group-ingress --group-name testingicmp --protocol icmp --port 8 --cidr 8.8.4.4/32
aws --output json ec2 authorize-security-group-ingress --group-name testingicmp --protocol icmp --port -1 --cidr 8.8.4.4/32
```

And this one gets a similar error.

``` bash
aws --output json ec2 authorize-security-group-ingress --group-name testingicmp --protocol icmp --from-port 8 --to-port -1 --cidr 8.8.4.4/32
```

```
A client error (InvalidParameterCombination) occurred when calling the AuthorizeSecurityGroupIngress operation: The parameter 'ipPermissions' may not be used in combination with 'fromPort'
```

Describing the group again, I see that the first two work, but do not match the AWS Management Console regarding ToPort and FromPort

``` bash
aws --output json ec2 describe-security-groups --group-names testingicmp
```

``` json
{
    "SecurityGroups": [
        {
            "IpPermissionsEgress": [], 
            "Description": "Testing ICMP", 
            "IpPermissions": [
                {
                    "ToPort": -1, 
                    "IpProtocol": "icmp", 
                    "IpRanges": [
                        {
                            "CidrIp": "8.8.4.4/32"
                        }
                    ], 
                    "UserIdGroupPairs": [], 
                    "FromPort": -1
                }, 
                {
                    "ToPort": 8, 
                    "IpProtocol": "icmp", 
                    "IpRanges": [
                        {
                            "CidrIp": "8.8.4.4/32"
                        }
                    ], 
                    "UserIdGroupPairs": [], 
                    "FromPort": 8
                }, 
                {
                    "ToPort": -1, 
                    "IpProtocol": "icmp", 
                    "IpRanges": [
                        {
                            "CidrIp": "8.8.8.8/32"
                        }
                    ], 
                    "UserIdGroupPairs": [], 
                    "FromPort": 8
                }
            ], 
            "GroupName": "testingicmp", 
            "OwnerId": "618125783243", 
            "GroupId": "sg-5387753e"
        }
    ]
}
```

I'm running the latest AWS CLI release and Python 2.7.

``` bash
aws --version
```

```
aws-cli/1.3.25 Python/2.7.8 Linux/3.17.7-300.fc21.x86_64
```

Here is the revoke command that gets an error, with debugging enabled.

``` bash
aws --debug --output json ec2 revoke-security-group-ingress --group-name testingicmp --protocol icmp --from-port 8 --to-port -1 --cidr 8.8.8.8/32
```

```
2014-12-30 15:27:33,378 - MainThread - awscli.clidriver - DEBUG - CLI version: aws-cli/1.6.10 Python/2.7.8 Linux/3.17.7-300.fc21.x86_64, botocore version: 0.80.0
2014-12-30 15:27:33,378 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function add_scalar_parsers at 0x7fa461ddded8>
2014-12-30 15:27:33,378 - MainThread - botocore.hooks - DEBUG - Event session-initialized: calling handler <function inject_assume_role_provider at 0x7fa4622362a8>
2014-12-30 15:27:33,378 - MainThread - botocore.service - DEBUG - Creating service object for: ec2
2014-12-30 15:27:33,451 - MainThread - botocore.hooks - DEBUG - Event service-data-loaded.ec2: calling handler <function register_retries_for_service at 0x7fa462a37320>
2014-12-30 15:27:33,458 - MainThread - botocore.handlers - DEBUG - Registering retry handlers for service: ec2
2014-12-30 15:27:33,458 - MainThread - botocore.hooks - DEBUG - Event service-data-loaded.ec2: calling handler <function signature_overrides at 0x7fa462a37488>
2014-12-30 15:27:33,458 - MainThread - botocore.hooks - DEBUG - Event service-data-loaded.ec2: calling handler <function register_retries_for_service at 0x7fa462a37320>
2014-12-30 15:27:33,459 - MainThread - botocore.handlers - DEBUG - Registering retry handlers for service: ec2
2014-12-30 15:27:33,459 - MainThread - botocore.hooks - DEBUG - Event service-data-loaded.ec2: calling handler <function signature_overrides at 0x7fa462a37488>
2014-12-30 15:27:33,459 - MainThread - botocore.service - DEBUG - Creating operation objects for: Service(ec2)
2014-12-30 15:27:33,474 - MainThread - botocore.hooks - DEBUG - Event building-command-table.ec2: calling handler <functools.partial object at 0x7fa461df5578>
2014-12-30 15:27:33,474 - MainThread - awscli.customizations.removals - DEBUG - Removing operation: import-instance
2014-12-30 15:27:33,474 - MainThread - awscli.customizations.removals - DEBUG - Removing operation: import-volume
2014-12-30 15:27:33,474 - MainThread - botocore.hooks - DEBUG - Event building-command-table.ec2: calling handler <function add_waiters at 0x7fa462236de8>
2014-12-30 15:27:33,477 - MainThread - awscli.clidriver - DEBUG - OrderedDict([(u'dry-run', <awscli.arguments.BooleanArgument object at 0x7fa461d4e310>), (u'no-dry-run', <awscli.arguments.BooleanArgument object at 0x7fa461d4e350>), (u'group-name', <awscli.arguments.CLIArgument object at 0x7fa461d4e390>), (u'group-id', <awscli.arguments.CLIArgument object at 0x7fa461d4e3d0>), (u'source-security-group-name', <awscli.arguments.CLIArgument object at 0x7fa461d4e410>), (u'source-security-group-owner-id', <awscli.arguments.CLIArgument object at 0x7fa461d4e450>), (u'ip-protocol', <awscli.arguments.CLIArgument object at 0x7fa461d4e490>), (u'from-port', <awscli.arguments.CLIArgument object at 0x7fa461d4e4d0>), (u'to-port', <awscli.arguments.CLIArgument object at 0x7fa461d4e510>), (u'cidr-ip', <awscli.arguments.CLIArgument object at 0x7fa461d4e550>), (u'ip-permissions', <awscli.arguments.ListArgument object at 0x7fa461d4e590>)])
2014-12-30 15:27:33,478 - MainThread - botocore.hooks - DEBUG - Event building-argument-table.ec2.revoke-security-group-ingress: calling handler <function add_streaming_output_arg at 0x7fa4623719b0>
2014-12-30 15:27:33,478 - MainThread - botocore.hooks - DEBUG - Event building-argument-table.ec2.revoke-security-group-ingress: calling handler <function _rename_arg at 0x7fa461df0b90>
2014-12-30 15:27:33,478 - MainThread - botocore.hooks - DEBUG - Event building-argument-table.ec2.revoke-security-group-ingress: calling handler <function _rename_arg at 0x7fa461df0c80>
2014-12-30 15:27:33,478 - MainThread - botocore.hooks - DEBUG - Event building-argument-table.ec2.revoke-security-group-ingress: calling handler <functools.partial object at 0x7fa461df5fc8>
2014-12-30 15:27:33,479 - MainThread - botocore.hooks - DEBUG - Event building-argument-table.ec2.revoke-security-group-ingress: calling handler <function _add_params at 0x7fa46232f1b8>
2014-12-30 15:27:33,479 - MainThread - botocore.hooks - DEBUG - Event building-argument-table.ec2.revoke-security-group-ingress: calling handler <function add_cli_input_json at 0x7fa462227578>
2014-12-30 15:27:33,479 - MainThread - botocore.hooks - DEBUG - Event building-argument-table.ec2.revoke-security-group-ingress: calling handler <function unify_paging_params at 0x7fa4623919b0>
2014-12-30 15:27:33,480 - MainThread - botocore.hooks - DEBUG - Event building-argument-table.ec2.revoke-security-group-ingress: calling handler <function add_generate_skeleton at 0x7fa4622272a8>
2014-12-30 15:27:33,480 - MainThread - botocore.hooks - DEBUG - Event before-building-argument-table-parser.ec2.revoke-security-group-ingress: calling handler <bound method CliInputJSONArgument.override_required_args of <awscli.customizations.cliinputjson.CliInputJSONArgument object at 0x7fa461d4ea50>>
2014-12-30 15:27:33,480 - MainThread - botocore.hooks - DEBUG - Event before-building-argument-table-parser.ec2.revoke-security-group-ingress: calling handler <bound method GenerateCliSkeletonArgument.override_required_args of <awscli.customizations.generatecliskeleton.GenerateCliSkeletonArgument object at 0x7fa461d2ddd0>>
2014-12-30 15:27:33,481 - MainThread - botocore.hooks - DEBUG - Event operation-args-parsed.ec2.revoke-security-group-ingress: calling handler <functools.partial object at 0x7fa46181acb0>
2014-12-30 15:27:33,482 - MainThread - botocore.hooks - DEBUG - Event operation-args-parsed.ec2.revoke-security-group-ingress: calling handler <function _check_args at 0x7fa46232f230>
2014-12-30 15:27:33,482 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.dry-run: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,482 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.group-name: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,482 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.ec2.revoke-security-group-ingress: calling handler <awscli.argprocess.ParamShorthand object at 0x7fa461de87d0>
2014-12-30 15:27:33,482 - MainThread - awscli.argprocess - DEBUG - Detected structure: scalar
2014-12-30 15:27:33,482 - MainThread - awscli.arguments - DEBUG - Unpacked value of u'testingicmp' for parameter "group_name": u'testingicmp'
2014-12-30 15:27:33,482 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.group-id: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,482 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.source-security-group-name: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,482 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.source-security-group-owner-id: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,483 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.ip-protocol: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,483 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.from-port: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,483 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.ec2.revoke-security-group-ingress: calling handler <awscli.argprocess.ParamShorthand object at 0x7fa461de87d0>
2014-12-30 15:27:33,483 - MainThread - awscli.argprocess - DEBUG - Detected structure: scalar
2014-12-30 15:27:33,483 - MainThread - awscli.arguments - DEBUG - Unpacked value of u'8' for parameter "from_port": 8
2014-12-30 15:27:33,483 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.to-port: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,483 - MainThread - botocore.hooks - DEBUG - Event process-cli-arg.ec2.revoke-security-group-ingress: calling handler <awscli.argprocess.ParamShorthand object at 0x7fa461de87d0>
2014-12-30 15:27:33,483 - MainThread - awscli.argprocess - DEBUG - Detected structure: scalar
2014-12-30 15:27:33,483 - MainThread - awscli.arguments - DEBUG - Unpacked value of u'-1' for parameter "to_port": -1
2014-12-30 15:27:33,483 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.cidr-ip: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,483 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.ip-permissions: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.protocol: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.port: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.cidr: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.source-group: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.group-owner: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.cli-input-json: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ec2.revoke-security-group-ingress.generate-cli-skeleton: calling handler <function uri_param at 0x7fa4623c8d70>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event calling-command.ec2.revoke-security-group-ingress: calling handler <bound method GenerateCliSkeletonArgument.generate_json_skeleton of <awscli.customizations.generatecliskeleton.GenerateCliSkeletonArgument object at 0x7fa461d2ddd0>>
2014-12-30 15:27:33,484 - MainThread - botocore.hooks - DEBUG - Event calling-command.ec2.revoke-security-group-ingress: calling handler <bound method CliInputJSONArgument.add_to_call_parameters of <awscli.customizations.cliinputjson.CliInputJSONArgument object at 0x7fa461d4ea50>>
2014-12-30 15:27:33,484 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: env
2014-12-30 15:27:33,485 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: assume-role
2014-12-30 15:27:33,485 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: shared-credentials-file
2014-12-30 15:27:33,485 - MainThread - botocore.credentials - DEBUG - Looking for credentials via: config-file
2014-12-30 15:27:33,486 - MainThread - botocore.credentials - INFO - Credentials found in config file: ~/.aws/config
2014-12-30 15:27:33,487 - MainThread - botocore.operation - DEBUG - Operation:RevokeSecurityGroupIngress called with kwargs: {u'ToPort': -1, u'GroupName': u'testingicmp', 'ip_permissions': [{'IpProtocol': u'icmp', 'IpRanges': [{'CidrIp': u'8.8.8.8/32'}]}], u'FromPort': 8}
2014-12-30 15:27:33,488 - MainThread - botocore.endpoint - DEBUG - Making request for <botocore.model.OperationModel object at 0x7fa461d8d650> (verify_ssl=True) with params: {'query_string': '', 'headers': {}, 'url_path': '/', 'body': {u'FromPort': 8, u'GroupName': u'testingicmp', u'IpPermissions.1.IpRanges.1.CidrIp': u'8.8.8.8/32', u'IpPermissions.1.IpProtocol': u'icmp', u'ToPort': -1, 'Version': u'2014-10-01', 'Action': u'RevokeSecurityGroupIngress'}, 'method': u'POST'}
2014-12-30 15:27:33,489 - MainThread - botocore.auth - DEBUG - Calculating signature using v4 auth.
2014-12-30 15:27:33,489 - MainThread - botocore.auth - DEBUG - CanonicalRequest:
POST
/

host:ec2.us-east-1.amazonaws.com
user-agent:aws-cli/1.6.10 Python/2.7.8 Linux/3.17.7-300.fc21.x86_64
x-amz-date:20141230T202733Z

host;user-agent;x-amz-date
5e834b9b723192c8a6ec022405624471eadcbb3909f7e8f2ff11b3795fe97a36
2014-12-30 15:27:33,489 - MainThread - botocore.auth - DEBUG - StringToSign:
AWS4-HMAC-SHA256
20141230T202733Z
20141230/us-east-1/ec2/aws4_request
8bdf3d1f589178a78bfa831893eaa194bf23a812f250b6988b9257e56b420764
2014-12-30 15:27:33,489 - MainThread - botocore.auth - DEBUG - Signature:
d79376a375bba9d7d25d2ed41853bd7c681b5bc3f69fc5a8899f6692adb47620
2014-12-30 15:27:33,494 - MainThread - botocore.endpoint - DEBUG - Sending http request: <PreparedRequest [POST]>
2014-12-30 15:27:33,495 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - INFO - Starting new HTTPS connection (1): ec2.us-east-1.amazonaws.com
2014-12-30 15:27:34,024 - MainThread - botocore.vendored.requests.packages.urllib3.connectionpool - DEBUG - "POST / HTTP/1.1" 400 None
2014-12-30 15:27:34,026 - MainThread - botocore.parsers - DEBUG - Response headers:
{'cneonction': 'close',
 'date': 'Tue, 30 Dec 2014 20:27:33 GMT',
 'server': 'AmazonEC2',
 'transfer-encoding': 'chunked'}
2014-12-30 15:27:34,026 - MainThread - botocore.parsers - DEBUG - Response body:
<?xml version="1.0" encoding="UTF-8"?>
<Response><Errors><Error><Code>InvalidParameterCombination</Code><Message>The parameter 'ipPermissions' may not be used in combination with 'fromPort'</Message></Error></Errors><RequestID>3bf79ad0-f5be-4915-a091-487b3619b410</RequestID></Response>
2014-12-30 15:27:34,026 - MainThread - botocore.hooks - DEBUG - Event needs-retry.ec2.RevokeSecurityGroupIngress: calling handler <botocore.retryhandler.RetryHandler object at 0x7fa4618cf950>
2014-12-30 15:27:34,026 - MainThread - botocore.retryhandler - DEBUG - No retry needed.
2014-12-30 15:27:34,027 - MainThread - botocore.hooks - DEBUG - Event after-call.ec2.RevokeSecurityGroupIngress: calling handler <awscli.errorhandler.ErrorHandler object at 0x7fa461de8810>
2014-12-30 15:27:34,027 - MainThread - awscli.errorhandler - DEBUG - HTTP Response Code: 400
2014-12-30 15:27:34,027 - MainThread - awscli.clidriver - DEBUG - Exception caught in main()
Traceback (most recent call last):
  File "/usr/local/aws/lib/python2.7/site-packages/awscli/clidriver.py", line 197, in main
    return command_table[parsed_args.command](remaining, parsed_args)
  File "/usr/local/aws/lib/python2.7/site-packages/awscli/clidriver.py", line 357, in __call__
    return command_table[parsed_args.operation](remaining, parsed_globals)
  File "/usr/local/aws/lib/python2.7/site-packages/awscli/clidriver.py", line 492, in __call__
    self._operation_object, call_parameters, parsed_globals)
  File "/usr/local/aws/lib/python2.7/site-packages/awscli/clidriver.py", line 597, in invoke
    **parameters)
  File "/usr/local/aws/lib/python2.7/site-packages/botocore/operation.py", line 98, in call
    parsed=response[1])
  File "/usr/local/aws/lib/python2.7/site-packages/botocore/session.py", line 735, in emit
    return self._events.emit(event_name, **kwargs)
  File "/usr/local/aws/lib/python2.7/site-packages/botocore/hooks.py", line 182, in emit
    response = handler(**kwargs)
  File "/usr/local/aws/lib/python2.7/site-packages/awscli/errorhandler.py", line 70, in __call__
    http_status_code=http_response.status_code)
ClientError: A client error (InvalidParameterCombination) occurred when calling the RevokeSecurityGroupIngress operation: The parameter 'ipPermissions' may not be used in combination with 'fromPort'
2014-12-30 15:27:34,029 - MainThread - awscli.clidriver - DEBUG - Exiting with rc 255

A client error (InvalidParameterCombination) occurred when calling the RevokeSecurityGroupIngress operation: The parameter 'ipPermissions' may not be used in combination with 'fromPort'
```



Discussion:
Thanks for all the debug info, it's really helpful.

To revoke this rule, at the API level, we need to specify a FromPort of 8 and a ToPort of -1.  The `--port` argument has a syntax of `fromport-toport` so the syntax _should_ be: `--port 8--1`.  However, there's a bug in our parser which isn't expecting the double minus sign that we need to fix.

In the meantime, you can use the `--ip-permissions` option.  This is a more verbose option, but it internally maps to the same API parameter and round trips from the output of the `describe-security-groups` command.  For example:

```
# I have the same rule in your example above:
$ aws ec2 describe-security-groups --group-names TestICMP3 --query SecurityGroups[].IpPermissions[]
[
    {
        "ToPort": -1,
        "IpProtocol": "icmp",
        "IpRanges": [
            {
                "CidrIp": "8.8.8.8/32"
            }
        ],
        "UserIdGroupPairs": [],
        "FromPort": 8
    }
]

# I can feed that into the `--ip-permissions` options.  Note I'll need to enclose this in double quotes:
$ aws ec2 revoke-security-group-ingress --group-name TestICMP3 --ip-permissions "$(aws ec2 describe-security-groups --group-names TestICMP3 --query SecurityGroups[].IpPermissions[])"
$

# And the rule is gone:
$ aws ec2 describe-security-groups --group-names TestICMP3 {
    "SecurityGroups": [
        {
            "IpPermissionsEgress": [],
            "Description": "testicmp3",
            "IpPermissions": [],
            "GroupName": "TestICMP3",
            "OwnerId": "id",
            "GroupId": "id"
        }
    ]
}
```

Thank you for the workaround. I had ended up using the Ruby AWS SDK to do the immediate task, but this would work well too.
I see now that I had missed the documentation specifying range syntax for the port option. Getting this working with -1 will be good.

```
--port (string)
   For  TCP  or UDP: The range of ports to allow. A single integer or a
   range (min-max). You can specify all to mean all ports
```


Resolving patch:
diff --git a/awscli/customizations/ec2secgroupsimplify.py b/awscli/customizations/ec2secgroupsimplify.py
--- a/awscli/customizations/ec2secgroupsimplify.py
+++ b/awscli/customizations/ec2secgroupsimplify.py
@@ -154,7 +154,11 @@ def add_to_params(self, parameters, value):
                     fromstr = '-1'
                     tostr = '-1'
                 elif '-' in value:
-                    fromstr, tostr = value.split('-')
+                    # We can get away with simple logic here because
+                    # argparse will not allow values such as
+                    # "-1-8", and these aren't actually valid
+                    # values any from from/to ports.
+                    fromstr, tostr = value.split('-', 1)
                 else:
                     fromstr, tostr = (value, value)
                 _build_ip_permissions(parameters, 'FromPort', int(fromstr))
diff --git a/awscli/testutils.py b/awscli/testutils.py
--- a/awscli/testutils.py
+++ b/awscli/testutils.py
@@ -345,8 +345,9 @@ def run_cmd(self, cmd, expected_rc=0):
         stdout = captured_stdout.getvalue()
         self.assertEqual(
             rc, expected_rc,
-            "Unexpected rc (expected: %s, actual: %s) for command: %s" % (
-                expected_rc, rc, cmd))
+            "Unexpected rc (expected: %s, actual: %s) for command: %s\n"
+            "stdout:\n%sstderr:\n%s" % (
+                expected_rc, rc, cmd, stdout, stderr))
         return stdout, stderr, rc
 
 


Test patch:
diff --git a/tests/unit/ec2/test_security_group_operations.py b/tests/unit/ec2/test_security_group_operations.py
--- a/tests/unit/ec2/test_security_group_operations.py
+++ b/tests/unit/ec2/test_security_group_operations.py
@@ -36,6 +36,17 @@ def test_all_port(self):
                                        'ToPort': -1}]}
         self.assert_params_for_cmd2(args, result)
 
+    def test_icmp_echo_request(self):
+        # This corresponds to a from port of 8 and a to port of -1, i.e
+        # --port 8--1.
+        args = self.prefix + (
+            '--group-name foobar --protocol tcp --port 8--1 --cidr 0.0.0.0/0')
+        result = {'GroupName': 'foobar',
+                  'ip_permissions': [{'FromPort': 8, 'IpProtocol': 'tcp',
+                                      'IpRanges': [{'CidrIp': '0.0.0.0/0'}],
+                                      'ToPort': -1}]}
+        self.assert_params_for_cmd2(args, result)
+
     def test_all_protocol(self):
         args = self.prefix + (
             '--group-name foobar --protocol all --port all --cidr 0.0.0.0/0')