Skip to main content

Understanding Terraform Templates

OpenPrime uses a template system to generate Terraform code from your environment configurations.

Template Structure​

Templates are located in openprime-infra-templates/templates/:

templates/
β”œβ”€β”€ aws/
β”‚ β”œβ”€β”€ eks/
β”‚ β”‚ β”œβ”€β”€ main.tf.tpl
β”‚ β”‚ β”œβ”€β”€ variables.tf.tpl
β”‚ β”‚ └── outputs.tf.tpl
β”‚ β”œβ”€β”€ rds/
β”‚ └── s3/
β”œβ”€β”€ azure/
β”‚ └── aks/
└── gcp/
└── gke/

Template Syntax​

Parameters​

Use @param to define configurable values:

# @param cluster_name
# @param cluster_version default=1.28
# @param node_count default=3

resource "aws_eks_cluster" "main" {
name = var.cluster_name
version = var.cluster_version
}

Conditional Sections​

Use @section for optional blocks:

# @section enable_logging begin
resource "aws_cloudwatch_log_group" "eks" {
name = "/aws/eks/${var.cluster_name}/cluster"
retention_in_days = 30
}
# @section enable_logging end

Loops​

Use @foreach for repeated resources:

# @foreach node_group in node_groups begin
resource "aws_eks_node_group" "node_group_${node_group.name}" {
cluster_name = aws_eks_cluster.main.name
node_group_name = "${node_group.name}"

scaling_config {
desired_size = ${node_group.desired_size}
min_size = ${node_group.min_size}
max_size = ${node_group.max_size}
}

instance_types = ["${node_group.instance_type}"]
}
# @foreach end

Processing Pipeline​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Template │────▢│ Injecto │────▢│ Terraform β”‚
β”‚ Files β”‚ β”‚ Processor β”‚ β”‚ Code β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β–² β–²
β”‚ β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”
β”‚ Template β”‚ β”‚ Environment β”‚
β”‚ Config β”‚ β”‚ Config β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Generated Output​

Input Configuration​

name: production
provider: aws
region: us-east-1
services:
kubernetes:
enabled: true
clusterName: prod-cluster
version: "1.28"
nodeGroups:
- name: general
instanceType: t3.large
desiredSize: 5

Generated Terraform​

# main.tf
terraform {
required_version = ">= 1.0"

required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}

backend "s3" {
bucket = "openprime-tfstate"
key = "production/terraform.tfstate"
region = "us-east-1"
dynamodb_table = "openprime-tflock"
encrypt = true
}
}

provider "aws" {
region = var.aws_region

default_tags {
tags = {
Environment = "production"
ManagedBy = "OpenPrime"
}
}
}

module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 19.0"

cluster_name = "prod-cluster"
cluster_version = "1.28"

vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets

eks_managed_node_groups = {
general = {
instance_types = ["t3.large"]

min_size = 2
max_size = 10
desired_size = 5
}
}
}

Customizing Templates​

Modifying Existing Templates​

  1. Edit files in openprime-infra-templates/templates/
  2. Follow the @param and @section syntax
  3. Test with ./terraforge.sh

Adding New Templates​

  1. Create directory structure:
mkdir -p templates/aws/my-service
  1. Create template files:
# templates/aws/my-service/main.tf.tpl
# @param service_name
# @param instance_count default=1

resource "aws_my_resource" "main" {
name = var.service_name
count = var.instance_count
}
  1. Register in service config:
// servicesConfig.js
myService: {
template: 'aws/my-service',
schema: { ... }
}

Template Variables​

Standard Variables​

VariableDescription
environment_nameEnvironment name
providerCloud provider
regionDeployment region
tagsResource tags

Service-Specific Variables​

Variables defined in service schemas are available:

# From kubernetes service schema
var.cluster_name
var.cluster_version
var.node_groups

Testing Templates​

Local Processing​

cd openprime-infra-templates/local
./terraforge.sh

Validation​

cd output/
terraform init
terraform validate
terraform plan

Best Practices​

  1. Use modules - Reference Terraform Registry modules
  2. Pin versions - Lock provider and module versions
  3. Document parameters - Add descriptions to @param
  4. Test thoroughly - Validate generated code compiles
  5. Keep DRY - Extract common patterns to shared templates