Skip to content

Commit

Permalink
Merge pull request #570 from sentryinsurance/subnet_filter_tags_cleanup
Browse files Browse the repository at this point in the history
Adds support for defining multiple tags for `subnet_filter`
  • Loading branch information
tas50 authored Dec 21, 2021
2 parents 6e71914 + 2f028f7 commit c7ddbb1
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 23 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,22 @@ The default is unset, or `nil`.

#### `subnet_filter`

The EC2 [subnet][subnet_docs] to use, specified by tag.

The EC2 [subnet][subnet_docs] to use, specified by tag(s).
The default is unset, or `nil`.

An example of usage:
```yaml
# By Tag
subnet_filter:
tag: 'Name'
value: 'example-subnet-name'
# Multiple Tags
subnet_filter:
- tag: 'Type'
value: 'application'
- tag: 'Environment'
value: 'dev'
```

#### `tags`
Expand All @@ -272,6 +279,17 @@ The Hash of EC tag name/value pairs which will be applied to the instance.

The default is `{ "created-by" => "test-kitchen" }`.

An example of usage:
```yaml
# Single tag
tags:
created-by: 'test-kitchen'
# Multiple Tags
tags:
created-by: 'test-kitchen'
reason: 'Only used for testing can be deleted'
```

#### `user_data`

Expand Down
20 changes: 12 additions & 8 deletions lib/kitchen/driver/aws/instance_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,19 @@ def ec2_instance_data # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
vpc_id = nil
client = ::Aws::EC2::Client.new(region: config[:region])
if config[:subnet_id].nil? && config[:subnet_filter]
subnets = client.describe_subnets(
filters: [
filters = [config[:subnet_filter]].flatten

r = { filters: [] }
filters.each do |subnet_filter|
r[:filters] <<
{
name: "tag:#{config[:subnet_filter][:tag]}",
values: [config[:subnet_filter][:value]],
},
]
).subnets
raise "The subnet tagged '#{config[:subnet_filter][:tag]}:#{config[:subnet_filter][:value]}' does not exist!" unless subnets.any?
name: "tag:#{subnet_filter[:tag]}",
values: [subnet_filter[:value]],
}
end

subnets = client.describe_subnets(r).subnets
raise "Subnets with tags '#{filters}' not found during security group creation" if subnets.empty?

# => Select the least-populated subnet if we have multiple matches
subnet = subnets.max_by { |s| s[:available_ip_address_count] }
Expand Down
42 changes: 29 additions & 13 deletions lib/kitchen/driver/ec2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,8 @@ def create(state)
create_ec2_json(state) if /chef/i.match?(instance.provisioner.name)
debug("ec2:create '#{state[:hostname]}'")
rescue Exception => e
# Clean up any auto-created security groups or keys on the way out.
delete_security_group(state)
delete_key(state)
# Clean up the instance and any auto-created security groups or keys on the way out.
destroy(state)
raise "#{e.message} in the specified region #{config[:region]}. Please check this AMI is available in this region."
end

Expand Down Expand Up @@ -433,15 +432,21 @@ def submit_spots
else
# => Enable cascading through matching subnets
client = ::Aws::EC2::Client.new(region: config[:region])
subnets = client.describe_subnets(
filters: [

filters = [config[:subnet_filter]].flatten

r = { filters: [] }
filters.each do |subnet_filter|
r[:filters] <<
{
name: "tag:#{config[:subnet_filter][:tag]}",
values: [config[:subnet_filter][:value]],
},
]
).subnets
raise "A subnet matching '#{config[:subnet_filter][:tag]}:#{config[:subnet_filter][:value]}' does not exist!" unless subnets.any?
name: "tag:#{subnet_filter[:tag]}",
values: [subnet_filter[:value]],
}
end

subnets = client.describe_subnets(r).subnets

raise "Subnets with tags '#{filters}' not found!" if subnets.empty?

configs = subnets.map do |subnet|
new_config = config.clone
Expand Down Expand Up @@ -751,8 +756,19 @@ def create_security_group(state)

subnets.first.vpc_id
elsif config[:subnet_filter]
subnets = ec2.client.describe_subnets(filters: [{ name: "tag:#{config[:subnet_filter][:tag]}", values: [config[:subnet_filter][:value]] }]).subnets
raise "Subnets with tag '#{config[:subnet_filter][:tag]}=#{config[:subnet_filter][:value]}' not found during security group creation" if subnets.empty?
filters = [config[:subnet_filter]].flatten

r = { filters: [] }
filters.each do |subnet_filter|
r[:filters] << {
name: "tag:#{subnet_filter[:tag]}",
values: [subnet_filter[:value]],
}
end

subnets = ec2.client.describe_subnets(r).subnets

raise "Subnets with tags '#{filters}' not found during security group creation" if subnets.empty?

subnets.first.vpc_id
else
Expand Down
24 changes: 24 additions & 0 deletions spec/kitchen/driver/ec2_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,30 @@
include_examples "common create"
end

context "with multiple subnet filters configured" do
before do
config.delete(:subnet_id)
config[:subnet_filter] = [{
tag: "foo",
value: "bar",
},
{
tag: "hello",
value: "world",
}]
expect(actual_client).to receive(:describe_subnets).with(filters: [{ name: "tag:foo", values: ["bar"] }, { name: "tag:hello", values: ["world"] }]).and_return(double(subnets: [double(vpc_id: "vpc-1")]))
expect(actual_client).to receive(:create_security_group).with(group_name: /kitchen-/, description: /Test Kitchen for/, vpc_id: "vpc-1").and_return(double(group_id: "sg-9876"))
expect(actual_client).to receive(:authorize_security_group_ingress).with(group_id: "sg-9876", ip_permissions: [
{ ip_protocol: "tcp", from_port: 22, to_port: 22, ip_ranges: [{ cidr_ip: "0.0.0.0/0" }] },
{ ip_protocol: "tcp", from_port: 3389, to_port: 3389, ip_ranges: [{ cidr_ip: "0.0.0.0/0" }] },
{ ip_protocol: "tcp", from_port: 5985, to_port: 5985, ip_ranges: [{ cidr_ip: "0.0.0.0/0" }] },
{ ip_protocol: "tcp", from_port: 5986, to_port: 5986, ip_ranges: [{ cidr_ip: "0.0.0.0/0" }] },
])
end

include_examples "common create"
end

context "with an ip address configured as a string" do
before do
config[:security_group_cidr_ip] = "1.2.3.4/32"
Expand Down

0 comments on commit c7ddbb1

Please sign in to comment.