Recipes

Practical examples. The canonical chain comes first: specs, workspace and block release, push, pull, action install. Git and CI are optional and consume the same chain — see Develop and deploy (git-free).

Develop and deploy (git-free)

Product process (no Git, no CI-first, no sed on version:):

  1. Specs at done — Open Questions empty.
  2. Workspace release: release create, release update (changelog message and RELEASENOTE highlights), release finalize.
  3. Block release: release create, release update (CHANGELOG message; app_version if the block carries an app image), release finalize. There is no block bump.
  4. polycrate block push <block>
  5. Downstream: polycrate block pull <registry/org/name:version> writes from: on every workspace instance of that FQBN.
  6. polycrate run <block> install
polycrate spec update <id> --set status=done
polycrate release create X.Y.Z
polycrate release update X.Y.Z --set type=feat --set message="..."
polycrate release finalize X.Y.Z
polycrate block push <block>
polycrate block pull <registry/org/name:version>
polycrate run <block> install

--workspace / -w must be an absolute path.

Details and hard fails: Develop and deploy.

Workspace setup

Clone an existing API workspace

# Default path: ~/.polycrate/workspaces/acme/acme-production-1
polycrate workspace clone acme/acme-production-1
cd ~/.polycrate/workspaces/acme/acme-production-1
polycrate workspace inspect

Prerequisite: API configured (polycrate api) and an SSH key for the Git remote. The command aborts if the target directory already exists.

Workspaces — clone a workspace

Create and initialize a new workspace

# Create workspace
mkdir -p ~/workspaces/production-cluster
cd ~/workspaces/production-cluster
polycrate workspace init --with-name production-cluster

# Pull the first block (product chain: pull with version, then install)
polycrate block pull registry.my-org.com/blocks/k8s/cluster:1.0.0
polycrate run cluster install

VCS (git init / commit) stays an optional habit — not the Polycrate process. See Git integration.

Create a workspace from a template

workspace.config is not a free key-value bag for app or environment data — only typed Polycrate keys (e.g. blocksroot, artifactsroot). Free configuration belongs in blocks[].config. Details → Configuration.

mkdir -p ~/.polycrate/workspaces/acme/acme-production-1
cd ~/.polycrate/workspaces/acme/acme-production-1
polycrate workspace init --with-name acme-production-1 --with-organization acme

cat > workspace.poly << 'EOF'
name: acme-production-1
organization: acme

blocks:
  - name: k8s
    from: registry.acme.corp/blocks/k8s/cluster:1.2.0
    config:
      cluster_name: production
      region: eu-west-1

  - name: monitoring
    from: cargo.ayedo.cloud/ayedo/k8s/victoria-metrics-stack:1.0.0

workflows:
  - name: deploy-all
    steps:
      - name: setup-cluster
        block: k8s
        action: install
      - name: deploy-monitoring
        block: monitoring
        action: install
EOF

polycrate workflows run deploy-all --blocks-auto-pull

Multi-environment setup

Naming: $org-$purpose-$count. All workspaces under ~/.polycrate/workspaces/<org>/…. Always pass -w as an absolute path.

WS=~/.polycrate/workspaces/acme
mkdir -p "$WS"/{acme-production-1,acme-staging-1,acme-dev-1}

cd "$WS/acme-production-1"
polycrate workspace init --with-name acme-production-1 --with-organization acme

cd "$WS/acme-staging-1"
polycrate workspace init --with-name acme-staging-1 --with-organization acme

cd "$WS/acme-dev-1"
polycrate workspace init --with-name acme-dev-1 --with-organization acme

polycrate run my-block install -w "$HOME/.polycrate/workspaces/acme/acme-production-1"
polycrate run my-block install -w "$HOME/.polycrate/workspaces/acme/acme-staging-1"

Block management

Develop and test a block

cd my-workspace
mkdir -p blocks/my-custom-block

cat > blocks/my-custom-block/block.poly << 'EOF'
name: my-custom-block
version: 0.1.0

config:
  app_name: my-app
  port: 8080

actions:
  - name: install
    playbook: install.yml
  - name: uninstall
    playbook: uninstall.yml
EOF

polycrate run my-custom-block install
polycrate run my-custom-block install --local
polycrate block validate my-custom-block
polycrate block inspect my-custom-block

Release a block and install it downstream

Do not sed version:, do not block bump, and do not treat a Git tag as source of truth. Changelog and version are set by polycrate release *.

polycrate spec update <id> --set status=done
polycrate release create 0.2.0
polycrate release update 0.2.0 --set type=feat --set message="New feature description"
polycrate release finalize 0.2.0

polycrate block push my-block
polycrate block pull registry.my-org.com/infra/my-block:0.2.0
polycrate run my-block install

--workspace / -w must be an absolute path.

Canonical chain: Develop and deploy.

Block with a template reference

# workspace.poly
blocks:
  - name: k8s
    from: registry.my-org.com/blocks/k8s/cluster:1.0.0

  - name: my-app
    from: registry.my-org.com/blocks/k8s/my-app:1.0.0
    kubeconfig:
      from: k8s
    config:
      namespace: production
polycrate run my-app deploy --blocks-auto-pull

Dynamic blocks

Several instances of one block

# workspace.poly
name: multi-service

blocks:
  - name: generic-service
    config:
      service_name: template
      port: 8080
    actions:
      - name: deploy
        playbook: deploy.yml

  - name: frontend
    from: generic-service
    config:
      service_name: frontend
      port: 3000

  - name: backend
    from: generic-service
    config:
      service_name: backend
      port: 8080

  - name: api
    from: generic-service
    config:
      service_name: api
      port: 8081
polycrate run frontend deploy
polycrate run backend deploy
polycrate run api deploy
polycrate workflows run deploy-all

Workflows

Complex deployment workflow

# workspace.poly
workflows:
  - name: full-deployment
    prompt:
      message: "Start production deployment?"
    steps:
      - name: pre-deployment-check
        block: healthcheck
        action: validate
      - name: backup-database
        block: database
        action: backup
        allow_failure: true
      - name: deploy-database-migrations
        block: database
        action: migrate
      - name: deploy-backend
        block: backend
        action: install
      - name: deploy-frontend
        block: frontend
        action: install
      - name: run-smoke-tests
        block: tests
        action: smoke-test
      - name: notify-team
        block: notifications
        action: send
        allow_failure: true
polycrate workflow run full-deployment --force

Rollback workflow

# workspace.poly
workflows:
  - name: rollback
    prompt:
      message: "Really roll back to the previous version?"
    steps:
      - name: stop-services
        block: services
        action: stop
      - name: restore-database
        block: database
        action: restore
      - name: deploy-previous-version
        block: app
        action: install
      - name: restart-services
        block: services
        action: start
      - name: verify
        block: healthcheck
        action: validate

Artifacts

Share artifacts between actions

Complex artifact work belongs in Ansible playbooks, not scripts. Use block.artifacts.local_path when writing and workspace.config.artifacts_root when reading from another block.

Full artifact documentation

SSH and remote hosts

ssh-keygen -t ed25519 -f ./id_rsa -C "polycrate@example.com"
ssh-copy-id -i ./id_rsa.pub user@host1
polycrate ssh host1
echo "my-secure-passphrase" > ssh-passphrase.poly
polycrate workspace encrypt
polycrate run my-block install --ssh-use-passphrase

Encryption and secrets

secrets.poly uses the same shape as workspace.poly — secrets are defined per block. Encrypt with polycrate workspace encrypt.

Workspace encryption

CI/CD (consumes the same chain)

CI is not the product process. Pipelines call the same git-free chain (release, push, pull, install) — see Develop and deploy.

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy with Polycrate

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install Polycrate
        run: |
          curl -sSL https://get.polycrate.io | bash
          echo "$HOME/.polycrate/bin" >> $GITHUB_PATH
      - name: Deploy
        run: polycrate run my-app install --force

See also