class AWS::EC2::SecurityGroup

Represents a security group in EC2.

@attr_reader [String] description The short informal description

given when the group was created.

@attr_reader [String] name The name of the security group.

@attr_reader [String] owner_id The security group owner’s id.

@attr_reader [String,nil] vpc_id If this is a VPC security group,

vpc_id is the ID of the VPC this group was created in.
Returns false otherwise.

Constants

IpPermissionCollection

alias for ingress permissions

Attributes

group_id[R]

@return [String] The ID of the security group.

id[R]

@return [String] The ID of the security group.

Public Class Methods

describe_call_name() click to toggle source

@private

# File lib/aws/ec2/security_group.rb, line 325
def self.describe_call_name
  :describe_security_groups
end
new(id, options = {}) click to toggle source
# File lib/aws/ec2/security_group.rb, line 41
def initialize id, options = {}
  @id = id
  super
end

Public Instance Methods

allow_ping(*sources) click to toggle source

Adds ingress rules for ICMP pings. Defaults to 0.0.0.0/0 for the list of allowed IP ranges the ping can come from.

security_group.allow_ping # anyone can ping servers in this group

# only allow ping from a particular address
security_group.allow_ping('123.123.123.123/0')

@param [String] ip_ranges One or more IP ranges to allow ping from.

Defaults to 0.0.0.0/0

@return [nil]

# File lib/aws/ec2/security_group.rb, line 112
def allow_ping *sources
  sources << '0.0.0.0/0' if sources.empty?
  authorize_ingress('icmp', -1, *sources)
end
authorize_egress(*sources) click to toggle source

Authorize egress (outbound) traffic for a VPC security group.

# allow traffic for all protocols/ports from the given sources
security_group.authorize_egress('10.0.0.0/16', '10.0.0.1/16')

# allow tcp traffic outband via port 80
security_group.authorize_egress('10.0.0.0/16',
  :protocol => :tcp, :ports => 80..80)

@note Calling this method on a non-VPC security group raises an error.

@overload #authorize_egress(*sources, options = {})

@param [Mixed] sources One or more CIDR IP addresses,
  security groups or load balancers.  See {#authorize_ingress}
  for more information on accepted formats for sources.

@param [Hash] options

@option options [Symbol] :protocol (:any) The protocol name or number
  to authorize egress traffic for.  For a complete list of protocols
  see: {http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml}

@option options [Range<Integer>,Integer] :ports (nil) An optional
  port or range of ports.  This option is required depending on
  the protocol.

@return [nil]

# File lib/aws/ec2/security_group.rb, line 278
def authorize_egress *sources
  client.authorize_security_group_egress(
    :group_id => id,
    :ip_permissions => [egress_opts(sources)])
  nil
end
authorize_ingress(protocol, ports, *sources) click to toggle source

Add an ingress rules to this security group. Ingress rules permit inbound traffic over a given protocol for a given port range from one or more souce ip addresses.

This example grants the whole internet (0.0.0.0/0) access to port 80 over TCP (HTTP web traffic).

security_group.authorize_ingress(:tcp, 80)

You can specify port ranges as well:

# ftp
security_group.authorize_ingress(:tcp, 20..21)

Sources

Security groups accept ingress trafic from:

  • CIDR IP addresses

  • security groups

  • load balancers

Ip Addresses

In the following example allow incoming SSH from a list of IP address ranges.

security_group.authorize_ingress(:tcp, 22, 
  '111.111.111.111/0', '222.222.222.222/0')

Security Groups

To autohrize ingress traffic from all EC2 instance in another security group, just pass the security group:

web = security_groups.create('webservers')
db = security_groups.create('database')
db.authorize_ingress(:tcp, 3306, web)

You can also pass a hash of security group details instead of a {SecurityGroup} object.

# by security group name
sg.authorize_ingress(:tcp, 80, { :group_name => 'other-group' })

# by security group id
sg.authorize_ingress(:tcp, 80, { :group_id => 'sg-1234567' })

If the security group belongs to a different account, just make sure it has the correct owner ID populated:

not_my_sg = SecurityGroup.new('sg-1234567', :owner_id => 'abcxyz123')
my_sg.authorize_ingress(:tcp, 80, not_my_sg)

You can do the same with a hash as well (with either :group_id or :group_name):

sg.authorize_ingress(:tcp, 21..22, { :group_id => 'sg-id', :user_id => 'abcxyz123' })

Load Balancers

If you use ELB to manage load balancers, then you need to add ingress permissions to the security groups they route traffic into. You can do this by passing the {ELB::LoadBalancer} into #authorize_ingress:

load_balancer = AWS::ELB.new.load_balancers['web-load-balancer']

sg.authorize_ingress(:tcp, 80, load_balancer)

Multiple Sources

You can provide multiple sources each time you call authorize ingress, and you can mix and match the source types:

sg.authorize_ingress(:tcp, 80, other_sg, '1.2.3.4/0', load_balancer)

@param [String, Symbol] protocol Should be :tcp, :udp or :icmp

or the string equivalent.

@param [Integer, Range] ports The port (or port range) to allow

traffic through.  You can pass a single integer (like 80) 
or a range (like 20..21).

@param [Mixed] sources One or more CIDR IP addresses,

security groups, or load balancers.  Security groups
can be specified as hashes.

A security group hash must provide either +:group_id+ or 
+:group_name+ for the security group.  If the security group
does not belong to you aws account then you must also
provide +:user_id+ (which can be an AWS account ID or alias).

@return [nil]

# File lib/aws/ec2/security_group.rb, line 225
def authorize_ingress protocol, ports, *sources
  client.authorize_security_group_ingress(
    :group_id => id,
    :ip_permissions => [ingress_opts(protocol, ports, sources)]
  )
  nil
end
delete() click to toggle source

Deletes this security group.

If you attempt to delete a security group that contains instances, or attempt to delete a security group that is referenced by another security group, an error is raised. For example, if security group B has a rule that allows access from security group A, security group A cannot be deleted until the rule is removed. @return [nil]

# File lib/aws/ec2/security_group.rb, line 309
def delete
  client.delete_security_group(:group_id => id)
  nil
end
describe_call_name() click to toggle source
# File lib/aws/ec2/security_group.rb, line 328
def describe_call_name; self.class.describe_call_name; end
disallow_ping(*sources) click to toggle source

Removes ingress rules for ICMP pings. Defaults to 0.0.0.0/0 for the list of IP ranges to revoke.

@param [String] ip_ranges One or more IP ranges to allow ping from.

Defaults to 0.0.0.0/0

@return [nil]

# File lib/aws/ec2/security_group.rb, line 125
def disallow_ping *sources
  sources << '0.0.0.0/0' if sources.empty?
  revoke_ingress('icmp', -1, *sources)
end
egress_ip_permissions() click to toggle source

@return [SecurityGroup::EgressIpPermissionCollection] Returns a

collection of {IpPermission} objects that represents all of
the egress permissions this security group has authorizations for.
# File lib/aws/ec2/security_group.rb, line 95
def egress_ip_permissions
  EgressIpPermissionCollection.new(self, :config => config)
end
exists?() click to toggle source

@return [Boolean] True if the security group exists.

# File lib/aws/ec2/security_group.rb, line 68
def exists?
  client.describe_security_groups(:filters => [
    { :name => "group-id", :values => [id] }
  ]).security_group_index.key?(id)
end
inflected_name() click to toggle source

@private

# File lib/aws/ec2/security_group.rb, line 320
def inflected_name
  "group"
end
ingress_ip_permissions() click to toggle source

@return [SecurityGroup::IngressIpPermissionCollection] Returns a

collection of {IpPermission} objects that represents all of
the (ingress) permissions this security group has 
authorizations for.
# File lib/aws/ec2/security_group.rb, line 87
def ingress_ip_permissions
  IngressIpPermissionCollection.new(self, :config => config)
end
Also aliased as: ip_permissions
ip_permissions() click to toggle source
resource_type() click to toggle source

@private

# File lib/aws/ec2/security_group.rb, line 315
def resource_type
  'security-group'
end
revoke_egress(*sources) click to toggle source

Revokes an egress (outound) ip permission. This is the inverse operation to {authorize_egress}. See {authorize_egress} for param and option documentation.

@see authorize_egress

@return [nil]

# File lib/aws/ec2/security_group.rb, line 293
def revoke_egress *sources
  client.revoke_security_group_egress(
    :group_id => id,
    :ip_permissions => [egress_opts(sources)])
  nil
end
revoke_ingress(protocol, ports, *sources) click to toggle source

Revokes an ingress (inbound) ip permission. This is the inverse operation to {authorize_ingress}. See {authorize_ingress} for param and option documentation.

@see authorize_ingress

@return [nil]

# File lib/aws/ec2/security_group.rb, line 241
def revoke_ingress protocol, ports, *sources
  client.revoke_security_group_ingress(
    :group_id => id,
    :ip_permissions => [ingress_opts(protocol, ports, sources)]
  )
  nil
end
vpc?() click to toggle source

Returns true if this security group is a VPC security group and not an EC2 security group. VPC security groups belong to a VPC subnet and can have egress rules. @return [Boolean] Returns true if this is a VPC security group and

false if this is an EC2 security group.
# File lib/aws/ec2/security_group.rb, line 79
def vpc?
  vpc_id ? true : false
end

Protected Instance Methods

egress_opts(args) click to toggle source

@private

# File lib/aws/ec2/security_group.rb, line 350
def egress_opts args
  ensure_vpc do

    last = args.last
    
    if last.is_a?(Hash) and (last.key?(:protocol) or last.key?(:ports))
      # hashes at the end of egress methods could be a hash intedned
      # to be a source, like:
      #
      #   { :group_id => ..., :user_id => ... }
      #
      options = args.pop
    else
      options = {}
    end

    opts = {}

    opts[:ip_protocol] = [nil,:any, '-1'].include?(options[:protocol]) ?
      '-1' : options[:protocol].to_s.downcase

    if options[:ports]
      opts[:from_port] = Array(options[:ports]).first.to_i
      opts[:to_port] = Array(options[:ports]).last.to_i
    end

    ips, groups = parse_sources(args)

    opts[:ip_ranges] = ips unless ips.empty?
    opts[:user_id_group_pairs] = groups unless groups.empty?

    opts

  end
end
ensure_vpc() { || ... } click to toggle source

@private

# File lib/aws/ec2/security_group.rb, line 435
def ensure_vpc &block
  raise 'operation permitted for VPC security groups only' unless vpc?
  yield
end
find_in_response(resp) click to toggle source

@private

# File lib/aws/ec2/security_group.rb, line 442
def find_in_response(resp)
  resp.security_group_index[id]
end
ingress_opts(protocol, ports, sources) click to toggle source

@private

# File lib/aws/ec2/security_group.rb, line 332
def ingress_opts protocol, ports, sources

  opts = {}
  opts[:ip_protocol] = protocol.to_s.downcase
  opts[:from_port] = Array(ports).first.to_i
  opts[:to_port] = Array(ports).last.to_i

  ips, groups = parse_sources(sources)

  opts[:ip_ranges] = ips unless ips.empty?
  opts[:user_id_group_pairs] = groups unless groups.empty?

  opts

end
parse_sources(sources) click to toggle source

@private

# File lib/aws/ec2/security_group.rb, line 388
def parse_sources sources

  ips = []
  groups = []

  sources.each do |source|
    case source

    when String
      ips << { :cidr_ip => source }

    when SecurityGroup
      groups << { :group_id => source.id, :user_id => source.owner_id }

    when ELB::LoadBalancer 
      groups << source.source_security_group

    when Hash
      
      # group name or id required
      unless source.has_key?(:group_id) or source.has_key?(:group_name)
        raise ArgumentError, 'invalid ip permission hash, ' +
          'must provide :group_id or :group_name'
      end

      # prevent typos
      unless source.keys - [:group_id, :group_name, :user_id] == []
        raise ArgumentError, 'invalid ip permission hash, ' +
          'only accepts the following keys, :group_id, :group_name, :user_id'
      end

      groups << source

    else
      raise ArgumentError, 'invalid ingress ip permission, ' +
        'expected CIDR IP address or SecurityGroup'
    end
  end

  ips << { :cidr_ip => '0.0.0.0/0' } if ips.empty? and groups.empty?

  [ips, groups]
  
end