Source Control Overview
Last updated
Last updated
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.
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
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
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
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
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 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:
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
Version infrastructure resources
Use semantic versioning for infrastructure modules
Tag stable infrastructure releases
Handle state files securely
Never store state files with secrets in source control
Use remote state with appropriate access controls
Manage secrets properly
Use secret management services (AWS Secrets Manager, Azure Key Vault)
Consider solutions like SOPS or Vault for encrypted secrets in Git
When creating a new repository, the team should at least do the following:
Agree on the branch, release, and merge strategy
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:
Using conventional commits improves repository readability and enables automated versioning:
Common types include:
feat
: A new feature
fix
: A bug fix
docs
: Documentation changes
chore
: Routine tasks, maintenance
refactor
: Code change that neither fixes a bug nor adds a feature
test
: Adding or correcting tests
ci
: Changes to CI configuration
Example:
When working on an existing project:
git clone
the 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
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
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
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 and ).
Define the merge strategy ()
Lock the default branch and merge using
Agree on (e.g. feature/add-monitoring
or user/your_alias/feature_name
)
Establish
- Official Git documentation
- Microsoft's DevOps platform
- GitHub documentation and guides
- GitLab documentation
- Interactive Git tutorial
- Commit message convention
- A lightweight branch-based workflow
- Core GitOps concepts and practices