Skip to content

Commit 4aa87dc

Browse files
authored
Refactor security-group module (#57)
1 parent bb619dd commit 4aa87dc

File tree

15 files changed

+534
-116
lines changed

15 files changed

+534
-116
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ Terraform Modules from [this package](https://github.com/tedilabs/terraform-aws-
4343
- [vpc-simple](./examples/vpc-simple)
4444
- [vpc-with-ipam](./examples/vpc-with-ipam)
4545

46+
### Security Group
47+
48+
- [security-group-simple](./examples/security-group-simple)
49+
- [security-group-with-ipv4-cidrs](./examples/security-group-with-ipv4-cidrs)
50+
4651
### NAT Gateway
4752

4853
- [nat-gateway-public](./examples/nat-gateway-public/)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
provider "aws" {
2+
region = "us-east-1"
3+
}
4+
5+
data "aws_vpc" "default" {
6+
default = true
7+
}
8+
9+
10+
###################################################
11+
# Security Group
12+
###################################################
13+
14+
module "security_group" {
15+
source = "../../modules/security-group"
16+
# source = "tedilabs/ipam/aws//modules/security-group"
17+
# version = "~> 0.30.0"
18+
19+
vpc_id = data.aws_vpc.default.id
20+
21+
name = "hello-world"
22+
23+
tags = {
24+
"project" = "terraform-aws-network-examples"
25+
}
26+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
output "security_group" {
2+
description = "The Security Group."
3+
value = module.security_group
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = "~> 1.5"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = "~> 5.0"
8+
}
9+
}
10+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
provider "aws" {
2+
region = "us-east-1"
3+
}
4+
5+
data "aws_vpc" "default" {
6+
default = true
7+
}
8+
9+
10+
###################################################
11+
# Security Group
12+
###################################################
13+
14+
module "security_group" {
15+
source = "../../modules/security-group"
16+
# source = "tedilabs/ipam/aws//modules/security-group"
17+
# version = "~> 0.30.0"
18+
19+
vpc_id = data.aws_vpc.default.id
20+
21+
name = "hello-world-ipv4-cidrs"
22+
description = "Sample Security Group with IPv4 CIDRs."
23+
24+
revoke_rules_on_delete = true
25+
26+
ingress_rules = [
27+
{
28+
id = "tcp/80"
29+
description = "Allow HTTP from VPC"
30+
from_port = 80
31+
to_port = 80
32+
protocol = "tcp"
33+
ipv4_cidrs = ["192.168.0.0/16", "10.0.0.0/8", "172.168.0.0/24"]
34+
},
35+
]
36+
egress_rules = [
37+
{
38+
id = "all/all"
39+
description = "Allow all traffics to the internet"
40+
from_port = 0
41+
to_port = 0
42+
protocol = "-1"
43+
ipv4_cidrs = ["0.0.0.0/0"]
44+
},
45+
]
46+
47+
tags = {
48+
"project" = "terraform-aws-network-examples"
49+
}
50+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
output "security_group" {
2+
description = "The Security Group."
3+
value = module.security_group
4+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
terraform {
2+
required_version = "~> 1.5"
3+
4+
required_providers {
5+
aws = {
6+
source = "hashicorp/aws"
7+
version = "~> 5.0"
8+
}
9+
}
10+
}

modules/security-group/README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@
33
This module creates following resources.
44

55
- `aws_security_group`
6-
- `aws_security_group_rule` (optional)
6+
- `aws_vpc_security_group_ingress_rule` (optional)
7+
- `aws_vpc_security_group_egress_rule` (optional)
78

89
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
910
## Requirements
1011

1112
| Name | Version |
1213
|------|---------|
13-
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.5 |
14-
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 3.45 |
14+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.6 |
15+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.3 |
1516

1617
## Providers
1718

1819
| Name | Version |
1920
|------|---------|
20-
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.19.0 |
21+
| <a name="provider_aws"></a> [aws](#provider\_aws) | 5.24.0 |
2122

2223
## Modules
2324

@@ -30,8 +31,8 @@ This module creates following resources.
3031
| Name | Type |
3132
|------|------|
3233
| [aws_security_group.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group) | resource |
33-
| [aws_security_group_rule.egress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource |
34-
| [aws_security_group_rule.ingress](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule) | resource |
34+
| [aws_vpc_security_group_egress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_egress_rule) | resource |
35+
| [aws_vpc_security_group_ingress_rule.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc_security_group_ingress_rule) | resource |
3536

3637
## Inputs
3738

@@ -40,10 +41,9 @@ This module creates following resources.
4041
| <a name="input_name"></a> [name](#input\_name) | (Required) The name of the security group. | `string` | n/a | yes |
4142
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | (Required) The ID of the associated VPC. | `string` | n/a | yes |
4243
| <a name="input_description"></a> [description](#input\_description) | (Optional) The security group description. This field maps to the AWS `GroupDescription` attribute, for which there is no Update API. | `string` | `"Managed by Terraform."` | no |
43-
| <a name="input_egress_rules"></a> [egress\_rules](#input\_egress\_rules) | (Optional) A list of egress rules in a security group. | `any` | `[]` | no |
44-
| <a name="input_ingress_rules"></a> [ingress\_rules](#input\_ingress\_rules) | (Optional) A list of ingress rules in a security group. | `any` | `[]` | no |
44+
| <a name="input_egress_rules"></a> [egress\_rules](#input\_egress\_rules) | (Optional) The configuration for egress rules of the security group. Each block of `egress_rules` as defined below.<br> (Required) `id` - The ID of the egress rule. This value is only used internally within Terraform code.<br> (Optional) `description` - The description of the rule.<br> (Required) `protocol` - The protocol to match. Note that if `protocol` is set to `-1`, it translates to all protocols, all port ranges, and `from_port` and `to_port` values should not be defined.<br> (Required) `from_port` - The start of port range for the TCP and UDP protocols, or an ICMP/ICMPv6 type.<br> (Required) `to_port` - The end of port range for the TCP and UDP protocols, or an ICMP/ICMPv6 code.<br> (Optional) `ipv4_cidrs` - The IPv4 network ranges to allow, in CIDR notation.<br> (Optional) `ipv6_cidrs` - The IPv6 network ranges to allow, in CIDR notation.<br> (Optional) `prefix_lists` - The prefix list IDs to allow.<br> (Optional) `security_groups` - The source security group IDs to allow.<br> (Optional) `self` - Whether the security group itself will be added as a source to this ingress rule. | <pre>list(object({<br> id = string<br> description = optional(string, "Managed by Terraform.")<br> protocol = string<br> from_port = number<br> to_port = number<br> ipv4_cidrs = optional(list(string), [])<br> ipv6_cidrs = optional(list(string), [])<br> prefix_lists = optional(list(string), [])<br> security_groups = optional(list(string), [])<br> self = optional(bool, false)<br> }))</pre> | `[]` | no |
45+
| <a name="input_ingress_rules"></a> [ingress\_rules](#input\_ingress\_rules) | (Optional) The configuration for ingress rules of the security group. Each block of `ingress_rules` as defined below.<br> (Required) `id` - The ID of the ingress rule. This value is only used internally within Terraform code.<br> (Optional) `description` - The description of the rule.<br> (Required) `protocol` - The protocol to match. Note that if `protocol` is set to `-1`, it translates to all protocols, all port ranges, and `from_port` and `to_port` values should not be defined.<br> (Required) `from_port` - The start of port range for the TCP and UDP protocols, or an ICMP/ICMPv6 type.<br> (Required) `to_port` - The end of port range for the TCP and UDP protocols, or an ICMP/ICMPv6 code.<br> (Optional) `ipv4_cidrs` - The IPv4 network ranges to allow, in CIDR notation.<br> (Optional) `ipv6_cidrs` - The IPv6 network ranges to allow, in CIDR notation.<br> (Optional) `prefix_lists` - The prefix list IDs to allow.<br> (Optional) `security_groups` - The source security group IDs to allow.<br> (Optional) `self` - Whether the security group itself will be added as a source to this ingress rule. | <pre>list(object({<br> id = string<br> description = optional(string, "Managed by Terraform.")<br> protocol = string<br> from_port = number<br> to_port = number<br> ipv4_cidrs = optional(list(string), [])<br> ipv6_cidrs = optional(list(string), [])<br> prefix_lists = optional(list(string), [])<br> security_groups = optional(list(string), [])<br> self = optional(bool, false)<br> }))</pre> | `[]` | no |
4546
| <a name="input_module_tags_enabled"></a> [module\_tags\_enabled](#input\_module\_tags\_enabled) | (Optional) Whether to create AWS Resource Tags for the module informations. | `bool` | `true` | no |
46-
| <a name="input_name_prefix"></a> [name\_prefix](#input\_name\_prefix) | (Optional) Creates a unique name beginning with the specified prefix. Conflicts with `name`. | `string` | `null` | no |
4747
| <a name="input_resource_group_description"></a> [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no |
4848
| <a name="input_resource_group_enabled"></a> [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no |
4949
| <a name="input_resource_group_name"></a> [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no |
@@ -55,7 +55,10 @@ This module creates following resources.
5555
| Name | Description |
5656
|------|-------------|
5757
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the security group. |
58+
| <a name="output_description"></a> [description](#output\_description) | The description of the security group. |
59+
| <a name="output_egress_rules"></a> [egress\_rules](#output\_egress\_rules) | The configuration of the security group egress rules. |
5860
| <a name="output_id"></a> [id](#output\_id) | The ID of the security group. |
61+
| <a name="output_ingress_rules"></a> [ingress\_rules](#output\_ingress\_rules) | The configuration of the security group ingress rules. |
5962
| <a name="output_name"></a> [name](#output\_name) | The name of the security group. |
6063
| <a name="output_owner_id"></a> [owner\_id](#output\_owner\_id) | The ID of the AWS account that owns the security group. |
6164
| <a name="output_vpc_id"></a> [vpc\_id](#output\_vpc\_id) | The ID of the associated VPC. |

modules/security-group/main.tf

Lines changed: 12 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,21 @@ locals {
1414
} : {}
1515
}
1616

17+
18+
###################################################
19+
# Security Group
20+
###################################################
21+
22+
# INFO: Not supported attributes
23+
# - `name_prefix`
24+
# INFO: Use a separate resource
25+
# - `egress`
26+
# - `ingress`
1727
resource "aws_security_group" "this" {
1828
vpc_id = var.vpc_id
1929

20-
name = var.name
21-
name_prefix = var.name_prefix
30+
name = var.name
31+
# name_prefix = var.name_prefix
2232
description = var.description
2333

2434
revoke_rules_on_delete = var.revoke_rules_on_delete
@@ -31,85 +41,3 @@ resource "aws_security_group" "this" {
3141
var.tags,
3242
)
3343
}
34-
35-
36-
###################################################
37-
# Security Group Rules
38-
###################################################
39-
40-
locals {
41-
normalized_ingress_rules = [
42-
for rule in var.ingress_rules : {
43-
id = rule.id
44-
description = lookup(rule, "description", "Managed by Terraform")
45-
46-
protocol = rule.protocol
47-
from_port = rule.from_port
48-
to_port = rule.to_port
49-
50-
cidr_blocks = try(sort(compact(rule.cidr_blocks)), null)
51-
ipv6_cidr_blocks = try(sort(compact(rule.ipv6_cidr_blocks)), null)
52-
prefix_list_ids = try(sort(compact(rule.prefix_list_ids)), null)
53-
source_security_group_id = try(rule.source_security_group_id, null)
54-
self = try(rule.self, false) ? true : null
55-
}
56-
]
57-
normalized_egress_rules = [
58-
for rule in var.egress_rules : {
59-
id = rule.id
60-
description = lookup(rule, "description", "Managed by Terraform")
61-
62-
protocol = rule.protocol
63-
from_port = rule.from_port
64-
to_port = rule.to_port
65-
66-
cidr_blocks = try(sort(compact(rule.cidr_blocks)), null)
67-
ipv6_cidr_blocks = try(sort(compact(rule.ipv6_cidr_blocks)), null)
68-
prefix_list_ids = try(sort(compact(rule.prefix_list_ids)), null)
69-
source_security_group_id = try(rule.source_security_group_id, null)
70-
self = try(rule.self, false) ? true : null
71-
}
72-
]
73-
}
74-
75-
resource "aws_security_group_rule" "ingress" {
76-
for_each = {
77-
for rule in local.normalized_ingress_rules :
78-
rule.id => rule
79-
}
80-
81-
security_group_id = aws_security_group.this.id
82-
type = "ingress"
83-
description = each.value.description
84-
85-
protocol = each.value.protocol
86-
from_port = each.value.from_port
87-
to_port = each.value.to_port
88-
89-
cidr_blocks = each.value.cidr_blocks
90-
ipv6_cidr_blocks = each.value.ipv6_cidr_blocks
91-
prefix_list_ids = each.value.prefix_list_ids
92-
source_security_group_id = each.value.source_security_group_id
93-
self = each.value.self
94-
}
95-
96-
resource "aws_security_group_rule" "egress" {
97-
for_each = {
98-
for rule in local.normalized_egress_rules :
99-
rule.id => rule
100-
}
101-
102-
security_group_id = aws_security_group.this.id
103-
type = "egress"
104-
description = each.value.description
105-
106-
protocol = each.value.protocol
107-
from_port = each.value.from_port
108-
to_port = each.value.to_port
109-
110-
cidr_blocks = each.value.cidr_blocks
111-
ipv6_cidr_blocks = each.value.ipv6_cidr_blocks
112-
prefix_list_ids = each.value.prefix_list_ids
113-
source_security_group_id = each.value.source_security_group_id
114-
self = each.value.self
115-
}

modules/security-group/outputs.tf

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ output "name" {
1313
value = aws_security_group.this.name
1414
}
1515

16+
output "description" {
17+
description = "The description of the security group."
18+
value = aws_security_group.this.description
19+
}
20+
1621
output "owner_id" {
1722
description = "The ID of the AWS account that owns the security group."
1823
value = aws_security_group.this.owner_id
@@ -22,3 +27,39 @@ output "vpc_id" {
2227
description = "The ID of the associated VPC."
2328
value = aws_security_group.this.vpc_id
2429
}
30+
31+
output "ingress_rules" {
32+
description = <<EOF
33+
The configuration of the security group ingress rules.
34+
EOF
35+
value = {
36+
for name, rule in aws_vpc_security_group_ingress_rule.this :
37+
name => {
38+
id = rule.id
39+
arn = rule.arn
40+
description = rule.description
41+
42+
protocol = rule.ip_protocol
43+
from_port = rule.from_port
44+
to_port = rule.to_port
45+
}
46+
}
47+
}
48+
49+
output "egress_rules" {
50+
description = <<EOF
51+
The configuration of the security group egress rules.
52+
EOF
53+
value = {
54+
for name, rule in aws_vpc_security_group_egress_rule.this :
55+
name => {
56+
id = rule.id
57+
arn = rule.arn
58+
description = rule.description
59+
60+
protocol = rule.ip_protocol
61+
from_port = rule.from_port
62+
to_port = rule.to_port
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)