Your Cloud, Your Code: Dive into Everything as Code with GitOps Principles in Google Cloud
The DevOps movement has long strived for automation and consistency across the software development lifecycle. GitOps emerged as a powerful operating model, particularly for cloud-native environments like Kubernetes. It emphasises a Git repository as the single source of truth for declarative infrastructure and application configuration. But can we push this further?
The concept of “Everything as Code” represents the ultimate goal: extending declarative, version-controlled principles to the entire CI/CD process and beyond. It’s about creating a fully automated, auditable, and reliable system for building, securing, deploying, and managing applications and infrastructure. Let’s explore how to achieve this vision on Google Cloud Platform (GCP).
The “Everything as Code” Vision
Imagine a seamless flow where every component of your system is defined declaratively and managed through Git workflows:
- Trigger: A developer pushes code changes to an application repository.
- CI (Continuous Integration): A Git event automatically triggers a CI pipeline defined as code. This pipeline builds the application, runs tests, performs security scans (DevSecOps), and pushes immutable artifacts (like container images) to a registry.
- Configuration Update: The CI pipeline automatically updates the application’s deployment configuration (e.g., image tag) in a separate configuration Git repository.
- CD (Continuous Deployment): A GitOps controller (Config Sync in GCP) continuously monitors the configuration repository. Upon detecting changes, it pulls the new desired state and automatically reconciles the target environments (Dev, Staging, Prod) to match.
- Infrastructure & Policy: The underlying infrastructure (Kubernetes clusters, databases, etc.) and security/compliance policies are also defined declaratively in Git and managed through similar automated processes, with policy enforcement handled by tools like Policy Controller in GCP.
- Monitoring & Feedback: The entire system is continuously monitored, providing feedback and ensuring compliance.
This closed-loop system, entirely driven by code stored in Git, minimizes manual intervention, increases velocity, enhances security, and provides complete auditability.
Mapping the Vision to Google Cloud Platform Services
GCP offers a rich set of managed services that map perfectly to this “Everything as Code” model:
- Source Control: Cloud Source Repositories (or GitHub/Bitbucket connected via Cloud Build). Hosts your application code and declarative configuration.
- CI (Continuous Integration): Cloud Build. GCP’s serverless CI/CD platform. Pipelines are defined declaratively in
cloudbuild.yamlfiles stored alongside your code. - Artifact Management: Artifact Registry. A fully managed service to store, manage, and secure container images, language packages (Maven, npm, Python), and OS packages. It integrates vulnerability scanning.
- CD (Continuous Deployment — GitOps Sync): Config Sync (part of GKE Enterprise). Deployed on Google Kubernetes Engine (GKE) clusters, Config Sync continuously monitors your configuration repository (like Cloud Source Repositories) and automatically applies manifests (YAML, Helm charts, Kustomize overlays) to keep clusters synchronized with the desired state defined in Git.
- Policy Enforcement: Policy Controller (part of GKE Enterprise). Enforces custom policies (constraints) on your GKE clusters based on the OPA Gatekeeper project, ensuring security and compliance guardrails.
- Infrastructure/Cluster Management: Google Kubernetes Engine (GKE). Managed Kubernetes service. Infrastructure can be provisioned declaratively using Terraform (managed via Cloud Build) or Config Controller (a hosted service that includes Config Sync, Policy Controller, and Config Connector).
- Security & Integration
- Binary Authorization: Enforces signature verification for images deployed to GKE, ensuring only trusted images run.
- Artifact Registry Vulnerability Scanning: Automatically scans container images for known vulnerabilities.
- Security Command Center: Provides centralized visibility into security posture and threats.
Putting It Together: A GCP Workflow Example
Let’s walk through a simplified “Everything as Code” flow on GCP:
1. Developer Push: A developer pushes application code changes to a dedicated application repository in Cloud Source Repositories.
2. Cloud Build Trigger: A Cloud Build trigger, configured to watch the application repository’s main branch, automatically starts a build.
3. CI Pipeline (cloudbuild.yaml): The pipeline, defined in cloudbuild.yaml within the application repo, executes:
YAML
# Example cloudbuild.yaml for Application Repo
steps:
# 1. Build the container image
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPO_NAME}/${_SERVICE_NAME}:$COMMIT_SHA', '.']
id: 'Build'
# 2. Push the image to Artifact Registry
- name: 'gcr.io/cloud-builders/docker'
args: ['push', '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPO_NAME}/${_SERVICE_NAME}:$COMMIT_SHA']
id: 'Push'
# (Optional) Add steps for testing, vulnerability scanning here
# 3. Update configuration in the separate Config Repo
# Clone the config repo, update manifest, push back
# Requires granting Cloud Build service account access to the config repo
- name: 'gcr.io/cloud-builders/gcloud'
entrypoint: /bin/bash
args:
- -c
- |
gcloud source repos clone config-repo --project=$PROJECT_ID && \
cd config-repo && \
# Example: Update Kustomize overlay image tag
kustomize edit set image IMAGE_PLACEHOLDER=${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPO_NAME}/${_SERVICE_NAME}:$COMMIT_SHA && \
# Or update a Helm values.yaml using sed, yq, etc.
git config user.email $(gcloud auth list --filter=status:ACTIVE --format='value(account)') && \
git commit -am "Update image for ${_SERVICE_NAME} to $COMMIT_SHA [Cloud Build]" && \
git push origin main
id: 'Update Config Repo'
images:
- '${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPO_NAME}/${_SERVICE_NAME}:$COMMIT_SHA'
# Define substitutions if needed
# substitutions:
# _LOCATION: 'us-central1'
# _REPO_NAME: 'my-artifact-repo'
# _SERVICE_NAME: 'my-app'(Note: This config update step is illustrative. Ensure proper authentication and error handling.)
4. GitOps Sync (Config Sync):
- Config Sync, running on your GKE cluster(s), has a
RootSyncorRepoSyncresource is configured to watch the configuration repository.
YAML
# Example simplified RootSync resource (apply to cluster)
apiVersion: configsync.gke.io/v1beta1
kind: RootSync
metadata:
name: root-sync # Or a name relevant to the repo/app
namespace: config-management-system # Default namespace for RootSync
spec:
sourceFormat: unstructured # Or 'hierarchy'
git:
repo: https://source.developers.google.com/p/${PROJECT_ID}/r/config-repo # Your Config Repo URL
branch: main
dir: path/to/relevant/configs # Directory within the repo
auth: gcpserviceaccount # Use Workload Identity
gcpServiceAccountEmail: your-ksa-name@${PROJECT_ID}.iam.gserviceaccount.com # KSA mapped to GSA
# For SSH auth:
# auth: ssh
# secretRef:
# name: git-credsGKE Config Sync for more details.
- Config Sync detects the commit made by Cloud Build in the configuration repo.
- It pulls the updated manifests (e.g., the Deployment YAML now pointing to the new image tag) and applies them to the GKE cluster. Kubernetes handles the rolling update.
5. Policy Enforcement (Policy Controller):
- As Config Sync applies resources, Policy Controller intercepts the requests via the admission webhook.
- It checks resources against installed constraints. Example: Ensure all Namespaces have a
teamlabel.
YAML
# Example Constraint (apply via Config Sync)
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
name: ns-must-have-team-label
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels:
- key: "team"(Based on templates from the library)
- If a resource violates a policy (and the policy isn’t in
dryrunmode), the apply operation is rejected.
But there is always a budget friendly option in the market for something expensive!!!
Budget-Friendly Alternative: Cloud Deploy for GitOps Workflows
While GKE Enterprise provides a comprehensive suite of tools including Config Sync and Policy Controller, the licensing costs might be prohibitive for smaller teams or organizations with limited budgets. Fear not — Google Cloud Deploy offers a more cost-effective path to achieving similar GitOps workflows, albeit with some additional manual configuration work.
Cloud Deploy as Your GitOps Engine
Cloud Deploy is Google’s managed continuous delivery service that can serve as an excellent alternative for implementing GitOps principles without requiring GKE Enterprise. Here’s how you can adapt the “Everything as Code” workflow:
Modified Workflow with Cloud Deploy:
- CI Pipeline Integration: Your Cloud Build pipeline remains largely the same, but instead of directly updating a configuration repository, it creates a Cloud Deploy release.
yaml
# Additional step in cloudbuild.yaml
- name: 'gcr.io/cloud-builders/gcloud'
args:
- 'deploy'
- 'releases'
- 'create'
- 'release-$SHORT_SHA'
- '--delivery-pipeline=${_PIPELINE_NAME}'
- '--region=${_REGION}'
- '--images=app=${_LOCATION}-docker.pkg.dev/$PROJECT_ID/${_REPO_NAME}/${_SERVICE_NAME}:$COMMIT_SHA'
id: 'Create Cloud Deploy Release'- Declarative Delivery Pipelines: Define your deployment pipeline as code using Cloud Deploy’s YAML configuration, stored alongside your application code or in a separate GitOps repository.
yaml
# clouddeploy.yaml
apiVersion: deploy.cloud.google.com/v1
kind: DeliveryPipeline
metadata:
name: my-app-pipeline
description: My application delivery pipeline
serialPipeline:
stages:
- targetId: dev
profiles: []
- targetId: staging
profiles: []
- targetId: prod
profiles: []
strategy:
standard:
verify: true
---
apiVersion: deploy.cloud.google.com/v1
kind: Target
metadata:
name: dev
description: Development environment
gke:
cluster: projects/PROJECT_ID/locations/us-central1/clusters/dev-clusterThe Trade-offs:
What you gain with Cloud Deploy:
- Cost Efficiency: No GKE Enterprise licensing required — you only pay for the underlying GKE Standard clusters
- Managed Service: Google handles the deployment orchestration, eliminating the need to manage GitOps operators
- Built-in Approvals: Native support for deployment approvals and rollback capabilities
- Audit Trail: Complete visibility into deployment history and changes
What requires additional work:
- Policy Enforcement: You’ll need to implement policy checks through Cloud Build steps, admission controllers, or other mechanisms rather than Policy Controller
- Configuration Drift Detection: Unlike Config Sync’s continuous reconciliation, you’ll need to implement your own drift detection mechanisms
- Multi-Repository Sync: Managing multiple configuration repositories requires additional automation scripts in your CI pipelines
Making It Work:
To achieve GitOps-like behavior with Cloud Deploy, consider these patterns:
- Store your deployment configurations (Kubernetes manifests, Helm charts) in Git alongside your Cloud Deploy pipeline definitions
- Use Cloud Build triggers on configuration repository changes to create new Cloud Deploy releases
- Implement configuration validation and policy checking as Cloud Build pipeline steps
- Set up monitoring and alerting to detect configuration drift between your Git state and cluster state
While this approach requires more manual orchestration compared to the fully automated GKE Enterprise solution, it provides a pragmatic path to “Everything as Code” principles that’s accessible to budget-conscious teams. You can always migrate to GKE Enterprise later as your organization scales and the ROI justifies the investment.
Benefits on GCP
Adopting “Everything as Code” on GCP using these services provides significant advantages:
- Consistency: Declarative definitions ensure environments are configured identically and reliably.
- Auditability: Git history provides a complete log of all changes — who changed what, when, and why.
- Velocity: Automation accelerates the entire development-to-production process.
- Reliability: Automated reconciliation via Config Sync corrects drift, and Git provides easy rollback capabilities.
- Security: Policies are enforced automatically by Policy Controller, vulnerability scanning is integrated, and infrastructure is managed securely through code.
- Scalability: Easily manage configurations and policies across numerous GKE clusters and GCP resources using GKE Enterprise features.
Conclusion
Achieving “Everything as Code” is no longer just a theoretical ideal. By leveraging the GitOps principles detailed in “The Path to GitOps” and combining the power of GCP services like Cloud Build, Artifact Registry, GKE, Config Sync, and Policy Controller, you can build a truly automated, declarative, and secure end-to-end system. It requires a shift in thinking and an upfront investment in setting up the workflows, but the long-term benefits in terms of speed, reliability, and governance are immense. Start automating your GCP environment today!
Read my other tech blogs
Connect with me on LinkedIn: Rahul Kumar Singh

