Skip to content

Commit b4482a1

Browse files
authored
feat: use security-group module to provision AWS SG (#82)
1 parent b510fe6 commit b4482a1

File tree

11 files changed

+171
-80
lines changed

11 files changed

+171
-80
lines changed

README.md

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,25 @@ We literally have [*hundreds of terraform modules*][terraform_modules] that are
6767

6868

6969

70+
## Security & Compliance [<img src="https://cloudposse.com/wp-content/uploads/2020/11/bridgecrew.svg" width="250" align="right" />](https://bridgecrew.io/)
71+
72+
Security scanning is graciously provided by Bridgecrew. Bridgecrew is the leading fully hosted, cloud-native solution providing continuous Terraform security and compliance.
73+
74+
| Benchmark | Description |
75+
|--------|---------------|
76+
| [![Infrastructure Security](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/general)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=INFRASTRUCTURE+SECURITY) | Infrastructure Security Compliance |
77+
| [![CIS KUBERNETES](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/cis_kubernetes)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=CIS+KUBERNETES+V1.5) | Center for Internet Security, KUBERNETES Compliance |
78+
| [![CIS AWS](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/cis_aws)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=CIS+AWS+V1.2) | Center for Internet Security, AWS Compliance |
79+
| [![CIS AZURE](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/cis_azure)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=CIS+AZURE+V1.1) | Center for Internet Security, AZURE Compliance |
80+
| [![PCI-DSS](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/pci)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=PCI-DSS+V3.2) | Payment Card Industry Data Security Standards Compliance |
81+
| [![NIST-800-53](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/nist)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=NIST-800-53) | National Institute of Standards and Technology Compliance |
82+
| [![ISO27001](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/iso)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=ISO27001) | Information Security Management System, ISO/IEC 27001 Compliance |
83+
| [![SOC2](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/soc2)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=SOC2)| Service Organization Control 2 Compliance |
84+
| [![CIS GCP](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/cis_gcp)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=CIS+GCP+V1.1) | Center for Internet Security, GCP Compliance |
85+
| [![HIPAA](https://www.bridgecrew.cloud/badges/github/cloudposse/terraform-aws-ec2-instance/hipaa)](https://www.bridgecrew.cloud/link/badge?vcs=github&fullRepo=cloudposse%2Fterraform-aws-ec2-instance&benchmark=HIPAA) | Health Insurance Portability and Accountability Compliance |
86+
87+
88+
7089
## Usage
7190

7291

@@ -120,7 +139,43 @@ module "kafka_instance" {
120139
stage = "dev"
121140
additional_ips_count = 1
122141
ebs_volume_count = 2
123-
allowed_ports = [22, 80, 443]
142+
security_group_rules = [
143+
{
144+
type = "egress"
145+
from_port = 0
146+
to_port = 65535
147+
protocol = "-1"
148+
cidr_blocks = ["0.0.0.0/0"]
149+
},
150+
{
151+
type = "ingress"
152+
from_port = 22
153+
to_port = 22
154+
protocol = "tcp"
155+
cidr_blocks = ["0.0.0.0/0"]
156+
},
157+
{
158+
type = "ingress"
159+
from_port = 80
160+
to_port = 80
161+
protocol = "tcp"
162+
cidr_blocks = ["0.0.0.0/0"]
163+
},
164+
{
165+
type = "ingress"
166+
from_port = 443
167+
to_port = 443
168+
protocol = "tcp"
169+
cidr_blocks = ["0.0.0.0/0"]
170+
},
171+
{
172+
type = "ingress"
173+
from_port = 53
174+
to_port = 53
175+
protocol = "udp"
176+
cidr_blocks = ["0.0.0.0/0"]
177+
},
178+
]
124179
}
125180
```
126181

@@ -163,8 +218,6 @@ Available targets:
163218
|------|-------------|------|---------|:--------:|
164219
| additional\_ips\_count | Count of additional EIPs | `number` | `0` | no |
165220
| additional\_tag\_map | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no |
166-
| allowed\_ports | List of allowed ingress TCP ports | `list(number)` | `[]` | no |
167-
| allowed\_ports\_udp | List of allowed ingress UDP ports | `list(number)` | `[]` | no |
168221
| ami | The AMI to use for the instance. By default it is the AMI provided by Amazon with Ubuntu 16.04 | `string` | `""` | no |
169222
| ami\_owner | Owner of the given AMI (ignored if `ami` unset) | `string` | `""` | no |
170223
| applying\_period | The period in seconds over which the specified statistic is applied | `number` | `60` | no |
@@ -212,6 +265,7 @@ Available targets:
212265
| root\_iops | Amount of provisioned IOPS. This must be set if root\_volume\_type is set to `io1` | `number` | `0` | no |
213266
| root\_volume\_size | Size of the root volume in gigabytes | `number` | `10` | no |
214267
| root\_volume\_type | Type of root volume. Can be standard, gp2 or io1 | `string` | `"gp2"` | no |
268+
| security\_group\_rules | A list of maps of Security Group rules. <br>The values of map is fully complated with `aws_security_group_rule` resource. <br>To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule . | `list(any)` | <pre>[<br> {<br> "cidr_blocks": [<br> "0.0.0.0/0"<br> ],<br> "from_port": 0,<br> "protocol": "-1",<br> "to_port": 65535,<br> "type": "egress"<br> }<br>]</pre> | no |
215269
| security\_groups | List of Security Group IDs allowed to connect to the instance | `list(string)` | `[]` | no |
216270
| source\_dest\_check | Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs | `bool` | `true` | no |
217271
| ssh\_key\_pair | SSH key pair to be provisioned on the instance | `string` | n/a | yes |

README.yaml

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,43 @@ usage: |-
8282
stage = "dev"
8383
additional_ips_count = 1
8484
ebs_volume_count = 2
85-
allowed_ports = [22, 80, 443]
85+
security_group_rules = [
86+
{
87+
type = "egress"
88+
from_port = 0
89+
to_port = 65535
90+
protocol = "-1"
91+
cidr_blocks = ["0.0.0.0/0"]
92+
},
93+
{
94+
type = "ingress"
95+
from_port = 22
96+
to_port = 22
97+
protocol = "tcp"
98+
cidr_blocks = ["0.0.0.0/0"]
99+
},
100+
{
101+
type = "ingress"
102+
from_port = 80
103+
to_port = 80
104+
protocol = "tcp"
105+
cidr_blocks = ["0.0.0.0/0"]
106+
},
107+
{
108+
type = "ingress"
109+
from_port = 443
110+
to_port = 443
111+
protocol = "tcp"
112+
cidr_blocks = ["0.0.0.0/0"]
113+
},
114+
{
115+
type = "ingress"
116+
from_port = 53
117+
to_port = 53
118+
protocol = "udp"
119+
cidr_blocks = ["0.0.0.0/0"]
120+
},
121+
]
86122
}
87123
```
88124
references:

docs/terraform.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
|------|-------------|------|---------|:--------:|
2121
| additional\_ips\_count | Count of additional EIPs | `number` | `0` | no |
2222
| additional\_tag\_map | Additional tags for appending to tags\_as\_list\_of\_maps. Not added to `tags`. | `map(string)` | `{}` | no |
23-
| allowed\_ports | List of allowed ingress TCP ports | `list(number)` | `[]` | no |
24-
| allowed\_ports\_udp | List of allowed ingress UDP ports | `list(number)` | `[]` | no |
2523
| ami | The AMI to use for the instance. By default it is the AMI provided by Amazon with Ubuntu 16.04 | `string` | `""` | no |
2624
| ami\_owner | Owner of the given AMI (ignored if `ami` unset) | `string` | `""` | no |
2725
| applying\_period | The period in seconds over which the specified statistic is applied | `number` | `60` | no |
@@ -69,6 +67,7 @@
6967
| root\_iops | Amount of provisioned IOPS. This must be set if root\_volume\_type is set to `io1` | `number` | `0` | no |
7068
| root\_volume\_size | Size of the root volume in gigabytes | `number` | `10` | no |
7169
| root\_volume\_type | Type of root volume. Can be standard, gp2 or io1 | `string` | `"gp2"` | no |
70+
| security\_group\_rules | A list of maps of Security Group rules. <br>The values of map is fully complated with `aws_security_group_rule` resource. <br>To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule . | `list(any)` | <pre>[<br> {<br> "cidr_blocks": [<br> "0.0.0.0/0"<br> ],<br> "from_port": 0,<br> "protocol": "-1",<br> "to_port": 65535,<br> "type": "egress"<br> }<br>]</pre> | no |
7271
| security\_groups | List of Security Group IDs allowed to connect to the instance | `list(string)` | `[]` | no |
7372
| source\_dest\_check | Controls if traffic is routed to the instance when the destination address does not match the instance. Used for NAT or VPNs | `bool` | `true` | no |
7473
| ssh\_key\_pair | SSH key pair to be provisioned on the instance | `string` | n/a | yes |

eni.tf

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ resource "aws_network_interface" "additional" {
88

99
security_groups = compact(
1010
concat(
11-
[
12-
var.create_default_security_group ? join("", aws_security_group.default.*.id) : ""
13-
],
11+
formatlist("%s", module.default_sg.id),
1412
var.security_groups
1513
)
1614
)

examples/complete/fixtures.us-east-2.tfvars

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,42 @@ associate_public_ip_address = true
1616

1717
instance_type = "t3.micro"
1818

19-
allowed_ports = [22, 80, 443]
19+
security_group_rules = [
20+
{
21+
type = "egress"
22+
from_port = 0
23+
to_port = 65535
24+
protocol = "-1"
25+
cidr_blocks = ["0.0.0.0/0"]
26+
},
27+
{
28+
type = "ingress"
29+
from_port = 22
30+
to_port = 22
31+
protocol = "tcp"
32+
cidr_blocks = ["0.0.0.0/0"]
33+
},
34+
{
35+
type = "ingress"
36+
from_port = 80
37+
to_port = 80
38+
protocol = "tcp"
39+
cidr_blocks = ["0.0.0.0/0"]
40+
},
41+
{
42+
type = "ingress"
43+
from_port = 443
44+
to_port = 443
45+
protocol = "tcp"
46+
cidr_blocks = ["0.0.0.0/0"]
47+
},
48+
{
49+
type = "ingress"
50+
from_port = 53
51+
to_port = 53
52+
protocol = "udp"
53+
cidr_blocks = ["0.0.0.0/0"]
54+
},
55+
]
2056

2157
ssh_public_key_path = "/secrets"

examples/complete/main.tf

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@ module "ec2_instance" {
8282
assign_eip_address = var.assign_eip_address
8383
associate_public_ip_address = var.associate_public_ip_address
8484
instance_type = var.instance_type
85-
allowed_ports = var.allowed_ports
86-
allowed_ports_udp = var.allowed_ports_udp
85+
security_group_rules = var.security_group_rules
8786
instance_profile = aws_iam_instance_profile.test.name
8887

8988
context = module.this.context

examples/complete/variables.tf

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,16 @@ variable "instance_type" {
2323
description = "The type of the instance"
2424
}
2525

26-
variable "allowed_ports" {
27-
type = list(number)
28-
description = "List of allowed ingress TCP ports"
29-
default = []
30-
}
31-
32-
variable "allowed_ports_udp" {
33-
type = list(number)
34-
description = "List of allowed ingress UDP ports"
35-
default = []
36-
}
37-
3826
variable "ssh_public_key_path" {
3927
type = string
4028
description = "Path to SSH public key directory (e.g. `/secrets`)"
4129
}
30+
31+
variable "security_group_rules" {
32+
type = list(any)
33+
description = <<-EOT
34+
A list of maps of Security Group rules.
35+
The values of map is fully complated with `aws_security_group_rule` resource.
36+
To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule .
37+
EOT
38+
}

main.tf

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ locals {
33
# create an instance profile if the instance is enabled and we aren't given one to use
44
instance_profile_count = module.this.enabled ? (length(var.instance_profile) > 0 ? 0 : 1) : 0
55
instance_profile = local.instance_profile_count == 0 ? var.instance_profile : join("", aws_iam_instance_profile.default.*.name)
6-
security_group_count = var.create_default_security_group ? 1 : 0
6+
security_group_enabled = module.this.enabled && var.create_default_security_group ? true : false
77
region = var.region != "" ? var.region : data.aws_region.default.name
88
root_iops = var.root_volume_type == "io1" ? var.root_iops : "0"
99
ebs_iops = var.ebs_volume_type == "io1" ? var.ebs_iops : "0"
@@ -121,9 +121,7 @@ resource "aws_instance" "default" {
121121

122122
vpc_security_group_ids = compact(
123123
concat(
124-
[
125-
var.create_default_security_group ? join("", aws_security_group.default.*.id) : "",
126-
],
124+
formatlist("%s", module.default_sg.id),
127125
var.security_groups
128126
)
129127
)

outputs.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ output "security_group_ids" {
4242
description = "IDs on the AWS Security Groups associated with the instance"
4343
value = compact(
4444
concat(
45-
[var.create_default_security_group == true ? join("", aws_security_group.default.*.id) : ""],
45+
formatlist("%s", module.default_sg.id),
4646
var.security_groups
4747
)
4848
)

security_group.tf

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,9 @@
1-
resource "aws_security_group" "default" {
2-
count = local.security_group_count
3-
name = module.this.id
4-
vpc_id = var.vpc_id
5-
description = "Instance default security group (only egress access is allowed)"
6-
tags = module.this.tags
7-
8-
lifecycle {
9-
create_before_destroy = true
10-
}
11-
}
12-
13-
resource "aws_security_group_rule" "egress" {
14-
count = var.create_default_security_group ? 1 : 0
15-
type = "egress"
16-
from_port = 0
17-
to_port = 65535
18-
protocol = "-1"
19-
cidr_blocks = ["0.0.0.0/0"]
20-
security_group_id = join("", aws_security_group.default.*.id)
21-
}
22-
23-
resource "aws_security_group_rule" "ingress_tcp" {
24-
count = var.create_default_security_group ? length(compact(var.allowed_ports)) : 0
25-
type = "ingress"
26-
from_port = var.allowed_ports[count.index]
27-
to_port = var.allowed_ports[count.index]
28-
protocol = "tcp"
29-
cidr_blocks = ["0.0.0.0/0"]
30-
security_group_id = join("", aws_security_group.default.*.id)
31-
}
32-
33-
resource "aws_security_group_rule" "ingress_udp" {
34-
count = var.create_default_security_group ? length(compact(var.allowed_ports_udp)) : 0
35-
type = "ingress"
36-
from_port = var.allowed_ports_udp[count.index]
37-
to_port = var.allowed_ports_udp[count.index]
38-
protocol = "udp"
39-
cidr_blocks = ["0.0.0.0/0"]
40-
security_group_id = join("", aws_security_group.default.*.id)
1+
module "default_sg" {
2+
source = "cloudposse/security-group/aws"
3+
version = "0.1.0"
4+
rules = var.security_group_rules
5+
vpc_id = var.vpc_id
6+
7+
enabled = local.security_group_enabled
8+
context = module.this.context
419
}

variables.tf

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,22 @@ variable "security_groups" {
4444
default = []
4545
}
4646

47-
variable "allowed_ports" {
48-
type = list(number)
49-
description = "List of allowed ingress TCP ports"
50-
default = []
51-
}
52-
53-
variable "allowed_ports_udp" {
54-
type = list(number)
55-
description = "List of allowed ingress UDP ports"
56-
default = []
47+
variable "security_group_rules" {
48+
type = list(any)
49+
default = [
50+
{
51+
type = "egress"
52+
from_port = 0
53+
to_port = 65535
54+
protocol = "-1"
55+
cidr_blocks = ["0.0.0.0/0"]
56+
}
57+
]
58+
description = <<-EOT
59+
A list of maps of Security Group rules.
60+
The values of map is fully complated with `aws_security_group_rule` resource.
61+
To get more info see https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/security_group_rule .
62+
EOT
5763
}
5864

5965
variable "subnet" {
@@ -287,4 +293,4 @@ variable "kms_key_id" {
287293
type = string
288294
default = null
289295
description = "KMS key ID used to encrypt EBS volume. When specifying kms_key_id, ebs_volume_encrypted needs to be set to true"
290-
}
296+
}

0 commit comments

Comments
 (0)