From 365d54b1f57bbbbb916772cd1c152f513031dbd2 Mon Sep 17 00:00:00 2001 From: Marek Skrajnowski Date: Fri, 24 Apr 2020 16:00:41 +0200 Subject: [PATCH 1/6] docs(ecs): added a simple locustfile to easily generate some traffic to example's web service --- ecs/example/locust/locustfile.py | 29 +++++++++++++++++++++++++++++ ecs/example/locust/start | 10 ++++++++++ ecs/example/main.tf | 4 ++++ 3 files changed, 43 insertions(+) create mode 100644 ecs/example/locust/locustfile.py create mode 100755 ecs/example/locust/start diff --git a/ecs/example/locust/locustfile.py b/ecs/example/locust/locustfile.py new file mode 100644 index 00000000..6b75cd98 --- /dev/null +++ b/ecs/example/locust/locustfile.py @@ -0,0 +1,29 @@ +import random + +from locust import HttpLocust, TaskSet, task, between + + +class UserBehaviour(TaskSet): + @task(5) + def status_2xx(self): + self.client.get("/status/200") + + @task(2) + def status_3xx(self): + self.client.get("/redirect-to", params=dict( + url="/status/200", + status_code=302, + )) + + @task(2) + def status_4xx(self): + self.client.get("/status/400") + + @task(1) + def status_5xx(self): + self.client.get("/status/500") + + +class WebsiteUser(HttpLocust): + task_set = UserBehaviour + wait_time = between(5, 10) diff --git a/ecs/example/locust/start b/ecs/example/locust/start new file mode 100755 index 00000000..dab7b0a1 --- /dev/null +++ b/ecs/example/locust/start @@ -0,0 +1,10 @@ +#!/bin/sh + +set -eux + +docker run \ + -p 8089:8089 \ + --volume "$PWD/locust/locustfile.py:/mnt/locust/locustfile.py" \ + -e LOCUSTFILE_PATH=/mnt/locust/locustfile.py \ + -e TARGET_URL="$(terraform output lb_url)" \ + locustio/locust diff --git a/ecs/example/main.tf b/ecs/example/main.tf index c0022183..9b90d329 100644 --- a/ecs/example/main.tf +++ b/ecs/example/main.tf @@ -99,3 +99,7 @@ module "web" { output "hosts_id" { value = module.hosts.id } + +output "lb_url" { + value = "http://${module.cluster.load_balancer_domain}" +} From 91d32c14a565a9260eac5237ff78a8f0c98e0c64 Mon Sep 17 00:00:00 2001 From: Marek Skrajnowski Date: Mon, 27 Apr 2020 13:44:45 +0200 Subject: [PATCH 2/6] feat(ecs): enabled container insights --- ecs/main.tf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ecs/main.tf b/ecs/main.tf index dfb64fd4..4b1bfeed 100644 --- a/ecs/main.tf +++ b/ecs/main.tf @@ -23,5 +23,10 @@ resource "aws_ecs_cluster" "cluster" { count = var.create ? 1 : 0 name = "${var.project}-${var.environment}" + + setting { + name = "containerInsights" + value = "enabled" + } } From 5e5494fbdc4df416b3cb9045994941adf4329e67 Mon Sep 17 00:00:00 2001 From: Marek Skrajnowski Date: Mon, 27 Apr 2020 13:45:47 +0200 Subject: [PATCH 3/6] docs(ecs): adjusted example tasks memory and cpu requirements --- ecs/example/main.tf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ecs/example/main.tf b/ecs/example/main.tf index 9b90d329..5fb8f172 100644 --- a/ecs/example/main.tf +++ b/ecs/example/main.tf @@ -48,7 +48,8 @@ module "worker_task" { environment = local.environment task = "worker" image = "kennethreitz/httpbin:latest" - memory_soft_limit = 128 + memory_soft_limit = 48 + cpu = 128 environment_variables = { DEBUG = "True" @@ -72,7 +73,8 @@ module "web_task" { environment = local.environment task = "web" image = "kennethreitz/httpbin:latest" - memory_soft_limit = 128 + memory_soft_limit = 48 + cpu = 128 ports = [80] environment_variables = { From 9ba42f5b5d150b4d08de7d27b068af02267f019f Mon Sep 17 00:00:00 2001 From: Marek Skrajnowski Date: Mon, 4 May 2020 11:46:38 +0200 Subject: [PATCH 4/6] feat(ecs): added empty metrics and widget outputs --- ecs/README.md | 8 ++++++++ ecs/metrics.tf | 5 +++++ ecs/outputs.tf | 10 ++++++++++ ecs/widgets.tf | 5 +++++ 4 files changed, 28 insertions(+) create mode 100644 ecs/metrics.tf create mode 100644 ecs/widgets.tf diff --git a/ecs/README.md b/ecs/README.md index 0d48c3e4..c81d637f 100644 --- a/ecs/README.md +++ b/ecs/README.md @@ -153,6 +153,10 @@ Based on [AWS reference architecture](https://github.com/aws-samples/ecs-refarch The canonical hosted zone ID of the Application Load Balancer (to be used in a Route 53 Alias record) +* `metrics` + + ECS cluster Cloudwatch metrics, see [metrics.tf](./metrics.tf) for details + * `name` Cluster name @@ -192,3 +196,7 @@ Based on [AWS reference architecture](https://github.com/aws-samples/ecs-refarch * `web_service_role_name` ECS web service task role name + +* `widgets` + + ECS cluster Cloudwatch dashboard widgets, see [widgets.tf](./widgets.tf) for details diff --git a/ecs/metrics.tf b/ecs/metrics.tf new file mode 100644 index 00000000..c4db1a29 --- /dev/null +++ b/ecs/metrics.tf @@ -0,0 +1,5 @@ +locals { + metrics = { + + } +} diff --git a/ecs/outputs.tf b/ecs/outputs.tf index dd7e8346..8c93a81a 100644 --- a/ecs/outputs.tf +++ b/ecs/outputs.tf @@ -8,6 +8,16 @@ output "arn" { description = "Cluster ARN" } +output "metrics" { + value = local.metrics + description = "ECS cluster Cloudwatch metrics, see [metrics.tf](./metrics.tf) for details" +} + +output "widgets" { + value = local.widgets + description = "ECS cluster Cloudwatch dashboard widgets, see [widgets.tf](./widgets.tf) for details" +} + # network outputs output "vpc_id" { diff --git a/ecs/widgets.tf b/ecs/widgets.tf new file mode 100644 index 00000000..f1ee0bc0 --- /dev/null +++ b/ecs/widgets.tf @@ -0,0 +1,5 @@ +locals { + widgets = { + + } +} From 2cf37b935184273837d51d6328c7fb4012533451 Mon Sep 17 00:00:00 2001 From: Marek Skrajnowski Date: Mon, 4 May 2020 12:36:24 +0200 Subject: [PATCH 5/6] feat(ecs): added cpu and memory utilization metrics and widgets --- ecs/example/main.tf | 14 +++++++++++++ ecs/metrics.tf | 50 +++++++++++++++++++++++++++++++++++++++++++++ ecs/widgets.tf | 25 ++++++++++++++++++++++- 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/ecs/example/main.tf b/ecs/example/main.tf index 5fb8f172..0eb2a7c1 100644 --- a/ecs/example/main.tf +++ b/ecs/example/main.tf @@ -98,6 +98,16 @@ module "web" { healthcheck_path = "/" } +module "dashboard" { + source = "./../../cloudwatch/dashboard" + + name = "terraform-ecs-example" + widgets = [ + module.cluster.widgets.cpu_utilization, + module.cluster.widgets.memory_utilization, + ] +} + output "hosts_id" { value = module.hosts.id } @@ -105,3 +115,7 @@ output "hosts_id" { output "lb_url" { value = "http://${module.cluster.load_balancer_domain}" } + +output "dashboard_url" { + value = module.dashboard.url +} diff --git a/ecs/metrics.tf b/ecs/metrics.tf index c4db1a29..cb0fd048 100644 --- a/ecs/metrics.tf +++ b/ecs/metrics.tf @@ -1,5 +1,55 @@ locals { metrics = { + cpu_utilization = module.metrics_cpu.out_map.utilization + cpu_reservation = module.metrics_cpu.out_map.reservation + memory_utilization = module.metrics_memory.out_map.utilization + memory_reservation = module.metrics_memory.out_map.reservation + } +} + +module "cloudwatch_consts" { + source = "./../cloudwatch/consts" +} + +locals { + colors = module.cloudwatch_consts.colors +} + +locals { + cluster_dimensions = { + ClusterName = var.create ? aws_ecs_cluster.cluster[0].name : "" + } + metrics_utilization = { + reservation = { name = "Reservation", color = local.colors.grey } + utilization = { name = "Utilization", color = local.colors.orange } } } + +module "metrics_cpu" { + source = "./../cloudwatch/metric/many" + + vars_map = { for k, v in local.metrics_utilization : k => { + namespace = "AWS/ECS" + dimensions = local.cluster_dimensions + name = "CPU${v.name}" + label = "CPU ${lower(v.name)}" + color = v.color + stat = "Average" + period = 60 + } } +} + +module "metrics_memory" { + source = "./../cloudwatch/metric/many" + + vars_map = { for k, v in local.metrics_utilization : k => { + namespace = "AWS/ECS" + dimensions = local.cluster_dimensions + name = "Memory${v.name}" + label = "Memory ${lower(v.name)}" + color = v.color + stat = "Average" + period = 60 + } } +} diff --git a/ecs/widgets.tf b/ecs/widgets.tf index f1ee0bc0..30fc10fb 100644 --- a/ecs/widgets.tf +++ b/ecs/widgets.tf @@ -1,5 +1,28 @@ locals { widgets = { - + cpu_utilization = module.widget_cpu_utilization + memory_utilization = module.widget_memory_utilization } } + +module "widget_cpu_utilization" { + source = "./../cloudwatch/metric_widget" + + title = "ECS CPU utilization" + left_metrics = [ + local.metrics.cpu_reservation, + local.metrics.cpu_utilization, + ] + left_range = [0, 100] +} + +module "widget_memory_utilization" { + source = "./../cloudwatch/metric_widget" + + title = "ECS memory utilization" + left_metrics = [ + local.metrics.memory_reservation, + local.metrics.memory_utilization, + ] + left_range = [0, 100] +} From d9e65a29dd5718a75bd2f2fd81cc3a7290c1fd34 Mon Sep 17 00:00:00 2001 From: Marek Skrajnowski Date: Mon, 4 May 2020 12:47:20 +0200 Subject: [PATCH 6/6] feat(ecs): added instance/service/task count metrics and widgets --- ecs/example/main.tf | 3 +++ ecs/metrics.tf | 25 +++++++++++++++++++++++++ ecs/widgets.tf | 28 ++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/ecs/example/main.tf b/ecs/example/main.tf index 0eb2a7c1..9936a3db 100644 --- a/ecs/example/main.tf +++ b/ecs/example/main.tf @@ -105,6 +105,9 @@ module "dashboard" { widgets = [ module.cluster.widgets.cpu_utilization, module.cluster.widgets.memory_utilization, + module.cluster.widgets.instances, + module.cluster.widgets.services, + module.cluster.widgets.tasks, ] } diff --git a/ecs/metrics.tf b/ecs/metrics.tf index cb0fd048..a87ef820 100644 --- a/ecs/metrics.tf +++ b/ecs/metrics.tf @@ -4,6 +4,10 @@ locals { cpu_reservation = module.metrics_cpu.out_map.reservation memory_utilization = module.metrics_memory.out_map.utilization memory_reservation = module.metrics_memory.out_map.reservation + + instances = module.metrics_count.out_map.instance + services = module.metrics_count.out_map.service + tasks = module.metrics_count.out_map.task } } @@ -53,3 +57,24 @@ module "metrics_memory" { period = 60 } } } + +locals { + metrics_count = { + instance = { name = "ContainerInstance", label = "Instances" } + service = { name = "Service", label = "Services" } + task = { name = "Task", label = "Tasks" } + } +} + +module "metrics_count" { + source = "./../cloudwatch/metric/many" + + vars_map = { for k, v in local.metrics_count : k => { + namespace = "ECS/ContainerInsights" + dimensions = local.cluster_dimensions + name = "${v.name}Count" + label = v.label + stat = "Average" + period = 60 + } } +} diff --git a/ecs/widgets.tf b/ecs/widgets.tf index 30fc10fb..83278a93 100644 --- a/ecs/widgets.tf +++ b/ecs/widgets.tf @@ -2,6 +2,10 @@ locals { widgets = { cpu_utilization = module.widget_cpu_utilization memory_utilization = module.widget_memory_utilization + + instances = module.widget_instances + services = module.widget_services + tasks = module.widget_tasks } } @@ -26,3 +30,27 @@ module "widget_memory_utilization" { ] left_range = [0, 100] } + +module "widget_instances" { + source = "./../cloudwatch/metric_widget" + + title = "ECS instances" + left_metrics = [local.metrics.instances] + left_range = [0, null] +} + +module "widget_services" { + source = "./../cloudwatch/metric_widget" + + title = "ECS services" + left_metrics = [local.metrics.services] + left_range = [0, null] +} + +module "widget_tasks" { + source = "./../cloudwatch/metric_widget" + + title = "ECS tasks" + left_metrics = [local.metrics.tasks] + left_range = [0, null] +}