flux
Flux CD on Kubernetes, including KCL-based config rendering, SOPS secretencryption, Git commit of rendered manifests, Helmfile-driven operator
install, and reconciliation waiting via the Flux CLI.
Installation
dagger install github.com/stuttgart-things/blueprints/flux@v2.9.2Entrypoint
Return Type
Flux Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
func (m *MyModule) Example() *dagger.Flux {
return dag.
Flux()
}@function
def example() -> dagger.Flux:
return (
dag.flux()
)@func()
example(): Flux {
return dag
.flux()
}Types
Flux 🔗
applyConfig() 🔗
ApplyConfig applies rendered config (non-secret) manifests to the cluster.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| configContent | String ! | - | Config YAML content |
| namespace | String | "flux-system" | Target namespace |
| kubeConfig | Secret ! | - | Kubeconfig secret for cluster access |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
apply-config --config-content string --kube-config env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, configContent string, kubeConfig *dagger.Secret) string {
return dag.
Flux().
Applyconfig(ctx, configContent, kubeConfig)
}@function
async def example(configcontent: str, kubeconfig: dagger.Secret) -> str:
return await (
dag.flux()
.applyconfig(configcontent, kubeconfig)
)@func()
async example(configContent: string, kubeConfig: Secret): Promise<string> {
return dag
.flux()
.applyConfig(configContent, kubeConfig)
}applySecrets() 🔗
ApplySecrets applies secret manifests to the cluster.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| secretContent | String ! | - | Secret YAML content |
| namespace | String | "flux-system" | Target namespace |
| kubeConfig | Secret ! | - | Kubeconfig secret for cluster access |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
apply-secrets --secret-content string --kube-config env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, secretContent string, kubeConfig *dagger.Secret) string {
return dag.
Flux().
Applysecrets(ctx, secretContent, kubeConfig)
}@function
async def example(secretcontent: str, kubeconfig: dagger.Secret) -> str:
return await (
dag.flux()
.applysecrets(secretcontent, kubeconfig)
)@func()
async example(secretContent: string, kubeConfig: Secret): Promise<string> {
return dag
.flux()
.applySecrets(secretContent, kubeConfig)
}bootstrap() 🔗
Bootstrap orchestrates a full Flux bootstrap lifecycle.
Phase order:
0: ValidateAgeKeyPair (secrets module) — fail fast on key mismatch
1: RenderConfig — render all manifests
2: EncryptString (secrets module) — encrypt before committing
3: CommitConfig — push to Git
4: DeployOperator — install operator (Helmfile)
5: ApplyConfig — apply FluxInstance CR
6: ApplySecrets — apply AFTER operator is running
7: VerifySecrets — confirm secrets exist
8: WaitForReconciliation — wait for Flux to reconcile
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| ociSource | String | "ghcr.io/stuttgart-things/kcl-flux-instance:0.3.3" | OCI KCL module source for rendering Flux instance config |
| configParameters | String | - | Additional comma-separated key=value pairs for KCL parameters |
| fluxVersion | String | "2.8.5" | Flux instance version |
| entrypoint | String | "main.k" | KCL entrypoint file name |
| renderSecrets | Boolean | false | Whether KCL should also render Secret manifests |
| gitUsername | Secret | - | Git username for pull secret |
| gitPassword | Secret | - | GitHub token for git pull secret |
| sopsAgeKey | Secret | - | AGE private key for SOPS decryption (applied to cluster) |
| agePublicKey | Secret | - | AGE public key for encrypting secrets before git commit |
| sopsConfig | File | - | SOPS config file (.sops.yaml) |
| kubeConfig | Secret ! | - | Kubeconfig secret for cluster access |
| namespace | String | "flux-system" | Target namespace for Flux |
| repository | String | - | Repository in “owner/repo” format |
| branchName | String | "main" | Branch name for git operations |
| destinationPath | String | "clusters/" | Destination path within the repository |
| gitRef | String | "refs/heads/main" | Git reference for Flux source (e.g., refs/heads/main) |
| gitToken | Secret | - | GitHub token for git operations |
| helmfileRef | String | "helmfile.yaml" | Helmfile reference |
| src | Directory | - | Directory containing the helmfile |
| applySecrets | Boolean | true | Apply rendered secrets to cluster |
| encryptSecrets | Boolean | false | Encrypt secrets with SOPS before git commit |
| commitToGit | Boolean | false | Commit rendered config to git |
| deployOperator | Boolean | true | Deploy Flux operator via Helmfile |
| waitForReconciliation | Boolean | true | Wait for Flux reconciliation |
| reconciliationTimeout | String | "5m" | Timeout for reconciliation check |
| applyConfig | Boolean | false | Apply rendered config to cluster |
| fluxCliImage | String | "ghcr.io/fluxcd/flux-cli:v2.8.5" | Flux CLI container image |
| operatorVersion | String | "0.47.0" | Flux operator version for Helmfile state values |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
bootstrap --kube-config env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, kubeConfig *dagger.Secret) string {
return dag.
Flux().
Bootstrap(ctxkubeConfig)
}@function
async def example(kubeconfig: dagger.Secret) -> str:
return await (
dag.flux()
.bootstrap(kubeconfig)
)@func()
async example(kubeConfig: Secret): Promise<string> {
return dag
.flux()
.bootstrap(kubeConfig)
}bootstrapInfra() 🔗
BootstrapInfra renders infrastructure Kustomizations from a values file, commits them, and verifies that each one actually became Ready on the cluster.
The rendering is done by the claim-flux-kustomizations KCL module, the same
one whose output carries the managed-by: kcl-flux-kustomizations annotation
in the cluster repositories – this function drives it instead of the files
being written by hand.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| valuesFile | File ! | - | values.yaml describing the source and the components |
| ociSource | String | "ghcr.io/stuttgart-things/claim-flux-kustomizations:0.3.34" | OCI KCL module rendering the Kustomizations |
| entrypoint | String | "main.k" | KCL entrypoint file name |
| repository | String | - | Target repository in “owner/repo” format |
| branchName | String | "main" | Branch to commit to |
| destinationPath | String | "clusters/" | Destination path within the repository (the cluster directory) |
| gitToken | Secret | - | GitHub token for the commit |
| kubeConfig | Secret | - | Kubeconfig of the target cluster, required for verification |
| namespace | String | "flux-system" | Namespace the Kustomizations live in |
| commitToGit | Boolean | true | Commit the rendered manifests |
| verify | Boolean | true | Wait until every enabled component reports Ready |
| verifyTimeout | String | "10m" | How long to wait for all components together |
| fluxCliImage | String | "ghcr.io/fluxcd/flux-cli:v2.9.4" | Flux CLI image used for verification |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
bootstrap-infra --values-file file:pathfunc (m *MyModule) Example(ctx context.Context, valuesFile *dagger.File) string {
return dag.
Flux().
Bootstrapinfra(ctx, valuesFile)
}@function
async def example(valuesfile: dagger.File) -> str:
return await (
dag.flux()
.bootstrapinfra(valuesfile)
)@func()
async example(valuesFile: File): Promise<string> {
return dag
.flux()
.bootstrapInfra(valuesFile)
}commitConfig() 🔗
CommitConfig commits rendered config and optional secrets to a Git repository.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| configContent | String ! | - | Config YAML content to commit |
| repository | String ! | - | Repository in “owner/repo” format |
| branchName | String | "main" | Branch name for git operations |
| destinationPath | String | "clusters/" | Destination path within the repository |
| gitToken | Secret ! | - | GitHub token for git operations |
| secretsContent | String | - | Optional secrets YAML content to include in the commit |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
commit-config --config-content string --repository string --git-token env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, configContent string, repository string, gitToken *dagger.Secret) string {
return dag.
Flux().
Commitconfig(ctx, configContent, repository, gitToken)
}@function
async def example(configcontent: str, repository: str, gittoken: dagger.Secret) -> str:
return await (
dag.flux()
.commitconfig(configcontent, repository, gittoken)
)@func()
async example(configContent: string, repository: string, gitToken: Secret): Promise<string> {
return dag
.flux()
.commitConfig(configContent, repository, gitToken)
}deployOperator() 🔗
DeployOperator deploys the Flux operator via Helmfile.
Return Type
Void !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| kubeConfig | Secret ! | - | Kubeconfig secret for cluster access |
| helmfileRef | String | "helmfile.yaml" | Helmfile reference |
| src | Directory | - | Directory containing the helmfile |
| stateValues | String | - | Comma-separated key=value pairs for –state-values-set (e.g., “version=0.42.1”) |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
deploy-operator --kube-config env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, kubeConfig *dagger.Secret) {
return dag.
Flux().
Deployoperator(ctx, kubeConfig)
}@function
async def example(kubeconfig: dagger.Secret) -> None:
return await (
dag.flux()
.deployoperator(kubeconfig)
)@func()
async example(kubeConfig: Secret): Promise<void> {
return dag
.flux()
.deployOperator(kubeConfig)
}destroy() 🔗
Destroy tears down Flux from a cluster.
Phase order:
0: Delete FluxInstance CR
1: Delete Flux secrets
2: Uninstall Flux operator (Helmfile destroy)
3: Delete flux-system namespace
Usage:
dagger call -m flux destroy --kube-config file:///tmp/kubeconfig
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| kubeConfig | Secret ! | - | Kubeconfig secret for cluster access |
| namespace | String | "flux-system" | Target namespace |
| helmfileRef | String | "helmfile.yaml" | Helmfile reference for Flux operator |
| src | Directory | - | Directory containing the helmfile |
| operatorVersion | String | "0.42.1" | Flux operator version for Helmfile state values |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
destroy --kube-config env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, kubeConfig *dagger.Secret) string {
return dag.
Flux().
Destroy(ctx, kubeConfig)
}@function
async def example(kubeconfig: dagger.Secret) -> str:
return await (
dag.flux()
.destroy(kubeconfig)
)@func()
async example(kubeConfig: Secret): Promise<string> {
return dag
.flux()
.destroy(kubeConfig)
}renderConfig() 🔗
RenderConfig renders the Flux instance configuration using a KCL module. Returns the full rendered YAML (multi-document).
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| ociSource | String | "ghcr.io/stuttgart-things/kcl-flux-instance:0.3.3" | OCI KCL module source |
| configParameters | String ! | - | Comma-separated key=value pairs for KCL parameters |
| entrypoint | String | "main.k" | KCL entrypoint file name |
| renderSecrets | Boolean | false | Whether KCL should also render Secret manifests |
| gitUsername | Secret | - | Git username for pull secret |
| gitPassword | Secret | - | GitHub token for git pull secret |
| sopsAgeKey | Secret | - | AGE private key for SOPS decryption (applied to cluster) |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
render-config --config-parameters stringfunc (m *MyModule) Example(ctx context.Context, configParameters string) string {
return dag.
Flux().
Renderconfig(ctxconfigParameters)
}@function
async def example(configparameters: str) -> str:
return await (
dag.flux()
.renderconfig(configparameters)
)@func()
async example(configParameters: string): Promise<string> {
return dag
.flux()
.renderConfig(configParameters)
}renderInfra() 🔗
RenderInfra renders the infrastructure Kustomizations and returns them as a directory, without touching git or a cluster.
BootstrapInfra returns only a report, so this is the way to see what would
actually be committed – dagger call render-infra --values-file v.yaml
export --path ./out puts the manifests on disk for review.
Return Type
Directory !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| valuesFile | File ! | - | values.yaml describing the source and the components |
| ociSource | String | "ghcr.io/stuttgart-things/claim-flux-kustomizations:0.3.34" | OCI KCL module rendering the Kustomizations |
| entrypoint | String | "main.k" | KCL entrypoint file name |
| namespace | String | "flux-system" | Namespace the Kustomizations live in |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
render-infra --values-file file:pathfunc (m *MyModule) Example(valuesFile *dagger.File) *dagger.Directory {
return dag.
Flux().
Renderinfra(valuesFile)
}@function
def example(valuesfile: dagger.File) -> dagger.Directory:
return (
dag.flux()
.renderinfra(valuesfile)
)@func()
example(valuesFile: File): Directory {
return dag
.flux()
.renderInfra(valuesFile)
}verifySecrets() 🔗
VerifySecrets auto-extracts secret names from the YAML and verifies they exist in the cluster.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| secretContent | String ! | - | Secret YAML content (multi-document) |
| namespace | String | "flux-system" | Target namespace |
| kubeConfig | Secret ! | - | Kubeconfig secret for cluster access |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
verify-secrets --secret-content string --kube-config env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, secretContent string, kubeConfig *dagger.Secret) string {
return dag.
Flux().
Verifysecrets(ctx, secretContent, kubeConfig)
}@function
async def example(secretcontent: str, kubeconfig: dagger.Secret) -> str:
return await (
dag.flux()
.verifysecrets(secretcontent, kubeconfig)
)@func()
async example(secretContent: string, kubeConfig: Secret): Promise<string> {
return dag
.flux()
.verifySecrets(secretContent, kubeConfig)
}waitForReconciliation() 🔗
WaitForReconciliation runs flux check with retry, reconciles sources, and gets all Flux resources.
Return Type
String !Arguments
| Name | Type | Default Value | Description |
|---|---|---|---|
| namespace | String | "flux-system" | Target namespace |
| kubeConfig | Secret ! | - | Kubeconfig secret for cluster access |
| reconciliationTimeout | String | "5m" | Timeout for reconciliation check |
| fluxCliImage | String | "ghcr.io/fluxcd/flux-cli:v2.8.3" | Flux CLI container image |
Example
dagger -m github.com/stuttgart-things/blueprints/flux@75d4855337d14390f01ad1c20865387515eb2c83 call \
wait-for-reconciliation --kube-config env:MYSECRETfunc (m *MyModule) Example(ctx context.Context, kubeConfig *dagger.Secret) string {
return dag.
Flux().
Waitforreconciliation(ctxkubeConfig)
}@function
async def example(kubeconfig: dagger.Secret) -> str:
return await (
dag.flux()
.waitforreconciliation(kubeconfig)
)@func()
async example(kubeConfig: Secret): Promise<string> {
return dag
.flux()
.waitForReconciliation(kubeConfig)
}