Skip to content

Commit

Permalink
feat: customer acl rules(#360)
Browse files Browse the repository at this point in the history
* feat: give option to append or prepend ibm rules
* feat: add a deny all as last element of the list (this is a best practice, and not mandatory as implicit - but absence typically raise questions)
* feat: add prefix "ibmflow-" to ibm rules

BREAKING CHANGE: The interface of the `network_acls` input variable has changed. If your code is setting this variable explicitly, this change requires to add a few extra optional parameters: `add_ibm_cloud_internal_rules`, `add_vpc_connectivity_rules`, `prepend_ibm_rules` . The parameter `add_cluster_rules` has been renamed `add_ibm_cloud_internal_rules`
  • Loading branch information
vburckhardt authored Feb 28, 2023
1 parent c0abc72 commit 6148fc2
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 71 deletions.
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

0 comments on commit 6148fc2

Please sign in to comment.