Source Control Overview
Source control (or version control) is fundamental to modern DevOps practices. It provides a single source of truth for both application code and infrastructure definitions. This guide covers best practices for implementing effective source control strategies across cloud providers.
Popular Source Control Systems
- GitHub - Widely used for public and private repositories with excellent CI/CD integration
- GitLab - Self-hosted or SaaS platform with built-in CI/CD capabilities
- Azure DevOps - Microsoft’s comprehensive DevOps platform with integrated work tracking
- Bitbucket - Atlassian’s Git solution that integrates with their suite of products
Sections within Source Control
- Merge Strategies
- Branch Naming
- Versioning
- Working with Secrets
- Git Guidance
- Monorepo vs. Multirepo
- GitOps Workflow
- Infrastructure as Code Management
Goal
- Following industry best practice to work in geo-distributed teams which encourage contributions across organizations
- Improve code quality by enforcing reviews before merging into main branches
- Improve traceability of features and fixes through a clean commit history
- Enable GitOps workflows for infrastructure and application deployments
- Support multi-cloud environments with consistent practices
Modern Source Control Patterns
Trunk-Based Development
Trunk-based development is a source control pattern where developers collaborate on code in a single branch (trunk/main), using feature flags and other techniques to disable incomplete code in production.
Key characteristics:
- Short-lived feature branches (typically less than 2 days)
- Frequent merges to the main branch (at least daily)
- Comprehensive automated testing
- Feature toggles to manage incomplete features
# Example workflow
git checkout -b feature/add-monitoring
# Make changes
git commit -am "Add Prometheus metrics endpoint"
# Pull latest changes from main
git pull origin main --rebase
# Run tests
npm test
# Push and create PR
git push -u origin feature/add-monitoring
# PR is reviewed and merged quickly (same day if possible)
Monorepo vs. Multirepo
Monorepo
A monorepo stores multiple projects in a single repository.
Advantages:
- Simplified dependency management
- Atomic changes across projects
- Unified versioning
- Easier code sharing and refactoring
Disadvantages:
- Can become unwieldy for very large projects
- Requires more sophisticated build tooling
- Access control is less granular
Multirepo
A multirepo uses separate repositories for different projects or services.
Advantages:
- Clear ownership boundaries
- Fine-grained access control
- Focused scope per repository
- Independent release cycles
Disadvantages:
- Challenging cross-project changes
- Dependency management complexity
- Version compatibility issues
Decision criteria:
- Team size and structure
- Project architecture (monolith vs microservices)
- Deployment frequency requirements
- Security and access control needs
GitOps Workflow
GitOps uses Git repositories as the source of truth for declarative infrastructure and applications.
Core principles:
- The entire system is described declaratively
- The canonical desired system state is versioned in Git
- Approved changes can be automatically applied to the system
- Software agents ensure correctness and alert on drift
Example GitOps workflow with Flux:
# Example Flux GitRepository resource
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: infrastructure
namespace: flux-system
spec:
interval: 1m
url: https://github.com/organization/infrastructure
ref:
branch: main
Infrastructure as Code Management
Best practices for managing Infrastructure as Code in source control:
- Structure repositories effectively
- Separate application code from infrastructure code
- Organize by environment, region, or component
infrastructure/ ├── modules/ # Reusable infrastructure components ├── environments/ # Environment-specific configurations │ ├── dev/ │ ├── staging/ │ └── production/ └── platform/ # Shared platform resources - Version infrastructure resources
- Use semantic versioning for infrastructure modules
- Tag stable infrastructure releases
# Tag infrastructure releases git tag -a "infra/v1.2.0" -m "Added VPC peering and updated security groups" - Handle state files securely
- Never store state files with secrets in source control
- Use remote state with appropriate access controls
# Terraform remote state example terraform { backend "s3" { bucket = "terraform-state" key = "prod/network/terraform.tfstate" region = "us-west-2" encrypt = true dynamodb_table = "terraform-locks" } } - Manage secrets properly
- Use secret management services (AWS Secrets Manager, Azure Key Vault)
- Consider solutions like SOPS or Vault for encrypted secrets in Git
General Guidance
Consistency is important, so agree to the approach as a team before starting to code. Treat this as a design decision, so include a design proposal and review, in the same way as you would document all design decisions (see Working Agreements and Design Reviews).
Creating a new repository
When creating a new repository, the team should at least do the following:
- Agree on the branch, release, and merge strategy
- Define the merge strategy (linear or non-linear)
- Lock the default branch and merge using pull requests (PRs)
- Agree on branch naming (e.g.
feature/add-monitoringoruser/your_alias/feature_name) - Establish branch/PR policies
- Configure CI/CD pipelines to run on PR creation
- Set up automated linting and security scanning
- For public repositories the default branch should contain the following files:
Conventional Commits
Using conventional commits improves repository readability and enables automated versioning:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
Common types include:
feat: A new featurefix: A bug fixdocs: Documentation changeschore: Routine tasks, maintenancerefactor: Code change that neither fixes a bug nor adds a featuretest: Adding or correcting testsci: Changes to CI configuration
Example:
feat(api): add endpoint for user authentication
Implement JWT-based authentication for the API service.
BREAKING CHANGE: `Authorization` header now required for protected routes
Contributing to an existing repository
When working on an existing project:
git clonethe repository- Review the project’s README.md and CONTRIBUTING.md files
- Understand the team’s branch, merge and release strategy
- Follow the established workflow and coding standards
# Clone the repository
git clone https://github.com/organization/project.git
# Create a feature branch
git checkout -b feature/implement-monitoring
# Make changes, commit using conventional commits
git commit -m "feat(monitoring): add Prometheus metrics endpoint"
# Push changes and create a pull request
git push -u origin feature/implement-monitoring
Multi-Cloud Source Control Practices
When managing infrastructure for multiple cloud providers:
- Unified Repository Structure
- Use consistent naming conventions across providers
- Organize by capability rather than by provider when possible
- Provider Abstractions
- Consider using abstraction layers in IaC
- Implement consistent tagging across cloud providers
- Cross-Provider Testing
- Test infrastructure changes across all targeted cloud environments
- Use matrix CI/CD jobs to validate across providers
Mixed DevOps Environments
For most engagements, having a single hosted DevOps environment (i.e., Azure DevOps) is the preferred path, but there are times when a mixed DevOps environment (e.g., Azure DevOps for Agile/Work item tracking & GitHub for Source Control) is needed due to customer requirements. When working in a mixed environment:
- Use integrations between systems where available (Azure Boards GitHub App)
- Manually reference work items in commits with standard formats (e.g., AB#123)
- Ensure that the scope of work items / tasks align with PR’s
- Consider automation tools like GitHub Actions to sync state between systems
- Document the workflow clearly to avoid confusion
Resources
- Git - Official Git documentation
- Azure DevOps - Microsoft’s DevOps platform
- GitHub - GitHub documentation and guides
- GitLab - GitLab documentation
- Learn Git Branching - Interactive Git tutorial
- Conventional Commits - Commit message convention
- GitHub - Removing sensitive data from a repository
- GitHub Flow - A lightweight branch-based workflow
- GitOps Principles - Core GitOps concepts and practices