<TemplateInline>
The <TemplateInline> block renders a Boilerplate template written in the runbook file itself and shows the rendered output inline. <Template> loads its templates from a directory.
Basic usage
Section titled “Basic usage”<Inputs id="greeting">```yamlvariables: - name: Name type: string default: World```</Inputs>
<TemplateInline id="greeting-preview" inputsId="greeting" outputPath="hello.txt">```txtHello, {{ .inputs.Name }}!```</TemplateInline>vs. Template
Section titled “vs. Template”TemplateInline and Template both render Boilerplate templates:
| Feature | <TemplateInline> |
<Template> |
|---|---|---|
| Template source | Inline in runbook | Directory with boilerplate.yml |
| Form rendered | No (uses Inputs) | Yes, from boilerplate.yml |
| File generation | Optional (generateFile={true}) |
Always saves to workspace |
| Use case | Preview or generate a single file without a template directory | Generate files from a template directory with a boilerplate.yml |
Required props
Section titled “Required props”id(string). Unique identifier for this block. See Block IDs.- Inline template content. The template to render, written as a fenced code block inside the
<TemplateInline>tags. Give the code block a language hint (e.g.,hcl,yaml,dockerfile) for syntax highlighting.
Optional props
Section titled “Optional props”inputsId(string | string[]). ID of the Inputs block(s) to get variable values from. When multiple IDs are provided as an array, variables are merged in order (later IDs override earlier ones). If not provided, the template renders without variable substitution.outputPath(string). File path for the rendered output (e.g.,config.yamlordocs/account.hcl). This appears as the filename in the code block header. WithgenerateFile={true}, it is also where the file is saved, relative to the output directory. Missing parent directories are created.generateFile(boolean). Whether to save the rendered file to the workspace. Whenfalse(the default), the block only shows the rendered output inline.target("generated"|"worktree"). Where template output is written whengenerateFile={true}. Defaults to"generated", which writes to the generated files directory ($GENERATED_FILES)."worktree"writes into the active git worktree: the one selected in the workspace, or else the most recently cloned repository. It requires a<GitClone>block to have run first. Until then, the block shows an error in place of the preview.
With variables
Section titled “With variables”Using inputsId
Section titled “Using inputsId”Reference a separate Inputs block to get variable values:
<Inputs id="docker-config">```yamlvariables: - name: AppName type: string - name: NodeVersion type: string default: "18"```</Inputs>
<TemplateInline id="docker-preview" inputsId="docker-config" outputPath="Dockerfile">```dockerfileFROM node:{{ .inputs.NodeVersion }}-alpine
WORKDIR /appCOPY package*.json ./RUN npm installCOPY . .
EXPOSE 3000CMD ["node", "server.js"]```</TemplateInline>Using multiple inputsId values
Section titled “Using multiple inputsId values”You can reference multiple Inputs blocks by passing an array of IDs. Variables are merged in order, with later IDs overriding earlier ones:
<Inputs id="global-config">```yamlvariables: - name: Environment type: enum options: [dev, staging, prod] default: dev```</Inputs>
<Inputs id="service-config">```yamlvariables: - name: ServiceName type: string - name: Port type: int default: 8080```</Inputs>
<TemplateInline id="deploy-preview" inputsId={["global-config", "service-config"]} outputPath="deploy.tf">```hclresource "aws_ecs_service" "main" { name = "{{ .inputs.ServiceName }}-{{ .inputs.Environment }}"
load_balancer { container_port = {{ .inputs.Port }} }}```</TemplateInline>Multiple files
Section titled “Multiple files”You can have multiple <TemplateInline> blocks referencing the same <Inputs>:
<Inputs id="app-config">```yamlvariables: - name: AppName type: string - name: Environment type: enum options: [dev, prod]```</Inputs>
<TemplateInline id="app-config-preview" inputsId="app-config" outputPath="config.yaml">```yamlapp: name: {{ .inputs.AppName }} environment: {{ .inputs.Environment }}```</TemplateInline>
<TemplateInline id="app-env-preview" inputsId="app-config" outputPath=".env">```bashAPP_NAME={{ .inputs.AppName }}ENVIRONMENT={{ .inputs.Environment }}```</TemplateInline>With Boilerplate logic
Section titled “With Boilerplate logic”Templates can use Boilerplate template syntax, including conditionals and loops:
<Inputs id="terraform-config">```yamlvariables: - name: Environment type: enum options: [dev, prod] - name: EnableMonitoring type: bool default: false```</Inputs>
<TemplateInline id="terraform-preview" inputsId="terraform-config" outputPath="main.tf">```hclresource "aws_instance" "app" { ami = "ami-12345678" instance_type = "{{ if eq .inputs.Environment "prod" }}t3.large{{ else }}t3.micro{{ end }}"
{{- if .inputs.EnableMonitoring }} monitoring = true {{- end }}}```</TemplateInline>See Template syntax.
Using block outputs
Section titled “Using block outputs”TemplateInline can reference outputs from Command or Check blocks using the outputs namespace:
<TemplateInline id="account-info" outputPath="account-info.txt">```txtAccount ID: {{ .outputs.create_account.account_id }}Region: {{ .outputs.create_account.region }}```</TemplateInline>Runbooks scans the template content for output references and shows a warning until all upstream blocks have run.
For producing outputs, consuming them, dependency behavior, and ID naming rules, see Block outputs.
Generating files
Section titled “Generating files”By default, <TemplateInline> shows the rendered output and saves no file. To also save it, set generateFile={true}. The file is saved at outputPath inside the generated files directory (or inside the active git worktree with target="worktree"), and it is rewritten each time the block re-renders, for example when its inputs change:
<Inputs id="config">```yamlvariables: - name: ProjectName type: string```</Inputs>
<TemplateInline id="readme-preview" inputsId="config" outputPath="README.md" generateFile={true}>```markdown# {{ .inputs.ProjectName }}
Welcome to {{ .inputs.ProjectName }}!```</TemplateInline>If outputPath changes between renders, for example because it uses a <DirPicker> output, the block saves the file at the new path and cleans up the one it saved at the old path:
- If the block created the old file, it is removed, along with any directories that removal leaves empty.
- If a file was already at the old path before the block wrote to it, the block puts back its earlier content. The block never deletes a file it did not create.
- If the old file no longer holds what the block wrote, for example because you edited it, it is left as it is.
Cleanup only happens inside the directory the block is writing to now. With target="worktree", a file the block wrote into an earlier repo stays there after another <GitClone> makes a different repo the active worktree.
Complete example
Section titled “Complete example”# Configure Your Docker Service
Enter your service configuration:
<Inputs id="service-config">```yamlvariables: - name: ServiceName type: string description: Name of your service validations: - required - name: Port type: int description: Port to expose default: 8080 - name: Environment type: enum description: Deployment environment options: [dev, staging, prod] default: dev```</Inputs>
Here's what your Docker Compose file will look like:
<TemplateInline id="docker-compose" inputsId="service-config" outputPath="docker-compose.yaml" generateFile={true}>```yamlversion: "3.8"services: {{ .inputs.ServiceName }}: build: . ports: - "{{ .inputs.Port }}:{{ .inputs.Port }}" environment: - NODE_ENV={{ .inputs.Environment }}```</TemplateInline>
And your environment file:
<TemplateInline id="env-file" inputsId="service-config" outputPath=".env" generateFile={true}>```bashSERVICE_NAME={{ .inputs.ServiceName }}PORT={{ .inputs.Port }}ENVIRONMENT={{ .inputs.Environment }}```</TemplateInline>