Creating Bundle Templates
Bundle templates are boilerplate projects that help you quickly scaffold new Massdriver bundles. This guide explains how to create and configure custom templates for your organization.
Overview
Templates allow you to standardize how bundles are created across your organization. Each template is a directory containing a massdriver.yaml file with Liquid templating support, along with any IaC files needed for the bundle.
Directory Structure
A templates directory has a simple flat structure where each subdirectory is a template:
templates/
├── opentofu-module/
│ ├── massdriver.yaml
│ ├── operator.md
│ └── src/
│ ├── _providers.tf
│ └── main.tf
├── helm-chart/
│ ├── massdriver.yaml
│ └── chart/
│ ├── Chart.yaml
│ ├── values.yaml
│ └── templates/
├── kubernetes-deployment/
│ ├── massdriver.yaml
│ └── src/
└── my-custom-template/
├── massdriver.yaml
└── ...
Each template directory must contain a massdriver.yaml file at its root. This file will be rendered with user-provided values when creating a new bundle.
Creating a Template
1. Create the Template Directory
mkdir -p my-templates/my-opentofu-bundle
cd my-templates/my-opentofu-bundle
2. Create the massdriver.yaml Template
The massdriver.yaml file uses Liquid templating to interpolate user-provided values. Here's a complete example:
name: "{{ name }}"
description: "{{ description }}"
source_url: github.com/YOUR_ORG/{{ name }}
access: private
steps:
- path: src
provisioner: opentofu
# Parameters - use paramsSchema if importing from existing IaC
{%- if paramsSchema.size > 0 %}
{{ paramsSchema }}
{% else %}
params:
examples:
- __name: Development
instance_type: t3.small
- __name: Production
instance_type: t3.large
required:
- instance_type
properties:
instance_type:
type: string
title: Instance Type
description: EC2 instance type
default: t3.small
{% endif %}
# Connections - populated from user selections
connections:
{%- if connections.size > 0 %}
required:
{%- for conn in connections %}
- {{ conn.name -}}
{% endfor %}
properties:
{%- for conn in connections %}
{{ conn.name }}:
$ref: {{ conn.artifact_definition -}}
{% endfor %}
{% else %}
properties: {}
{% endif %}
# Artifacts - define outputs your bundle produces
artifacts:
properties: {}
# UI customization
ui:
ui:order:
- "*"
Available Template Variables
| Variable | Description |
|---|---|
{{ name }} | Bundle name provided by user |
{{ description }} | Bundle description provided by user |
{{ connections }} | Array of connection objects with name and artifact_definition |
{{ paramsSchema }} | YAML string of params imported from existing IaC |
{{ envs }} | Map of environment variable templates from artifact definitions |
3. Add IaC Files
Create the infrastructure code in a src/ directory (or appropriate location for your provisioner):
mkdir src
src/main.tf
resource "aws_instance" "main" {
ami = var.ami
instance_type = var.instance_type
tags = var.md_metadata.default_tags
}
src/_providers.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
massdriver = {
source = "massdriver-cloud/massdriver"
}
}
}
provider "aws" {
region = var.aws_authentication.data.arn
assume_role {
role_arn = var.aws_authentication.data.arn
}
default_tags {
tags = var.md_metadata.default_tags
}
}
4. Add an Operator Guide (Optional)
Create an operator.md file to provide documentation for bundle users:
## {{ name }}
{{ description }}
### Configuration
Configure the instance type based on your workload requirements.
### Troubleshooting
Check CloudWatch logs for any deployment issues.
Configuring the CLI
To use your templates directory, configure the Massdriver CLI with the path to your templates.
Option 1: Environment Variable
export MD_TEMPLATES_PATH=/path/to/my-templates
Option 2: Config File
Create or edit ~/.config/massdriver/config.yaml:
templates_path: /path/to/my-templates
The environment variable takes precedence over the config file, making it easy to switch between template repositories for different projects.
Using Templates
Once configured, you can use your templates with the CLI:
List Available Templates
mass bundle template list
Output:
Available templates:
helm-chart
kubernetes-deployment
my-custom-template
opentofu-module
Create a New Bundle
mass bundle new
Or non-interactively:
mass bundle new \
--name my-new-bundle \
--template-name opentofu-module \
--output-directory ./my-new-bundle \
--connections aws_authentication=massdriver/aws-iam-role
Template Best Practices
1. Include Cloud Credentials
Always include the appropriate cloud credential connection for your target cloud:
| Cloud | Artifact Definition | Suggested Name |
|---|---|---|
| AWS | massdriver/aws-iam-role | aws_authentication |
| GCP | massdriver/gcp-service-account | gcp_authentication |
| Azure | massdriver/azure-service-principal | azure_service_principal |
2. Use Configuration Presets
Include examples in your params to provide configuration presets:
params:
examples:
- __name: Development
instance_type: t3.small
storage_size: 20
- __name: Production
instance_type: t3.large
storage_size: 100
3. Organize by Use Case
Structure your templates directory by common use cases in your organization:
templates/
├── aws-lambda-api/ # API Gateway + Lambda
├── aws-ecs-service/ # ECS Fargate service
├── gcp-cloud-run/ # Cloud Run service
├── k8s-deployment/ # Generic Kubernetes deployment
└── internal-api/ # Your org's internal API pattern
4. Version Your Templates
Keep your templates in version control and tag releases:
git tag v1.0.0
git push origin v1.0.0
Example: Complete OpenTofu Template
Here's a complete example of an OpenTofu template for an AWS S3 bucket:
Directory structure:
s3-bucket/
├── massdriver.yaml
├── operator.md
└── src/
├── _providers.tf
├── main.tf
└── _variables.tf
massdriver.yaml:
name: "{{ name }}"
description: "{{ description }}"
source_url: github.com/YOUR_ORG/{{ name }}
access: private
steps:
- path: src
provisioner: opentofu
params:
examples:
- __name: Development
bucket_name: my-dev-bucket
versioning_enabled: false
- __name: Production
bucket_name: my-prod-bucket
versioning_enabled: true
required:
- bucket_name
properties:
bucket_name:
type: string
title: Bucket Name
description: Name of the S3 bucket
versioning_enabled:
type: boolean
title: Enable Versioning
description: Enable versioning on the bucket
default: false
connections:
required:
- aws_authentication
properties:
aws_authentication:
$ref: massdriver/aws-iam-role
artifacts:
required:
- bucket
properties:
bucket:
$ref: massdriver/aws-s3-bucket
ui:
ui:order:
- bucket_name
- versioning_enabled
Reference Templates
For more examples, see the Massdriver Application Templates repository, which contains templates for common deployment patterns across AWS, GCP, Azure, and Kubernetes.