Skip to content

Commit

Permalink
start refactor to use prefix_lists
Browse files Browse the repository at this point in the history
  • Loading branch information
badra001 committed Mar 19, 2026
1 parent 091efce commit f677bc1
Show file tree
Hide file tree
Showing 7 changed files with 338 additions and 130 deletions.
42 changes: 16 additions & 26 deletions it-windows-base/README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,15 @@
# About it-windows-base

This describes how to use the aws-common-security-groups submodule for it-windows-base.

Commonly used ports and services are set up here, including ICMP, AD, RDP, NTP, DNS, SNMP,
monit, munin, iperf, netperf, NetBackup and Opsware.

## Usage

```hcl
module "it-windows-base" {
source = "git@github.e.it.census.gov:terraform-modules/aws-common-security-groups.git//it-windows-base"
# name = "it-windows-base"
vpc_id = var.vpc_id
# Name, CostAllocation, and Environment are pre-set, but they can be overriden
# tags = { }
}
```

## Requirements

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

## Providers

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

## Modules

Expand All @@ -42,9 +22,17 @@ module "it-windows-base" {

| Name | Type |
|------|------|
| [aws_security_group.this_security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
| [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 |
| [aws_security_group.sg](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
| [aws_vpc_security_group_egress_rule.all](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource |
| [aws_vpc_security_group_ingress_rule.cidr_block](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
| [aws_vpc_security_group_ingress_rule.prefix_lists](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
| [aws_vpc_security_group_ingress_rule.security_group](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
| [aws_vpc_security_group_ingress_rule.self](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | 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_vpc.selected](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |
| [aws_vpc.this_vpc](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/vpc) | data source |

Expand All @@ -54,9 +42,11 @@ module "it-windows-base" {
|------|-------------|------|---------|:--------:|
| <a name="input_description"></a> [description](#input\_description) | Security Group Description | `string` | `"Windows Common Base Security Group"` | no |
| <a name="input_egress_networks"></a> [egress\_networks](#input\_egress\_networks) | List of egress networks (all ports) | `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_security_groups"></a> [egress\_security\_groups](#input\_egress\_security\_groups) | List of egress security groups (all ports) | `list(string)` | `[]` | 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 external access (not all ports) | `list(string)` | <pre>[<br/> "0.0.0.0/0"<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_security_groups"></a> [ingress\_security\_groups](#input\_ingress\_security\_groups) | List of ingress security groups for all ports | `list(string)` | `[]` | no |
| <a name="input_name"></a> [name](#input\_name) | Security Group Name | `string` | `"it-windows-base"` | no |
| <a name="input_short_description"></a> [short\_description](#input\_short\_description) | Security Group Short Description | `string` | `"Windows"` | no |
Expand Down
1 change: 1 addition & 0 deletions it-windows-base/data.tf
211 changes: 110 additions & 101 deletions it-windows-base/main.tf
Original file line number Diff line number Diff line change
@@ -1,123 +1,132 @@
/**
* # About it-windows-base
*
* This describes how to use the aws-common-security-groups submodule for it-windows-base.
*
* Commonly used ports and services are set up here, including ICMP, AD, RDP, NTP, DNS, SNMP,
* monit, munin, iperf, netperf, NetBackup and Opsware.
*
* ## Usage
*
* ```hcl
* module "it-windows-base" {
* source = "git@github.e.it.census.gov:terraform-modules/aws-common-security-groups.git//it-windows-base"
*
* # name = "it-windows-base"
* vpc_id = var.vpc_id
* # Name, CostAllocation, and Environment are pre-set, but they can be overriden
* # tags = { }
* }
* ```
*/

data "aws_vpc" "this_vpc" {
count = var.use_vpc_cidr ? 1 : 0
id = var.vpc_id
id = var.vpc_id
}

data "aws_security_group" "ingress_security_groups" {
count = length(var.ingress_security_groups)
id = element(var.ingress_security_groups, count.index)
}
locals {
n_all = ["0.0.0.0/0"]

data "aws_security_group" "egress_security_groups" {
count = length(var.egress_security_groups)
id = element(var.egress_security_groups, count.index)
ingress_networks = var.ingress_networks == null ? [] : var.ingress_networks
egress_networks = var.egress_networks == null ? [] : var.egress_networks
}

locals {
vpc_networks = var.use_vpc_cidr ? [data.aws_vpc.this_vpc[0].cidr_block] : []
vpc_networks = var.use_vpc_cidr ? [data.aws_vpc.this_vpc.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 ? [1] : []
short_description = var.short_description == "" ? var.description : var.short_description
# 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)
}

resource "aws_security_group" "this_security_group" {
name = local.name
description = var.description
vpc_id = var.vpc_id
# vpc_id = "${data.aws_vpc.selected.id}"

# 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 ? local.external_ingress_networks : p.value["cidr"]
locals {
_sg = yamldecode(file("${path.module}/ports.yml"))
sg = [merge(sg, { ingress_networks = flatten(distinct(compact(concat(local.ingress_networks, sg.vpc_cidr ? [data.aws_vpc.this_vpc.cidr_block] : [])))) })]
sg_ingress_prefix_lists = distinct(compact([for sgr in local.sg[0].ingress : try(sgr.prefix_list, null)]))
sg_egress_prefix_lists = try(distinct(compact([for sgr in local.sg[0].egress : try(sgr.prefix_list, null)])), null)
sg_c1 = flatten([for k, v in local.sg : [for i in v.ingress : merge(i, {
key = k,
label = format("%v:%v:%v", k, i.from, i.proto)
cidr_blocks = try(i.cidr_blocks, null) == "%%INCOMING%%" ? local.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]
)]])
sg_cidr = flatten([for sg in local.sg_c1 : [for c in sg.cidr_blocks : merge(sg, {
cidr_label = format("%v:%v", sg.label, c)
cidr_block = c
}
}

# ingress self (list with one or zero items)
dynamic "ingress" {
for_each = local.self
iterator = sg
content {
description = "${local.short_description}: from self"
from_port = 0
to_port = 0
protocol = -1
self = true
)]])
sg_sg = flatten([for k, v in local.sg : [for i in try(v.ingress_security_groups, []) : merge(v, {
key = k,
label = format("%v:%v", k, i)
security_group_name = i
}
}
)]])
sg_pl = flatten([for sg in local.sg_c1 : [for plk, plv in data.aws_ec2_managed_prefix_list.ingress : merge(sg, {
prefix_list_label = format("%v:%v", sg.label, plk)
prefix_list_id = plv.id
}
)]])
}
# egress all
egress {
description = "${local.short_description}: All"
from_port = 0
to_port = 0
protocol = -1
cidr_blocks = local.egress_networks
data "aws_ec2_managed_prefix_list" "ingress" {
for_each = toset(local.sg_ingress_prefix_lists)
filter {
name = "prefix-list-name"
values = [each.key]
}
}

# 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]
}
data "aws_ec2_managed_prefix_list" "egress" {
for_each = toset(local.sg_egress_prefix_lists)
filter {
name = "prefix-list-name"
values = [each.key]
}
}

# create group with just egress. Add all ingress via secondary resource
resource "aws_security_group" "sg" {
for_each = local.sg
name = format("%v-%v", var.name_prefix, each.key)
description = trimspace(format("%v %v", var.description_prefix, each.value.description))
vpc_id = var.vpc_id

tags = merge(
local.base_tags,
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]))
}
{ "Name" = format("sg-%v-%v", var.name_prefix, each.key) }
)
}

# egress: all
resource "aws_vpc_security_group_egress_rule" "all" {
for_each = { for k, v in local.sg : k => aws_security_group.sg[k].id }

security_group_id = each.value
description = "ALL"
ip_protocol = -1
# cidr_block = local.egress_networks
cidr_ipv4 = local.n_all[0]
}


# ingress: self
resource "aws_vpc_security_group_ingress_rule" "self" {
for_each = { for k, v in local.sg : k => aws_security_group.sg[k].id if try(v.self, false) }

security_group_id = each.value
description = "self"
ip_protocol = -1
referenced_security_group_id = each.value
}

# ingress: by security_group
resource "aws_vpc_security_group_ingress_rule" "security_group" {
for_each = { for x in local.sg_sg : x.label => x }

security_group_id = aws_security_group.sg[each.value.key].id
description = "self"
ip_protocol = -1
referenced_security_group_id = aws_security_group.sg[each.value.security_group_name].id
}

# ingress: by cidr_block
resource "aws_vpc_security_group_ingress_rule" "cidr_block" {
for_each = { for x in local.sg_cidr : x.cidr_label => x }

security_group_id = aws_security_group.sg[each.value.key].id
description = each.value.short
from_port = each.value.from
to_port = each.value.to
ip_protocol = each.value.proto
cidr_ipv4 = each.value.cidr_block
}

# ingress: by prefix_list
resource "aws_vpc_security_group_ingress_rule" "prefix_lists" {
for_each = { for x in local.sg_pl : x.prefix_list_label => x }

security_group_id = aws_security_group.sg[each.value.key].id
description = each.value.short
from_port = each.value.from
to_port = each.value.to
ip_protocol = each.value.proto
prefix_list_id = each.value.prefix_list_id
}
Loading

0 comments on commit f677bc1

Please sign in to comment.