DataDog / helm-charts

Helm charts for Datadog products
Apache License 2.0
341 stars 1.01k forks source link

Add Environment Variable to Helm Deployment via Terraform #538

Open gallowaystorm opened 2 years ago

gallowaystorm commented 2 years ago

Describe what happened: Errored on adding enviornment variable to help deployment via Terraform.

Describe what you expected: I want an environment variable of DD_LOGS_CONFIG_USE_HTTP set to true.

Steps to reproduce the issue:

  1. Apply terraform code

Additional environment details (Operating System, Cloud provider, etc): This is the terraform code:

locals {
  # Must be a space seperated list, see datadog documentation.
  # https://github.com/DataDog/helm-charts/blob/main/charts/datadog/values.yaml
  exclude_image_list = "image:gcr.io/datadoghq/agent image:harness/delegate image:harness/delegate-ng"
}

resource "helm_release" "datadog" {
  name       = "datadog"
  repository = "https://helm.datadoghq.com"
  chart      = "datadog"

  namespace        = "datadog"
  create_namespace = true

  # Default Configuration items
  set {
    name  = "datadog.apiKey"
    value = var.datadog_api_key
  }

  set {
    name  = "datadog.appKey"
    value = var.datadog_app_key
  }

  set {
    name  = "clusterAgent.enabled"
    value = true
  }

  set {
    name  = "targetSystem"
    value = "linux"
  }

  # Set Datadog Configuration Items

  # Event Collection
  set {
    name  = "agents.rbac.create"
    value = true
  }

  set {
    name  = "datadog.leaderElection"
    value = true
  }

  set {
    name  = "datadog.collectEvents"
    value = true
  }

  # Custom/External Metrics
  set {
    name  = "clusterAgent.metricsProvider.enabled"
    value = true
  }

  # APM Configuration
  set {
    name  = "datadog.apm.enabled"
    value = true
  }

  # Logs Configuration
  set {
    name  = "datadog.logs.enabled"
    value = true
  }

  set {
    name  = "datadog.logs.containerCollectAll"
    value = true
  }

  set {
    name  = "datadog.containerExcludeLogs"
    value = local.exclude_image_list
  }

  # Set logging verbosity, valid log levels are: trace, debug, info, warn, error, critical, off.  Default is info
  set {
    name  = "datadog.logLevel"
    value = "INFO"
  }

  # Process Collection Configuration
  set {
    name  = "datadog.processAgent.enabled"
    value = true
  }

  # Exclude Containers
  set {
    name  = "datadog.containerExclude"
    value = local.exclude_image_list
  }

  # Set Environment Variables
  # DD_LOGS_CONFIG_USE_HTTP is for DD AWS PrivateLink: https://docs.datadoghq.com/agent/guide/private-link/?tab=useast1
  set {
    name  = "datadog.env"
    value = "[{name=DD_LOGS_CONFIG_USE_HTTP, value=true}]"
    type = "auto"
  }
}

This is the error:

╷
│ Error: template: datadog/templates/daemonset.yaml:106:12: executing "datadog/templates/daemonset.yaml" at <include "container-agent" .>: error calling include: template: datadog/templates/_container-agent.yaml:27:8: executing "container-agent" at <include "containers-common-env" .>: error calling include: template: datadog/templates/_containers-common-env.yaml:81:4: executing "containers-common-env" at <include "additional-env-entries" .Values.datadog.env>: error calling include: template: datadog/templates/_helpers.tpl:557:10: executing "additional-env-entries" at <.>: range can't iterate over [{name=DD_LOGS_CONFIG_USE_HTTP
│ 
│   with module.datadog.helm_release.datadog,
│   on .terraform/modules/datadog/helm.tf line 7, in resource "helm_release" "datadog":
│    7: resource "helm_release" "datadog" {

The documentation is not very clear on this.

DanielRis commented 2 years ago

The Helm TF provider is not ideal when it comes to values, I got rid of most of these issues using this method (i do not use it for DD but i was using it for Splunk)

locals {
  splunk_connect_for_kubernetes_values = <<EOL
---
global:
  logLevel: ${var.log_level}
  splunk:
    hec:
      protocol: https
      token: ${local.splunk_hec_token}
      host: ${local.splunk_hec_host}
      port: 443
      indexName: ${local.splunk_index}
splunk-kubernetes-logging:
  enabled: true
  containers:
    logFormatType: json
    logFormat: "%Y-%m-%dT%H:%M:%S.%N%:z"
  kubernetes:
    clusterName: ${var.cluster_id}
    securityContext: true
  journalLogPath: /var/log/journal
  podSecurityPolicy:
    create: false
    apparmor_security: false
  k8sMetadata:
  # Pod labels to collect
    podLabels:
      - app
      - k8s-app
      - release
  customMetadata:
    - name: "sdlc"
      value: "${var.common["sdlcenv"]}"
    - name: "aws_account_id"
      value: "${module.gatherer.account_id}"
    - name: "aws_account_name"
      value: "${data.aws_iam_account_alias.current.id}"
    - name: "aws_region"
      value: "${module.gatherer.region_name}"
    - name: "segment_business_unit"
      value: "${module.gatherer.common["segment_business_unit"]}"
    - name: "application_name"
      value: "${module.gatherer.common["application_name"]}"
    - name: "short_name"
      value: "${var.common["product"]}"

splunk-kubernetes-objects:
  enabled: false

splunk-kubernetes-metrics:
  enabled: false
EOL
}

resource "helm_release" "splunk_connect_for_kubernetes" {
  <removed>
  values = [
    yamlencode(yamldecode(local.splunk_connect_for_kubernetes_values))
  ]
}
pkoraca commented 2 years ago

I used this approach:

    {
      name  = "agents.containers.agent.env[0].name"
      value = "DD_SECRET_BACKEND_COMMAND"
    },
    {
      name  = "agents.containers.agent.env[0].value"
      value = "/readsecret_multiple_providers.sh"
    },
  }
gallowaystorm commented 2 years ago

Hmm, none of those seem to have worked for me. Has there been any update on this

mohsiur commented 2 years ago

I use the following approach, where the values.yaml file is the same in the examples folder

resource "helm_release" "datadog" {
  name             = "datadog"
  namespace        = local.k8s_datadog_namespace
  create_namespace = true
  repository       = "https://helm.datadoghq.com"
  version          = var.datadog_version
  chart            = "datadog"
  values = [file("datadog-chart-values.yaml"]
}

Alternately you could use templatefile to pass in values as well

szarya commented 2 years ago

I got this working using jsonencode and values.

values = [jsonencode(
    { 
        "datadog" = {
            "env" = [
            {
                "name"  = "DD_LOGS_CONFIG_USE_HTTP"
                "value" = "true"
            }
            ] 
        } 
    }
)]

The tricky part was figuring out that using a . as a separator will get misinterpreted by terraform, and that I actually had to construct a proper nested map instead.

marianodav commented 2 years ago

This works for me:

values = [<<YAML
datadog:
    env:
      - name: DD_LOGS_CONFIG_USE_HTTP
        value: "true"
YAML
  ]
aman10592 commented 2 years ago

This has been changed to {{- include "additional-env-entries" .Values.clusterAgent.env | indent 10 }}

galvarado commented 1 year ago

As mentioned by @mohsiur using templatefile:

resource "helm_release" "datadog_agent" {
  name       = "datadog-agent"
  chart      = "datadog"
  repository = "https://helm.datadoghq.com"
  version    = "3.7.3"
  namespace  = "default"
  set_sensitive {
    name  = "datadog.apiKey"
    value = var.datadog_api_key
  }
  # The full list of configuration options for the datadog-value.yaml file in the helm/charts GitHub repository.
  # https://github.com/DataDog/helm-charts/tree/main/charts/datadog#all-configuration-options
  set {
    name  = "datadog.site"
    value = "datadoghq.com"
  }
values = [templatefile("${path.module}/templates/datadog_env_vars.tpl", {
    datadog_log_collection_only = var.datadog_log_collection_only ? "false" : "true"
  })]

The template:

datadog:
    env:
    - name: DD_CLOUD_PROVIDER_METADATA
      value: "aws"
    - name: DD_ENABLE_PAYLOADS_EVENTS
      value: "${datadog_log_collection_only}"