Jsonnet apps can be deployed with ArgoCD, but they need to be converted to Kubernetes manifests first.

ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes. It watches a Git repository for changes to desired application state (Kubernetes manifests) and automatically applies those changes to a cluster. When you want to deploy applications defined in Jsonnet, you need a way to translate those Jsonnet files into standard Kubernetes YAML manifests that ArgoCD can understand.

Let’s see this in action. Imagine we have a simple Jsonnet file, app.jsonnet:

local appName = 'my-nginx-app';
local replicas = 2;

{
  apiVersion: 'apps/v1',
  kind: 'Deployment',
  metadata: {
    name: appName,
    labels: {
      app: appName,
    },
  },
  spec: {
    replicas: replicas,
    selector: {
      matchLabels: {
        app: appName,
      },
    },
    template: {
      metadata: {
        labels: {
          app: appName,
        },
      },
      spec: {
        containers: [
          {
            name: appName,
            image: 'nginx:latest',
            ports: [
              {
                containerPort: 80,
              },
            ],
          },
        ],
      },
    },
  },
}

This Jsonnet code defines a Kubernetes Deployment for a simple Nginx application. To deploy this with ArgoCD, we need to generate the YAML.

The core problem Jsonnet solves is the DRY (Don’t Repeat Yourself) principle for Kubernetes configurations. Instead of writing repetitive YAML, you can define reusable components, functions, and variables. For example, you could have a deployment.libsonnet file that defines a generic deployment template, and then in your app.jsonnet, you simply instantiate that template with specific parameters like appName and replicas.

Here’s how you’d typically integrate this into an ArgoCD workflow:

  1. Local Generation (CI/CD Pipeline): The most common approach is to have a CI/CD pipeline that first runs the Jsonnet compiler (jsonnet) to generate the Kubernetes YAML, and then commits that YAML to a Git repository that ArgoCD monitors.

    • Install Jsonnet:

      # On macOS with Homebrew
      brew install jsonnet
      # Or download from releases: https://github.com/google/jsonnet/releases
      
    • Compile Jsonnet to YAML:

      jsonnet app.jsonnet > app.yaml
      

      This command takes your app.jsonnet file and outputs the equivalent Kubernetes YAML to app.yaml.

    • Commit app.yaml to Git: Add app.yaml to your Git repository and commit it.

  2. ArgoCD Application: Create an ArgoCD Application resource that points to your Git repository.

    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: my-jsonnet-app
      namespace: argocd
    spec:
      project: default
      source:
        repoURL: 'https://github.com/your-username/your-repo.git' # Replace with your repo URL
        path: 'path/to/your/manifests' # Directory containing app.yaml
        targetRevision: HEAD
      destination:
        server: 'https://kubernetes.default.svc'
        namespace: default # Namespace where the app will be deployed
      syncPolicy:
        automated:
          prune: true
          selfHeal: true
    

    When ArgoCD detects changes in the specified Git path, it will apply the app.yaml (generated from Jsonnet) to your cluster.

  3. Direct Jsonnet Integration (Less Common, More Advanced): Some setups might involve custom ArgoCD plugins or sidecars that can directly process Jsonnet. However, the standard and most robust method is to generate YAML first. Tools like ksonnet (though largely superseded by jsonnet itself and other templating tools) or custom build scripts are often used.

The beauty of this is that your Git repository becomes the single source of truth, containing the compiled Kubernetes manifests. ArgoCD just ensures the cluster state matches what’s in Git. Your Jsonnet code lives elsewhere, perhaps in a separate repo or a dedicated directory within the same repo, and is used to generate the manifests that GitOps relies on.

A key advantage of using Jsonnet with ArgoCD is parameterization. You can have a single Jsonnet application definition and generate different configurations (e.g., dev, staging, prod) by passing different parameters.

For instance, if you have a params.jsonnet file:

{
  appName: 'my-nginx-app-prod',
  replicas: 5,
}

You could compile your app.jsonnet using this parameter file:

jsonnet app.jsonnet --ext-str-file params.jsonnet > app-prod.yaml

This allows for sophisticated configuration management where your core application logic is defined once in Jsonnet, and environment-specific details are managed through parameters. ArgoCD then deploys the resulting YAML.

The mental model is: Jsonnet -> YAML Generator -> Git Repo -> ArgoCD -> Kubernetes Cluster.

Most people don’t realize that ArgoCD’s Application resource can be configured to use different sources. While repoURL and path are common, you can also specify helm or kustomize. For Jsonnet, you’re effectively using the path source, but the content of that path is generated YAML. Some advanced users might build custom ArgoCD plugins to directly invoke jsonnet as part of the sync process, but this adds complexity and deviates from the standard GitOps flow of committing declarative manifests.

The next logical step after mastering this is exploring how to manage multiple Jsonnet applications and their dependencies within a single GitOps repository for ArgoCD.

Want structured learning?

Take the full Argocd course →