Skip to content
English
  • There are no suggestions because the search field is empty.

Kargo Projects Created via Terraform Not Visible in UI or CLI

Understanding and Resolving Issues with kargo_instance Terraform Resource and local.projects Variable Configuration

When using the kargo_instance Terraform resource to manage project creation, it’s possible for Terraform to report successful application of resources while the corresponding projects do not appear in the Kargo UI or CLI.

This issue commonly stems from how the local.projects variable is constructed, particularly when using yamldecode and jsonencode to generate Kargo project manifests dynamically.

Observed Behavior

  • Terraform plan and apply complete successfully with no reported errors.

  • Kargo projects are not visible via:

    • Kargo UI

    • kargo get projects CLI command

  • The Terraform state file (terraform.tfstate) reflects the resources as applied.

Root Cause

The problem is typically due to how the local.projects block generates keys and values when using Terraform locals.

Here’s the problematic configuration snippet:

 locals {
  kargo_resource_objects = [
    for p in var.projects :
    yamldecode(<<-EOT
      apiVersion: kargo.akuity.io/v1alpha1
      kind: Project
      metadata:
        name: ${p}
    EOT
    )
  ]

  projects = {
    for obj in local.kargo_resource_objects :
    "${obj.apiVersion}/${obj.kind}/${try(obj.metadata.namespace, "")}/${obj.metadata.name}" => jsonencode(obj)
  }
}
 

The issue lies in the namespace resolution (try(obj.metadata.namespace, "")) — the empty namespace ("") in the key generation can lead to misalignment with what the Kargo provider expects. As a result, the resources are "applied" in Terraform but never reach the actual API server.

In other words, Terraform sees the locals as valid inputs, but the Kargo provider doesn't submit a valid resource definition to the control plane due to malformed or incomplete keys.

Resolution Steps

  1. Update the locals block to correctly handle namespaces and serialization:

    locals {
    kargo_resource_objects = [
    for p in var.projects :
    yamldecode(<<-EOT
    apiVersion: kargo.akuity.io/v1alpha1
    kind: Project
    metadata:
    name: ${p}
    namespace: kargo-system
    EOT
    )
    ]

    projects = {
    for obj in local.kargo_resource_objects :
    "${obj.apiVersion}/${obj.kind}/${obj.metadata.namespace}/${obj.metadata.name}" => jsonencode(obj)
    }
    }

     

    Key changes:

    • Explicitly set a namespace (e.g., kargo-system).

    • Removed the try() wrapper to ensure valid key formation.

    • Guaranteed that every resource includes both apiVersion, kind, and namespace keys for correct API mapping.

  2. Re-run Terraform Apply 

    terraform plan
    terraform apply
  3. Verify the Project Exists

    • Via CLI:

      kargo get projects

    • Via UI:
      Navigate to the Projects tab in the Kargo UI — the newly created projects should now appear.

  4. Optional Validation
    Confirm that the Kargo controller has received the resource definitions: 

    kubectl get projects.kargo.akuity.io -A

Additional Notes

  • Terraform may not report validation issues when locals or dynamic resources generate invalid or incomplete manifests — it only verifies syntax and HCL structure, not the correctness of the YAML for the API.

  • Always ensure that:

    • apiVersion and kind are correct.

    • metadata.namespace is explicitly defined.

    • The resulting jsonencode() output matches the schema expected by the Kargo API.