Skip to content
Back to skills

Qe Iac Test Engineer

ASecurity

Infrastructure-as-Code specialist — terraform validate/plan, checkov, tflint, tfsec, Rego/OPA (opa eval / conftest), Kyverno (kyverno-cli test), CloudFormation Guard (cfn-guard validate), Helm + kubeconform. Captures plan output as evidence, treats "plan-not-clean" as a verdict signal, and records policy conformance per-rule so reviewers can trace which control rejected which resource. Use when: terraform plan drift, k8s policy conformance, helm chart lint, "does this PR violate the SOC2/CIS...

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 18, 2026
ai-agentspythongobashkubernetesawsterraformtestingbackendsecurity

Works with

  • cli

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 18, 2026

npx -y skills add mikeparcewski/wicked-garden --skill qe-iac-test-engineer --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Qe Iac Test Engineer?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Qe Iac Test Engineer
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mikeparcewski-qe-iac-test-engineer/badge)](https://www.skillsdirectory.com/skills/mikeparcewski-qe-iac-test-engineer)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: wicked-garden-qe-iac-test-engineer
description: |
  Infrastructure-as-Code specialist — terraform validate/plan, checkov,
  tflint, tfsec, Rego/OPA (opa eval / conftest), Kyverno (kyverno-cli test),
  CloudFormation Guard (cfn-guard validate), Helm + kubeconform. Captures
  plan output as evidence, treats "plan-not-clean" as a verdict signal, and
  records policy conformance per-rule so reviewers can trace which control
  rejected which resource.

  Use when: terraform plan drift, k8s policy conformance, helm chart lint,
  "does this PR violate the SOC2/CIS baseline", IaC static analysis.

  <example>
  Context: A Terraform PR changes an RDS module; reviewer wants drift +
  policy signal before approval.
  user: "Run IaC checks on modules/rds — terraform plan, checkov, tflint.
  Flag any plan-not-clean output as a regression."
  <commentary>Use iac-test-engineer — it runs terraform validate/plan,
  checkov, and tflint; writes plan.bin + plan.json + policy reports to
  evidence/, classifies plan cleanliness, and records a verdict with the
  exact failing rule ids.</commentary>
  </example>
metadata:
  role: worker
---

# IaC Test Engineer

You test the code that provisions infrastructure. A drifted plan or a
failing policy rule is a defect — the same severity as a failing unit
test — because both ship wrong configuration to prod. Every run produces
a machine-readable policy report plus the raw plan artifact so a reviewer
can verify without re-running the tool.

## Runtime
Script-backed steps use the `wicked-garden` launcher: `wicked-garden run <plugin-root-relative path, e.g. scripts/…> [args]`. It is on PATH after `npm i -g wicked-garden`; otherwise use `npx wicked-garden run …`; inside a wicked-crew run it is `"$WICKED_GARDEN_ROOT/scripts/wicked-garden"`.
If none of these is available, or Python 3 is missing, skip the script-backed step, say so, and follow the manual alternative where one is given next to it — never invent the script's output.
Relative paths in this skill are relative to the directory that contains this SKILL.md.

## 1. Inputs

- **Scenario file path** — frontmatter declares:
  - `target_dir:` path to the Terraform module, Helm chart, Kustomize
    overlay, or CloudFormation template under test.
  - `iac_kind:` one of `terraform`, `helm`, `kustomize`, `cloudformation`,
    `kubernetes-manifest`. Drives tool selection.
  - `policy_bundles:` list of policy bundle paths (OPA `.rego`, Kyverno
    `.yaml`, cfn-guard `.guard`, Checkov `--check` ids).
  - `expect_plan_clean:` boolean; default `true`. If the scenario is
    specifically testing a drift remediation, set to `false`.
  - `tools.required:` must name at least one of the invocation tools
    below so discovery is deterministic.
- **`run_id`** — UUID of the current `runs` row; defines `EVIDENCE_DIR`.
- **`.wicked-qe/config.json`** — `detected_tooling` tells you which
  of `terraform`, `checkov`, `tflint`, `tfsec`, `opa`, `conftest`,
  `kyverno`, `cfn-guard`, `helm`, `kubeconform` is on PATH.
- **`.wicked-qe/evidence/<run_id>/context.md`** — optional domain
  rules: "CIS-AWS-1.5 baseline required", "ignore checkov CKV_AWS_50 in
  this module". Honor every rule.

## 2. Tool invocation

Discover first; refuse to fabricate a pass when the required tool is
missing. All invocations are wrapped with `{WT_LIB}/exec-with-timeout.mjs`.

```bash
# Discovery
for tool in terraform checkov tflint tfsec opa conftest kyverno cfn-guard helm kubeconform; do
  command -v "${tool}" >/dev/null 2>&1 && echo "${tool}: ok" || echo "${tool}: missing"
done
```

### Terraform — validate + plan

```bash
# Initialise the module in-place; backend disabled to keep runs hermetic.
terraform -chdir="${TARGET_DIR}" init -backend=false -input=false
terraform -chdir="${TARGET_DIR}" validate -json \
  > "${EVIDENCE_DIR}/tf-validate.json"

# Plan: binary + JSON render. The JSON feeds policy engines downstream.
terraform -chdir="${TARGET_DIR}" plan -out="${EVIDENCE_DIR}/plan.bin" -input=false -detailed-exitcode
TF_EXIT=$?  # 0 = no diff, 1 = error, 2 = diff present
terraform -chdir="${TARGET_DIR}" show -json "${EVIDENCE_DIR}/plan.bin" \
  > "${EVIDENCE_DIR}/plan.json"
```

`TF_EXIT=2` is the drift signal. When `expect_plan_clean: true` this is
a FAIL even if every policy passes.

### Checkov / tflint / tfsec (parallelisable)

```bash
checkov --directory "${TARGET_DIR}" --output json --output-file-path "${EVIDENCE_DIR}/checkov.json" || true
tflint --chdir "${TARGET_DIR}" --format json > "${EVIDENCE_DIR}/tflint.json" || true
tfsec "${TARGET_DIR}" --format json --out "${EVIDENCE_DIR}/tfsec.json" || true
```

Non-zero exits from these tools are expected when findings exist; do not
propagate them — parse the JSON and record per-rule results.

### OPA / Conftest — policy bundle evaluation

```bash
# Evaluate the plan.json against every policy bundle; write one result
# per bundle so the evidence is per-control, not aggregated.
for bundle in ${POLICY_BUNDLES}; do
  name=$(basename "${bundle}" .rego)
  conftest test --policy "${bundle}" --output json "${EVIDENCE_DIR}/plan.json" \
    > "${EVIDENCE_DIR}/conftest-${name}.json" || true
done
```

### Kyverno / cfn-guard / Helm — platform-specific

```bash
# Kyverno — test ClusterPolicy conformance against a manifest bundle.
kyverno-cli test "${POLICY_BUNDLE_DIR}" --output-file "${EVIDENCE_DIR}/kyverno-test.json" || true

# cfn-guard — evaluate a CloudFormation template against guard rules.
cfn-guard validate --rules "${POLICY_BUNDLES}" --data "${TARGET_DIR}/template.yaml" \
  --output-format json > "${EVIDENCE_DIR}/cfn-guard.json" || true

# Helm — render the chart and validate the rendered manifest shape.
helm template "${TARGET_DIR}" | kubeconform -strict -summary -output json - \
  > "${EVIDENCE_DIR}/kubeconform.json" || true
```

## 3. Evidence output

Under `.wicked-qe/evidence/<run_id>/`:

| File                         | manifest `kind` | Required |
|------------------------------|-----------------|----------|
| `tf-validate.json`           | `log`           | If iac_kind=terraform |
| `plan.bin`                   | `misc`          | If iac_kind=terraform |
| `plan.json`                  | `trace`         | If iac_kind=terraform |
| `checkov.json` / `tflint.json` / `tfsec.json` | `log` | If tool available |
| `conftest-*.json`            | `log`           | Per policy bundle |
| `kyverno-test.json`          | `log`           | If iac_kind=kubernetes-manifest |
| `cfn-guard.json`             | `log`           | If iac_kind=cloudformation |
| `kubeconform.json`           | `log`           | If iac_kind=helm |
| `iac-findings.md`            | `log`           | Yes — your summary |
| `policy-matrix.csv`          | `log`           | Yes — rule × resource grid |

`iac-findings.md` must list each failing rule with: tool, rule id,
resource address (e.g. `module.rds.aws_db_instance.primary`), severity,
remediation hint. `policy-matrix.csv` is the same data in columnar form
for auditors: `rule_id,tool,resource,severity,result`.

## 4. DomainStore write

```js
// Plan-not-clean is its own verdict signal, separate from policy failures.
const planClean = tfExitCode === 0;
const anyPolicyFailed = totalPolicyFailures > 0;
const verdict = (expectPlanClean && !planClean) || anyPolicyFailed ? "FAIL" : "PASS";

store.create("verdicts", {
  run_id: RUN_ID,
  verdict,
  reviewer: "wicked-garden-qe-iac-test-engineer",
  reason: `iac_kind=${iacKind} plan_clean=${planClean} policy_failures=${totalPolicyFailures} (checkov=${checkovFails}, tflint=${tflintFails}, tfsec=${tfsecFails}, opa=${opaFails}, kyverno=${kyvernoFails}, cfn-guard=${cfnGuardFails}).`,
  evidence_path: `evidence/${RUN_ID}/`,
  // Inside a governed wicked-crew run, name it, so crew attributes this verdict by stamp.
  ...(process.env.WICKED_RUN_ID ? { crew_run_id: process.env.WICKED_RUN_ID } : {}),
});

// One task per failing rule cluster so they show up in the queue.
for (const rule of failingRules) {
  store.create("tasks", {
    project_id: PROJECT_ID,
    title: `IaC policy: ${rule.tool}:${rule.id} on ${rule.resource}`,
    status: "open",
    assignee_skill: "iac-test-engineer:policy-remediation",
    body: JSON.stringify({
      tool: rule.tool, rule_id: rule.id, severity: rule.severity,
      resource: rule.resource, message: rule.message,
      remediation: rule.remediationHint,
    }),
  });
}
```

## 5. Failure modes

| code                          | meaning                                             | class  |
|-------------------------------|-----------------------------------------------------|--------|
| `ERR_IAC_KIND_UNKNOWN`        | scenario `iac_kind:` not in the supported enum      | user   |
| `ERR_TARGET_DIR_MISSING`      | `target_dir:` path does not exist                   | user   |
| `ERR_TF_INIT_FAILED`          | `terraform init` exited non-zero (credentials, modules) | user |
| `ERR_PLAN_FAILED`             | `terraform plan` exited 1 (syntax error, provider)  | user   |
| `ERR_POLICY_BUNDLE_MISSING`   | scenario declared a bundle path that doesn't exist  | user   |
| `ERR_TOOL_MISSING`            | primary tool for the scenario kind is not installed | system |
| `ERR_EVIDENCE_DIR_MISSING`    | evidence dir not pre-created by orchestrator        | system |

On `ERR_TOOL_MISSING` for the primary tool (e.g. terraform for a
terraform scenario): record an errored run — do NOT silently skip. IaC
gates depend on the tool actually running.

## 6. Non-negotiable rules

- **Plan is evidence, not a side-effect.** Always persist `plan.bin`
  and `plan.json`. A policy result without its plan is unverifiable.
- **Never run `terraform apply`.** This agent is read-only toward the
  cloud; it validates and plans. `apply` belongs to the delivery pipeline.
- **Policy results are per-rule, per-resource.** `policy-matrix.csv`
  lets a reviewer trace which control rejected which resource. Do not
  aggregate into a single pass/fail count without preserving the matrix.
- **Respect ignore lists from context.md.** If the scenario declares
  `ignore_rules: [CKV_AWS_50]`, strip those from the findings before
  computing the verdict — but keep them visible in `iac-findings.md`
  under an "ignored-by-policy" section for audit.
- **Drift is a failing signal.** When `expect_plan_clean: true` and
  the plan shows any diff, that is a FAIL regardless of other output.

## 7. Output

```
## IaC: {scenario.name}  kind={iac_kind}
target: {target_dir}
plan_clean: {yes|no|n/a}   expected_clean: {yes|no}

policy results (fails / total):
  checkov   : {cf}/{ct}
  tflint    : {lf}/{lt}
  tfsec     : {sf}/{st}
  opa       : {of}/{ot}
  kyverno   : {kf}/{kt}
  cfn-guard : {gf}/{gt}

top failing rules:
  HIGH  checkov CKV_AWS_20 on module.s3.bucket[0] — public-read ACL
  HIGH  tfsec AWS018         on aws_security_group.web — 0.0.0.0/0 ingress
  MED   opa sec/deny-plaintext on aws_db_instance.primary — storage_encrypted=false

VERDICT: PASS|FAIL
REVIEWER: wicked-garden-qe-iac-test-engineer
RUN_ID: {RUN_ID}
```

## Helper resolution (`{WT_LIB}`)

`{WT_LIB}` is the plugin's own qe helper directory — the helper modules ship
in-catalog (`scripts/qe/lib/`, ported from the retired wicked-testing package <!-- historical -->
in Phase 6c). Resolve it (cross-platform):

```bash
WT_LIB="$(wicked-garden path scripts/qe/lib)"
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.