Inheritance & Worked Example
Both connections and environments support extends: for composition.
Connection inheritance — a base template
Section titled “Connection inheritance — a base template”extends: on a connection is a base-template pattern. Define the shared fields once:
type: zenvara/akeneoTimeoutSeconds: 120BatchSize: 100MaxConcurrency: 4AutoSanitizeCodes: true
# connections/akeneo-pim-prod/definition.yamlextends: akeneo-baseBaseUrl: "https://prod.cloud.akeneo.com"ClientId: "${secret:akeneo/pim-prod/client-id}"ClientSecret: "${secret:akeneo/pim-prod/client-secret}"Username: "${secret:akeneo/pim-prod/username}"Password: "${secret:akeneo/pim-prod/password}"Three overrides plus one base, instead of four near-identical files.
Environment inheritance
Section titled “Environment inheritance”extends: on an environment is a list of parent environments composed in order — single-level only (no transitive chains), to keep the resolution graph easy to read.
kind: stagingextends: - commonconnections: db: warehouse-staging # overrides whatever `common` had under dbWorked example: dev → prod for one flow
Section titled “Worked example: dev → prod for one flow”Two connections (one Postgres, one SFTP), two environments, one flow:
type: zenvara/postgresqlTimeoutSeconds: 30
# connections/audit-postgres-dev/definition.yamlextends: audit-postgres-baseConnectionString: "${secret:audit/dev:connection-string}"
# connections/audit-postgres-prod/definition.yamlextends: audit-postgres-baseConnectionString: "${secret:audit/prod:connection-string}"
# environments/dev/definition.yamlkind: developmentconnections: { audit: audit-postgres-dev, drop: drop-zone-dev }
# environments/prod/definition.yamlkind: productionconnections: { audit: audit-postgres-prod, drop: drop-zone-prod }status: activeoutput: archived: !int
steps: - $rows: invoke: postgresql.query on: audit with: { Query: "SELECT * FROM incidents WHERE archived = false" }
- $upload: create: sftp.file on: drop with: Path: "/incidents/${= str(_invocation-id)}.json" Input: "${rows.body}"
- return: archived: "${= len(rows.rows)}"Run it twice:
zen invoke-flow incident-archive --env devzen invoke-flow incident-archive --env prodSame flow, different audit DB, different SFTP drop zone. The environment is the only thing that changed — which is the whole point of the model.