Template Contribution Guide#

Agent Zone validation templates are reusable infrastructure configurations that agents and developers use to validate changes. A Kubernetes devcontainer template, an ephemeral EKS cluster module, a static validation pipeline script – each follows a standard format so that any agent or developer can pick one up, understand its purpose, and use it without reading through implementation details.

This guide defines the standards for contributing templates. It covers directory structure, required files, testing, quality expectations, versioning, and the submission process.

Template Format Standards#

Directory Structure#

Every template lives in its own directory under templates/. The directory name describes what the template validates, using lowercase words separated by hyphens.

templates/
  ephemeral-eks-cluster/
    README.md
    main.tf
    variables.tf
    outputs.tf
    terraform.tfvars.example
    scripts/
      validate.sh
      cleanup.sh
    tests/
      test_create_destroy.sh
    COST.md

  kubernetes-devcontainer/
    README.md
    .devcontainer/
      devcontainer.json
      Dockerfile
      post-create.sh
    tests/
      test_devcontainer.sh

  helm-validation-pipeline/
    README.md
    scripts/
      validate.sh
    policy/
      kubernetes.rego
    tests/
      test_validation.sh
      fixtures/
        valid-chart/
        invalid-chart/

Required Files#

Every template must include these files:

README.md – The primary documentation. Follows a strict format:

# Template Name

One-sentence description of what this template validates.

## Prerequisites

- List of tools required (with minimum versions)
- Cloud accounts or credentials needed
- Estimated cost (for cloud templates)

## Quick Start

Step-by-step instructions to use the template. Must be copy-pasteable.

## What It Validates

Explicit list of what this template checks.

## What It Does Not Validate

Explicit list of known gaps. This prevents users from assuming
the template covers more than it does.

## Configuration

| Variable | Default | Description |
|---|---|---|
| cluster_name | ephemeral | Name of the cluster |

## Cost Estimate

(Cloud templates only)
- Per-hour cost breakdown
- Expected validation duration
- Maximum cost if cleanup fails
- Auto-destroy mechanism description

## Cleanup

How to manually clean up if automated cleanup fails.

## Platform Support

| Platform | Status |
|---|---|
| Linux x86_64 | Tested |
| macOS ARM64 | Tested |
| Windows WSL2 | Untested |

tests/ – Directory containing automated tests. At minimum, one test that exercises the template end-to-end. See the testing section below for specifics.

scripts/validate.sh – For templates that run validation, this is the entry point. It must accept standard arguments and return exit code 0 on success, non-zero on failure.

Optional Files#

COST.md – Detailed cost breakdown for cloud templates. Required if the template creates billable resources.

Makefile – For templates with multiple commands, a Makefile provides standardized targets:

.PHONY: validate test clean

validate:
	bash scripts/validate.sh

test:
	bash tests/test_create_destroy.sh

clean:
	bash scripts/cleanup.sh

.tool-versions – Pin tool versions using asdf format:

terraform 1.7.5
kubectl 1.29.3
helm 3.14.3
kind 0.24.0

Testing Requirements#

Every template must include automated tests. The tests prove the template works as described and serve as living documentation for how to use it.

Test Structure#

Tests are shell scripts in the tests/ directory. They follow a consistent pattern:

#!/bin/bash
# test_validation.sh -- Tests for the helm-validation-pipeline template.
# Requires: helm, kubeconform, conftest
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEMPLATE_DIR="$(dirname "$SCRIPT_DIR")"
FAILURES=0

pass() { echo "  PASS: $1"; }
fail() { echo "  FAIL: $1"; FAILURES=$((FAILURES + 1)); }

echo "=== Testing helm-validation-pipeline ==="

# Test 1: Valid chart passes validation
echo "Test: Valid chart passes validation"
if bash "$TEMPLATE_DIR/scripts/validate.sh" "$SCRIPT_DIR/fixtures/valid-chart" 2>/dev/null; then
  pass "Valid chart accepted"
else
  fail "Valid chart rejected"
fi

# Test 2: Invalid chart fails validation
echo "Test: Invalid chart fails validation"
if bash "$TEMPLATE_DIR/scripts/validate.sh" "$SCRIPT_DIR/fixtures/invalid-chart" 2>/dev/null; then
  fail "Invalid chart accepted (should have failed)"
else
  pass "Invalid chart rejected"
fi

# Test 3: Missing chart directory reports error
echo "Test: Missing directory reports error"
if bash "$TEMPLATE_DIR/scripts/validate.sh" "/nonexistent/path" 2>/dev/null; then
  fail "Missing directory did not report error"
else
  pass "Missing directory reported error"
fi

echo ""
if [ "$FAILURES" -eq 0 ]; then
  echo "All tests passed."
  exit 0
else
  echo "$FAILURES test(s) failed."
  exit 1
fi

Test Categories#

Unit tests – Test individual components of the template in isolation. For a validation pipeline, test that each tool catches its expected errors using fixture files.

tests/
  fixtures/
    valid-chart/           # A minimal valid Helm chart
    invalid-chart/         # A chart with known errors
    deprecated-api/        # Manifests using removed API versions
    missing-limits/        # Deployment without resource limits

Integration tests – Test the full template workflow. For a devcontainer template, build the container image and verify each tool is installed at the expected version. For an ephemeral cluster template, create and destroy the cluster (these tests are slow and may require cloud credentials).

Negative tests – Verify that the template correctly rejects invalid input. A validation template must fail on bad input, not silently pass. Include fixture files that represent each category of error the template claims to catch, and assert that the template reports errors for each one.

Test Environment Expectations#

Tests must not require credentials unless explicitly documented. Tests that need cloud credentials must be marked as such:

# test_ephemeral_eks.sh
# REQUIRES: AWS credentials (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
# COST: ~$0.50 per run (creates and destroys an EKS cluster)
# DURATION: ~15 minutes

Tests that create cloud resources must clean up after themselves, using the same trap pattern described in the ephemeral clusters article:

cleanup() {
  echo "Cleaning up test resources..."
  terraform destroy -auto-approve -input=false 2>&1 | tail -5
}
trap cleanup EXIT

Quality Checklist#

Before submitting a template, verify each item on this checklist. Reviewers will check these same items.

Functionality#

  • Template works on all stated platforms (check the Platform Support table in README)
  • Quick Start instructions are copy-pasteable and produce the described result
  • All tests pass from a clean state (no pre-existing state or cached data)
  • Template handles partial failures gracefully (cleanup runs even if validation fails)

Cleanup#

  • Template cleans up all resources it creates
  • Cloud templates include auto-destroy mechanisms (TTL tags, trap handlers, or both)
  • Manual cleanup instructions are documented for when automation fails
  • No orphaned resources after make clean runs

Documentation#

  • README follows the standard format (all required sections present)
  • Prerequisites list specific minimum versions, not just tool names
  • “What It Validates” and “What It Does Not Validate” sections are honest and specific
  • Cost estimates are provided for any template that creates billable resources

Cost (Cloud Templates Only)#

  • COST.md breaks down per-resource costs with hourly and per-run estimates
  • Maximum cost if cleanup fails is calculated and documented
  • Auto-destroy TTL is set to a reasonable default (4 hours or less)

Security#

  • No credentials are hardcoded; example files use placeholder values
  • Cloud resources are created with minimal permissions
  • IAM roles and security groups follow least-privilege

Code Quality#

  • Shell scripts pass shellcheck (shellcheck scripts/*.sh tests/*.sh)
  • Terraform passes terraform fmt -check and terraform validate
  • No TODO or FIXME comments in submitted code

Versioning#

Tool Version Pinning#

Templates must pin the versions of all tools they depend on. Unpinned versions cause silent breakage when a tool updates its behavior or output format.

Pin versions in three places:

  1. In the template itself. Dockerfiles use ARG for version variables. Terraform uses required_version and provider version constraints. Shell scripts check tool versions at startup.
ARG KUBECTL_VERSION=1.29.3
RUN curl -fsSL "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl" \
      -o /usr/local/bin/kubectl
terraform {
  required_version = ">= 1.5, < 2.0"
  required_providers {
    aws = { source = "hashicorp/aws", version = "~> 5.0" }
  }
}
  1. In .tool-versions for asdf users (terraform 1.7.5, kubectl 1.29.3, helm 3.14.3).

  2. In README prerequisites with minimum versions listed explicitly.

When to Update Versions#

Update tool versions when:

  • A new Kubernetes version is released and the template should support it (update kubectl, kubeconform schemas, kind node images)
  • A security vulnerability is found in a pinned version
  • A tool release adds features the template should use
  • A pinned version reaches end of life

Do not update versions just because a newer version exists. Version updates are a change that requires testing. Update, run all tests, and submit the update as its own change with a clear description of why the update was made.

Template Versioning#

Templates themselves follow semantic versioning in their README:

# Ephemeral EKS Cluster Template

**Version: 1.2.0**
  • Major (1.x.x to 2.x.x): Breaking changes to the interface (renamed variables, changed directory structure, removed features)
  • Minor (x.1.x to x.2.x): New features that do not break existing usage (new validation checks, additional platform support)
  • Patch (x.x.1 to x.x.2): Bug fixes and version bumps that do not change behavior

Submission Process#

Step 1: Check for Existing Templates#

Search the existing templates to verify that your template does not duplicate an existing one. If a similar template exists, consider contributing improvements to it rather than creating a new one.

Step 2: Create Your Template#

Follow the directory structure and required files described above. Write tests before or alongside the template implementation.

Step 3: Self-Review Against the Quality Checklist#

Run through every item in the quality checklist. Fix any issues before submission. The most common rejection reasons are: missing cleanup, missing negative tests, unpinned tool versions, and incomplete README sections.

Step 4: Run All Tests#

# From the template directory
make test

# Or directly
bash tests/test_*.sh

All tests must pass. If cloud tests are included, run those too and document the cost incurred.

Step 5: Run Linters#

# Shell scripts
shellcheck scripts/*.sh tests/*.sh

# Terraform
cd terraform/ && terraform fmt -check && terraform validate

# Dockerfiles (if hadolint is installed)
hadolint .devcontainer/Dockerfile

Step 6: Submit#

Submit the template through the Agent Zone content submission process. Include:

  • The full template directory
  • Test results (output of the test run)
  • Cost report if cloud resources were used during testing
  • A brief description of what validation gap this template fills

Review Criteria#

Reviewers evaluate submissions against these priorities, in order:

  1. Correctness – Does the template do what it claims? Do tests prove it?
  2. Cleanup – Does the template clean up after itself in all cases (success, failure, interruption)?
  3. Documentation – Can someone use this template from the README alone, without reading the implementation?
  4. Security – Does the template follow least-privilege? Are there hardcoded credentials or overly permissive configurations?
  5. Portability – Does it work on the stated platforms? Are there unnecessary platform-specific assumptions?

Templates that fail on criteria 1 or 2 are rejected. Templates that fail on criteria 3 through 5 receive feedback and can be resubmitted after addressing the issues.

Common Mistakes#

Assuming tool availability. Do not assume that jq, yq, kubeconform, or any tool is pre-installed. Either include it in the Dockerfile, check for it at the start of scripts with a clear error message, or list it explicitly in prerequisites.

Testing only the happy path. A validation template that passes valid input is only half-tested. It must also correctly reject invalid input. Include fixtures for every category of error the template claims to detect.

Forgetting cleanup on failure. The trap cleanup EXIT pattern is mandatory for any template that creates resources. Without it, a test failure leaves resources running and costs accumulating.

Hardcoding region or zone. Use variables with sensible defaults. A template hardcoded to us-east-1 is useless to someone in eu-west-1 who faces data residency requirements.

Skipping cost documentation. If a template creates a $0.10/hour resource and someone leaves it running for a month, that is $73. Document the cost so users can make informed decisions.