Skip to content

Commit ca1bc01

Browse files
authored
Merge pull request #123 from SKozlovsky/bugfix/firewall-allow-internal
Fix bug for firewall allow-internal rules
2 parents 3ee7419 + b93c322 commit ca1bc01

File tree

4 files changed

+236
-6
lines changed

4 files changed

+236
-6
lines changed

examples/submodule_firewall/main.tf

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,21 +48,96 @@ module "test-vpc-module" {
4848
]
4949
}
5050

51+
// Custom firewall rules
52+
locals {
53+
custom_rules = {
54+
// Example of custom tcp/udp rule
55+
deny-ingress-6534-6566 = {
56+
description = "Deny all INGRESS to port 6534-6566"
57+
direction = "INGRESS"
58+
action = "deny"
59+
ranges = ["0.0.0.0/0"] # source or destination ranges (depends on `direction`)
60+
use_service_accounts = false # if `true` targets/sources expect list of instances SA, if false - list of tags
61+
targets = null # target_service_accounts or target_tags depends on `use_service_accounts` value
62+
sources = null # source_service_accounts or source_tags depends on `use_service_accounts` value
63+
rules = [{
64+
protocol = "tcp"
65+
ports = ["6534-6566"]
66+
},
67+
{
68+
protocol = "udp"
69+
ports = ["6534-6566"]
70+
}]
71+
72+
extra_attributes = {
73+
disabled = true
74+
priority = 95
75+
}
76+
}
77+
78+
// Example how to allow connection from instances with `backend` tag, to instances with `databases` tag
79+
allow-backend-to-databases = {
80+
description = "Allow backend nodes connection to databases instances"
81+
direction = "INGRESS"
82+
action = "allow"
83+
ranges = null
84+
use_service_accounts = false
85+
targets = ["databases"] # target_tags
86+
sources = ["backed"] # source_tags
87+
rules = [{
88+
protocol = "tcp"
89+
ports = ["3306", "5432", "1521", "1433"]
90+
}]
91+
92+
extra_attributes = {}
93+
}
94+
95+
// Example how to allow connection from an instance with a given service account
96+
allow-all-admin-sa = {
97+
description = "Allow all traffic from admin sa instances"
98+
direction = "INGRESS"
99+
action = "allow"
100+
ranges = null
101+
use_service_accounts = true
102+
targets = null
103+
sources = ["[email protected]"]
104+
rules = [{
105+
protocol = "tcp"
106+
ports = null # all ports
107+
},
108+
{
109+
protocol = "udp"
110+
ports = null # all ports
111+
}
112+
]
113+
extra_attributes = {
114+
priority = 30
115+
}
116+
}
117+
}
118+
}
119+
120+
121+
51122
module "test-firewall-submodule" {
52123
source = "../../modules/fabric-net-firewall"
53124
project_id = var.project_id
54125
network = module.test-vpc-module.network_name
55126
internal_ranges_enabled = true
56127
internal_ranges = module.test-vpc-module.subnets_ips
57128

58-
internal_allow = [{
59-
protocol = "icmp"
129+
internal_allow = [
130+
{
131+
protocol = "icmp"
60132
},
61133
{
62-
protocol = "tcp"
134+
protocol = "tcp",
135+
ports = ["8080", "1000-2000"]
63136
},
64137
{
65138
protocol = "udp"
139+
# all ports will be opened if `ports` key isn't specified
66140
},
67141
]
142+
custom_rules = local.custom_rules
68143
}

modules/fabric-net-firewall/main.tf

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,24 @@ resource "google_compute_firewall" "allow-internal" {
2727
source_ranges = var.internal_ranges
2828

2929
dynamic "allow" {
30-
for_each = [var.internal_allow]
30+
for_each = [for rule in var.internal_allow :
31+
{
32+
protocol = lookup(rule, "protocol", null)
33+
ports = lookup(rule, "ports", null)
34+
}
35+
]
3136
content {
32-
protocol = lookup(allow.value[count.index], "protocol", null)
33-
ports = lookup(allow.value[count.index], "ports", null)
37+
protocol = allow.value.protocol
38+
ports = allow.value.ports
3439
}
3540
}
41+
3642
}
3743

44+
45+
46+
47+
3848
resource "google_compute_firewall" "allow-admins" {
3949
count = var.admin_ranges_enabled == true ? 1 : 0
4050
name = "${var.network}-ingress-admins"

test/integration/submodule_firewall/controls/gcloud.rb

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,148 @@
3838
end
3939
end
4040

41+
describe "allowed internal rules" do
42+
it "should contain ICMP rule" do
43+
expect(data["allowed"]).to include({"IPProtocol" => "icmp"})
44+
end
45+
46+
it "should contain UDP rule" do
47+
expect(data["allowed"]).to include({"IPProtocol" => "udp"})
48+
end
49+
50+
it "should contain TCP rule" do
51+
expect(data["allowed"]).to include({"IPProtocol"=>"tcp", "ports"=>["8080", "1000-2000"]})
52+
end
53+
end
54+
end
55+
56+
# Custom rules
57+
describe command("gcloud compute firewall-rules describe allow-backend-to-databases --project=#{project_id} --format=json") do
58+
its(:exit_status) { should eq 0 }
59+
its(:stderr) { should eq '' }
60+
61+
let(:data) do
62+
if subject.exit_status == 0
63+
JSON.parse(subject.stdout)
64+
else
65+
{}
66+
end
67+
end
68+
69+
describe "Custom TAG rule" do
70+
it "has backend tag as source" do
71+
expect(data).to include(
72+
"sourceTags" => ["backed"]
73+
)
74+
end
75+
76+
it "has databases tag as target" do
77+
expect(data).to include(
78+
"targetTags" => ["databases"]
79+
)
80+
end
81+
82+
it "has expected TCP rule" do
83+
expect(data["allowed"]).to include(
84+
{
85+
"IPProtocol" => "tcp",
86+
"ports" => ["3306", "5432", "1521", "1433"]
87+
}
88+
)
89+
end
90+
end
91+
end
92+
93+
describe command("gcloud compute firewall-rules describe deny-ingress-6534-6566 --project=#{project_id} --format=json") do
94+
its(:exit_status) { should eq 0 }
95+
its(:stderr) { should eq '' }
96+
97+
let(:data) do
98+
if subject.exit_status == 0
99+
JSON.parse(subject.stdout)
100+
else
101+
{}
102+
end
103+
end
104+
105+
describe "deny-ingress-6534-6566" do
106+
it "should be disabled" do
107+
expect(data).to include(
108+
"disabled" => true
109+
)
110+
end
111+
112+
it "has 0.0.0.0/0 source range" do
113+
expect(data).to include(
114+
"sourceRanges" => ["0.0.0.0/0"]
115+
)
116+
end
117+
118+
it "has expected TCP rules" do
119+
expect(data["denied"]).to include(
120+
{
121+
"IPProtocol" => "tcp",
122+
"ports" => ["6534-6566"]
123+
}
124+
)
125+
end
126+
127+
it "has expected UDP rules" do
128+
expect(data["denied"]).to include(
129+
{
130+
"IPProtocol" => "udp",
131+
"ports" => ["6534-6566"]
132+
}
133+
)
134+
end
135+
end
136+
end
137+
138+
139+
describe command("gcloud compute firewall-rules describe allow-all-admin-sa --project=#{project_id} --format=json") do
140+
its(:exit_status) { should eq 0 }
141+
its(:stderr) { should eq '' }
142+
143+
let(:data) do
144+
if subject.exit_status == 0
145+
JSON.parse(subject.stdout)
146+
else
147+
{}
148+
end
149+
end
150+
151+
describe "allow-all-admin-sa" do
152+
it "should be enabled" do
153+
expect(data).to include(
154+
"disabled" => false
155+
)
156+
end
157+
158+
it "should has correct source SA" do
159+
expect(data["sourceServiceAccounts"]).to eq(["[email protected]"])
160+
end
161+
162+
it "should has priority 30" do
163+
expect(data["priority"]).to eq(30)
164+
end
165+
166+
it "has expected TCP rules" do
167+
expect(data["allowed"]).to include(
168+
{
169+
"IPProtocol" => "tcp"
170+
}
171+
)
172+
end
173+
174+
it "has expected UDP rules" do
175+
expect(data["allowed"]).to include(
176+
{
177+
"IPProtocol" => "udp"
178+
}
179+
)
180+
end
181+
end
41182
end
42183

43184
end
185+

test/integration/submodule_firewall/controls/gcp.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
its('firewall_names') { should include "#{network_name}-ingress-tag-https" }
2525
its('firewall_names') { should include "#{network_name}-ingress-tag-ssh" }
2626
its('firewall_names') { should_not include "default-ingress-admins" }
27+
its('firewall_names') { should include "deny-ingress-6534-6566" }
28+
its('firewall_names') { should include "allow-backend-to-databases" }
29+
its('firewall_names') { should include "allow-all-admin-sa" }
2730
end
2831

2932
end

0 commit comments

Comments
 (0)