Skip to content

Commit

Permalink
Merge pull request #35 from terraform-modules/refactor/base
Browse files Browse the repository at this point in the history
refactor/base
  • Loading branch information
badra001 committed Mar 19, 2026
2 parents 091efce + 1f1a5e9 commit c4817c8
Show file tree
Hide file tree
Showing 9 changed files with 354 additions and 130 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,5 @@
* 2.10.0 -- 2026-03-03
- rds-mysql: add prefix list capability

* 2.11.0 -- 2026-03-19
- it-windows-base: refactor to use prefix lists and a YAML file
2 changes: 1 addition & 1 deletion common/version.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
locals {
_module_version = "2.10.0"
_module_version = "2.11.0"
}
40 changes: 15 additions & 25 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 @@ -43,8 +23,16 @@ 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_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
219 changes: 118 additions & 101 deletions it-windows-base/main.tf
Original file line number Diff line number Diff line change
@@ -1,123 +1,140 @@
/**
* # 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(local._sg, { ingress_networks = flatten(distinct(compact(concat(local.ingress_networks, var.use_vpc_cidr ? [data.aws_vpc.this_vpc.cidr_block] : [])))) })
sg_ingress_prefix_lists = distinct(compact([for sgr in local.sg.ingress : try(sgr.prefix_list, null)]))
sg_egress_prefix_lists = try(distinct(compact([for sgr in local.sg.egress : try(sgr.prefix_list, null)])), [])
sg_c1 = flatten([for i in local.sg.ingress : merge(i, {
key = local.sg.name,
# label = format("%v:%v:%v", local.sg.name, i.from, i.proto)
label = format("%v:%v:%v", i.from, i.to, i.proto)
# cidr_blocks = try(i.cidr_blocks, null) == "%%INCOMING%%" ? local.ingress_networks : []
cidr_blocks = try(i.cidr_blocks, [])
}
}

# 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 i in try(local.sg.ingress_security_groups, []) : merge(local.sg, {
key = local.sg.name,
# label = format("%v:%v", local.sg.name, i)
label = 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
}) if try(sg.prefix_list, null) == plk
]])
}
# 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" {
resource "aws_security_group" "this_security_group" {
# for_each = { for sg in local.sg: sg.name => sg }
# name = format("%v-%v", var.name_prefix, each.key)
name = local.sg.name
# description = trimspace(format("%v %v", var.description_prefix, each.value.description))
description = trimspace(local.sg.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) }
{ "Name" = format("sg-%v", local.sg.name) }
)
}

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

security_group_id = aws_security_group.this_security_group.id
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 = try(local.sg.self, false) ? { (local.sg.name) = aws_security_group.this_security_group.id } : {}

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.this_security_group.id
description = "self"
ip_protocol = -1
referenced_security_group_id = aws_security_group.this_security_group.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.this_security_group.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.this_security_group.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 c4817c8

Please sign in to comment.