MCPG
Guides
Guides6 min

Terraform provider for MCPG

The native terraform-provider-mcpg — typed MCPG custom resources with plan-time validation that mirrors the operator's admission webhook, so bad input fails locally before it reaches the cluster.

The native provider manages MCPG custom resources directly against the operator/CRD plane, adding what the module suite can't: it validates your resources at terraform plan using the same rules the operator's admission webhook enforces — so bad input fails locally, before it reaches the cluster.

Status: the provider ships the four core resources with plan-time validation and full CRUD. Fully-typed per-kind attribute schemas (today spec is JSON) and import / data-sources are on the roadmap.

Provider configuration

Auth mirrors the standard kubeconfig chain.

hcl
terraform {
  required_providers {
    mcpg = { source = "mcpg-dev/mcpg" }
  }
}

provider "mcpg" {
  kubeconfig = "~/.kube/config" # optional; falls back to KUBECONFIG / in-cluster
  context    = "prod"           # optional kubeconfig context
}
ArgumentTypeDescription
kubeconfigstring, optionalPath to a kubeconfig file.
contextstring, optionalkubeconfig context to use.

Resources

All four resources share the same shape: a typed kind with a spec supplied as JSON (use jsonencode), validated at plan time. The provider applies them with server-side apply (field manager terraform-provider-mcpg).

ResourceKindScope
mcpg_gatewayMCPGGatewaynamespaced
mcpg_pluginMCPGPlugincluster
mcpg_plugin_setMCPGPluginSetnamespaced
mcpg_revocation_listMCPGRevocationListcluster

The full CRD set the operator reconciles is documented in the operator CRD reference.

Common attributes

AttributeType
namestring, requiredresource name
namespacestringrequired for namespaced kinds; ignored for cluster-scoped
specstring, requiredthe CR spec as JSON (jsonencode({...}))
idstring, computednamespace/name (or name for cluster-scoped)
config_hashstring, computedthe operator's status.configHash, when present (drift signal)

Example

hcl
resource "mcpg_gateway" "orders" {
  name      = "orders"
  namespace = "mcpg-system"
  spec = jsonencode({
    image    = { repository = "ghcr.io/mcpg-dev/gateway", tag = "v1.0.0-rc.17" }
    replicas = 2
    config   = { governance = { audit = { sinks = [{ kind = "dev.mcpg.builtin.audit.local-file" }] } } }
  })
}

resource "mcpg_revocation_list" "default" {
  name = "cluster-default"
  spec = jsonencode({
    version     = 1
    revocations = [{ artifactSha256 = "…64 hex…", reason = "compromised" }]
  })
}

The config block inside a gateway spec is the gateway's own AppConfig — see the configuration reference.

Plan-time validation

terraform plan runs the admission-mirror checks and fails with a clear error when input is invalid — no cluster round-trip needed. The rules:

  • gatewayimage required; workloadIdentity exactly one of aws|gcp|azure|spiffe.
  • plugin — digest-pinned OR cosign identity; cosign certificateIdentityRegexp anchored with ^/$ and compiles; oidcIssuer set when cosign is present.
  • plugin-setentries non-empty; entry ids unique.
  • revocation-listversion == 1; each artifactSha256 is 64 lowercase hex; no duplicates.

These validators are shared with the Pulumi CrossGuard pack and exercised by a cross-tool contract test, so all three surfaces stay aligned with admission.

Commands (Nx)

bash
nx run terraform-provider-mcpg:build   # go build ./...
nx run terraform-provider-mcpg:test    # go test ./...
nx run terraform-provider-mcpg:lint    # gofmt + go vet

Compatibility

ProviderOperator chartCRD apiVersionTerraform / OpenTofu
0.x0.1.xv1alpha2≥ 1.7

A CRD apiVersion bump is a provider minor with a regenerated schema; a breaking CRD change is a major.

Module suite vs provider

Module suiteNative provider
LanguageHCLHCL (provider in Go)
Plan-time validationgateway bootmirrors admission at plan
CR applicationkubectl_manifesttyped resources + SSA
Best forthe 80% case, ship-firststrict shops wanting fail-fast plans

Both are fully supported; you can mix them.

See also