Skip to content

Commit b875984

Browse files
author
Sumit Sarkar
committed
FEAT: Enable multi instance ECS cluster
1 parent 24d4a35 commit b875984

File tree

5 files changed

+135
-85
lines changed

5 files changed

+135
-85
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.idea
2+
*.tfstate
3+
*.tfstate*
4+
.terraform
5+
*.tfvars

README.md

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# terraform-aws-ecs-cluster
22

3-
A Terraform module to create an Amazon Web Services (AWS) EC2 Container Service (ECS) cluster.
3+
A Terraform module to create an Amazon Web Services (AWS) EC2 Container Service (ECS) cluster. This module is an offshoot from [this module](azavea/terraform-aws-ecs-cluster) where extra feature of enabling multiple types of instances in a cluster is enabled. This will allow the task to have more granular placement constraints.
4+
5+
####NOTE
6+
7+
Please make sure you have the exact same size lists as that of the `instance_types`. If it's smaller that the `instance_types` list, you'll face errors.
48

59
## Usage
610

@@ -18,17 +22,17 @@ module "container_service_cluster" {
1822
1923
vpc_id = "vpc-20f74844"
2024
ami_id = "ami-b2df2ca4"
21-
instance_type = "t2.micro"
25+
instance_type = ["t2.micro", "m4.large"]
2226
key_name = "hector"
2327
cloud_config_content = "${data.template_file.container_instance_cloud_config.rendered}"
2428
25-
root_block_device_type = "gp2"
26-
root_block_device_size = "10"
29+
root_block_device_type = ["gp2", "standard"]
30+
root_block_device_size = ["10", "50"]
2731
2832
health_check_grace_period = "600"
29-
desired_capacity = "1"
30-
min_size = "0"
31-
max_size = "1"
33+
desired_capacity = ["1", "2"]
34+
min_size = ["0", "0"]
35+
max_size = ["3", "4"]
3236
3337
enabled_metrics = [
3438
"GroupMinSize",
@@ -56,7 +60,7 @@ module "container_service_cluster" {
5660
- `ami_owners` - List of accounts that own the AMI (default: `self, amazon, aws-marketplace`)
5761
- `root_block_device_type` - Instance root block device type (default: `gp2`)
5862
- `root_block_device_size` - Instance root block device size in gigabytes (default: `8`)
59-
- `instance_type` - Instance type for cluster instances (default: `t2.micro`)
63+
- `instance_types` - Instance types for cluster instances (default: `[t2.micro]`)
6064
- `key_name` - EC2 Key pair name
6165
- `cloud_config_content` - user data supplied to launch configuration for cluster nodes
6266
- `cloud_config_content_type` - the type of configuration being passed in as user data, see [EC2 user guide](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AmazonLinuxAMIBasics.html#CloudInit) for a list of possible types (default: `text/cloud-config`)
@@ -66,20 +70,20 @@ module "container_service_cluster" {
6670
- `max_size` - Maximum number of EC2 instances in cluster (default: `1`)
6771
- `enabled_metrics` - A list of metrics to gather for the cluster
6872
- `private_subnet_ids` - A list of private subnet IDs to launch cluster instances
69-
- `scale_up_cooldown_seconds` - Number of seconds before allowing another scale up activity (default: `300`)
70-
- `scale_down_cooldown_seconds` - Number of seconds before allowing another scale down activity (default: `300`)
71-
- `high_cpu_evaluation_periods` - Number of evaluation periods for high CPU alarm (default: `2`)
72-
- `high_cpu_period_seconds` - Number of seconds in an evaluation period for high CPU alarm (default: `300`)
73-
- `high_cpu_threshold_percent` - Threshold as a percentage for high CPU alarm (default: `90`)
74-
- `low_cpu_evaluation_periods` - Number of evaluation periods for low CPU alarm (default: `2`)
75-
- `low_cpu_period_seconds` - Number of seconds in an evaluation period for low CPU alarm (default: `300`)
76-
- `low_cpu_threshold_percent` - Threshold as a percentage for low CPU alarm (default: `10`)
77-
- `high_memory_evaluation_periods` - Number of evaluation periods for high memory alarm (default: `2`)
78-
- `high_memory_period_seconds` - Number of seconds in an evaluation period for high memory alarm (default: `300`)
79-
- `high_memory_threshold_percent` - Threshold as a percentage for high memory alarm (default: `90`)
80-
- `low_memory_evaluation_periods` - Number of evaluation periods for low memory alarm (default: `2`)
81-
- `low_memory_period_seconds` - Number of seconds in an evaluation period for low memory alarm (default: `300`)
82-
- `low_memory_threshold_percent` - Threshold as a percentage for low memory alarm (default: `10`)
73+
- `scale_up_cooldown_seconds` - List for Number of seconds before allowing another scale up activity (default: `[300]`)
74+
- `scale_down_cooldown_seconds` - List for Number of seconds before allowing another scale down activity (default: `[300]`)
75+
- `high_cpu_evaluation_periods` - List for Number of evaluation periods for high CPU alarm (default: `[2]`)
76+
- `high_cpu_period_seconds` - List for Number of seconds in an evaluation period for high CPU alarm (default: `[300]`)
77+
- `high_cpu_threshold_percent` - Threshold as a percentage for high CPU alarm (default: `[90]`)
78+
- `low_cpu_evaluation_periods` - List for Number of evaluation periods for low CPU alarm (default: `[2]`)
79+
- `low_cpu_period_seconds` - List for Number of seconds in an evaluation period for low CPU alarm (default: `[300]`)
80+
- `low_cpu_threshold_percent` - List for Threshold as a percentage for low CPU alarm (default: `[10]`)
81+
- `high_memory_evaluation_periods` - List for Number of evaluation periods for high memory alarm (default: `[2]`)
82+
- `high_memory_period_seconds` -List for Number of seconds in an evaluation period for high memory alarm (default: `[300]`)
83+
- `high_memory_threshold_percent` - List for Threshold as a percentage for high memory alarm (default: `[90]`)
84+
- `low_memory_evaluation_periods` - List for Number of evaluation periods for low memory alarm (default: `[2]`)
85+
- `low_memory_period_seconds` - List for Number of seconds in an evaluation period for low memory alarm (default: `[300]`)
86+
- `low_memory_threshold_percent` - List for Threshold as a percentage for low memory alarm (default: `[10]`)
8387
- `project` - Name of project this cluster is for (default: `Unknown`)
8488
- `environment` - Name of environment this cluster is targeting (default: `Unknown`)
8589

main.tf

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
provider "aws" {
2+
region = "${var.region}"
3+
}
4+
15
#
26
# Container Instance IAM resources
37
#
@@ -144,13 +148,15 @@ data "aws_ami" "user_ami" {
144148
}
145149

146150
resource "aws_launch_configuration" "container_instance" {
151+
count = "${length(var.instance_types)}"
152+
147153
lifecycle {
148154
create_before_destroy = true
149155
}
150156

151157
root_block_device {
152-
volume_type = "${var.root_block_device_type}"
153-
volume_size = "${var.root_block_device_size}"
158+
volume_type = "${element(var.root_block_device_type, count.index)}"
159+
volume_size = "${element(var.root_block_device_size, count.index)}"
154160
}
155161

156162
name_prefix = "lc${title(var.environment)}ContainerInstance-"
@@ -160,25 +166,26 @@ resource "aws_launch_configuration" "container_instance" {
160166
# https://github.com/hashicorp/terraform/issues/2831#issuecomment-298751019
161167
image_id = "${var.lookup_latest_ami ? join("", data.aws_ami.ecs_ami.*.image_id) : join("", data.aws_ami.user_ami.*.image_id)}"
162168

163-
instance_type = "${var.instance_type}"
169+
instance_type = "${element(var.instance_types, count.index)}"
164170
key_name = "${var.key_name}"
165171
security_groups = ["${aws_security_group.container_instance.id}"]
166172
user_data = "${data.template_cloudinit_config.container_instance_cloud_config.rendered}"
167173
}
168174

169175
resource "aws_autoscaling_group" "container_instance" {
176+
count = "${length(var.instance_types)}"
170177
lifecycle {
171178
create_before_destroy = true
172179
}
173180

174-
name = "asg${title(var.environment)}ContainerInstance"
175-
launch_configuration = "${aws_launch_configuration.container_instance.name}"
181+
name = "asg${title(var.environment)}ContainerInstance${count.index}"
182+
launch_configuration = "${element(aws_launch_configuration.container_instance.*.name, count.index)}"
176183
health_check_grace_period = "${var.health_check_grace_period}"
177184
health_check_type = "EC2"
178-
desired_capacity = "${var.desired_capacity}"
185+
desired_capacity = "${element(var.desired_capacity, count.index)}"
179186
termination_policies = ["OldestLaunchConfiguration", "Default"]
180-
min_size = "${var.min_size}"
181-
max_size = "${var.max_size}"
187+
min_size = "${element(var.min_size, count.index)}"
188+
max_size = "${element(var.max_size, count.index)}"
182189
enabled_metrics = ["${var.enabled_metrics}"]
183190
vpc_zone_identifier = ["${var.private_subnet_ids}"]
184191

@@ -212,95 +219,103 @@ resource "aws_ecs_cluster" "container_instance" {
212219
# CloudWatch resources
213220
#
214221
resource "aws_autoscaling_policy" "container_instance_scale_up" {
215-
name = "asgScalingPolicy${title(var.environment)}ClusterScaleUp"
222+
count = "${length(var.instance_types)}"
223+
224+
name = "asgScalingPolicy${title(var.environment)}ClusterScaleUp${count.index}"
216225
scaling_adjustment = 1
217226
adjustment_type = "ChangeInCapacity"
218-
cooldown = "${var.scale_up_cooldown_seconds}"
219-
autoscaling_group_name = "${aws_autoscaling_group.container_instance.name}"
227+
cooldown = "${element(var.scale_up_cooldown_seconds, count.index)}"
228+
autoscaling_group_name = "${element(aws_autoscaling_group.container_instance.*.name, count.index)}"
220229
}
221230

222231
resource "aws_autoscaling_policy" "container_instance_scale_down" {
223-
name = "asgScalingPolicy${title(var.environment)}ClusterScaleDown"
232+
count = "${length(var.instance_types)}"
233+
name = "asgScalingPolicy${title(var.environment)}ClusterScaleDown${count.index}"
224234
scaling_adjustment = -1
225235
adjustment_type = "ChangeInCapacity"
226-
cooldown = "${var.scale_down_cooldown_seconds}"
227-
autoscaling_group_name = "${aws_autoscaling_group.container_instance.name}"
236+
cooldown = "${element(var.scale_down_cooldown_seconds, count.index)}"
237+
autoscaling_group_name = "${element(aws_autoscaling_group.container_instance.*.name, count.index)}"
228238
}
229239

230240
resource "aws_cloudwatch_metric_alarm" "container_instance_high_cpu" {
231-
alarm_name = "alarm${title(var.environment)}ClusterCPUReservationHigh"
241+
count = "${length(var.instance_types)}"
242+
243+
alarm_name = "alarm${title(var.environment)}ClusterCPUReservationHigh${count.index}"
232244
comparison_operator = "GreaterThanOrEqualToThreshold"
233-
evaluation_periods = "${var.high_cpu_evaluation_periods}"
245+
evaluation_periods = "${element(var.high_cpu_evaluation_periods, count.index)}"
234246
metric_name = "CPUReservation"
235247
namespace = "AWS/ECS"
236-
period = "${var.high_cpu_period_seconds}"
248+
period = "${element(var.high_cpu_period_seconds, count.index)}"
237249
statistic = "Maximum"
238-
threshold = "${var.high_cpu_threshold_percent}"
250+
threshold = "${element(var.high_cpu_threshold_percent, count.index)}"
239251

240252
dimensions {
241253
ClusterName = "${aws_ecs_cluster.container_instance.name}"
242254
}
243255

244256
alarm_description = "Scale up if CPUReservation is above N% for N duration"
245-
alarm_actions = ["${aws_autoscaling_policy.container_instance_scale_up.arn}"]
257+
alarm_actions = ["${element(aws_autoscaling_policy.container_instance_scale_up.*.arn, count.index)}"]
246258
}
247259

248260
resource "aws_cloudwatch_metric_alarm" "container_instance_low_cpu" {
249-
alarm_name = "alarm${title(var.environment)}ClusterCPUReservationLow"
261+
count = "${length(var.instance_types)}"
262+
alarm_name = "alarm${title(var.environment)}ClusterCPUReservationLow${count.index}"
250263
comparison_operator = "LessThanOrEqualToThreshold"
251-
evaluation_periods = "${var.low_cpu_evaluation_periods}"
264+
evaluation_periods = "${element(var.low_cpu_evaluation_periods, count.index)}"
252265
metric_name = "CPUReservation"
253266
namespace = "AWS/ECS"
254-
period = "${var.low_cpu_period_seconds}"
267+
period = "${element(var.low_cpu_period_seconds, count.index)}"
255268
statistic = "Maximum"
256-
threshold = "${var.low_cpu_threshold_percent}"
269+
threshold = "${element(var.low_cpu_threshold_percent, count.index)}"
257270

258271
dimensions {
259272
ClusterName = "${aws_ecs_cluster.container_instance.name}"
260273
}
261274

262275
alarm_description = "Scale down if the CPUReservation is below N% for N duration"
263-
alarm_actions = ["${aws_autoscaling_policy.container_instance_scale_down.arn}"]
276+
alarm_actions = ["${element(aws_autoscaling_policy.container_instance_scale_down.*.arn, count.index)}"]
264277

265278
depends_on = ["aws_cloudwatch_metric_alarm.container_instance_high_cpu"]
266279
}
267280

268281
resource "aws_cloudwatch_metric_alarm" "container_instance_high_memory" {
269-
alarm_name = "alarm${title(var.environment)}ClusterMemoryReservationHigh"
282+
count = "${length(var.instance_types)}"
283+
alarm_name = "alarm${title(var.environment)}ClusterMemoryReservationHigh${count.index}"
270284
comparison_operator = "GreaterThanOrEqualToThreshold"
271-
evaluation_periods = "${var.high_memory_evaluation_periods}"
285+
evaluation_periods = "${element(var.high_memory_evaluation_periods, count.index)}"
272286
metric_name = "MemoryReservation"
273287
namespace = "AWS/ECS"
274-
period = "${var.high_memory_period_seconds}"
288+
period = "${element(var.high_memory_period_seconds, count.index)}"
275289
statistic = "Maximum"
276-
threshold = "${var.high_memory_threshold_percent}"
290+
threshold = "${element(var.high_memory_threshold_percent, count.index)}"
277291

278292
dimensions {
279293
ClusterName = "${aws_ecs_cluster.container_instance.name}"
280294
}
281295

282296
alarm_description = "Scale up if the MemoryReservation is above N% for N duration"
283-
alarm_actions = ["${aws_autoscaling_policy.container_instance_scale_up.arn}"]
297+
alarm_actions = ["${element(aws_autoscaling_policy.container_instance_scale_up.*.arn, count.index)}"]
284298

285299
depends_on = ["aws_cloudwatch_metric_alarm.container_instance_low_cpu"]
286300
}
287301

288302
resource "aws_cloudwatch_metric_alarm" "container_instance_low_memory" {
289-
alarm_name = "alarm${title(var.environment)}ClusterMemoryReservationLow"
303+
count = "${length(var.instance_types)}"
304+
alarm_name = "alarm${title(var.environment)}ClusterMemoryReservationLow${count.index}"
290305
comparison_operator = "LessThanOrEqualToThreshold"
291-
evaluation_periods = "${var.low_memory_evaluation_periods}"
306+
evaluation_periods = "${element(var.low_memory_evaluation_periods, count.index)}"
292307
metric_name = "MemoryReservation"
293308
namespace = "AWS/ECS"
294-
period = "${var.low_memory_period_seconds}"
309+
period = "${element(var.low_memory_period_seconds, count.index)}"
295310
statistic = "Maximum"
296-
threshold = "${var.low_memory_threshold_percent}"
311+
threshold = "${element(var.low_memory_threshold_percent, count.index)}"
297312

298313
dimensions {
299314
ClusterName = "${aws_ecs_cluster.container_instance.name}"
300315
}
301316

302317
alarm_description = "Scale down if the MemoryReservation is below N% for N duration"
303-
alarm_actions = ["${aws_autoscaling_policy.container_instance_scale_down.arn}"]
318+
alarm_actions = ["${element(aws_autoscaling_policy.container_instance_scale_down.*.arn, count.index)}"]
304319

305320
depends_on = ["aws_cloudwatch_metric_alarm.container_instance_high_memory"]
306321
}

outputs.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ output "ecs_service_role_name" {
1919
}
2020

2121
output "container_instance_autoscaling_group_name" {
22-
value = "${aws_autoscaling_group.container_instance.name}"
22+
value = "${aws_autoscaling_group.container_instance.*.name}"
2323
}
2424

2525
output "ecs_service_role_arn" {

0 commit comments

Comments
 (0)