Skip to content

Commit 0537057

Browse files
authored
feat: use security-group module instead of resource (#31)
1 parent da4a979 commit 0537057

15 files changed

+522
-297
lines changed

README.md

+153-92
Large diffs are not rendered by default.

README.yaml

+33-2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ usage: |-
7979
source = "cloudposse/ec2-instance-group/aws"
8080
# Cloud Posse recommends pinning every module to a specific version
8181
# version = "x.x.x"
82+
8283
namespace = "eg"
8384
stage = "prod"
8485
name = "app"
@@ -91,8 +92,38 @@ usage: |-
9192
associate_public_ip_address = true
9293
additional_ips_count = 1
9394
ebs_volume_count = 2
94-
allowed_ports = [22, 80, 443]
9595
instance_count = 3
96+
97+
security_group_rules = [
98+
{
99+
type = "egress"
100+
from_port = 0
101+
to_port = 65535
102+
protocol = "-1"
103+
cidr_blocks = ["0.0.0.0/0"]
104+
},
105+
{
106+
type = "ingress"
107+
from_port = 22
108+
to_port = 22
109+
protocol = "tcp"
110+
cidr_blocks = ["0.0.0.0/0"]
111+
},
112+
{
113+
type = "ingress"
114+
from_port = 80
115+
to_port = 80
116+
protocol = "tcp"
117+
cidr_blocks = ["0.0.0.0/0"]
118+
},
119+
{
120+
type = "ingress"
121+
from_port = 443
122+
to_port = 443
123+
protocol = "tcp"
124+
cidr_blocks = ["0.0.0.0/0"]
125+
}
126+
]
96127
}
97128
```
98129
@@ -127,7 +158,7 @@ contributors:
127158
github: "osterman"
128159
- name: "Jamie Nelson"
129160
github: "Jamie-BitFlight"
130-
- name: "Vladimir"
161+
- name: "Vladimir Syromyatnikov"
131162
github: "SweetOps"
132163
- name: "Andriy Knysh"
133164
github: "aknysh"

docs/terraform.md

+118-86
Large diffs are not rendered by default.

eni.tf

+4-12
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
locals {
2-
additional_ips_count = var.associate_public_ip_address && var.instance_enabled && var.additional_ips_count > 0 ? var.additional_ips_count : 0
2+
additional_ips_count = var.associate_public_ip_address && module.this.enabled && var.additional_ips_count > 0 ? var.additional_ips_count : 0
33
}
44

55
resource "aws_network_interface" "additional" {
6-
count = local.additional_ips_count * var.instance_count
7-
subnet_id = var.subnet
8-
9-
security_groups = compact(
10-
concat(
11-
[
12-
var.create_default_security_group ? join("", aws_security_group.default.*.id) : ""
13-
],
14-
var.security_groups
15-
)
16-
)
6+
count = local.additional_ips_count * var.instance_count
7+
subnet_id = var.subnet
8+
security_groups = compact(concat(module.security_group.*.id, var.security_groups))
179

1810
tags = module.label.tags
1911
depends_on = [aws_instance.default]

examples/complete/fixtures.us-west-1.tfvars

-4
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ instance_type = "t2.micro"
1212

1313
instance_count = 2
1414

15-
allowed_ports = [22, 80, 443]
16-
1715
ssh_public_key_path = "/secrets"
1816

1917
generate_ssh_key_pair = true
@@ -29,5 +27,3 @@ root_volume_type = "gp2"
2927
root_volume_size = 10
3028

3129
delete_on_termination = true
32-
33-
create_default_security_group = true

examples/complete/main.tf

+46-17
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,52 @@ data "aws_ami" "ubuntu" {
4040
}
4141

4242
module "ec2_instance_group" {
43-
source = "../../"
44-
region = var.region
45-
ami = data.aws_ami.ubuntu.id
46-
ami_owner = var.ami_owner
47-
vpc_id = module.vpc.vpc_id
48-
subnet = module.subnets.private_subnet_ids[0]
49-
security_groups = [module.vpc.vpc_default_security_group_id]
50-
assign_eip_address = var.assign_eip_address
51-
associate_public_ip_address = var.associate_public_ip_address
52-
instance_type = var.instance_type
53-
instance_count = var.instance_count
54-
allowed_ports = var.allowed_ports
55-
create_default_security_group = var.create_default_security_group
56-
generate_ssh_key_pair = var.generate_ssh_key_pair
57-
root_volume_type = var.root_volume_type
58-
root_volume_size = var.root_volume_size
59-
delete_on_termination = var.delete_on_termination
43+
source = "../../"
44+
region = var.region
45+
ami = data.aws_ami.ubuntu.id
46+
ami_owner = var.ami_owner
47+
vpc_id = module.vpc.vpc_id
48+
subnet = module.subnets.private_subnet_ids[0]
49+
security_groups = [module.vpc.vpc_default_security_group_id]
50+
assign_eip_address = var.assign_eip_address
51+
associate_public_ip_address = var.associate_public_ip_address
52+
instance_type = var.instance_type
53+
instance_count = var.instance_count
54+
generate_ssh_key_pair = var.generate_ssh_key_pair
55+
root_volume_type = var.root_volume_type
56+
root_volume_size = var.root_volume_size
57+
delete_on_termination = var.delete_on_termination
58+
59+
security_group_rules = [
60+
{
61+
type = "egress"
62+
from_port = 0
63+
to_port = 65535
64+
protocol = "-1"
65+
cidr_blocks = ["0.0.0.0/0"]
66+
},
67+
{
68+
type = "ingress"
69+
from_port = 22
70+
to_port = 22
71+
protocol = "tcp"
72+
cidr_blocks = ["0.0.0.0/0"]
73+
},
74+
{
75+
type = "ingress"
76+
from_port = 80
77+
to_port = 80
78+
protocol = "tcp"
79+
cidr_blocks = ["0.0.0.0/0"]
80+
},
81+
{
82+
type = "ingress"
83+
from_port = 443
84+
to_port = 443
85+
protocol = "tcp"
86+
cidr_blocks = ["0.0.0.0/0"]
87+
}
88+
]
6089

6190
context = module.this.context
6291
}

examples/complete/outputs.tf

+15
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,18 @@ output "instance_count" {
9292
value = module.ec2_instance_group.instance_count
9393
description = "Total number of instances created"
9494
}
95+
96+
output "security_group_id" {
97+
value = module.ec2_instance_group.security_group_id
98+
description = "EC2 instances Security Group ID"
99+
}
100+
101+
output "security_group_arn" {
102+
value = module.ec2_instance_group.security_group_arn
103+
description = "EC2 instances Security Group ARN"
104+
}
105+
106+
output "security_group_name" {
107+
value = module.ec2_instance_group.security_group_name
108+
description = "EC2 instances Security Group name"
109+
}

examples/complete/variables.tf

-10
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,6 @@ variable "instance_type" {
2828
description = "Type of the instance"
2929
}
3030

31-
variable "allowed_ports" {
32-
type = list(number)
33-
description = "List of allowed ingress ports"
34-
}
35-
3631
variable "ami_owner" {
3732
type = string
3833
description = "Owner of the given AMI"
@@ -53,11 +48,6 @@ variable "delete_on_termination" {
5348
description = "Whether the volume should be destroyed on instance termination"
5449
}
5550

56-
variable "create_default_security_group" {
57-
type = bool
58-
description = "Create default Security Group with only Egress traffic allowed"
59-
}
60-
6151
variable "instance_count" {
6252
type = number
6353
description = "Count of ec2 instances to create"

main.tf

+10-18
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
locals {
2-
instance_count = var.instance_enabled ? var.instance_count : 0
3-
security_group_count = var.create_default_security_group ? 1 : 0
4-
region = var.region != "" ? var.region : data.aws_region.default.name
5-
root_iops = var.root_volume_type == "io1" ? var.root_iops : 0
6-
ebs_iops = var.ebs_volume_type == "io1" ? var.ebs_iops : 0
7-
availability_zone = var.availability_zone
8-
root_volume_type = var.root_volume_type != "" ? var.root_volume_type : data.aws_ami.info.root_device_type
9-
count_default_ips = var.associate_public_ip_address && var.assign_eip_address && var.instance_enabled ? var.instance_count : 0
10-
ssh_key_pair_path = var.ssh_key_pair_path == "" ? path.cwd : var.ssh_key_pair_path
2+
instance_count = module.this.enabled ? var.instance_count : 0
3+
region = var.region != "" ? var.region : data.aws_region.default.name
4+
root_iops = var.root_volume_type == "io1" ? var.root_iops : 0
5+
ebs_iops = var.ebs_volume_type == "io1" ? var.ebs_iops : 0
6+
availability_zone = var.availability_zone
7+
root_volume_type = var.root_volume_type != "" ? var.root_volume_type : data.aws_ami.info.root_device_type
8+
count_default_ips = var.associate_public_ip_address && var.assign_eip_address && module.this.enabled ? var.instance_count : 0
9+
ssh_key_pair_path = var.ssh_key_pair_path == "" ? path.cwd : var.ssh_key_pair_path
10+
security_group_enabled = module.this.enabled && var.security_group_enabled
1111
}
1212

1313
locals {
@@ -98,15 +98,7 @@ resource "aws_instance" "default" {
9898
source_dest_check = var.source_dest_check
9999
ipv6_address_count = var.ipv6_address_count < 0 ? null : var.ipv6_address_count
100100
ipv6_addresses = length(var.ipv6_addresses) > 0 ? var.ipv6_addresses : null
101-
102-
vpc_security_group_ids = compact(
103-
concat(
104-
[
105-
var.create_default_security_group ? join("", aws_security_group.default.*.id) : ""
106-
],
107-
var.security_groups
108-
)
109-
)
101+
vpc_security_group_ids = compact(concat(module.security_group.*.id, var.security_groups))
110102

111103
root_block_device {
112104
volume_type = local.root_volume_type

outputs.tf

+16-8
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,22 @@ output "ssh_key_pem_path" {
4545

4646
output "security_group_ids" {
4747
description = "ID on the new AWS Security Group associated with creating instance"
48-
value = compact(
49-
concat(
50-
[
51-
var.create_default_security_group ? join("", aws_security_group.default.*.id) : ""
52-
],
53-
var.security_groups
54-
)
55-
)
48+
value = compact(concat(module.security_group.*.id, var.security_groups))
49+
}
50+
51+
output "security_group_id" {
52+
value = module.security_group.id
53+
description = "EC2 instances Security Group ID"
54+
}
55+
56+
output "security_group_arn" {
57+
value = module.security_group.arn
58+
description = "EC2 instances Security Group ARN"
59+
}
60+
61+
output "security_group_name" {
62+
value = module.security_group.name
63+
description = "EC2 instances Security Group name"
5664
}
5765

5866
output "role_names" {

security_group.tf

+9-28
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,12 @@
1-
resource "aws_security_group" "default" {
2-
count = local.security_group_count
3-
name = module.label.id
4-
vpc_id = var.vpc_id
5-
description = "Instance default security group (only egress access is allowed)"
6-
tags = module.label.tags
1+
module "security_group" {
2+
source = "cloudposse/security-group/aws"
3+
version = "0.3.1"
74

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-
}
5+
use_name_prefix = var.security_group_use_name_prefix
6+
rules = var.security_group_rules
7+
description = var.security_group_description
8+
vpc_id = var.vpc_id
229

23-
resource "aws_security_group_rule" "ingress" {
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)
10+
enabled = local.security_group_enabled
11+
context = module.this.context
3112
}

test/src/examples_complete_test.go

+27
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package test
22

33
import (
4+
"math/rand"
5+
"strconv"
46
"testing"
7+
"time"
58

69
"github.com/gruntwork-io/terratest/modules/terraform"
710
"github.com/stretchr/testify/assert"
@@ -11,12 +14,20 @@ import (
1114
func TestExamplesComplete(t *testing.T) {
1215
t.Parallel()
1316

17+
rand.Seed(time.Now().UnixNano())
18+
19+
randId := strconv.Itoa(rand.Intn(100000))
20+
attributes := []string{randId}
21+
1422
terraformOptions := &terraform.Options{
1523
// The path to where our Terraform code is located
1624
TerraformDir: "../../examples/complete",
1725
Upgrade: true,
1826
// Variables to pass to our Terraform code using -var-file options
1927
VarFiles: []string{"fixtures.us-west-1.tfvars"},
28+
Vars: map[string]interface{}{
29+
"attributes": attributes,
30+
},
2031
}
2132

2233
// At the end of the test, run `terraform destroy` to clean up any resources that were created
@@ -39,4 +50,20 @@ func TestExamplesComplete(t *testing.T) {
3950
publicSubnetCidrs := terraform.OutputList(t, terraformOptions, "public_subnet_cidrs")
4051
// Verify we're getting back the outputs we expect
4152
assert.Equal(t, []string{"172.16.128.0/18", "172.16.192.0/18"}, publicSubnetCidrs)
53+
54+
// Run `terraform output` to get the value of an output variable
55+
securityGroupName := terraform.Output(t, terraformOptions, "security_group_name")
56+
expectedSecurityGroupName := "eg-test-ec2-group-test-" + randId
57+
// Verify we're getting back the outputs we expect
58+
assert.Equal(t, expectedSecurityGroupName, securityGroupName)
59+
60+
// Run `terraform output` to get the value of an output variable
61+
securityGroupID := terraform.Output(t, terraformOptions, "security_group_id")
62+
// Verify we're getting back the outputs we expect
63+
assert.Contains(t, securityGroupID, "sg-", "SG ID should contains substring 'sg-'")
64+
65+
// Run `terraform output` to get the value of an output variable
66+
securityGroupARN := terraform.Output(t, terraformOptions, "security_group_arn")
67+
// Verify we're getting back the outputs we expect
68+
assert.Contains(t, securityGroupARN, "arn:aws:ec2", "SG ID should contains substring 'arn:aws:ec2'")
4269
}

test/src/go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ module github.com/cloudposse/terraform-aws-ec2-instance-group
33
go 1.14
44

55
require (
6-
github.com/gruntwork-io/terratest v0.31.1
6+
github.com/gruntwork-io/terratest v0.34.7
77
github.com/stretchr/testify v1.5.1
88
)

0 commit comments

Comments
 (0)