Sobes.tech
Middle

How do you perform version control of infrastructure code?

sobes.tech AI

Answer from AI

Version control of infrastructure code (Infrastructure as Code, IaC) is carried out as follows:

  1. Version control system: Using Git as the main system. Every change in Terraform, Ansible, Kubernetes manifests, and other configuration files is committed.
  2. Branches: I apply a branching model, most often GitFlow or a simplified version with feature branches, develop, and main/master. Development is done in feature branches, merged into develop for testing, and then into main for deployment to production.
  3. Pull Requests (Merge Requests): All changes go through a review process via Pull Requests. This allows team members to review code, discuss changes, and ensure their quality and security before merging.
  4. Tagging: I use tags to denote stable versions of the infrastructure corresponding to specific deployments (e.g., a version deployed to production on a certain date or after a specific release of the application).
  5. Modularization: Dividing code into reusable modules (e.g., in Terraform) or roles/playbooks (in Ansible) helps manage complexity and version each part of the infrastructure separately if needed.
  6. Automated tests: Infrastructure testing (e.g., Terratest for Terraform, Molecule for Ansible) is included in the CI/CD pipeline. Commits pass tests before merging and deployment.

Example of repository structure:

// Root folder of the IaC repository
├── terraform/
│   ├── modules/
│   │   └── vpc/
│   │       └── main.tf
│   ├── environments/
│   │   ├── dev/
│   │   │   └── main.tf
│   │   └── prod/
│   │       └── main.tf
│   └── main.tf
├── ansible/
│   ├── roles/
│   │   └── webserver/
│   │       └── tasks/
│   │           └── main.yml
│   ├── inventory/
│   │   ├── dev
│   │   └── prod
│   └── site.yml
├── kubernetes/
│   └── deployments/
│       └── app/
│           └── deployment.yaml
├── .gitignore
├── README.md
└── Jenkinsfile // or .gitlab-ci.yml, .github/workflows/...

Each change within these directories is versioned with Git. Different environments (dev, prod) are also explicitly represented in the code, and their configurations are version-controlled. Tagging at the commit level allows precise knowledge of which infrastructure code version was deployed in each environment.