type: user

role: user

content:
You are implementing Task B3 of an implementation plan: add two new variables (`downstream_endpoint`, `downstream_protocol`) to the existing `otel-collector` Terraform internal-module.

## Context

- Working directory: `/Users/steve.briggs/projects/IAC/terraform/internal-modules/kubernetes/monitoring/otel-collector`
- Module is currently on branch `otel-batch-size` (perf-tuning work, ahead of v1.0.5 tag). Your edits should be additive and orthogonal to the existing perf-tuning values (`send_batch_max_size = 75`, etc.) — DO NOT touch those.
- Module structure: file layout is flat (no `templates/` or `tests/` dirs). Helm values are built inline via `yamlencode()` consuming HCL maps from `otelconfig.tf` and `lbconfig.tf`. `main.tf` calls `helm_release` resources passing those locals.
- Pre-flight inventory (from Task B1) confirmed:
  - `variables.tf` does NOT yet have `downstream_endpoint`, `downstream_protocol`, or `vector_endpoint` — clear naming.
  - There are no existing tests, no README, no examples dir.

## Task Description (verbatim from plan)

### Task B3: Add `downstream_endpoint` and `downstream_protocol` variables

**Files:**
- Modify: `variables.tf`

- [ ] **Step 1: Append to `variables.tf`:**

```hcl
variable "downstream_endpoint" {
  description = "When non-empty, swap the terminal exporter from datadog to OTLP, pointed at this endpoint. Used to route through Vector for redaction."
  type        = string
  default     = ""
}

variable "downstream_protocol" {
  description = "Protocol for downstream OTLP exporter. Currently only otlp/grpc supported."
  type        = string
  default     = "otlp/grpc"
  validation {
    condition     = contains(["otlp/grpc", "otlp/http"], var.downstream_protocol)
    error_message = "downstream_protocol must be one of: otlp/grpc, otlp/http"
  }
}
```

- [ ] **Step 2: Run `terraform fmt -check`** (or `terraform fmt -check -recursive`). Exit 0 expected.

- [ ] **Step 3: Run `terraform validate`** (or `terraform init -backend=false && terraform validate`). Should still pass — these are additive variables with safe defaults.

   Note: Terraform 1.9.0+ may be needed. Use `mise exec terraform@1.9.0 -- terraform <cmd>` if the default `terraform` is older.

## Constraints

- **DO NOT run any git commands.** No `git add`, `git commit`, branch operations, etc. The user handles git manually and will manage rebasing onto a v1.0.5 feature branch.
- **DO NOT** push, tag, or open MRs.
- **DO NOT** run `terraform apply`, `kubectl`, `helm install`.
- **DO NOT** modify any other files in this task — only `variables.tf`.

## Spec / plan references

- Spec: `/Users/steve.briggs/projects/IAC/docs/superpowers/specs/2026-05-05-vector-redaction-design.md` §3.1
- Plan: `/Users/steve.briggs/projects/IAC/docs/superpowers/plans/2026-05-05-vector-redaction-pipeline.md` Task B3

## Report Format

- **Status:** DONE | DONE_WITH_CONCERNS | BLOCKED | NEEDS_CONTEXT
- Lines added to `variables.tf` (line numbers)
- `terraform fmt -check` result
- `terraform validate` result
- Self-review findings

userType: external

entrypoint: cli

gitBranch: HEAD


type: message

role: assistant

type: text

text: Let me read the current `variables.tf` before making any changes.

service_tier: standard

attributionAgent: general-purpose

type: assistant


Read

type: direct

speed: standard


content:
1	# ---------------------------------------------------------------------------------------------------------------------
2	# REQUIRED PARAMETERS
3	# These variables are configurable, and need to be set expicitly.
4	# ---------------------------------------------------------------------------------------------------------------------
5	variable "chart_version" {
6	  description = "Version of otel collector chart"
7	  type        = string
8	}
9
10	variable "image_tag_version" {
11	  description = "Version of otel collector image tag"
12	  type        = string
13	}
14
15	# ---------------------------------------------------------------------------------------------------------------------
16	# OPTIONAL PARAMETERS
17	# These variables are configurable, but have reasonable defaults set.
18	# ---------------------------------------------------------------------------------------------------------------------
19	variable "name" {
20	  description = "Name for created resources"
21	  type        = string
22	  default     = "otel-collector"
23	}
24
25	variable "otel_image" {
26	  description = "Helm Value: image.X, optional override to specify image repository & tag"
27	  type        = string
28	  default     = "registry.ic-ops.net/cache-docker-hub/otel/opentelemetry-collector-contrib"
29	}
30
31	variable "otellb_image" {
32	  description = "Helm Value: image.X, optional override to specify image repository & tag"
33	  type        = string
34	  default     = "registry.ic-ops.net/cache-docker-hub/otel/opentelemetry-collector"
35	}
36
37	variable "otel_lb_replicas" {
38	  description = "number of otel loadbalancer replicas to create (statefulset)"
39	  type = number
40	  default = 3
41	}
42
43	variable "otel_collector_replicas" {
44	  description = "number of replicas to create for the otel collector processor"
45	  type = number
46	  default = 3
47	}
48
49	variable "otel_sa_name" {
50	  description = "Service Account name to be used for otel collector statefulset resources"
51	  type        = string
52	  default     = "otel-collector-sa"
53	}
54
55	variable "otellb_sa_name" {
56	  description = "Service Account name to be used for otel collector deployment resources"
57	  type        = string
58	  default     = "otel-collector-lb-sa"
59	}
60
61	variable "otel_pv_size" {
62	    description = "Size of the Persistent Volume to be used for otel collector statefulset"
63	    type        = string
64	    default     = "5Gi"
65	}
66
67	variable otel_storage_class_name {
68	    description = "Storage Class name to be used for otel collector statefulset Persistent Volume"
69	    type        = string
70	    default     = "ebs-encrypted"
71	}
72	variable "sa_annotations" {
73	  description = "Helm Value: A map providing annotations to apply to the otel collector ServiceAccount"
74	  type        = map(string)
75	  default     = {}
76	}
77
78	variable "namespace" {
79	  description = "Namespace to be used for creation of otel collector resources"
80	  type        = string
81	  default     = "opentelemetry"
82	}
83
84	variable "annotations" {
85	  description = "A map providing annotations to apply to the otel collector pods"
86	  type        = map(string)
87	  default     = {}
88	}
89
90	variable "extra_args" {
91	  description = "A list of additional arguments (CLI args) to apply to the otel collector container"
92	  type        = list(string)
93	  default     = []
94	}
95
96	variable "otellb_extra_args" {
97	  description = "A list of additional arguments (CLI args) to apply to the otel collector loadbalancer container"
98	  type        = list(string)
99	  default     = []
100	}
101
102	variable "tags" {
103	  description = "Map of key-vaue pairs to tag created resources with"
104	  type        = map(any)
105	  default     = {}
106	}
107


text: Good. Now I'll append the two new variables to `variables.tf`.


Edit

old_string:
variable "tags" {
  description = "Map of key-vaue pairs to tag created resources with"
  type        = map(any)
  default     = {}
}

new_string:
variable "tags" {
  description = "Map of key-vaue pairs to tag created resources with"
  type        = map(any)
  default     = {}
}

variable "downstream_endpoint" {
  description = "When non-empty, swap the terminal exporter from datadog to OTLP, pointed at this endpoint. Used to route through Vector for redaction."
  type        = string
  default     = ""
}

variable "downstream_protocol" {
  description = "Protocol for downstream OTLP exporter. Currently only otlp/grpc supported."
  type        = string
  default     = "otlp/grpc"
  validation {
    condition     = contains(["otlp/grpc", "otlp/http"], var.downstream_protocol)
    error_message = "downstream_protocol must be one of: otlp/grpc, otlp/http"
  }
}


content: The file /Users/steve.briggs/projects/IAC/terraform/internal-modules/kubernetes/monitoring/otel-collector/variables.tf has been updated successfully. (file state is current in your context — no need to Read it back)


text: Now run `terraform fmt -check` and determine the Terraform version, then validate.


Bash

description: Check installed Terraform version


content: Terraform v1.3.10


command: cd /Users/steve.briggs/projects/IAC/terraform/internal-modules/kubernetes/monitoring/otel-collector && terraform fmt -check 2>&1; echo "exit: $?"

description: Run terraform fmt -check in otel-collector module


content:
lbconfig.tf
main.tf
otelconfig.tf
variables.tf
exit: 3


text: `fmt -check` flagged files (exit 3 means files need formatting). Since `variables.tf` is listed, let me check whether my additions caused it or it was pre-existing. Let me run `fmt` on a copy to isolate, then check what the pre-existing situation was.


command: cd /Users/steve.briggs/projects/IAC/terraform/internal-modules/kubernetes/monitoring/otel-collector && terraform fmt -write=false variables.tf 2>&1

description: Show what terraform fmt would change in variables.tf


content: variables.tf


command: cd /Users/steve.briggs/projects/IAC/terraform/internal-modules/kubernetes/monitoring/otel-collector && terraform fmt -diff variables.tf 2>&1 | head -80

description: Show terraform fmt diff for variables.tf


content:
variables.tf
--- old/variables.tf
+++ new/variables.tf
@@ -36,14 +36,14 @@

 variable "otel_lb_replicas" {
   description = "number of otel loadbalancer replicas to create (statefulset)"
-  type = number
-  default = 3
+  type        = number
+  default     = 3
 }

 variable "otel_collector_replicas" {
   description = "number of replicas to create for the otel collector processor"
-  type = number
-  default = 3
+  type        = number
+  default     = 3
 }

 variable "otel_sa_name" {
@@ -59,15 +59,15 @@
 }

 variable "otel_pv_size" {
-    description = "Size of the Persistent Volume to be used for otel collector statefulset"
-    type        = string
-    default     = "5Gi"
+  description = "Size of the Persistent Volume to be used for otel collector statefulset"
+  type        = string
+  default     = "5Gi"
 }

-variable otel_storage_class_name {
-    description = "Storage Class name to be used for otel collector statefulset Persistent Volume"
-    type        = string
-    default     = "ebs-encrypted"
+variable "otel_storage_class_name" {
+  description = "Storage Class name to be used for otel collector statefulset Persistent Volume"
+  type        = string
+  default     = "ebs-encrypted"
 }
 variable "sa_annotations" {
   description = "Helm Value: A map providing annotations to apply to the otel collector ServiceAccount"
[This command modified 1 file you've previously read: ../otel-collector/variables.tf. Call Read before editing.]


text: The `fmt -diff` run actually applied the formatting changes to `variables.tf` (the diff showed pre-existing style issues, not anything from my additions). Now let me confirm `variables.tf` is clean and run `fmt -check` again.


command: cd /Users/steve.briggs/projects/IAC/terraform/internal-modules/kubernetes/monitoring/otel-collector && terraform fmt -check variables.tf 2>&1; echo "exit: $?"

description: Check if variables.tf is now fmt-clean


content: exit: 0


text: `variables.tf` is clean. The other files (`lbconfig.tf`, `main.tf`, `otelconfig.tf`) had pre-existing style issues unrelated to this task. Now validate. The default Terraform is 1.3.10, which is too old for the `validation` block syntax changes, but `validation` blocks have been supported since 0.13 — let me try with the default first, and fall back to `mise` if needed.


command: cd /Users/steve.briggs/projects/IAC/terraform/internal-modules/kubernetes/monitoring/otel-collector && terraform init -backend=false 2>&1 | tail -5

description: Initialize terraform without backend to allow validate


content:
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.


command: cd /Users/steve.briggs/projects/IAC/terraform/internal-modules/kubernetes/monitoring/otel-collector && terraform validate 2>&1; echo "exit: $?"

description: Run terraform validate on the module


content:
Success! The configuration is valid.

exit: 0


text: Everything passes. Let me do a final read of the file to confirm the appended variables look exactly right.


content:
100	}
101
102	variable "tags" {
103	  description = "Map of key-vaue pairs to tag created resources with"
104	  type        = map(any)
105	  default     = {}
106	}
107
108	variable "downstream_endpoint" {
109	  description = "When non-empty, swap the terminal exporter from datadog to OTLP, pointed at this endpoint. Used to route through Vector for redaction."
110	  type        = string
111	  default     = ""
112	}
113
114	variable "downstream_protocol" {
115	  description = "Protocol for downstream OTLP exporter. Currently only otlp/grpc supported."
116	  type        = string
117	  default     = "otlp/grpc"
118	  validation {
119	    condition     = contains(["otlp/grpc", "otlp/http"], var.downstream_protocol)
120	    error_message = "downstream_protocol must be one of: otlp/grpc, otlp/http"
121	  }
122	}
123


text:
---

**Status:** DONE

**Lines added to `variables.tf`:** lines 108–122 (15 lines appended after the existing `tags` variable)

**`terraform fmt -check` result:**
- `variables.tf` now exits 0 (clean).
- Note: `lbconfig.tf`, `main.tf`, and `otelconfig.tf` have pre-existing style issues (misaligned `type`/`default` attributes, 4-space indented blocks, unquoted variable name `otel_storage_class_name`). These were present before this task and are out of scope per the constraint to only modify `variables.tf`. The `terraform fmt -diff` run that revealed the diff also applied formatting to `variables.tf` — that incidentally fixed those pre-existing style issues in `variables.tf` itself (alignment on `otel_lb_replicas`, `otel_collector_replicas`, `otel_pv_size`, and the quoted `otel_storage_class_name` variable name). Those are harmless correctness fixes in the file we were already editing.

**`terraform validate` result:** `Success! The configuration is valid.` (exit 0, using default Terraform v1.3.10 — `validation` block syntax is supported since v0.13, no `mise` fallback needed)

**Self-review findings:**
- Both variables are additive with safe defaults (`""` and `"otlp/grpc"` respectively), so no existing callers are broken.
- The `downstream_protocol` validation correctly gates on `["otlp/grpc", "otlp/http"]` matching the spec.
- No perf-tuning variables (`send_batch_max_size`, etc.) were touched.
- The only unexpected side-effect is that `terraform fmt -diff` (run to inspect changes) also wrote formatting fixes to `variables.tf` for pre-existing style debt in that file. Those changes are benign and consistent with what `fmt` would require anyway.