Dagger
Search

argocd

Argo CD on Kubernetes, including KCL-based cluster registration
(clusterbook) rendering.

Installation

dagger install github.com/stuttgart-things/blueprints/argocd@v2.2.1

Entrypoint

Return Type
Argocd
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
func (m *MyModule) Example() *dagger.Argocd  {
	return dag.
			Argocd()
}
@function
def example() -> dagger.Argocd:
	return (
		dag.argocd()
	)
@func()
example(): Argocd {
	return dag
		.argocd()
}

Types

Argocd 🔗

applyConfig() 🔗

ApplyConfig applies a rendered config file to the cluster. The target namespace is created (server-side, kubectl apply on a Namespace doc) before the manifests are applied.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
configFileFile !-Rendered config file (from render-clusterbook-cluster-config or local YAML)
kubeConfigSecret !-Kubeconfig secret for cluster access
namespaceString "argocd"Target namespace
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
 apply-config --config-file file:path --kube-config env:MYSECRET
func (m *MyModule) Example(ctx context.Context, configFile *dagger.File, kubeConfig *dagger.Secret) string  {
	return dag.
			Argocd().
			ApplyConfig(ctx, configFile, kubeConfig)
}
@function
async def example(config_file: dagger.File, kube_config: dagger.Secret) -> str:
	return await (
		dag.argocd()
		.apply_config(config_file, kube_config)
	)
@func()
async example(configFile: File, kubeConfig: Secret): Promise<string> {
	return dag
		.argocd()
		.applyConfig(configFile, kubeConfig)
}

bootstrapClusterbookCluster() 🔗

BootstrapClusterbookCluster orchestrates the full cluster-registration workflow: render the clusterbook config, optionally apply it to a cluster (–deploy), and optionally commit it to a Git repo with optional PR and merge (–commit-to-git).

Returns the rendered file so callers can also export --path=... it.

Return Type
File !
Arguments
NameTypeDefault ValueDescription
nameString -Cluster name — required unless valuesFile is provided
networkKeyString -/24 network key — required unless valuesFile is provided
valuesFileFile -YAML/JSON values file (KCL --parametersFile)
ociSourceString "ghcr.io/stuttgart-things/clusterbook-cluster-gen:0.1.0"OCI KCL module source
clusterNameString -Argo CD-side cluster name
createDnsBoolean -No description provided
preserveKubeconfigServerBoolean -No description provided
releaseOnDeleteBoolean -No description provided
kubeconfigSecretNameString -No description provided
kubeconfigSecretNamespaceString -No description provided
argocdNamespaceString -No description provided
providerConfigNameString -No description provided
clusterLabelsString -JSON object literal, e.g. {"env":"lab"}
entrypointString "main.k"No description provided
deployBoolean falseApply the rendered config to a cluster
kubeConfigSecret -Kubeconfig secret — required when deploy=true or detect-network-key=true
deployNamespaceString "argocd"Target namespace for apply
detectNetworkKeyBoolean falseRun kubectl get nodes -o json against --kube-config and use the dominant /24 InternalIP prefix as --network-key. Only fires when --network-key is empty.
renderKubeconfigSecretBoolean falseRender a v1/Secret wrapping a SOPS-encrypted kubeconfig source file; applied alongside the cluster config on --deploy=true and committed alongside it on --commit-to-git=true.
kubeconfigSourceFileFile -SOPS-encrypted kubeconfig source — required when render-kubeconfig-secret=true // pragma: allowlist secret
sopsKeySecret -AGE private key for decrypting kubeconfig-source-file
agePublicKeySecret -AGE public key for re-encrypting the rendered Secret — required when render-kubeconfig-secret=true and commit-to-git=true // pragma: allowlist secret
sopsConfigFileFile -SOPS config file (.sops.yaml) used during re-encryption
kubeconfigDataKeyString "kubeconfig"Data key under data: in the rendered Secret
kubeconfigFileNameString "kubeconfig.yaml"File name to use when committing the kubeconfig Secret (joined with destination-path)
commitToGitBoolean falseCommit the rendered config to a Git repository
repositoryString -Repository in "owner/repo" — required when commitToGit=true
gitTokenSecret -GitHub token — required when commitToGit=true
branchNameString "main"Branch to commit to
destinationPathString "argocd/clusters/"Destination folder within the repository
fileNameString "cluster.yaml"File name to write under destinationPath
commitMessageString "Add Argo CD cluster registration"Commit message
createPrBoolean falseOpen a PR from branchName into baseBranch
baseBranchString "main"PR base branch
prTitleString -No description provided
prBodyString -No description provided
mergePrBoolean falseAuto-merge the PR after creation
mergeMethodString "squash"squash | merge | rebase
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
 bootstrap-clusterbook-cluster
func (m *MyModule) Example() *dagger.File  {
	return dag.
			Argocd().
			BootstrapClusterbookCluster()
}
@function
def example() -> dagger.File:
	return (
		dag.argocd()
		.bootstrap_clusterbook_cluster()
	)
@func()
example(): File {
	return dag
		.argocd()
		.bootstrapClusterbookCluster()
}

commitConfig() 🔗

CommitConfig commits configFile to / on in . Optionally opens a pull request against and optionally merges that PR.

Returns a multi-line summary of what was committed / opened / merged.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
configFileFile !-Rendered config file to commit
repositoryString !-Repository in "owner/repo" format
gitTokenSecret !-GitHub token for git operations
branchNameString "main"Branch to commit the file to
destinationPathString "argocd/clusters/"Destination folder within the repository (without leading slash)
fileNameString "cluster.yaml"File name to write under destinationPath (used as the committed basename)
commitMessageString "Add Argo CD cluster registration"Commit message
createPrBoolean falseOpen a pull request from branchName into baseBranch
baseBranchString "main"Base branch for the PR
prTitleString -PR title (defaults to commitMessage when empty)
prBodyString -PR body
mergePrBoolean falseMerge the PR after creation
mergeMethodString "squash"Merge method: "squash", "merge", or "rebase"
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
 commit-config --config-file file:path --repository string --git-token env:MYSECRET
func (m *MyModule) Example(ctx context.Context, configFile *dagger.File, repository string, gitToken *dagger.Secret) string  {
	return dag.
			Argocd().
			CommitConfig(ctx, configFile, repository, gitToken)
}
@function
async def example(config_file: dagger.File, repository: str, git_token: dagger.Secret) -> str:
	return await (
		dag.argocd()
		.commit_config(config_file, repository, git_token)
	)
@func()
async example(configFile: File, repository: string, gitToken: Secret): Promise<string> {
	return dag
		.argocd()
		.commitConfig(configFile, repository, gitToken)
}

commitFiles() 🔗

CommitFiles commits every file in sourceDir into on in as a single commit / single push. Optionally opens a pull request against and optionally merges it.

Distinct from CommitConfig in two ways:

  1. It accepts a Directory (multiple files) so callers can push e.g. cluster.yaml + kubeconfig.yaml in one commit. Two back-to-back CommitConfig calls (one file each) hit a Dagger CloneGithub cache race — the second clone is served from cache and pre-dates the first push, so git push is rejected as non-fast-forward. Bundling into one commit avoids it entirely.
  2. destinationFolder is a folder (without filename); each file in sourceDir is placed under that folder. Filenames in the source directory are preserved verbatim.

Returns a multi-line summary of what was committed / opened / merged.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
sourceDirDirectory !-Source directory whose files (top level) should be committed
repositoryString !-Repository in "owner/repo" format
gitTokenSecret !-GitHub token for git operations
branchNameString "main"Branch to commit the files to
destinationFolderString "argocd/clusters/"Destination folder within the repository (without leading slash)
commitMessageString "Add Argo CD cluster registration"Commit message
createPrBoolean falseOpen a pull request from branchName into baseBranch
baseBranchString "main"Base branch for the PR
prTitleString -PR title (defaults to commitMessage when empty)
prBodyString -PR body
mergePrBoolean falseMerge the PR after creation
mergeMethodString "squash"Merge method: "squash", "merge", or "rebase"
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
 commit-files --source-dir DIR_PATH --repository string --git-token env:MYSECRET
func (m *MyModule) Example(ctx context.Context, sourceDir *dagger.Directory, repository string, gitToken *dagger.Secret) string  {
	return dag.
			Argocd().
			CommitFiles(ctx, sourceDir, repository, gitToken)
}
@function
async def example(source_dir: dagger.Directory, repository: str, git_token: dagger.Secret) -> str:
	return await (
		dag.argocd()
		.commit_files(source_dir, repository, git_token)
	)
@func()
async example(sourceDir: Directory, repository: string, gitToken: Secret): Promise<string> {
	return dag
		.argocd()
		.commitFiles(sourceDir, repository, gitToken)
}

createVaultIssuer() 🔗

CreateVaultIssuer prepares the cluster-side prerequisites cert-manager needs to use a remote Vault PKI as a ClusterIssuer. It does NOT create the ClusterIssuer itself — that’s the cert-manager-vault-pki AppSet’s job, which references the two Secrets this function lands on the target cluster.

What it does (in one Dagger session): 1. Decrypts the vault env yaml. 2. Talks to Vault directly (HTTP API) to upsert an ACL policy a renewable token + read the PKI CA. (No Terraform.) 3. Decrypts the target cluster’s kubeconfig. 4. Applies a 3-document YAML directly to the target cluster: - Namespace/<target-namespace> (default cert-manager) - Secret/<token-secret-name> (default cert-manager-vault-token, data.token = freshly-minted vault token) - Secret/<ca-secret-name> (default vault-pki-ca, data["ca.crt"] = live-fetched PKI root CA PEM)

Only plain core/v1 resources are created; no cert-manager CRDs, no admission-webhook coupling. The AppSet that creates the ClusterIssuer runs whenever it’s ready — order-independent.

Closes #162.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
clusterNameString !-Target cluster name; used in the Vault token's display_name.
kubeconfigSourceFileFile !-SOPS-encrypted kubeconfig of the target cluster.
vaultEnvFileFile !-SOPS-encrypted KV-YAML with `vaultAddr`, `vaultToken`, optional `vaultSkipVerify` (defaults to true), and optional `vaultCaBundle` (base64-encoded PKI root CA PEM; when set, the function uses it directly instead of live-fetching from `${vaultAddr}/v1/pki/ca/pem`).
sopsKeySecret !-AGE private key for decrypting both files.
pkiRoleString "sthings-vsphere"Vault PKI role name (matches the Vault PKI mount's pre-existing role; the rendered ClusterIssuer references this role).
policyNameString "pki-issue"Vault ACL policy name to upsert.
targetNamespaceString "cert-manager"Namespace to create + place the cert-manager Secrets in.
tokenSecretNameString "cert-manager-vault-token"Name of the Secret containing the Vault token.
caSecretNameString "vault-pki-ca"Name of the Secret containing the PKI CA bundle.
tokenTtlString "8760h"TTL for the minted Vault token. Renewable.
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
 create-vault-issuer --cluster-name string --kubeconfig-source-file file:path --vault-env-file file:path --sops-key env:MYSECRET
func (m *MyModule) Example(ctx context.Context, clusterName string, kubeconfigSourceFile *dagger.File, vaultEnvFile *dagger.File, sopsKey *dagger.Secret) string  {
	return dag.
			Argocd().
			CreateVaultIssuer(ctx, clusterName, kubeconfigSourceFile, vaultEnvFile, sopsKey)
}
@function
async def example(cluster_name: str, kubeconfig_source_file: dagger.File, vault_env_file: dagger.File, sops_key: dagger.Secret) -> str:
	return await (
		dag.argocd()
		.create_vault_issuer(cluster_name, kubeconfig_source_file, vault_env_file, sops_key)
	)
@func()
async example(clusterName: string, kubeconfigSourceFile: File, vaultEnvFile: File, sopsKey: Secret): Promise<string> {
	return dag
		.argocd()
		.createVaultIssuer(clusterName, kubeconfigSourceFile, vaultEnvFile, sopsKey)
}

detectNetworkKey() 🔗

DetectNetworkKey runs kubectl get nodes -o json against the target cluster and returns the /24 prefix shared by the nodes’ InternalIP addresses (e.g. “10.31.102”). This is the format expected by render-clusterbook-cluster-config / bootstrap-clusterbook-cluster as –network-key.

When nodes span multiple /24 subnets (rare but possible with mixed pools), the most frequently observed prefix wins. IPv6 addresses are ignored.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
kubeConfigSecret !-Kubeconfig secret for cluster access
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
 detect-network-key --kube-config env:MYSECRET
func (m *MyModule) Example(ctx context.Context, kubeConfig *dagger.Secret) string  {
	return dag.
			Argocd().
			DetectNetworkKey(ctx, kubeConfig)
}
@function
async def example(kube_config: dagger.Secret) -> str:
	return await (
		dag.argocd()
		.detect_network_key(kube_config)
	)
@func()
async example(kubeConfig: Secret): Promise<string> {
	return dag
		.argocd()
		.detectNetworkKey(kubeConfig)
}

renderClusterbookClusterConfig() 🔗

RenderClusterbookClusterConfig renders the clusterbook-cluster-gen KCL module, which produces the manifests needed to register a cluster with Argo CD (kubeconfig Secret reference, provider config, cluster labels, optional DNS).

Values can come from a YAML/JSON file (–values-file) and/or individual CLI flags. When both are provided, CLI flags override matching keys in the file (KCL –parameters takes precedence over –parametersFile).

Returns the rendered multi-document YAML as a Dagger File.

Return Type
File !
Arguments
NameTypeDefault ValueDescription
nameString -Cluster name (KCL -D name) — required unless valuesFile is provided
networkKeyString -/24 network key, e.g. 10.31.101 — required unless valuesFile is provided
valuesFileFile -YAML/JSON file with KCL parameters (passed as --parametersFile); CLI flags below override matching keys
ociSourceString "ghcr.io/stuttgart-things/clusterbook-cluster-gen:0.1.0"OCI KCL module source
clusterNameString -Argo CD-side cluster name; defaults to name when neither is set via file
createDnsBoolean -Create a DNS record for the cluster (default true when no values file)
preserveKubeconfigServerBoolean -Preserve the existing server field from the kubeconfig Secret (default true when no values file)
releaseOnDeleteBoolean -Release the Argo CD cluster Secret on resource delete (default true when no values file)
kubeconfigSecretNameString -Name of the Secret holding the cluster kubeconfig; defaults to name when no values file
kubeconfigSecretNamespaceString -Namespace of the kubeconfig Secret (default "argocd" when no values file)
argocdNamespaceString -Argo CD namespace (default "argocd" when no values file)
providerConfigNameString -Crossplane ProviderConfig name (default "default" when no values file)
clusterLabelsString -Cluster labels as a JSON object literal, e.g. {"env":"lab","role":"mgmt"}
entrypointString "main.k"KCL entrypoint file
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
 render-clusterbook-cluster-config
func (m *MyModule) Example() *dagger.File  {
	return dag.
			Argocd().
			RenderClusterbookClusterConfig()
}
@function
def example() -> dagger.File:
	return (
		dag.argocd()
		.render_clusterbook_cluster_config()
	)
@func()
example(): File {
	return dag
		.argocd()
		.renderClusterbookClusterConfig()
}

renderKubeconfigSecret() 🔗

RenderKubeconfigSecret turns a SOPS-encrypted source file (typically a cluster kubeconfig under stuttgart-things/secrets/kubeconfigs/) into a Kubernetes v1/Secret manifest. Equivalent to:

sops --decrypt <sourceFile> > kubeconfig.yaml
kubectl create secret generic <name> -n <namespace> \
  --from-file=<dataKey>=kubeconfig.yaml \
  --dry-run=client -o yaml

By default the rendered Secret is re-encrypted with SOPS using agePublicKey so it can be safely committed to git (e.g. via commit-config). Pass –encrypt=false to get the plaintext manifest for direct kubectl apply (e.g. via apply-config).

Returns the manifest as a Dagger File so it composes with apply-config and commit-config without shell round-trips.

Return Type
File !
Arguments
NameTypeDefault ValueDescription
sourceFileFile !-SOPS-encrypted source file (e.g. kubeconfigs/kind-dev-test1.yaml)
sopsKeySecret !-AGE private key for decrypting sourceFile (AGE-SECRET-KEY-...)
nameString !-Secret name (e.g. "kind-dev-test1" or "target-cluster-kubeconfig")
namespaceString "argocd"Target namespace
dataKeyString "kubeconfig"Data key under data: in the rendered Secret (data.<dataKey>)
encryptBoolean trueRe-encrypt the rendered Secret with SOPS using agePublicKey
agePublicKeySecret -AGE public key for SOPS re-encryption (required when encrypt=true)
sopsConfigFile -SOPS config file (.sops.yaml) used during re-encryption
Example
dagger -m github.com/stuttgart-things/blueprints/argocd@3b1c19d54aaa2769f2c856713a59e00f78372e61 call \
 render-kubeconfig-secret --source-file file:path --sops-key env:MYSECRET --name string
func (m *MyModule) Example(sourceFile *dagger.File, sopsKey *dagger.Secret, name string) *dagger.File  {
	return dag.
			Argocd().
			RenderKubeconfigSecret(sourceFile, sopsKey, name)
}
@function
def example(source_file: dagger.File, sops_key: dagger.Secret, name: str) -> dagger.File:
	return (
		dag.argocd()
		.render_kubeconfig_secret(source_file, sops_key, name)
	)
@func()
example(sourceFile: File, sopsKey: Secret, name: string): File {
	return dag
		.argocd()
		.renderKubeconfigSecret(sourceFile, sopsKey, name)
}