Install MCPG with Pulumi
Install the MCPG operator and manage gateways with Pulumi — a typed CRD SDK, opinionated components, the config builder, and a CrossGuard policy pack that mirrors the operator's admission rules at preview.
The MCPG Pulumi offering is three packages that deliver the same capabilities as the Terraform suite in a general-purpose language (TypeScript today; Python / Go / C# / Java via multi-language packaging):
| Package | Role |
|---|---|
@mcpg/pulumi-crds | typed CRD resource classes, generated by crd2pulumi from the operator's CRD OpenAPI (all 8 mcpg.dev kinds) |
@mcpg/pulumi | opinionated components — Operator, Gateway, PluginSet, TrustBootstrap, Tenant, McpgStack — plus the config builder |
@mcpg/pulumi-policy | a CrossGuard policy pack mirroring the operator's admission rules at pulumi preview |
Why Pulumi maps cleanly
- The Kubernetes provider does server-side apply by default and awaits
readiness (
pulumi.com/waitFor: condition=Ready) — so the operator-install ordering and gateway readiness are handled for you. - Secrets are encrypted in state by default; ESC is the secret/config backend; the Pulumi Kubernetes Operator gives a Pulumi-native GitOps loop.
Prerequisites
- Node.js + the Pulumi CLI, a Pulumi state backend (Pulumi Cloud or self-managed S3/GCS/Azure-Blob/filesystem), and a kubeconfig.
npm i @mcpg/pulumi @mcpg/pulumi-crds(the policy pack is referenced atpreviewtime, not imported into your program).- cert-manager installed in the cluster. The
Operatorcomponent defaultscertManager.enabled=true(the admission webhook fails closed and needs real TLS); override viaoperator.values.certManagerfor BYO TLS.
Beta note: the operator chart is not yet published to
oci://ghcr.io/mcpg-dev/source-code/charts(reserved, not live). For now setoperator.chartRepoto a local path or a private OCI mirror.
Quick start
import { McpgStack } from "@mcpg/pulumi";
export const stack = new McpgStack("prod", {
operator: { chartVersion: "0.1.0" }, // installs the operator
gateway: {
image: { repository: "ghcr.io/mcpg-dev/gateway", tag: "v1.0.0-rc.17" },
governance: { audit: { sinks: [{ kind: "dev.mcpg.builtin.audit.local-file" }] } },
},
});
pulumi up installs the operator (CRDs as first-class resources,
crd.install=false), seeds cluster-default trust, and creates a gateway that
waits for Ready. The same program runs from Python/Go/C#/Java once the
multi-language SDKs are published.
Components
Operator
Installs the chart via kubernetes.helm.v4.Chart (SSA) with the CRDs applied as
explicit resources — closing the Helm-doesn't-upgrade-CRDs hazard.
import { Operator } from "@mcpg/pulumi";
const op = new Operator("mcpg", { chartVersion: "0.1.0", namespace: "mcpg-system" });
Gateway + the config builder
Typed sections plus an extraConfig escape hatch merged last; readiness via the
built-in waitFor annotation.
import { Gateway } from "@mcpg/pulumi";
new Gateway("orders", {
namespace: "mcpg-system",
image: { repository: "…", tag: "…" },
replicas: 3,
governance: { audit: { sinks: [{ kind: "dev.mcpg.builtin.audit.local-file" }] } },
plugins: [{ id: "db.read", source: { oci: "plugins/sql:1.4.2" }, enforce: true }],
extraConfig: { /* anything not yet typed */ },
}, { dependsOn: op });
The assembled spec.config is the gateway's own AppConfig — see the
configuration reference.
Tenant
Namespace + NetworkPolicy isolation + plugin-set + gateway — fan out a fleet with a plain loop:
import { Tenant } from "@mcpg/pulumi";
for (const t of tenants) {
new Tenant(t.name, { tenantName: t.name, gateway: { image: t.image }, pluginSet: { entries: [] } });
}
See the multi-tenant deployments guide for the tenant model these components implement.
Typed CRD SDK
@mcpg/pulumi-crds gives you the raw typed classes when you need them:
import { mcpg } from "@mcpg/pulumi-crds";
new mcpg.v1alpha2.MCPGGateway("orders", {
metadata: { namespace: "mcpg-system" },
spec: { image: { repository: "…", tag: "…" }, config: {} },
});
Regenerate after a CRD change: nx run pulumi-mcpg-crds:codegen (the
codegen-check drift gate keeps it in sync in CI). The CRD set is documented in
the operator CRD reference.
Policy (CrossGuard)
Enforce the operator's admission rules before deploy:
pulumi preview --policy-pack node_modules/@mcpg/pulumi-policy
Rules: gateway workload-identity one-of; plugin digest-or-cosign with an anchored
certificateIdentityRegexp; plugin-set entry-id uniqueness; revocation-list
64-hex + no duplicates. The same pure validators feed MCPG's cross-tool contract
test, so they never drift from admission.
Commands (Nx)
nx run pulumi-mcpg-crds:codegen # regenerate the typed SDK
nx run pulumi-mcpg-crds:codegen-check # drift gate
nx run pulumi-mcpg:typecheck # tsc --noEmit
nx run pulumi-mcpg-policy:test # validator unit tests
Compatibility
@mcpg/pulumi* | Operator chart | CRD apiVersion | Pulumi | @pulumi/kubernetes |
|---|---|---|---|---|
0.x | 0.1.x | v1alpha2 | ≥ 3.x | ≥ v4 |
Secrets, GitOps, day-2
- Secrets — reference K8s Secrets by name; unavoidable values use
pulumi.secret()(encrypted in state). ESC projects signing keys / TLS / tokens from Vault / cloud KMS. - GitOps — run the program in-cluster via the Pulumi Kubernetes Operator
(
StackCRD), or have Argo CD / Flux sync rendered manifests. - Day-2 / DR — declarative input edits; the Automation API scripts DR ordering (CRDs → operator → trust → CRs) and CR snapshot/restore.
See also
- Install MCPG with Terraform — the Terraform module suite
- Terraform provider — typed resources, plan-time validation
- OpenTofu — OSI-approved IaC with state encryption
- Operator CRD reference — the 8
mcpg.devCRDs