Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework network ACLs (phase 1) #360

Merged
merged 14 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ You need the following permissions to run this module.
| <a name="input_default_routing_table_name"></a> [default\_routing\_table\_name](#input\_default\_routing\_table\_name) | OPTIONAL - Name of the Default Routing Table. If null, a name will be automatically generated | `string` | `null` | no |
| <a name="input_default_security_group_name"></a> [default\_security\_group\_name](#input\_default\_security\_group\_name) | OPTIONAL - Name of the Default Security Group. If null, a name will be automatically generated | `string` | `null` | no |
| <a name="input_name"></a> [name](#input\_name) | Name for VPC | `string` | n/a | yes |
| <a name="input_network_acls"></a> [network\_acls](#input\_network\_acls) | List of ACLs to create. Rules can be automatically created to allow inbound and outbound traffic from a VPC tier by adding the name of that tier to the `network_connections` list. Rules automatically generated by these network connections will be added at the beginning of a list, and will be web-tierlied to traffic first. At least one rule must be provided for each ACL. | <pre>list(<br> object({<br> name = string<br> network_connections = optional(list(string))<br> add_cluster_rules = optional(bool)<br> rules = list(<br> object({<br> name = string<br> action = string<br> destination = string<br> direction = string<br> source = string<br> tcp = optional(<br> object({<br> port_max = optional(number)<br> port_min = optional(number)<br> source_port_max = optional(number)<br> source_port_min = optional(number)<br> })<br> )<br> udp = optional(<br> object({<br> port_max = optional(number)<br> port_min = optional(number)<br> source_port_max = optional(number)<br> source_port_min = optional(number)<br> })<br> )<br> icmp = optional(<br> object({<br> type = optional(number)<br> code = optional(number)<br> })<br> )<br> })<br> )<br> })<br> )</pre> | <pre>[<br> {<br> "add_cluster_rules": true,<br> "name": "vpc-acl",<br> "rules": [<br> {<br> "action": "allow",<br> "destination": "0.0.0.0/0",<br> "direction": "inbound",<br> "name": "allow-all-inbound",<br> "source": "0.0.0.0/0"<br> },<br> {<br> "action": "allow",<br> "destination": "0.0.0.0/0",<br> "direction": "outbound",<br> "name": "allow-all-outbound",<br> "source": "0.0.0.0/0"<br> }<br> ]<br> }<br>]</pre> | no |
| <a name="input_network_acls"></a> [network\_acls](#input\_network\_acls) | List of ACLs to create. Rules can be automatically created to allow inbound and outbound traffic from a VPC tier by adding the name of that tier to the `network_connections` list. Rules automatically generated by these network connections will be added at the beginning of a list, and will be web-tierlied to traffic first. At least one rule must be provided for each ACL. | <pre>list(<br> object({<br> name = string<br> network_connections = optional(list(string))<br> add_ibm_cloud_internal_rules = optional(bool)<br> add_vpc_connectivity_rules = optional(bool)<br> prepend_ibm_rules = optional(bool)<br> rules = list(<br> object({<br> name = string<br> action = string<br> destination = string<br> direction = string<br> source = string<br> tcp = optional(<br> object({<br> port_max = optional(number)<br> port_min = optional(number)<br> source_port_max = optional(number)<br> source_port_min = optional(number)<br> })<br> )<br> udp = optional(<br> object({<br> port_max = optional(number)<br> port_min = optional(number)<br> source_port_max = optional(number)<br> source_port_min = optional(number)<br> })<br> )<br> icmp = optional(<br> object({<br> type = optional(number)<br> code = optional(number)<br> })<br> )<br> })<br> )<br> })<br> )</pre> | <pre>[<br> {<br> "add_ibm_cloud_internal_rules": true,<br> "add_vpc_connectivity_rules": true,<br> "name": "vpc-acl",<br> "prepend_ibm_rules": true,<br> "rules": [<br> {<br> "action": "allow",<br> "destination": "0.0.0.0/0",<br> "direction": "inbound",<br> "name": "allow-all-443-inbound",<br> "source": "0.0.0.0/0",<br> "tcp": {<br> "port_max": 443,<br> "port_min": 443<br> }<br> },<br> {<br> "action": "allow",<br> "destination": "0.0.0.0/0",<br> "direction": "outbound",<br> "name": "allow-all-443-outbound",<br> "source": "0.0.0.0/0",<br> "tcp": {<br> "source_port_max": 443,<br> "source_port_min": 443<br> }<br> }<br> ]<br> }<br>]</pre> | no |
| <a name="input_network_cidr"></a> [network\_cidr](#input\_network\_cidr) | Network CIDR for the VPC. This is used to manage network ACL rules for cluster provisioning. | `string` | `"10.0.0.0/8"` | no |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | The prefix that you would like to append to your resources | `string` | n/a | yes |
| <a name="input_region"></a> [region](#input\_region) | The region to which to deploy the VPC | `string` | n/a | yes |
Expand Down
2 changes: 1 addition & 1 deletion common-dev-assets
32 changes: 21 additions & 11 deletions module-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,26 +92,36 @@
},
"network_acls": {
"name": "network_acls",
"type": "list(\n object({\n name = string\n network_connections = optional(list(string))\n add_cluster_rules = optional(bool)\n rules = list(\n object({\n name = string\n action = string\n destination = string\n direction = string\n source = string\n tcp = optional(\n object({\n port_max = optional(number)\n port_min = optional(number)\n source_port_max = optional(number)\n source_port_min = optional(number)\n })\n )\n udp = optional(\n object({\n port_max = optional(number)\n port_min = optional(number)\n source_port_max = optional(number)\n source_port_min = optional(number)\n })\n )\n icmp = optional(\n object({\n type = optional(number)\n code = optional(number)\n })\n )\n })\n )\n })\n )",
"type": "list(\n object({\n name = string\n network_connections = optional(list(string))\n add_ibm_cloud_internal_rules = optional(bool)\n add_vpc_connectivity_rules = optional(bool)\n prepend_ibm_rules = optional(bool)\n rules = list(\n object({\n name = string\n action = string\n destination = string\n direction = string\n source = string\n tcp = optional(\n object({\n port_max = optional(number)\n port_min = optional(number)\n source_port_max = optional(number)\n source_port_min = optional(number)\n })\n )\n udp = optional(\n object({\n port_max = optional(number)\n port_min = optional(number)\n source_port_max = optional(number)\n source_port_min = optional(number)\n })\n )\n icmp = optional(\n object({\n type = optional(number)\n code = optional(number)\n })\n )\n })\n )\n })\n )",
"description": "List of ACLs to create. Rules can be automatically created to allow inbound and outbound traffic from a VPC tier by adding the name of that tier to the `network_connections` list. Rules automatically generated by these network connections will be added at the beginning of a list, and will be web-tierlied to traffic first. At least one rule must be provided for each ACL.",
"default": [
{
"add_cluster_rules": true,
"add_ibm_cloud_internal_rules": true,
"add_vpc_connectivity_rules": true,
"name": "vpc-acl",
"prepend_ibm_rules": true,
"rules": [
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "inbound",
"name": "allow-all-inbound",
"source": "0.0.0.0/0"
"name": "allow-all-443-inbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 443,
"port_min": 443
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "outbound",
"name": "allow-all-outbound",
"source": "0.0.0.0/0"
"name": "allow-all-443-outbound",
"source": "0.0.0.0/0",
"tcp": {
"source_port_max": 443,
"source_port_min": 443
}
}
]
}
Expand Down Expand Up @@ -202,7 +212,7 @@
],
"pos": {
"filename": "variables.tf",
"line": 362
"line": 374
}
},
"security_group_rules": {
Expand All @@ -221,7 +231,7 @@
],
"pos": {
"filename": "variables.tf",
"line": 296
"line": 308
}
},
"subnets": {
Expand Down Expand Up @@ -259,7 +269,7 @@
],
"pos": {
"filename": "variables.tf",
"line": 233
"line": 245
}
},
"tags": {
Expand Down Expand Up @@ -312,7 +322,7 @@
],
"pos": {
"filename": "variables.tf",
"line": 207
"line": 219
}
}
},
Expand Down Expand Up @@ -419,7 +429,7 @@
},
"pos": {
"filename": "network_acls.tf",
"line": 121
"line": 133
}
},
"ibm_is_public_gateway.gateway": {
Expand Down
106 changes: 59 additions & 47 deletions network_acls.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
##############################################################################

locals {
cluster_rules = [
# Cluster Rules
ibm_cloud_internal_rules = [
# IaaS and PaaS Rules. Note that this coarse grained list will be narrowed in upcoming releases.
{
name = "roks-create-worker-nodes-inbound"
name = "ibmflow-iaas-inbound"
action = "allow"
source = "161.26.0.0/16"
destination = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
Expand All @@ -16,7 +16,7 @@ locals {
icmp = null
},
{
name = "roks-create-worker-nodes-outbound"
name = "ibmflow-iaas-outbound"
action = "allow"
destination = "161.26.0.0/16"
source = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
Expand All @@ -26,7 +26,7 @@ locals {
icmp = null
},
{
name = "roks-nodes-to-service-inbound"
name = "ibmflow-paas-inbound"
action = "allow"
source = "166.8.0.0/14"
destination = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
Expand All @@ -36,67 +36,62 @@ locals {
icmp = null
},
{
name = "roks-nodes-to-service-outbound"
name = "ibmflow-paas-outbound"
action = "allow"
destination = "166.8.0.0/14"
source = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
direction = "outbound"
tcp = null
udp = null
icmp = null
},
# App Rules
}
]

vpc_connectivity_rules = [
# All connectivity across any subnet within VPC
# TODO: narrow down to VPC address spaces
{
name = "allow-app-incoming-traffic-requests"
name = "ibmflow-allow-vpc-connectivity-inbound"
action = "allow"
source = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
destination = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
direction = "inbound"
tcp = {
source_port_min = 30000
source_port_max = 32767
}
udp = null
icmp = null
tcp = null
udp = null
icmp = null
},
{
name = "allow-app-outgoing-traffic-requests"
name = "ibmflow-allow-vpc-connectivity-outbound"
action = "allow"
source = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
destination = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
direction = "outbound"
tcp = {
port_min = 30000
port_max = 32767
}
udp = null
icmp = null
},
tcp = null
udp = null
icmp = null
}
]

deny_all_rules = [
{
name = "allow-lb-incoming-traffic-requests"
action = "allow"
source = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
destination = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
name = "ibmflow-deny-all-inbound"
action = "deny"
source = "0.0.0.0/0"
destination = "0.0.0.0/0"
direction = "inbound"
tcp = {
port_min = 443
port_max = 443
}
udp = null
icmp = null
tcp = null
udp = null
icmp = null
},
{
name = "allow-lb-outgoing-traffic-requests"
action = "allow"
source = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
destination = var.network_cidr != null ? var.network_cidr : "0.0.0.0/0"
name = "ibmflow-deny-all-outbound"
action = "deny"
source = "0.0.0.0/0"
destination = "0.0.0.0/0"
direction = "outbound"
tcp = {
source_port_min = 443
source_port_max = 443
}
udp = null
icmp = null
tcp = null
udp = null
icmp = null
}
]

Expand All @@ -106,13 +101,30 @@ locals {
network_acl.name => {
name = network_acl.name
rules = flatten([
# Prepend ibm rules
[
# These rules cannot be added in a conditional operator due to inconsistant typing
# This will add all cluster rules if the acl object contains add_cluster rules
for rule in local.cluster_rules :
rule if network_acl.add_cluster_rules == true
# This will add all internal rules if the acl object contains add_ibm_cloud_internal_rules rules
for rule in local.ibm_cloud_internal_rules :
rule if network_acl.add_ibm_cloud_internal_rules == true && network_acl.prepend_ibm_rules == true
],
[
for rule in local.vpc_connectivity_rules :
rule if network_acl.add_vpc_connectivity_rules == true && network_acl.prepend_ibm_rules == true
],
# Customer rules
network_acl.rules,
# Append ibm rules
[
for rule in local.ibm_cloud_internal_rules :
rule if network_acl.add_ibm_cloud_internal_rules == true && network_acl.prepend_ibm_rules != true
],
[
for rule in local.vpc_connectivity_rules :
rule if network_acl.add_vpc_connectivity_rules == true && network_acl.prepend_ibm_rules != true
],
network_acl.rules
# Best practice to add deny all at the end of ACL
local.deny_all_rules
])
}
}
Expand Down
2 changes: 2 additions & 0 deletions tests/pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ func TestRunBasicExample(t *testing.T) {
}

func TestRunUpgradeBasicExample(t *testing.T) {
// Breaking change in this PR leading to next major version - skip upgrade test
t.Skip()
t.Parallel()

options := setupOptions(t, "slz-vpc-upg")
Expand Down
34 changes: 23 additions & 11 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,11 @@ variable "network_acls" {
description = "List of ACLs to create. Rules can be automatically created to allow inbound and outbound traffic from a VPC tier by adding the name of that tier to the `network_connections` list. Rules automatically generated by these network connections will be added at the beginning of a list, and will be web-tierlied to traffic first. At least one rule must be provided for each ACL."
type = list(
object({
name = string
network_connections = optional(list(string))
add_cluster_rules = optional(bool)
name = string
network_connections = optional(list(string))
add_ibm_cloud_internal_rules = optional(bool)
add_vpc_connectivity_rules = optional(bool)
prepend_ibm_rules = optional(bool)
rules = list(
object({
name = string
Expand Down Expand Up @@ -138,20 +140,30 @@ variable "network_acls" {

default = [
{
name = "vpc-acl"
add_cluster_rules = true
name = "vpc-acl"
add_ibm_cloud_internal_rules = true
add_vpc_connectivity_rules = true
prepend_ibm_rules = true
rules = [
{
name = "allow-all-inbound"
action = "allow"
direction = "inbound"
name = "allow-all-443-inbound"
action = "allow"
direction = "inbound"
tcp = {
port_min = 443
port_max = 443
}
destination = "0.0.0.0/0"
source = "0.0.0.0/0"
},
{
name = "allow-all-outbound"
action = "allow"
direction = "outbound"
name = "allow-all-443-outbound"
action = "allow"
direction = "outbound"
tcp = {
source_port_min = 443
source_port_max = 443
}
destination = "0.0.0.0/0"
source = "0.0.0.0/0"
}
Expand Down