Skip to content
Browse Docs

Deep Dives

AI: Claude and Codex patterns

ConfigHub: Deploy and manage

Docs
Configs
Stacks
Apps
Plugins
Guides

Read an EKS + H100 + Kubeflow platform before you build one

This is one entry in the AI platform catalog. You do not need to know AICR to follow it. AICR is a tool from NVIDIA for building AI-cluster platforms. You describe the platform you want, for example an EKS cluster with H100 GPUs, Ubuntu, Kubeflow, and a training job. AICR then picks 15 components, puts them in the right install order, and hands you the files to install them. It does not decide how your team reviews, approves, or promotes those files. It is one of the NVIDIA AICR pages. You can also view this as a markdown file.

Use this entry in ConfigHub in five steps, from fetching its exact objects to promoting a change.

What it is. AICR recipe aicr-eks-h100-training-kubeflow v0.14.0, as 17 Argo CD Applications.

Install it. Apply its Applications on a cluster that runs Argo CD. The five steps below give the commands.

OCI bundle. oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/aicr-eks-h100-training-kubeflow-argocd-config:0.14.0

Needs first. AICR assigned the 16 component Applications to sync waves 0 through 15. The parent and two path-based child Applications refer to the public AICR Helm source package at its recorded version and digest.

That is where ConfigHub comes in, and the boundary is the whole point. AICR decides what goes in the platform. It selects the 15 components, sets the install order, and writes the exact files. ConfigHub then records that decision as data a team can govern. It stores the files, checks them, requires approval for a cluster-wide change, and keeps a copy per environment instead of rebuilding the package by hand. Argo CD or Flux install the approved files onto the cluster.

This example asks NVIDIA AICR v0.14.0 for an EKS platform with H100 accelerators, Ubuntu, Kubeflow, and a training workload. The result includes storage, networking, certificates, GPU support, monitoring, scheduling, and Kubeflow training.

One detail shows this was operated, not just read about. AICR fixes almost the whole platform when it builds the files. Exactly four choices stay open: the storage type, the selector for GPU nodes, the selector for the training job, and where the installer reads the published package. The first three are set when the files are built. The fourth points the installer at the built package.

Why you would want this

The recipe pins most of the platform before installation. Four choices remain at install time: the StorageClass, the selector for accelerated nodes, the selector for training workloads, and the source the delivery controller reads. The first three are fixed when the bundle is generated. The fourth must point at the published bundle.

Keeping the recipe, those four choices, and the generated files together answers two practical questions later: what did we ask AICR to build, and what did each cluster actually receive?

What is in the repository

The original Git-oriented bundle still contains https://github.com/YOUR_ORG/YOUR_REPO.git. It is kept so the limitation is visible; it is not deployable.

The OCI-oriented bundle has no repository placeholder. AICR replaces its two local charts with ArtifactGenerator resources, and their HelmRelease objects refer to ExternalArtifact outputs. The generated checksums.txt originally contained the absolute output directory. The committed copy changes only those path prefixes to paths relative to the bundle root, so the checksum list is portable and does not expose a workstation path.

How you know these are the files AICR wrote

The digest-index directory compiles the whole example into one digest-bound platform index, following the pattern the Kubara importer proved: one immutable payload per component plus one index that names every payload by its exact hash. The compiler reads only committed bytes and refuses to compile if any rendered file drifts from its recorded checksum.

npm run aicr-digest-index:verify
npm run aicr-digest-index:self-test

The verify lane recompiles the index and compares every committed file byte for byte. The self-test compiles fake surfaces only and proves determinism, digest sensitivity to a single changed byte, tamper refusal, and the structural refusals: duplicate Application names, broken sync-wave ranges, a second root, an off-version member. The planned OCI references inside the index are plans, not publications; the index records compiled-offline and claims no registry push. As everywhere in this example, the index proves config-plane mechanics only. No GPU workload ran to produce or verify it.

Rebuild it yourself

Install AICR v0.14.0, then run these commands from the example directory:

aicr recipe \
  --service eks \
  --accelerator h100 \
  --os ubuntu \
  --intent training \
  --platform kubeflow \
  --output recipe.yaml

aicr bundle \
  --recipe recipe.yaml \
  --deployer flux \
  --output flux-bundle \
  --storage-class gp3 \
  --accelerated-node-selector nvidia.com/gpu.present=true \
  --workload-selector app.kubernetes.io/part-of=training

That command reproduces the Git-oriented bundle. For a usable Git bundle, add --repo https://github.com/ORG/REPOSITORY.git, regenerate it, and review the resulting GitRepository and HelmRelease objects before upload.

The OCI-oriented run used the same recipe and choices:

aicr bundle \
  --recipe recipe.yaml \
  --deployer flux \
  --output oci://REGISTRY/aicr-eks-h100-training-kubeflow:v0.14.0 \
  --image-refs oci-image-ref.txt \
  --storage-class gp3 \
  --accelerated-node-selector nvidia.com/gpu.present=true \
  --workload-selector app.kubernetes.io/part-of=training

For a local HTTP registry, add --plain-http. The recorded local manifest digest is sha256:b8089d6400833531c5d0d91177e70cf48f2b86896b0214c2b3318916ac4d29ba. This proves local packaging and pullability. It does not prove a public registry push or a working GPU cluster.

Run npm run aicr-example:verify to check both bundles. The verifier checks the criteria, command options, release and binary checksums, every generated file, the local OCI manifest, the two ArtifactGenerator resources, and the matching ExternalArtifact references.

Deliver it with Flux

AICR's OCI form requires Flux v2.7 or newer, the source-watcher controller, and ExternalArtifact=true on helm-controller. The target also needs an OCIRepository named aicr-bundle in flux-system that points at the published AICR artifact. Those are part of the operating configuration, so the receipt records them instead of leaving them as setup knowledge.

Deliver it with Argo CD

AICR can also generate an argocd-helm bundle. This output is a Helm chart that creates one parent Argo CD Application and 16 component Application objects. The components use sync waves 0 through 15, so storage, certificates, GPU support, monitoring, scheduling, and training are presented to Argo CD in the intended order.

Two OCI artifacts have different jobs:

ArtifactWhat it containsWho uses it
AICR Argo source packageThe generated Helm chart, values, local chart files, and Argo CD templatesHelm and Argo CD
Rendered Argo configurationThe 17 exact Application objects, one YAML layer per objectConfigHub

Both artifacts are public in Google Artifact Registry:

oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/aicr-eks-h100-training-kubeflow-argocd:0.14.0
oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/aicr-eks-h100-training-kubeflow-argocd-config:0.14.0

The source package digest is sha256:1120c9a17b23f2c885121034d55445f2d3948c95c23756d02fa2209e4baf8c2e. The 17-object configuration digest is sha256:dcf7feeeeaece04cb5d55cbc1106862172b3ae77718154252b39db1ad8957010. Both passed anonymous pull checks. The small OCI layouts are also committed, so the verifier can compare the public artifacts with the exact source and rendered files.

Run npm run aicr-argocd-example:verify to check the source package, the 17 Applications, both OCI manifests and layouts, every file checksum, the source references, and the complete set of sync waves. Run npm run aicr-argocd-example:public-verify to pull both public artifacts without registry credentials and check their recorded digests.

Keep it in ConfigHub

The live demo imports the public literal configuration OCI:

cub variant upload \
  --component aicr-eks-h100-training-kubeflow \
  --variant v0-14-0-argocd \
  --space aicr-eks-h100-training-kubeflow-v0-14-0-argocd \
  --granularity minimal \
  oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/aicr-eks-h100-training-kubeflow-argocd-config:0.14.0

ConfigHub pulled digest sha256:dcf7feeeeaece04cb5d55cbc1106862172b3ae77718154252b39db1ad8957010, created one base Space, and stored all 17 Application objects in one Unit. A verifier compared every live object with the committed AICR output and confirmed sync waves 0 through 15.

The upload also names two requirements that must already exist: the argocd Namespace and the default Argo CD AppProject. The live Space records both in its README.

cub variant upload does not run AICR or render charts. It imports exact YAML and records the source reference and resolved digest on the Space. ConfigHub can then show changes to those files and manage derived variants for environments or cluster classes.

The whole round trip, start to finish

A separate live test checked the next boundary. It imported the same 17-Application literal configuration OCI into a temporary ConfigHub base, published a ConfigHub release OCI, pulled that release back, and compared every Application with the AICR input.

All 17 Applications matched. ConfigHub added its confighub.com/origin annotation to each object so the released configuration can be traced back to its ConfigHub record. The input and output OCI digests are different because they are different artifacts; the object comparison proves that the Kubernetes configuration stayed the same.

Read the plain-English result or the live receipt. The test used a temporary local input registry and a throwaway cluster only to obtain a legitimate ConfigHub release target and scoped OCI credential. It did not apply the Applications, reconcile the AICR stack, create an EKS cluster, or run a GPU workload.

The public pull does not need a Google login. Argo CD delivery and live GPU-cluster reconciliation have not run. The example proves generation, public OCI packaging, exact ConfigHub upload, policy attachment, and promotion, but it does not claim a working GPU platform.

The uploaded base requires approval because it changes cluster-wide GPU, monitoring, and training-platform configuration. That rule applies before production too. A live dry-run of the exact 17-Application Unit was rejected by the required-approval gate. The Unit had no target attached, its revision and data hash stayed unchanged, and nothing was sent to Kubernetes. Run npm run aicr-argocd-example:hub-policy-check while authenticated to repeat that check.

Change one value and promote it

The generated AICR configuration includes the example Grafana setting adminPassword: admin inside the kube-prometheus-stack Application. ConfigHub can keep the AICR output as the base, while development and staging use an existing Secret named aicr-grafana-admin.

The persistent helm-catalog demo follows four steps:

  1. Import the exact 17-Application OCI bundle as a base variant.
  2. Create development from the base and staging from development.
  3. Preview and apply the Grafana Secret change in development. Only Application argocd/kube-prometheus-stack changed.
  4. Preview the staging promotion, confirm that the preview changed nothing, then run the promotion and confirm that staging matched the reviewed development config.

The persistent promotion receipt records the public OCI digests, three live Spaces, exact changed Application, dry-run results, promotion revision, policy checks, and required approval. Each Space has one short README that explains what to inspect.

The configuration Unit is promoted by itself so development and staging can keep different README text. This is the same upstream upgrade operation used by a bulk variant promotion, scoped to the one Unit that contains the 17 Applications.

Run the live check while authenticated:

CUB_CONTEXT=<context> npm run aicr-argocd-example:promotion-verify

A separate scratch proof records an earlier temporary run of the same configuration change. Neither proof started a Kubernetes cluster, so neither claims Argo CD delivery, application health, or GPU workload health.

Use this entry in ConfigHub

Every Catalog entry page carries these five steps in this order. Each step says what the Catalog has run for this entry, and a step with a missing precondition gives no command.

Steps 1 and 2 need no account. Install the cub CLI before any cub command. Step 2 uses cub config diff, which cub plugin install confighub/cub-workshop@v0.6.61 adds. This page covers 2 entries, so open the one you want. A live run on 2026-10-08 used these cub variant commands on other configuration, with no Target. It is not a run for this entry.

AICR recipe, base argocd, version v0.14.0
What is fixed, and what you supply

Fixed when this entry was built. These went into the build, so the objects already carry them. To change one, build the entry again from its source.

  • accelerator is h100
  • intent is training
  • os is ubuntu
  • platform is kubeflow
  • service is eks
  • acceleratedNodeSelector is nvidia.com/gpu.present=true
  • storageClass is gp3
  • workloadSelector is app.kubernetes.io/part-of=training
  • namespace is argocd
  • repoURL is oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt
  • targetRevision is 0.14.0

Yours to supply or check. The listing records no input for the destination. The Catalog has not ruled one out for your cluster.

This entry's plan, and how to test it

These are the steps that plain objects cannot carry. ConfigHub stores them and does not carry them out. The words in italics say what the Catalog knows about each.

  • Once the destination is known. AICR assigned the 16 component Applications to sync waves 0 through 15. Who: not selected. Generated. Not run on a cluster.
  • Once the destination is known. The parent and two path-based child Applications refer to the public AICR Helm source package at its recorded version and digest. Who: not selected. Recorded as published.

Read what a plan is, and why some entries have one.

1. Get the exact objects Run for this entry

The Catalog rendered this entry and retains its 17 Argo CD Applications as files that one inventory lists.

# make the directories the inventory names
$ mkdir -p aicr-eks-h100-training-kubeflow-v0-14-0-argocd/templates

# fetch the inventory, then every file it lists
$ curl -fsSL -o aicr-eks-h100-training-kubeflow-v0-14-0-argocd/checksums.txt https://raw.githubusercontent.com/confighub/helm-expt/main/examples/aicr/eks-h100-training-kubeflow/argocd-rendered/checksums.txt

$ cut -c67- aicr-eks-h100-training-kubeflow-v0-14-0-argocd/checksums.txt | xargs -I{} curl -fsSL -o aicr-eks-h100-training-kubeflow-v0-14-0-argocd/{} https://raw.githubusercontent.com/confighub/helm-expt/main/examples/aicr/eks-h100-training-kubeflow/argocd-rendered/{}

# check every file against the inventory
$ (cd aicr-eks-h100-training-kubeflow-v0-14-0-argocd && shasum -a 256 -c checksums.txt)

# check the inventory against the listing digest
$ shasum -a 256 aicr-eks-h100-training-kubeflow-v0-14-0-argocd/checksums.txt
fc03b2950c81db63a4853424fcb30942e9ecf0e94e54f7474439421dcc254801  aicr-eks-h100-training-kubeflow-v0-14-0-argocd/checksums.txt

# join the files into one for step 2
$ cat aicr-eks-h100-training-kubeflow-v0-14-0-argocd/templates/*.yaml > aicr-eks-h100-training-kubeflow-v0-14-0-argocd.yaml

2. Compare with another version or base Not run for this entry

The listing records no comparison for this entry. The commands run on the retained files, with no account. This version has one other base in the Catalog, base. The Catalog holds 4 other versions, v0.18.0, v0.19.0, v0.20.0 and v1.0.0.

# fetch the argocd base at version v0.18.0
$ mkdir -p aicr-eks-h100-training-kubeflow-v0-18-0-argocd/templates

$ curl -fsSL -o aicr-eks-h100-training-kubeflow-v0-18-0-argocd/checksums.txt https://raw.githubusercontent.com/confighub/helm-expt/main/examples/aicr/eks-h100-training-kubeflow-v0-18-0/argocd-rendered/checksums.txt

$ cut -c67- aicr-eks-h100-training-kubeflow-v0-18-0-argocd/checksums.txt | xargs -I{} curl -fsSL -o aicr-eks-h100-training-kubeflow-v0-18-0-argocd/{} https://raw.githubusercontent.com/confighub/helm-expt/main/examples/aicr/eks-h100-training-kubeflow-v0-18-0/argocd-rendered/{}

# join them into one file
$ cat aicr-eks-h100-training-kubeflow-v0-18-0-argocd/templates/*.yaml > aicr-eks-h100-training-kubeflow-v0-18-0-argocd.yaml

# list what changes from v0.14.0 to v0.18.0
$ cub config diff aicr-eks-h100-training-kubeflow-v0-14-0-argocd.yaml aicr-eks-h100-training-kubeflow-v0-18-0-argocd.yaml --summary

3. Upload it as a variant Run for this entry

The Catalog saved this entry in ConfigHub. The commands use its published literal configuration bundle. Read the receipt.

# sign in; steps 3 to 5 write to your ConfigHub organization
$ cub auth login

# preview the upload of the published bundle; nothing is written
$ cub variant upload --dry-run --component eks-h100-training-kubeflow --variant argocd --space aicr-eks-h100-training-kubeflow-v0-14-0-argocd oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/aicr-eks-h100-training-kubeflow-argocd-config:0.14.0

# upload the bundle as a base Space of Units
$ cub variant upload --component eks-h100-training-kubeflow --variant argocd --space aicr-eks-h100-training-kubeflow-v0-14-0-argocd oci://europe-west1-docker.pkg.dev/nth-fort-499605-q5/helm-expt/aicr-eks-h100-training-kubeflow-argocd-config:0.14.0

4. Deploy it Partly run for this entry

A delivery is partly recorded for this entry, and no run has passed. Argo CD is partly recorded, Flux does not apply, and kubectl has no record. The commands name the Target workshop/target, which cub cluster up --name workshop creates on a local kind cluster with Argo CD. Use your own Target for a real destination. Read the receipt.

# clone the base onto a Target as a dev variant
$ cub variant create dev aicr-eks-h100-training-kubeflow-v0-14-0-argocd --target workshop/target --space-pattern "template:aicr-eks-h100-training-kubeflow-v0-14-0-argocd-dev"

# publish the Release that Argo CD or Flux pulls
$ cub release publish aicr-eks-h100-training-kubeflow-v0-14-0-argocd-dev

5. Promote a change Run for this entry

A promotion ran for this entry. It followed base to development to staging. Promotion carries a change in the base to the dev variant. The base changes when you edit a Unit or upload a newer version into the same Space. Read the receipt.

# preview what the dev variant would take from the base
$ cub variant promote aicr-eks-h100-training-kubeflow-v0-14-0-argocd-dev --dry-run -o mutations

# promote once you have read the preview
$ cub variant promote aicr-eks-h100-training-kubeflow-v0-14-0-argocd-dev --change-desc "Pull the reviewed base forward"
AICR recipe, base base, version v0.14.0
What is fixed, and what you supply

Fixed when this entry was built. These went into the build, so the objects already carry them. To change one, build the entry again from its source.

  • accelerator is h100
  • intent is training
  • os is ubuntu
  • platform is kubeflow
  • service is eks
  • acceleratedNodeSelector is nvidia.com/gpu.present=true
  • storageClass is gp3
  • workloadSelector is app.kubernetes.io/part-of=training

Yours to supply or check. The listing records no input for the destination. The Catalog has not ruled one out for your cluster.

This entry's plan, and how to test it

These are the steps that plain objects cannot carry. ConfigHub stores them and does not carry them out. The words in italics say what the Catalog knows about each.

  • Once the destination is known. AICR generated Flux dependsOn relationships for the component order. This repo has not reconciled the bundle on a live target. Who: not selected. Generated. Not run on a cluster.
  • Once the destination is known. Two local charts use ArtifactGenerator and ExternalArtifact. Flux must run source-watcher and enable ExternalArtifact on helm-controller. Who: not selected. Generated. Not run on a cluster.
  • Once the destination is known. The target needs an OCIRepository named aicr-bundle in flux-system that points at the published AICR artifact. Who: not selected. Not run.

Read what a plan is, and why some entries have one.

1. Get the exact objects Run for this entry

The Catalog rendered this entry and retains its 29 objects as files that one inventory lists.

# make the directories the inventory names
$ mkdir -p aicr-eks-h100-training-kubeflow-v0-14-0-base aicr-eks-h100-training-kubeflow-v0-14-0-base/aws-ebs-csi-driver aicr-eks-h100-training-kubeflow-v0-14-0-base/aws-efa aicr-eks-h100-training-kubeflow-v0-14-0-base/cert-manager aicr-eks-h100-training-kubeflow-v0-14-0-base/gpu-operator aicr-eks-h100-training-kubeflow-v0-14-0-base/k8s-ephemeral-storage-metrics aicr-eks-h100-training-kubeflow-v0-14-0-base/kai-scheduler aicr-eks-h100-training-kubeflow-v0-14-0-base/kube-prometheus-stack aicr-eks-h100-training-kubeflow-v0-14-0-base/kubeflow-trainer aicr-eks-h100-training-kubeflow-v0-14-0-base/kubeflow-trainer-post aicr-eks-h100-training-kubeflow-v0-14-0-base/kubeflow-trainer-post/templates/components/kubeflow-trainer/manifests aicr-eks-h100-training-kubeflow-v0-14-0-base/nfd aicr-eks-h100-training-kubeflow-v0-14-0-base/nodewright-customizations aicr-eks-h100-training-kubeflow-v0-14-0-base/nodewright-customizations/templates/components/nodewright-customizations/manifests aicr-eks-h100-training-kubeflow-v0-14-0-base/nodewright-operator aicr-eks-h100-training-kubeflow-v0-14-0-base/nvidia-dra-driver-gpu aicr-eks-h100-training-kubeflow-v0-14-0-base/nvsentinel aicr-eks-h100-training-kubeflow-v0-14-0-base/prometheus-adapter aicr-eks-h100-training-kubeflow-v0-14-0-base/prometheus-operator-crds aicr-eks-h100-training-kubeflow-v0-14-0-base/sources

# fetch the inventory, then every file it lists
$ curl -fsSL -o aicr-eks-h100-training-kubeflow-v0-14-0-base/checksums.txt https://raw.githubusercontent.com/confighub/helm-expt/main/examples/aicr/eks-h100-training-kubeflow/flux-oci-bundle/checksums.txt

$ cut -c67- aicr-eks-h100-training-kubeflow-v0-14-0-base/checksums.txt | xargs -I{} curl -fsSL -o aicr-eks-h100-training-kubeflow-v0-14-0-base/{} https://raw.githubusercontent.com/confighub/helm-expt/main/examples/aicr/eks-h100-training-kubeflow/flux-oci-bundle/{}

# check every file against the inventory
$ (cd aicr-eks-h100-training-kubeflow-v0-14-0-base && shasum -a 256 -c checksums.txt)

# check the inventory against the listing digest
$ shasum -a 256 aicr-eks-h100-training-kubeflow-v0-14-0-base/checksums.txt
6d3e39557e3274037fc57cc1ba437ea3c96d0b4f72effc7b037608bb44488104  aicr-eks-h100-training-kubeflow-v0-14-0-base/checksums.txt

2. Compare with another version or base Not available yet

The other Catalog entries for this source retain a different object shape, so no object comparison is given. A sibling retained in the same shape as this entry would make this step available. This version has one other base in the Catalog, argocd. The Catalog holds 4 other versions, v0.18.0, v0.19.0, v0.20.0 and v1.0.0.

3. Upload it as a variant Not available yet

This entry is not published, so there is no public artifact to upload. The listing records its literal configuration bundle as held only as a local layout. Publishing the rendered objects as that bundle, with a receipt, would make this step available.

4. Deploy it Partly run for this entry

A delivery is partly recorded for this entry, and no run has passed. Argo CD has not run, Flux is partly recorded, and kubectl has no record. Read the record that states this.

5. Promote a change Not available yet

This step needs an upload command from step 3, and this entry has none. A published artifact for this entry, with a receipt, would make this step available.

Technical notes and disclaimers

  • This entry is a set of Argo CD Applications, so a test needs Argo CD. The Catalog has no test script for it.

Generated from the committed markdown file docs/demo/aicr/eks-h100-training-kubeflow.md. The source file is the authoritative version.