Introduction
Flux CD is a CNCF graduated GitOps toolkit for Kubernetes. It continuously reconciles your cluster state with declarations in Git — when you push a change to your repository, Flux automatically applies it to the cluster. Managing Flux with Ansible lets you bootstrap multiple clusters, configure Git sources, and set up deployment pipelines as code.
Prerequisites
pip install kubernetes openshift
ansible-galaxy collection install kubernetes.core community.general
Bootstrap Flux with Ansible
---
- name: Bootstrap Flux CD on Kubernetes
hosts: localhost
connection: local
vars:
flux_version: "2.4.0"
github_owner: "myorg"
github_repo: "fleet-config"
github_token: "{{ vault_github_token }}"
cluster_name: "production"
tasks:
- name: Install Flux CLI
ansible.builtin.get_url:
url: "https://github.com/fluxcd/flux2/releases/download/v{{ flux_version }}/flux_{{ flux_version }}_linux_amd64.tar.gz"
dest: /tmp/flux.tar.gz
- name: Extract Flux CLI
ansible.builtin.unarchive:
src: /tmp/flux.tar.gz
dest: /usr/local/bin/
remote_src: true
- name: Check Flux prerequisites
ansible.builtin.command:
cmd: flux check --pre
register: flux_check
changed_when: false
- name: Bootstrap Flux with GitHub
ansible.builtin.command:
cmd: >
flux bootstrap github
--owner={{ github_owner }}
--repository={{ github_repo }}
--branch=main
--path=clusters/{{ cluster_name }}
--personal
environment:
GITHUB_TOKEN: "{{ github_token }}"
register: bootstrap
changed_when: "'configured' in bootstrap.stdout"
- name: Verify Flux installation
ansible.builtin.command:
cmd: flux check
register: verify
changed_when: false
- name: Show Flux status
ansible.builtin.debug:
msg: "{{ verify.stdout }}"
Configure Git Sources
- name: Configure Flux GitRepository sources
hosts: localhost
connection: local
tasks:
- name: Create application Git source
kubernetes.core.k8s:
state: present
definition:
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app
namespace: flux-system
spec:
interval: 1m
url: "https://github.com/{{ github_owner }}/my-app"
ref:
branch: main
secretRef:
name: github-auth
- name: Create Helm repository source
kubernetes.core.k8s:
state: present
definition:
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: bitnami
namespace: flux-system
spec:
interval: 30m
url: "https://charts.bitnami.com/bitnami"
Deploy Applications with Kustomization
- name: Configure Flux Kustomizations
hosts: localhost
connection: local
tasks:
- name: Deploy app with Kustomization
kubernetes.core.k8s:
state: present
definition:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
namespace: flux-system
spec:
interval: 10m
targetNamespace: production
sourceRef:
kind: GitRepository
name: my-app
path: ./deploy/production
prune: true
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: my-app
namespace: production
timeout: 5m
- name: Deploy infrastructure components
kubernetes.core.k8s:
state: present
definition:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 30m
sourceRef:
kind: GitRepository
name: fleet-config
path: ./infrastructure
prune: true
dependsOn:
- name: cert-manager
- name: ingress-nginx
HelmRelease Deployments
- name: Deploy Helm charts via Flux
hosts: localhost
connection: local
tasks:
- name: Deploy Redis via HelmRelease
kubernetes.core.k8s:
state: present
definition:
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: redis
namespace: production
spec:
interval: 30m
chart:
spec:
chart: redis
version: "18.x"
sourceRef:
kind: HelmRepository
name: bitnami
namespace: flux-system
values:
architecture: replication
replica:
replicaCount: 3
auth:
existingSecret: redis-password
metrics:
enabled: true
Multi-Cluster Setup
---
- name: Bootstrap Flux on multiple clusters
hosts: localhost
connection: local
vars:
clusters:
- name: staging
context: staging-cluster
path: clusters/staging
- name: production
context: production-cluster
path: clusters/production
tasks:
- name: Bootstrap each cluster
ansible.builtin.command:
cmd: >
flux bootstrap github
--context={{ item.context }}
--owner={{ github_owner }}
--repository={{ github_repo }}
--branch=main
--path={{ item.path }}
--personal
environment:
GITHUB_TOKEN: "{{ github_token }}"
loop: "{{ clusters }}"
register: results
changed_when: "'configured' in results.stdout"
Troubleshooting
# Check all Flux resources
flux get all
# Check specific source
flux get sources git
# Check kustomization status
flux get kustomizations
# Force reconciliation
flux reconcile kustomization my-app --with-source
# View Flux logs
flux logs --all-namespaces
# Suspend/resume reconciliation
flux suspend kustomization my-app
flux resume kustomization my-app
Related Articles
- Ansible Kubernetes Guide
- Ansible Helm Chart Deployments
- Ansible CI/CD with GitHub Actions
- Ansible GitLab CI/CD Integration
- Ansible Istio Service Mesh
Conclusion
Ansible + Flux creates a powerful GitOps pipeline: use Ansible to bootstrap and configure Flux across clusters, then let Flux continuously reconcile your desired state from Git. This combination gives you infrastructure-as-code provisioning (Ansible) plus continuous delivery (Flux) in a single workflow.
Further reading
To go deeper, Ansible for Kubernetes by Example expands on these patterns in production.