Skip to content

Conversation

@RoseSecurity
Copy link

@RoseSecurity RoseSecurity commented Jul 15, 2025

what

Note

This improvement was first introduced by Nuru, but they never made it back to the community component. Feel free to adopt or disregard

config_map added, old configuration moved

The config_map argument of the datadog_synthetics_test resource is now the primary way
to configure a test. The old collection of top-level arguments is still supported,
but it is now deprecated. The top level arguments are still applied to all tests, but
now you can deploy the same test multiple times with different parameters.

Note that if an entry in config_map.synthetics_paths specifies multiple test files, or if the test file
itself contains multiple tests, they will all get the same configuration. If you want
to deploy tests with different configurations, you will need to use multiple files and
configure them individually.

Outputs are now maps

Corresponding to the change in the config_map argument, the outputs of the module
are all maps, with keys corresponding to the keys in the config_map argument.
The outputs relating to the top-level arguments are included in the maps
under the key _top_level.

config_paramters now map of strings

The config_parameters argument of the datadog_synthetics_test resource is now a map of strings
instead of a map(any). The values have to be converted to strings anyway to be interpolated
into the test configuration, and it resolves some type conversion issues in Terraform to
use fully-specified types.

usage

components:
  terraform:
    datadog-synthetics:
      metadata:
        component: "datadog-synthetics"
      settings:
        spacelift:
          workspace_enabled: true
      vars:
        enabled: true
        name: "datadog-synthetics"
        config_map:
          # The top-level key must be unique within the component configuration.
          this-test:
            config_parameters:
              this_test_param: "this-test-value"
            synthetics_paths:
              # Paths relative to the component directory (where `main.tf` is located)
              - catalog/synthetics/this-test.yaml
          # If re-using the same test with different parameters, ensure they keys
          # are distinct. One way to do this is to parameterize the key along with
          # the test parameters and fill them in using Atmos' Go template support,
          # https://atmos.tools/core-concepts/stacks/imports/#go-templates-in-imports
          "web-page_{{ .web_page }}":
            config_parameters:
              web_page: "{{ .web_page }}"
            synthetics_paths:
              - catalog/synthetics/web-page.yaml
        locations:
          # Locations configured here are added to all tests.
          # You can configure additional locations per test in the test configuration YAML file
          # and in `config_map.locations`.
          - "aws:us-west-2"
        # As with `locations`, if `private_location_test_enabled` is set to `true`,
        # the private location is added to all tests. In this case, the name of the
        # private location is retrieved from the specified component.
        # Alternately, you can configure the private location per test just like
        # any other location, using the location ID, which has the form
        # pl:<private-location-name>-<32-hex-characters>
        # and can be retrieved from the Datadog web UI under
        # UX Monitoring > Settings > Private Locations > <private-location-name> > Metadata > ID
        synthetics_private_location_component_name: "datadog-synthetics-private-location"
        private_location_test_enabled: true

Summary by CodeRabbit

  • New Features

    • Multi-config deployments via config_map with per-test parameters, locations, and tags.
    • Private-location test support and improved runtime validation when no tests are found.
  • Refactor

    • Outputs now return structured maps keyed by config entries.
    • Per-config handling replaces single-merged-map behavior; config_parameters now require string values; synthetics_paths deprecated.
  • Documentation

    • Expanded guides for parameterizing tests, importing from the Datadog API, and tag handling; updated examples and workflow.
  • Chores

    • Requires Terraform >= 1.3.9; project version bumped to v2.0.0.

@RoseSecurity RoseSecurity added the major Breaking changes (or first stable release) label Jul 15, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jul 15, 2025

Walkthrough

Adds a config_map-driven, per-config workflow for Datadog Synthetics: per-config synthetics_paths, parameters, locations, and tags; merges globals/context tags/per-config overrides per test; iterates per-test for module creation; restructures outputs to maps keyed by config entries; adds runtime validation; updates docs and Terraform version/provider.

Changes

Cohort / File(s) Summary
Documentation
README.yaml, src/CHANGELOG.md
README documents parameterized tests, config_map usage, API import workflow, tag behavior, examples, and per-test location/private-location guidance. CHANGELOG records v2.0.0 restructuring: config_map adoption, output shape change, parameter typing, and default-location behavior.
Core orchestration
src/main.tf
Implements per-config handling: local.configs, test_keys_list/test_keys_map, tests_by_config, synthetics_merged; changes module for_each/input signatures to iterate per-config and per-test; merges globals, context tags, per-config tags, and YAML maps; adds null_resource precondition for missing tests and top-level module aliasing.
Inputs / schema
src/variables.tf
Adds config_map (map(object)) and synthetics_private_location_component_name; changes config_parameters to map(string); deprecates top-level synthetics_paths; enforces nullable=false/defaults and clarifies context_tags_enabled, locations, and private-location behavior.
Outputs
src/outputs.tf
Refactors outputs to per-config maps: datadog_synthetics_test_names, test_ids, monitor_ids, and test name→id maps are now nested under config keys.
Terraform versions / providers
src/versions.tf
Raises required_version to >= 1.3.9 and adds null provider (hashicorp/null >= 3.2.4).
Non-functional / formatting
src/context.tf
Minor indentation/formatting changes in variable descriptions only; no behavior change.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant T as Terraform
  participant YC as YAML Loader
  participant M as Merge Logic
  participant DP as Datadog Provider
  participant O as Outputs

  rect rgba(230,240,255,0.5)
  note over U,T: Run terraform plan/apply with `config_map` (and optional top-level vars)
  U->>T: terraform apply
  end

  rect rgba(240,255,230,0.5)
  T->>T: Build local.configs (merge top-level with config_map)
  T->>YC: Load synthetics_paths per config
  YC-->>T: map_configs per config key
  T->>T: Build test_keys_map (config_key,test_key)
  end

  rect rgba(255,245,230,0.5)
  T->>T: Validate: error if no tests across configs
  end

  rect rgba(235,255,255,0.5)
  T->>M: Merge [globals + context_tags? + per-config tags + YAML test map]
  M-->>T: per-test merged definitions
  end

  rect rgba(255,235,245,0.5)
  T->>DP: Create/Update Synthetics per merged test (for_each)
  DP-->>T: returns test IDs, monitor IDs, names
  end

  rect rgba(245,245,245,0.8)
  T->>O: Aggregate outputs keyed by config keys
  O-->>U: structured maps: names, ids, monitor_ids, name→id
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Suggested labels

migration

Poem

In burrows of YAML I hop and I map,
Configs in bundles—each test gets its cap,
Keys merge and nest, outputs tidy and bright,
Tags, locations, and params all set just right.
If no tests are found, I thump—then we fix the gap. 🥕🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title Check ❓ Inconclusive The title is generic and does not clearly convey the primary change, which is introducing the new config_map approach and restructuring test parameterization; it uses vague terms like “logic improvements” and “structure for synthetics” without specifying the main feature. Consider revising the title to explicitly reference the new config_map argument and test parameterization restructure, for example: “feat: add config_map support and per-test parameterization for Datadog synthetics.”
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch introduce-major-logic-improvements-and-structure

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mergify mergify bot requested review from a team July 15, 2025 15:41
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
src/CHANGELOG.md (1)

22-27: Fix typo in heading

config_paramtersconfig_parameters for consistency with the variable name and to avoid confusion.

-### `config_paramters` now map of strings
+### `config_parameters` now map of strings
README.yaml (1)

104-108: Spelling & grammar touch-ups

  1. expecsexpects
  2. Datadog provider name should be capitalised consistently.
-  the Datadog Terraform provider and the Datadog API expecs tags to be passed in
+  the Datadog Terraform provider and the Datadog API expects tags to be passed in
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 324a36f and 2c858dc.

📒 Files selected for processing (7)
  • README.yaml (4 hunks)
  • src/CHANGELOG.md (1 hunks)
  • src/context.tf (1 hunks)
  • src/main.tf (2 hunks)
  • src/outputs.tf (1 hunks)
  • src/variables.tf (2 hunks)
  • src/versions.tf (1 hunks)
🧰 Additional context used
🪛 LanguageTool
src/CHANGELOG.md

[style] ~38-~38: To form a complete sentence, be sure to include a subject.
Context: .../synthetics/tests/browser/{public_id}` can be directly used a map value (you still...

(MISSING_IT_THERE)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
🔇 Additional comments (4)
src/context.tf (1)

267-269: Indentation tidy-up looks good

Pure whitespace change that improves readability; no functional impact.

src/versions.tf (1)

13-16: Validate the new cloudposse/utils provider requirement

Adding a required provider that is never configured or referenced will trigger an unnecessary download and can confuse consumers.
Please double-check that:

  1. utils functions/resources are actually used in this module (e.g. utils_* data sources).
  2. The version constraint >= 1.12.0 matches the first version that contains the needed functionality.

If the provider is not yet used, consider dropping the stanza (or follow up with the provider blocks that will use it).

src/outputs.tf (1)

17-20: Confirm correct output attribute on module.datadog_synthetics

It looks like you’re iterating over v.datadog_synthetic_tests, but the cloudposse/platform/datadog//modules/synthetics module may export its tests under a different key (for example synthetic_tests or syntics_tests). A typo here will cause your plan to fail.

• Inspect the actual outputs of module.datadog_synthetics (via the Terraform Registry docs, the module’s source, or terraform console)
• Update your loop to match the exact attribute name. For example, if the output is synthetic_tests:

-    for vv in v.datadog_synthetic_tests : vv.name => vv.id
+    for vv in v.synthetic_tests        : vv.name => vv.id

Or, if it’s synthetics_tests:

-    for vv in v.datadog_synthetic_tests : vv.name => vv.id
+    for vv in v.synthetics_tests       : vv.name => vv.id

Please verify the correct attribute name and update accordingly.

src/variables.tf (1)

55-59: Narrowing config_parameters to map(string) – double-check call sites

Changing from map(any) to map(string) tightens type safety, but it will force callers to cast numbers/booleans to strings, breaking existing configs that interpolate raw values. Please verify all downstream modules and sample YAML still compile after the change.

@RoseSecurity RoseSecurity requested review from aknysh and removed request for a team July 15, 2025 16:37
@mergify mergify bot requested review from a team July 15, 2025 16:37
@mergify mergify bot added the needs-test Needs testing label Jul 15, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/main.tf (1)

81-82: Merge order still flips precedence – per-config parameters lose

merge(a, b, c) lets later arguments win.
Keeping each.value.config_parameters first means any overlapping key in var.config_parameters overrides the per-config value, contrary to the documented behaviour flagged in the previous review.

-  parameters = merge(each.value.config_parameters, var.config_parameters, local.context_tags)
+  # per-config > global > context
+  parameters = merge(var.config_parameters, each.value.config_parameters, local.context_tags)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c858dc and ee35c50.

📒 Files selected for processing (1)
  • src/main.tf (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary

RoseSecurity and others added 3 commits July 15, 2025 12:55
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/main.tf (1)

8-16: Fallback map still overrides user-provided _top_level entry

merge() gives later arguments precedence, therefore the synthetic fallback that is supplied after var.config_map will clobber any caller-defined _top_level key—exactly the concern raised in an earlier review.
Please reverse the merge order (or gate the fallback behind contains(keys(var.config_map), local.legacy_config_key) as suggested previously) so user intent wins.

🧹 Nitpick comments (1)
src/main.tf (1)

73-75: Pin module sources to immutable SHAs to satisfy CKV_TF_1 and ensure reproducibility

Static analysis flags every module block because only a version is pinned. Supply the full registry source with ?ref= or convert to a Git source locked to a commit hash.

-source  = "cloudposse/config/yaml"
-version = "1.0.2"
+source  = "cloudposse/config/yaml"
+version = "1.0.2"
+# recommend:
+# source  = "git::https://github.com/cloudposse/terraform-yaml-config.git?ref=<commit-sha>"

Repeat for cloudposse/config/yaml//modules/deepmerge and cloudposse/platform/datadog//modules/synthetics.

Also applies to: 88-90, 103-106

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ee35c50 and a5da2d4.

📒 Files selected for processing (1)
  • src/main.tf (1 hunks)
🧰 Additional context used
🪛 Checkov (3.2.334)
src/main.tf

[MEDIUM] 72-84: Ensure Terraform module sources use a commit hash

(CKV_TF_1)


[MEDIUM] 86-100: Ensure Terraform module sources use a commit hash

(CKV_TF_1)

🪛 GitHub Actions: Branch
src/main.tf

[error] 80-80: Git diff detected changes in src/main.tf. The pipeline failed due to uncommitted changes.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary
🔇 Additional comments (1)
src/main.tf (1)

1-123: Formatting / updated plan artefacts caused pipeline failure

CI reports “Git diff detected changes in src/main.tf”. Run terraform fmt and commit the result, or inspect whether autogenerated terraform-docs/tfsec updates were missed.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
src/main.tf (2)

8-16: Fallback _top_level entry still overrides user-supplied config

merge(var.config_map, …fallback…) gives the second argument higher precedence, so a caller-defined _top_level entry will be silently clobbered by the empty fallback map – exactly the issue called out in a previous review.

-  configs = local.enabled ? merge(var.config_map, length(var.synthetics_paths) == 0 ? {} : { (local.legacy_config_key) = {
+  configs = local.enabled ? merge(
+    # only add the fallback when the caller did **not** define the key
+    contains(keys(var.config_map), local.legacy_config_key) || length(var.synthetics_paths) == 0
+      ? {}
+      : {
+          (local.legacy_config_key) = {
+            synthetics_paths     = var.synthetics_paths
+            config_parameters    = {}
+            locations            = []
+            tags                 = {}
+            context_tags_enabled = null
+          }
+        },
+    var.config_map,
+  ) : {}

This preserves user intent and prevents hard-to-trace configuration loss.


95-97: coalesce() will crash when both inputs are null

coalesce(local.configs[…].context_tags_enabled, var.context_tags_enabled) throws an evaluation error if both values are unset (the default). Wrap in try() or add a safe fallback:

-      coalesce(local.configs[each.value.config_key].context_tags_enabled, var.context_tags_enabled) ? local.context_tags : {},
+      coalesce(
+        local.configs[each.value.config_key].context_tags_enabled,
+        var.context_tags_enabled,
+        false, # safe default
+      ) ? local.context_tags : {},
🧹 Nitpick comments (1)
src/main.tf (1)

72-84: Pin registry modules to a specific commit to satisfy CKV_TF_1

Checkov flags both module blocks for not using a commit hash. Consider pinning via the ref attribute to an exact commit or tag to ensure reproducible builds and reduce supply-chain risk.

Also applies to: 86-100

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a5da2d4 and bc305a7.

📒 Files selected for processing (2)
  • src/main.tf (1 hunks)
  • src/versions.tf (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/versions.tf
🧰 Additional context used
🪛 Checkov (3.2.334)
src/main.tf

[MEDIUM] 72-84: Ensure Terraform module sources use a commit hash

(CKV_TF_1)


[MEDIUM] 86-100: Ensure Terraform module sources use a commit hash

(CKV_TF_1)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary

@RoseSecurity
Copy link
Author

Bats is finding a magical null provider:

Cloud Posse requires all providers to use registry format introduced in Terraform 0.13, for example
    aws = {
       source  = "hashicorp/aws"
       version = ">= 3.0"
    }

Please add constraints for these providers:
  - null
---------------------------------

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
src/main.tf (3)

8-16: Fallback _top_level entry can still clobber caller-supplied config

merge(var.config_map, …fallback…) gives the fallback higher precedence, so if a caller already defines _top_level, their values are silently replaced by the empty stub.
This is the exact issue flagged in the previous review and is still unresolved.

-  configs = local.enabled ? merge(var.config_map, length(var.synthetics_paths) == 0 ? {} : { (local.legacy_config_key) = {
+  configs = local.enabled ? merge(
+    # inject fallback only when the caller did **not** define the key
+    contains(keys(var.config_map), local.legacy_config_key) || length(var.synthetics_paths) == 0
+      ? {}
+      : {
+          (local.legacy_config_key) = {
+            synthetics_paths     = var.synthetics_paths
+            config_parameters    = {}
+            locations            = []
+            tags                 = {}
+            context_tags_enabled = null
+          }
+        },
+    var.config_map,
+  ) : {}

Failing to flip the precedence will keep erasing legitimate user input and lead to puzzling plans.


81-82: Parameter-precedence is still inverted; context_tags overwrite per-config values

merge() is last-arg wins. With the current order
merge(each.value.config_parameters, var.config_parameters, local.context_tags)
every collision is won by local.context_tags, then by global parameters, leaving per-config settings with the lowest priority—opposite to the documented intent.

-  parameters = merge(each.value.config_parameters, var.config_parameters, local.context_tags)
+  # precedence: context < global < per-config
+  parameters = merge(
+    local.context_tags,
+    var.config_parameters,
+    each.value.config_parameters,
+  )

This keeps behaviour predictable and in line with the README.


95-97: coalesce() may throw when both inputs are null

coalesce(local.configs[…].context_tags_enabled, var.context_tags_enabled) will panic if both sides are null (the default). Plans will fail unless the user explicitly sets one of them.

Guard with a safe default or try():

-      coalesce(local.configs[each.value.config_key].context_tags_enabled, var.context_tags_enabled) ? local.context_tags : {},
+      coalesce(
+        local.configs[each.value.config_key].context_tags_enabled,
+        var.context_tags_enabled,
+        false,               # safe default
+      )
+      ? local.context_tags
+      : {},

Preventing unexpected runtime errors is worth the small verbosity.

🧹 Nitpick comments (1)
src/main.tf (1)

112-116: Location list may contain duplicated private location IDs

distinct(compact(concat(local.configs[each.key].locations, var.locations, [local.datadog_synthetics_private_location_id]))) removes duplicates, but if the caller already included the private location in either list and provided it in a different capitalisation, the distinct() on raw strings will consider them different.
Consider normalising to lower-case before distinct() to avoid accidental duplication of the same location ID.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc305a7 and 098cc6e.

📒 Files selected for processing (1)
  • src/main.tf (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Summary

@aknysh
Copy link
Contributor

aknysh commented Jul 21, 2025

/terratest

@github-actions
Copy link

There are no real tests for this component. So we set terratest statuses to successful execution without running any tests

@aknysh
Copy link
Contributor

aknysh commented Jul 21, 2025

@goruha
Copy link
Contributor

goruha commented Jul 25, 2025

@RoseSecurity it's not "magical" provider

https://registry.terraform.io/providers/hashicorp/null

@mergify
Copy link

mergify bot commented Sep 22, 2025

Heads up! This pull request looks stale. It will be closed soon, if there are no new commits. ⏳

@mergify mergify bot added stale This PR has gone stale and removed stale This PR has gone stale labels Sep 22, 2025
@mergify
Copy link

mergify bot commented Oct 1, 2025

💥 This pull request now has conflicts. Could you fix it @RoseSecurity? 🙏

@mergify mergify bot added the conflict This PR has conflicts label Oct 1, 2025
@mergify
Copy link

mergify bot commented Oct 8, 2025

Heads up! This pull request looks stale. It will be closed soon, if there are no new commits. ⏳

@mergify mergify bot added stale This PR has gone stale and removed stale This PR has gone stale labels Oct 8, 2025
@mergify
Copy link

mergify bot commented Oct 15, 2025

Heads up! This pull request looks stale. It will be closed soon, if there are no new commits. ⏳

@mergify mergify bot added stale This PR has gone stale and removed stale This PR has gone stale labels Oct 15, 2025
@mergify mergify bot removed the conflict This PR has conflicts label Oct 15, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (10)
README.yaml (7)

51-67: Fix typo and call out string-only parameters (map(string))

  • “they keys” → “the keys”.
  • Add note: config_parameters is map(string); quote/convert non-strings.
           config_map:
             # The top-level key must be unique within the component configuration.
             this-test:
               config_parameters:
                 this_test_param: "this-test-value"
+              # Note: config_parameters is a map(string). Quote all values or coerce to strings.
               synthetics_paths:
                 # Paths relative to the component directory (where `main.tf` is located)
                 - catalog/synthetics/this-test.yaml
-            # If re-using the same test with different parameters, ensure they keys
+            # If re-using the same test with different parameters, ensure the keys
             # are distinct. One way to do this is to parameterize the key along with
             # the test parameters and fill them in using Atmos' Go template support,
             # https://atmos.tools/core-concepts/stacks/imports/#go-templates-in-imports

118-127: Fix typo and clarify tags format guidance

  • “expecs” → “expects”.
  • Explicitly tell users to omit list-based tags in YAML and use component inputs.
   ### Special note about tags

   Cloud Posse modules expect tags to be passed in as a map of strings, but
-  the Datadog Terraform provider and the Datadog API expecs tags to be passed in
+  the Datadog Terraform provider and the Datadog API expects tags to be passed in
   as a list of strings. Unfortunately, we do not have a good way to support
   both formats at the same time. We have chosen to support the
   map of strings, to be consistent with other Cloud Posse modules, which
-  means that tags passed in via the API schema will be ignored. If you want
-  to specify tags in the YAML files, you need to specify them as maps of strings.
+  means that tags passed in via the API schema will be ignored. If you want
+  to specify tags in YAML, omit the list-based `tags` field entirely and provide tags
+  via the component inputs (map of strings). Having both will cause Terraform to fail.

206-209: Update examples link to this repo’s path

Point to this repository’s examples under src/catalog/synthetics/examples.

-  These configuration examples are defined in the YAML files in the [catalog/synthetics/examples](https://github.com/cloudposse/terraform-aws-components/tree/main/modules/datadog-synthetics/catalog/synthetics/examples) folder.
+  These configuration examples are defined in the YAML files in the [catalog/synthetics/examples](https://github.com/cloudposse-terraform-components/aws-datadog-synthetics/tree/main/src/catalog/synthetics/examples) folder.

261-269: Align env var names with headers (DD_*), and mention both keys

-  # Be sure you have already set `public_id` and `DATADOG_APP_KEY` as described above
+  # Be sure you have already set `public_id`, `DD_API_KEY`, and `DD_APP_KEY` as described above

342-344: Avoid backticks; quote the Terraform address literally

-  atmos terraform import datadog-synthetics `module.datadog_synthetics["long key name"].datadog_synthetics_test.default["other long key name"]` ${public_id} -s=<stack-name>
+  atmos terraform import datadog-synthetics 'module.datadog_synthetics["long key name"].datadog_synthetics_test.default["other long key name"]' "${public_id}" -s=<stack-name>

211-216: Variable name typo: use synthetics_paths

Fix reference to match the variable name used elsewhere.

-  Then use the `synthetic_paths` variable to point the component to the synthetic test configuration files.
+  Then use the `synthetics_paths` variable to point the component to the synthetic test configuration files.

236-239: Replace hex-like example keys to avoid Gitleaks/CI failures

Use placeholders; add a warning comment.

-     export DD_API_KEY="1234567890abcdef1234567890abcdef"
-     export DD_APP_KEY="1234567890abcdef1234567890abcdef12345678"
+     export DD_API_KEY="<YOUR_DD_API_KEY>"
+     export DD_APP_KEY="<YOUR_DD_APP_KEY>"
+     # Do not commit real keys. These are placeholders for local use only.
src/main.tf (3)

8-16: Fallback _top_level can overwrite user-provided entry

Merging the fallback after var.config_map will clobber a user-defined _top_level. Inject only when missing.

-  configs = local.enabled ? merge(var.config_map, length(var.synthetics_paths) == 0 ? {} : { (local.legacy_config_key) = {
+  configs = local.enabled ? merge(
+    contains(keys(var.config_map), local.legacy_config_key) || length(var.synthetics_paths) == 0
+      ? {}
+      : { (local.legacy_config_key) = {
         synthetics_paths = var.synthetics_paths
         # We do not need to include the top-level parameters here because they are always included,
         # but we do need to include the attributes to ensure they are always present, even when var.config_map is empty.
         config_parameters    = {}
         locations            = []
         tags                 = {}
         context_tags_enabled = null
-  } }) : {}
+      } },
+    var.config_map,
+  ) : {}

81-82: Parameter precedence inverted (context should be lowest, per-config highest)

Per-config must override globals; context tags should not overwrite either.

-  parameters = merge(each.value.config_parameters, var.config_parameters, local.context_tags)
+  # precedence: context < global < per-config
+  parameters = merge(
+    local.context_tags,
+    var.config_parameters,
+    each.value.config_parameters,
+  )

95-97: coalesce() can error when both inputs are null

Add a safe fallback to avoid plan-time crash.

-    { tags = merge(
-      coalesce(local.configs[each.value.config_key].context_tags_enabled, var.context_tags_enabled) ? local.context_tags : {},
-    local.configs[each.value.config_key].tags) },
+    { tags = merge(
+      coalesce(
+        local.configs[each.value.config_key].context_tags_enabled,
+        var.context_tags_enabled,
+        false
+      )
+      ? local.context_tags
+      : {},
+      local.configs[each.value.config_key].tags
+    ) },
🧹 Nitpick comments (1)
src/main.tf (1)

44-59: Add provider constraint for null to fix CI

Null resource is used; CI complains about missing provider constraints. Add to src/versions.tf.

Proposed src/versions.tf snippet:

terraform {
  required_version = ">= 1.5.0"
  required_providers {
    null = {
      source  = "hashicorp/null"
      version = "~> 3.2"
    }
    # existing providers...
  }
}

Please add and re-run CI to confirm the failure is resolved.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed59459 and ac3beac.

📒 Files selected for processing (2)
  • README.yaml (4 hunks)
  • src/main.tf (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
src/{main,variables,outputs,providers,versions,context}.tf

📄 CodeRabbit inference engine (AGENTS.md)

Keep the Terraform component as the single source of truth in src/ with files: main.tf, variables.tf, outputs.tf, providers.tf, versions.tf, and context.tf

Files:

  • src/main.tf
src/**/*.tf

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.tf: Use 2-space indentation for Terraform files
In Terraform, prefer lower_snake_case for variables and locals; keep resource/data names descriptive and aligned with Cloud Posse null-label patterns
Do not commit formatting or lint violations; ensure terraform fmt -recursive has been applied
Comply with TFLint rules configured in .tflint.hcl

Files:

  • src/main.tf
README.yaml

📄 CodeRabbit inference engine (AGENTS.md)

Treat README.yaml as the source for generated documentation

Files:

  • README.yaml
**/*.{yaml,yml,md}

📄 CodeRabbit inference engine (AGENTS.md)

Use 2-space indentation for YAML and Markdown files

Files:

  • README.yaml
🪛 Gitleaks (8.28.0)
README.yaml

[high] 237-237: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 238-238: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🔇 Additional comments (1)
src/main.tf (1)

112-116: Only include private location when enabled

In src/main.tf (lines 112–116), wrap the private location ID in a conditional:

   locations = distinct(compact(concat(
     local.configs[each.key].locations,
     var.locations,
-    [local.datadog_synthetics_private_location_id]
+    var.private_location_test_enabled ? [local.datadog_synthetics_private_location_id] : []
   )))

Verify that var.private_location_test_enabled (or a per-config equivalent) is wired correctly in your configs.

Comment on lines +250 to +254
Next, download the test definition (in JSON), convert it to YAML, and save it to a file. We use the `yq` command from
[mikefarah](https://github.com/mikefarah/yq) to do the conversion. You can install it with `brew install yq` on a Mac,
or you the version pre-installed in Geodesic. (Note that there are several other similar tools with the same name,
so be sure you are using the one from `mikefarah` by reviewing the output of `yq --version`.)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Grammar fix

“or you the version pre-installed” → “or use the version pre-installed”.

-  or you the version pre-installed in Geodesic. (Note that there are several other similar tools with the same name,
+  or use the version pre-installed in Geodesic. (Note that there are several other similar tools with the same name,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Next, download the test definition (in JSON), convert it to YAML, and save it to a file. We use the `yq` command from
[mikefarah](https://github.com/mikefarah/yq) to do the conversion. You can install it with `brew install yq` on a Mac,
or you the version pre-installed in Geodesic. (Note that there are several other similar tools with the same name,
so be sure you are using the one from `mikefarah` by reviewing the output of `yq --version`.)
Next, download the test definition (in JSON), convert it to YAML, and save it to a file. We use the `yq` command from
[mikefarah](https://github.com/mikefarah/yq) to do the conversion. You can install it with `brew install yq` on a Mac,
or use the version pre-installed in Geodesic. (Note that there are several other similar tools with the same name,
so be sure you are using the one from `mikefarah` by reviewing the output of `yq --version`.)
🤖 Prompt for AI Agents
In README.yaml around lines 250 to 254, fix the grammatical error in the
sentence that reads "or you the version pre-installed in Geodesic." by changing
it to "or use the version pre-installed in Geodesic." so the instruction reads
correctly while leaving the rest of the paragraph unchanged.

Comment on lines +52 to +56
"Check that the `synthetic_paths` list matches at least one valid YAML file.\n\n %s\n\n"
]), join("\n ", [for k, v in module.datadog_synthetics_yaml_config : k if length(v.map_configs) == 0]),
join("\n ", concat(["<config_map key>: [<synthetics_paths>]", "--------------------------------------"],
[for k, v in module.datadog_synthetics_yaml_config : format("%s: [\"%s\"]", k, join("\", \"", local.configs[k].synthetics_paths)) if length(v.map_configs) == 0])
))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Message typo: use synthetics_paths in precondition error

Align with variable name.

-        "Check that the `synthetic_paths` list matches at least one valid YAML file.\n\n   %s\n\n"
+        "Check that the `synthetics_paths` list matches at least one valid YAML file.\n\n   %s\n\n"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Check that the `synthetic_paths` list matches at least one valid YAML file.\n\n %s\n\n"
]), join("\n ", [for k, v in module.datadog_synthetics_yaml_config : k if length(v.map_configs) == 0]),
join("\n ", concat(["<config_map key>: [<synthetics_paths>]", "--------------------------------------"],
[for k, v in module.datadog_synthetics_yaml_config : format("%s: [\"%s\"]", k, join("\", \"", local.configs[k].synthetics_paths)) if length(v.map_configs) == 0])
))
"Check that the `synthetics_paths` list matches at least one valid YAML file.\n\n %s\n\n"
]), join("\n ", [for k, v in module.datadog_synthetics_yaml_config : k if length(v.map_configs) == 0]),
join("\n ", concat(["<config_map key>: [<synthetics_paths>]", "--------------------------------------"],
[for k, v in module.datadog_synthetics_yaml_config : format("%s: [\"%s\"]", k, join("\", \"", local.configs[k].synthetics_paths)) if length(v.map_configs) == 0])
))
🤖 Prompt for AI Agents
In src/main.tf around lines 52 to 56, the precondition error message uses the
wrong variable name "synthetic_paths" — change that string to "synthetics_paths"
so it matches the actual variable/local name used elsewhere; update any
formatted output that referenced the incorrect name to use "synthetics_paths"
consistently and ensure the join/format lines still interpolate
local.configs[k].synthetics_paths correctly.

@mergify
Copy link

mergify bot commented Oct 22, 2025

Heads up! This pull request looks stale. It will be closed soon, if there are no new commits. ⏳

@mergify mergify bot added stale This PR has gone stale and removed stale This PR has gone stale labels Oct 22, 2025
@mergify
Copy link

mergify bot commented Oct 29, 2025

Heads up! This pull request looks stale. It will be closed soon, if there are no new commits. ⏳

@mergify mergify bot added stale This PR has gone stale and removed stale This PR has gone stale labels Oct 29, 2025
@mergify
Copy link

mergify bot commented Nov 5, 2025

Heads up! This pull request looks stale. It will be closed soon, if there are no new commits. ⏳

@mergify mergify bot added stale This PR has gone stale and removed stale This PR has gone stale labels Nov 5, 2025
@mergify
Copy link

mergify bot commented Nov 12, 2025

Heads up! This pull request looks stale. It will be closed soon, if there are no new commits. ⏳

@mergify mergify bot added stale This PR has gone stale and removed stale This PR has gone stale labels Nov 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

major Breaking changes (or first stable release) needs-test Needs testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants