Skip to content
This repository was archived by the owner on Jun 5, 2020. It is now read-only.

Commit 138a2ec

Browse files
committed
Allow setting ingress rules for default security groups in VPC
Due to default security groups all being named default we couldn't reference them previously due to unique resouce naming conflicts. This patch allows for a composite namevar only in the case of the default group. Note that the composite name populates the VPC field automatically, so you don't have to duplicate the information in a separate property.
1 parent 1367373 commit 138a2ec

File tree

6 files changed

+88
-8
lines changed

6 files changed

+88
-8
lines changed

examples/vpc-example/init.pp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818
}]
1919
}
2020

21+
ec2_securitygroup { 'sample-vpc::default':
22+
ensure => present,
23+
region => 'sa-east-1',
24+
description => 'default VPC security group',
25+
ingress => [{
26+
protocol => 'tcp',
27+
port => 22,
28+
cidr => '0.0.0.0/0'
29+
},{
30+
security_group => 'default',
31+
}],
32+
}
33+
2134
ec2_vpc_subnet { 'sample-subnet':
2235
ensure => present,
2336
region => 'sa-east-1',

lib/puppet/provider/ec2_securitygroup/v2.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,13 @@ def self.security_group_to_hash(region, group)
8686
vpc_name_tag ? vpc_name_tag.value : nil
8787
end
8888
end
89+
name = group[:group_name]
90+
name = "#{vpc_name}::#{name}" if vpc_name && name == 'default'
8991
{
90-
id: group.group_id,
91-
name: group.group_name,
92-
description: group.description,
92+
name: name,
93+
group_name: group[:group_name],
94+
id: group[:group_id],
95+
description: group[:description],
9396
ensure: :present,
9497
ingress: format_ingress_rules(ec2, group),
9598
vpc: vpc_name,

lib/puppet/type/ec2_securitygroup.rb

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66

77
ensurable
88

9-
newparam(:name, namevar: true) do
10-
desc 'the name of the security group'
9+
newparam(:name) do
10+
desc 'the name of the security group resource'
11+
isnamevar
1112
validate do |value|
1213
fail 'security groups must have a name' if value == ''
1314
fail 'name should be a String' unless value.is_a?(String)
1415
end
1516
end
1617

18+
newparam(:group_name) do
19+
desc 'the name of the security group'
20+
isnamevar
21+
end
22+
1723
newproperty(:region) do
1824
desc 'the region in which to launch the security group'
1925
validate do |value|
@@ -51,6 +57,7 @@ def insync?(is)
5157

5258
newproperty(:vpc) do
5359
desc 'A VPC to which the group should be associated'
60+
isnamevar
5461
validate do |value|
5562
fail 'vpc should be a String' unless value.is_a?(String)
5663
end
@@ -71,4 +78,25 @@ def should_autorequire?(rule)
7178
autorequire(:ec2_vpc) do
7279
self[:vpc]
7380
end
81+
82+
# When you create a VPC you automatically get a security group called default. You can't change the name.
83+
# This lack of uniqueness makes managing these default security groups difficult. Enter a composite namevar.
84+
# We support two name formats:
85+
#
86+
# 1. {some-security-group}
87+
# 2. {some-vpc-name}::default
88+
#
89+
# Note that we only support prefixing a security group name with the vpc name for the default security group
90+
# at this point. This avoids the issue of otherwise needing to store the resources in two places for non-default
91+
# VPC security groups.
92+
#
93+
# In the case of a a default security group, we maintain the full name (including the VPC name) in the name property
94+
# as otherwise it won't be unique and uniqueness and composite namevars are fun.
95+
def self.title_patterns
96+
[
97+
[ /^(([\w\-]+)::(default))$/, [ [ :name, lambda {|x| x} ], [ :vpc, lambda {|x| x} ], [ :group_name, lambda {|x| x} ] ] ],
98+
[ /^((.*))$/, [ [ :name, lambda {|x| x} ], [ :group_name, lambda {|x| x} ] ] ]
99+
]
100+
end
101+
74102
end

spec/acceptance/fixtures/vpc.pp.tmpl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,27 @@ ec2_vpc { '{{name}}-vpc':
1111
},
1212
}
1313

14+
ec2_securitygroup { '{{name}}-vpc::default':
15+
ensure => {{ensure}},
16+
region => '{{region}}',
17+
description => 'default VPC security group',
18+
ingress => [
19+
{{#security_group_ingress}}
20+
{
21+
{{#values}}
22+
{{k}} => '{{v}}',
23+
{{/values}}
24+
},
25+
{{/security_group_ingress}}
26+
],
27+
tags => {
28+
{{#tags}}
29+
{{k}} => '{{v}}',
30+
{{/tags}}
31+
},
32+
require => Ec2_vpc['{{name}}-vpc'],
33+
}
34+
1435
ec2_securitygroup { '{{name}}-sg':
1536
ensure => {{ensure}},
1637
description => 'VPC accceptance test',

spec/acceptance/vpc_spec.rb

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ def find_instance(name)
5050
finder(name, 'get_instances')
5151
end
5252

53-
def find_security_group(name)
54-
group_response = @aws.ec2_client.describe_security_groups(filters: [
53+
def find_security_group(name, vpc_id=nil)
54+
filters = [
5555
{name: 'group-name', values: [name]}
56-
])
56+
]
57+
filters << {name: 'vpc-id', values: [vpc_id]} unless vpc_id.nil?
58+
group_response = @aws.ec2_client.describe_security_groups(filters: filters)
5759
items = group_response.data.security_groups
5860
expect(items.count).to eq(1)
5961
items.first
@@ -118,6 +120,7 @@ def generate_ip
118120
@vgw = find_vpn_gateway("#{@name}-vgw")
119121
@cgw = find_customer_gateway("#{@name}-cgw")
120122
@sg = find_security_group("#{@name}-sg")
123+
@dsg = find_security_group('default', @vpc.vpc_id)
121124
end
122125

123126
after(:all) do
@@ -155,6 +158,12 @@ def generate_ip
155158
expect(@aws.tag_difference(@sg, @config[:tags])).to be_empty
156159
end
157160

161+
it 'should manage the default VPC security group' do
162+
expect(@dsg).not_to be_nil
163+
expect(@dsg.vpc_id).to eq(@vpc.vpc_id)
164+
expect(@aws.tag_difference(@dsg, @config[:tags])).to be_empty
165+
end
166+
158167
it 'should create a route table' do
159168
table = find_route_table("#{@name}-routes")
160169
expect(table).not_to be_nil

spec/unit/type/ec2_securitygroup_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,10 @@
6767
expect(type_class).to order_tags_on_output
6868
end
6969

70+
it 'should extract the vpc from a composite name' do
71+
sg = type_class.new({name: 'sample::default'})
72+
expect(sg[:vpc]).to eq('sample')
73+
expect(sg[:group_name]).to eq('default')
74+
end
75+
7076
end

0 commit comments

Comments
 (0)