Skip to content

Commit

Permalink
Allow default_security_group to have no rules
Browse files Browse the repository at this point in the history
The current implementation of the aws_default_security_group
uses dynamic blocks for both ingress and egress rules. If no
rules are passed in, then no dynamic blocks are generated,
and no pre-existng rules are changed. In order to implement the
CIS benchmark of no rules, the aws_default_security_group
resorce needs to be created passing empty lists as ingress
and egress rules.

This commit updates the default ingress/egress rules to be
those AWS uses when it initially created the default SG.
It then sets the boolen local.empty_default_security_group
if both ingress and egress rules passed in are empty lists.
Finally it conditionally creates empty aws_default_security_group
resource if local.empty_default_security_group is true.  If
local.empty_default_security_group is false, the original
aws_default_security_group resource is utilized.
  • Loading branch information
Britt Houser authored and Britt Houser committed Sep 30, 2024
1 parent e226cc1 commit 0b0b3c8
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ No modules.
| [aws_db_subnet_group.database](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_subnet_group) | resource |
| [aws_default_network_acl.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_network_acl) | resource |
| [aws_default_route_table.default](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_route_table) | resource |
| [aws_default_security_group.empty](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_security_group) | resource |
| [aws_default_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_security_group) | resource |
| [aws_default_vpc.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_vpc) | resource |
| [aws_egress_only_internet_gateway.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/egress_only_internet_gateway) | resource |
Expand Down Expand Up @@ -406,8 +407,8 @@ No modules.
| <a name="input_default_route_table_propagating_vgws"></a> [default\_route\_table\_propagating\_vgws](#input\_default\_route\_table\_propagating\_vgws) | List of virtual gateways for propagation | `list(string)` | `[]` | no |
| <a name="input_default_route_table_routes"></a> [default\_route\_table\_routes](#input\_default\_route\_table\_routes) | Configuration block of routes. See https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/default_route_table#route | `list(map(string))` | `[]` | no |
| <a name="input_default_route_table_tags"></a> [default\_route\_table\_tags](#input\_default\_route\_table\_tags) | Additional tags for the default route table | `map(string)` | `{}` | no |
| <a name="input_default_security_group_egress"></a> [default\_security\_group\_egress](#input\_default\_security\_group\_egress) | List of maps of egress rules to set on the default security group | `list(map(string))` | `[]` | no |
| <a name="input_default_security_group_ingress"></a> [default\_security\_group\_ingress](#input\_default\_security\_group\_ingress) | List of maps of ingress rules to set on the default security group | `list(map(string))` | `[]` | no |
| <a name="input_default_security_group_egress"></a> [default\_security\_group\_egress](#input\_default\_security\_group\_egress) | List of maps of egress rules to set on the default security group. Default is the AWS default egress rule. | `list(map(string))` | <pre>[<br> {<br> "cidr_blocks": "0.0.0.0/0",<br> "from_port": 0,<br> "ipv6_cidr_blocks": "::/0",<br> "protocol": "-1",<br> "to_port": 0<br> }<br>]</pre> | no |
| <a name="input_default_security_group_ingress"></a> [default\_security\_group\_ingress](#input\_default\_security\_group\_ingress) | List of maps of ingress rules to set on the default security group. Default is AWS default ingress rule. | `list(map(string))` | <pre>[<br> {<br> "from_port": 0,<br> "protocol": -1,<br> "self": true,<br> "to_port": 0<br> }<br>]</pre> | no |
| <a name="input_default_security_group_name"></a> [default\_security\_group\_name](#input\_default\_security\_group\_name) | Name to be used on the default security group | `string` | `null` | no |
| <a name="input_default_security_group_tags"></a> [default\_security\_group\_tags](#input\_default\_security\_group\_tags) | Additional tags for the default security group | `map(string)` | `{}` | no |
| <a name="input_default_vpc_enable_dns_hostnames"></a> [default\_vpc\_enable\_dns\_hostnames](#input\_default\_vpc\_enable\_dns\_hostnames) | Should be true to enable DNS hostnames in the Default VPC | `bool` | `true` | no |
Expand Down
26 changes: 25 additions & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ locals {
local.len_redshift_subnets,
)

# True if both var.default_security_group_ingress and var.default_security_group_egress are empty lists
empty_default_security_group = length(var.default_security_group_ingress) < 1 && length(var.default_security_group_egress) < 1

# Use `local.vpc_id` to give a hint to Terraform that subnets should be deleted before secondary CIDR blocks can be free!
vpc_id = try(aws_vpc_ipv4_cidr_block_association.this[0].vpc_id, aws_vpc.this[0].id, "")

Expand Down Expand Up @@ -1229,8 +1232,29 @@ resource "aws_default_vpc" "this" {
)
}

################################################################################
# Default Security Group
################################################################################

# Default security group with no rules, per CIS Benchmark
resource "aws_default_security_group" "empty" {
count = local.create_vpc && var.manage_default_security_group && local.empty_default_security_group ? 1 : 0

vpc_id = aws_vpc.this[0].id
ingress = []
egress = []

tags = merge(
{ "Name" = coalesce(var.default_security_group_name, "${var.name}-default") },
var.tags,
var.default_security_group_tags,
)

}

# Default security group with user provided rules
resource "aws_default_security_group" "this" {
count = local.create_vpc && var.manage_default_security_group ? 1 : 0
count = local.create_vpc && var.manage_default_security_group && !local.empty_default_security_group ? 1 : 0

vpc_id = aws_vpc.this[0].id

Expand Down
23 changes: 19 additions & 4 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -1355,15 +1355,30 @@ variable "default_security_group_name" {
}

variable "default_security_group_ingress" {
description = "List of maps of ingress rules to set on the default security group"
description = "List of maps of ingress rules to set on the default security group. Default is AWS default ingress rule."
type = list(map(string))
default = []
default = [
{
protocol = -1
self = true
from_port = 0
to_port = 0
},
]
}

variable "default_security_group_egress" {
description = "List of maps of egress rules to set on the default security group"
description = "List of maps of egress rules to set on the default security group. Default is the AWS default egress rule."
type = list(map(string))
default = []
default = [
{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = "0.0.0.0/0"
ipv6_cidr_blocks = "::/0"
},
]
}

variable "default_security_group_tags" {
Expand Down

0 comments on commit 0b0b3c8

Please sign in to comment.