Skip to content

Commit

Permalink
add prefix-list capability to custom
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Aug 26, 2025
1 parent cf5aba7 commit 9c454ce
Show file tree
Hide file tree
Showing 9 changed files with 225 additions and 10 deletions.
2 changes: 1 addition & 1 deletion common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ No modules.
| <a name="input_ingress_security_groups"></a> [ingress\_security\_groups](#input\_ingress\_security\_groups) | List of ingress security groups for all ports | `list(string)` | `[]` | no |
| <a name="input_ingress_self_port_list"></a> [ingress\_self\_port\_list](#input\_ingress\_self\_port\_list) | Ingress port list of 4-tuple: from, to, proto, description | `list` | `[]` | no |
| <a name="input_ingress_self_port_map"></a> [ingress\_self\_port\_map](#input\_ingress\_self\_port\_map) | Ingress self access port list of objects: from, to, proto, description | <pre>list(object({<br/> from = number<br/> to = number<br/> proto = any<br/> description = string<br/> }))</pre> | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Extra security group tags | `map` | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Extra security group tags | `map(any)` | `{}` | no |
| <a name="input_use_vpc_cidr"></a> [use\_vpc\_cidr](#input\_use\_vpc\_cidr) | Enable\|Disable use of VPC CIDR block in the ingress\_networks | `bool` | `false` | no |
| <a name="input_vpc_full_name"></a> [vpc\_full\_name](#input\_vpc\_full\_name) | VPC Name | `string` | `""` | no |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | VPC ID Number | `string` | n/a | yes |
Expand Down
2 changes: 1 addition & 1 deletion common/variables.common.tf
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ variable "egress_security_groups" {

variable "tags" {
description = "Extra security group tags"
type = map
type = map(any)
default = {}
}

Expand Down
19 changes: 13 additions & 6 deletions custom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,14 @@ module "sg_test" {

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 0.12 |
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0.0 |
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.0 |

## Providers

| Name | Version |
|------|---------|
| <a name="provider_aws"></a> [aws](#provider\_aws) | n/a |
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.0 |

## Modules

Expand All @@ -123,6 +124,8 @@ No modules.
| [aws_security_group.this_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_ec2_managed_prefix_list.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_managed_prefix_list) | data source |
| [aws_ec2_managed_prefix_list.ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ec2_managed_prefix_list) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
| [aws_security_group.egress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source |
| [aws_security_group.ingress_security_groups](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/security_group) | data source |
Expand All @@ -133,19 +136,23 @@ No modules.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_description"></a> [description](#input\_description) | Security Group Description | `string` | `""` | no |
| <a name="input_egress_networks"></a> [egress\_networks](#input\_egress\_networks) | List of egress networks (with all pre-defined egress ports) (default: any) | `list(string)` | <pre>[<br> "0.0.0.0/0"<br>]</pre> | no |
| <a name="input_egress_networks"></a> [egress\_networks](#input\_egress\_networks) | List of egress networks (with all pre-defined egress ports) (default: any) | `list(string)` | <pre>[<br/> "0.0.0.0/0"<br/>]</pre> | no |
| <a name="input_egress_prefix_list_names"></a> [egress\_prefix\_list\_names](#input\_egress\_prefix\_list\_names) | List of prefix list names for eggress access | `list(string)` | `[]` | no |
| <a name="input_egress_prefix_list_ports"></a> [egress\_prefix\_list\_ports](#input\_egress\_prefix\_list\_ports) | List of port objects (from,to,proto,label) for egress prefix lists | <pre>list(object({<br/> from = number<br/> to = number<br/> proto = optional(string, "tcp")<br/> label = optional(string)<br/> }))</pre> | <pre>[<br/> {<br/> "from": 0,<br/> "label": "all",<br/> "proto": -1,<br/> "to": 0<br/> }<br/>]</pre> | no |
| <a name="input_egress_security_groups"></a> [egress\_security\_groups](#input\_egress\_security\_groups) | List of egress security groups (all ports) | `list(string)` | `[]` | no |
| <a name="input_enable_default_egress"></a> [enable\_default\_egress](#input\_enable\_default\_egress) | Enable\|Disable default egress of ALL | `bool` | `true` | no |
| <a name="input_enable_self"></a> [enable\_self](#input\_enable\_self) | Enable\|Disable self full access | `bool` | `false` | no |
| <a name="input_ingress_networks"></a> [ingress\_networks](#input\_ingress\_networks) | List of ingress networks for access (with all pre-defined ingress ports) | `list(string)` | `[]` | no |
| <a name="input_ingress_port_list"></a> [ingress\_port\_list](#input\_ingress\_port\_list) | Ingress port list of 5-tuple: from, to, proto, description, and cidr(list) | `list` | `[]` | no |
| <a name="input_ingress_port_map"></a> [ingress\_port\_map](#input\_ingress\_port\_map) | Ingress port list of objects: from, to, proto, description and cidr(list) | <pre>list(object({<br> from = number<br> to = number<br> proto = any<br> description = string<br> cidr = list(string)<br> }))</pre> | `[]` | no |
| <a name="input_ingress_port_map"></a> [ingress\_port\_map](#input\_ingress\_port\_map) | Ingress port list of objects: from, to, proto, description and cidr(list) | <pre>list(object({<br/> from = number<br/> to = number<br/> proto = any<br/> description = string<br/> cidr = list(string)<br/> }))</pre> | `[]` | no |
| <a name="input_ingress_prefix_list_names"></a> [ingress\_prefix\_list\_names](#input\_ingress\_prefix\_list\_names) | List of prefix list names for ingress access | `list(string)` | `[]` | no |
| <a name="input_ingress_prefix_list_ports"></a> [ingress\_prefix\_list\_ports](#input\_ingress\_prefix\_list\_ports) | List of port objects (from,to,proto,label) for ingress prefix lists | <pre>list(object({<br/> from = number<br/> to = number<br/> proto = optional(string, "tcp")<br/> label = optional(string)<br/> }))</pre> | `[]` | no |
| <a name="input_ingress_security_groups"></a> [ingress\_security\_groups](#input\_ingress\_security\_groups) | List of ingress security groups for all ports | `list(string)` | `[]` | no |
| <a name="input_ingress_self_port_list"></a> [ingress\_self\_port\_list](#input\_ingress\_self\_port\_list) | Ingress port list of 4-tuple: from, to, proto, description | `list` | `[]` | no |
| <a name="input_ingress_self_port_map"></a> [ingress\_self\_port\_map](#input\_ingress\_self\_port\_map) | Ingress self access port list of objects: from, to, proto, description | <pre>list(object({<br> from = number<br> to = number<br> proto = any<br> description = string<br> }))</pre> | `[]` | no |
| <a name="input_ingress_self_port_map"></a> [ingress\_self\_port\_map](#input\_ingress\_self\_port\_map) | Ingress self access port list of objects: from, to, proto, description | <pre>list(object({<br/> from = number<br/> to = number<br/> proto = any<br/> description = string<br/> }))</pre> | `[]` | no |
| <a name="input_name"></a> [name](#input\_name) | Security Group Name (required) | `string` | n/a | yes |
| <a name="input_short_description"></a> [short\_description](#input\_short\_description) | Security Group Short Description | `string` | `""` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Extra security group tags | `map` | `{}` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | Extra security group tags | `map(any)` | `{}` | no |
| <a name="input_use_vpc_cidr"></a> [use\_vpc\_cidr](#input\_use\_vpc\_cidr) | Enable\|Disable use of VPC CIDR block in the ingress\_networks | `bool` | `false` | no |
| <a name="input_vpc_full_name"></a> [vpc\_full\_name](#input\_vpc\_full\_name) | VPC Name | `string` | `""` | no |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | VPC ID Number | `string` | n/a | yes |
Expand Down
185 changes: 185 additions & 0 deletions custom/custom.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
locals {
vpc_networks = var.use_vpc_cidr ? [data.aws_vpc.this_vpc[0].cidr_block] : []
external_ingress_networks = compact(concat(local.vpc_networks, local.ingress_networks))
ingress_sg_names = zipmap(var.ingress_security_groups, data.aws_security_group.ingress_security_groups[*].name)
egress_sg_names = zipmap(var.egress_security_groups, data.aws_security_group.egress_security_groups[*].name)
# self = var.enable_self ? local.self_ports : []
}

resource "aws_security_group" "this_security_group" {
name = local.name
description = var.description
vpc_id = var.vpc_id

#---
# ingress
#---
# ingresss external port list (list + vpc if enabaled)
dynamic "ingress" {
for_each = local.port_map["external"]
iterator = p
content {
description = "${local.short_description}: ${p.value["description"]}"
from_port = p.value["from"]
to_port = p.value["to"]
protocol = p.value["proto"]
cidr_blocks = length(p.value["cidr"]) == 0 ? distinct(flatten(compact(concat(local.external_ingress_networks, var.ingress_networks)))) : distinct(flatten(compact(concat(p.value["cidr"], var.ingress_networks))))
}
}

# ingress module-defined ports
dynamic "ingress" {
for_each = local.port_map["module_ports"]
iterator = p
content {
description = "${local.short_description}: ${p.value["description"]}"
from_port = p.value["from"]
to_port = p.value["to"]
protocol = p.value["proto"]
cidr_blocks = length(p.value["cidr"]) == 0 ? distinct(flatten(compact(concat(local.external_ingress_networks, var.ingress_networks)))) : distinct(flatten(compact(concat(p.value["cidr"], var.ingress_networks))))
}
}

# ingress_ports
dynamic "ingress" {
for_each = local.port_map["ingress_ports"]
iterator = p
content {
description = "${local.short_description}: ${p.value["description"]}"
from_port = p.value["from"]
to_port = p.value["to"]
protocol = p.value["proto"]
cidr_blocks = length(p.value["cidr"]) == 0 ? distinct(flatten(compact(concat(local.external_ingress_networks, var.ingress_networks)))) : distinct(flatten(compact(concat(p.value["cidr"], var.ingress_networks))))
}
}

# ingress map
dynamic "ingress" {
for_each = local.port_map["ingress_map"]
iterator = p
content {
description = "${local.short_description}: ${p.value["description"]}"
from_port = p.value["from"]
to_port = p.value["to"]
protocol = p.value["proto"]
cidr_blocks = length(p.value["cidr"]) == 0 ? distinct(flatten(compact(concat(local.external_ingress_networks, var.ingress_networks)))) : distinct(flatten(compact(concat(p.value["cidr"], var.ingress_networks))))
}
}

# ingress security group ids (all)
dynamic "ingress" {
for_each = local.ingress_sg
iterator = sg
content {
description = "${local.short_description}: ${local.ingress_sg_names[sg.value]}"
from_port = 0
to_port = 0
protocol = -1
security_groups = [sg.value]
}
}

#---
# ingress self
#---
# ingress self port list
dynamic "ingress" {
for_each = var.enable_self ? local.self_port_map["ingress_ports"] : []
iterator = sg
content {
description = "${local.short_description}: self ${sg.value["description"]}"
from_port = sg.value["from"]
to_port = sg.value["to"]
protocol = sg.value["proto"]
self = true
}
}

# ingress self port map
dynamic "ingress" {
for_each = var.enable_self ? local.self_port_map["ingress_map"] : []
iterator = sg
content {
description = "${local.short_description}: self ${sg.value["description"]}"
from_port = sg.value["from"]
to_port = sg.value["to"]
protocol = sg.value["proto"]
self = true
}
}

# ingress self port default
dynamic "ingress" {
for_each = var.enable_self ? local.self_port_map["default"] : []
iterator = sg
content {
description = "${local.short_description}: self ${sg.value["description"]}"
from_port = sg.value["from"]
to_port = sg.value["to"]
protocol = sg.value["proto"]
self = true
}
}

# inress with prefix lists
dynamic "ingress" {
for_each = length(var.ingress_prefix_list_names) && length(var.ingress_prefix_list_ports) > 0 ? toset(var.ingress_prefix_list_ports) : toset([])
iterator = p
content {
description = try(p.value.label, local.short_description)
from_port = p.value.from
to_port = p.value.to
protocol = p.value.proto
prefix_list_ids = [for pl in data.aws_ec2_managed_prefix_list.inress : pl.id]
}
}

# egress all (with flag enable_default_egress)
dynamic "egress" {
for_each = var.enable_default_egress ? [1] : []
iterator = sg
content {
description = "${local.short_description}: All"
from_port = 0
to_port = 0
protocol = -1
cidr_blocks = distinct(flatten(compact(concat(local.egress_networks, var.egress_networks))))
}
}

# egress security group ids (all)
dynamic "egress" {
for_each = local.egress_sg
iterator = sg
content {
description = "${local.short_description}: ${local.egress_sg_names[sg]}"
from_port = 0
to_port = 0
protocol = -1
security_groups = [sg]
}
}

# egress with prefix lists
dynamic "egress" {
for_each = length(var.egress_prefix_list_names) && length(var.egress_prefix_list_ports) > 0 ? toset(var.egress_prefix_list_ports) : toset([])
iterator = p
content {
description = try(p.value.label, local.short_description)
from_port = p.value.from
to_port = p.value.to
protocol = p.value.proto
prefix_list_ids = [for pl in data.aws_ec2_managed_prefix_list.egress : pl.id]
}
}

tags = merge(
var.tags,
{
"Name" = "sg-${local.name}"
"boc:created_by" = "terraform"
"boc:tf_module_version" = local._module_version
"boc:vpc:info" = join(" ", compact([var.vpc_id, var.vpc_full_name]))
}
)
}
1 change: 1 addition & 0 deletions custom/data.prefix_lists.tf
1 change: 0 additions & 1 deletion custom/resources.tf

This file was deleted.

2 changes: 1 addition & 1 deletion custom/settings.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
locals {
name = var.name != "" ? var.name : local._defaults["name"]
is_modular = var.name == "" || length(regexall("^m-", var.name)) > 0
enable_self = var.enable_self ? ! local.is_modular : false
enable_self = var.enable_self ? !local.is_modular : false
description = var.description != "" ? var.description : local._defaults["description"]
short_description = var.short_description != "" ? var.short_description : local._defaults["short_description"]
}
1 change: 1 addition & 0 deletions custom/variables.prefix_lists.tf
22 changes: 22 additions & 0 deletions custom/variables.prefix_lists_ports.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
variable "ingress_prefix_list_ports" {
description = "List of port objects (from,to,proto,label) for ingress prefix lists"
type = list(object({
from = number
to = number
proto = optional(string, "tcp")
label = optional(string)
}))
default = []
}

variable "egress_prefix_list_ports" {
description = "List of port objects (from,to,proto,label) for egress prefix lists"
type = list(object({
from = number
to = number
proto = optional(string, "tcp")
label = optional(string)
}))
default = [{ from = 0, to = 0, proto = -1, label = "all" }]
}

0 comments on commit 9c454ce

Please sign in to comment.