DevOps Guides
What Are Infrastructure as Code and GitOps? A Practical Guide to Terraform, OpenTofu, Argo CD and Flux
A practical guide to Infrastructure as Code and GitOps covering Terraform, OpenTofu, state, plan/apply workflows, modules, drift, Argo CD, Flux, secrets, policy-as-code, CI/CD, and a 90-day rollout roadmap.
π‘Key Takeaways
- A practical guide to Infrastructure as Code and GitOps covering Terraform, OpenTofu, state, plan/apply workflows, modules, drift, Argo CD, Flux, secrets, policy-as-code, CI/CD, and a 90-day rollout roadmap.

Image was checked before being inserted into this Markdown file. Extracted from HashiCorp Terraform documentation, PNG file, not SVG.1

Image was checked before being inserted into this Markdown file. Extracted from HashiCorp Terraform documentation, PNG file, not SVG.2

Image was checked before being inserted into this Markdown file. Extracted from Argo CD documentation, PNG file, not SVG.3
Quick summary
Infrastructure as Code, or IaC, means managing infrastructure through version-controlled configuration files that can be reviewed, tested and automated. Instead of manually creating VMs, VPCs, databases, firewall rules, DNS records or Kubernetes resources in a console, you describe the desired state in code and let a tool such as Terraform or OpenTofu create and manage it.
HashiCorp describes Terraform as an infrastructure as code tool that lets you build, change and version cloud and on-prem resources safely and efficiently; its core workflow is Write, Plan and Apply.4 OpenTofu similarly describes itself as an IaC tool for defining cloud and on-prem resources in human-readable configuration files that can be versioned, reused and shared.5
GitOps is an operating model where Git is the source of truth for desired state. Flux describes GitOps as managing infrastructure and applications so that the whole system is described declaratively, version controlled, and automated so the deployed environment matches the state defined in Git repositories.6 Argo CD is a declarative GitOps continuous delivery tool for Kubernetes and follows the pattern of using Git repositories as the source of truth for desired application state.7
Simple version: IaC manages infrastructure as code; GitOps uses Git plus controllers to keep systems aligned with declared state.
Why IaC and GitOps matter
Manual infrastructure management causes common operational problems:
- unclear change history;
- dev/staging/prod drift;
- difficult rollback;
- misconfigured firewalls or security groups;
- unused cloud resources;
- no review before changes;
- documentation diverges from reality;
- deployments depend on a few experts;
- disaster recovery is slow.
IaC and GitOps change the model:
Code in Git
β
Pull Request review
β
Plan / diff / policy check
β
Apply or automatic reconciliation
β
Clear audit trail
Infrastructure and application delivery become more like software delivery: versioned, reviewed, tested, released, rolled back and owned.
What IaC is not
| IaC is | IaC is not |
|---|---|
| Version-controlled infrastructure configuration | Only shell scripts creating servers |
| Plan/diff before changes | Clicking in a cloud console and writing notes later |
| State, modules, policies and review | A random YAML file nobody owns |
| A way to reproduce environments | A guarantee that nothing will fail |
| Requires state and secret security | A place to store plaintext passwords in Git |
| Useful for cloud, on-prem, Kubernetes and SaaS | Only for large cloud platforms |
IaC does not automatically make infrastructure secure. If you write an unsafe security group, IAM policy or Kubernetes manifest, IaC tools can still create unsafe infrastructure. Review, scanning, policy and monitoring are required.
What GitOps is not
| GitOps is | GitOps is not |
|---|---|
| Git as source of truth for desired state | Putting files in Git without process |
| A controller reconciling actual state against Git | Only running kubectl apply in CI |
| Drift detection and auditability | People constantly editing production by hand |
| Strong for Kubernetes and declarative systems | Perfect for every workload in the same way |
| Often pull-based deployment | One mandatory tool |
| Requires secure repos, secrets and controllers | Automatically safe because it uses Git |
Good GitOps requires discipline: do not modify production directly without reflecting the change in Git.
How Terraform and OpenTofu work
Terraform/OpenTofu usually follow three stages:
Write β Plan β Apply
Write
Write configuration files describing desired infrastructure.
Simple example:
resource "aws_s3_bucket" "logs" {
bucket = "company-prod-logs"
}
resource "aws_s3_bucket_versioning" "logs" {
bucket = aws_s3_bucket.logs.id
versioning_configuration {
status = "Enabled"
}
}
Plan
The tool compares configuration, state and real infrastructure, then creates an execution plan.
terraform plan
# or
tofu plan
The plan shows what will be created, updated, replaced or destroyed.
Apply
After review, apply the change:
terraform apply
# or
tofu apply
OpenTofu documents the same core workflow: Write, Plan and Apply.8
What is state and why does it matter?
State maps code resources to real resources.
Example:
aws_instance.web β i-0abcd1234
aws_db_instance.main β real production database
State matters because it:
- drives planning;
- tracks managed resources;
- contains metadata;
- may contain sensitive values;
- is hard to recover if lost;
- can expose infrastructure structure and outputs if leaked.
Recommendations:
- do not use local state for team production;
- use a remote backend;
- enable locking;
- encrypt state;
- restrict state access;
- back up state;
- avoid secret outputs where possible;
- never commit state to Git.
Backends and locking
A remote backend makes team workflows safer.
Example S3 backend with locking:
terraform {
backend "s3" {
bucket = "company-terraform-state"
key = "prod/network/terraform.tfstate"
region = "ap-southeast-1"
dynamodb_table = "terraform-locks"
encrypt = true
}
}
Goals:
- central state storage;
- avoid concurrent apply conflicts;
- audit access;
- simplify backup;
- support CI/CD workflows.
Without locking, two simultaneous applies can corrupt or confuse infrastructure state.
What are modules?
A module packages reusable infrastructure.
Example VPC module:
module "vpc" {
source = "../modules/vpc"
name = "prod"
cidr_block = "10.0.0.0/16"
azs = ["ap-southeast-1a", "ap-southeast-1b"]
}
Benefits:
- standard configuration;
- less copy-paste;
- enforced best practices;
- easier review;
- reusable platform building blocks.
Common mistakes:
- overly complex modules;
- unversioned modules;
- too many inputs;
- outputs leaking secrets;
- breaking module changes without migration plans.
What is drift?
Drift happens when real infrastructure differs from Git/IaC configuration.
Example:
Git: security group allows only port 443
Reality: someone opened port 22 from 0.0.0.0/0 in the cloud console
Mitigations:
- restrict manual changes;
- run plans regularly;
- use drift detection;
- change infrastructure via PRs;
- alert on dangerous drift;
- if emergency changes are made, update code immediately.
GitOps controllers such as Argo CD and Flux also detect drift between desired Git state and live Kubernetes state.
GitOps with Kubernetes
Typical GitOps flow:
Developer / Platform Engineer
β Pull Request
Git repository with manifests/Helm/Kustomize
β
GitOps controller inside cluster
β
Compare desired state with live state
β
Sync / reconcile
β
Kubernetes cluster reaches desired state
Argo CD follows the GitOps pattern and uses Git repositories as source of truth, then automates deployment of desired application states to target environments.9 Flux describes reconciliation as ensuring actual state matches desired state declaratively defined in Git or another source.10
What is Argo CD?
Argo CD is a declarative GitOps continuous delivery tool for Kubernetes.7
Strengths:
- visual UI;
- desired vs live state comparison;
- automatic or manual sync;
- Helm, Kustomize, Jsonnet and plain YAML support;
- multi-cluster management;
- SSO and RBAC;
- rollback to old commits;
- health status;
- audit trails;
- Prometheus metrics.
It is a good fit when teams want clear UI, easier onboarding and strong application visibility.
What is Flux CD?
Flux is a set of GitOps controllers for Kubernetes. Flux concepts describe the GitOps Toolkit as a set of controllers, APIs and Go packages for building continuous delivery workflows on Kubernetes using GitOps principles.11
Strengths:
- Kubernetes-native;
- clear reconciliation model;
- supports GitRepository, OCIRepository, HelmRepository and Bucket sources;
- can use OCI artifacts as sources;
- good automation support;
- integrates well with SOPS/Sealed Secrets and cloud-native workflows.
It is a good fit for teams that prefer declarative CRDs and automation over UI-first operations.
Terraform/OpenTofu vs GitOps
| Criteria | Terraform/OpenTofu | GitOps with Argo CD/Flux |
|---|---|---|
| Goal | create/manage infrastructure through provider APIs | keep Kubernetes/app state aligned with Git |
| Execution | plan/apply, usually CLI or CI | controller continuously reconciles |
| State | state file/backend | desired Git state + live cluster state |
| Scope | cloud resources, DNS, IAM, DB, SaaS, Kubernetes | mainly Kubernetes apps/config |
| Change flow | PR + plan + apply | PR merge + controller sync |
| Drift detection | plan/drift detection | OutOfSync detection |
| Main risk | state/secrets/IAM/accidental destroy | controller privileges, secrets in Git, bad sync |
They often work together:
Terraform/OpenTofu creates cluster + network + IAM + database
Argo CD/Flux deploys applications into the cluster
IaC repository models
Simple monorepo
infra/
modules/
vpc/
eks/
database/
envs/
dev/
staging/
prod/
Good for small teams.
Multi-repo
infra-modules/
infra-live-dev/
infra-live-prod/
platform-gitops/
app-manifests/
Better for larger organizations and permission separation.
App repo + environment repo
app-repo/
src/
Dockerfile
helm-chart/
env-repo/
clusters/
prod/
apps/
checkout/
Common for GitOps: app team builds artifacts; environment repo decides which version runs.
Example GitOps repo structure
gitops/
clusters/
prod/
apps/
checkout/
kustomization.yaml
deployment.yaml
service.yaml
payments/
platform/
ingress/
cert-manager/
monitoring/
staging/
base/
checkout/
payments/
policies/
Principles:
- separate base and overlays;
- separate prod and staging;
- clear ownership;
- no plaintext secrets;
- all changes through PRs;
- branch protection;
- policy scanning before merge.
IaC security
Checklist:
- never commit credentials;
- avoid secret outputs;
- remote encrypted locked state;
- least-privilege IAM for CI/CD;
- plan in pull requests;
- apply only after approval;
- restrict production destroy;
- scan IaC using Checkov, Trivy or tfsec;
- use policy-as-code with OPA/Sentinel/Kyverno where useful;
- pin provider versions;
- review module sources;
- separate workspaces/environments clearly;
- audit cloud changes.
Provider pinning example:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
GitOps security
Checklist:
- branch protection;
- required PR reviews;
- signed commits where needed;
- no plaintext secrets;
- SOPS, Sealed Secrets or External Secrets;
- least-privilege Argo CD/Flux RBAC;
- not everyone is GitOps admin;
- production sync permissions separated;
- admission policies for dangerous manifests;
- image digest pinning;
- signature verification where possible;
- sync history auditing;
- alerts for OutOfSync/Degraded apps;
- backup GitOps repo and controller config.
Secrets in GitOps
Do not commit plaintext Secret YAML:
apiVersion: v1
kind: Secret
data:
password: cGFzc3dvcmQ=
Base64 is not encryption. Use:
- SOPS + KMS/age/PGP;
- Sealed Secrets;
- External Secrets Operator;
- cloud secret managers;
- Vault.
Model:
Git repo
β encrypted secret / external secret reference
GitOps controller
β decrypt or sync from secret manager
Kubernetes Secret
Policy-as-Code
Policy-as-code blocks mistakes before infrastructure or workloads are created.
Example policies:
No public S3 buckets
No security group opening 0.0.0.0/0 port 22
No privileged Kubernetes pods
No latest image tag
Resource limits required
owner/team/environment labels required
Run policy at multiple points:
pre-commit
β
CI pull request
β
Terraform plan policy check
β
Kubernetes admission controller
β
Scheduled drift/compliance scan
CI/CD workflow for IaC
Pull Request
β
terraform fmt / tofu fmt
β
terraform validate / tofu validate
β
IaC security scan
β
terraform plan / tofu plan
β
Comment plan into PR
β
Approval
β
Apply via protected environment
β
Post-apply drift/compliance check
Do not auto-apply production from every branch. Use protected environments and approvals.
GitOps workflow for applications
App code merge
β
CI builds image
β
Scan image + sign image
β
Push registry
β
Update GitOps repo image tag/digest
β
PR review
β
Merge
β
Argo CD/Flux sync
β
Health check + metrics + rollback if needed
For production, pin by digest:
image: registry.example.com/checkout@sha256:abc123...
30/60/90-day rollout roadmap
Days 1β30: IaC foundation
- Inventory manually managed infrastructure.
- Choose Terraform or OpenTofu.
- Create an infrastructure repo.
- Write a small module for network or staging.
- Configure remote backend and locking.
- Enable branch protection.
- Run fmt/validate/plan in PRs.
- Do not commit state or secrets.
- Add basic IaC scanning with Trivy/Checkov.
- Document the workflow.
Days 31β60: standardization and security
- Separate dev/staging/prod.
- Create reusable modules.
- Pin provider and module versions.
- Add policy-as-code.
- Restrict cloud permissions for CI/CD.
- Require approval for production apply.
- Start drift detection.
- Create rollback/state recovery runbook.
- Use a secret manager.
- Add cost/resource dashboard.
Days 61β90: GitOps operations
- Install Argo CD or Flux.
- Create GitOps repo.
- Deploy staging app with GitOps.
- Add SOPS, Sealed Secrets or External Secrets.
- Enable RBAC/SSO for the controller.
- Enforce admission policy.
- Sync first production app.
- Alert on OutOfSync/Degraded apps.
- Create app-of-apps or bootstrap model.
- Review incident scenarios: drift, bad apply, leaked secret.
Common mistakes
- Committing state to Git.
- Storing plaintext secrets in
.tfvars. - One workspace for every environment.
- Not reviewing plans.
- Auto-applying production without approval.
- Using IAM admin for CI/CD.
- Not pinning providers/modules.
- Overly complex modules.
- Editing cloud console without updating code.
- Using GitOps but manually editing the cluster.
- Committing base64 Kubernetes Secrets.
- Giving GitOps controller excessive privileges.
- No drift detection.
- No rollback runbook.
Reference tooling
| Need | Tool |
|---|---|
| Cloud/on-prem IaC | Terraform, OpenTofu |
| IaC scanning | Checkov, Trivy, tfsec |
| Policy-as-code | OPA, Sentinel, Kyverno |
| Kubernetes GitOps | Argo CD, Flux |
| GitOps secrets | SOPS, Sealed Secrets, External Secrets Operator |
| Kubernetes packaging | Helm, Kustomize |
| CI/CD | GitHub Actions, GitLab CI, Jenkins, Tekton |
| State backend | S3/GCS/Azure Storage/HCP Terraform/cloud backend |
| Cost visibility | Infracost, cloud cost tools |
| Drift detection | scheduled Terraform plan, Argo CD/Flux sync status |
FAQ
What is Infrastructure as Code?
Infrastructure as Code means defining and managing infrastructure in configuration files that can be versioned, reviewed, reused and automated. Terraform and OpenTofu are popular IaC tools.45
What is GitOps?
GitOps manages infrastructure and applications using desired state in Git plus automation that ensures deployed environments match that Git state.6
How are Terraform and OpenTofu different?
Terraform is HashiCorpβs IaC tool. OpenTofu is a community IaC tool forked from Terraform and governed in the Linux Foundation ecosystem. Both follow a similar Write, Plan, Apply workflow.45
How are Argo CD and Flux different?
Argo CD is strong in UI, application views and observability of GitOps state. Flux is Kubernetes-native, controller-oriented and automation-friendly. Both implement GitOps principles for Kubernetes.
Should GitOps manage everything?
Not necessarily. GitOps is excellent for Kubernetes and declarative workloads. Terraform/OpenTofu is often better for VPCs, IAM, databases, DNS and cloud resources. Many teams use both.
Should secrets live in a GitOps repo?
Not as plaintext. Use SOPS, Sealed Secrets or External Secrets; for sensitive systems, prefer a real secret manager.
Conclusion
Infrastructure as Code and GitOps are core foundations of modern DevOps. IaC gives infrastructure versioning, review, plan/apply workflows and reproducibility. GitOps gives Kubernetes/application delivery a clear source of truth, drift detection and automated reconciliation. Used together, they reduce manual operations, improve auditability, simplify rollback and standardize operations.
Start small: move one infrastructure area into Terraform/OpenTofu, secure remote state, run plans in PRs, add scanning and policy, then expand into GitOps with Argo CD or Flux. Security must be included from the beginning: never commit secrets, avoid overpowered CI/CD credentials, do not auto-apply production without approval, and do not give GitOps controllers more privileges than needed.
References
Footnotes
-
HashiCorp Terraform docs image.
intro-terraform-apis.png. https://web-unified-docs-hashicorp.vercel.app/api/assets/terraform/latest/img/docs/intro-terraform-apis.png β© -
HashiCorp Terraform docs image.
intro-terraform-workflow.png. https://web-unified-docs-hashicorp.vercel.app/api/assets/terraform/latest/img/docs/intro-terraform-workflow.png β© -
Argo CD docs image.
argocd_architecture.png. https://argo-cd.readthedocs.io/en/stable/assets/argocd_architecture.png β© -
HashiCorp Developer. βWhat is Terraform?β https://developer.hashicorp.com/terraform/intro β© β©2 β©3
-
OpenTofu Docs. βWhat is OpenTofu?β https://opentofu.org/docs/intro/ β© β©2 β©3
-
Flux Docs. βGitOps.β https://fluxcd.io/flux/concepts/ β© β©2
-
Argo CD Docs. βWhat Is Argo CD?β https://argo-cd.readthedocs.io/en/stable/ β© β©2
-
OpenTofu Docs. Core OpenTofu workflow. https://opentofu.org/docs/intro/ β©
-
Argo CD Docs. βHow it works.β https://argo-cd.readthedocs.io/en/stable/ β©
-
Flux Docs. βReconciliation.β https://fluxcd.io/flux/concepts/ β©
-
Flux Docs. βGitOps Toolkit.β https://fluxcd.io/flux/concepts/ β©
Written by PixelRouter Editorial Team
We publish deep, authoritative guides on AI infrastructure, API gateway security, cloud financial management, and system optimizations for developers.
FAQ
What is Infrastructure as Code?
Infrastructure as Code means defining and managing infrastructure in version-controlled configuration files that can be reviewed, reused and automated. Tools such as Terraform and OpenTofu use this approach to manage cloud and on-prem resources.
What is GitOps?
GitOps is an operating model where Git is the source of truth for desired state, and automation helps keep deployed environments aligned with the state defined in Git repositories.
How do Terraform and OpenTofu work?
Terraform and OpenTofu commonly follow a Write, Plan and Apply workflow: write configuration, review a plan showing intended changes, then apply those changes after approval.
Why does Terraform or OpenTofu state matter?
State maps resources in code to real infrastructure resources. It drives planning, tracks managed resources, may contain sensitive values, and should be protected with remote storage, locking, encryption, access controls and backups.
How do Argo CD and Flux fit into GitOps?
Argo CD and Flux are GitOps tools for Kubernetes. They compare desired state from Git with live cluster state and help sync or reconcile the cluster so it matches the declared configuration.
Should secrets be stored in a GitOps repository?
Not as plaintext. The article recommends avoiding plaintext Kubernetes Secrets in Git and using approaches such as SOPS, Sealed Secrets, External Secrets, cloud secret managers or Vault.