DataDog / terraform-provider-datadog

Terraform Datadog provider
https://www.terraform.io/docs/providers/datadog/
Mozilla Public License 2.0
403 stars 379 forks source link

Synthetic test fails with INVALID_CHAR_IN_HEADER if entry in request_headers comes from data.local_file #2462

Closed mariodescanva closed 4 months ago

mariodescanva commented 4 months ago

Datadog Terraform Provider Version

v3.37.0

Terraform Version

v1.5.7

What resources or data sources are affected?

datadog_synthetics_test

Terraform Configuration Files

terraform {
  required_version = ">= 0.14.11, < 2.0.0"
}

locals {
  app_name = "app_name"
  supported_events = [
    "x",
    "y",
    "z",
  ]
  # NOTE: these files need to exist locally
  fixtures = {
    for idx, event_name in local.supported_events: idx => {
      name = event_name,
      payload = jsonencode(jsondecode(file("${path.module}/fixtures/event/${event_name}.json"))),
      sha256_path = "${path.module}/fixtures/event/${event_name}.sha256.txt"
    }
  }
}

resource "aws_lambda_function_url" "this" {
  function_name      = "y"
  authorization_type = "NONE"
}

data "aws_secretsmanager_secret_version" "current" {
  secret_id = "k"
}

resource "terraform_data" "calculate_sha256" {
  for_each = local.fixtures

  # Since the file won't be stored in remote state, we have to enforce TF to always
  # generate it.
  triggers_replace = [timestamp()]

  provisioner "local-exec" {
    interpreter = ["bash", "-c"]

    environment = {
      payload = each.value.payload
      secret  = data.aws_secretsmanager_secret_version.current.secret_string
      sha256_path = each.value.sha256_path
    }

    command = <<EOF
      echo -n "$payload" | openssl dgst -sha256 -hmac "$secret" -binary | xxd -p -c 256 | xargs -I{} echo "sha256={}" > "$sha256_path"
    EOF
  }
}

data "local_file" "sha256" {
  for_each = local.fixtures
  filename = each.value.sha256_path
  depends_on = [terraform_data.calculate_sha256]
}

resource "datadog_synthetics_test" "this" {
  for_each  = local.fixtures
  name      = "[${local.app_name}] Publish '${each.value.name}' event"
  type      = "api"
  status    = "live"
  locations = ["aws:${var.region}"]
  message   = "Notify ${local.formatted_slack_channels}"
  tags      = local.monitor_tags

  options_list {
    tick_every = 30
  }

  request_definition {
    method    = "POST"
    url       = aws_lambda_function_url.this.function_url
    body      = each.value.payload
    body_type = "application/json"
    timeout   = 10
  }

  request_headers = {
    x-hub-signature-256                    = data.local_file.sha256[each.key].content
    x-github-event                         = each.value.name
    x-github-delivery                      = "X"
    x-github-hook-id                       = "X"
    x-github-hook-installation-target-id   = "X"
    x-github-hook-installation-target-type = "X"
    Content-Type                           = "application/json"
  }

  assertion {
    type     = "statusCode"
    operator = "is"
    target   = 200
  }

  assertion {
    type     = "responseTime"
    operator = "lessThan"
    target   = 4 * 1000 # 4 seconds
  }
}

Relevant debug or panic output

N/A - it applies successfully.

Expected Behavior

Synthetic tests should run successfully, without the need to edit the x-hub-signature-256 header value and save it.

Actual Behavior

Synthetic tests are failing with INVALID_CHAR_IN_HEADER

Steps to Reproduce

  1. Create empty files in ./fixtures/event/*.json - these need to map to the local.fixtures
  2. terraform apply
  3. Go to synthetic test page in DataDog and run them

Important Factoids

No response

References

No response

HantingZhang2 commented 4 months ago

Hi @mariodescanva the headerx-hub-signature-256 = data.local_file.sha256[each.key].content seem to be the cause of the INVALID_CHAR_IN_HEADER error, do you have the content of this header that might be an invalid character ?

mariodescanva commented 4 months ago

Hi @mariodescanva the headerx-hub-signature-256 = data.local_file.sha256[each.key].content seem to be the cause of the INVALID_CHAR_IN_HEADER error, do you have the content of this header that might be an invalid character ?

@HantingZhang2 I looked closer into the value that comes from datadog backend and turns out datadog doesn't prevent the provider from storing a new line in that field. It was hard to debug because in the UI, there is no way to tell whether it's a new line or not, unless you open up the browser console and try to edit the html tag.

image

That being said, should the provider validation be extended to not allow new line characters?