Configuring GitOps with Flux CD
This tutorial walks through deploying OpenChoreo resources using Flux CD and a sample GitOps repository. You will fork the repository, point Flux at your fork, and watch platform infrastructure and a sample Component deploy automatically. Then you will promote the Component from the development Environment to staging and production by committing ReleaseBinding manifests to Git.
What you will learn:
- How Flux CD syncs OpenChoreo resources from Git
- The structure of a GitOps repository for OpenChoreo (platform vs. projects)
- How ComponentReleases and ReleaseBindings drive environment promotion
- How to promote across the development β staging β production pipeline
Prerequisitesβ
Before you begin, ensure you have:
- OpenChoreo installed in your Kubernetes cluster (see Run Locally or the Deployment Topology guide for production setup)
- Flux CD installed in your cluster - see the official Flux CD installation docs. Note that only the
source-controllerandkustomize-controllerare required - kubectl configured to access your cluster
- git CLI installed
- A GitHub account (to fork the sample repository)
This tutorial assumes you are using the k3d local setup from the "Try It Out" guide. If you are using a different cluster, adjust hostnames and ports accordingly.
Step 1: Fork and Clone the Sample Repositoryβ
First, fork the sample GitOps repository to your GitHub account:
- Navigate to https://github.com/openchoreo/sample-gitops
- Click the Fork button in the top-right corner
- Clone your fork locally:
git clone https://github.com/<your-github-username>/sample-gitops.git
cd sample-gitops
Repository Structureβ
The repository is organized to separate platform-level resources from application resources:
.
βββ flux/ # Flux CD configuration
β βββ gitrepository.yaml # Points Flux to this repo
β βββ namespaces-kustomization.yaml # Syncs namespaces/
β βββ platform-shared-kustomization.yaml # Syncs platform-shared/
β βββ oc-demo-platform-kustomization.yaml # Syncs platform/ (depends on namespaces, platform-shared)
β βββ oc-demo-projects-kustomization.yaml # Syncs projects/ (depends on platform)
β
βββ platform-shared/ # cluster-scoped resources
β βββ cluster-workflow-templates/
β βββ argo/
β βββ docker.yaml
β βββ bulk-gitops-release-template.yaml
β
βββ namespaces/ # namespace-scoped resources
βββ <namespace>/
βββ namespace.yaml
β
βββ platform/ # platform-level resources (managed by platform team)
β βββ infra/
β β βββ deployment-pipelines/
β β β βββ standard.yaml
β β βββ environments/
β β βββ development.yaml
β β βββ staging.yaml
β β βββ production.yaml
β βββ component-types/
β β βββ service.yaml
β β βββ webapp.yaml
β β βββ scheduled-task.yaml
β βββ traits/
β β βββ persistent-volume.yaml
β β βββ api-management.yaml
β βββ component-workflows/
β β βββ docker-with-gitops.yaml
β βββ workflows/
β βββ bulk-gitops-release.yaml
β
βββ projects/ # application resources (managed by development teams)
βββ <project-name>/
βββ project.yaml
βββ components/
βββ <component-name>/
βββ component.yaml
βββ workload.yaml
βββ releases/
β βββ <component>-<date>-<revision>.yaml
βββ release-bindings/
βββ <component>-development.yaml
βββ <component>-staging.yaml
The platform/ directory is synced first, ensuring Environments, DataPlanes, and ComponentTypes exist before any Components are created. Flux enforces this ordering through the dependsOn field in oc-demo-projects-kustomization.yaml.
Step 2: Update the Git Repository URLβ
Flux needs to know where to find your fork. Edit the flux/gitrepository.yaml file to point to your forked repository.
Open flux/gitrepository.yaml and update the url field:
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: sample-gitops
namespace: flux-system
spec:
interval: 1m
url: https://github.com/<your-github-username>/sample-gitops
ref:
branch: main
If your fork is a private repository, you will need to configure a Flux secret for Git authentication. See the Flux secret create guide for details.
Step 3: Apply the Flux Resourcesβ
Apply all Flux resources to your cluster:
kubectl apply -f flux/
This creates five resources:
- GitRepository (
sample-gitops): Tells Flux to monitor your fork - Kustomization (
namespaces): Syncs thenamespaces/directory (namespace definitions) - Kustomization (
platform-shared): Syncs theplatform-shared/directory (cluster-scoped resources) - Kustomization (
oc-demo-platform): Syncs thenamespaces/default/platform/directory (depends on namespaces and platform-shared) - Kustomization (
oc-demo-projects): Syncs thenamespaces/default/projects/directory (depends on platform being ready first)
Verify the Flux resources were created:
kubectl get gitrepository,kustomization -n flux-system
To trigger an immediate sync instead of waiting for the interval:
kubectl annotate gitrepository -n flux-system sample-gitops \
reconcile.fluxcd.io/requestedAt="$(date +%s)" --overwrite
Step 4: Verify Platform Resourcesβ
Within 1-2 minutes, Flux syncs the namespaces/default/platform/ directory. Verify the platform resources were created:
kubectl get environments # β development, staging, production
kubectl get dataplanes # β default
kubectl get deploymentpipelines # β standard
kubectl get componenttypes # β deployment/service, deployment/web-application, deployment/scheduled-task
The standard DeploymentPipeline defines the promotion flow: development β staging (auto-promote) β production (requires approval).
Step 5: Verify Application Resourcesβ
After the platform is ready, Flux syncs the namespaces/default/projects/ directory. Verify that your application resources have been created:
kubectl get projects
kubectl get components
kubectl get componentreleases
kubectl get releasebindings
You should see the Projects, Components, ComponentReleases, and ReleaseBindings that correspond to the manifests in your namespaces/default/projects/ directory.
Step 6: How a Component Gets Deployedβ
In OpenChoreo, deploying a Component to an Environment requires three key resources in the namespaces/default/projects/ directory:
- Component β defines the application, its ComponentType, and configuration parameters
- ComponentRelease β an immutable snapshot capturing the exact state of the Component, its ComponentType, and Workload at a point in time
- ReleaseBinding β binds a ComponentRelease to a specific Environment, triggering OpenChoreo to render and deploy the actual Kubernetes resources (Deployment, Service, etc.)
In a GitOps workflow, you commit all three as YAML manifests. The sample repository already includes a ReleaseBinding for the development Environment, so your Component was deployed automatically when Flux synced in the previous step.
To verify the deployment is running:
kubectl get releasebindings -o wide
kubectl get deployments -A
kubectl get pods -A
The READY column on your ReleaseBindings should show True.
To deploy to additional Environments, you create new ReleaseBinding manifests that reference the same ComponentRelease but target a different Environment. The following steps demonstrate this promotion workflow.
Step 7: Promote a Componentβ
Key concept: To promote a Component to a new Environment, you create a ReleaseBinding in Git that binds the same ComponentRelease to the target Environment. Flux syncs the new file, and OpenChoreo deploys to that Environment.
Create a new file namespaces/default/projects/demo-project-gitops/components/greeter-service-gitops/release-bindings/greeter-service-gitops-staging.yaml:
apiVersion: openchoreo.dev/v1alpha1
kind: ReleaseBinding
metadata:
name: greeter-service-gitops-staging
namespace: default
spec:
environment: staging
owner:
componentName: greeter-service-gitops
projectName: demo-project-gitops
releaseName: greeter-service-gitops-70168a71
Commit and push the change:
git add namespaces/default/projects/demo-project-gitops/components/greeter-service-gitops/release-bindings/greeter-service-gitops-staging.yaml
git commit -m "Promote greeter-service-gitops to staging"
git push origin main
Force Flux to sync immediately and verify the deployment:
kubectl annotate kustomization -n flux-system oc-demo-projects \
reconcile.fluxcd.io/requestedAt="$(date +%s)" --overwrite
kubectl get releasebinding greeter-service-gitops-staging -o wide
kubectl get deployment,pods -A | grep greeter
The same ComponentRelease (greeter-service-gitops-70168a71) is now deployed to both development and staging. This is the power of the ReleaseBinding model: one immutable release, multiple Environments.
Step 8: Deploy a New Versionβ
The repository contains a second ComponentRelease (greeter-service-gitops-a9b44f18). To deploy a new version, update the development ReleaseBinding to reference the new release.
Edit namespaces/default/projects/demo-project-gitops/components/greeter-service-gitops/release-bindings/greeter-service-gitops-development.yaml and change the releaseName:
spec:
releaseName: greeter-service-gitops-a9b44f18 # Updated from 70168a71
Commit and push:
git add namespaces/default/projects/demo-project-gitops/components/greeter-service-gitops/release-bindings/greeter-service-gitops-development.yaml
git commit -m "Deploy new version of greeter-service to development"
git push origin main
Staging and production still run the previous version (70168a71). This is the standard GitOps progressive delivery pattern: deploy to development first, verify, then update staging and production bindings when ready.
To roll back, revert the releaseName in the ReleaseBinding to the previous ComponentRelease name and push. OpenChoreo handles the rest.
Step 9: Add Environment-Specific Overridesβ
Different Environments often need different configurations β for example, a staging Environment might use a different database endpoint or log level than development. In OpenChoreo, the ReleaseBinding is where you define these environment-specific overrides.
The ReleaseBinding supports three types of overrides:
componentTypeEnvOverridesβ override ComponentType parameters for a specific EnvironmenttraitOverridesβ override Trait configurations for a specific EnvironmentworkloadOverridesβ override workload-level settings such as environment variables and file mounts
This approach keeps the ComponentRelease immutable β the same release artifact is deployed everywhere, with only the configuration varying per Environment.
See the ReleaseBinding API reference for full details on available override fields.
Summaryβ
Congratulations! You've successfully:
- Forked and configured a GitOps repository for OpenChoreo
- Used Flux CD to automatically sync platform infrastructure and application resources
- Deployed a Component to the development Environment through Git
- Promoted the Component to staging and production by creating ReleaseBindings in Git
- Deployed a new version to development while keeping other Environments on the previous version
What to explore next:
- GitOps Overview - Deep dive into repository patterns and best practices
- Getting Started - Reference guide for Flux configuration options
- DeploymentPipeline API - Customize promotion paths and approval gates
- ReleaseBinding API - Environment-specific overrides and workload customization
Advanced flows:
- Build and Release Workflows - Automate container builds and GitOps releases using ComponentWorkflows
- Bulk Promote - Promote multiple components to an environment in a single operation
Clean Upβ
To remove the Flux resources:
kubectl delete -f flux/