> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ubiquex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# sync Flux Kustomization

> Register a GitOps kustomization with Flux — the same sync block, a different controller.

Flux and ArgoCD solve the same problem — continuous GitOps reconciliation from a git repository to a Kubernetes cluster — with different architectures and different operator communities. Flux uses a `Kustomization` CRD from the `kustomize.toolkit.fluxcd.io/v1` API; ArgoCD uses an `Application` CRD from `argoproj.io/v1alpha1`. In ubx, the difference is just the type label on the `sync` block: `sync "flux"` instead of `sync "argocd"`. The attribute shapes are identical — `repo`, `path`, `target`, `namespace`, `values` — because ubx's `sync` abstraction treats both controllers as implementations of the same interface. Switch your GitOps controller, change one word in your `.iac` file.

## What you'll learn

* How `sync "flux"` emits a Flux `Kustomization` CRD
* How `sync "flux"` and `sync "argocd"` share the same attribute shape
* When to choose Flux vs ArgoCD (and why ubx makes the switch trivial)

***

## Why this matters

<Info>
  ubx's `sync` abstraction is controller-agnostic. A team that starts with ArgoCD and later migrates to Flux changes one word in each sync block. The infrastructure provisioning, the Pending type wiring, the sequencing — nothing else changes.
</Info>

***

## The source code

<CodeGroup>
  ```hcl main.iac theme={"theme":"css-variables"}
  # sync "flux" emits a kustomize.toolkit.fluxcd.io/v1 Kustomization CRD.
  # Attributes are identical to sync "argocd" — only the type label differs.
  sync "flux" "platform" {
    repo      = "https://github.com/myorg/platform"
    path      = "./clusters/${input.env}"
    namespace = "flux-system"
  }
  ```

  ```hcl inputs.iac theme={"theme":"css-variables"}
  input "env" {
    type    = "string"
    default = "prod"
  }
  ```

  ```hcl ubx.iac theme={"theme":"css-variables"}
  ubx {
    name    = "sync-flux-kustomization"
    runtime = "typescript"
    stacks  = ["dev", "staging", "prod"]
  }

  backend "s3" {
    bucket = "my-ubx-state"
    region = "us-east-1"
    key    = "${stack}/sync-flux.tfstate"
  }
  ```
</CodeGroup>

***

## How it works

<Steps>
  <Step title="sync 'flux' emits a Flux Kustomization CRD">
    The type label `"flux"` tells ubx to generate a `kustomize.toolkit.fluxcd.io/v1/Kustomization` object instead of an ArgoCD `Application`. The `repo`, `path`, and `namespace` attributes map to the corresponding Flux Kustomization spec fields.
  </Step>

  <Step title="The attribute model is identical to sync 'argocd'">
    Both sync types use the same `repo`, `path`, `target`, `namespace`, and `values` attributes — ubx normalises the differences between the two CRD schemas. The `values` map compiles to Flux's `spec.postBuild.substitute` substitution variables rather than ArgoCD's Helm parameters.
  </Step>

  <Step title="Pending values sequence the CRD exactly as with ArgoCD">
    If any value in `values` is `Pending<T>`, the Kustomization CRD creation is sequenced after the pending dependency — identical behaviour to `sync "argocd"`. The Pending type system is controller-agnostic.
  </Step>
</Steps>

***

## sync "argocd" vs sync "flux" — side by side

```hcl theme={"theme":"css-variables"}
# ArgoCD
sync "argocd" "platform" {
  repo      = "https://github.com/myorg/platform"
  path      = "./clusters/prod"
  target    = "https://kubernetes.default.svc"
  namespace = "argocd"
}

# Flux — one word changes
sync "flux" "platform" {
  repo      = "https://github.com/myorg/platform"
  path      = "./clusters/prod"
  namespace = "flux-system"
}
```

The `target` attribute is optional for Flux (defaults to the in-cluster endpoint). Otherwise the blocks are identical.

***

## What ubx generates

<CodeGroup>
  ```typescript index.ts theme={"theme":"css-variables"}
  // Generated by ubx — do not edit
  import * as pulumi from "@pulumi/pulumi";
  import * as k8s from "@pulumi/kubernetes";

  const config = new pulumi.Config();
  const env = config.get("env") || "prod";

  const platform = new k8s.apiextensions.CustomResource("platform", {
      apiVersion: "kustomize.toolkit.fluxcd.io/v1",
      kind: "Kustomization",
      metadata: { name: "platform", namespace: "flux-system" },
      spec: {
          interval: "10m",
          sourceRef: {
              kind: "GitRepository",
              name: "platform",
          },
          path: `./clusters/${env}`,
          prune: true,
      },
  });
  ```

  ```python __main__.py theme={"theme":"css-variables"}
  # Generated by ubx — do not edit
  import pulumi
  import pulumi_kubernetes as k8s

  config = pulumi.Config()
  env = config.get("env") or "prod"

  platform = k8s.apiextensions.CustomResource("platform",
      api_version="kustomize.toolkit.fluxcd.io/v1",
      kind="Kustomization",
      metadata={"name": "platform", "namespace": "flux-system"},
      spec={
          "interval": "10m",
          "sourceRef": {"kind": "GitRepository", "name": "platform"},
          "path": f"./clusters/{env}",
          "prune": True,
      },
  )
  ```

  ```go main.go theme={"theme":"css-variables"}
  // Generated by ubx — do not edit
  package main

  import (
      "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/apiextensions"
      "github.com/pulumi/pulumi/sdk/v3/go/pulumi"
      "github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
  )

  func main() {
      pulumi.Run(func(ctx *pulumi.Context) error {
          cfg := config.New(ctx, "")
          env := cfg.Get("env")
          if env == "" { env = "prod" }

          _, err := apiextensions.NewCustomResource(ctx, "platform", &apiextensions.CustomResourceArgs{
              ApiVersion: pulumi.String("kustomize.toolkit.fluxcd.io/v1"),
              Kind:       pulumi.String("Kustomization"),
              Metadata:   pulumi.Map{"name": pulumi.String("platform"), "namespace": pulumi.String("flux-system")},
              OtherFields: pulumi.Map{
                  "spec": pulumi.Map{
                      "interval":   pulumi.String("10m"),
                      "sourceRef":  pulumi.Map{"kind": pulumi.String("GitRepository"), "name": pulumi.String("platform")},
                      "path":       pulumi.Sprintf("./clusters/%s", env),
                      "prune":      pulumi.Bool(true),
                  },
              },
          })
          return err
      })
  }
  ```
</CodeGroup>

***

## Common mistakes

<Warning>
  `sync "flux"` requires Flux to be installed in the cluster and a `GitRepository` source object to already exist with the same name as the Kustomization. The `repo` attribute in ubx's `sync` block is a convenience — Flux actually reads from its `GitRepository` CRD, not directly from the URL. Ensure your Flux bootstrap has created the `GitRepository` source before applying this sync block.
</Warning>

<Tip>
  The `path` attribute supports string interpolation — `"./clusters/${input.env}"` is valid and useful for environment-specific manifest paths. This is one of the few places in ubx where an interpolated string goes directly into a CRD field rather than a resource attribute.
</Tip>

***

## Run it

```bash theme={"theme":"css-variables"}
ubx validate   # type-checks the sync block
ubx plan       # requires Kubernetes credentials with Flux installed
ubx apply      # creates the Flux Kustomization CRD
```

***

## What you learned

<Check>`sync "flux"` emits a `kustomize.toolkit.fluxcd.io/v1/Kustomization` CRD</Check>
<Check>The attribute shape is identical to `sync "argocd"` — switching controllers is a one-word change</Check>
<Check>Flux requires a `GitRepository` source object to exist before the Kustomization can reconcile</Check>

***

## Next steps

<CardGroup cols={2}>
  <Card title="exec block" href="/v1/tutorials/28-exec-block-db-migration">
    Run a command at apply time as part of the resource graph
  </Card>

  <Card title="sync block reference" href="/v1/language/sync">
    Full sync block syntax for both ArgoCD and Flux
  </Card>
</CardGroup>

***

<Info>
  Full runnable example: [github.com/ubiquex/ubx-examples/27-sync-flux-kustomization](https://github.com/ubiquex/ubx-examples/tree/main/27-sync-flux-kustomization)
</Info>
