Skip to main content

Managed Versions

Use version in atmos.yaml to manage software versions with Atmos-native tracks, policies, groups, and lock files.

Managed versions are for software versions Atmos needs to resolve consistently. That includes local tools Atmos can install and run through Toolchain, plus versions Atmos only needs to track and render into files: GitHub Actions refs, OCI and Docker images, Helm charts, Terraform or OpenTofu-related constraints, release tags, and other package versions. Human-authored policy lives in atmos.yaml; resolved versions live in versions.lock.yaml.

This is separate from version.use, version.check, and version.constraint, which manage the Atmos CLI itself.

Configuration

atmos.yaml
version:
track: prod
lock_file: versions.lock.yaml

providers:
dockerhub:
kind: docker
url: registry-1.docker.io

ecr_prod:
kind: aws/ecr
region: us-east-1
registry_id: "123456789012"

ghcr:
kind: oci
url: ghcr.io

local_registry:
kind: oci
url: localhost:5000
insecure: true # plain-HTTP access; local/emulated registries only

defaults:
update:
strategy: patch
cooldown: 14d
include: ["v1.*"]
exclude: ["*-rc*", "*-beta*"]
prerelease: false
labels: [dependencies]

groups:
infrastructure:
ecosystems: [docker, oci, helm, terraform, opentofu, github/actions]
patterns: ["terraform*", "opentofu", "actions/*", "nginx"]
update:
strategy: minor
cooldown: 14d
exclude: ["1.5.*"]
labels: [infrastructure]

dependencies:
opentofu:
ecosystem: toolchain
datasource: toolchain
package: opentofu
desired: "~1.10"

checkout:
ecosystem: github/actions
datasource: github-tags
provider: github
package: actions/checkout
desired: "v6"
update:
pin: sha # lock and apply the commit SHA, not the mutable tag

nginx:
ecosystem: oci
datasource: oci-tags
provider: dockerhub
package: library/nginx
desired: "1.28.0"

tracks:
prod:
defaults:
update:
cooldown: 30d

dependencies:
nginx:
desired: "1.29.0"

# Which project files the file managers maintain (see File Managers below).
files:
- manager: github-actions
paths:
- .github/workflows/*.yaml
- manager: marker
paths:
- Dockerfile
- manager: template
paths:
- "**/*.tmpl"

Core Concepts

FieldDescription
ecosystemDependency domain, such as toolchain, github/actions, docker, oci, helm, terraform, or opentofu.
datasourceVersion lookup strategy, such as toolchain, github-tags, github-releases, docker-tags, oci-tags, or helm.
providerConcrete backend or auth target, such as github, dockerhub, ecr_prod, or ghcr.
trackNamed version lane, such as dev, staging, or prod.
groupBatch of related updates with shared match rules and policy.
dependenciesBase catalog of software versions tracked by Atmos. Track-level dependencies override the base catalog.
lock_fileFile that stores resolved versions. Defaults to versions.lock.yaml.
filesRules mapping file managers to the project files they maintain.

Ecosystem names alias to their default datasource: github and github/actions resolve via github-tags, docker via docker-tags, and oci via oci-tags. Set datasource explicitly to override (for example, github-releases to follow published releases instead of tags).

Update Policy

The update policy inherits through version.defaults → track defaults → entry → group:

strategy
How far atmos version track update may advance a locked version: major, minor, or patch. pin (alias: digest) never advances the version and only refreshes digests.
cooldown
Minimum age of a release before it is eligible, checked against the upstream release timestamp: 14d, 2w, or Go durations such as 36h.
pin
Artifact form emitted for the entry: digest (alias: sha) locks and renders the immutable identifier — the git commit SHA for GitHub datasources, the sha256: manifest digest for OCI registries — alongside the human-readable version. none or empty keeps plain version references. Strategy decides how far updates may advance; pin decides which form is written. Configuring a pin on a datasource that cannot provide immutable identifiers fails loudly.
include
Candidate version patterns to allow. When set, versions must match at least one include pattern.
exclude
Candidate version patterns to block. Excluded versions cannot be selected, even when requested directly.
prerelease
Whether prerelease candidates are eligible. Defaults to false.

Update vs. Lock

lock and update answer different questions:

  • lock resolves each entry's desired expression as-is and writes the lock file. Use it to bootstrap a catalog or repair a lock.
  • update starts from the locked state and advances only as far as the policy allows. Every newer candidate held back by a strategy cap or cooldown produces a structured reason.

Status reporting is policy-aware: update-available means an update the policy would actually take. A newer upstream version held back by policy reports newer-available (blocked) with the blocking reason — and still passes verify, because the locked version is exactly what the policy wants deployed.

Tracks

Tracks let different environments converge at different speeds without putting version definitions in every stack.

stacks/deploy/prod.yaml
version:
track: prod

When a stack asserts a track, !version and {{ .version.name }} resolve from that track. If a stack does not assert a track, Atmos uses version.track from atmos.yaml, then falls back to default.

Runtime Usage

Use !version when the value is YAML data:

dependencies:
tools:
opentofu: !version opentofu

Use .version in Go templates when the value is embedded inside a string:

vars:
image:
uri: "public.ecr.aws/datadog/lambda-extension:{{ .version.dd_forwarder }}"

For pinned entries, {{ .version.name }} emits the pinned form (the digest), while {{ .version.name.Version }} and {{ .version.name.Digest }} are individually addressable. !version always returns the version, never the digest.

GitHub Actions workflow files need literal refs (GitHub parses them before Atmos runs). Maintain them with the github-actions file manager, or author *.tmpl templates and apply them with atmos version track apply.

File Managers

version.files declares which project files carry managed versions, so a single atmos version track apply (alias: sync) sweeps everything, and verify fails in CI when any of them drifts from the lock. Each rule maps a manager to the glob paths it maintains:

version:
files:
- manager: github-actions
paths:
- .github/workflows/*.yaml
- manager: marker
paths:
- Dockerfile
- scripts/**/*.sh
- manager: template
paths:
- "**/*.tmpl"

When files is empty, managers with default paths (github-actions, template) run over those defaults.

github-actions

Scans workflow files for uses: lines and rewrites the ref from the lock, matching entries by owner/repo package. Subdirectory actions (owner/repo/subdir) and reusable workflows (owner/repo/.github/workflows/x.yml) are included; local (./path) and docker:// references never match. Rewriting is line-based, so formatting and unrelated comments are preserved.

Pinned entries use the Renovate/Dependabot round-trip convention — the immutable SHA with the human-readable version as a trailing comment:

- uses: actions/checkout@8edcb1bdb4e267140fa742c62e395cd74f332709 # v6.1.0

marker

The Renovate regex-manager equivalent for arbitrary text files. A comment annotation marks which line carries a managed version:

<comment> atmos:version <entry-name> [match=<regex-with-one-capture-group>]

A trailing comment marks its own line; a standalone comment marks the next non-blank, non-comment line. The manager rewrites the version token in place from the lock; pinned entries replace digest tokens (sha256: digests and 40-character git SHAs).

# atmos:version opentofu
ENV TOFU_VERSION=1.10.6
tofu_version: 1.10.6 # atmos:version opentofu

Comment delimiters are detected per language:

DelimiterLanguages
#YAML, shell, Dockerfile, Python, TOML
//Go, JavaScript, TypeScript, C-family
/*CSS, C-family block comments
;INI, Lisp, assembly
--SQL, Lua, Haskell
<!--HTML, XML, Markdown

Use the optional match= regex (with exactly one capture group) when the default version-token detection is ambiguous on the target line. Formats without comments (JSON) should use the template manager instead.

template

*.tmpl files are the human-edited source of truth and render to a sibling file with the .tmpl suffix stripped (for example, versions.json.tmplversions.json), using the .version context resolved from the lock. This covers comment-hostile formats and any file where an explicit template beats in-place rewriting.

Editing the Catalog

The add, set, remove, and get subcommands edit dependency entries in atmos.yaml without hand-editing YAML, preserving comments, anchors, and formatting. add infers the ecosystem from the package coordinate:

atmos version track add checkout --package=actions/checkout --pin=sha
atmos version track set nginx --desired=1.29.0
atmos version track remove legacy-tool

Lock File

versions.lock.yaml
version: 1
tracks:
prod:
opentofu:
version: 1.10.6
ecosystem: toolchain
datasource: toolchain
package: opentofu
resolved_at: "2026-07-03T00:00:00Z"

checkout:
version: v6.1.0
ecosystem: github/actions
datasource: github-tags
provider: github
package: actions/checkout
digest: 8edcb1bdb4e267140fa742c62e395cd74f332709
resolved_at: "2026-07-03T00:00:00Z"
released_at: "2026-06-12T00:00:00Z"

Atmos runtime resolution reads from the lock file. This keeps local runs and CI deterministic. Entries with pin: digest also record the immutable identifier (digest) and the upstream release timestamp (released_at) used by cooldown checks.

Resolver Support

Implemented datasources:

DatasourceBackendNotes
toolchainAqua registryTool versions for toolchain packages.
github-tagsGitHub APITags carry commit SHAs for pinning.
github-releasesGitHub APIReleases carry publish timestamps for cooldown.
oci-tagsOCI registriesTag listing plus manifest digests.
docker-tagsDocker registriesSame engine as oci-tags against Docker Hub-style registries.

desired accepts a concrete version, a SemVer constraint (for example, ~1.10), or latest. Providers configured under version.providers supply the registry url and options such as insecure for plain-HTTP local or emulated registries.

See Also