Blocks
Blocks are the modular building units of a Polycrate workspace: block.poly structure, block instances and template blocks, recommended metadata, vulnerability products, changelog and examples.poly.
Blocks
Blocks
A Polycrate workspace is a modular system made up of so-called blocks. Blocks are specialized code/function building units that can be configured via the block config (default: block.poly) or the workspace config (default: workspace.poly). Blocks offer actions that can be executed with polycrate run $BLOCK_NAME $ACTION_NAME.
Polycrate looks for blocks in the block root directory (default: blocks inside the workspace directory). Nested directories (e.g. blocks/foo/bar/baz) are allowed.
Block instances
A block instance is an entry under blocks: in workspace.poly. It can consist ad hoc of configuration only (without its own block directory under blocks/), in which case it uses only the tools available in the Polycrate container – or it references a template block with from:.
Template blocks live under blocks/ (locally) or are typically pulled from an OCI-compatible registry. The instance can inherit defaults and the working directory from the template and, if needed, override or extend config: and actions:.
Colloquially, block instances and template blocks are often referred to jointly as a “block” or “blocks”.
Block directory structure
The block directory is the directory below the block root that contains the custom code and the block configuration (block.poly) of a block.
Typical structure:
blocks/my-block/
├── block.poly # Block configuration (required)
├── README.md # Documentation
├── CHANGELOG.poly # Version history (→ Block changelog)
├── examples.poly # Configuration examples (→ Block examples)
├── install.yml # Ansible playbook: installation
├── uninstall.yml # Ansible playbook: uninstallation
├── backup.yml # Ansible playbook: backup (optional)
├── templates/ # Jinja2 templates for Ansible
│ ├── values.yaml.j2
│ └── deployment.yml.j2
└── scripts/ # Bash/Python scripts (if used)
└── init.sh
Block configuration (block.poly)
The block configuration contains the metadata and configuration for a single block.
Minimal block.poly
name: acme-demo-app
version: 1.0.0
actions:
- name: install
playbook: install.yml
Extended block.poly
# blocks/acme-demo-postgres/block.poly
name: acme-demo-postgres
version: 1.2.3
kind: k8sapp
type: database
flavor: postgresql
# Freely definable configuration (defaults)
config:
namespace: default
replicas: 1
database:
name: mydb
user: dbuser
persistence:
enabled: true
size: 10Gi
storageClass: standard
# Actions
actions:
- name: install
playbook: install.yml
- name: backup
playbook: backup.yml
- name: restore
playbook: restore.yml
The config: section is freely definable and not typed.
Recommended metadata
For template blocks that end up in the hub or as a catalogue app, the following fields should be set. The source of truth is block.poly.
Identity & classification
| Field | Recommended | Description |
|---|---|---|
name |
yes | Technical block name (naming rules) |
display_name |
yes | Human-readable title (hub, local). On API publish after blocks push (CLI ≥ 0.51.3) the API field display_name is the registry URL |
description |
yes | Short description |
icon_url |
yes | Icon URL for hub/API UI |
kind |
yes | e.g. k8sapp, k8scluster, linuxapp, dockerapp, library, generic |
type |
yes* | Category, e.g. db, kv, mq, s3, web (*for apps) |
flavor |
yes* | Technology, e.g. postgresql, redis |
implementation |
optional | Operator/stack, e.g. cnpg |
alias |
optional | Alternative search names |
labels |
optional | Free key/value labels |
supports_ha |
optional | true if HA is supported |
Version & license
| Field | Recommended | Description |
|---|---|---|
version |
yes | Block version (SemVer) |
app_version |
yes* | Upstream app version (outdated/upstream comparison) |
license |
yes | e.g. Apache-2.0 |
license_url |
optional | Link to the license text |
URLs
| Field | Recommended | Description |
|---|---|---|
website_url |
yes | Project website |
documentation_url |
yes | Documentation |
git_repository_url |
yes* | Upstream Git (catalogue meta sync) |
releases_url |
yes* | Upstream releases (GitHub sync) |
* especially for catalogue apps with upstream tracking.
name: postgres
display_name: "CloudNativePG PostgreSQL"
icon_url: https://cdn.example.com/icons/postgresql.svg
kind: k8sapp
type: db
flavor: postgresql
implementation: cnpg
supports_ha: true
description: "PostgreSQL with CloudNativePG"
app_version: "16.2"
license: Apache-2.0
website_url: https://cloudnative-pg.io
documentation_url: https://cloudnative-pg.io/documentation/
git_repository_url: https://github.com/cloudnative-pg/cloudnative-pg
releases_url: https://github.com/cloudnative-pg/cloudnative-pg/releases
→ Short rules: Best practices – metadata
Vulnerability products
Optional key vulnerability.products — for template blocks that end up as a catalogue app: product identities for CVE/OSV matching.
The section is identity only (vendor/product/PURL/…). No CVE lists and no enrichment in block.poly.
# block.poly (excerpt)
name: authentik
version: 0.12.0
kind: k8sapp
app_version: "2025.2.0"
releases_url: https://github.com/goauthentik/authentik/releases
git_repository_url: https://github.com/goauthentik/authentik
vulnerability:
products:
- vendor: goauthentik
product: authentik
ecosystem: Go
purl: "pkg:golang/goauthentik.io/authentik"
# cvefeed_product_id: "12345" # optional
# cpe: "cpe:2.3:a:goauthentik:authentik:*:*:*:*:*:*:*:*" # optional
| Field | Required | Description |
|---|---|---|
vendor |
yes | Vendor / upstream organization |
product |
yes | Product name for matching |
ecosystem |
no | OSV ecosystem (e.g. Go, PyPI, npm, Maven) – without a value there is no meaningful OSV query |
purl |
no | Package URL |
cpe |
no | CPE string |
cvefeed_product_id |
no | External product ID (e.g. CVEfeed) |
Behavior
- Section missing: the block remains valid; products can be maintained manually in the catalogue app tab Vulnerability Products.
- Section present: after hub/template block import or periodic sync, the API takes over the entries as
VulnerabilityProduct(source=block). The block is the source of truth for these keys; manually created rows (source=manual) are preserved. - Without products in the block and the UI: the CVE catalogue enrichment (OSV) has nothing to match.
→ Best practices · API: Vulnerability Management
Naming rules
Short overview – details, regex and examples:
Registry examples in this documentation often use the fictional organization acme and the registry registry.acme.corp (convention for generic examples).
Block versions and instances
Best practices:
- Explicit versions: always specify the version in the
from:key (from: .../block:1.2.3) - Consistency: update all instances at the same time when upgrading
- Validation: run
polycrate validate workspace-poly ./workspace.polyafter version updates
→ Detailed information in Dependencies
Missing block dependencies
If a block in workspace.poly references a block via from: that is not present in the workspace (or has a different version than requested), the command aborts with an error message (excerpt, varies slightly depending on the code path):
dependency 'cargo.ayedo.cloud/ayedo/k8s/postgres' not found in the Workspace. Please run `polycrate workspace update`, `polycrate block pull cargo.ayedo.cloud/ayedo/k8s/postgres` or run Polycrate with the `--blocks-auto-pull` flag
(polycrate block and polycrate blocks are the same command.)
Resolution:
- Include the dependency:
polycrate workspace updateand/orpolycrate block pull <registry/path/block-name>:<version>(alias:polycrate blocks pull …) - Automatically on run:
polycrate run ... --blocks-auto-pull– missing blocks are pulled automatically before execution
Block changelog
Every block can contain a CHANGELOG.poly. Recommended for reusable blocks — see the format below; SemVer notes: Best practices – block scoping.
The format has no author field; authorship can be documented in description: or in the Git commit if needed.
CHANGELOG.poly format
# blocks/my-block/CHANGELOG.poly
- version: "1.2.0"
date: "2025-12-30"
type: feat
message: "Added new feature"
description: |
- Implemented feature A
- Fixed bug B
- Improved performance
- version: "1.1.0"
date: "2025-12-15"
type: fix
message: "Bugfixes and improvements"
description: |
- Fixed critical bug
- Updated documentation
Changelog types
| Type | Description |
|---|---|
feat |
New feature |
fix |
Bugfix |
chore |
Maintenance, dependencies |
breaking |
Breaking change |
docs |
Documentation |
Showing the changelog
# Show the block changelog in an interactive TUI
polycrate block changelog my-block
# Show the changelog format specification
polycrate block changelog --spec
The TUI shows all versions with details and allows navigation with j/k or the arrow keys.
Block examples (examples.poly)
Blocks can ship an examples.poly file in the block directory containing typical configuration scenarios as named examples. The examples are shown in the CLI as an interactive TUI or as plain text and serve as a template for workspace.poly.
Format
examples.poly is a YAML mapping from example names to a config: section:
# blocks/acme-postgres/examples.poly
single-node:
config:
replicas: 1
database:
name: devdb
user: devuser
persistence:
enabled: false
ha-production:
config:
replicas: 3
database:
name: proddb
user: appuser
persistence:
enabled: true
size: 100Gi
storageClass: fast-ssd
read-replica:
config:
replicas: 2
read_replica: true
persistence:
enabled: true
size: 50Gi
The config: section of each example corresponds directly to the config: section that can be entered under the block instance in workspace.poly.
Showing examples
# Interactive TUI (select + view details)
polycrate block examples my-block
# Plain-text output (CI, scripting)
polycrate block examples my-block --no-pager
The TUI shows all examples as a navigable list. Enter shows the complete config: section of the selected example as YAML, Esc returns to the list.
Using an example in the workspace
# workspace.poly — adopt an example configuration
blocks:
- name: postgres
from: cargo.ayedo.cloud/ayedo/k8s/postgres:2.1.0
config:
replicas: 3
database:
name: proddb
user: appuser
persistence:
enabled: true
size: 100Gi
storageClass: fast-ssd
Hub display
Blocks published on the PolyHub show their examples.poly content in the block detail view. On block push the file is automatically uploaded as part of the block package.
See also
- Naming conventions
- Registry
- Dependencies — singletons and
from:versions - Inheritance
- Actions
- PolyHub
- Best practices