Skip to content

niaid/terraform-datadog-synthetics-test

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Terraform Module for Setting up Datadog Synthetics Test(s)

This module is used to create, manage, and update Datadog's Synethentics Test. The primary use-case for this module as envisioned by its authors is the ability to just pass in structured data (JSON, YAML, HCL maps, etc.) to create tests, instead of requiring Terraform. This is useful if want users who dont know Terraform, third-party remote systems via an API, etc. to return information that you can then turn into tests.

The module is fairly unopinionated, but does set a few defaults (like the type and status) to reduce the boilerplate, but these can be changed as needed.

Structure

Because the Datadog synthetics resource makes heavy use of Terraform blocks, this module follows the following heauristic for passing in data:

  • If a block can be used multiple times, the input variable will be (essentially) a list of maps, and the input variable/field will have an s at the end to signal this
  • If only a single block can be created, the input variable/field will be a map.

For example, the options_list block can only be set once, so the input variable would look like:

options_list = {
  tick_every = 60
}

Whereas you can create multiple api_step blocks, and within this, you can create multiple assertion blocks, but only one request_definition so the input looks like:

api_steps = [
  {
    name = "Test first"

    assertions = [
      {
        type     = "statusCode"
        operator = "is"
        target   = "200"
      }
    ]

    request_definition = {
      method = "GET"
      url    = "https://example.org"
    }
  }
]

Examples

The following is a simple example for setting up a basic uptime monitor:

module "datadog_sythetics_test" {
  source = "."

  name      = "test-tf-module"
  subtype   = "multi"
  locations = ["aws:eu-central-1"]
  tags      = ["terraform:true"]

  options_list = {
    tick_every = 60

    retry = {
      count    = 2
      interval = 300
    }

    monitor_options = {
      renotify_interval = 120
    }
  }

  api_steps = [
    {
      name = "Test first"

      assertions = [
        {
          type     = "statusCode"
          operator = "is"
          target   = "200"
        }
      ]

      request_definition = {
        method = "GET"
        url    = "https://example.org"
      }
    }
  ]
}

While writing your test(s) like this is perfectly valid, it's not really where this module shines. Imagine instead you wanted to create this test (or any test) for 500 URLs, with slightly different settings for each? If you imagine that you can pull these URLs from a third-party API in your organization, which returns something like:

{
  "https://example.org": {
    "test_frequency_in_sec": 120,
    "locations": ["aws:us-east-1"]
  },
  "https://google.com": {
    "test_frequency_in_sec": 60,
    "locations": ["aws:us-east-2"]
  },
  "https://amazon.com": {
    "test_frequency_in_sec": 180,
    "locations": [
      "aws:us-east-1",
      "aws:us-east-2"
    ]
  }
}

You could then do:

data "http" "get_urls_to_monitor" {
  url = "https://some-company.com/api/v1/urls"

  request_headers = {
    content-type = "application/json"
    access_key   = "somekindofaccesskey"
  }
}

module "datadog_sythetics_test" {
  source   = "."
  for_each =  jsondecode(data.http.get_urls_to_monitor.response_body)

  name      = "Simple uptime monitor for ${each.key}"
  subtype   = "multi"
  locations = each.value["locations"]
  tags      = ["terraform:true"]

  options_list = {
    tick_every = each.value["test_frequency_in_sec"]

    retry = {
      count    = 2
      interval = 300
    }

    monitor_options = {
      renotify_interval = 120
    }
  }

  api_steps = [
    {
      name = "Test first"

      assertions = [
        {
          type     = "statusCode"
          operator = "is"
          target   = "200"
        }
      ]

      request_definition = {
        method = "GET"
        url    = each.key
      }
    }
  ]
}

Or, if you wanted another team or group which doesn't know Terraform/HCL, but can write, copy and paste, etc. some YAML configuration, these tests could be written in YAML, stored in a repo, remote API, etc. and then you could yamldecode this data into HCL, which you could pass into the module directly, as seen above, or transform it using Terraform locals (for blocks, functions, etc.) to get your desired tests.

Requirements

Name Version
datadog ~> 3.0

Providers

Name Version
datadog ~> 3.0

Modules

No modules.

Resources

Name Type
datadog_synthetics_test.main resource

Inputs

Name Description Type Default Required
api_steps Steps for multistep api tests list(any) null no
assertions Assertions used for the test list(any) null no
browser_steps Steps for browser tests list(any) null no
browser_variables Variables used for a browser test steps list(any) null no
config_variables Variables used for the test configuration list(any) null no
device_ids Array with the different device IDs used to run the test. Valid values are laptop_large, tablet, mobile_small, chrome.laptop_large, chrome.tablet, chrome.mobile_small, firefox.laptop_large, firefox.tablet, firefox.mobile_small, edge.laptop_large, edge.tablet, edge.mobile_small list(string)
[
"laptop_large"
]
no
enabled Whether this test should be created bool true no
locations Array of locations used to run the test. Refer to Datadog documentation for available locations list(string) n/a yes
message A message to include with notifications for this synthetics test string "" no
name Name of Datadog synthetics test string n/a yes
options_list Options for your tests (pass in a map) any null no
request_basicauth The HTTP basic authentication credentials (pass in a map) any null no
request_client_certificate Client certificate to use when performing the test request (pass in a map) any null no
request_definition Required if type = "api". The synthetics test request (pass in a map) any null no
request_headers Header name and value map any null no
request_proxy The proxy to perform the test (pass in a map) any null no
request_query Query arguments name and value map map(string) null no
set_cookie Cookies to be used for a browser test request, using the Set-Cookie syntax string null no
status Define whether you want to start (live) or pause (paused) a Synthetic test. Valid values are live, paused. string "live" no
subtype The subtype of the Synthetic API test. Defaults to http. Valid values are http, ssl, tcp, dns, multi, icmp, udp, websocket, grpc string "http" no
tags A list of tags to associate with your synthetics test. This can help you categorize and filter tests in the manage synthetics page of the UI. list(string) [] no
type Synthetics test type. Valid values are api, browser. string "api" no

Outputs

Name Description
test n/a