diff --git a/modules/add-ons/adot-collector-nginx/README.md b/modules/add-ons/adot-collector-nginx/README.md new file mode 100644 index 0000000..f2aac70 --- /dev/null +++ b/modules/add-ons/adot-collector-nginx/README.md @@ -0,0 +1,49 @@ +# Observability Pattern for Nginx + +This module provides an automated experience around Observability for Nginx workloads. +It provides the following resources: + +- AWS Distro For OpenTelemetry Operator and Collector +- AWS Managed Grafana Dashboard and data source +- Alerts and recording rules with AWS Managed Service for Prometheus + + +## Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.0.0 | +| [aws](#requirement\_aws) | >= 3.72 | +| [kubernetes](#requirement\_kubernetes) | >= 2.10 | + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | >= 3.72 | + +## Modules + +| Name | Source | Version | +|------|--------|---------| +| [helm\_addon](#module\_helm\_addon) | ../helm-addon | n/a | + +## Resources + +| Name | Type | +|------|------| +| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [addon\_context](#input\_addon\_context) | Input configuration for the addon |
object({
aws_caller_identity_account_id = string
aws_caller_identity_arn = string
aws_eks_cluster_endpoint = string
aws_partition_id = string
aws_region_name = string
eks_cluster_id = string
eks_oidc_issuer_url = string
eks_oidc_provider_arn = string
irsa_iam_permissions_boundary = string
irsa_iam_role_path = string
tags = map(string)
})
| n/a | yes | +| [amazon\_prometheus\_workspace\_endpoint](#input\_amazon\_prometheus\_workspace\_endpoint) | Amazon Managed Prometheus Workspace Endpoint | `string` | `null` | no | +| [amazon\_prometheus\_workspace\_region](#input\_amazon\_prometheus\_workspace\_region) | Amazon Managed Prometheus Workspace's Region | `string` | `null` | no | +| [helm\_config](#input\_helm\_config) | Helm Config for Prometheus | `any` | `{}` | no | + +## Outputs + +No outputs. + diff --git a/modules/add-ons/adot-collector-nginx/main.tf b/modules/add-ons/adot-collector-nginx/main.tf new file mode 100644 index 0000000..d9f1ff6 --- /dev/null +++ b/modules/add-ons/adot-collector-nginx/main.tf @@ -0,0 +1,62 @@ +locals { + name = "adot-collector-nginx" + namespace = try(var.helm_config.namespace, local.name) +} + +data "aws_partition" "current" {} + +module "helm_addon" { + source = "../helm-addon" + + helm_config = merge( + { + name = local.name + chart = "${path.module}/otel-config" + version = "0.2.0" + namespace = local.namespace + description = "ADOT helm Chart deployment configuration" + }, + var.helm_config + ) + + set_values = [ + { + name = "ampurl" + value = "${var.amazon_prometheus_workspace_endpoint}api/v1/remote_write" + }, + { + name = "region" + value = var.amazon_prometheus_workspace_region + }, + { + name = "prometheusMetricsEndpoint" + value = "metrics" + }, + { + name = "prometheusMetricsPort" + value = 8888 + }, + { + name = "scrapeInterval" + value = "15s" + }, + { + name = "scrapeTimeout" + value = "10s" + }, + { + name = "scrapeSampleLimit" + value = 1000 + } + ] + + irsa_config = { + create_kubernetes_namespace = try(var.helm_config["create_namespace"], true) + kubernetes_namespace = local.namespace + create_kubernetes_service_account = true + kubernetes_service_account = try(var.helm_config.service_account, local.name) + irsa_iam_policies = ["arn:${data.aws_partition.current.partition}:iam::aws:policy/AmazonPrometheusRemoteWriteAccess"] + } + + addon_context = var.addon_context +} diff --git a/modules/add-ons/adot-collector-nginx/outputs.tf b/modules/add-ons/adot-collector-nginx/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/modules/add-ons/adot-collector-nginx/variables.tf b/modules/add-ons/adot-collector-nginx/variables.tf new file mode 100644 index 0000000..b7d13c3 --- /dev/null +++ b/modules/add-ons/adot-collector-nginx/variables.tf @@ -0,0 +1,34 @@ +variable "helm_config" { + description = "Helm Config for Prometheus" + type = any + default = {} +} + +variable "amazon_prometheus_workspace_endpoint" { + description = "Amazon Managed Prometheus Workspace Endpoint" + type = string + default = null +} + +variable "amazon_prometheus_workspace_region" { + description = "Amazon Managed Prometheus Workspace's Region" + type = string + default = null +} + +variable "addon_context" { + description = "Input configuration for the addon" + type = object({ + aws_caller_identity_account_id = string + aws_caller_identity_arn = string + aws_eks_cluster_endpoint = string + aws_partition_id = string + aws_region_name = string + eks_cluster_id = string + eks_oidc_issuer_url = string + eks_oidc_provider_arn = string + irsa_iam_permissions_boundary = string + irsa_iam_role_path = string + tags = map(string) + }) +} diff --git a/modules/add-ons/adot-collector-nginx/versions.tf b/modules/add-ons/adot-collector-nginx/versions.tf new file mode 100644 index 0000000..d2ddf87 --- /dev/null +++ b/modules/add-ons/adot-collector-nginx/versions.tf @@ -0,0 +1,14 @@ +terraform { + required_version = ">= 1.0.0" + + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.72" + } + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.10" + } + } +} diff --git a/modules/workloads/nginx/otel-config/Chart.yaml b/modules/workloads/nginx/otel-config/Chart.yaml new file mode 100644 index 0000000..94c1fbd --- /dev/null +++ b/modules/workloads/nginx/otel-config/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: opentelemetry +description: A Helm chart to install otel operator +type: application +version: 0.2.0 +appVersion: v0.1.0 diff --git a/modules/workloads/nginx/otel-config/templates/clusterrole.yaml b/modules/workloads/nginx/otel-config/templates/clusterrole.yaml new file mode 100644 index 0000000..4bb1fb7 --- /dev/null +++ b/modules/workloads/nginx/otel-config/templates/clusterrole.yaml @@ -0,0 +1,29 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: otel-prometheus-role +rules: + - apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - services + - endpoints + - pods + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses + verbs: + - get + - list + - watch + - nonResourceURLs: + - /metrics + verbs: + - get diff --git a/modules/workloads/nginx/otel-config/templates/clusterrolebinding.yaml b/modules/workloads/nginx/otel-config/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..7bd8168 --- /dev/null +++ b/modules/workloads/nginx/otel-config/templates/clusterrolebinding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: otel-prometheus-role-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: otel-prometheus-role +subjects: + - kind: ServiceAccount + name: adot-collector-nginx + namespace: adot-collector-nginx diff --git a/modules/workloads/nginx/otel-config/templates/opentelemetrycollector.yaml b/modules/workloads/nginx/otel-config/templates/opentelemetrycollector.yaml new file mode 100644 index 0000000..aaefbdd --- /dev/null +++ b/modules/workloads/nginx/otel-config/templates/opentelemetrycollector.yaml @@ -0,0 +1,67 @@ +apiVersion: opentelemetry.io/v1alpha1 +kind: OpenTelemetryCollector +metadata: + name: adot +spec: + image: public.ecr.aws/aws-observability/aws-otel-collector:latest + mode: deployment + serviceAccount: adot-collector-nginx + config: | + receivers: + prometheus: + config: + global: + scrape_interval: {{ .Values.scrapeInterval }} + scrape_timeout: {{ .Values.scrapeTimeout }} + + scrape_configs: + - job_name: 'kubernetes-pod-nginx' + sample_limit: {{ .Values.scrapeSampleLimit }} + metrics_path: /{{ .Values.prometheusMetricsEndpoint }} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: [ __address__ ] + action: keep + regex: '.*:9404$' + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: replace + source_labels: [ __meta_kubernetes_namespace ] + target_label: Namespace + - source_labels: [ __meta_kubernetes_pod_name ] + action: replace + target_label: pod_name + - action: replace + source_labels: [ __meta_kubernetes_pod_container_name ] + target_label: container_name + - action: replace + source_labels: [ __meta_kubernetes_pod_controller_kind ] + target_label: pod_controller_kind + - action: replace + source_labels: [ __meta_kubernetes_pod_phase ] + target_label: pod_controller_phase + metric_relabel_configs: + - source_labels: [ __name__ ] + regex: 'jvm_gc_collection_seconds.*' + action: drop + exporters: + awsprometheusremotewrite: + endpoint: {{ .Values.ampurl }} + aws_auth: + region: {{ .Values.region }} + service: "aps" + logging: + loglevel: info + extensions: + health_check: + pprof: + endpoint: :1888 + zpages: + endpoint: :55679 + service: + extensions: [pprof, zpages, health_check] + pipelines: + metrics: + receivers: [prometheus] + exporters: [logging, awsprometheusremotewrite] diff --git a/modules/workloads/nginx/otel-config/values.yaml b/modules/workloads/nginx/otel-config/values.yaml new file mode 100644 index 0000000..f3517b2 --- /dev/null +++ b/modules/workloads/nginx/otel-config/values.yaml @@ -0,0 +1,7 @@ +ampurl: ${amp_url} +region: ${region} +prometheusMetricsEndpoint: ${prometheus_metrics_endpoint} +prometheusMetricsPort: ${prometheus_metrics_port} +scrapeInterval: ${scrape_interval} +scrapeTimeout: ${scrape_timeout} +scrapeSampleLimit: ${scrape_sample_limit}