Skip to main content

atmos scaffold

Atmos scaffolds turn a template directory into a governed generation workflow. A template asks for validated values, conditionally generates files, runs declared finishing steps, and can later merge upstream template improvements into an existing project.

Commands

CommandPurpose
atmos scaffold listList embedded, configured, and catalog templates.
atmos scaffold generateGenerate or update output from a template.
atmos scaffold validateValidate a template's scaffold.yaml manifest.

Template Contract

Each template directory contains a versioned scaffold.yaml plus files to generate. Files are discovered automatically; use spec.files only to conditionally gate discovered files.

scaffold.yaml
apiVersion: atmos/v1
kind: AtmosScaffoldConfig
metadata:
name: terraform-component
description: Standard Terraform component
spec:
fields:
- name: component_name
label: Component name
type: input
required: true
validation:
pattern: "^[a-z0-9-]+$"
message: Use lowercase letters, digits, and hyphens.
- name: environments
label: Environments
type: multiselect
options: [dev, staging, prod]
default: [dev]

spec.fields replaces the retired prompts: shape. Fields are available to rendered files as {{ .Config.component_name }}. Atmos validates declared fields after it merges interactive input, defaults, persisted spec.values, and repeated --set key=value flags, so automation follows the same rules as an interactive run.

Supported field types are input, text, string, select, multiselect, confirm, bool, and boolean. Required fields reject missing or blank text and empty multiselect values; false is a valid boolean answer. Select values must come from options, and text fields can use validation.pattern with an optional validation.message.

Conditions and Files

Use when: to make one template adapt to its answers. A condition can be always, never, ci, or local; a CEL expression; or a list treated as an implicit logical all. A field can only read answers from fields declared before it.

scaffold.yaml
spec:
fields:
- name: enable_monitoring
type: confirm
default: false
- name: alert_email
type: input
when: "answers.enable_monitoring == true"
files:
- path: monitoring/alerts.tf
when: "answers.enable_monitoring == true"
- path: stacks/staging.yaml
when: "'staging' in answers.environments"

Use CEL operators such as &&, ||, and ! for compound conditions. The map form {all: ...}, {any: ...}, or {not: ...} is not accepted in scaffold manifests.

Generation Hooks

Scaffold hooks run around generation at before.scaffold.generate and after.scaffold.generate. They use the shared hook envelope but intentionally support only kind: step and kind: steps because generation has no stack/component context.

scaffold.yaml
spec:
hooks:
format:
events: [after.scaffold.generate]
kind: step
type: shell
with:
command: terraform fmt -recursive
verify:
events: [after.scaffold.generate]
kind: steps
when: "answers.enable_monitoring == true"
with:
- type: require
tools: [terraform]
- type: shell
command: terraform validate

For kind: step, type: selects one registered step type and with: is its configuration. For kind: steps, with: is an ordered step list. The envelope owns events, when, env, retry, and on_failure; answer values are available in conditions as answers and in step templates as {{ .Answers.<field> }}. Hooks run in stable name order.

Use --skip-hooks or --skip-hooks=name1,name2 when inspecting an untrusted template or diagnosing generation. See lifecycle hooks for the broader stack-hook kinds and the shared step bridge.

Update Existing Output

atmos scaffold generate terraform-component ./components/terraform/vpc
atmos scaffold generate terraform-component ./components/terraform/vpc --update
atmos scaffold generate terraform-component ./components/terraform/vpc --update --merge-strategy=theirs

--update uses the recorded base revision to perform an optimistic three-way merge. The default manual strategy surfaces real conflicts; ours keeps local changes and theirs applies the template side of a conflict.

Project Initialization

atmos init consumes the same manifest and generation engine for complete project templates. Use init to select a built-in or catalog project starting point; use scaffold generate to distribute an organization-specific component, configuration, or other golden path.

atmos scaffold generate
 
00:00.0 / 00:00.0

Example: Scaffold Templates

Scaffold templates for generating new Atmos projects and components.

Learn more in the Scaffold Command Documentation.

What You'll See

  • Scaffold template configuration with scaffold.yaml
  • Interactive prompts for customizing generated projects
  • Template files with Go templating support
  • Conditional promptsvendor_version is only asked when: enable_vendoring was answered true
  • Conditional file generationvendor.yaml is only generated when: enable_vendoring is true, and is skipped entirely otherwise

Try It

# List available scaffold templates
atmos scaffold list

# Generate a new project from a template
atmos scaffold generate example ./my-project

# Generate with a pinned component version
atmos scaffold generate example ./my-project --set project_name=my-app --set enable_vendoring=true --set vendor_version=1.536.0

# Skip vendoring entirely — vendor_version is never asked and vendor.yaml is never generated
atmos scaffold generate example ./my-project --set enable_vendoring=false

Key Files

FilePurpose
scaffold.yamlTemplate configuration with prompts, conditional when: rules, and metadata
atmos.yamlTemplate for generated Atmos configuration
vendor.yamlConditionally-generated vendor manifest (only when enable_vendoring: true)

Learn More: Generation Hooks

Templates can also declare hooks that run automatically before or after generation — for example, formatting generated files or running a linter. Hooks reuse the same when: condition engine as Atmos workflows and CI hooks, and support --skip-hooks to opt out per invocation. This example doesn't wire one up, but the syntax looks like:

hooks:
format:
events:
- after.scaffold.generate
kind: step
type: shell
with:
command: "terraform fmt"

Creating Custom Templates

Scaffold templates use Go templates with access to:

  • .Config - Values from prompts and --vars flags
  • Sprig functions for string manipulation
  • Gomplate functions for advanced templating

See the Scaffold Templates Guide for more details.

Learn More