From 48c4688582fc329c8217f347a2de90f176fb3780 Mon Sep 17 00:00:00 2001 From: Eduard Hirsch Date: Mon, 30 Sep 2024 14:30:02 +0300 Subject: [PATCH 1/2] CAT-24419 Added CW Application Signals setup and example --- examples/app-signals/.gitignore | 2 + examples/app-signals/.terraform.lock.hcl | 26 +++++++++++ examples/app-signals/main.tf | 12 +++++ examples/app-signals/outputs.tf | 3 ++ examples/app-signals/sample-backend.tf | 9 ++++ examples/app-signals/sample-provider.tf | 12 +++++ examples/app-signals/tags.tf | 45 +++++++++++++++++++ examples/app-signals/vars.tf | 4 ++ locals.tf | 57 ++++++++++++++++++++++++ optional-task.tf | 14 ++++++ task.tf | 6 ++- 11 files changed, 188 insertions(+), 2 deletions(-) create mode 100644 examples/app-signals/.gitignore create mode 100644 examples/app-signals/.terraform.lock.hcl create mode 100644 examples/app-signals/main.tf create mode 100644 examples/app-signals/outputs.tf create mode 100644 examples/app-signals/sample-backend.tf create mode 100644 examples/app-signals/sample-provider.tf create mode 100644 examples/app-signals/tags.tf create mode 100644 examples/app-signals/vars.tf diff --git a/examples/app-signals/.gitignore b/examples/app-signals/.gitignore new file mode 100644 index 0000000..576a5c5 --- /dev/null +++ b/examples/app-signals/.gitignore @@ -0,0 +1,2 @@ +backend.tf +provider.tf diff --git a/examples/app-signals/.terraform.lock.hcl b/examples/app-signals/.terraform.lock.hcl new file mode 100644 index 0000000..6713911 --- /dev/null +++ b/examples/app-signals/.terraform.lock.hcl @@ -0,0 +1,26 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "4.62.0" + constraints = ">= 4.5.0" + hashes = [ + "h1:6x4fZWzzoUpQyIa6wl160ONU9o9IRmK6Hivt9zNFDug=", + "h1:H/nY2teFoN9LU+Xtc1dx7TGS6w2HrARs0Q7cFb6vbus=", + "zh:12059dc2b639797b9facb6397ac6aec563891634be8e5aadf3a457590c1147d4", + "zh:1b3515d70b6998359d0a6d3b3c287940ab2e5c59cd02f95c7d9dab7df76e86b6", + "zh:423a1d3afdb6b625f2e3b06770ef4324740d400ff1a0d6d566c87d3f841d74fc", + "zh:58612b5a27d929dd1dff04d18d840b9cc59d45fed06247f0c2f87c1e5d3257d9", + "zh:5b243cd2250dd097293e06c1cc85e805565194e53f594ccd070252c7af644f54", + "zh:61ad9739e7d6fca8fddef269cb2ba7285f0632f5f27660755662550e1f69e4bb", + "zh:6700d86f5bfcae8491c87a7769b211a079dbf6dfb325bde76bf407aca3e76ff4", + "zh:67c7925f3b7ac1988c2aee8965b1f6f04738984cf8ae302b88215549793d14c1", + "zh:686770264b907b3e4c75fd751f8ea717a7e393d2fbde0950c4703fa809e573f0", + "zh:740236fda351a8f4976ddbd37e543c8d746a409e3a6aa290a8c5ff774b264455", + "zh:88ace13281a344044624ed088125c30f1a803188bf95874d09ca7e95725d5727", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:a4810a034f5def017607b0b079c7867c983da653928bd9f67edbc18575c0b629", + "zh:e1c10e1641b5f17fec61910d6c3514e241f650ced84523f09cb16271a9a1e651", + "zh:f63593ee2e01a2e1096ae9959fa43f0521114b3335f6440170f0d35d1969e8a2", + ] +} diff --git a/examples/app-signals/main.tf b/examples/app-signals/main.tf new file mode 100644 index 0000000..b846d15 --- /dev/null +++ b/examples/app-signals/main.tf @@ -0,0 +1,12 @@ +module "service" { + source = "../.." + + hosted_zone = var.hosted_zone + + enable_application_signals = true + + organization = var.organization + environment = var.environment + product = var.product + repo = var.repo +} diff --git a/examples/app-signals/outputs.tf b/examples/app-signals/outputs.tf new file mode 100644 index 0000000..acbe6e1 --- /dev/null +++ b/examples/app-signals/outputs.tf @@ -0,0 +1,3 @@ +output "domain_name" { + value = module.service.domain_name +} diff --git a/examples/app-signals/sample-backend.tf b/examples/app-signals/sample-backend.tf new file mode 100644 index 0000000..54572f9 --- /dev/null +++ b/examples/app-signals/sample-backend.tf @@ -0,0 +1,9 @@ +# terraform { +# backend "s3" { +# bucket = "my-bucket-tfstate" +# key = "example-terraform-aws-ecs-service-basic" +# profile = "my-profile" +# region = "us-east-1" +# dynamodb_table = "terraform-lock" +# } +# } diff --git a/examples/app-signals/sample-provider.tf b/examples/app-signals/sample-provider.tf new file mode 100644 index 0000000..f8c7957 --- /dev/null +++ b/examples/app-signals/sample-provider.tf @@ -0,0 +1,12 @@ +# provider "aws" { +# region = "us-east-1" +# profile = "my-profile" +# default_tags { +# tags = { +# product = var.product +# environment = var.environment +# repo = var.repo +# organization = var.organization +# } +# } +# } diff --git a/examples/app-signals/tags.tf b/examples/app-signals/tags.tf new file mode 100644 index 0000000..13585ef --- /dev/null +++ b/examples/app-signals/tags.tf @@ -0,0 +1,45 @@ +variable "environment" { + description = "Environment (sharedtools, dev, staging, prod)" + type = string + + default = "sharedtools" + + validation { + condition = contains(["sharedtools", "dev", "staging", "prod"], var.environment) + error_message = "The environment variable must be one of [sharedtools, dev, staging, prod]." + } +} + +variable "product" { + description = "Tag used to group resources according to application" + + default = "example-tf-ecs-service-basic" + + validation { + condition = can(regex("[a-z\\-]+", var.product)) + error_message = "The product variable violates approved regex." + } +} + +variable "repo" { + description = "Tag used to point to the repo using this module" + + default = "https://github.com/pbs/terraform-ecs-service-module.git" + + validation { + condition = can(regex("(?:git|ssh|https?|git@[-\\w.]+):(\\/\\/)?(.*?)(\\.git)(\\/?|\\#[-\\d\\w._]+?)$", var.repo)) + error_message = "The repo variable violates approved regex." + } +} + +variable "organization" { + description = "Organization using this module. Used to prefix tags so that they are easily identified as being from your organization" + type = string + + default = "example" + + validation { + condition = can(regex("[a-z\\-]+", var.organization)) + error_message = "The organization variable violates approved regex." + } +} diff --git a/examples/app-signals/vars.tf b/examples/app-signals/vars.tf new file mode 100644 index 0000000..1b94bc9 --- /dev/null +++ b/examples/app-signals/vars.tf @@ -0,0 +1,4 @@ +variable "hosted_zone" { + type = string + description = "Primary hosted zone for this service. Populate `TF_VAR_hosted_zone` before running any tests to have this value populated." +} diff --git a/locals.tf b/locals.tf index 1df98d2..3cf11d7 100644 --- a/locals.tf +++ b/locals.tf @@ -57,6 +57,63 @@ locals { creator = "terraform" + application_signals_envs = var.enable_application_signals == false ? [] : [ + { + "name" : "OTEL_RESOURCE_ATTRIBUTES", + "value" : "service.name=${var.product},deployment.environment=${var.environment}" + }, + { + "name" : "PYTHONPATH", + "value" : var.PYTHONPATH + }, + { + "name" : "OTEL_EXPORTER_OTLP_PROTOCOL", + "value" : "http/protobuf" + }, + { + "name" : "OTEL_TRACES_SAMPLER", + "value" : "xray" + }, + { + "name" : "OTEL_TRACES_SAMPLER_ARG", + "value" : "endpoint=http://localhost:2000" + }, + { + "name" : "OTEL_LOGS_EXPORTER", + "value" : "none" + }, + { + "name" : "OTEL_PYTHON_DISTRO", + "value" : "aws_distro" + }, + { + "name" : "OTEL_PYTHON_CONFIGURATOR", + "value" : "aws_configurator" + }, + { + "name" : "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT", + "value" : "http://localhost:4316/v1/traces" + }, + { + "name" : "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT", + "value" : "http://localhost:4316/v1/metrics" + }, + { + "name" : "OTEL_METRICS_EXPORTER", + "value" : "none" + }, + { + "name" : "OTEL_AWS_APPLICATION_SIGNALS_ENABLED", + "value" : "true" + } + ] + + # setunion() cannot use empty sets + env_vars = var.enable_application_signals == false ? var.env_vars : var.env_vars == null || var.env_vars == [] ? local.application_signals_envs : setunion( + local.application_signals_envs, + var.env_vars + ) + defaulted_tags = merge( var.tags, { diff --git a/optional-task.tf b/optional-task.tf index a591ece..a8ef6fe 100644 --- a/optional-task.tf +++ b/optional-task.tf @@ -157,3 +157,17 @@ variable "awslogs_driver_mode" { default = "non-blocking" type = string } + +# Clowdwatch Application Signals +variable "enable_application_signals" { + description = "(optional) if set to true, will enable CW Application Signals" + default = false + type = bool +} + +variable "PYTHONPATH" { + description = "(optional) PYTHONPATH of the application; required by the cwagent sidecar container" + type = string + + default = ":" +} diff --git a/task.tf b/task.tf index 68fb8cf..3fe0050 100644 --- a/task.tf +++ b/task.tf @@ -1,6 +1,6 @@ module "task" { count = var.task_def_arn == null ? 1 : 0 - source = "github.com/pbs/terraform-aws-ecs-task-definition-module?ref=2.0.0" + source = "github.com/pbs/terraform-aws-ecs-task-definition-module?ref=2.0.2" name = local.name @@ -26,7 +26,7 @@ module "task" { virtual_node = var.virtual_node ssm_path = var.ssm_path - env_vars = var.env_vars + env_vars = local.env_vars efs_mounts = var.efs_mounts @@ -35,6 +35,8 @@ module "task" { use_xray_sidecar = var.use_xray_sidecar + use_cwagent_sidecar = var.enable_application_signals + envoy_tag = var.envoy_tag network_mode = var.network_mode From 6a16c0d91458fbc13edb205185e0a293a2f72715 Mon Sep 17 00:00:00 2001 From: ehirsch-3pg Date: Mon, 30 Sep 2024 11:33:01 +0000 Subject: [PATCH 2/2] Running document script --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 94630d0..ba009ae 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ### Using the Repo Source ```hcl -github.com/pbs/terraform-aws-ecs-service-module?ref=6.0.1 +github.com/pbs/terraform-aws-ecs-service-module?ref=x.y.z ``` ### Alternative Installation Methods @@ -26,7 +26,7 @@ Integrate this module like so: ```hcl module "service" { - source = "github.com/pbs/terraform-aws-ecs-service-module?ref=6.0.1" + source = "github.com/pbs/terraform-aws-ecs-service-module?ref=x.y.z" # Required hosted_zone = "example.com" @@ -49,7 +49,7 @@ This module will create an ECS cluster if one is not provided. If you would like ```hcl module "service" { - source = "github.com/pbs/terraform-aws-ecs-service-module?ref=6.0.1" + source = "github.com/pbs/terraform-aws-ecs-service-module?ref=x.y.z" # Required hosted_zone = "example.com" @@ -73,7 +73,7 @@ module "service" { If this repo is added as a subtree, then the version of the module should be close to the version shown here: -`6.0.1` +`x.y.z` Note, however that subtrees can be altered as desired within repositories. @@ -103,7 +103,7 @@ Below is automatically generated documentation on this Terraform module using [t | Name | Source | Version | |------|--------|---------| | [cluster](#module\_cluster) | github.com/pbs/terraform-aws-ecs-cluster-module | 1.0.2 | -| [task](#module\_task) | github.com/pbs/terraform-aws-ecs-task-definition-module | 2.0.0 | +| [task](#module\_task) | github.com/pbs/terraform-aws-ecs-task-definition-module | 2.0.2 | ## Resources @@ -162,6 +162,7 @@ Below is automatically generated documentation on this Terraform module using [t | [organization](#input\_organization) | Organization using this module. Used to prefix tags so that they are easily identified as being from your organization | `string` | n/a | yes | | [product](#input\_product) | Tag used to group resources according to product | `string` | n/a | yes | | [repo](#input\_repo) | Tag used to point to the repo using this module | `string` | n/a | yes | +| [PYTHONPATH](#input\_PYTHONPATH) | (optional) PYTHONPATH of the application; required by the cwagent sidecar container | `string` | `":"` | no | | [acm\_arn](#input\_acm\_arn) | ARN of the ACM certificate to use for the service. If null, one will be guessed based on the primary hosted zone of the service. | `string` | `null` | no | | [alb\_ssl\_policy](#input\_alb\_ssl\_policy) | SSL policy to use for an Application Load Balancer application. | `string` | `"ELBSecurityPolicy-2016-08"` | no | | [aliases](#input\_aliases) | CNAME(s) that are allowed to be used for this service. Default is `product`.`hosted_zone`. e.g. [product.example.com] --> [product.example.com] | `list(string)` | `null` | no | @@ -194,6 +195,7 @@ Below is automatically generated documentation on this Terraform module using [t | [deployment\_minimum\_healthy\_percent](#input\_deployment\_minimum\_healthy\_percent) | The lower limit (as a percentage of the service's desiredCount) of the number of running tasks that must remain running and healthy in a service during a deployment | `number` | `100` | no | | [dns\_evaluate\_target\_health](#input\_dns\_evaluate\_target\_health) | evaluate health of endpoints by querying DNS records | `bool` | `false` | no | | [efs\_mounts](#input\_efs\_mounts) | (optional) efs mount set of objects. Components should include dns\_name, container\_mount\_point, efs\_mount\_point |
set(object({
file_system_id = string
efs_path = string
container_path = string
}))
| `[]` | no | +| [enable\_application\_signals](#input\_enable\_application\_signals) | (optional) if set to true, will enable CW Application Signals | `bool` | `false` | no | | [enable\_circuit\_breaker](#input\_enable\_circuit\_breaker) | Enables ECS circuit breaker | `bool` | `true` | no | | [enable\_circuit\_breaker\_rollback](#input\_enable\_circuit\_breaker\_rollback) | Enables ECS circuit breaker rollback | `bool` | `true` | no | | [enable\_cross\_zone\_load\_balancing](#input\_enable\_cross\_zone\_load\_balancing) | Enable cross-zone load balancing for NLBs. ALB have this enabled by default and cannot be disabled. | `string` | `true` | no |