aws-sdk-ruby: Using DescribeSecurityGroup IpPermissions in RevokeSecurityGroupIngress Raises Error

Issue description

Passing the ip_permissions property of the result of describe_security_groups to revoke_security_group_ingress results in a server error Aws::EC2::Errors::InvalidParameterValue: missing mandatory parameter: exactly one of remote-security-group, remote-ip-range, remote-ipv6-range, or prefix-list-id must be present This is due to the definition of rules that reference other security groups that take the format:

{
  :from_port => 0, 
  :ip_protocol => "tcp", 
  :ip_ranges => [], 
  :ipv_6_ranges => [], 
  :prefix_list_ids => [], 
  :to_port => 65535, 
  :user_id_group_pairs => [
    {:group_id => "[elided]", :user_id => "[elided]"}, 
    {:group_id => "[elided]", :user_id => "[elided]"}
  ]
}

There appears to be a mismatch in expectations between the client code and server code since adding dry_run: true to my request results in: Aws::EC2::Errors::DryRunOperation: Request would have succeeded, but DryRun flag is set.

Background

Because of a cyclical dependency issue between EMR-managed security groups, I’m attempting to clear the rules from them before letting CloudFormation delete them. Before my CloudFormation stack delete code runs, I attempt to run DataPipeline#clear_security_group_rules defined below.

Gem name

aws-sdk-ec2 @ 1.27.0 and 1.25.0

Version of Ruby, OS environment

MacOS Sierra, ruby-2.4.2

Code snippets / steps to reproduce

class DataPipeline
  # EMR-managed groups create security groups with cross-dependency rules.
  # The rules need to be removed so CloudFormation can delete the security groups
  def clear_security_group_rules
    security_groups.each do |security_group|
      puts security_group.ip_permissions.map(&:to_hash)
      ec2_client.revoke_security_group_ingress(
        group_id: security_group.group_id,
        ip_permissions: security_group.ip_permissions
      )
    end
  end

  def security_groups
    ec2_client.describe_security_groups(
      group_ids: ['sg-af0264d0', 'sg-bd0f69c2'] # Hard-coded here to reduce irrelevant code
    ).security_groups
  end

  def ec2_client
    @ec2_client ||= Aws::EC2::Client.new
  end
end


pipeline = DataPipeline.new
pipeline.clear_security_group_rules
# Prints:
#   {:from_port=>0, :ip_protocol=>"tcp", :ip_ranges=>[], :ipv_6_ranges=>[], :prefix_list_ids=>[], :to_port=>65535, :user_id_group_pairs=>[{:group_id=>"[elided]", :user_id=>"[elided]"}, {:group_id=>"[elided]", :user_id=>"[elided]"}]}
#   {:from_port=>0, :ip_protocol=>"udp", :ip_ranges=>[], :ipv_6_ranges=>[], :prefix_list_ids=>[], :to_port=>65535, :user_id_group_pairs=>[{:group_id=>"[elided]", :user_id=>"[elided]"}, {:group_id=>"[elided]", :user_id=>"[elided]"}]}
#   {:from_port=>-1, :ip_protocol=>"icmp", :ip_ranges=>[], :ipv_6_ranges=>[], :prefix_list_ids=>[], :to_port=>-1, :user_id_group_pairs=>[{:group_id=>"[elided]", :user_id=>"[elided]"}, {:group_id=>"[elided]", :user_id=>"[elided]"}]}
# Raises:
#   Aws::EC2::Errors::InvalidParameterValue: missing mandatory parameter: exactly one of remote-security-group, remote-ip-range, remote-ipv6-range, or prefix-list-id must be present

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 21 (9 by maintainers)

Most upvoted comments

It appears that removing the “empty” key/value pairs fixes the issue. Reconstructing a new hash (rather than using to_hash, which includes :ip_ranges=>[], :ipv_6_ranges=>[], :prefix_list_ids=>[],) succeeds. The error “missing parameter” is doubly infuriating since I included too many of them.