GitOps Patterns for Multi-Cloud (2025)
GitOps has evolved significantly to address the complexities of multi-cloud environments. This guide presents modern GitOps patterns for 2025 that enable reliable, consistent management of infrastructure and applications across AWS, Azure, and GCP.
Core GitOps Principles: 2025 Edition
The foundational principles of GitOps have expanded to accommodate multi-cloud realities:
Declarative Infrastructure - All infrastructure, not just applications, is defined declaratively
Git as Single Source of Truth - All changes across clouds are tracked in version control
Pull-Based Deployments - Controllers in each cloud pull desired state from Git
Continuous Reconciliation - System automatically corrects drift from the desired state
Immutable Infrastructure - Resources are replaced, not modified
Security by Default - Security controls are embedded in the GitOps workflow
Observability Integration - GitOps workflows emit metrics, logs, and traces
Implementation Architecture
Centralized vs. Federated GitOps Models
1. Centralized Model
In a centralized model, a single Git repository contains configurations for all clouds, with separate directories for each provider:
infrastructure/
├── aws/
│ ├── eks/
│ ├── networking/
│ └── security/
├── azure/
│ ├── aks/
│ ├── networking/
│ └── security/
└── gcp/
├── gke/
├── networking/
└── security/
Benefits:
Unified view across all environments
Consistent policies and patterns
Simplified cross-cloud orchestration
Single approval workflow
Challenges:
Repository can become large and complex
Teams may have different cloud ownership
Security boundaries might be more complex
Example implementation with Flux:
# Root Kustomization for multi-cloud deployment
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 10m
path: ./infrastructure
prune: true
sourceRef:
kind: GitRepository
name: flux-system
---
# Cloud-specific Kustomizations
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: aws-infrastructure
namespace: flux-system
spec:
dependsOn:
- name: infrastructure
interval: 10m
path: ./infrastructure/aws
prune: true
sourceRef:
kind: GitRepository
name: flux-system
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: azure-infrastructure
namespace: flux-system
spec:
dependsOn:
- name: infrastructure
interval: 10m
path: ./infrastructure/azure
prune: true
sourceRef:
kind: GitRepository
name: flux-system
2. Federated Model
In a federated model, separate repositories exist for each cloud provider with a "meta-repo" that references them:
# Meta repository structure
fleet/
├── aws-fleet.yaml
├── azure-fleet.yaml
└── gcp-fleet.yaml
Each cloud-specific repository contains its own configuration:
# aws-infrastructure repository
eks/
networking/
security/
Benefits:
Clear separation of concerns
Independent team ownership
Granular access control
Smaller, more focused repositories
Challenges:
Cross-cloud coordination is more complex
Requires additional synchronization mechanisms
Can be challenging to implement holistic policies
Example implementation with ArgoCD:
# Application of applications pattern
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: fleet-of-clouds
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/organization/fleet.git
targetRevision: HEAD
path: .
destination:
server: https://kubernetes.default.svc
namespace: argocd
---
# AWS-specific application in fleet repo
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: aws-infrastructure
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/organization/aws-infrastructure.git
targetRevision: HEAD
path: .
destination:
server: https://kubernetes.default.svc
namespace: aws-infra
Multi-Cloud GitOps Tools
1. Flux
Flux is a set of continuous and progressive delivery solutions for Kubernetes that can be extended to manage cloud resources.
# Example Flux Terraform Controller deployment
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
name: terraform-aws
namespace: flux-system
spec:
interval: 1m
url: https://github.com/organization/terraform-aws
ref:
branch: main
---
apiVersion: infra.contrib.fluxcd.io/v1alpha1
kind: Terraform
metadata:
name: aws-vpc
namespace: flux-system
spec:
interval: 10m
path: ./vpc
sourceRef:
kind: GitRepository
name: terraform-aws
approvePlan: auto
writeOutputsToSecret:
name: aws-vpc-outputs
2. ArgoCD
ArgoCD is a declarative GitOps continuous delivery tool for Kubernetes that can be extended with plugins for multi-cloud scenarios.
# ArgoCD with AWS plugin
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: aws-resources
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/organization/aws-resources.git
targetRevision: HEAD
path: .
plugin:
name: argocd-vault-plugin
destination:
server: https://kubernetes.default.svc
namespace: aws-resources
3. Crossplane
Crossplane is a control plane that enables platform teams to create cloud-native applications using managed services from multiple providers.
# Crossplane AWS VPC configuration
apiVersion: ec2.aws.crossplane.io/v1beta1
kind: VPC
metadata:
name: production-vpc
spec:
forProvider:
region: us-west-2
cidrBlock: 10.0.0.0/16
enableDnsSupport: true
enableDnsHostNames: true
tags:
environment: production
providerConfigRef:
name: aws-provider
Advanced GitOps Patterns
1. Multi-Cluster Configuration Management
For organizations managing multiple Kubernetes clusters across different clouds:
# Centralized configuration with cluster-specific overlays
clusters/
├── base/
│ ├── monitoring/
│ │ └── prometheus.yaml
│ └── security/
│ └── network-policies.yaml
└── overlays/
├── aws-prod/
│ ├── kustomization.yaml
│ └── monitoring/
│ └── prometheus-aws.yaml
├── azure-prod/
│ ├── kustomization.yaml
│ └── monitoring/
│ └── prometheus-azure.yaml
└── gcp-prod/
├── kustomization.yaml
└── monitoring/
└── prometheus-gcp.yaml
2. Progressive Delivery Across Clouds
Implementing canary and blue/green deployments across multiple cloud environments:
# Flux Canary Release for multi-cloud
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: podinfo
namespace: podinfo
spec:
interval: 5m
chart:
spec:
chart: podinfo
version: '>=6.0.0'
sourceRef:
kind: HelmRepository
name: podinfo
values:
replicaCount: 3
upgrade:
# Gradual rollout across clusters
remediation:
remediateLastFailure: true
strategy:
canary:
steps:
- setWeight: 5
- pause: {duration: 5m}
- setWeight: 20
- pause: {duration: 10m}
- setWeight: 50
- pause: {duration: 10m}
3. Policy-as-Code Integration
Enforcing consistent policies across all cloud environments:
# OPA/Gatekeeper constraint template
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
4. Secret Management in GitOps Workflows
Secure handling of secrets across multiple clouds:
# External Secrets Operator with AWS Parameter Store
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: aws-secret
spec:
refreshInterval: "1h"
secretStoreRef:
name: aws-parameterstore
kind: ClusterSecretStore
target:
name: application-secrets
creationPolicy: Owner
data:
- secretKey: dbPassword
remoteRef:
key: /myapp/production/db-password
CI/CD Integration with GitOps
1. Pull Request Workflows
Modern GitOps implementations include CI processes that validate changes before they're merged:
# GitHub Actions workflow for multi-cloud validation
name: Validate Changes
on:
pull_request:
branches: [ main ]
paths:
- 'infrastructure/**'
jobs:
validate:
runs-on: ubuntu-latest
strategy:
matrix:
provider: [aws, azure, gcp]
include:
- provider: aws
workdir: ./infrastructure/aws
validate_cmd: terraform validate
- provider: azure
workdir: ./infrastructure/azure
validate_cmd: az bicep build --file main.bicep
- provider: gcp
workdir: ./infrastructure/gcp
validate_cmd: gcloud beta terraform vet
steps:
- uses: actions/checkout@v3
- name: Setup provider tools
run: |
if [ "${{ matrix.provider }}" == "aws" ]; then
# AWS setup
curl -s "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# Install Terraform
curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
sudo apt-get update && sudo apt-get install terraform
elif [ "${{ matrix.provider }}" == "azure" ]; then
# Azure setup
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az bicep install
elif [ "${{ matrix.provider }}" == "gcp" ]; then
# GCP setup
echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key --keyring /usr/share/keyrings/cloud.google.gpg add -
sudo apt-get update && sudo apt-get install google-cloud-sdk
fi
- name: Validate ${{ matrix.provider }} configuration
working-directory: ${{ matrix.workdir }}
run: ${{ matrix.validate_cmd }}
- name: Run Policy Checks
uses: open-policy-agent/conftest-action@v2.0.0
with:
files: ${{ matrix.workdir }}
policy: ./policies/${{ matrix.provider }}
2. Post-Merge Verification
After changes are merged to the main branch, automated processes verify successful application:
# GitLab CI post-merge verification
stages:
- validate
- apply
- verify
verify-aws:
stage: verify
script:
- aws cloudformation describe-stacks --stack-name production-stack --query "Stacks[0].StackStatus" | grep -q "COMPLETE"
- aws eks describe-cluster --name production --query "cluster.status" | grep -q "ACTIVE"
only:
- main
verify-azure:
stage: verify
script:
- az deployment group show --name production-deployment --resource-group production --query "properties.provisioningState" | grep -q "Succeeded"
only:
- main
verify-gcp:
stage: verify
script:
- gcloud deployment-manager deployments describe production --format="json" | jq '.operation.status' | grep -q "DONE"
only:
- main
Multi-Cloud GitOps Best Practices
Adopt Common Tooling: Use the same GitOps tools across clouds when possible
Define Consistent Patterns: Create templates and standards that work across providers
Implement Strong RBAC: Use granular permissions to control who can change what
Cross-Cloud Testing: Implement testing across all target environments
Standardize Observability: Use consistent monitoring and alerting across clouds
Automate Drift Detection: Implement regular checks for configuration drift
Document Failure Modes: Plan for GitOps controller failures or Git outages
Implement Backup Strategies: Ensure GitOps state can be recovered
Real-World Examples
Example 1: Financial Services Multi-Cloud Deployment
A financial services company implements GitOps across AWS (primary) and Azure (secondary) for regulatory compliance:
# ArgoCD ApplicationSet for multi-region deployment
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: financial-application
spec:
generators:
- list:
elements:
- cloud: aws
region: us-east-1
clusterUrl: https://aws-east.example.com
- cloud: aws
region: us-west-2
clusterUrl: https://aws-west.example.com
- cloud: azure
region: eastus
clusterUrl: https://azure-east.example.com
template:
metadata:
name: '{{cloud}}-{{region}}-app'
spec:
project: default
source:
repoURL: https://github.com/financial-org/app-configs.git
targetRevision: main
path: overlays/{{cloud}}/{{region}}
destination:
server: '{{clusterUrl}}'
namespace: financial-app
syncPolicy:
automated:
prune: true
selfHeal: true
Example 2: Retail Company with Edge Locations
A retail company manages Kubernetes clusters across AWS, Azure, and edge locations:
# Flux deployment with multi-type structure
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: retail-infrastructure
namespace: flux-system
spec:
interval: 10m
path: ./base
prune: true
sourceRef:
kind: GitRepository
name: retail-infrastructure
postBuild:
substituteFrom:
- kind: ConfigMap
name: cluster-config
---
# ConfigMap with cluster-specific values
apiVersion: v1
kind: ConfigMap
metadata:
name: cluster-config
namespace: flux-system
data:
CLUSTER_TYPE: "EDGE" # Alternative: AWS, AZURE
REGION: "store-1234"
RESOURCE_TIER: "small" # Depends on the location's size
Conclusion
Modern GitOps patterns enable organizations to maintain consistency across multi-cloud environments while respecting the unique characteristics of each provider. By implementing these patterns, teams can achieve greater reliability, improved security, and faster deployment cycles across their entire infrastructure.
Resources
Last updated