Infrastructure Testing — Molecule, Test Kitchen, InSpec, Chainsaw

Infrastructure code needs testing like application code does. The tools here cover different layers: role testing, integration testing, compliance checking, and Kubernetes end-to-end testing.


Molecule — Ansible role testing

Molecule is the standard testing framework for Ansible roles and playbooks. It manages the full test lifecycle: spin up instances, apply the role, verify the result, tear everything down.

Stages:

molecule create    # spin up test instances (Docker, Podman, EC2, etc.)
molecule converge  # apply the role/playbook
molecule verify    # run assertions
molecule destroy   # clean up
molecule test      # full cycle in sequence

Drivers control where instances run — Docker or Podman for local development, EC2 or other cloud providers for closer-to-production testing.

Verifiers run assertions after converge. The default is Ansible itself (run a playbook of assertions), but Testinfra (pytest-based) and Goss are popular alternatives.

A minimal molecule/default/molecule.yml:

driver:
  name: docker

platforms:
  - name: instance
    image: ubuntu:22.04

provisioner:
  name: ansible

verifier:
  name: ansible

Wire into CI: molecule test runs the full cycle and exits non-zero on failure.


Test Kitchen — integration testing for infrastructure

Test Kitchen (kitchen.ci) is an integration testing framework originally built for Chef but now multi-platform. It creates instances, applies configuration, runs a verifier, and destroys.

Drivers: Docker, Vagrant, and cloud providers (EC2, GCP, Azure). Plugins also exist for Ansible (kitchen-ansible) and Terraform (kitchen-terraform).

Verifiers: InSpec (most common), Busser.

A kitchen.yml for a Chef cookbook:

driver:
  name: docker

provisioner:
  name: chef_zero

verifier:
  name: inspec

platforms:
  - name: ubuntu-22.04

suites:
  - name: default
    verifier:
      inspec_tests:
        - test/integration/default
kitchen list      # show instance state
kitchen converge  # apply provisioner
kitchen verify    # run verifier
kitchen test      # full cycle

Test Kitchen is less commonly adopted outside Chef shops, but the multi-platform support means it can be useful for testing across providers in one framework.


InSpec — compliance testing as code

InSpec (now Progress Chef InSpec) is a compliance testing framework. You write assertions about the state of a system — packages installed, ports listening, file permissions, user accounts — in a Ruby DSL. InSpec executes them locally, over SSH, against Docker containers, or against cloud APIs.

describe package('nginx') do
  it { should be_installed }
end

describe service('nginx') do
  it { should be_running }
  it { should be_enabled }
end

describe port(80) do
  it { should be_listening }
end

describe file('/etc/nginx/nginx.conf') do
  its('mode') { should cmp '0644' }
end

Profiles are the distributable unit — a collection of controls with metadata. The InSpec community maintains profiles for CIS benchmarks, DISA STIGs, and other compliance standards.

Where it fits: compliance auditing, security baselines, post-deploy verification. Wired into CI as a final gate or run on a schedule against production.

inspec exec path/to/profile --target ssh://user@host
inspec exec path/to/profile --target docker://container-id

Chainsaw — Kubernetes e2e testing

Chainsaw is a declarative end-to-end testing framework for Kubernetes. Originally from the Kyverno project, now standalone. Write test scenarios in YAML — apply manifests, assert on resource state, clean up — without writing Go or any test framework code.

Particularly useful for testing Kubernetes operators, controllers, and admission webhooks: the things that are hard to unit test because they depend on the Kubernetes API.

apiVersion: chainsaw.kyverno.io/v1alpha1
kind: Test
metadata:
  name: basic-deployment
spec:
  steps:
  - name: create deployment
    try:
    - apply:
        resource:
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: test-app
          spec:
            replicas: 2
            # ...
    - assert:
        resource:
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: test-app
          status:
            readyReplicas: 2
  - name: cleanup
    try:
    - delete:
        ref:
          apiVersion: apps/v1
          kind: Deployment
          name: test-app
chainsaw test ./tests/

vs Terratest for Kubernetes: Terratest requires Go code; Chainsaw is YAML. For testing Kubernetes resources and operators specifically, Chainsaw is simpler to write and maintain.


Terratest — Go-based infrastructure testing

Covered in the Terraform page. The short version: Go tests that deploy real infrastructure, run assertions via cloud SDKs, then tear it down. The most complete integration testing approach for Terraform modules — and the highest cost in setup and test execution time.


Choosing

ToolBest forLanguage
MoleculeAnsible role testingYAML + Python/Ansible
Test KitchenMulti-platform integration testingYAML + Ruby (InSpec)
InSpecCompliance assertions, security baselinesRuby DSL
ChainsawKubernetes operators and controllersYAML
TerratestTerraform module integration testingGo
Built with Hugo
Theme Stack designed by Jimmy