-
Notifications
You must be signed in to change notification settings - Fork 0
added helm resource #471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
added helm resource #471
Conversation
WalkthroughIntroduces a new Helm module for Kubernetes (k8s flavor v0.2) with a facet definition, Terraform providers, variables, Helm release deployment logic, and outputs exposing Helm release metadata and status. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant Facet as Facet (facets.yaml)
participant TF as Terraform Module
participant Helm as Provider: helm3
participant K8s as Provider: kubernetes
Note over Facet: Defines spec schema (helm + values) and inputs
User->>Facet: Provide spec (chart/repo/version/namespace/values)
Facet->>TF: Pass instance, environment, inputs
TF->>TF: Build locals (static/secret env, values)
TF->>Helm: helm_release(external_helm_charts)
Helm->>K8s: Create namespace (if needed)
Helm->>K8s: Install/upgrade Helm chart
K8s-->>Helm: Status/metadata
Helm-->>TF: Release metadata/status
TF-->>User: Outputs: metadata, status
Note over TF: cleanup_on_fail, wait, timeout handling
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
🧹 Nitpick comments (8)
modules/helm/k8s/0.2/versions.tf (1)
10-11: Consider tightening the Terraform version constraint.
>= 0.13is extremely broad and allows pre-1.0 releases with different behaviors. Consider pinning to the tested major/minor range (for example,>= 1.3, < 2.0) to avoid unexpected init/plan differences across environments. If you already validated with a specific 1.x series, lock that in.Would you like me to propose exact version constraints for both Terraform and the Helm/Kubernetes providers based on your currently tested versions?
modules/helm/k8s/0.2/variables.tf (3)
6-9: Avoid defaultinginstance_nameto a placeholder.A default like
"test_instance"can cause accidental cross-env name collisions. Prefer making it required (no default) or generate it upstream.
18-21:inputsappears unused in this module.If not used, drop it to reduce surface area; if it is planned, reference it in
main.tf.
1-4: Enforce a strict schema forvar.instanceinstead of usinganyand guard direct indexingThe untyped
variable "instance"inmodules/helm/k8s/0.2/variables.tf(lines 1–4) allows arbitrary values, but we have unguarded reads like:
chart = var.instance.spec["helm"]["chart"]inmodules/helm/k8s/0.2/main.tf:20variables = lookup(var.instance.spec, "env", [])(guarded here, but others are not)To catch missing or misspelled attributes at plan time and avoid runtime errors, replace the
anytype with a minimalobjectschema that mirrors the expected shape, and then you can safely use direct indexing on required fields (or continue to uselookup()for optional ones).Locations to update:
- modules/helm/k8s/0.2/variables.tf (lines 1–4)
- modules/helm/k8s/0.2/main.tf (lines 19–23)
Proposed diff for
variables.tf:variable "instance" { - type = any - default = {} + type = object({ + spec = object({ + helm = object({ + chart = string + namespace = optional(string, var.environment.namespace) + timeout = optional(number, 300) + wait = optional(bool, true) + repository = optional(string, "") + version = optional(string, "") + recreate_pods = optional(bool, false) + repository_username = optional(string, null) + repository_password = optional(string, null) + }) + env = optional(list(object({ key = string, value = string, type = string })), []) + values = optional(map(any), {}) + }) + }) }And for
main.tf, either:• Rely on direct indexing for required fields now enforced by the type:
chart = var.instance.spec.helm.chart namespace = var.instance.spec.helm.namespace …• Or wrap all reads in
lookup()/try()if you’d rather keepanyand handle missing keys at runtime:- chart = var.instance.spec["helm"]["chart"] + chart = lookup(var.instance.spec["helm"], "chart", "")Let me know if you’d like a full typed-schema proposal for other modules’
instancevariables or any adjustments here.modules/helm/k8s/0.2/facets.yaml (3)
45-47: Typo in error message: “hypens” → “hyphens”; also consider restricting to lowercase for chart names.Helm chart names conventionally use lowercase alphanumeric and hyphens. Fix the typo and optionally update the regex to enforce lowercase to match common constraints.
- pattern: ^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*[a-zA-Z0-9]$ - x-ui-error-message: Invalid format. Only alphabets, numbers and hypens are - allowed + pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$' + x-ui-error-message: Invalid format. Only lowercase letters, numbers, and hyphens are allowed.
26-29: Provider naming inconsistency across layers.The facet lists provider names
kubernetes,helm,kubernetes-alpha, butversions.tfuses a provider namedhelm3. Align the naming to avoid confusion in orchestration and provider wiring docs.
10-12: Validate more thanvariables.tfin IAC gates.Given the logic concentrated in
main.tfand schema in this file, include them in validation to catch drifts early.iac: validated_files: - - variables.tf + - variables.tf + - main.tf + - facets.yamlmodules/helm/k8s/0.2/outputs.tf (1)
1-6:output_interfacesis declared but unused.If this is a convention for consumers, keep it; otherwise, drop it to reduce noise.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (5)
modules/helm/k8s/0.2/facets.yaml(1 hunks)modules/helm/k8s/0.2/main.tf(1 hunks)modules/helm/k8s/0.2/outputs.tf(1 hunks)modules/helm/k8s/0.2/variables.tf(1 hunks)modules/helm/k8s/0.2/versions.tf(1 hunks)
| pattern: ^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$ | ||
| x-ui-error-message: Invalid namespace format. The namespace must be DNS-compliant, | ||
| containing only letters, numbers, and hyphens, and must not start or end | ||
| with a hyphen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Namespace regex allows uppercase and violates k8s DNS-1123 label rules.
Kubernetes namespaces must be lowercase alphanumeric plus hyphen, start/end with alphanumeric, max 63 chars. Update the pattern accordingly.
- pattern: ^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$
- x-ui-error-message: Invalid namespace format. The namespace must be DNS-compliant,
- containing only letters, numbers, and hyphens, and must not start or end
- with a hyphen
+ pattern: '^[a-z0-9]([-a-z0-9]*[a-z0-9])?$'
+ x-ui-error-message: Invalid namespace format. Must be DNS-1123 compliant: lowercase letters,
+ numbers, and hyphens; must start and end with an alphanumeric character.Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In modules/helm/k8s/0.2/facets.yaml around lines 66 to 69, the current regex
allows uppercase letters and doesn't enforce Kubernetes DNS-1123 label rules;
replace the pattern with one that enforces lowercase letters, numbers and
hyphens only, ensures the name starts and ends with an alphanumeric character,
and limits length to 1–63 characters (e.g. use a pattern like
^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$), and adjust the x-ui-error-message to
mention lowercase and the 63-character limit.
| required: | ||
| - helm | ||
| - values | ||
| sample: | ||
| $schema: https://facets-cloud.github.io/facets-schemas/schemas/helm/helm.schema.json | ||
| kind: helm | ||
| flavor: k8s | ||
| disabled: true | ||
| metadata: {} | ||
| version: '0.2' | ||
| spec: | ||
| helm: | ||
| repository: https://helm.datadoghq.com | ||
| chart: datadog | ||
| namespace: default | ||
| wait: false | ||
| values: null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Schema requires values but sample sets it to null; this will fail validation.
You mark values as required and typed object, yet the sample has values: null and main.tf explicitly supports null. Relax the schema or drop values from required.
Option A (allow nulls):
- values:
- type: object
+ values:
+ type:
+ - object
+ - 'null'
@@
- required:
- - helm
- - values
+ required:
+ - helmOption B (if you want to require non-null values): update sample and main.tf to align.
📝 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.
| required: | |
| - helm | |
| - values | |
| sample: | |
| $schema: https://facets-cloud.github.io/facets-schemas/schemas/helm/helm.schema.json | |
| kind: helm | |
| flavor: k8s | |
| disabled: true | |
| metadata: {} | |
| version: '0.2' | |
| spec: | |
| helm: | |
| repository: https://helm.datadoghq.com | |
| chart: datadog | |
| namespace: default | |
| wait: false | |
| values: null | |
| # In your JSON Schema definitions (e.g. under `properties:`) | |
| values: | |
| type: | |
| - object | |
| - 'null' | |
| # In the same file, replace the `required` block: | |
| required: | |
| - helm | |
| # (The rest of the sample stays unchanged:) | |
| sample: | |
| $schema: https://facets-cloud.github.io/facets-schemas/schemas/helm/helm.schema.json | |
| kind: helm | |
| flavor: k8s | |
| disabled: true | |
| metadata: {} | |
| version: '0.2' | |
| spec: | |
| helm: | |
| repository: https://helm.datadoghq.com | |
| chart: datadog | |
| namespace: default | |
| wait: false | |
| values: null |
🤖 Prompt for AI Agents
In modules/helm/k8s/0.2/facets.yaml around lines 101 to 117, the schema marks
`values` as required and object-typed but the sample sets `values: null`,
causing validation failure; fix by either A) allowing nulls in the schema (make
the `values` type accept null, e.g., object OR null) or remove `values` from the
required list so null is permitted, or B) if `values` must be non-null, update
the sample to provide a valid object for `values` and adjust main.tf to disallow
nulls consistently.
| variables = lookup(var.instance.spec, "env", []) | ||
| # filter out static variables | ||
| static_variables = toset([for x in local.variables : x if x["type"] == "static"]) | ||
| # filter out static variables | ||
| dynamic_variables_raw = toset([for x in local.variables : x if x["type"] == "secret"]) | ||
| # replace the value | ||
| dynamic_variables = toset([ | ||
| for x in local.dynamic_variables_raw : { | ||
| name = x["name"], | ||
| default = lookup(var.environment.secrets, x["attribute"], "Invalid Secret Reference") | ||
| } | ||
| ]) | ||
| all_variables = setunion(local.static_variables, local.dynamic_variables) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guard nested attribute access and avoid set unions across heterogeneous object shapes.
Directly accessing var.instance.spec and var.environment.secrets will error when absent. Also, setunion across objects with different shapes (static vs. dynamic) can fail type unification. Use try()/lookup() and keep lists unless you specifically need sets.
Apply this refactor to harden locals:
locals {
-
- variables = lookup(var.instance.spec, "env", [])
- # filter out static variables
- static_variables = toset([for x in local.variables : x if x["type"] == "static"])
- # filter out static variables
- dynamic_variables_raw = toset([for x in local.variables : x if x["type"] == "secret"])
- # replace the value
- dynamic_variables = toset([
- for x in local.dynamic_variables_raw : {
- name = x["name"],
- default = lookup(var.environment.secrets, x["attribute"], "Invalid Secret Reference")
- }
- ])
- all_variables = setunion(local.static_variables, local.dynamic_variables)
+ spec = try(var.instance.spec, {})
+ helm_spec = try(local.spec.helm, {})
+ variables = try(local.spec.env, [])
+
+ # Filter static variables
+ static_variables = [for x in local.variables : x if try(x.type, null) == "static"]
+
+ # Filter secret-backed variables
+ dynamic_variables_raw = [for x in local.variables : x if try(x.type, null) == "secret"]
+
+ # Resolve secret defaults safely (environment.secrets may be absent)
+ dynamic_variables = [
+ for x in local.dynamic_variables_raw : {
+ name = x.name
+ default = lookup(lookup(var.environment, "secrets", {}), x.attribute, "Invalid Secret Reference")
+ }
+ ]
+
+ # Combine without forcing a set of mixed object shapes
+ all_variables = concat(local.static_variables, local.dynamic_variables)
}Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In modules/helm/k8s/0.2/main.tf around lines 3 to 15, the code directly indexes
nested attributes and performs setunion across objects with different shapes
which will break when var.instance.spec or var.environment.secrets are absent
and when static and dynamic objects differ; change to use lookup()/try() to
safely access var.instance.spec and var.environment.secrets with sensible
defaults, keep variables as lists (not sets) while you build/transform them to
maintain consistent object shapes, ensure both static and dynamic entries share
the same key set (e.g., name and value/default) or normalize them into a common
object shape, then concatenate lists (concat()) instead of setunion() or convert
to sets only after normalization if deduping is required, and provide default
fallback strings for missing secret lookups via lookup(var.environment.secrets,
attr, "<missing>").
| provider = "helm3" | ||
| chart = var.instance.spec["helm"]["chart"] | ||
| name = var.instance_name | ||
| namespace = lookup(var.instance.spec["helm"], "namespace", var.environment.namespace) | ||
| timeout = lookup(var.instance.spec["helm"], "timeout", 300) | ||
| create_namespace = true | ||
| wait = lookup(var.instance.spec["helm"], "wait", true) | ||
| repository = lookup(var.instance.spec["helm"], "repository", "") | ||
| version = lookup(var.instance.spec["helm"], "version", "") | ||
| recreate_pods = lookup(var.instance.spec["helm"], "recreate_pods", false) | ||
| repository_username = lookup(var.instance.spec["helm"], "repository_username", null) | ||
| repository_password = lookup(var.instance.spec["helm"], "repository_password", null) | ||
| values = lookup(var.instance.spec, "values", null) != null ? [yamlencode(lookup(var.instance.spec, "values", {}))] : null | ||
| cleanup_on_fail = true | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Fix provider reference and make Helm spec access safe.
- The
providermeta-arg must reference a configured provider block (e.g.,helmorhelm.alias), not a string. Remove it here and let the root module pass the provider mapping, or switch toprovider = helm.some_aliasif you declare it. - Use the guarded locals to read Helm settings without crashing when keys are absent.
- Optional: align default
waitwith the facet sample (false) to avoid surprises.
resource "helm_release" "external_helm_charts" {
- provider = "helm3"
- chart = var.instance.spec["helm"]["chart"]
- name = var.instance_name
- namespace = lookup(var.instance.spec["helm"], "namespace", var.environment.namespace)
- timeout = lookup(var.instance.spec["helm"], "timeout", 300)
- create_namespace = true
- wait = lookup(var.instance.spec["helm"], "wait", true)
- repository = lookup(var.instance.spec["helm"], "repository", "")
- version = lookup(var.instance.spec["helm"], "version", "")
- recreate_pods = lookup(var.instance.spec["helm"], "recreate_pods", false)
- repository_username = lookup(var.instance.spec["helm"], "repository_username", null)
- repository_password = lookup(var.instance.spec["helm"], "repository_password", null)
- values = lookup(var.instance.spec, "values", null) != null ? [yamlencode(lookup(var.instance.spec, "values", {}))] : null
- cleanup_on_fail = true
+ # provider = helm # (optional) let root module pass provider; uncomment and set alias if needed
+ chart = local.helm_spec.chart
+ name = var.instance_name
+ namespace = lookup(local.helm_spec, "namespace", lookup(var.environment, "namespace", "default"))
+ timeout = lookup(local.helm_spec, "timeout", 300)
+ create_namespace = true
+ wait = lookup(local.helm_spec, "wait", true)
+ repository = lookup(local.helm_spec, "repository", "")
+ version = lookup(local.helm_spec, "version", "")
+ recreate_pods = lookup(local.helm_spec, "recreate_pods", false)
+ repository_username = lookup(local.helm_spec, "repository_username", null)
+ repository_password = lookup(local.helm_spec, "repository_password", null)
+ values = try(local.spec.values, null) != null ? [yamlencode(local.spec.values)] : null
+ cleanup_on_fail = true
}- If you intend to keep an aliased provider (e.g.,
helm3), addprovider "helm" { alias = "v3" }in the root and useprovider = helm.v3here, and adjustrequired_providerstohelm = { source = "hashicorp/helm" }inversions.tf. - Confirm whether
waitdefault should befalseto match the facet sample (values.wait: false).
🏁 Script executed:
#!/bin/bash
set -e
# Inspect for locals block within the helm module
echo ">>> Checking for locals blocks in modules/helm/k8s/0.2/main.tf"
rg -n 'locals' -C3 modules/helm/k8s/0.2/main.tf || echo "No locals block found in this file"
# Search for any references to helm_spec throughout the repo
echo ">>> Searching for 'helm_spec' references across the repository"
rg -n 'helm_spec' -C3 . || echo "No occurrences of 'helm_spec' found"Length of output: 544
Fix missing local.helm_spec definition and correct provider usage
The suggested diff references local.helm_spec, but no such local is defined in modules/helm/k8s/0.2/main.tf. To implement these changes safely:
• Add a locals block at the top of modules/helm/k8s/0.2/main.tf:
locals {
# pull the Helm-specific settings, or use an empty object if absent
helm_spec = lookup(var.instance.spec, "helm", {})
# pull any top-level values, or default to empty map
spec_values = lookup(var.instance.spec, "values", {})
}• In the helm_release.external_helm_charts resource (lines 19–33), replace all lookup(var.instance.spec["helm"], …) calls with lookup(local.helm_spec, …) and change the values argument to:
values = length(local.spec_values) > 0 ? [yamlencode(local.spec_values)] : null• Remove the hard-coded provider = "helm3" meta-arg. Either:
- Omit the
providersetting so the root module’s provider mapping applies, or - Declare an aliased provider in the root (e.g.
provider "helm" { alias = "v3" }andrequired_providers { helm = { source = "hashicorp/helm" } }) and reference it here asprovider = helm.v3.
• Decide on awaitdefault (truevs.false) to match your facet sample (values.wait = falsevs. current defaulttrue).
Revised snippet for the resource:
resource "helm_release" "external_helm_charts" {
- provider = "helm3"
- chart = var.instance.spec["helm"]["chart"]
+ # provider = helm.v3 # uncomment if using an aliased provider
+ chart = local.helm_spec.chart
name = var.instance_name
namespace = lookup(local.helm_spec, "namespace", lookup(var.environment, "namespace", "default"))
timeout = lookup(local.helm_spec, "timeout", 300)
create_namespace = true
wait = lookup(local.helm_spec, "wait", true)
repository = lookup(local.helm_spec, "repository", "")
version = lookup(local.helm_spec, "version", "")
recreate_pods = lookup(local.helm_spec, "recreate_pods", false)
repository_username = lookup(local.helm_spec, "repository_username", null)
repository_password = lookup(local.helm_spec, "repository_password", null)
- values = lookup(var.instance.spec, "values", null) != null ? [yamlencode(lookup(var.instance.spec, "values", {}))] : null
+ values = length(local.spec_values) > 0 ? [yamlencode(local.spec_values)] : null
cleanup_on_fail = true
}🤖 Prompt for AI Agents
In modules/helm/k8s/0.2/main.tf around lines 19 to 33, the code references
local.helm_spec which is not defined and hard-codes provider = "helm3"; fix by
adding a locals block at the top that defines helm_spec =
lookup(var.instance.spec, "helm", {}) and spec_values =
lookup(var.instance.spec, "values", {}), replace all
lookup(var.instance.spec["helm"], ...) calls in the
helm_release.external_helm_charts resource with lookup(local.helm_spec, ...),
change the values argument to use local.spec_values (e.g. values =
length(local.spec_values) > 0 ? [yamlencode(local.spec_values)] : null), and
remove the hard-coded provider meta-arg (or instead reference an aliased
provider declared in the root module such as provider = helm.v3) and ensure the
wait default is set consistently with your facet (choose true or false).
| output "metadata" { | ||
| value = helm_release.external_helm_charts.metadata | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
helm_release doesn’t expose a metadata attribute; construct a metadata map instead.
The Helm provider’s helm_release resource exports fields like name, namespace, chart, version, status, etc., but not a single metadata map. Building your own avoids plan/apply failures.
-output "metadata" {
- value = helm_release.external_helm_charts.metadata
-}
+output "metadata" {
+ value = {
+ name = helm_release.external_helm_charts.name
+ namespace = helm_release.external_helm_charts.namespace
+ chart = helm_release.external_helm_charts.chart
+ version = helm_release.external_helm_charts.version
+ }
+}📝 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.
| output "metadata" { | |
| value = helm_release.external_helm_charts.metadata | |
| } | |
| output "metadata" { | |
| value = { | |
| name = helm_release.external_helm_charts.name | |
| namespace = helm_release.external_helm_charts.namespace | |
| chart = helm_release.external_helm_charts.chart | |
| version = helm_release.external_helm_charts.version | |
| } | |
| } |
🤖 Prompt for AI Agents
In modules/helm/k8s/0.2/outputs.tf around lines 8 to 10, the output references a
non-existent helm_release.external_helm_charts.metadata attribute; replace it by
constructing and returning a map of metadata using existing attributes (for
example name, namespace, chart, version, status, and any other exported fields
you need) — e.g., build a map literal that pulls
helm_release.external_helm_charts.name, .namespace, .chart, .version, .status,
etc., and output that instead so Terraform plan/apply won’t fail.
| variable "environment" { | ||
| type = any | ||
| default = { | ||
| namespace = "default" | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default environment lacks secrets; downstream attribute access will crash.
main.tf reads var.environment.secrets. With the current default, var.environment.secrets is undefined and will trigger an evaluation error. Add a default empty map for secrets.
variable "environment" {
type = any
default = {
namespace = "default"
+ secrets = {}
}
}🤖 Prompt for AI Agents
In modules/helm/k8s/0.2/variables.tf around lines 11 to 16, the variable
"environment" default lacks a "secrets" key which causes var.environment.secrets
to be undefined downstream; update the default value to include a secrets
attribute (empty map) so the structure matches expectations (e.g., add secrets =
{} inside the default map) and ensure the variable type still accepts that
shape.
| helm3 = { | ||
| source = "hashicorp/helm3" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the official Helm provider source and local name; hashicorp/helm3 is invalid.
Terraform’s official Helm provider is hashicorp/helm, and the local name should match how you reference the provider elsewhere. Using helm3 here plus a string literal provider reference in resources will fail provider wiring at plan time.
Apply this diff to align with the official provider:
required_providers {
- helm3 = {
- source = "hashicorp/helm3"
- }
+ helm = {
+ source = "hashicorp/helm"
+ }
kubernetes = {
source = "hashicorp/kubernetes"
}
}📝 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.
| helm3 = { | |
| source = "hashicorp/helm3" | |
| } | |
| required_providers { | |
| helm = { | |
| source = "hashicorp/helm" | |
| } | |
| kubernetes = { | |
| source = "hashicorp/kubernetes" | |
| } | |
| } |
🤖 Prompt for AI Agents
In modules/helm/k8s/0.2/versions.tf around lines 3 to 5, the provider source and
local name are incorrect: replace the invalid "hashicorp/helm3" and local name
"helm3" with the official provider source "hashicorp/helm" and a local name that
matches how the provider is referenced elsewhere in the module (e.g., "helm" if
resources refer to provider.helm); update any provider aliases/references in the
module to match the new local name so Terraform can wire the provider correctly
at plan time.
| @@ -0,0 +1,33 @@ | |||
| locals { | |||
|
|
|||
| variables = lookup(var.instance.spec, "env", []) | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dont have this, variables, static_variables, dynamic_variables_raw etc
| default = {} | ||
| } | ||
|
|
||
| variable "instance_name" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ask mcp to validate the variables.tf file
|
Pending for iac release |

Description
Related issues
Type of change
Checklist
developbranchTesting
Reviewer instructions
Summary by CodeRabbit