From 735ddc715abeb3a2111982ef2a71b0ef84126d60 Mon Sep 17 00:00:00 2001 From: Ruchika Modi Date: Tue, 16 Jan 2024 12:24:13 +0000 Subject: [PATCH] Updating EKS container insights to replace deamonset with tf resource --- docs/container-insights/eks.md | 33 +++++++++-- examples/eks-container-insights/locals.tf | 24 ++++---- examples/eks-container-insights/main.tf | 36 ++---------- examples/eks-container-insights/variables.tf | 23 +++++--- examples/eks-container-insights/versions.tf | 12 ---- modules/eks-container-insights/main.tf | 62 ++++++++++++-------- modules/eks-container-insights/outputs.tf | 19 ------ modules/eks-container-insights/values.yaml | 1 - modules/eks-container-insights/variables.tf | 54 +++++++++-------- modules/eks-container-insights/versions.tf | 12 ---- 10 files changed, 129 insertions(+), 147 deletions(-) delete mode 100644 modules/eks-container-insights/values.yaml diff --git a/docs/container-insights/eks.md b/docs/container-insights/eks.md index 104b6739..5c58a4d1 100644 --- a/docs/container-insights/eks.md +++ b/docs/container-insights/eks.md @@ -1,8 +1,6 @@ # Setting Up Container Insights for your EKS Cluster -This example deploys AWS Distro of OpenTelemetry on your EKS cluster as a Daemonset which will enable -Container Insights metrics Dashboard on Amazon CloudWatch. - +This example deploys CloudWatch Observability EKS add-on on an exisiting Amazon EKS cluster, wihich has Container Insights enhanced observability for Amazon EKS and CloudWatch Application Signals enabled by default. ## Prerequisites @@ -42,12 +40,37 @@ Simply run this command to deploy the example terraform apply ``` -## Visualization +## Enabling Application Signals for your services +CloudWatch Application Signals is currenlty supported for **Java** applications running on your Amazon EKS cluster. + +Next, you have to update your Application to `Configure application metrics and trace sampling`. For this, you must add an annotation to a manifest YAML in your cluster. Adding this annotation auto-instruments the application to send metrics, traces, and logs to Application Signals. You have two options for the annotation: + +1. **Annotate Workload** auto-instruments a single workload in the cluster. + - Paste the below line into the PodTemplate section of the workload manifest. + ``` + annotations: instrumentation.opentelemetry.io/inject-java: "true" + ``` + - In your terminal, enter `kubectl apply -f your_deployment_yaml` to apply the change. + +2. **Annotate Namespace** auto-instruments all workloads deployed in the selected namespace. + - Paste the below line into the metadata section of the namespace manifest. + ``` + annotations: instrumentation.opentelemetry.io/inject-java: "true" + ``` + - In your terminal, enter `kubectl apply -f your_namespace_yaml` to apply the change. + - In your terminal, enter a command to restart all pods in the namespace. An example command to restart deployment workloads is `kubectl rollout restart deployment -n namespace_name` -After apply, open your Amazon CloudWatch console in the same region as your EKS cluster, then from the left hand side choose `Insights -> Container Insights`, there choose the `Performance montoring` from the drop down, choose the `cluster name` and you will see the metrics shown on the dashboard: +## Visualization of Container Insights data + +After the terraform apply is successful, open your Amazon CloudWatch console in the same region as your EKS cluster, then from the left hand side choose `Insights -> Container Insights`, there choose the `EKS` from the drop down and you will see the metrics shown on the dashboard: ![image](https://github.com/aws-observability/terraform-aws-observability-accelerator/assets/10175027/c5b9b685-5894-4350-b68a-ca86d1128f6f) +## Visualization of Application Signal data + +After enabling your Application to pass metrics and traces by following [these steps](#enabling-application-signals-for-your-services), open your Amazon CloudWatch console in the same region as your EKS cluster, then from the left hand side choose `Application Signals -> Services` and you will see the metrics shown on the dashboard: + + ## Cleanup diff --git a/examples/eks-container-insights/locals.tf b/examples/eks-container-insights/locals.tf index 7419dac8..c2c3d90f 100644 --- a/examples/eks-container-insights/locals.tf +++ b/examples/eks-container-insights/locals.tf @@ -1,13 +1,15 @@ -data "aws_partition" "current" {} - -data "aws_caller_identity" "current" {} - -data "aws_region" "current" {} - -data "aws_eks_cluster" "eks_cluster" { - name = var.eks_cluster_id -} - locals { - eks_cluster_endpoint = data.aws_eks_cluster.eks_cluster.endpoint + name = "amazon-cloudwatch-observability" + kubernetes_version = var.eks_cluster_version + eks_oidc_issuer_url = replace(data.aws_eks_cluster.eks_cluster.identity[0].oidc[0].issuer, "https://", "") + + addon_context = { + aws_caller_identity_account_id = data.aws_caller_identity.current.account_id + aws_caller_identity_arn = data.aws_caller_identity.current.arn + aws_partition_id = data.aws_partition.current.partition + aws_region_name = data.aws_region.current.name + eks_oidc_provider_arn = "arn:${data.aws_partition.current.partition}:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${local.eks_oidc_issuer_url}" + eks_cluster_id = data.aws_eks_cluster.eks_cluster.id + tags = var.tags + } } diff --git a/examples/eks-container-insights/main.tf b/examples/eks-container-insights/main.tf index 93c5360e..b15743e4 100644 --- a/examples/eks-container-insights/main.tf +++ b/examples/eks-container-insights/main.tf @@ -1,33 +1,7 @@ -provider "aws" { - region = var.aws_region -} - -provider "kubernetes" { - host = local.eks_cluster_endpoint - cluster_ca_certificate = base64decode(data.aws_eks_cluster.eks_cluster.certificate_authority[0].data) - exec { - api_version = "client.authentication.k8s.io/v1beta1" - args = ["eks", "get-token", "--cluster-name", var.eks_cluster_id] - command = "aws" - } -} - -provider "helm" { - kubernetes { - host = local.eks_cluster_endpoint - cluster_ca_certificate = base64decode(data.aws_eks_cluster.eks_cluster.certificate_authority[0].data) - exec { - api_version = "client.authentication.k8s.io/v1beta1" - args = ["eks", "get-token", "--cluster-name", var.eks_cluster_id] - command = "aws" - } - } -} - - -# Deploy the CW Application Signals and Container Insights - module "eks_container_insights" { - source = "../../modules/eks-container-insights" - eks_cluster_id = var.eks_cluster_id + source = "./modules/eks-container-insights" + cluster_name = var.cluster_name + enable_amazon_eks_cw_observability = true + create_cloudwatch_observability_irsa_role = true + eks_oidc_provider_arn = local.addon_context.eks_oidc_provider_arn } diff --git a/examples/eks-container-insights/variables.tf b/examples/eks-container-insights/variables.tf index 36319c1a..00eaaaff 100644 --- a/examples/eks-container-insights/variables.tf +++ b/examples/eks-container-insights/variables.tf @@ -1,25 +1,32 @@ -variable "eks_cluster_id" { +variable "cluster_name" { description = "EKS cluster name" type = string } -variable "aws_region" { - description = "EKS cluster region" +variable "eks_cluster_domain" { + description = "The domain for the EKS cluster" type = string + default = "" } -variable "irsa_iam_role_path" { - description = "IAM role path for IRSA roles" +variable "eks_oidc_provider" { + description = "The OpenID Connect identity provider (issuer URL without leading `https://`)" type = string - default = "/" + default = null } -variable "irsa_iam_permissions_boundary" { - description = "IAM permissions boundary for IRSA roles" +variable "eks_oidc_provider_arn" { + description = "The OpenID Connect identity provider ARN" type = string default = null } +variable "eks_cluster_version" { + description = "The Kubernetes version for the cluster" + type = string + default = "1.28" +} + variable "tags" { description = "Additional tags (e.g. `map('BusinessUnit`,`XYZ`)" type = map(string) diff --git a/examples/eks-container-insights/versions.tf b/examples/eks-container-insights/versions.tf index ea7a421f..e426124f 100644 --- a/examples/eks-container-insights/versions.tf +++ b/examples/eks-container-insights/versions.tf @@ -6,17 +6,5 @@ terraform { source = "hashicorp/aws" version = ">= 5.0.0" } - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.10" - } - kubectl = { - source = "alekc/kubectl" - version = ">= 2.0.3" - } - helm = { - source = "hashicorp/helm" - version = ">= 2.4.1" - } } } diff --git a/modules/eks-container-insights/main.tf b/modules/eks-container-insights/main.tf index d4c11538..0b7e816a 100644 --- a/modules/eks-container-insights/main.tf +++ b/modules/eks-container-insights/main.tf @@ -1,30 +1,46 @@ -provider "kubernetes" { - host = data.aws_eks_cluster.eks_cluster.endpoint - cluster_ca_certificate = base64decode(data.aws_eks_cluster.eks_cluster.certificate_authority[0].data) - exec { - api_version = "client.authentication.k8s.io/v1beta1" - args = ["eks", "get-token", "--cluster-name", local.addon_context.eks_cluster_id] - command = "aws" - } +locals { + name = "amazon-cloudwatch-observability" } -provider "helm" { - kubernetes { - host = data.aws_eks_cluster.eks_cluster.endpoint - cluster_ca_certificate = base64decode(data.aws_eks_cluster.eks_cluster.certificate_authority[0].data) - exec { - api_version = "client.authentication.k8s.io/v1beta1" - args = ["eks", "get-token", "--cluster-name", local.addon_context.eks_cluster_id] - command = "aws" +module "cloudwatch_observability_irsa_role" { + source = "terraform-aws-modules/iam/aws//modules/iam-role-for-service-accounts-eks" + count = var.create_cloudwatch_observability_irsa_role ? 1 : 0 + + role_name = "cloudwatch-observability" + attach_cloudwatch_observability_policy = true + + oidc_providers = { + ex = { + provider_arn = var.eks_oidc_provider_arn + namespace_service_accounts = ["amazon-cloudwatch:cloudwatch-agent"] } } } -module "helm_addon" { - source = "github.com/aws-ia/terraform-aws-eks-blueprints//modules/kubernetes-addons/helm-addon?ref=v4.32.1" - manage_via_gitops = var.manage_via_gitops - set_values = local.set_values - helm_config = local.helm_config - irsa_config = local.irsa_config - addon_context = local.addon_context +data "aws_eks_addon_version" "eks_addon_version" { + addon_name = local.name + kubernetes_version = var.kubernetes_version + most_recent = var.most_recent +} + +resource "aws_eks_addon" "amazon-cloudwatch-observability" { + count = var.enable_amazon_eks_cw_observability ? 1 : 0 + + cluster_name = var.cluster_name + addon_name = local.name + addon_version = try(var.addon_config.addon_version, data.aws_eks_addon_version.eks_addon_version.version) + resolve_conflicts_on_create = try(var.addon_config.resolve_conflicts_on_create, "OVERWRITE") + service_account_role_arn = try(module.cloudwatch_observability_irsa_role[0].iam_role_arn, null) + preserve = try(var.addon_config.preserve, true) + configuration_values = try(var.addon_config.configuration_values, null) + + tags = merge( + # var.addon_context.tags, + try(var.addon_config.tags, {}) + ) +} + +resource "aws_iam_service_linked_role" "application-signals-cw" { + count = var.create_cloudwatch_application_signals_role ? 1 : 0 + aws_service_name = "application-signals.cloudwatch.amazonaws.com" } diff --git a/modules/eks-container-insights/outputs.tf b/modules/eks-container-insights/outputs.tf index 37b305f9..e69de29b 100644 --- a/modules/eks-container-insights/outputs.tf +++ b/modules/eks-container-insights/outputs.tf @@ -1,19 +0,0 @@ -output "release_metadata" { - description = "Map of attributes of the Helm release metadata" - value = module.helm_addon.release_metadata -} - -output "irsa_arn" { - description = "IAM role ARN for the service account" - value = module.helm_addon.irsa_arn -} - -output "irsa_name" { - description = "IAM role name for the service account" - value = module.helm_addon.irsa_name -} - -output "service_account" { - description = "Name of Kubernetes service account" - value = module.helm_addon.service_account -} diff --git a/modules/eks-container-insights/values.yaml b/modules/eks-container-insights/values.yaml deleted file mode 100644 index bd8e751b..00000000 --- a/modules/eks-container-insights/values.yaml +++ /dev/null @@ -1 +0,0 @@ -clusterName: ${eks_cluster_id} diff --git a/modules/eks-container-insights/variables.tf b/modules/eks-container-insights/variables.tf index b66d6555..4760b7a4 100644 --- a/modules/eks-container-insights/variables.tf +++ b/modules/eks-container-insights/variables.tf @@ -1,46 +1,50 @@ -variable "helm_config" { - description = "Helm provider config for adot-exporter-for-eks-on-ec2" - type = any - default = {} +variable "cluster_name" { + default = "eks-cw" + type = string } -variable "manage_via_gitops" { +variable "enable_amazon_eks_cw_observability" { + description = "Enable Amazon EKS CloudWatch Observability add-on" type = bool - description = "Determines if the add-on should be managed via GitOps." default = false } -variable "irsa_policies" { - description = "Additional IAM policies for a IAM role for service accounts" - type = list(string) - default = [] +variable "addon_config" { + description = "Amazon EKS Managed CloudWatch Observability Add-on config" + type = any + default = {} } -variable "eks_cluster_id" { - description = "EKS Cluster Id" +variable "cluster_version" { + description = "The Version of Kubernetes to deploy" type = string + default = "1.25" } -variable "aws_cloudwatch_metrics_chart_verison" { - description = "AWS CloudWatch Observability Metrics helm chart version" +variable "kubernetes_version" { + description = "Kubernetes version" type = string - default = "0.0.7" + default = "1.28" } -variable "tags" { - description = "Additional tags (e.g. `map('BusinessUnit`,`XYZ`)" - type = map(string) - default = {} +variable "most_recent" { + type = string + default = "false" +} + +variable "eks_oidc_provider_arn" { + type = string + default = "" } -variable "irsa_iam_role_path" { - description = "IAM role path for IRSA roles" +variable "create_cloudwatch_observability_irsa_role" { type = string - default = "/" + default = true + description = "Create a Cloudwatch Observability IRSA" } -variable "irsa_iam_permissions_boundary" { - description = "IAM permissions boundary for IRSA roles" +variable "create_cloudwatch_application_signals_role" { type = string - default = null + default = true + description = "Create a Cloudwatch Application Signals service-linked role" } diff --git a/modules/eks-container-insights/versions.tf b/modules/eks-container-insights/versions.tf index ea7a421f..e426124f 100644 --- a/modules/eks-container-insights/versions.tf +++ b/modules/eks-container-insights/versions.tf @@ -6,17 +6,5 @@ terraform { source = "hashicorp/aws" version = ">= 5.0.0" } - kubernetes = { - source = "hashicorp/kubernetes" - version = ">= 2.10" - } - kubectl = { - source = "alekc/kubectl" - version = ">= 2.0.3" - } - helm = { - source = "hashicorp/helm" - version = ">= 2.4.1" - } } }