A Terraform provider offering utility functions including template rendering with custom placeholder syntax that doesn't conflict with other templating systems.
When working with Terraform to deploy resources like Argo Workflows, Kubernetes manifests, or shell scripts, you often need to inject Terraform-managed values (like namespaces, image tags, or dates) into templates that also contain their own templating syntax.
The problem:
- Standard Terraform templating conflicts with Argo
{{}}, shell${}, and bash operators - Other providers like
kbst/kustomizationor Helm are often overkill for simple template substitution - Managing Kustomize overlays or Helm charts adds unnecessary complexity when you just need variable injection
Common conflicts:
- Argo Workflows:
{{inputs.parameters.*}}syntax - Shell scripts:
${VAR},$(command)syntax - Bash:
[[ ]],<<,>>,<>,&&,||,(( ))operators - Windows batch files:
%%VAR%%syntax
This provider solves it by using a distinctive placeholder syntax (@@VAR@@) that doesn't conflict with anything, while staying lightweight and focused on just template rendering.
- Conflict-free syntax:
@@VAR@@placeholders don't interfere with other templating systems - Validation: All placeholders must have corresponding values or an error is returned
- Simple: Pure data source, no infrastructure created
- Fast: Template rendering happens locally during plan/apply
π View Complete Documentation - Comprehensive guides for users and contributors
- Getting Started - Tutorial, examples, and best practices
- Reference - Complete API documentation
- Contributing - Development setup and releases
Add to your terraform block:
terraform {
required_providers {
utils = {
source = "spantree/utils"
version = "~> 0.2"
}
}
}
provider "utils" {}For local development and testing:
-
Build the provider:
make build
-
Create a local provider override in
~/.terraformrc:provider_installation { dev_overrides { "spantree/utils" = "/path/to/provider/directory" } direct {} }
data "utils_render_template" "greeting" {
template = "Hello @@NAME@@, welcome to @@PLACE@@!"
values = {
NAME = "Alice"
PLACE = "Wonderland"
}
}
output "greeting" {
value = data.utils_render_template.greeting.result
# Output: "Hello Alice, welcome to Wonderland!"
}data "utils_render_template" "config" {
template = <<-EOT
server {
host = "@@HOST@@"
port = @@PORT@@
environment = "@@ENV@@"
}
EOT
values = {
HOST = "localhost"
PORT = "8080"
ENV = "production"
}
}data "utils_render_template" "script" {
template = <<-EOT
#!/bin/bash
# Terraform-injected values
NAMESPACE=@@NAMESPACE@@
IMAGE_TAG=@@IMAGE_TAG@@
# Shell variables remain as-is
echo "Namespace: $${NAMESPACE}"
echo "Tag: $(echo $IMAGE_TAG)"
# Bash conditionals work fine
if [[ -n "$NAMESPACE" ]]; then
echo "Valid"
fi
EOT
values = {
NAMESPACE = "production"
IMAGE_TAG = "v1.2.3"
}
}This is the primary use case - deploying Argo WorkflowTemplates where you need both Terraform values and Argo's runtime parameters:
variable "namespace" {
default = "argo"
}
variable "image_tag" {
default = "v1.0.0"
}
data "utils_render_template" "workflow" {
template = file("${path.module}/workflow.yaml")
values = {
NAMESPACE = var.namespace
IMAGE_TAG = var.image_tag
}
}
resource "kubernetes_manifest" "workflow" {
manifest = yamldecode(data.utils_render_template.workflow.result)
}Where workflow.yaml contains:
apiVersion: argoproj.io/v1alpha1
kind: WorkflowTemplate
metadata:
name: my-workflow
namespace: @@NAMESPACE@@
spec:
templates:
- name: process
inputs:
parameters:
- name: input
container:
image: myapp:@@IMAGE_TAG@@
command: [sh, -c]
args:
# Argo's {{}} syntax is preserved
- echo "Processing {{inputs.parameters.input}}"After rendering, the @@NAMESPACE@@ and @@IMAGE_TAG@@ are replaced with Terraform values, while {{inputs.parameters.input}} remains intact for Argo to evaluate at runtime.
Use @@VARIABLE_NAME@@ format - alphanumeric and underscores only.
Learn more: Reference Documentation
β
Conflict-free with Argo {{}}, shell ${}, bash operators
β
Validates all placeholders have values
β
Clear error messages
β
No infrastructure created
Learn more: Getting Started
See Contributing Guide for detailed instructions.
Quick start:
# Install pre-commit hooks (one-time setup)
brew install pre-commit
pre-commit install
# Build
make build
# Test
make test
# Run examples
cd examples/basic && terraform init && terraform planNote: Pre-commit hooks automatically generate documentation from your code before each commit. See Contributing Guide for complete setup and release documentation.
Contributions welcome! See the Contributing Guide.
- π Documentation - Complete user guides and API reference
- π» Examples - Working code examples
- π Issues - Report bugs or request features
- π¦ Terraform Registry - Official provider listing
MIT License - see LICENSE for details.