Skip to content

Sidecar (deckctl.yaml)

The sidecar is the file at a template’s root that declares how the template renders and what it expects. Its default filename is deckctl.yaml, overridable globally with --sidecar <name>.

On a local source, a directory without a sidecar is not a template at all. On a GitLab source every project is a template; one without a sidecar simply gets the built-in defaults.

delimiters:
variable_start: "[["
variable_end: "]]"
block_start: "[%"
block_end: "%]"
comment_start: "[#"
comment_end: "#]"
template_suffixes:
- ".tmpl"
- ".jinja"
subdirectory: template
variables:
- name: app_name
description: "Name of the application"
type: str
default: "myapp"
- name: port
type: int
default: 8080
- name: enable_metrics
type: bool
default: true
- name: runtime
type: choice
choices: ["go", "python", "node"]
default: "go"

Every top-level key is optional.

KeyTypeDefaultDescription
delimitersmappingJinja2 defaultsPer-template delimiter overrides
template_suffixeslist.tpl, .tmpl, .jinja, .j2Filename suffixes that trigger rendering. Replaces the default list.
subdirectorystring(empty)Render from this path inside the template root instead of the root
variableslist[]The variables the template expects
FieldDefault
variable_start{{
variable_end}}
block_start{%
block_end%}
comment_start{#
comment_end#}

Only set what you’re changing; anything omitted falls back to the default. Each pair must be both set or both empty — setting one half is a validation error:

variables delimiters must both be set or both empty

See Custom delimiters.

template_suffixes:
- ".tmpl" # now ONLY .tmpl renders; .tpl/.j2/.jinja files are copied verbatim

Setting this replaces the whole default list rather than adding to it. An empty or omitted list means the defaults apply.

subdirectory: template

Everything outside that subdirectory — the sidecar itself, the template repo’s own README, its CI config — is neither rendered nor copied. Equivalent to Copier’s _subdirectory.

FieldRequiredTypeDescription
nameyesstringIdentifier used inside template files
descriptionnostringShown by template variables; used as prompt help
typenostringstr (default), int, bool, choice
defaultnoanyAny YAML scalar; retains its YAML type
choicesonly for choicelist of stringsAllowed values
RuleError when broken
type must be one of str, int, bool, choice, or omitted"x" is not a valid type, please use any of "...
type: choice requires choicesvariable of type "choice" requires choices to be set
choices requires type: choiceN choices found, please set the variable type to "choice"

Check every local template’s sidecar with:

Terminal window
deckctl validate -t sidecar

At apply time each variable resolves as --vardefault → prompt.

default keeps its YAML type: default: 8080 is an integer, default: true a boolean. Values from --var are always strings — see Variables and prompting.

type and choices are metadata: they drive template variables output and sidecar validation. They do not constrain the interactive prompt, which is a free-text input for every type.

When a template has a copier.yml instead, deckctl translates it into this same structure:

CopierSidecar
_subdirectorysubdirectory
_templates_suffixtemplate_suffixes (single-entry list)
_envops.variable_start_string etc.delimiters.variable_start etc.
<question>: <scalar>A variable whose default is that scalar
<question>.helpdescription
<question>.typetype (str/int/bool; anything else → str + warning)
<question>.choiceschoices, and type forced to choice
<question>.defaultdefault, Jinja-evaluated if it looks like an expression
<question>.whenNo sidecar equivalent — evaluated during resolution
validator, secret, multiselect, placeholderIgnored, with a warning
Any other _-prefixed keyIgnored, with a warning

See Copier compatibility.