Platform engineers can create reusable infrastructure templates from existing projects (blueprints, POCs, or reference architectures) and publish them for consumption through Internal Developer Platforms like Backstage.
Template Format: ThothCTL uses #{ }# placeholder expressions for parameterization, not Jinja2 syntax.
Example Blueprint: terragrunt_ecs_blueprint - Production-ready ECS Fargate architecture with ALB, RDS, and multi-AZ deployment.
A platform engineering team has developed a production-ready reference architecture for a microservices platform. They want to:
#{ }# expressions%%{init: {'theme':'base', 'themeVariables': {
'primaryColor':'#3b82f6',
'primaryTextColor':'#ffffff',
'primaryBorderColor':'#2563eb',
'lineColor':'#94a3b8',
'secondaryColor':'#10b981',
'tertiaryColor':'#8b5cf6',
'background':'transparent',
'mainBkg':'#3b82f6',
'secondBkg':'#10b981',
'tertiaryBkg':'#8b5cf6',
'clusterBkg':'rgba(241, 245, 249, 0.05)',
'clusterBorder':'#475569',
'titleColor':'currentColor',
'edgeLabelBackground':'transparent',
'nodeTextColor':'#ffffff',
'textColor':'currentColor',
'nodeBorder':'#1e293b',
'fontSize':'14px'
}}}%%
graph LR
A["Working<br/>Project"] --> B["Convert to<br/>Template"]
B --> C["Parameterize<br/>Values"]
C --> D["Test<br/>Template"]
D --> E["Publish to<br/>Git"]
E --> F["Register in<br/>Backstage"]
F --> G["Self-Service<br/>Consumption"]
classDef projectStyle fill:#3b82f6,stroke:#60a5fa,stroke-width:2px,color:#fff
classDef processStyle fill:#10b981,stroke:#34d399,stroke-width:2px,color:#fff
classDef publishStyle fill:#8b5cf6,stroke:#a78bfa,stroke-width:2px,color:#fff
class A projectStyle
class B,C,D processStyle
class E,F,G publishStyle
Ensure your project is production-ready:
# Navigate to your reference architecture
cd /path/to/microservices-platform
# Verify structure
tree -L 2
Example Project Structure:
microservices-platform/
├── common/
│ ├── backend.tf
│ └── variables.tf
├── environments/
│ ├── dev/
│ ├── staging/
│ └── prod/
├── stacks/
│ ├── networking/
│ ├── compute/
│ ├── database/
│ └── monitoring/
├── docs/
│ └── README.md
└── root.hcl
Use ThothCTL to convert your project into a reusable template:
# Convert project to template
thothctl project convert --make-template --template-project-type terraform
# Or for Terraform with Terragrunt
thothctl project convert --make-template --template-project-type terraform-terragrunt
# Or for standalone Terragrunt
thothctl project convert --make-template --template-project-type terragrunt
# Or for OpenTofu
thothctl project convert --make-template --template-project-type tofu
# Or for CDK v2
thothctl project convert --make-template --template-project-type cdkv2
# Or for Terraform modules
thothctl project convert --make-template --template-project-type terraform_module
# Or for custom project types
thothctl project convert --make-template --template-project-type custom
What This Does:
[project_properties] in .thothcf.toml#{placeholder}# expressions in project files~/.thothcf/<project_name>/The conversion creates template files with #{ }# placeholder expressions:
Before (Project):
# environments/prod/main.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "microservices-vpc"
Environment = "production"
Team = "platform-engineering"
}
}
After (Template):
# environments/#{environment}#/main.tf
resource "aws_vpc" "main" {
cidr_block = "#{vpc_cidr}#"
tags = {
Name = "#{project_name}#-vpc"
Environment = "#{environment}#"
Team = "#{team_name}#"
}
}
Example from Blueprint:
# common/common.tfvars
project_name = "#{project}#"
environment = "#{environment}#"
region = "#{backend_region}#"
dynamodb_table = "#{dynamodb_backend}#"
backend_bucket = "#{backend_bucket}#"
You can also manually replace values using your IDE or shell script:
# Example replacements from terragrunt_ecs_blueprint
project_name = "#{project}#"
environment = "#{environment}#"
region = "#{backend_region}#"
dynamodb_table = "#{dynamodb_backend}#"
backend_bucket = "#{backend_bucket}#"
Using find and replace in your IDE:
"my-project-name" → Replace: "#{project}#""production" → Replace: "#{environment}#""us-east-1" → Replace: "#{backend_region}#"The .thothcf.toml file is critical for template functionality. It maps #{ }# placeholders to parameters with validation rules and defines project structure requirements.
Create .thothcf.toml in your template root:
[thothcf]
project_id = "microservices-platform"
project_type = "terraform"
# Define template parameters with validation
[template_input_parameters.project_name]
template_value = "#{project}#"
condition = "^[a-zA-Z0-9_-]+$"
description = "Project Name"
[template_input_parameters.environment]
template_value = "#{environment}#"
condition = "(dev|qa|stg|staging|test|prod)"
description = "Environment name (dev|qa|stg|staging|test|prod)"
[template_input_parameters.deployment_region]
template_value = "#{backend_region}#"
condition = "^[a-z]{2}-[a-z]{4,10}-\\d$"
description = "AWS Region for deployment"
[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.backend_region]
template_value = "#{backend_region}#"
condition = "^[a-z]{2}-[a-z]{4,10}-\\d$"
description = "Backend AWS Region"
[template_input_parameters.backend_dynamodb]
template_value = "#{dynamodb_backend}#"
condition = "^[a-zA-Z0-9_.-]{3,255}$"
description = "DynamoDB table for state locking"
[template_input_parameters.owner]
template_value = "#{team_name}#"
condition = "^[a-zA-Z0-9_-]+$"
description = "Team or role owner for this deployment"
[template_input_parameters.vpc_cidr]
template_value = "#{vpc_cidr}#"
condition = "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}/\\d{1,2}$"
description = "VPC CIDR block"
[template_input_parameters.cloud_provider]
template_value = "aws"
condition = "(aws|azure|oci|gcp)"
description = "Cloud provider (aws|azure|oci|gcp)"
[template_input_parameters.deployment_profile]
template_value = "default"
condition = "^[a-zA-Z0-9_.-]{3,255}$"
description = "AWS CLI deployment profile"
# Define project structure requirements
[project_structure]
root_files = [
".gitignore",
"README.md",
".thothcf.toml"
]
ignore_folders = [
".git",
".terraform",
"Reports"
]
[[project_structure.folders]]
name = "common"
mandatory = true
type = "root"
content = ["backend.tf", "variables.tf"]
[[project_structure.folders]]
name = "environments"
mandatory = true
type = "root"
[[project_structure.folders]]
name = "stacks"
mandatory = true
type = "root"
Key Components:
#{ }# placeholder to a parameter with:
template_value: The placeholder used in filescondition: Regex validation patterndescription: Human-readable descriptionOptional: Backstage template.yaml
If you plan to integrate with Backstage for self-service, you can create a separate template.yaml in Backstage scaffolder format (see Step 6 below). The .thothcf.toml is the primary configuration for ThothCTL’s template engine.
Before publishing, test the template by converting it back to a project:
# Create a test project from the template
thothctl project convert --make-project --template-project-type terraform
# Verify generated project
cd test-microservices
terraform init
terraform plan
Push your template to a Git repository:
# Initialize Git repository
cd microservices-platform
git init
git add .
git commit -m "feat: create microservices platform template"
# Push to remote (GitHub, GitLab, Azure DevOps)
git remote add origin https://github.com/your-org/microservices-platform-template.git
git push -u origin main
# Tag the release
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
Create a Backstage template definition:
template.yaml (Backstage format):
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: microservices-platform
title: Microservices Platform on AWS
description: Production-ready microservices infrastructure with networking, compute, database, and monitoring
tags:
- terraform
- aws
- microservices
- platform-engineering
spec:
owner: platform-team
type: infrastructure
parameters:
- title: Project Information
required:
- project_name
- team_name
properties:
project_name:
title: Project Name
type: string
description: Name for your microservices platform
team_name:
title: Team Name
type: string
description: Team responsible for this infrastructure
environment:
title: Environment
type: string
description: Target environment
enum:
- dev
- staging
- prod
default: dev
- title: Network Configuration
properties:
vpc_cidr:
title: VPC CIDR Block
type: string
description: CIDR block for the VPC
default: "10.0.0.0/16"
aws_region:
title: AWS Region
type: string
description: AWS region for deployment
default: us-east-1
enum:
- us-east-1
- us-west-2
- eu-west-1
steps:
- id: fetch-template
name: Fetch Template
action: fetch:template
input:
url: https://github.com/your-org/microservices-platform-template
values:
project_name: $
team_name: $
environment: $
vpc_cidr: $
aws_region: $
- id: publish
name: Publish to GitHub
action: publish:github
input:
allowedHosts: ['github.com']
description: $ - Microservices Platform
repoUrl: github.com?owner=your-org&repo=$
- id: register
name: Register Component
action: catalog:register
input:
repoContentsUrl: $
catalogInfoPath: '/catalog-info.yaml'
output:
links:
- title: Repository
url: $
- title: Open in Backstage
icon: catalog
entityRef: $
Developers can now use the template through Backstage:
Result: A new repository with fully configured infrastructure ready for deployment.
For advanced deployment patterns:
# Convert to Terramate stacks
thothctl project convert \
--make-terramate-stacks \
--branch-name main
# This creates Terramate stack structure
# with proper dependencies and ordering
Convert a template back to a working project:
# Create project from template
thothctl project convert \
--make-project \
--template-project-type terraform
Scenario: Create standardized blueprints for common architectures
Examples:
Command:
thothctl project convert --make-template --template-project-type terraform
Scenario: Convert successful POC into production-ready template
Workflow:
Command:
thothctl project convert --make-template --template-project-type terraform
Scenario: Build a library of reference architectures
Structure:
reference-architectures/
├── microservices-platform/
├── data-analytics-platform/
├── ml-training-platform/
└── serverless-api-platform/
Each template includes:
Scenario: Create templates for different cloud providers
Examples:
Benefit: Consistent architecture across clouds
name: Validate Template
on:
push:
branches: [main]
pull_request:
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install ThothCTL
run: pip install thothctl
- name: Test Template
run: |
cd templates/source-project
thothctl project convert --make-project --template-project-type terraform
terraform init
terraform validate
validate-template:
stage: test
script:
- pip install thothctl
- thothctl project convert --make-project --template-project-type terraform
- terraform init && terraform validate
✅ Do:
❌ Don’t:
✅ Do:
Include in your template:
README.md - Overview and quick startUSAGE.md - Detailed usage guideARCHITECTURE.md - Architecture decisionsPARAMETERS.md - Parameter referenceEXAMPLES.md - Usage examplesTest your templates:
microservices-platform-template/
├── .github/
│ └── workflows/
│ └── validate.yml
├── common/
│ ├── backend.tf
│ └── variables.tf
├── environments/
│ └── #{environment}#/
├── stacks/
│ ├── networking/
│ ├── compute/
│ ├── database/
│ └── monitoring/
├── docs/
│ ├── README.md
│ ├── ARCHITECTURE.md
│ └── PARAMETERS.md
├── examples/
│ ├── dev-example.yaml
│ ├── staging-example.yaml
│ └── prod-example.yaml
├── .thothcf.toml # ThothCTL template config (parameters + structure)
├── backstage-template.yaml # Backstage template config
├── catalog-info.yaml # Backstage catalog entry
├── CHANGELOG.md
└── LICENSE
| Command | Purpose |
|---|---|
thothctl project convert --make-template |
Convert project to template |
thothctl project convert --make-project |
Convert template to project |
thothctl project convert --make-terramate-stacks |
Create Terramate stacks |
thothctl init project --reuse --space <name> |
Create project from VCS template |
thothctl project bootstrap |
Add ThothCTL support to existing project |
thothctl project upgrade |
Upgrade project from template |
✅ Standardization - Consistent infrastructure across teams
✅ Reusability - Write once, use many times
✅ Governance - Enforce best practices and compliance
✅ Efficiency - Reduce time from idea to deployment
✅ Quality - Battle-tested, production-ready templates
✅ Self-Service - Deploy infrastructure without platform team
✅ Speed - Minutes instead of weeks
✅ Confidence - Pre-validated, secure configurations
✅ Focus - Spend time on features, not infrastructure
✅ Consistency - Same patterns across projects
Platform Engineering Team
Enabling developer velocity through self-service infrastructure