Skip to content

Commit f22d250

Browse files
committed
Add support for Fargate. Add option to prevent creation of cluster instances.
1 parent 203718c commit f22d250

13 files changed

+723
-423
lines changed

asg.tf

+7-3
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ data "aws_ami" "amazon_linux_2" {
2222
}
2323

2424
resource "aws_launch_template" "cluster" {
25+
count = var.include_cluster_instances ? 1 : 0
26+
2527
name_prefix = "cluster-${var.component}-${var.deployment_identifier}-${var.cluster_name}-"
2628
image_id = local.ami_id
2729
instance_type = var.cluster_instance_type
2830
key_name = var.cluster_instance_ssh_public_key_path == null ? "" : element(concat(aws_key_pair.cluster.*.key_name, [""]), 0)
2931

3032
iam_instance_profile {
31-
name = aws_iam_instance_profile.cluster.name
33+
name = aws_iam_instance_profile.cluster[0].name
3234
}
3335

3436
metadata_options {
@@ -43,7 +45,7 @@ resource "aws_launch_template" "cluster" {
4345

4446
network_interfaces {
4547
associate_public_ip_address = var.associate_public_ip_addresses
46-
security_groups = concat([aws_security_group.cluster.id], var.security_groups)
48+
security_groups = concat([aws_security_group.cluster[0].id], var.security_groups)
4749
}
4850

4951
block_device_mappings {
@@ -79,12 +81,14 @@ resource "aws_launch_template" "cluster" {
7981
}
8082

8183
resource "aws_autoscaling_group" "cluster" {
84+
count = var.include_cluster_instances ? 1 : 0
85+
8286
name_prefix = "asg-${var.component}-${var.deployment_identifier}-${var.cluster_name}-"
8387

8488
vpc_zone_identifier = var.subnet_ids
8589

8690
launch_template {
87-
id = aws_launch_template.cluster.id
91+
id = aws_launch_template.cluster[0].id
8892
version = "$Latest"
8993
}
9094

capacity_provider.tf

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
resource "aws_ecs_capacity_provider" "autoscaling_group" {
2-
count = var.include_asg_capacity_provider ? 1 : 0
2+
count = (var.include_cluster_instances && var.include_asg_capacity_provider) ? 1 : 0
33

44
name = "cp-${var.component}-${var.deployment_identifier}-${var.cluster_name}"
55

66
auto_scaling_group_provider {
7-
auto_scaling_group_arn = aws_autoscaling_group.cluster.arn
7+
auto_scaling_group_arn = aws_autoscaling_group.cluster[0].arn
88

99
managed_termination_protection = var.asg_capacity_provider_manage_termination_protection ? "ENABLED" : "DISABLED"
1010

@@ -18,9 +18,9 @@ resource "aws_ecs_capacity_provider" "autoscaling_group" {
1818
}
1919

2020
resource "aws_ecs_cluster_capacity_providers" "cluster_capacity_providers" {
21-
count = var.include_asg_capacity_provider ? 1 : 0
21+
count = ((var.include_cluster_instances && var.include_asg_capacity_provider) || length(var.additional_capacity_providers) > 0) ? 1 : 0
2222

2323
cluster_name = aws_ecs_cluster.cluster.name
2424

25-
capacity_providers = var.include_asg_capacity_provider ? [aws_ecs_capacity_provider.autoscaling_group[0].name] : []
25+
capacity_providers = var.include_asg_capacity_provider ? [aws_ecs_capacity_provider.autoscaling_group[0].name] : var.additional_capacity_providers
2626
}

iam.tf

+11-3
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,35 @@ locals {
55
}
66

77
resource "aws_iam_role" "cluster_instance_role" {
8+
count = var.include_cluster_instances ? 1 : 0
9+
810
description = "cluster-instance-role-${var.component}-${var.deployment_identifier}-${var.cluster_name}"
911
assume_role_policy = file("${path.module}/policies/cluster-instance-role.json")
1012

1113
tags = local.tags
1214
}
1315

1416
resource "aws_iam_policy" "cluster_instance_policy" {
17+
count = var.include_cluster_instances ? 1 : 0
18+
1519
description = "cluster-instance-policy-${var.component}-${var.deployment_identifier}-${var.cluster_name}"
1620
policy = local.cluster_instance_policy_contents
1721
}
1822

1923
resource "aws_iam_policy_attachment" "cluster_instance_policy_attachment" {
24+
count = var.include_cluster_instances ? 1 : 0
25+
2026
name = "cluster-instance-policy-attachment-${var.component}-${var.deployment_identifier}-${var.cluster_name}"
21-
roles = [aws_iam_role.cluster_instance_role.id]
22-
policy_arn = aws_iam_policy.cluster_instance_policy.arn
27+
roles = [aws_iam_role.cluster_instance_role[0].id]
28+
policy_arn = aws_iam_policy.cluster_instance_policy[0].arn
2329
}
2430

2531
resource "aws_iam_instance_profile" "cluster" {
32+
count = var.include_cluster_instances ? 1 : 0
33+
2634
name = "cluster-instance-profile-${var.component}-${var.deployment_identifier}-${var.cluster_name}"
2735
path = "/"
28-
role = aws_iam_role.cluster_instance_role.name
36+
role = aws_iam_role.cluster_instance_role[0].name
2937
}
3038

3139
resource "aws_iam_role" "cluster_service_role" {

outputs.tf

+10-10
Original file line numberDiff line numberDiff line change
@@ -15,47 +15,47 @@ output "cluster_arn" {
1515

1616
output "autoscaling_group_name" {
1717
description = "The name of the autoscaling group for the ECS container instances."
18-
value = aws_autoscaling_group.cluster.name
18+
value = try(aws_autoscaling_group.cluster[0].arn, "")
1919
}
2020

2121
output "autoscaling_group_arn" {
2222
description = "The ARN of the autoscaling group for the ECS container instances."
23-
value = aws_autoscaling_group.cluster.arn
23+
value = try(aws_autoscaling_group.cluster[0].arn, "")
2424
}
2525

2626
output "launch_template_name" {
2727
description = "The name of the launch template for the ECS container instances."
28-
value = aws_launch_template.cluster.name
28+
value = try(aws_launch_template.cluster[0].name, "")
2929
}
3030

3131
output "launch_template_id" {
3232
description = "The id of the launch template for the ECS container instances."
33-
value = aws_launch_template.cluster.id
33+
value = try(aws_launch_template.cluster[0].id, "")
3434
}
3535

3636
output "security_group_id" {
3737
description = "The ID of the default security group associated with the ECS container instances."
38-
value = aws_security_group.cluster.id
38+
value = try(aws_security_group.cluster[0].id, "")
3939
}
4040

4141
output "instance_role_arn" {
4242
description = "The ARN of the container instance role."
43-
value = aws_iam_role.cluster_instance_role.arn
43+
value = try(aws_iam_role.cluster_instance_role[0].arn, "")
4444
}
4545

4646
output "instance_role_id" {
4747
description = "The ID of the container instance role."
48-
value = aws_iam_role.cluster_instance_role.unique_id
48+
value = try(aws_iam_role.cluster_instance_role[0].unique_id, "")
4949
}
5050

5151
output "instance_policy_arn" {
5252
description = "The ARN of the container instance policy."
53-
value = aws_iam_policy.cluster_instance_policy.arn
53+
value = try(aws_iam_policy.cluster_instance_policy[0].arn, "")
5454
}
5555

5656
output "instance_policy_id" {
5757
description = "The ID of the container instance policy."
58-
value = aws_iam_policy.cluster_instance_policy.id
58+
value = try(aws_iam_policy.cluster_instance_policy[0].id, "")
5959
}
6060

6161
output "service_role_arn" {
@@ -85,5 +85,5 @@ output "log_group" {
8585

8686
output "asg_capacity_provider_name" {
8787
description = "The name of the ASG capacity provider associated with the cluster."
88-
value = var.include_asg_capacity_provider ? aws_ecs_capacity_provider.autoscaling_group[0].name : ""
88+
value = try(aws_ecs_capacity_provider.autoscaling_group[0].name, "")
8989
}

security_groups.tf

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
resource "aws_security_group" "cluster" {
2+
count = var.include_cluster_instances ? 1 : 0
3+
24
name = "${var.component}-${var.deployment_identifier}-${var.cluster_name}"
35
description = "Container access for component: ${var.component}, deployment: ${var.deployment_identifier}, cluster: ${var.cluster_name}"
46
vpc_id = var.vpc_id
@@ -10,11 +12,11 @@ resource "aws_security_group" "cluster" {
1012
}
1113

1214
resource "aws_security_group_rule" "cluster_default_ingress" {
13-
count = var.include_default_ingress_rule ? 1 : 0
15+
count = (var.include_cluster_instances && var.include_default_ingress_rule) ? 1 : 0
1416

1517
type = "ingress"
1618

17-
security_group_id = aws_security_group.cluster.id
19+
security_group_id = aws_security_group.cluster[0].id
1820

1921
protocol = "-1"
2022
from_port = 0
@@ -24,11 +26,11 @@ resource "aws_security_group_rule" "cluster_default_ingress" {
2426
}
2527

2628
resource "aws_security_group_rule" "cluster_default_egress" {
27-
count = var.include_default_egress_rule ? 1 : 0
29+
count = (var.include_cluster_instances && var.include_default_egress_rule) ? 1 : 0
2830

2931
type = "egress"
3032

31-
security_group_id = aws_security_group.cluster.id
33+
security_group_id = aws_security_group.cluster[0].id
3234

3335
protocol = "-1"
3436
from_port = 0

spec/unit/autoscaling_group_spec.rb

+29-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
@plan = plan(role: :root)
2222
end
2323

24-
it 'creates a autoscaling group' do
24+
it 'creates an autoscaling group' do
2525
expect(@plan)
2626
.to(include_resource_creation(type: 'aws_autoscaling_group')
2727
.once)
@@ -166,4 +166,32 @@
166166
.with_attribute_value(:protect_from_scale_in, false))
167167
end
168168
end
169+
170+
context 'when include_cluster_instances is false' do
171+
before(:context) do
172+
@plan = plan(role: :root) do |vars|
173+
vars.include_cluster_instances = false
174+
end
175+
end
176+
177+
it 'does not create an autoscaling group' do
178+
expect(@plan)
179+
.not_to(include_resource_creation(type: 'aws_autoscaling_group'))
180+
end
181+
end
182+
183+
184+
context 'when include_cluster_instances is true' do
185+
before(:context) do
186+
@plan = plan(role: :root) do |vars|
187+
vars.include_cluster_instances = true
188+
end
189+
end
190+
191+
it 'creates an autoscaling group' do
192+
expect(@plan)
193+
.to(include_resource_creation(type: 'aws_autoscaling_group')
194+
.once)
195+
end
196+
end
169197
end

spec/unit/capacity_provider_spec.rb

+96-2
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
@plan = plan(role: :root)
1515
end
1616

17-
context 'when capacity provider included' do
17+
context 'when include_asg_capacity_provider is true and include_cluster_instances is true' do
1818
describe 'by default' do
1919
before(:context) do
2020
@plan = plan(role: :root) do |vars|
2121
vars.include_asg_capacity_provider = true
22+
vars.include_cluster_instances = true
2223
end
2324
end
2425

@@ -53,6 +54,7 @@
5354
context 'with managed termination protection' do
5455
before(:context) do
5556
@plan = plan(role: :root) do |vars|
57+
vars.include_cluster_instances = true
5658
vars.include_asg_capacity_provider = true
5759
vars.asg_capacity_provider_manage_termination_protection = true
5860
end
@@ -75,6 +77,7 @@
7577
context 'without managed termination protection' do
7678
before(:context) do
7779
@plan = plan(role: :root) do |vars|
80+
vars.include_cluster_instances = true
7881
vars.include_asg_capacity_provider = true
7982
vars.asg_capacity_provider_manage_termination_protection = false
8083
end
@@ -97,6 +100,7 @@
97100
context 'with managed scaling' do
98101
before(:context) do
99102
@plan = plan(role: :root) do |vars|
103+
vars.include_cluster_instances = true
100104
vars.include_asg_capacity_provider = true
101105
vars.asg_capacity_provider_manage_scaling = true
102106
vars.asg_capacity_provider_minimum_scaling_step_size = 3
@@ -169,6 +173,7 @@
169173
context 'without managed scaling' do
170174
before(:context) do
171175
@plan = plan(role: :root) do |vars|
176+
vars.include_cluster_instances = true
172177
vars.include_asg_capacity_provider = true
173178
vars.asg_capacity_provider_manage_scaling = false
174179
end
@@ -191,9 +196,10 @@
191196
end
192197
end
193198

194-
context 'when capacity provider not included' do
199+
context 'when include_asg_capacity_provider is false and include_cluster_instances is true' do
195200
before(:context) do
196201
@plan = plan(role: :root) do |vars|
202+
vars.include_cluster_instances = true
197203
vars.include_asg_capacity_provider = false
198204
end
199205
end
@@ -216,4 +222,92 @@
216222
))
217223
end
218224
end
225+
226+
context 'when include_asg_capacity_provider is true and include_cluster_instances is false' do
227+
before(:context) do
228+
@plan = plan(role: :root) do |vars|
229+
vars.include_cluster_instances = false
230+
vars.include_asg_capacity_provider = true
231+
end
232+
end
233+
234+
it 'does not create a capacity provider for the ECS cluster' do
235+
expect(@plan)
236+
.not_to(include_resource_creation(type: 'aws_ecs_capacity_provider'))
237+
end
238+
239+
it 'does not include the AmazonECSManaged tag on the ASG' do
240+
expect(@plan)
241+
.not_to(include_resource_creation(type: 'aws_autoscaling_group')
242+
.with_attribute_value(
243+
:tag,
244+
including({
245+
key: 'AmazonECSManaged',
246+
propagate_at_launch: true,
247+
value: ''
248+
})
249+
))
250+
end
251+
end
252+
253+
context 'when include_asg_capacity_provider is false and include_cluster_instances is false' do
254+
before(:context) do
255+
@plan = plan(role: :root) do |vars|
256+
vars.include_cluster_instances = false
257+
vars.include_asg_capacity_provider = false
258+
end
259+
end
260+
261+
it 'does not create a capacity provider for the ECS cluster' do
262+
expect(@plan)
263+
.not_to(include_resource_creation(type: 'aws_ecs_capacity_provider'))
264+
end
265+
266+
it 'does not include the AmazonECSManaged tag on the ASG' do
267+
expect(@plan)
268+
.not_to(include_resource_creation(type: 'aws_autoscaling_group')
269+
.with_attribute_value(
270+
:tag,
271+
including({
272+
key: 'AmazonECSManaged',
273+
propagate_at_launch: true,
274+
value: ''
275+
})
276+
))
277+
end
278+
end
279+
280+
context 'when additional_capacity_providers are provided' do
281+
before(:context) do
282+
@plan = plan(role: :root) do |vars|
283+
vars.cluster_name = 'special-cluster'
284+
vars.include_cluster_instances = false
285+
vars.include_asg_capacity_provider = false
286+
vars.additional_capacity_providers = ["FARGATE"]
287+
end
288+
end
289+
290+
it 'creates a cluster capacity providers resource' do
291+
expect(@plan)
292+
.to(include_resource_creation(type: 'aws_ecs_cluster_capacity_providers')
293+
.once)
294+
end
295+
296+
it 'uses the correct cluster name on the cluster capacity providers resource' do
297+
expect(@plan)
298+
.to(include_resource_creation(type: 'aws_ecs_cluster_capacity_providers')
299+
.with_attribute_value(
300+
:cluster_name,
301+
"#{component}-#{dep_id}-special-cluster"
302+
))
303+
end
304+
305+
it 'adds the additional capacity providers to the cluster capacity providers' do
306+
expect(@plan)
307+
.to(include_resource_creation(type: 'aws_ecs_cluster_capacity_providers')
308+
.with_attribute_value(
309+
:capacity_providers, ["FARGATE"]
310+
))
311+
end
312+
end
219313
end

0 commit comments

Comments
 (0)