Goal: Create reusable, governed infrastructure templates from working projects and publish them for self-service consumption.
# Convert a working project into a reusable template
cd my-reference-architecture
thothctl project convert --make-template --template-project-type terraform-terragrunt
# Test it
thothctl project convert --make-project --template-project-type terraform-terragrunt
# Publish to Git
git init && git add . && git commit -m "feat: initial template"
git remote add origin https://github.com/myorg/my-template.git
git push -u origin main
The template engine converts concrete values in your project into parameterized #{placeholder}# expressions, creating a reusable pattern that other developers can instantiate with their own values.
Before (working project):
bucket = "my-api-prod-tfstate"
region = "us-east-1"
tags = { Team = "backend", Environment = "prod" }
After --make-template:
bucket = "#{project}#-#{environment}#-tfstate"
region = "#{deployment_region}#"
tags = { Team = "#{owner}#", Environment = "#{environment}#" }
The engine reads [project_properties] from .thothcf.toml to know which values to parameterize.
Ensure your project is production-ready and has a .thothcf.toml with project properties:
[thothcf]
project_id = "ecs-platform"
[project_properties]
project = "ecs-platform"
environment = "prod"
region = "us-east-1"
backend_bucket = "ecs-platform-tfstate"
backend_region = "us-east-2"
dynamodb_backend = "db-terraform-lock"
owner = "platform-team"
client = "myorg"
thothctl project convert --make-template --template-project-type terraform-terragrunt
This:
.git, .terraform, etc.)[project_properties] with #{key}# placeholders~/.thothcf/ecs-platform/Add [template_input_parameters] to .thothcf.toml for validation and better prompts when developers use the template:
[template_input_parameters.project]
template_value = "#{project}#"
condition = "^[a-z0-9-]+$"
description = "Project name (lowercase, hyphens allowed)"
[template_input_parameters.environment]
template_value = "#{environment}#"
condition = "(dev|qa|stg|prod)"
description = "Target environment"
[template_input_parameters.region]
template_value = "#{deployment_region}#"
condition = "^[a-z]{2}-[a-z]+-\\d$"
description = "AWS deployment region"
[template_input_parameters.backend_bucket]
template_value = "#{backend_bucket}#"
condition = "^[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$"
description = "S3 bucket for Terraform state"
[template_input_parameters.owner]
template_value = "#{owner}#"
condition = "^[a-zA-Z0-9_-]+$"
description = "Team or owner name"
Enforce required files/folders so developers don’t accidentally break the pattern:
[project_structure]
root_files = [".gitignore", "README.md", ".thothcf.toml", ".pre-commit-config.yaml"]
ignore_folders = [".git", ".terraform", ".terragrunt-cache"]
[[project_structure.folders]]
name = "stacks"
mandatory = true
type = "root"
[[project_structure.folders]]
name = "modules"
mandatory = true
type = "root"
content = ["main.tf", "variables.tf", "outputs.tf"]
# Create a project from your template to verify it works
thothctl project convert --make-project --template-project-type terraform-terragrunt
# Validate the output
terraform init
terraform validate
git init
git add .
git commit -m "feat: ecs-platform template v1.0.0"
git remote add origin https://github.com/myorg/ecs-platform-template.git
git push -u origin main
git tag -a v1.0.0 -m "Initial release"
git push origin v1.0.0
Option A — Register as custom scaffold URL:
# Any developer can now use it via init project
thothctl init template --project-type terraform-terragrunt \
--template-url https://github.com/myorg/ecs-platform-template.git
Option B — Add to a space (team-wide):
Place the template repo in your team’s GitHub org or Azure DevOps project. Developers discover it with:
thothctl init project --reuse --space my-team
Option C — Register in Backstage:
Create a catalog-info.yaml and a Backstage scaffolder template for portal-based self-service. See Platform Engineering Templates for the full Backstage integration guide.
When you improve the template (new security rules, updated configs):
thothctl project convert --make-templateDevelopers sync via:
thothctl project upgrade --dry-run # check
thothctl project upgrade # apply
ThothCTL tracks file hashes in ~/.thothcf/.thothcf.toml. When a developer runs --make-project, it can detect which files have drifted from the template and suggest updates.
[project_properties] that are ≥4 characters are replaced with word-boundary matchingkey = "value").git, .terraform, .terragrunt-cache, node_modules, __pycache__.terraform.lock.hcl, catalog-info.yaml, .gitignoreYou can also add #{placeholder}# expressions manually for values the automatic conversion doesn’t catch:
# Manually parameterized
vpc_cidr = "#{vpc_cidr}#"
max_az_count = #{max_az_count}#
Just make sure to add corresponding entries in [template_input_parameters].
| Command | Purpose |
|---|---|
thothctl project convert --make-template |
Convert project → parameterized template |
thothctl project convert --make-project |
Instantiate template → working project |
thothctl init template --project-type X --template-url Y |
Register custom scaffold URL |
thothctl project upgrade --dry-run |
Check what would update in downstream projects |
thothctl generate component |
Test component generation from structure rules |
thothctl check project iac |
Validate project against structure rules |
condition to catch mistakes at input timemake-template → make-project → terraform validate works