Snapshot
On every action, Polycrate creates a snapshot of the workspace state for reproducibility, template injection and debugging. This page describes the mechanism, the contents and inspection with --snapshot.
Snapshot
What is a snapshot?
Whenever you run an action with Polycrate, a snapshot of the current workspace state is created. A snapshot is a complete capture of all relevant configuration and data required for the action execution.
The snapshot serves several purposes:
- Reproducibility: every action can be reproduced exactly with the same state
- Template injection: scripts and playbooks can access snapshot data
- Debugging: with
--snapshotthe state can be inspected without execution
Snapshot mechanism
graph TB
Start[Action execution starts] --> Load[Load workspace]
Load --> Resolve[Resolve blocks with inheritance]
Resolve --> Snapshot[Create snapshot]
Snapshot --> WS[Workspace config]
Snapshot --> Block[Block config resolved]
Snapshot --> Inv[Inventory]
Snapshot --> Kube[Kubeconfig]
Snapshot --> Env[Runtime env incl. snapshot file path]
Snapshot --> Meta[Metadata transaction, user]
WS --> JSON[snapshot.json/yaml]
Block --> JSON
Inv --> JSON
Kube --> JSON
Env --> JSON
Meta --> JSON
JSON --> Template[Template injection into scripts]
JSON --> AnsibleVars[Ansible extra vars]
Template --> Exec[Action execution]
AnsibleVars --> Exec
Env --> Exec
Exec --> Persist[Snapshot file temporary, mounted in container]
What does a snapshot contain?
A snapshot contains the following data:
1. Workspace configuration
The complete workspace configuration from workspace.poly:
- Name, description, labels
- Container image configuration
- SSH configuration
- Sync options (Git)
2. Block configuration (resolved)
The fully resolved block configuration after applying inheritance:
- All inherited and overridden values
- Chart configuration (for K8s blocks)
- Dependencies
- Action definitions
3. Ansible inventory
The snapshot does not contain the full inventory content, but the resolved paths to the inventory file (local and inside the container), provided an inventory is configured. The actual inventory file is located at the configured path in the workspace or in the artifacts.
4. Kubeconfig
Likewise, the snapshot does not contain the full kubeconfig (no cluster contexts or credentials embedded), only the paths to the kubeconfig file. The content is read by tools such as kubectl or Ansible from the mounted file.
5. Metadata
When executing via the Polycrate API or connected services, the following information is available among others (not necessarily as fields in the snapshot YAML file):
- Transaction ID: unique UUID of the operation
- User: username and e-mail
- Timestamp: time of snapshot creation
- Command: executed Polycrate command
- Git commit: current Git commit SHA (if a Git repo)
Snapshot structure (example)
workspace:
name: my-workspace
config:
image:
reference: ghcr.io/polycrate-hub/workspace
version: latest
blocks_root: blocks
artifacts_root: artifacts
ssh_private_key: id_rsa
ssh_public_key: id_rsa.pub
inventory:
path: artifacts/inventory/hosts.ini
filename: hosts.ini
localpath: /home/user/my-workspace/artifacts/inventory/hosts.ini
containerpath: /workspace/artifacts/inventory/hosts.ini
kubeconfig:
path: artifacts/kubeconfig/config
filename: config
localpath: /home/user/my-workspace/artifacts/kubeconfig/config
containerpath: /workspace/artifacts/kubeconfig/config
block:
name: my-postgres
kind: k8sapp
type: db
flavor: postgresql
implementation: cnpg
version: 1.0.0
from: postgres-base # parent block
config:
namespace: production
chart:
name: postgresql
version: 12.0.0
repo:
name: bitnami
url: https://charts.bitnami.com/bitnami
app:
auth:
username: postgres
password: secretpassword
persistence:
enabled: true
size: 50Gi
storageClass: standard
replicas: 2
action:
name: install
description: Install PostgreSQL
playbook: install.yml
env:
POLYCRATE_WORKSPACE: /workspace
POLYCRATE_WORKSPACE_SNAPSHOT_YAML: /tmp/550e8400-abc-workspace-snapshot.yml
# ... further runtime variables from Polycrate
mounts:
/tmp/550e8400-abc-workspace-snapshot.yml: /tmp/550e8400-abc-workspace-snapshot.yml
Note: additional metadata (e.g. about an API transaction) may be kept outside this snapshot file; the serialized WorkspaceSnapshot structure primarily contains workspace, block, action, env and mounts.
Using the snapshot
In Ansible playbooks
The snapshot is automatically passed to Ansible as extra vars:
---
- name: Install Application
hosts: localhost
connection: local
tasks:
- name: Debug snapshot variables
debug:
msg: |
Workspace: {{ workspace.name }}
Block: {{ block.name }}
Action: {{ action.name }}
Namespace: {{ block.config.namespace }}
Transaction ID: {{ transaction.id }}
- name: Deploy with Helm
kubernetes.core.helm:
name: "{{ block.name }}"
namespace: "{{ block.config.namespace }}"
chart_ref: "{{ block.config.chart.repo.name }}/{{ block.config.chart.name }}"
values: "{{ block.config.app }}"
Polycrate invokes Ansible like this:
ansible-playbook -e '@/path/to/snapshot.json' playbook.yml
During execution Polycrate sets, among others, POLYCRATE_WORKSPACE_SNAPSHOT_YAML to the path of the serialized snapshot file (and mounts this file into the container). This does not replace access to workspace, block and action via Ansible extra vars; individual snapshot fields are not available as generic WORKSPACE_* variables in the environment.
Inspecting the snapshot
With the --snapshot flag
You can print the snapshot without executing the action:
# YAML format (default)
polycrate run my-block install --snapshot
# JSON format
polycrate run my-block install --snapshot -o json
# Save to file
polycrate run my-block install --snapshot > snapshot.yml
Example output
polycrate run my-postgres install --snapshot
Excerpt (shortened; the full output includes workspace with inventory/kubeconfig paths, env, mounts, among others):
workspace:
name: my-workspace
config:
blocks_root: blocks
artifacts_root: artifacts
block:
name: my-postgres
kind: k8sapp
config:
namespace: production
action:
name: install
playbook: install.yml
Snapshot and logging
Workspace-wide directories such as .logs/ for transaction dumps are no longer populated by Polycrate by default. For reproducibility and traceability use --snapshot (local output), the Polycrate API (action runs, audit) or your CI/GitOps processes.
Best practices
1. Use the snapshot for debugging
If an action fails, inspect the snapshot:
# Show the snapshot
polycrate run my-block install --snapshot
# Check:
# - Are all config values correct?
# - Do workspace.inventory.* and workspace.kubeconfig.* point to the expected files?
# - Are the inventory and kubeconfig files present and valid at the referenced path?
2. Use template variables
Use snapshot variables instead of hardcoding:
# ✅ Good: dynamic variables in the playbook
# deploy.yml
- name: Deploy application
hosts: localhost
tasks:
- name: Apply manifest
kubernetes.core.k8s:
state: present
namespace: "{{ block.config.namespace }}"
src: app.yml
# ❌ Bad: hardcoded values
# The namespace should come from block.config, not be hardcoded
3. Auditing and traceability
For auditable executions (who ran what, when, with which state) use the Polycrate API (action runs, audit log) or export snapshots deliberately with --snapshot and version the output in your pipeline – not via an outdated .logs/ directory in the workspace.
Relation to other concepts
- Inheritance: the snapshot contains the resolved block configuration after inheritance
- Container: the snapshot is mounted into the container
- Artifacts: inventory and kubeconfig are files in the workspace; the snapshot references them by path, not as embedded content