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 --snapshot the 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