Strict Version Pinning
Strict Version Pinning extends Folder-Based Versioning by creating explicit component versions using number-based versioning schemes like SemVer (vpc/1.2.3, vpc/2.0.0) within the Continuous Version Deployment strategy. This approach works particularly well when vendoring from external sources or managing shared component libraries within your organization.
This folder organization approach provides the most granular version control by using fixed-point versioning—each version folder represents a specific, immutable version. Components are organized into version-specific folders, making it explicit which exact version each environment uses. This is especially useful when vendoring components from external sources where you want to track specific upstream versions.
Strict Version Pinning works with number-based versioning schemes that create immutable version identifiers:
- SemVer (
1.2.3) - Communicates breaking vs. non-breaking changes - CalVer (
2024.10.1) - Date-based versions for temporal tracking - Sequential (
v1,v2) - Simple incrementing numbers - Major/Minor (
1.0,2.0) - Simplified SemVer
These are fixed points—once created, the version never changes. This contrasts with Release Tracks/Channels which use moving targets (labels like alpha, prod) that point to evolving versions.
You will learn
- How strict pinning provides reproducibility but encourages environment divergence
- Why lockstep promotion is critical when using strict version pinning
- The operational overhead of managing individual pins across many environments
- When strict pinning is appropriate despite its limitations
Use Cases
Use the Strict Version Pinning pattern when:
- Reproducibility and auditability are paramount requirements
- Your environment count is small and carefully curated
- You can enforce lockstep promotion across the SDLC without skipping versions
- Your organization truly needs to optimize for rollback over roll-forward
- You have regulatory requirements that mandate exact version tracking
- You need a clear audit trail of what ran where and when
Problem
While strict version pinning seems like the safest approach, it creates several challenges at scale:
1. Optimizes for Divergence
Each environment maintains its own version pins, causing environments to drift apart unless you continuously update them. This divergence makes it harder to reason about the overall system state.
2. Weak Feedback Loop
Lower environments stay pinned to older versions, so running terraform plan doesn't reveal cross-environment impacts. Problems like:
- Destructive operations
- Resource incompatibilities
- Dependency cycles
- State migration issues
These often surface only during promotion—sometimes first appearing in production.
3. Lockstep Promotion Required
If development or staging received 10 incremental releases, production must receive those same 10 releases in order. Skipping versions causes:
- Hidden assumptions to break
- Terraform dependency cycles to appear
- State inconsistencies
- "Worked incrementally, fails when batched" problems
4. Operational Overhead
At scale, maintaining individual pins creates significant overhead:
- Manual pin updates across dozens or hundreds of environments
- PR storms from automated dependency update tools
- Complex promotion orchestration
- Version tracking and coordination burden
Solution
When implementing strict version pinning in Atmos:
1. Pin Versions Through Vendoring
With strict version pinning, components are vendored at specific versions using Atmos vendor manifests.
Atmos vendor manifests support Go template syntax. The template is executed with the source specification as context, giving you access to fields like {{.Component}}, {{.Version}}, {{.Source}}, etc. This allows you to write DRY configurations where values defined once can be reused in multiple places.
In the example below, {{.Version}} references the version: "v1.12.3" field, so the source URL becomes ...?ref=v1.12.3 and the target path becomes components/terraform/vpc/v1.12.3.
vendor.yaml
stacks/prod/us-east-1.yaml
2. Maintain Stable Workspace Keys
Never include version information in workspace_key_prefix. This ensures state remains stable when versions change:
# WRONG - Will cause state migration issues
settings:
workspace_key_prefix: "prod/vpc/v1.12.3"
# CORRECT - Stable across version changes
settings:
workspace_key_prefix: "vpc"
3. Document Version History
Maintain clear documentation of version promotions:
docs/version-history.md
Rollback Strategy
With strict version pinning, rollback is straightforward - simply update the component reference in your stack configuration:
Option 1: Point to Previous Version
If you've already vendored multiple versions:
# stacks/prod/us-east-1.yaml
components:
terraform:
vpc:
metadata:
# Change from problematic version to previous version
component: vpc/v1.12.3 # Was: vpc/v1.12.4
Option 2: Revert the Commit
# Find the commit that introduced the problematic version
git log --oneline stacks/prod/us-east-1.yaml
# Revert the specific commit
git revert <commit-sha>
# Or reset to a known good state
git reset --hard <good-commit-sha>
Apply the Rollback
# Validate the rollback
atmos validate component vpc --stack prod-us-east-1
# Plan to see what will change
atmos terraform plan vpc --stack prod-us-east-1
# Apply the rollback
atmos terraform apply vpc --stack prod-us-east-1
Verify the Rollback
# Quick sanity check - verify stack config points to correct folder
atmos describe component vpc --stack prod-us-east-1 | grep "component:"
# Should show: component: vpc/v1.12.3
# TRUE VERIFICATION - plan should show no changes
atmos terraform plan vpc --stack prod-us-east-1
# Should output: No changes. Your infrastructure matches the configuration.
The "no changes" output proves that the rollback was successfully applied to the infrastructure, not just the configuration.
No re-vendoring required! If you've maintained versioned folders through your vendor process, you can simply update the component reference to point to the previous version that's already vendored.
Benefits
The Strict Version Pinning pattern provides:
- Clear Audit Trail: Exact tracking of what version ran where and when
- Simplified Rollback: Easy to revert to previous versions by changing pins
- Git as Source of Truth: Version history stored directly in Git
- Explicit Control: No surprises from automatic version updates
- Regulatory Compliance: Meets strict auditability requirements
Drawbacks
The pattern also has significant limitations:
- Environment Drift: Environments naturally diverge without constant updates
- Weak Early Warning: Problems surface late in the promotion cycle
- Lockstep Requirement: Cannot safely skip versions during promotion
- High Overhead: Manual pin management becomes burdensome at scale
- PR Storms: Automated update tools create many pull requests
Best Practices
When using strict version pinning:
- Automate Carefully: Tools like Renovate or Dependabot can help, but beware of The Automation Tool Trap—PR storms often create more problems than they solve
- Monitor Divergence: Set alerts when environments drift beyond acceptable thresholds
- Test Incrementally: Never skip versions; apply all updates in sequence
- Plan Broadly: Regularly run plans across all environments, not just the one being updated
- Document Everything: Maintain clear records of version histories and promotion decisions
- Consider Escape Routes: Design your workspace keys to allow migration to other patterns if needed
Drawbacks and Trade-offs
While Strict Version Pinning provides strong reproducibility, it comes with significant trade-offs:
Operational Overhead
- Manual version management for each environment
- Promotion fatigue from constant version updates
- Coordination complexity across teams and environments
- Documentation burden to track version decisions
Environment Divergence
- Version drift leads to "snowflake" environments
- Late feedback - issues discovered only when promoting to production
- Difficult debugging when environments behave differently
- Testing limitations - can't test against production-like configurations early
Scaling Challenges
- Exponential complexity as environment count grows
- Bottlenecks in promotion processes
- Increased risk of human error in version management
- Time-consuming rollback coordination across environments
Innovation Impedance
- Slow adoption of improvements and fixes
- Conservative bias against making changes
- Delayed security patches due to promotion overhead
- Reduced experimentation due to high change cost
The Automation Tool Trap
A common solution to strict pinning overhead is using dependency update tools like Dependabot or RenovateBot. While these tools automate version updates, they often create new problems:
Death by Pull Request:
- PR Inundation: Automated tools generate dozens or hundreds of version update PRs
- Lingering PRs: Pull requests sit unmerged as teams struggle to keep up with review volume
- Growing Backlog: PR queue grows exponentially while teams point fingers about responsibility
- Context Switching: Developers move on to next sprint tasks, forgetting pending version PRs
- Review Fatigue: Even when managed well, PR review becomes a routine chore rather than valuable work
The Real Question: If your workflow requires constant automated PR generation to stay current, why optimize for this approach?
A Better Path: Consider optimizing for the ideal solution—all environments converging to the same version with stability achieved through repetition and robust testing. Instead of managing version sprawl with automation tools, eliminate the need for per-environment version management entirely by embracing convergent patterns like Continuous Version Deployment or Release Tracks.
Focus your effort on improving deployment workflows and testing practices rather than perfecting version update automation. The goal isn't to get better at managing complexity—it's to eliminate unnecessary complexity.
Summary
Strict Version Pinning provides maximum control and reproducibility at the cost of operational overhead and environment divergence. It's best suited for small, carefully managed environment sets with strong regulatory requirements. For larger scales or teams preferring rapid iteration, consider patterns that promote convergence like Release Tracks/Channels or Folder-Based Versioning.
Many teams successfully operate by optimizing for roll-forward with strong convergence rather than rollback capabilities. Choose strict pinning only when its benefits clearly outweigh the operational costs.
Related Patterns
- Versioning Schemes - Number-based schemes (SemVer, CalVer) that work with strict pinning
- Release Tracks/Channels - Environments subscribe to moving version tracks
- Folder-Based Versioning - Version through repository structure
- Vendoring Components - Local control through vendoring
- Component Inheritance - Base configurations for pinned components