Agent Skills › akin-ozer/cc-devops-skills

akin-ozer/cc-devops-skills

GitHub

用于生成和脚手架化 Ansible 剧本、角色、任务、处理器、清单及配置文件。根据请求模式分类,收集必要输入并参考最佳实践与模板,输出生产就绪的代码或片段。不适用于纯验证或调试场景。

31 skills 262

Install All Skills

npx skills add akin-ozer/cc-devops-skills --all -g -y
More Options

List skills in collection

npx skills add akin-ozer/cc-devops-skills --list

Skills in Collection (31)

用于生成和脚手架化 Ansible 剧本、角色、任务、处理器、清单及配置文件。根据请求模式分类,收集必要输入并参考最佳实践与模板,输出生产就绪的代码或片段。不适用于纯验证或调试场景。
创建或生成 Ansible 内容 搭建 Ansible 项目结构 编写部署脚本
devops-skills-plugin/skills/ansible-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill ansible-generator -g -y
SKILL.md
Frontmatter
{
    "name": "ansible-generator",
    "description": "Generate, create, or scaffold Ansible playbooks, roles, tasks, handlers, inventory, vars."
}

Ansible Generator

Trigger Phrases

Use this skill when the request is to generate or scaffold Ansible content, for example:

  • "Create a playbook to deploy nginx with TLS."
  • "Generate an Ansible role for PostgreSQL backups."
  • "Write inventory files for prod and staging."
  • "Build reusable Ansible tasks for user provisioning."
  • "Initialize an Ansible project with ansible.cfg and requirements.yml."
  • "Give me a quick Ansible snippet to install Docker."

Do not use this skill as the primary workflow when the request is validation/debug-only (syntax errors, lint failures, Molecule/test failures). Use ansible-validator for those cases.

Deterministic Execution Flow

Run these stages in order. Do not skip a stage unless the Validation Exceptions Matrix explicitly allows it.

Stage 0: Classify Request Mode

Determine one mode first:

Mode Typical user intent Deliverable
full-generation "create/build/generate" a full playbook/role/inventory/project file set Complete file(s), production-ready
snippet-only "quick snippet/example" without full file context Focused task/play snippet
docs-only explanation, pattern comparison, or conceptual guidance only Explanatory content, optional examples

Stage 1: Collect Minimum Inputs

If details are missing, ask briefly. If the user does not provide them, proceed with safe defaults and state assumptions.

Resource type Required inputs Safe defaults if missing
Playbook target hosts, privilege (become), OS family, objective hosts: all, become: false, OS-agnostic modules
Role role name, primary service/package, supported OS role name from task domain, Debian + RedHat vars
Tasks file operation scope, required vars, execution context standalone reusable tasks with documented vars
Inventory environments, host groups, hostnames/IPs production/staging groups with placeholders
Project config collections/roles dependencies, lint policy minimal ansible.cfg, requirements.yml, .ansible-lint

Stage 2: Reference Extraction Checklist

Before drafting content, extract the following from local references/templates.

Required references

  • references/best-practices.md
    • Extract: FQCN requirements, idempotency rules, naming, security expectations.
  • references/module-patterns.md
    • Extract: correct module/parameter patterns for the exact task type.

Required templates by output type

  • Playbook: assets/templates/playbook/basic_playbook.yml
  • Role: assets/templates/role/ (including meta/argument_specs.yml and molecule/default/ for test scaffolding)
  • Inventory (INI): assets/templates/inventory/hosts
  • Inventory (YAML): assets/templates/inventory/hosts.yml
  • Project config: assets/templates/project/ansible.cfg, assets/templates/project/requirements.yml, assets/templates/project/.ansible-lint

Extraction checks

  • Identify every [PLACEHOLDER] that must be replaced.
  • Decide module selection priority (ansible.builtin.* first).
  • Capture at least one OS-appropriate package pattern when OS-specific behavior is needed.
  • Capture required prerequisites (collections, binaries, target assumptions).

Stage 3: Generate

Apply these generation standards:

  1. Use FQCN module names (ansible.builtin.* first choice).
  2. Keep tasks idempotent (state, creates/removes, changed_when when needed).
  3. Use descriptive verb-first task names.
  4. Use true/false booleans (not yes/no).
  5. Add no_log: true for sensitive values.
  6. Replace all placeholders before presenting output.
  7. Prefer ansible.builtin.dnf for RHEL 8+/CentOS 8+ (legacy yum only for older systems).

Stage 4: Validate (Default) or Apply Exception (Fallback)

Use the matrix below to keep validation deterministic and non-blocking.

Validation Exceptions Matrix

Scenario Default behavior Allowed fallback What to report
full-generation Run ansible-validator after generation and after each fix pass If validator/tools are unavailable, run manual static checks (YAML shape, placeholder scan, FQCN/idempotency/security review) and provide exact deferred validation commands Explicitly list which checks ran, which were skipped, and why
snippet-only Skip full validator by default; do inline sanity checks Run full validator only if user asks or snippet is promoted to full file State that validation was limited because output is snippet-only
docs-only No runtime validation None needed State that no executable artifact was generated
Offline environment (no web/docs access) Continue with local references and templates Skip external doc lookups; prefer builtin-module implementations; provide notes for later external verification State offline constraint and impacted checks/lookups

Resource Generation Guidance

Playbooks

  • Use assets/templates/playbook/basic_playbook.yml as structure.
  • Include: header comments, pre_tasks/tasks/post_tasks as needed, handlers, tags.
  • Add health checks when service deployment/configuration is involved.

Roles

  • Build from assets/templates/role/ structure.
  • Keep defaults in defaults/main.yml; keep higher-priority role vars in vars/main.yml.
  • Include OS-specific vars (vars/Debian.yml, vars/RedHat.yml) when relevant.
  • Add meta/argument_specs.yml for variable validation.
  • Include molecule/default/ scaffold (from assets/templates/role/molecule/) for production-ready roles.

Task Files

  • Keep scope narrow and reusable.
  • Document required input variables in comments.
  • Use conditionals for environment/OS-sensitive operations.

Inventory

  • Build logical host groups and optional group hierarchies.
  • Use variable layering intentionally: group_vars/all.yml -> group -> host.
  • Default to INI format (hosts) for simple topologies; use YAML format (hosts.yml) when the user requests it or when the hierarchy is complex.

Project Configuration

  • Provide baseline ansible.cfg, requirements.yml, and .ansible-lint.
  • Keep defaults practical and editable.

Custom Modules and Collections

When the request depends on non-builtin modules/collections:

  1. Identify collection + module and required version sensitivity.
  2. Check local references/module-patterns.md first.
  3. If still unresolved and network/tools are available, query Context7:
    • mcp__context7__resolve-library-id
    • mcp__context7__query-docs
  4. If Context7 is unavailable, use official Ansible docs / Ansible Galaxy pages.
  5. If external lookup is unavailable, provide a builtin fallback approach and state the limitation.

Always include collection installation guidance when collection modules are used.

Canonical Example Flows

Flow A: Full Generation (Playbook)

User prompt: "Create a playbook to deploy nginx with TLS on Ubuntu and RHEL."

  1. Classify as full-generation.
  2. Gather/confirm required inputs (hosts, cert paths, become, service name).
  3. Extract required references (best-practices.md, module-patterns.md) and playbook template.
  4. Generate complete playbook with OS conditionals (apt/dnf), handlers, validation for config templates.
  5. Run ansible-validator.
  6. Fix issues and rerun until checks pass (or apply matrix fallback if tooling unavailable).
  7. Present output with validation summary, usage command, and prerequisites.

Flow B: Quick Snippet (Task Block)

User prompt: "Give me a snippet to create a user and SSH key."

  1. Classify as snippet-only.
  2. Extract minimal module patterns for ansible.builtin.user and ansible.builtin.authorized_key.
  3. Generate concise snippet with FQCN, idempotency, and variable placeholders.
  4. Perform inline sanity checks (YAML shape, FQCN, obvious idempotency/security).
  5. Present snippet and note that full validator run was skipped due to snippet-only mode.

Output Requirements

For generated executable artifacts, use this response structure:

## Generated [Resource Type]: [Name]

**Validation Status:** [Passed / Partially validated / Skipped with reason]
- YAML syntax: [status]
- Ansible syntax: [status]
- Lint: [status]

**Summary:**
- [What was generated]
- [Key implementation choices]

**Assumptions:**
- [Defaults or inferred values]

**Usage:**
```bash
[Exact command(s)]

Prerequisites:

  • [Collections, binaries, environment needs]

## Done Criteria

This skill execution is complete only when all applicable items are true:

- Trigger decision is explicit (`full-generation`, `snippet-only`, or `docs-only`).
- Required references/templates were consulted for the selected artifact type.
- Generated output has no unresolved placeholders.
- Validation followed default behavior or a documented exception from the matrix.
- Any skipped checks include a concrete reason and deferred command(s).
- Final output includes summary, assumptions, usage, and prerequisites.
用于验证、检查、审计和调试Ansible代码的自动化技能。支持语法校验、静态分析、Molecule测试及安全检查,具备工具缺失时的自动回退机制,确保代码质量与合规性。
验证Playbook或Role 修复ansible-lint报错 执行Dry-Run测试 排查模块未找到错误 安全漏洞扫描
devops-skills-plugin/skills/ansible-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill ansible-validator -g -y
SKILL.md
Frontmatter
{
    "name": "ansible-validator",
    "description": "Validate, lint, audit, or debug Ansible playbooks, roles, inventories, FQCN, tasks."
}

Ansible Validator

Overview

Comprehensive toolkit for validating, linting, and testing Ansible playbooks, roles, and collections. This skill provides automated workflows for ensuring Ansible code quality, syntax validation, dry-run testing with check mode and molecule, and intelligent documentation lookup for custom modules and collections with version awareness.

Default behavior: When validating any Ansible role with a molecule/ directory, attempt Molecule automatically using bash scripts/test_role.sh <role-path>. If Molecule cannot run due to environment/runtime limits, mark Molecule as BLOCKED, report why, and continue all non-Molecule validation steps.

Trigger Guidance

Use this skill when the request is about validating or debugging existing Ansible code, not generating new code.

Common trigger phrases:

  • "validate this playbook"
  • "lint this role"
  • "why is ansible-lint failing"
  • "run check mode safely"
  • "test this role with molecule"
  • "find security issues in these Ansible files"
  • "module not found in this collection"

When to Use This Skill

Apply this skill when encountering any of these scenarios:

  • Working with Ansible files (.yml, .yaml playbooks, roles, inventories, vars)
  • Validating Ansible playbook syntax and structure
  • Linting and formatting Ansible code
  • Performing dry-run testing with ansible-playbook --check
  • Testing roles and playbooks with Molecule
  • Debugging Ansible errors or misconfigurations
  • Understanding custom Ansible modules, collections, or roles
  • Ensuring infrastructure-as-code best practices
  • Security validation of Ansible playbooks
  • Version compatibility checks for collections and modules

Preflight (Run First)

Run preflight before validation to avoid dead ends:

bash scripts/setup_tools.sh

Command path assumption: run commands from this skill root (devops-skills-plugin/skills/ansible-validator) or use absolute paths.

Preflight requirements:

  • Baseline validation: ansible, ansible-playbook, ansible-lint (plus yamllint recommended)
  • Molecule execution: molecule plus an available runtime (docker or podman)
  • Security scanning: checkov (wrapper can bootstrap if missing)

Deterministic fallback rules:

  • If baseline tools are missing but Python + pip are available, wrapper scripts bootstrap temporary environments automatically.
  • If wrapper bootstrap fails (offline index, pip failure, missing Python), run direct commands for available tools, mark missing stages as BLOCKED, and continue.
  • If Molecule runtime is unavailable (Docker/Podman missing or daemon not running), skip Molecule execution, mark as BLOCKED, and continue remaining stages.

Wrapper vs Direct Command Routing

Use wrappers by default for consistent behavior and fallback handling.

Validation scenario Default command Use direct command when Fallback if command cannot run
Playbook syntax/lint bash scripts/validate_playbook.sh <playbook.yml> User asks for a single focused check only (ansible-playbook --syntax-check, ansible-lint, or yamllint) Run any available direct checks and report skipped checks as BLOCKED
Role structural validation bash scripts/validate_role.sh <role-dir> User asks only for specific sub-checks (for example, structure only) Run structure/YAML checks that are possible and report missing stages
Role Molecule execution bash scripts/test_role.sh <role-dir> [scenario] User explicitly asks for manual stage-by-stage Molecule commands Mark Molecule BLOCKED with reason and continue non-Molecule role checks
Security scanning bash scripts/validate_playbook_security.sh <path> or bash scripts/validate_role_security.sh <path> plus bash scripts/scan_secrets.sh <path> User requests raw Checkov output formatting or custom flags Run whichever scanner is available; if one is missing, run the other and report coverage gap
Module/collection discovery bash scripts/extract_ansible_info_wrapper.sh <path> Python environment is already known-good and user wants direct parser output If extraction fails, manually inspect requirements.yml/galaxy.yml and continue with best-effort lookup

Validation Workflow

Follow this deterministic workflow and never stop at a missing dependency:

0. Preflight
   ├─> Run: bash scripts/setup_tools.sh
   ├─> Record tool/runtime readiness
   └─> Continue even when optional tools are missing

1. Identify scope
   ├─> Single playbook validation
   ├─> Role validation
   ├─> Collection validation
   └─> Multi-playbook/inventory validation

2. Syntax Validation
   ├─> Run ansible-playbook --syntax-check
   ├─> Run yamllint for YAML syntax
   └─> Report as PASS/FAIL/BLOCKED

3. Lint and Best Practices
   ├─> Run ansible-lint (comprehensive linting)
   ├─> Check for deprecated modules (see references/module_alternatives.md)
   ├─> **DETECT NON-FQCN MODULE USAGE** (apt vs ansible.builtin.apt)
   │   └─> Run bash scripts/check_fqcn.sh to identify short module names
   │   └─> Recommend FQCN alternatives from references/module_alternatives.md
   ├─> Verify role structure
   └─> Report linting issues

4. Dry-Run Testing (check mode)
   ├─> Run ansible-playbook --check (if inventory available)
   ├─> Analyze what would change
   └─> Report potential issues

5. Molecule Testing (for roles with molecule/) - AUTOMATIC ATTEMPT
   ├─> Check if molecule/ directory exists in role
   ├─> If present, run: bash scripts/test_role.sh <role-path> [scenario]
   ├─> If script exits 2, mark Molecule as BLOCKED (environment/runtime issue)
   ├─> If script exits 1, mark Molecule as FAIL (role/test issue)
   └─> Continue remaining validation regardless of Molecule outcome

6. Custom Module/Collection Analysis (if detected)
   ├─> Extract module/collection information
   ├─> Identify versions
   ├─> Lookup documentation (Context7 first, then web.search_query fallback)
   └─> Provide version-specific guidance

7. Security and Best Practices Review - DUAL SCANNING DEFAULT
   ├─> Run bash scripts/validate_playbook_security.sh or validate_role_security.sh (Checkov)
   ├─> Run bash scripts/scan_secrets.sh for hardcoded secret detection
   │   └─> This catches secrets Checkov may miss (passwords, API keys, tokens)
   ├─> If one scanner is unavailable, run the other and report reduced coverage
   ├─> Validate privilege escalation
   ├─> Review file permissions
   └─> Identify common anti-patterns

8. Reference Routing
   ├─> Map each error/warning class to the matching reference file
   ├─> Extract concrete remediation from references (not file-name-only mention)
   └─> Include source section + fix guidance in final report

9. Final Report (required format)
   ├─> Summary counts: PASS / FAIL / BLOCKED / SKIPPED
   ├─> Findings grouped by severity
   ├─> Tool/runtime blockers with exact command that failed
   └─> Next actions to reach full validation coverage

Status contract: BLOCKED means validation could not run due to environment/runtime constraints; FAIL means the Ansible code or tests failed.

Error-Class Reference Routing

When issues are detected, consult the mapped reference and include a specific remediation excerpt in the report.

Error class Typical detector Required reference Required action
YAML parse/format errors yamllint, ansible-playbook --syntax-check references/common_errors.md (Syntax Errors) Quote the matching syntax fix pattern and apply corrected YAML structure
Module/action resolution errors ansible-playbook, ansible-lint references/common_errors.md (Module/Collection Errors) Provide install/version fix commands (ansible-galaxy collection install ...)
Deprecated or non-FQCN module usage ansible-lint, bash scripts/check_fqcn.sh references/module_alternatives.md Provide exact FQCN/module replacement per finding
Template/variable errors ansible-playbook, check mode references/common_errors.md (Template/Variable Errors), references/best_practices.md (Variable Management) Recommend default(), required(), or type conversion fixes
Connection/inventory/privilege errors ansible-playbook --check, runtime output references/common_errors.md (Connection, Inventory, Privilege sections) Provide corrected inventory/auth/become configuration
Security policy failures (CKV_*) validate_*_security.sh / Checkov references/security_checklist.md Map failed policy to a secure task rewrite
Hardcoded secrets bash scripts/scan_secrets.sh references/security_checklist.md (Secrets Management) Replace with Vault/env/external secret manager approach
Role structure/idempotency warnings validate_role.sh, Molecule idempotence references/best_practices.md Provide role layout or idempotency remediation steps

External documentation lookup trigger:

  • If the issue involves a custom/private collection or unknown module parameters not covered locally, run module discovery + documentation lookup (see section 7).

Core Capabilities

1. YAML Syntax Validation

Purpose: Ensure YAML files are syntactically correct before Ansible parsing.

Tools:

  • yamllint - YAML linter for syntax and formatting
  • ansible-playbook --syntax-check - Ansible-specific syntax validation

Workflow:

# Check YAML syntax with yamllint
yamllint playbook.yml

# Or for entire directory
yamllint -c .yamllint .

# Check Ansible playbook syntax
ansible-playbook playbook.yml --syntax-check

Common Issues Detected:

  • Indentation errors
  • Invalid YAML syntax
  • Duplicate keys
  • Trailing whitespace
  • Line length violations
  • Missing colons or quotes

Best Practices:

  • Always run yamllint before ansible-lint
  • Use 2-space indentation consistently
  • Configure yamllint rules in .yamllint
  • Fix YAML syntax errors first, then Ansible-specific issues

2. Ansible Lint

Purpose: Enforce Ansible best practices and catch common errors.

Workflow:

# Lint a single playbook
ansible-lint playbook.yml

# Lint all playbooks in directory
ansible-lint .

# Lint with specific rules
ansible-lint -t yaml,syntax playbook.yml

# Skip specific rules
ansible-lint -x yaml[line-length] playbook.yml

# Output parseable format
ansible-lint -f pep8 playbook.yml

# Show rule details
ansible-lint -L

Common Issues Detected:

  • Deprecated modules or syntax
  • Missing task names
  • Improper use of command vs shell
  • Unquoted template expressions
  • Hard-coded values that should be variables
  • Missing become directives
  • Inefficient task patterns
  • Jinja2 template errors
  • Incorrect variable usage
  • Role dependencies issues

Severity Levels:

  • Error: Must fix - will cause failures
  • Warning: Should fix - potential issues
  • Info: Consider fixing - best practice violations

Auto-fix approach:

  • ansible-lint supports --fix for auto-fixable issues
  • Always review changes before applying
  • Some issues require manual intervention

3. Security Scanning (Checkov)

Purpose: Identify security vulnerabilities and compliance violations in Ansible code using Checkov, a static code analysis tool for infrastructure-as-code.

What Checkov Provides Beyond ansible-lint:

While ansible-lint focuses on code quality and best practices, Checkov specifically targets security policies and compliance:

  • SSL/TLS Security: Certificate validation enforcement
  • HTTPS Enforcement: Ensures secure protocols for downloads
  • Package Security: GPG signature verification for packages
  • Cloud Security: AWS, Azure, GCP misconfiguration detection
  • Compliance Frameworks: Maps to security standards
  • Network Security: Firewall and network policy validation

Workflow:

# Scan playbook for security issues
bash scripts/validate_playbook_security.sh playbook.yml

# Scan entire directory
bash scripts/validate_playbook_security.sh /path/to/playbooks/

# Scan role for security issues
bash scripts/validate_role_security.sh roles/webserver/

# Direct checkov usage
checkov -d . --framework ansible

# Scan with specific output format
checkov -d . --framework ansible --output json

# Scan and skip specific checks
checkov -d . --framework ansible --skip-check CKV_ANSIBLE_1

Common Security Issues Detected:

Certificate Validation:

  • CKV_ANSIBLE_1: URI module disabling certificate validation
  • CKV_ANSIBLE_2: get_url disabling certificate validation
  • CKV_ANSIBLE_3: yum disabling certificate validation
  • CKV_ANSIBLE_4: yum disabling SSL verification

HTTPS Enforcement:

  • CKV2_ANSIBLE_1: URI module using HTTP instead of HTTPS
  • CKV2_ANSIBLE_2: get_url using HTTP instead of HTTPS

Package Security:

  • CKV_ANSIBLE_5: apt installing packages without GPG signature
  • CKV_ANSIBLE_6: apt using force parameter bypassing signatures
  • CKV2_ANSIBLE_4:* dnf installing packages without GPG signature
  • CKV2_ANSIBLE_5: dnf disabling SSL verification
  • CKV2_ANSIBLE_6: dnf disabling certificate validation

Error Handling:

  • CKV2_ANSIBLE_3: Block missing error handling

Cloud Security (when managing cloud resources):

  • CKV_AWS_88: EC2 instances with public IPs
  • CKV_AWS_135: EC2 instances without EBS optimization

Example Violation:

# BAD - Disables certificate validation
- name: Download file
  get_url:
    url: https://example.com/file.tar.gz
    dest: /tmp/file.tar.gz
    validate_certs: false  # Security issue!

# GOOD - Certificate validation enabled
- name: Download file
  get_url:
    url: https://example.com/file.tar.gz
    dest: /tmp/file.tar.gz
    validate_certs: true  # Or omit (true by default)

Integration with Validation Workflow:

Checkov complements ansible-lint:

  1. ansible-lint catches code quality issues, deprecated modules, best practices
  2. Checkov catches security vulnerabilities, compliance violations, cryptographic issues

Best Practice: Run both tools for comprehensive validation:

# Complete validation workflow
bash scripts/validate_playbook.sh playbook.yml         # Syntax + Lint
bash scripts/validate_playbook_security.sh playbook.yml  # Security

Output Format:

Checkov provides clear security scan results:

Security Scan Results:
  Passed:  15 checks
  Failed:  2 checks
  Skipped: 0 checks

Failed Checks:
  Check: CKV_ANSIBLE_2 - "Ensure that certificate validation isn't disabled with get_url"
    FAILED for resource: tasks/main.yml:download_file
    File: /roles/webserver/tasks/main.yml:10-15

Remediation Resources:

Installation:

Checkov is automatically installed in a temporary environment if not available system-wide. For permanent installation:

pip3 install checkov

When to Use:

  • Before deploying to production
  • In CI/CD pipelines for automated security checks
  • When working with sensitive infrastructure
  • For compliance audits and security reviews
  • When downloading files or installing packages
  • When managing cloud resources with Ansible

4. Playbook Syntax Check

Purpose: Validate playbook syntax without executing tasks.

Workflow:

# Basic syntax check
ansible-playbook playbook.yml --syntax-check

# Syntax check with inventory
ansible-playbook -i inventory playbook.yml --syntax-check

# Syntax check with extra vars
ansible-playbook playbook.yml --syntax-check -e @vars.yml

# Check all playbooks
for file in *.yml; do
  ansible-playbook "$file" --syntax-check
done

Validation Checks:

  • YAML parsing
  • Playbook structure
  • Task definitions
  • Variable references
  • Module parameter syntax
  • Jinja2 template syntax
  • Include/import statements

Error Handling:

  • Parse error messages for specific issues
  • Check for typos in module names
  • Verify variable definitions
  • Ensure proper indentation
  • Check file paths for includes/imports

5. Dry-Run Testing (Check Mode)

Purpose: Preview changes that would be made without actually applying them.

Workflow:

# Run in check mode (dry-run)
ansible-playbook -i inventory playbook.yml --check

# Check mode with diff
ansible-playbook -i inventory playbook.yml --check --diff

# Check mode with verbose output
ansible-playbook -i inventory playbook.yml --check -v

# Check mode for specific hosts
ansible-playbook -i inventory playbook.yml --check --limit webservers

# Check mode with tags
ansible-playbook -i inventory playbook.yml --check --tags deploy

# Step through tasks
ansible-playbook -i inventory playbook.yml --check --step

Check Mode Analysis:

When reviewing check mode output, focus on:

  1. Task Changes:

    • ok: No changes needed
    • changed: Would make changes
    • failed: Would fail (check for check_mode support)
    • skipped: Conditional skip
  2. Diff Output:

    • Shows exact changes to files
    • Helps identify unintended modifications
    • Useful for reviewing template changes
  3. Handlers:

    • Which handlers would be notified
    • Service restarts that would occur
    • Potential downtime
  4. Failed Tasks:

    • Some modules don't support check mode
    • May need check_mode: no override
    • Identify tasks that would fail

Limitations:

  • Not all modules support check mode
  • Some tasks depend on previous changes
  • May not accurately reflect all changes
  • Stateful operations may show unexpected results

Safety Considerations:

  • Always run check mode before real execution
  • Review diff output carefully
  • Test in non-production first
  • Validate changes make sense
  • Check for unintended side effects

6. Molecule Testing

Purpose: Test Ansible roles in isolated environments with multiple scenarios.

Automatic attempt policy: When validating any Ansible role with a molecule/ directory, automatically attempt Molecule tests using bash scripts/test_role.sh <role-path> [scenario].

When to Use:

  • Automatically triggered when validating roles with molecule/ directory
  • Testing roles before deployment
  • Validating role compatibility across different OS versions
  • Integration testing for complex roles
  • CI/CD pipeline validation

Workflow:

# Initialize molecule for a role
cd roles/myrole
molecule init scenario --driver-name docker

# List scenarios
molecule list

# Run full test sequence
molecule test

# Individual test stages
molecule create      # Create test instances
molecule converge    # Run Ansible against instances
molecule verify      # Run verification tests
molecule destroy     # Destroy test instances

# Test with specific scenario
molecule test -s alternative

# Debug mode
molecule --debug test

# Keep instances for debugging
molecule converge
molecule login       # SSH into test instance

Test Sequence:

  1. dependency - Install role dependencies
  2. lint - Run yamllint and ansible-lint
  3. cleanup - Clean up before testing
  4. destroy - Destroy existing instances
  5. syntax - Run syntax check
  6. create - Create test instances
  7. prepare - Prepare instances (install requirements)
  8. converge - Run the role
  9. idempotence - Run again, verify no changes
  10. side_effect - Optional side effect playbook
  11. verify - Run verification tests (Testinfra, etc.)
  12. cleanup - Final cleanup
  13. destroy - Destroy test instances

Molecule Configuration:

Check molecule/default/molecule.yml:

dependency:
  name: galaxy
driver:
  name: docker
platforms:
  - name: instance
    image: ubuntu:22.04
provisioner:
  name: ansible
verifier:
  name: ansible

Verification Tests:

Molecule supports multiple verifiers:

  • Ansible (built-in): Use Ansible tasks to verify
  • Testinfra: Python-based infrastructure tests
  • Goss: YAML-based server validation

Example Ansible verifier (molecule/default/verify.yml):

---
- name: Verify
  hosts: all
  tasks:
    - name: Check service is running
      service:
        name: nginx
        state: started
      check_mode: true
      register: result
      failed_when: result.changed

Common Molecule Errors:

  • Driver not installed (docker, podman, vagrant)
  • Missing Python dependencies
  • Platform image not available
  • Network connectivity issues
  • Insufficient permissions for driver

Molecule Skip/Fallback Policy (Required):

  • If molecule/ does not exist: mark Molecule as SKIPPED and continue.
  • If test_role.sh exits 2: mark Molecule as BLOCKED (missing/unavailable runtime dependency) and continue.
  • If test_role.sh exits 1: mark Molecule as FAIL (role/test issue) and continue.
  • Never stop the full validation report because Molecule is blocked.

Use this reporting language for blocked Molecule runs:

Molecule Status: BLOCKED
Reason: <missing dependency/runtime and failing command>
Fallback Applied: Completed syntax, lint, check-mode, and security validation without Molecule runtime tests.
Next Action: <install/start dependency>; rerun `bash scripts/test_role.sh <role-path> [scenario]`

7. Custom Module and Collection Documentation Lookup

Purpose: Automatically discover and retrieve version-specific documentation for custom modules and collections using web search and Context7 MCP.

When to Trigger:

  • Encountering unfamiliar module usage
  • Working with custom/private collections
  • Debugging module-specific errors
  • Understanding new module parameters
  • Checking version compatibility
  • Deprecated module alternatives

Detection Workflow:

  1. Extract Module Information:

    • Use scripts/extract_ansible_info_wrapper.sh to parse playbooks and roles
    • Identify module usage and collections
    • Extract version constraints from requirements.yml
  2. Extract Collection Information:

    • Identify collection namespaces (e.g., community.general, ansible.posix)
    • Determine collection versions from requirements.yml or galaxy.yml
    • Detect custom/private vs. public collections

Documentation Lookup Strategy:

Use this deterministic lookup order:

  1. For public collections/modules:
    • Resolve library: mcp__context7__resolve-library-id
    • Query docs: mcp__context7__query-docs
  2. If Context7 has no suitable result:
    • Use web search via web.search_query with versioned queries
    • Prioritize official docs (docs.ansible.com, galaxy.ansible.com, vendor docs)
  3. For custom/private modules:
    • Prefer in-repo docs (README, module docs, role docs) first
    • Then use targeted web search with collection/module/version terms
  4. Always report source + version context used in final guidance

Search Query Templates:

# For custom modules
"[module-name] ansible module version [version] documentation"
"[module-name] ansible [module-type] example"
"ansible [collection-name].[module-name] parameters"

# For custom collections
"ansible collection [collection-name] version [version]"
"[collection-namespace].[collection-name] ansible documentation"
"ansible galaxy [collection-name] modules"

# For specific errors
"ansible [module-name] error: [error-message]"
"ansible [collection-name] module failed"

Example Workflow:

User working with: community.docker.docker_container version 3.0.0

1. Extract module info from playbook:
   tasks:
     - name: Start container
       community.docker.docker_container:
         name: myapp
         image: nginx:latest

2. Detect collection: community.docker

3. Search for documentation:
   - Try Context7: mcp__context7__resolve-library-id("ansible community.docker")
   - Fallback to web.search_query("ansible community.docker collection version 3.0 docker_container module documentation")

4. If official docs found:
   - Parse module parameters (required vs optional)
   - Identify return values
   - Find usage examples
   - Check version compatibility

5. Provide version-specific guidance to user

Version Compatibility Checks:

  • Compare required collection versions with available versions
  • Identify deprecated modules or parameters
  • Suggest upgrade paths if using outdated versions
  • Warn about breaking changes between versions
  • Check Ansible core version compatibility

Common Collection Sources:

  • Ansible Galaxy: Official community collections
  • Red Hat Automation Hub: Certified collections
  • GitHub: Custom/private collections
  • Internal repositories: Company-specific collections

8. Security and Best Practices Validation

Purpose: Identify security vulnerabilities and anti-patterns in Ansible playbooks.

Security Checks:

  1. Secrets Detection:

    # Check for hardcoded credentials
    grep -r "password:" *.yml
    grep -r "secret:" *.yml
    grep -r "api_key:" *.yml
    grep -r "token:" *.yml
    

    Remediation: Use Ansible Vault, environment variables, or external secret management

  2. Privilege Escalation:

    • Unnecessary use of become: yes
    • Missing become_user specification
    • Over-permissive sudo rules
    • Running entire playbooks as root
  3. File Permissions:

    • World-readable sensitive files
    • Missing mode parameter on file/template tasks
    • Incorrect ownership settings
    • Sensitive files not encrypted with vault
  4. Command Injection:

    • Unvalidated variables in shell/command modules
    • Missing quote filter for user input
    • Direct use of {{ var }} in command strings
  5. Network Security:

    • Unencrypted protocols (HTTP instead of HTTPS)
    • Missing SSL/TLS validation
    • Exposing services on 0.0.0.0
    • Insecure default ports

Best Practices:

  1. Playbook Organization:

    • Logical task separation
    • Reusable roles for common patterns
    • Clear directory structure
    • Meaningful playbook names
  2. Variable Management:

    • Vault encryption for sensitive data
    • Clear variable naming conventions
    • Variable precedence awareness
    • Group/host vars organization
    • Default values using default() filter
  3. Task Naming:

    • Descriptive task names
    • Consistent naming convention
    • Action-oriented descriptions
    • Include changed resource in name
  4. Idempotency:

    • All tasks should be idempotent
    • Use proper modules instead of command/shell
    • Check mode compatibility
    • Proper use of creates, removes for command tasks
    • Avoid changed_when: false unless necessary
  5. Error Handling:

    • Use failed_when for custom failure conditions
    • Implement block/rescue/always for error recovery
    • Set appropriate any_errors_fatal
    • Use ignore_errors sparingly
  6. Documentation:

    • README for each role
    • Variable documentation in defaults/main.yml
    • Role metadata in meta/main.yml
    • Playbook header comments

Reference Documentation:

For detailed security guidelines and best practices, refer to:

  • references/security_checklist.md - Common security vulnerabilities
  • references/best_practices.md - Ansible coding standards
  • references/common_errors.md - Common errors and solutions

Tool Prerequisites

Run this preflight before validation:

# Preferred one-shot preflight
bash scripts/setup_tools.sh

# Check Ansible installation
ansible --version
ansible-playbook --version

# Check ansible-lint installation
ansible-lint --version

# Check yamllint installation
yamllint --version

# Check molecule installation (for role testing with molecule/)
molecule --version

# Check container runtime for Molecule
docker --version
docker info
# or
podman --version
podman info

# Install missing tools (example for pip)
pip install ansible ansible-lint yamllint ansible-compat

# Install molecule with docker driver
pip install molecule molecule-docker

# Install molecule with podman driver (alternative)
pip install molecule molecule-podman

Minimum Versions:

  • Ansible: >= 2.9 (recommend >= 2.12)
  • ansible-lint: >= 6.0.0
  • yamllint: >= 1.26.0
  • molecule: >= 3.4.0 (if testing roles)

Execution policy when tools are missing:

  • If ansible/ansible-lint are missing, wrappers (validate_playbook.sh, validate_role.sh) attempt temporary venv bootstrap.
  • If Molecule runtime (docker info or podman info) is unavailable, Molecule is BLOCKED and non-Molecule checks continue.
  • If checkov is missing, security wrappers bootstrap it when possible; otherwise run scan_secrets.sh and report reduced security coverage.

Optional Tools:

  • ansible-inventory - Inventory validation and graphing
  • ansible-doc - Module documentation lookup
  • jq - JSON parsing for structured output

Error Troubleshooting

Common Errors and Solutions

Error: Module Not Found

Solution: Install required collection with ansible-galaxy
Check collections/requirements.yml
Verify collection namespace and name

Error: Undefined Variable

Solution: Define variable in vars, defaults, or group_vars
Check variable precedence
Use default() filter for optional variables
Verify variable file is included

Error: Template Syntax Error

Solution: Check Jinja2 template syntax
Verify variable types match filters
Ensure proper quote escaping
Test template rendering separately

Error: Connection Failed

Solution: Verify inventory host accessibility
Check SSH configuration and keys
Verify ansible_host and ansible_port
Test with ansible -m ping

Error: Permission Denied

Solution: Add become: yes for privilege escalation
Verify sudo/su configuration
Check file permissions
Verify user has necessary privileges

Error: Deprecated Module

Solution: Check ansible-lint output for replacement
Consult module documentation for alternatives
Update to recommended module
Test functionality with new module

Resources

scripts/

setup_tools.sh - Preflight checker for Ansible validator dependencies. Verifies baseline tools (ansible, ansible-playbook, ansible-lint, yamllint) and Molecule runtime readiness (docker/podman) and provides installation guidance.

Usage:

bash scripts/setup_tools.sh

extract_ansible_info_wrapper.sh - Bash wrapper for extract_ansible_info.py that automatically handles PyYAML dependencies. Creates a temporary venv if PyYAML is not available in system Python.

Usage:

bash scripts/extract_ansible_info_wrapper.sh <path-to-playbook-or-role>

Output: JSON structure with modules, collections, and versions

extract_ansible_info.py - Python script (called by wrapper) to parse Ansible playbooks and roles to extract module usage, collection dependencies, and version information. The wrapper script handles dependency management automatically.

validate_playbook.sh - Comprehensive validation script that runs syntax check, yamllint, and ansible-lint on playbooks. Automatically installs ansible and ansible-lint in a temporary venv if not available on the system (prefers system versions when available).

Usage:

bash scripts/validate_playbook.sh <playbook.yml>

validate_playbook_security.sh - Security validation script that scans playbooks for security vulnerabilities using Checkov. Automatically installs checkov in a temporary venv if not available. Complements validate_playbook.sh by focusing on security-specific checks like SSL/TLS validation, HTTPS enforcement, and package signature verification.

Usage:

bash scripts/validate_playbook_security.sh <playbook.yml>
# Or scan entire directory
bash scripts/validate_playbook_security.sh /path/to/playbooks/

validate_role.sh - Comprehensive role validation script that checks role structure, YAML syntax, Ansible syntax, linting, and molecule configuration.

Usage:

bash scripts/validate_role.sh <role-directory>

Validates:

  • Role directory structure (required and recommended directories)
  • Presence of main.yml files in each directory
  • YAML syntax across all role files
  • Ansible syntax using a test playbook
  • Best practices with ansible-lint
  • Molecule test configuration

validate_role_security.sh - Security validation script for Ansible roles using Checkov. Scans entire role directory for security issues. Automatically installs checkov in a temporary venv if not available. Complements validate_role.sh with security-focused checks.

Usage:

bash scripts/validate_role_security.sh <role-directory>

test_role.sh - Wrapper script for Molecule testing with automatic dependency installation. If molecule is missing, it creates a temporary venv and installs dependencies. Returns exit code 2 for environment/runtime blockers (for example missing Docker/Podman runtime) and exit code 1 for role/test failures.

Usage:

bash scripts/test_role.sh <role-directory> [scenario]

scan_secrets.sh - Comprehensive secret scanner that uses grep-based pattern matching to detect hardcoded secrets in Ansible files. Complements Checkov security scanning by catching secrets that static analysis may miss, including passwords, API keys, tokens, AWS credentials, and private keys.

Usage:

bash scripts/scan_secrets.sh <playbook.yml|role-directory|directory>

Detects:

  • Hardcoded passwords and credentials
  • API keys and tokens
  • AWS access keys and secret keys
  • Database connection strings with embedded credentials
  • Private key content (RSA, OpenSSH, EC, DSA)

IMPORTANT: This script should ALWAYS be run alongside Checkov (validate_*_security.sh) for comprehensive security scanning. Checkov catches SSL/TLS and protocol issues; this script catches hardcoded secrets.

check_fqcn.sh - Scans Ansible files to identify modules using short names instead of Fully Qualified Collection Names (FQCN). Recommends migration to ansible.builtin.* or appropriate collection namespace for better clarity and future compatibility.

Usage:

bash scripts/check_fqcn.sh <playbook.yml|role-directory|directory>

Detects:

  • ansible.builtin modules (apt, yum, copy, file, template, service, etc.)
  • community.general modules (ufw, docker_container, timezone, etc.)
  • ansible.posix modules (synchronize, acl, firewalld, etc.)

Provides specific migration recommendations with FQCN alternatives.

validate_inventory.sh - Validates Ansible inventory files and directories. Checks YAML syntax, resolves host/group hierarchy, and flags common structural issues such as plaintext credentials and missing ansible_connection=local for localhost entries. Automatically installs ansible in a temporary venv if not available.

Usage:

bash scripts/validate_inventory.sh <inventory-file|inventory-directory>

Validation stages:

  1. YAML syntax check (yamllint) on all inventory YAML files
  2. Inventory parse — ansible-inventory --list to verify host/group resolution
  3. Host graph — ansible-inventory --graph to display group hierarchy
  4. Structural checks — plaintext passwords, localhost connection settings, group_vars/host_vars presence

references/

security_checklist.md - Comprehensive security validation checklist for Ansible playbooks covering secrets management, privilege escalation, file permissions, and command injection.

best_practices.md - Ansible coding standards and best practices for playbook organization, variable handling, task naming, idempotency, and documentation.

common_errors.md - Database of common Ansible errors with detailed solutions and prevention strategies.

module_alternatives.md - Guide for replacing deprecated modules with current alternatives.

assets/

.yamllint - Pre-configured yamllint rules for Ansible YAML files.

.ansible-lint - Pre-configured ansible-lint configuration with reasonable rule settings.

molecule.yml.template - Template molecule configuration for role testing.

Workflow Examples

Example 1: Validate a Single Playbook

User: "Check if this playbook.yml file is valid"

Steps:
1. Run preflight: `bash scripts/setup_tools.sh`
2. Run wrapper: `bash scripts/validate_playbook.sh playbook.yml`
3. If inventory is provided, run check mode: `ansible-playbook -i <inventory> playbook.yml --check --diff`
4. Run security wrappers:
   - `bash scripts/validate_playbook_security.sh playbook.yml`
   - `bash scripts/scan_secrets.sh playbook.yml`
5. If custom modules are detected, run docs lookup workflow (Context7 first, web fallback)
6. Report results with PASS/FAIL/BLOCKED/SKIPPED counts and remediation steps

Example 2: Validate an Ansible Role

User: "Validate my ansible role in ./roles/webserver/"

Steps:
1. Run preflight: `bash scripts/setup_tools.sh`
2. Run role wrapper: `bash scripts/validate_role.sh ./roles/webserver/`
3. This checks:
   - Role directory structure (tasks/, defaults/, handlers/, meta/, etc.)
   - Required main.yml files
   - YAML syntax with yamllint
   - Ansible syntax with ansible-playbook
   - Best practices with ansible-lint
   - Molecule configuration (if present)
4. If `molecule/` exists, attempt Molecule automatically:
   - `bash scripts/test_role.sh ./roles/webserver/`
   - Exit `2`: report `Molecule Status: BLOCKED` with reason, continue remaining checks
   - Exit `1`: report `Molecule Status: FAIL` with debugging guidance
5. Run role security checks:
   - `bash scripts/validate_role_security.sh ./roles/webserver/`
   - `bash scripts/scan_secrets.sh ./roles/webserver/`
6. If custom modules detected, run documentation lookup workflow
7. Provide final report with severity, blockers, and rerun actions

Example 3: Dry-Run Testing for Production

User: "Run playbook in check mode for production servers"

Steps:
1. Verify inventory file exists
2. Run ansible-playbook --check --diff -i production
3. Analyze check mode output
4. Highlight tasks that would change
5. Review handler notifications
6. Flag any security concerns
7. Provide recommendation on safety of applying

Example 4: Understanding Custom Collection Module

User: "I'm using community.postgresql.postgresql_db version 2.3.0, what parameters are available?"

Steps:
1. Try Context7 MCP: `mcp__context7__resolve-library-id("ansible community.postgresql")`
2. If found, query docs with `mcp__context7__query-docs` for `postgresql_db`
3. If not found, use `web.search_query`: "ansible community.postgresql version 2.3.0 postgresql_db module documentation"
4. Extract module parameters (required vs optional)
5. Provide examples of common usage patterns
6. Note any version-specific considerations

Example 5: Testing Role with Molecule

User: "Test my nginx role with molecule"

Steps:
1. Check if molecule is configured in role
2. Run preflight (`bash scripts/setup_tools.sh`) and confirm Docker/Podman runtime availability
3. Run `bash scripts/test_role.sh <role-path> [scenario]`
4. If exit code is `2`, mark Molecule `BLOCKED`, report reason, and continue non-Molecule checks
5. If exit code is `1`, inspect converge/verify output and report role issues
6. Analyze idempotency, syntax, and verification outcomes
7. Suggest improvements and exact rerun command

Integration with Other Skills

This skill works well in combination with:

  • k8s-yaml-validator - When Ansible manages Kubernetes resources
  • terraform-validator - When Ansible and Terraform are used together
  • k8s-debug - For debugging infrastructure managed by Ansible

Notes

  • Run stages in order: preflight -> syntax -> lint/FQCN -> check mode -> Molecule (when applicable) -> security -> reference routing -> final report.
  • Use wrapper scripts as default execution path; switch to direct commands only when user asks or when wrapper bootstrapping is blocked.
  • Treat missing dependencies/runtime as BLOCKED (not silent skip), and continue with remaining stages.
  • For every detected issue class, include mapped reference guidance (common_errors, best_practices, module_alternatives, security_checklist).
  • Always include explicit rerun commands for failed or blocked stages.

Done Criteria

This skill execution is complete when:

  • Preflight status for required tools is reported (ansible, ansible-lint, and Molecule runtime status when role tests are in scope).
  • Validation produces deterministic stage outcomes using PASS, FAIL, BLOCKED, and SKIPPED.
  • Molecule never dead-ends the full validation flow; blocked runtime conditions are reported with fallback language.
  • Wrapper-vs-direct command choice is explicit and justified.
  • Reference lookups are tied to the actual error classes found, with concrete remediation guidance.
用于生成生产级Azure DevOps流水线YAML文件,支持CI/CD、Docker及Kubernetes等场景。通过分类请求模式、捕获输入参数并参考最佳实践,确保输出包含确定性步骤和明确完成标准的高质量配置。
用户要求创建或重构azure-pipelines.yml 构建多阶段Azure DevOps流水线 生成可复用的Azure流水线模板 将现有CI流程转换为Azure Pipelines
devops-skills-plugin/skills/azure-pipelines-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill azure-pipelines-generator -g -y
SKILL.md
Frontmatter
{
    "name": "azure-pipelines-generator",
    "description": "Generate\/create\/scaffold azure-pipelines.yml, stages, jobs, steps, or reusable templates."
}

Azure Pipelines Generator

Generate production-ready Azure DevOps pipeline YAML with deterministic steps, explicit fallbacks, and clear completion criteria.

Trigger Guidance

Use this skill when the user asks to generate or redesign Azure Pipelines YAML, for example:

  • "Create azure-pipelines.yml for my Node service."
  • "Build a multi-stage Azure DevOps pipeline with staging and production."
  • "Generate Azure pipeline templates for reuse across repos."
  • "Convert this CI flow to Azure Pipelines."

Do not use this skill for validation-only requests. For validation-only work, use azure-pipelines-validator.

Execution Model

Normative keywords:

  • MUST: required
  • SHOULD: default unless user asks otherwise
  • MAY: optional

Deterministic sequence:

  1. Classify request mode.
  2. Capture minimum required inputs.
  3. Load minimum references (progressive disclosure).
  4. Generate YAML using the quality checklist.
  5. Validate (validator skill, script fallback, or manual fallback).
  6. Return output in the required report format.

If a step cannot run due to environment limits, use the fallback in that step and continue.

1) Classify Request Mode

Choose exactly one primary mode:

  • Basic CI: build/test/lint for one stack.
  • Multi-stage CI/CD: build -> test -> deploy with environment tracking.
  • Docker: image build/push and optional deploy.
  • Kubernetes: image build/push plus Kubernetes deployment.
  • Language-specific: .NET, Node.js, Python, Go, Java focused.
  • Template-based: reusable templates plus thin root pipeline.
  • Snippet-only: partial YAML requested, not full pipeline.

Mode-to-example mapping:

  • Basic CI -> examples/basic-ci.yml
  • Multi-stage CI/CD -> examples/multi-stage-cicd.yml
  • .NET -> examples/dotnet-cicd.yml
  • Python -> examples/python-cicd.yml
  • Go -> examples/go-cicd.yml
  • Kubernetes -> examples/kubernetes-deploy.yml
  • Template-based -> examples/template-usage.yml + examples/templates/*.yml

2) Capture Required Inputs

Collect these before generation:

  • App stack and package manager
  • Build/test commands and report expectations
  • Deployment target (none, Azure service, Docker registry, Kubernetes)
  • Environment flow (dev/staging/prod) and branch gates
  • Service connections, variable groups, secret handling
  • Template requirement (yes/no)

Safe defaults when missing:

  • CI branches: main, develop
  • Production deploy branch: main only
  • Agent image: pinned image (for example ubuntu-22.04)
  • Deploy image tag: immutable ($(Build.BuildId)), never deploy latest

If key details are missing, state assumptions explicitly in final output.

3) Load References (Progressive Disclosure)

Read local references first.

Always read:

  • docs/yaml-schema.md
  • docs/best-practices.md

Read conditionally:

  • docs/tasks-reference.md when selecting tasks/inputs
  • docs/templates-guide.md only for template-based mode

Then read only the closest example(s) from the mode mapping above.

Fallback behavior for missing references:

  • Missing example: use nearest mode example and note substitution.
  • Missing doc section: continue with known conventions and mark uncertainty.
  • Snippet-only request: read only the minimum needed for safe output.

The final response MUST include:

  • References used
  • References skipped or missing
  • Impact

4) External Docs Escalation (Only When Needed)

Escalate beyond local docs only when:

  • required task info is not in local docs
  • task version compatibility is unclear
  • troubleshooting a task-specific failure

Use this order:

  1. Context7 (mcp__context7__resolve-library-id -> mcp__context7__query-docs)
  2. Official docs search (Microsoft Learn first)

If network/tools are unavailable, proceed with best-known local guidance and add a residual-risk note.

5) Pipeline Generation Checklist

Apply all items below unless user asks for a narrow snippet.

Security:

  • Never hardcode secrets.
  • Use service connections and variable groups/secrets.
  • Use immutable deploy image tags.

Versioning:

  • Pin vmImage to explicit version, not *-latest.
  • Pin task major versions (Task@N).
  • @0 is allowed only when that task uses major 0.

Reliability:

  • Use explicit dependsOn.
  • Add timeoutInMinutes for long-running jobs.
  • Use branch-gated deployment condition rules.
  • Use deployment jobs with environment for deploy stages.

Performance:

  • Use Cache@2 where it improves dependency install time.
  • Use shallow checkout when full history is not required.
  • Publish only required artifacts.

Testing/observability:

  • Run lint/tests in CI.
  • Publish test results with condition: succeededOrFailed().
  • Publish coverage when available.

Maintainability:

  • Add displayName for stages/jobs/key steps.
  • Use templates when logic repeats.
  • Add short comments only for non-obvious logic.

6) Validation Workflow

Default path (MUST for full pipeline generation):

  1. Generate or update YAML.
  2. Validate with azure-pipelines-validator.
  3. Fix findings.
  4. Re-run validation until no blocking issues remain.

Script fallback if validator skill is unavailable but local validator scripts exist:

bash devops-skills-plugin/skills/azure-pipelines-validator/scripts/validate_azure_pipelines.sh <pipeline-file>

Manual fallback when neither skill nor script can run:

  1. YAML structure/indentation sanity
  2. Hierarchy sanity (stages -> jobs -> steps)
  3. Task format sanity (Task@Major)
  4. Secret exposure scan (no plaintext credentials/tokens)
  5. Deployment safety scan (environment usage, immutable deploy tags)

When fallback is used, final response MUST include:

  • Validation status: Manual fallback
  • Checks performed
  • Residual risk

Validation MAY be skipped only for:

  • snippet-only YAML
  • documentation-only examples
  • explicit user request to skip validation

7) Output Contract

Final response MUST include:

  1. Pipeline YAML (or template set)
  2. Required setup:
    • service connections
    • variable groups/secrets
    • environments and approvals/checks
  3. Validation result:
    • validator status, script status, or manual fallback status
  4. Assumptions
  5. References used/skipped and impact
  6. Optional next improvements

8) Canonical Example Flows

Example A: Full multi-stage generation

  1. Select mode: Multi-stage CI/CD.
  2. Capture stack/deploy/service-connection inputs.
  3. Read docs/yaml-schema.md, docs/best-practices.md, and examples/multi-stage-cicd.yml.
  4. Add requested customizations (stages, branch gates, environments, tasks).
  5. Validate with azure-pipelines-validator; fix and re-run.
  6. Return YAML + setup + validation + assumptions + references.

Example B: Quick snippet generation

  1. Select mode: Snippet-only.
  2. Read only the minimum required reference section.
  3. Generate focused YAML snippet with safe defaults.
  4. Skip full validation and state Validation status: Skipped (snippet-only).
  5. Return snippet + assumptions + references.

9) Definition of Done

The execution is complete only when all applicable checks pass:

  • Request mode is explicitly chosen.
  • Assumptions are explicit for missing inputs.
  • YAML follows checklist requirements (security, versioning, reliability, performance, maintainability).
  • Validation path is documented (validator, script fallback, or manual fallback).
  • Final response follows the output contract, including references and impact.
用于验证 Azure Pipelines YAML 文件,检查语法、安全性和最佳实践。优先本地执行脚本,失败时参考文档。
Validate my azure-pipelines.yml. Why is this Azure pipeline YAML failing? Run a security scan on this Azure DevOps pipeline. Check this pipeline for best-practice issues.
devops-skills-plugin/skills/azure-pipelines-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill azure-pipelines-validator -g -y
SKILL.md
Frontmatter
{
    "name": "azure-pipelines-validator",
    "description": "Validate, lint, audit, or review azure-pipelines.yml — syntax, security, best practices."
}

Azure Pipelines Validator

Use this skill to validate Azure DevOps pipeline YAML (azure-pipelines.yml / azure-pipelines.yaml) with local scripts first, then escalate to docs only when local output is not enough.

Trigger Phrases

Use this skill when the user asks things like:

  • "Validate my azure-pipelines.yml."
  • "Why is this Azure pipeline YAML failing?"
  • "Run a security scan on this Azure DevOps pipeline."
  • "Check this pipeline for best-practice issues."
  • "Review this pipeline in CI before merge."

Do not use this skill for pipeline generation from scratch. Use azure-pipelines-generator for that.

Deterministic Path Setup (No Ambiguity)

Run from any directory using explicit absolute paths:

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
SKILL_DIR="$REPO_ROOT/devops-skills-plugin/skills/azure-pipelines-validator"
PIPELINE_FILE="$REPO_ROOT/azure-pipelines.yml"

If REPO_ROOT is empty, stop and ask for the repository root path. Do not guess paths.

Validate one file:

bash "$SKILL_DIR/scripts/validate_azure_pipelines.sh" "$PIPELINE_FILE"

Auto-detect from current directory (up to depth 3):

bash "$SKILL_DIR/scripts/validate_azure_pipelines.sh"

If auto-detect returns multiple files, rerun with one explicit file path.

Local-First Execution Model

  1. Preflight
  • Confirm bash and python3 are available.
  • Confirm target file exists.
  1. Run local validator
  • Default full pass:
bash "$SKILL_DIR/scripts/validate_azure_pipelines.sh" "$PIPELINE_FILE"
  • Syntax only:
bash "$SKILL_DIR/scripts/validate_azure_pipelines.sh" "$PIPELINE_FILE" --syntax-only
  • Best practices only:
bash "$SKILL_DIR/scripts/validate_azure_pipelines.sh" "$PIPELINE_FILE" --best-practices
  • Security only:
bash "$SKILL_DIR/scripts/validate_azure_pipelines.sh" "$PIPELINE_FILE" --security-only
  • Strict mode (warnings fail):
bash "$SKILL_DIR/scripts/validate_azure_pipelines.sh" "$PIPELINE_FILE" --strict
  1. Interpret exit behavior
  • 0: pass (or non-blocking checks only)
  • 1: validation failed (blocking issues)
  • 2: invalid invocation (missing/ambiguous file or bad args)
  1. Return findings in the report format below.

Expected Report Format (Severity Buckets)

Always return results in this structure:

Validation Report: <path>

Summary:
- Blocking: <count>        # Syntax errors + Security critical/high
- Warning: <count>         # Security medium/low + best-practice warnings
- Info: <count>            # Suggestions
- Skipped: <count>         # Explicitly name skipped checks

Findings:
- [Blocking][syntax][<rule-id>] line <n> - <message>
- [Blocking][security-high][<rule-id>] line <n> - <message>
- [Warning][security-medium][<rule-id>] line <n> - <message>
- [Warning][best-practice][<rule-id>] line <n> - <message>
- [Info][best-practice][<rule-id>] line <n> - <message>

Remediation:
- <short, concrete fix per finding>

Execution Notes:
- Commands run: <exact commands>
- Environment/fallback notes: <tool missing, skipped checks, offline constraints>

Escalation Policy (Docs Only When Needed)

Run local checks first. Escalate only when at least one condition is true:

  • Local finding depends on current upstream behavior (task versions, deprecations, new inputs).
  • User asks for "latest/current/recent" Azure Pipelines task or schema details.
  • Local scripts cannot determine validity for a specific task/resource syntax.

Escalation order:

  1. Context7 docs tooling first.
mcp__context7__resolve-library-id(...)
mcp__context7__query-docs(...)
  1. Official docs second (learn.microsoft.com / Microsoft Azure DevOps docs).
  2. General web search only if the first two are insufficient.

When escalating, cite the source URL and state what local check could not answer.

Fallback Behavior

Use this matrix when tools are unavailable:

  • Condition: yamllint unavailable.

  • Action: Continue with syntax/best-practice/security checks.

  • Report note: "YAML lint skipped because yamllint is unavailable."

  • Condition: python3 unavailable or venv/dependency setup fails.

  • Action: Mark scripted validation blocked; perform manual YAML review only if requested.

  • Report note: "Local scripted validation blocked by missing Python runtime/dependencies."

  • Condition: No network while dependencies/docs are needed.

  • Action: Run whatever local checks are still possible; defer doc/version verification.

  • Report note: "External verification deferred due offline environment."

  • Condition: Multiple auto-detected pipeline files.

  • Action: Do not pick arbitrarily; require explicit target file path.

  • Report note: "Validation paused until a single target file is specified."

Rule Buckets (What the Scripts Check)

Syntax examples:

  • yaml-syntax
  • yaml-invalid-root
  • invalid-hierarchy
  • task-invalid-format
  • pool-invalid
  • deployment-missing-strategy

Best-practice examples:

  • missing-displayname
  • task-version-zero
  • task-missing-version
  • pool-latest-image
  • missing-cache
  • missing-deployment-condition

Security examples:

  • hardcoded-password
  • hardcoded-secret
  • curl-pipe-shell
  • eval-command
  • insecure-ssl
  • container-latest-tag
  • variable-not-secret

Use script output rule IDs directly in the report.

References and Examples

  • Syntax reference: docs/azure-pipelines-reference.md
  • Example pipelines: examples/

Quick local test:

bash "$SKILL_DIR/scripts/validate_azure_pipelines.sh" "$SKILL_DIR/examples/basic-pipeline.yml"

Done Criteria

This skill execution is done when all conditions are true:

  • Trigger match is explicit and plain-language examples are provided near the top.
  • Validation command(s) were run with unambiguous paths.
  • Report uses severity buckets (Blocking, Warning, Info, Skipped).
  • Fallback behavior is explicitly reported for unavailable tools/environment constraints.
  • External docs were consulted only when local checks were insufficient.
生成生产级Bash脚本,涵盖需求捕获、模板或定制生成及验证。适用于创建自动化脚本、CLI工具、文本处理或运维辅助脚本。支持POSIX兼容性及错误处理配置,确保脚本安全高效。
创建或编写Bash/Shell脚本 将手动CLI步骤转换为自动化脚本 构建使用grep/awk/sed的文本处理脚本 创建运维助手、定时任务或CI工具脚本
devops-skills-plugin/skills/bash-script-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill bash-script-generator -g -y
SKILL.md
Frontmatter
{
    "name": "bash-script-generator",
    "description": "Create, generate, write, or scaffold bash\/shell scripts (.sh), automation, or CLI tools."
}

Bash Script Generator

Overview

Generate production-ready Bash scripts with clear requirements capture, deterministic generation flow, and validation-first iteration.

Trigger Phrases

Use this skill when the user asks to:

  • Create, generate, write, or build a Bash/shell script
  • Convert manual CLI steps into an automation script
  • Build a text-processing script using grep, awk, or sed
  • Create an operations helper script, cron script, or CI utility script

Do not use this skill for validating an existing script only. Use devops-skills:bash-script-validator for validation-only requests.

Execution Model

Follow stages in order. Do not skip a stage; use the documented fallback when blocked.

Stage 0: Preflight

  1. Confirm scope and target output path.
  2. Confirm shell target:
  • Default: bash
  • If portability is requested: POSIX sh
  1. Check capabilities and pick fallback path:
Capability Default Path Fallback Path
Requirement clarification AskUserQuestion tool Ask same questions in normal chat; mark unresolved items as assumptions
Script scaffold bash scripts/generate_script_template.sh ... Copy assets/templates/standard-template.sh manually or hand-craft minimal scaffold
Validation devops-skills:bash-script-validator Local checks: bash -n, shellcheck if available, sh -n for POSIX mode

If a fallback path is used, state it explicitly in the final summary.

Stage 1: Capture Requirements

Collect only what is needed to generate the script correctly:

  • Input source and format
  • Output destination and format
  • Error handling behavior (fail-fast/retry/continue)
  • Security constraints (sensitive data, privilege level)
  • Performance constraints (large files, parallelism)
  • Portability requirement (Bash-only vs POSIX)

Then create a Captured Requirements table with stable IDs.

## Captured Requirements

| Requirement ID | Description | Source | Implementation Plan |
|---|---|---|---|
| REQ-001 | Parse nginx logs from file input | User | `parse_args()` + `validate_file()` + `awk` parser |
| REQ-002 | Output top 10 errors | User | `analyze_errors()` + `sort | uniq -c | head -10` |
| REQ-003 | Handle large files efficiently | Assumption | Single-pass `awk`; avoid multi-pass loops |

Rules:

  • Every major design decision maps to at least one REQ-*.
  • Keep assumptions explicit and minimal.

Stage 2: Choose Generation Path

Use this deterministic decision tree:

Need multi-command architecture, unusual control flow, or strict non-template conventions?
├─ Yes -> Custom generation
└─ No
   Need standard CLI skeleton (usage/logging/arg parsing/cleanup)?
   ├─ Yes -> Template-first generation
   └─ No -> Custom generation

Template-first is the default for single-purpose CLI utilities.

Stage 3: Load Only Relevant References

Use progressive disclosure. Read only docs needed for the current request.

Need Reference
Tool choice (grep vs awk vs sed) docs/text-processing-guide.md
Script structure and argument patterns docs/script-patterns.md
Strict mode, shell differences, safety docs/bash-scripting-guide.md
Naming, organization, and quality baseline docs/generation-best-practices.md

Citation format (required):

  • [Ref: docs/<file>.md -> <section>]

Stage 4: Generate Script

Path A: Template-first (default)

  1. Generate scaffold:
bash scripts/generate_script_template.sh standard output-script.sh
  1. Replace placeholders and add business logic.
  2. Keep logging to stderr and data output to stdout unless requirements say otherwise.
  3. Add comments only where logic is non-obvious.

Path B: Custom generation

Build a script with at least:

  • Shebang and strict mode
  • usage()
  • parse_args()
  • Input validation and dependency checks
  • Main workflow function(s)
  • Predictable exit codes

Stage 5: Validate and Iterate

Default validation path:

  1. Invoke devops-skills:bash-script-validator
  2. Apply fixes
  3. Re-run validation
  4. Repeat until checks pass or blocker is identified

Fallback validation path (when validator skill is unavailable):

# Deterministic local gate for this skill:
bash scripts/run_ci_checks.sh --skip-shellcheck

# CI gate (shellcheck required):
bash scripts/run_ci_checks.sh --require-shellcheck

If any check is skipped, include Skipped check, Reason, and Risk in the output.

Stage 6: Final Response Contract

Always return:

  1. Generated script path
  2. Requirements traceability (REQ-* -> implementation)
  3. Validation results with rerun status
  4. Citations in standard format
  5. Any assumptions/fallbacks used

Canonical Example Flows

Example A: Full Flow (Template-first)

  1. Clarify missing data format and output expectations.
  2. Capture REQ-* table.
  3. Choose template-first path.
  4. Generate scaffold with scripts/generate_script_template.sh.
  5. Implement logic and map functions to REQ-*.
  6. Validate with devops-skills:bash-script-validator and rerun until clean.
  7. Return final summary with citations.

Example B: Constrained Environment Flow

Use this when AskUserQuestion, validator skill, or shellcheck is unavailable:

  1. Ask clarifying questions in chat.
  2. Mark unresolved items as assumptions in Captured Requirements.
  3. Generate from template script or template file copy fallback.
  4. Run bash -n (and sh -n if relevant).
  5. If shellcheck is missing, report skip with risk and mitigation.

Done Criteria

The task is complete only when all items are true:

  • Trigger matched and scope confirmed
  • Captured Requirements table exists with REQ-* IDs
  • Template-first vs custom decision is documented
  • Script is generated with deterministic structure
  • Validation executed and rerun policy applied
  • Any skipped checks include explicit reason and risk
  • Final response includes traceability, citations, and assumptions

Helper Scripts and Assets

  • Script generator: scripts/generate_script_template.sh
  • Deterministic CI gate: scripts/run_ci_checks.sh
  • Regression test suite: scripts/test_generator.sh
  • Standard scaffold: assets/templates/standard-template.sh
  • Example output style: examples/log-analyzer.sh

Reference Docs

  • docs/bash-scripting-guide.md
  • docs/script-patterns.md
  • docs/generation-best-practices.md
  • docs/text-processing-guide.md

External References

基于ShellCheck和bash -n对Bash/POSIX脚本进行语法验证、安全审计及修复建议。支持静态分析、代码审查及自动修正,确保脚本质量与可移植性。
Validate this bash script Lint this .sh file Find security issues in this shell script Why does this script fail ShellCheck? Make this script POSIX compliant
devops-skills-plugin/skills/bash-script-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill bash-script-validator -g -y
SKILL.md
Frontmatter
{
    "name": "bash-script-validator",
    "description": "Validate, lint, audit, or fix bash\/shell\/.sh scripts via ShellCheck."
}

Bash Script Validator

Overview

This skill validates Bash and POSIX shell scripts with layered checks:

  1. Syntax validation (bash -n or sh -n)
  2. ShellCheck static analysis (system binary or wrapper fallback)
  3. Custom security, portability, and optimization checks

Use the default flow below, then branch to fallbacks only when the environment is constrained.

Trigger Guidance

Use this skill when the request includes script quality, linting, syntax checking, or shell portability work.

Trigger Phrases

  • "Validate this bash script"
  • "Lint this .sh file"
  • "Find security issues in this shell script"
  • "Why does this script fail ShellCheck?"
  • "Make this script POSIX compliant"
  • "Review this shell script before CI"

Non-Trigger Examples

  • General Linux command questions with no script file
  • Kubernetes, Terraform, or pipeline validation tasks that do not involve shell scripts
  • Pure prose editing tasks

Deterministic Execution Model

Run commands from this skill directory:

cd devops-skills-plugin/skills/bash-script-validator

Step 1: Preflight

  1. Confirm target path exists and is readable.
  2. Confirm bash is available.
  3. Determine whether fixes can be applied directly (write access) or only suggested (read-only).

Step 2: Run Baseline Validation (Default Path)

bash scripts/validate.sh <script-path>

For deterministic stage behavior, set the ShellCheck provider explicitly:

# Modes: auto (default), system, wrapper, disabled
VALIDATOR_SHELLCHECK_MODE=system bash scripts/validate.sh <script-path>

Record:

  • Detected shell type
  • Exit code (0 clean, 1 warnings, 2 errors)
  • All reported issue lines and ShellCheck codes (SC####) when present

Step 3: Load Only Needed References

Progressive disclosure by issue type:

  • ShellCheck code explanations: docs/shellcheck-reference.md
  • General fix patterns and security mistakes: docs/common-mistakes.md
  • Bash-only behavior: docs/bash-reference.md
  • POSIX portability or bashism fixes: docs/shell-reference.md
  • Text-processing optimization issues: docs/grep-reference.md, docs/awk-reference.md, docs/sed-reference.md, docs/regex-reference.md (only when directly relevant)

Step 4: Provide or Apply Fixes

For each issue, include:

  1. Exact location from validator output (line number and snippet)
  2. Root cause
  3. Corrected code
  4. Why the change is safer or more portable
  5. Subsection-level citation (format below)

If the request includes patching files and write access is available, apply fixes in small batches grouped by issue type.

Step 5: Rerun Policy (Mandatory After Changes)

After each batch of edits, rerun the validator:

bash scripts/validate.sh <script-path>

Rerun loop rules:

  1. Continue until no new errors are introduced.
  2. If warnings remain by design, document why they are intentionally accepted.
  3. If constraints prevent full resolution, report unresolved items with a clear next action.
  4. Always report the latest rerun exit code and remaining issue count.

Fallback Behavior

Use these branches only when the default flow cannot run as-is.

Constraint Fallback action Reporting requirement
shellcheck missing, wrapper available Let scripts/validate.sh use scripts/shellcheck_wrapper.sh --cache automatically State that wrapper mode was used
shellcheck and wrapper unavailable Run syntax + custom checks only (validator does this) Explicitly call out reduced coverage and missing ShellCheck analysis
Python unavailable for wrapper Skip wrapper path, keep syntax + custom checks State why ShellCheck could not run
Target file is read-only Provide precise patch suggestions without editing Mark response as "advisory only"
Target file missing or unreadable Stop and request a valid file path Do not fabricate results
Binary/non-text input Stop validation Report unsupported input type

Citation Guidance for Fixes

Use subsection-level citations for every non-trivial fix.

Required citation format:

Reference: docs/<file>.md -> <Section> -> <Subsection>

Examples:

  • Reference: docs/common-mistakes.md -> 1. Unquoted Variables -> Solution
  • Reference: docs/shellcheck-reference.md -> SC2164: Use || exit After cd
  • Reference: docs/shell-reference.md -> POSIX Best Practices -> 5. Avoid Bashisms

Citation rules:

  1. Cite the most specific section that justifies the fix.
  2. For ShellCheck findings, include both the SC#### code and the matching section.
  3. If no exact subsection exists, cite the closest section and state that the fix is inferred from that guidance.

Response Template

Use this structure for deterministic output:

  • Validation Results
  • Command: bash scripts/validate.sh <script-path>
  • Detected shell: <shell>
  • Exit code: <code>
  • Summary: <errors> errors, <warnings> warnings, <info> info
  • Issue: <short label> (Line <n>)
  • Problem:
    <problematic snippet>
    
  • Fix:
    <corrected snippet>
    
  • Why: <short explanation>
  • Reference: docs/<file>.md -> <Section> -> <Subsection>
  • Rerun command: bash scripts/validate.sh <script-path>
  • Exit code after fixes: <code>
  • Remaining issues: <count or none>

Example Flows

Fully Automated Environment

# 1) Baseline validation
bash scripts/validate.sh examples/bad-bash.sh

# 2) Apply fixes to target script
# 3) Rerun validation
bash scripts/validate.sh examples/bad-bash.sh

Expected behavior: full syntax + ShellCheck + custom-check coverage, with iterative reruns until stable.

Deterministic CI Gate

# Requires a system shellcheck binary.
bash scripts/run_ci_checks.sh

This runner enforces VALIDATOR_REQUIRE_SHELLCHECK=1 and VALIDATOR_SHELLCHECK_MODE=system so CI fails if the ShellCheck stage is skipped or unavailable.

Constrained Environment (No ShellCheck Runtime)

# shellcheck unavailable and wrapper cannot run
bash scripts/validate.sh examples/bad-shell.sh

Expected behavior: syntax + custom checks still run. Report reduced coverage and list what must be revalidated once ShellCheck is available.

Validator Script Details

Scripts

  • scripts/validate.sh: primary validator entrypoint
  • scripts/shellcheck_wrapper.sh: optional ShellCheck fallback using a cached Python virtual environment

Detection and Ordering

Validation order in scripts/validate.sh:

  1. File checks (exists/readable/text)
  2. Shebang-based shell detection
  3. Syntax check
  4. ShellCheck (or fallback/skip behavior)
  5. Custom checks
  6. Summary with exit code

Exit Codes

  • 0: no issues found
  • 1: warnings found
  • 2: errors found

References

Load only what is needed:

  • docs/bash-reference.md
  • docs/shell-reference.md
  • docs/shellcheck-reference.md
  • docs/common-mistakes.md
  • docs/grep-reference.md
  • docs/awk-reference.md
  • docs/sed-reference.md
  • docs/regex-reference.md

Done Criteria

This skill update is complete when all are true:

  1. Trigger guidance is explicit (positive and non-trigger examples).
  2. Default workflow is deterministic and ordered.
  3. Fallback behavior is explicit for missing tooling and constrained environments.
  4. Fix explanations include subsection-level citations.
  5. Post-fix rerun policy is mandatory and reported with exit codes.
  6. Documentation supports both fully automated and constrained execution paths.
用于生成生产级、安全且优化的Dockerfile及多阶段构建配置。支持Node.js/Python等语言,自动处理.dockerignore,集成验证器进行迭代修复,确保最佳实践与性能优化。
创建新的Dockerfile 容器化应用程序 实现多阶段构建以优化镜像大小 将现有Dockerfile转换为最佳实践 生成生产就绪的容器配置
devops-skills-plugin/skills/dockerfile-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill dockerfile-generator -g -y
SKILL.md
Frontmatter
{
    "name": "dockerfile-generator",
    "description": "Create, generate, or write Dockerfiles and multi-stage Docker images. Containerize apps."
}

Dockerfile Generator

Overview

This skill provides a comprehensive workflow for generating production-ready Dockerfiles with security, optimization, and best practices built-in. Generates multi-stage builds, security-hardened configurations, and optimized layer structures with automatic validation and iterative error fixing.

Key Features:

  • Multi-stage builds for optimal image size (50-85% reduction)
  • Security hardening (non-root users, minimal base images, no secrets)
  • Layer caching optimization for faster builds
  • Language-specific templates (Node.js, Python, Go, Java)
  • Automatic .dockerignore generation
  • Integration with dockerfile-validator for validation
  • Iterative validation and error fixing (minimum 1 iteration if errors found)
  • Local references plus docs lookup fallback chain for framework-specific patterns

When to Use This Skill

Invoke this skill when:

  • Creating new Dockerfiles from scratch
  • Containerizing applications (Node.js, Python, Go, Java, or other languages)
  • Implementing multi-stage builds for size optimization
  • Converting existing Dockerfiles to best practices
  • Generating production-ready container configurations
  • Optimizing Docker builds for security and performance
  • The user asks to "create", "generate", "build", or "write" a Dockerfile
  • Implementing containerization for microservices
  • Setting up CI/CD pipeline container builds

Trigger Phrases

Use this skill immediately when the request contains phrasing like:

  • "Generate a production Dockerfile for my app"
  • "Create a multi-stage Dockerfile for <language/framework>"
  • "Containerize this service with security best practices"
  • "Optimize this Dockerfile for size and build speed"
  • "Write Dockerfile and .dockerignore for deployment"

Do NOT Use This Skill For

  • Validating existing Dockerfiles (use dockerfile-validator instead)
  • Building or running containers (use docker build/run commands)
  • Debugging running containers (use docker logs, docker exec)
  • Managing Docker images or registries

Deterministic Execution Model

Run these stages in order, and do not skip a stage unless the skip reason is reported in the final output.

  1. Gather requirements (language, runtime version, entrypoint, exposed port, package manager, health endpoint).
  2. Load references (local reference files first; external docs only when local references are insufficient).
  3. Generate Dockerfile and .dockerignore.
  4. Validate with dockerfile-validator or fallback local tools.
  5. Iterate fixes until stop condition is met.
  6. Publish final artifacts plus validation/audit report.

Stop conditions for stage 5:

  • Stop when there are zero validation errors and no unapproved warnings.
  • Stop after 3 iterations maximum, then emit an intentional-deviation report for unresolved findings.

Reference Path Map

Consult these files directly by path as needed:

  • references/security_best_practices.md for non-root users, secret handling, base image hardening, vulnerability scanning.
  • references/optimization_patterns.md for multi-stage strategy, cache optimization, layer reduction, BuildKit cache mounts.
  • references/language_specific_guides.md for language/framework runtime and package-manager patterns.
  • references/multistage_builds.md for advanced stage-splitting and artifact-copy patterns.

Dockerfile Generation Workflow

Follow this workflow when generating Dockerfiles. Adapt based on user needs:

Stage 1: Gather Requirements

Objective: Understand what needs to be containerized and gather all necessary information.

Information to Collect:

  1. Application Details:

    • Programming language and version (Node.js 18/20, Python 3.11/3.12, Go 1.21+, Java 17/21, etc.)
    • Application type (web server, API, CLI tool, batch job, etc.)
    • Framework (Express, FastAPI, Spring Boot, etc.)
    • Entry point (main file, command to run)
  2. Dependencies:

    • Package manager (npm/yarn/pnpm, pip/poetry, go mod, maven/gradle)
    • System dependencies (build tools, libraries, etc.)
    • Build-time vs runtime dependencies
  3. Application Configuration:

    • Port(s) to expose
    • Environment variables needed
    • Configuration files
    • Health check endpoint (for web services)
    • Volume mounts (if any)
  4. Build Requirements:

    • Build commands
    • Test commands (optional)
    • Compilation needs (for compiled languages)
    • Static asset generation
  5. Production Requirements:

    • Expected image size constraints
    • Security requirements
    • Scaling needs
    • Resource constraints (CPU, memory)

Use AskUserQuestion if information is missing or unclear.

Example Questions:

- What programming language and version is your application using?
- What is the main entry point to run your application?
- Does your application expose any ports? If so, which ones?
- Do you need any system dependencies beyond the base language runtime?
- Does your application need a health check endpoint?

Stage 2: Framework/Library Documentation Lookup (if needed)

Objective: Research framework-specific containerization patterns and best practices.

When to Perform This Stage:

  • User mentions a specific framework (Next.js, Django, FastAPI, Spring Boot, etc.)
  • Application has complex build requirements
  • Need guidance on framework-specific optimization

Research Process (strict fallback chain):

  1. Read local references first (required):

    • references/security_best_practices.md
    • references/optimization_patterns.md
    • references/language_specific_guides.md
  2. Use Context7 docs lookup when local references are insufficient (preferred external source):

    Use mcp__context7__resolve-library-id with the framework name
    Then use mcp__context7__query-docs with query:
    "docker deployment production build"
    
  3. Use web search only if Context7 is unavailable or missing needed details:

    "<framework>" "<version>" dockerfile production deployment best practices
    
  4. If external lookup is unavailable (offline/tooling limits):

    • Continue with local references and language templates in this file.
    • State assumptions explicitly in the output.
    • Mark the lookup limitation in the final report.
  5. Extract only actionable data:

    • Recommended base image + version policy
    • Build optimization techniques
    • Required runtime environment variables
    • Production vs development differences
    • Security requirements specific to the framework

Stage 3: Generate Dockerfile

Objective: Create a production-ready, multi-stage Dockerfile following best practices.

Core Principles:

  1. Multi-Stage Builds (REQUIRED for compiled languages, RECOMMENDED for all):

    • Separate build stage from runtime stage
    • Keep build tools out of final image
    • Copy only necessary artifacts
    • Results in 50-85% smaller images
  2. Security Hardening (REQUIRED):

    • Use specific version tags (NEVER use :latest)
    • Run as non-root user (create dedicated user)
    • Use minimal base images (alpine, distroless)
    • No hardcoded secrets
    • Scan base images for vulnerabilities
  3. Layer Optimization (REQUIRED):

    • Order instructions from least to most frequently changing
    • Copy dependency files before application code
    • Combine related RUN commands with &&
    • Clean up package manager caches in same layer
    • Leverage build cache effectively
  4. Production Readiness (REQUIRED):

    • Add HEALTHCHECK for services
    • Use exec form for ENTRYPOINT/CMD
    • Set WORKDIR to absolute paths
    • Document exposed ports with EXPOSE

Language-Specific Templates:

Node.js Multi-Stage Dockerfile

Build-stage dependency rule: If the application has a build step (TypeScript, Vite, Webpack, etc.), install all dependencies in the builder stage (omit --only=production) and prune dev deps after the build. Using --only=production before a build step will cause npm run build to fail because dev tools are not installed.

# syntax=docker/dockerfile:1

# Build stage — installs all deps so build tools (tsc, vite, etc.) are available,
# then prunes dev deps so the production stage only ships what is needed at runtime.
FROM node:20-alpine AS builder
WORKDIR /app

# Copy dependency files for caching
COPY package*.json ./
# Install ALL dependencies (including devDependencies required by the build step)
RUN npm ci && \
    npm cache clean --force

# Copy application code
COPY . .

# Build application and prune dev dependencies
RUN npm run build && \
    npm prune --production

# Production stage
FROM node:20-alpine AS production
WORKDIR /app

# Set production environment
ENV NODE_ENV=production

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

# Copy pruned node_modules and built application from builder
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app .

# Switch to non-root user
USER nodejs

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"

# Start application
CMD ["node", "index.js"]

Simple app (no build step): If there is no compilation or bundling, install only production deps in the builder stage and copy source from the host context:

RUN npm ci --only=production && npm cache clean --force
...
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --chown=nodejs:nodejs . .

Python Multi-Stage Dockerfile

# syntax=docker/dockerfile:1

# Build stage
FROM python:3.12-slim AS builder
WORKDIR /app

# Install build dependencies
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# Copy dependency files
COPY requirements.txt .

# Install Python dependencies
RUN pip install --no-cache-dir --user -r requirements.txt

# Production stage
FROM python:3.12-slim AS production
WORKDIR /app

# Create non-root user
RUN useradd -m -u 1001 appuser

# Copy dependencies from builder
COPY --from=builder /root/.local /home/appuser/.local

# Copy application code
COPY --chown=appuser:appuser . .

# Update PATH and set Python production env vars
# PYTHONUNBUFFERED=1 ensures stdout/stderr are flushed immediately (essential for container logs)
# PYTHONDONTWRITEBYTECODE=1 prevents writing .pyc files to disk
ENV PATH=/home/appuser/.local/bin:$PATH \
    PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1

# Switch to non-root user
USER appuser

# Expose port
EXPOSE 8000

# Health check (adjust endpoint as needed)
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()" || exit 1

# Start application
CMD ["python", "app.py"]

Go Multi-Stage Dockerfile

# syntax=docker/dockerfile:1

# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /app

# Copy go mod files
COPY go.mod go.sum ./
RUN go mod download

# Copy source code
COPY . .

# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o main .

# Production stage (using distroless for minimal image)
# gcr.io/distroless/static-debian12 IS a specific tag; hadolint DL3006 is a
# false positive for non-Docker-Hub registries.
# hadolint ignore=DL3006
FROM gcr.io/distroless/static-debian12 AS production
WORKDIR /

# Copy binary from builder
COPY --from=builder /app/main /main

# Expose port
EXPOSE 8080

# HEALTHCHECK is not supported in distroless images (no shell available)

# Switch to non-root user (distroless runs as nonroot by default)
USER nonroot:nonroot

# Start application
ENTRYPOINT ["/main"]

Java Multi-Stage Dockerfile

# syntax=docker/dockerfile:1

# Build stage
FROM eclipse-temurin:21-jdk-jammy AS builder
WORKDIR /app

# Copy Maven wrapper and pom.xml
COPY mvnw pom.xml ./
COPY .mvn .mvn

# Download dependencies (cached layer)
RUN ./mvnw dependency:go-offline

# Copy source code
COPY src ./src

# Build application
RUN ./mvnw clean package -DskipTests && \
    mv target/*.jar target/app.jar

# Production stage (using JRE instead of JDK)
FROM eclipse-temurin:21-jre-jammy AS production
WORKDIR /app

# Install healthcheck dependency and create non-root user
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/* && \
    useradd -m -u 1001 appuser

# Copy JAR from builder
COPY --from=builder --chown=appuser:appuser /app/target/app.jar ./app.jar

# Switch to non-root user
USER appuser

# Expose port
EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
    CMD curl -f http://localhost:8080/actuator/health || exit 1

# Start application
ENTRYPOINT ["java", "-jar", "app.jar"]

Selection Logic:

  • Node.js: Use for JavaScript/TypeScript applications
  • Python: Use for Python applications (web, API, scripts)
  • Go: Use for Go applications (excellent for minimal images)
  • Java: Use for Spring Boot, Quarkus, or other Java frameworks
  • Generic: Create custom Dockerfile for other languages

Always Include:

  1. Syntax directive: # syntax=docker/dockerfile:1
  2. Multi-stage build (build + production stages)
  3. Non-root user creation and usage
  4. HEALTHCHECK for services (if applicable)
  5. Proper WORKDIR settings
  6. EXPOSE for documented ports
  7. Clean package manager caches
  8. exec form for CMD/ENTRYPOINT

Stage 4: Generate .dockerignore

Objective: Create comprehensive .dockerignore to reduce build context and prevent secret leaks.

Always create .dockerignore with generated Dockerfile.

Standard .dockerignore Template:

# Git
.git
.gitignore
.gitattributes

# CI/CD
.github
.gitlab-ci.yml
.travis.yml
.circleci

# Documentation
README.md
CHANGELOG.md
CONTRIBUTING.md
LICENSE
*.md
docs/

# Docker
Dockerfile*
docker-compose*.yml
.dockerignore

# Environment
.env
.env.*
*.local

# Logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Dependencies (language-specific - add as needed)
node_modules/
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
venv/
.venv/
target/
*.class

# IDE
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store

# Testing
coverage/
.coverage
*.cover
.pytest_cache/
.tox/
test-results/

# Build artifacts
dist/
build/
*.egg-info/

Customize based on language:

  • Node.js: Add node_modules/, npm-debug.log, yarn-error.log
  • Python: Add __pycache__/, *.pyc, .venv/, .pytest_cache/
  • Go: Add vendor/, *.exe, *.test
  • Java: Add target/, *.class, *.jar (except final artifact)

Stage 5: Validate with dockerfile-validator

Objective: Ensure generated Dockerfile follows best practices and has no unresolved critical findings.

REQUIRED: Always run validation after generation.

Primary path (preferred):

  1. Invoke dockerfile-validator.
  2. Capture findings by severity (error, warning, info).
  3. Prioritize security and reproducibility findings first.

Fallback path (if skill invocation is unavailable):

  1. Try local validator script directly:
    bash ../dockerfile-validator/scripts/dockerfile-validate.sh Dockerfile
    
  2. If that path is unavailable, run available tools directly:
    hadolint Dockerfile
    checkov -f Dockerfile --framework dockerfile
    
  3. If one or more tools are unavailable, continue generation and report each skipped check in the final report.

Expected validator stages:

[1/4] Syntax Validation (hadolint)
[2/4] Security Scan (Checkov)
[3/4] Best Practices Validation
[4/4] Optimization Analysis

Stage 6: Validate-Iterate Loop (Explicit Requirements)

Objective: Apply deterministic fix loops with auditable iteration records.

Loop rules (required):

  1. Run at least one validation pass.
  2. If any error exists, apply fixes and re-run validation.
  3. Continue until:
    • no error remains, or
    • iteration count reaches 3.
  4. For warning, either fix it or mark it as intentional deviation with justification.
  5. Never silently suppress a finding.

Iteration log format (required):

Iteration Command/Path Used Errors Warnings Fixes Applied Result
1 dockerfile-validator or fallback command N N short summary pass/fail
2 ... N N short summary pass/fail
3 ... N N short summary pass/fail

Common fixes:

  • Add version tags to base images
  • Add USER directive before CMD/ENTRYPOINT
  • Add HEALTHCHECK for services
  • Combine RUN commands where safe
  • Clean package caches in same layer
  • Replace ADD with COPY where archive/url behavior is not needed

Stage 7: Final Review and Audit Report

Objective: Deliver runnable artifacts plus an auditable report.

Deliverables (required):

  1. Generated files:
    • Dockerfile (validated and optimized)
    • .dockerignore (comprehensive)
  2. Validation summary:
    • tool path used (primary vs fallback)
    • findings by severity
    • final status after loop
  3. Iteration log table from Stage 6.
  4. Intentional deviation report (only when applicable).
  5. Usage instructions.
  6. Optimization metrics and next steps.

Intentional deviation report (required when any finding is not fixed):

ID Rule/Check Severity Decision Justification Risk Mitigation Expiry/Review Date
DEV-001 e.g., DL3059 warning accepted build step readability requirement minor layer overhead revisit after refactor YYYY-MM-DD

Usage instructions template:

# Build image
docker build -t myapp:1.0 .

# Run container
docker run -p 3000:3000 myapp:1.0

# Probe health endpoint (if exposed)
curl http://localhost:3000/health

Optimization metrics (required):

## Optimization Metrics

| Metric | Estimate |
|--------|----------|
| Image Size | ~150MB (vs ~500MB without multi-stage, 70% reduction) |
| Build Cache | Layer caching enabled for dependencies |
| Security | Non-root user, minimal base image, no secrets |

Language-specific size estimates:

  • Node.js: ~50-150MB with Alpine (vs ~1GB with full node image)
  • Python: ~150-250MB with slim (vs ~900MB with full python image)
  • Go: ~5-20MB with distroless/scratch (vs ~800MB with full golang image)
  • Java: ~200-350MB with JRE (vs ~500MB+ with JDK)

Next steps (required):

## Next Steps

- [ ] Test the build locally: `docker build -t myapp:1.0 .`
- [ ] Run and verify the container works as expected
- [ ] Update CI/CD pipeline to use the new Dockerfile
- [ ] Consider BuildKit cache mounts for faster builds (see references/optimization_patterns.md)
- [ ] Set up automated vulnerability scanning with `docker scout` or `trivy`
- [ ] Push to registry and deploy

Generation Scripts (Optional Reference)

The scripts/ directory contains standalone bash scripts for manual Dockerfile generation outside of this skill:

  • generate_nodejs.sh - CLI tool for Node.js Dockerfiles
  • generate_python.sh - CLI tool for Python Dockerfiles
  • generate_golang.sh - CLI tool for Go Dockerfiles
  • generate_java.sh - CLI tool for Java Dockerfiles
  • generate_dockerignore.sh - CLI tool for .dockerignore generation

Purpose: These scripts are reference implementations and manual tools for users who want to generate Dockerfiles via command line without using skill invocation. They demonstrate the same best practices embedded in this skill.

When using this skill: Codex generates Dockerfiles directly using the templates and patterns documented in this SKILL.md, rather than invoking these scripts. The templates in this document are the authoritative source.

Script usage example:

# Manual Dockerfile generation
cd devops-skills-plugin/skills/dockerfile-generator/scripts
./generate_nodejs.sh --version 20 --port 3000 --output Dockerfile

Node/Python entrypoint flags (script mode):

Flag Purpose Notes
--entry Legacy shorthand entrypoint Simple whitespace split only. Quoted values are rejected.
--entry-cmd Preferred command/executable Use with repeated --entry-arg for exact argv control.
--entry-arg Preferred argument value Repeat for each argument; spaces are preserved per arg.
# Recommended for arguments containing spaces
./generate_nodejs.sh \
  --entry-cmd node \
  --entry-arg server.js \
  --entry-arg --message \
  --entry-arg "hello world"

Best Practices Reference

Security Best Practices

  1. Use Specific Tags:

    # Bad
    FROM node:alpine
    
    # Good
    FROM node:20-alpine
    
    # Better (with digest for reproducibility)
    FROM node:20-alpine@sha256:abc123...
    
  2. Run as Non-Root:

    # Create user
    RUN addgroup -g 1001 -S appgroup && \
        adduser -S appuser -u 1001 -G appgroup
    
    # Switch to user before CMD
    USER appuser
    
  3. Use Minimal Base Images:

    • Alpine Linux (small, secure)
    • Distroless (no shell, minimal attack surface)
    • Specific runtime images (node:alpine vs node:latest)
  4. Never Hardcode Secrets:

    # Bad
    ENV API_KEY=secret123
    
    # Good - use build secrets
    # docker build --secret id=api_key,src=.env
    RUN --mount=type=secret,id=api_key \
        API_KEY=$(cat /run/secrets/api_key) ./configure
    

Optimization Best Practices

  1. Layer Caching:

    # Copy dependency files first
    COPY package.json package-lock.json ./
    RUN npm ci
    
    # Copy application code last
    COPY . .
    
  2. Combine RUN Commands:

    # Bad (creates 3 layers)
    RUN apt-get update
    RUN apt-get install -y curl
    RUN rm -rf /var/lib/apt/lists/*
    
    # Good (creates 1 layer)
    RUN apt-get update && \
        apt-get install -y --no-install-recommends curl && \
        rm -rf /var/lib/apt/lists/*
    
  3. Multi-Stage Builds:

    # Build stage - can be large
    FROM node:20 AS builder
    WORKDIR /app
    COPY . .
    RUN npm install && npm run build
    
    # Production stage - minimal
    FROM node:20-alpine
    COPY --from=builder /app/dist ./dist
    CMD ["node", "dist/index.js"]
    

Production Readiness

  1. Health Checks:

    HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
        CMD curl -f http://localhost:3000/health || exit 1
    
  2. Proper Signals:

    # Use exec form for proper signal handling
    CMD ["node", "server.js"]  # Good
    CMD node server.js         # Bad (no signal forwarding)
    
  3. Metadata:

    LABEL maintainer="team@example.com" \
          version="1.0.0" \
          description="My application"
    

Common Patterns

Pattern 1: Node.js with Next.js

# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
CMD ["npm", "start"]

Pattern 2: Python with FastAPI

# syntax=docker/dockerfile:1
FROM python:3.12-slim AS builder
WORKDIR /app
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends gcc && \
    rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
RUN useradd -m -u 1001 appuser
COPY --from=builder /root/.local /home/appuser/.local
COPY --chown=appuser:appuser . .
ENV PATH=/home/appuser/.local/bin:$PATH \
    PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1
USER appuser
EXPOSE 8000
HEALTHCHECK CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

Pattern 3: Go CLI Tool

# syntax=docker/dockerfile:1
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /bin/app

FROM scratch
COPY --from=builder /bin/app /app
ENTRYPOINT ["/app"]

Modern Docker Features (2025)

Multi-Platform Builds with BuildX

Use Case: Build images that work on both AMD64 and ARM64 architectures (e.g., x86 servers and Apple Silicon Macs).

Enable BuildX:

# BuildX is included in Docker Desktop by default
# For Linux, ensure BuildX is installed
docker buildx version

Create Multi-Platform Images:

# Build for multiple platforms
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t myapp:latest \
  --push \
  .

# Build and load for current platform (testing)
docker buildx build \
  --platform linux/amd64 \
  -t myapp:latest \
  --load \
  .

Dockerfile Considerations:

# Most Dockerfiles work across platforms automatically
# Use platform-specific base images when needed
FROM --platform=$BUILDPLATFORM node:20-alpine AS builder

# Access build arguments for platform info
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "Building on $BUILDPLATFORM for $TARGETPLATFORM"

When to Use:

  • Deploying to mixed infrastructure (x86 + ARM)
  • Supporting Apple Silicon Macs in development
  • Optimizing for AWS Graviton (ARM-based) instances
  • Building cross-platform CLI tools

Software Bill of Materials (SBOM)

Use Case: Generate SBOM for supply chain security and compliance (increasingly required in 2025).

Generate SBOM During Build:

# Generate SBOM with BuildKit (Docker 24.0+)
docker buildx build \
  --sbom=true \
  -t myapp:latest \
  .

# SBOM is attached as attestation to the image
# View SBOM
docker buildx imagetools inspect myapp:latest --format "{{ json .SBOM }}"

Generate SBOM from Existing Image:

# Using Syft
syft myapp:latest -o json > sbom.json

# Using Docker Scout
docker scout sbom myapp:latest

SBOM Benefits:

  • Vulnerability tracking across supply chain
  • License compliance verification
  • Dependency transparency
  • Audit trail for security reviews
  • Required for government/enterprise contracts

Integration with CI/CD:

# GitHub Actions example
- name: Build with SBOM
  run: |
    docker buildx build \
      --sbom=true \
      --provenance=true \
      -t myapp:latest \
      --push \
      .

BuildKit Cache Mounts (Advanced)

Use Case: Dramatically faster builds by persisting package manager caches across builds.

Already covered in detail in references/optimization_patterns.md.

Quick reference:

# syntax=docker/dockerfile:1

# NPM cache mount (30-50% faster builds)
RUN --mount=type=cache,target=/root/.npm \
    npm ci

# Go module cache
RUN --mount=type=cache,target=/go/pkg/mod \
    go mod download

# Pip cache
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install -r requirements.txt

Error Handling

Common Generation Issues

  1. Missing dependency files:

    • Ensure package.json, requirements.txt, go.mod, pom.xml exist
    • Ask user to provide or generate template
  2. Unknown framework:

    • Use local references first, then Context7, then web search
    • Fall back to generic template
    • Ask user for specific runtime/build requirements
  3. Validation failures:

    • Apply fixes automatically
    • Iterate until clean
    • Document any suppressions

Integration with Other Skills

This skill works well in combination with:

  • dockerfile-validator - Validates generated Dockerfiles (REQUIRED)
  • k8s-yaml-generator - Generate Kubernetes deployments for the container
  • helm-generator - Create Helm charts with the container image

Notes

  • Always use multi-stage builds for compiled languages
  • Always create non-root user for security
  • Always generate .dockerignore to prevent secret leaks
  • Always validate with dockerfile-validator (or explicit fallback checks)
  • Iterate at least once if validation finds errors
  • Use alpine or distroless base images when possible
  • Pin all version tags (never use :latest)
  • Clean up package manager caches in same layer
  • Order Dockerfile instructions from least to most frequently changing
  • Use BuildKit features for advanced optimization
  • Test builds locally before committing
  • Keep Dockerfiles simple and maintainable
  • Document any non-obvious patterns with comments

Done Criteria

Mark the task done only when all items below are true:

  • Dockerfile and .dockerignore are generated.
  • Validation has been executed via dockerfile-validator or documented fallback commands.
  • Validate-iterate loop evidence is present (iteration log with command path, counts, and fixes).
  • No remaining validation error findings.
  • Every remaining warning has either a fix or an intentional-deviation report row.
  • Output includes optimization metrics and actionable next steps.

Sources

This skill is based on comprehensive research from authoritative sources:

Official Docker Documentation:

Security Guidelines:

Optimization Resources:

用于验证、检查和审计 Dockerfile 的安全性与最佳实践。涵盖语法校验、漏洞扫描及性能优化,提供确定性执行流程与严重性分级报告,适用于 CI/CD 前的代码审查。
validate this Dockerfile lint/check my Dockerfile security scan Dockerfile optimize Docker image size/build time review Dockerfile before merge find issues in Dockerfile.prod/Dockerfile.dev
devops-skills-plugin/skills/dockerfile-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill dockerfile-validator -g -y
SKILL.md
Frontmatter
{
    "name": "dockerfile-validator",
    "description": "Validate, lint, audit, or scan a Dockerfile for security and best practices."
}

Dockerfile Validator

Validate Dockerfiles with deterministic stages, clear severity reporting, and explicit fallbacks when tools or network access are constrained.

Trigger Phrases

Use this skill when the user asks for tasks like:

  • "validate this Dockerfile"
  • "lint/check my Dockerfile"
  • "security scan Dockerfile"
  • "optimize Docker image size/build time"
  • "review Dockerfile before merge"
  • "find issues in Dockerfile.prod/Dockerfile.dev"

Use / Do Not Use

Use this skill for:

  • Syntax and lint validation
  • Security and secrets checks
  • Best-practice and performance review
  • Dockerfile hardening before CI/CD or production

Do not use this skill for:

  • Generating a new Dockerfile from scratch (use dockerfile-generator)
  • Running containers, debugging runtime behavior, or image registry operations

Local Files In This Skill

  • Validator script: scripts/dockerfile-validate.sh
  • References:
    • references/security_checklist.md
    • references/optimization_guide.md
    • references/docker_best_practices.md
  • Example Dockerfiles: examples/*.Dockerfile

Deterministic Execution Flow (Required)

Run these steps in order. Do not skip steps unless a documented fallback branch applies.

1. Preflight and Path Setup

Assume repo root as working directory:

cd /path/to/repo
SKILL_DIR="devops-skills-plugin/skills/dockerfile-validator"
TARGET_DOCKERFILE="Dockerfile"   # replace when user provides a path

Validate inputs before running tools:

test -f "$SKILL_DIR/scripts/dockerfile-validate.sh"
test -f "$TARGET_DOCKERFILE"

If either check fails, stop and report the exact missing path.

2. Read the Target Dockerfile Explicitly

Use explicit file-read commands (not abstract "Read tool" wording):

sed -n '1,220p' "$TARGET_DOCKERFILE"

If needed for long files:

sed -n '220,440p' "$TARGET_DOCKERFILE"

3. Run Validation Script

Primary command:

bash "$SKILL_DIR/scripts/dockerfile-validate.sh" "$TARGET_DOCKERFILE"

Optional captured run for structured reporting:

bash "$SKILL_DIR/scripts/dockerfile-validate.sh" "$TARGET_DOCKERFILE" | tee /tmp/dockerfile-validator.out

4. Classify Findings by Severity (Standard)

Use this standard severity model:

  • Critical
    • Hardcoded secrets/credentials
    • Explicit root runtime with high-risk context
    • High-impact security policy failures
  • High
    • Checkov failures for container hardening
    • hadolint errors likely to cause insecure/unreliable builds
    • Missing or unsafe runtime-user posture (USER)
  • Medium
    • :latest image tags, missing pinning, cache-cleanup misses
    • Build cache inefficiency and layered install anti-patterns
  • Low
    • Style/info guidance and non-blocking optimization suggestions

5. No-Issue Fast Path (Required)

If validation has no actionable findings:

  • Return a concise pass summary.
  • Do not open reference files.
  • Do not generate fix diffs.

Use fast path when all are true:

  • Script reports overall pass.
  • No security failures.
  • No error/warning findings requiring user action.

6. Reference Loading Rules (Only When Findings Exist)

Only read references that match actual findings. Read each required file once.

Issue-to-reference mapping:

Issue category Trigger examples Read this file
Secrets, root user, exposed sensitive ports, hardening gaps CKV_DOCKER_*, hardcoded token/password, root runtime references/security_checklist.md
Image size, layer count, multi-stage opportunities, cache efficiency, .dockerignore gaps too many RUN, single-stage with build deps, cache misses references/optimization_guide.md
Tag pinning, instruction usage, COPY vs ADD, WORKDIR/CMD/ENTRYPOINT conventions :latest, unpinned packages, instruction-level best practices references/docker_best_practices.md

Explicit read commands:

sed -n '1,220p' "$SKILL_DIR/references/security_checklist.md"
sed -n '1,220p' "$SKILL_DIR/references/optimization_guide.md"
sed -n '1,220p' "$SKILL_DIR/references/docker_best_practices.md"

For targeted extraction:

rg -n "USER|secrets|EXPOSE|HEALTHCHECK" "$SKILL_DIR/references/security_checklist.md"
rg -n "multi-stage|cache|layer|dockerignore" "$SKILL_DIR/references/optimization_guide.md"
rg -n "FROM|COPY|ADD|WORKDIR|CMD|ENTRYPOINT|latest" "$SKILL_DIR/references/docker_best_practices.md"

7. Produce Standard Report Output

Use this template for every non-fast-path run:

## Dockerfile Validation Report
- Target: <path>
- Command: `bash <skill-script> <target>`
- Overall result: PASS | FAIL | PARTIAL (fallback)

### Critical
- <issue or `None`>

### High
- <issue or `None`>

### Medium
- <issue or `None`>

### Low
- <issue or `None`>

### Recommended Fixes
- <specific code-level fix per actionable issue>

### References Used
- <list only files actually read>

### Fallbacks Used
- `None` or exact fallback branch + reason

8. Offer Fix Application

After reporting:

  • Ask whether to apply fixes.
  • If user approves, patch the Dockerfile and rerun validation.

Fallback Behavior (Explicit)

When the primary script cannot complete, use deterministic fallback branches and report them.

Fallback A: Python/Tool Install Constraint

Condition:

  • Script exits with tool-install failure (for example Python missing, package install blocked, or restricted environment).

Action:

  1. Report primary failure and why.
  2. Run manual minimum checks:
# Basic syntax signal (if Docker is available)
DOCKERFILE_DIR="$(dirname "$TARGET_DOCKERFILE")"
docker build --no-cache -f "$TARGET_DOCKERFILE" "$DOCKERFILE_DIR"

# High-value static checks
grep -nEi "^[[:space:]]*FROM[[:space:]]+.*:latest" "$TARGET_DOCKERFILE" || true
grep -nEi "^[[:space:]]*(ENV|ARG)[[:space:]].*(password|secret|token|api[_-]?key)[[:space:]]*=" "$TARGET_DOCKERFILE" || true
grep -nEi "^[[:space:]]*USER[[:space:]]+(root|0(:0)?)$" "$TARGET_DOCKERFILE" || true
grep -nEi "^[[:space:]]*HEALTHCHECK[[:space:]]+" "$TARGET_DOCKERFILE" || true
  1. Classify output with PARTIAL result and clearly label skipped checks.

Fallback B: hadolint Not Available but Docker Available

Use hadolint container image:

docker run --rm -i hadolint/hadolint < "$TARGET_DOCKERFILE"

Fallback C: No Docker, No hadolint/checkov

Run only manual regex-based checks (Fallback A step 2), clearly mark as PARTIAL, and state which scanners were skipped.

Quick Command Set

Validate one Dockerfile

cd /path/to/repo
bash devops-skills-plugin/skills/dockerfile-validator/scripts/dockerfile-validate.sh Dockerfile

Validate alternate file

cd /path/to/repo
bash devops-skills-plugin/skills/dockerfile-validator/scripts/dockerfile-validate.sh Dockerfile.prod

Validate skill examples

cd /path/to/repo/devops-skills-plugin/skills/dockerfile-validator
bash scripts/dockerfile-validate.sh examples/good-example.Dockerfile
bash scripts/dockerfile-validate.sh examples/security-issues.Dockerfile

Run regression checks (CI entrypoint)

cd /path/to/repo
bash devops-skills-plugin/skills/dockerfile-validator/scripts/test_validate.sh

Optional strict mode for CI environments that must enforce ShellCheck:

STRICT_SHELLCHECK=true bash devops-skills-plugin/skills/dockerfile-validator/scripts/test_validate.sh

Progressive Disclosure Rules

  • Always read the target Dockerfile first.
  • Do not read any reference files unless findings require them.
  • Read only the matching reference file(s) from the issue-to-reference mapping.
  • Do not reread the same reference unless new issue categories appear.

Done Criteria

Consider this skill execution complete only when all conditions below are satisfied:

  • Trigger matched a Dockerfile validation/lint/security/optimization request.
  • Target Dockerfile path was explicitly verified.
  • Validation command (or explicit fallback) was executed.
  • Findings were reported using severity buckets (Critical, High, Medium, Low).
  • Reference usage matched issue categories and was explicitly listed.
  • No-issue fast path skipped unnecessary reference reads.
  • If fixes were applied, validation was rerun and final status reported.

Resources

  • Script: scripts/dockerfile-validate.sh
  • CI/regression entrypoint: scripts/test_validate.sh
  • Security reference: references/security_checklist.md
  • Optimization reference: references/optimization_guide.md
  • Best-practices reference: references/docker_best_practices.md
  • Examples: examples/good-example.Dockerfile, examples/bad-example.Dockerfile, examples/security-issues.Dockerfile, examples/python-optimized.Dockerfile, examples/golang-distroless.Dockerfile

Source Links

用于生成和创建 Fluent Bit 配置文件及日志管道,支持 Kubernetes 元数据、多种输出目标(如 ES、Loki)及自定义解析。通过交互式问卷收集需求,并依据条件自动选择脚本或手动方式生成配置。
创建或更新 Fluent Bit 配置文件 构建日志管道 (INPUT -> FILTER -> OUTPUT) 配置 Kubernetes 日志记录与元数据增强 将日志发送至 Elasticsearch、Loki 等后端 实现自定义解析器或多行处理逻辑
devops-skills-plugin/skills/fluentbit-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill fluentbit-generator -g -y
SKILL.md
Frontmatter
{
    "name": "fluentbit-generator",
    "description": "Generate\/create Fluent Bit configs — INPUT, FILTER, OUTPUT, parsers, log pipeline."
}

Fluent Bit Config Generator

Trigger Guidance

Use this skill when the user asks for any of the following:

  • Create or update a Fluent Bit config (fluent-bit.conf, parsers.conf)
  • Build a log pipeline (INPUT -> FILTER -> OUTPUT)
  • Configure Kubernetes logging with metadata enrichment
  • Send logs/metrics to Elasticsearch, Loki, CloudWatch, S3, Kafka, OTLP, or Prometheus remote write
  • Implement parser, multiline, lua, or stream processing behavior

Do not use this skill for pure validation-only requests; use fluentbit-validator in that case.

Execution Flow

Follow this sequence exactly. Do not skip stages.

Stage 1: Set Working Context and Preflight

Use one of these deterministic command patterns.

# Option A (recommended): run from this skill directory
cd /Users/akinozer/GolandProjects/cc-devops-skills/devops-skills-plugin/skills/fluentbit-generator
python3 scripts/generate_config.py --help
# Option B: run from any cwd with absolute paths
python3 /Users/akinozer/GolandProjects/cc-devops-skills/devops-skills-plugin/skills/fluentbit-generator/scripts/generate_config.py --help

Preflight checks:

  • Confirm python3 is available.
  • Confirm script help loads without errors.
  • If using relative output paths, run from the intended target cwd.

Fallback:

  • If python3 or script execution is unavailable, switch to manual generation flow (Stage 4) using examples/ templates.

Stage 2: Clarification Questionnaire (Explicit Template)

Collect these fields before generation.

Required questions:

  1. Primary use case: kubernetes, application logs, syslog, http ingest, metrics, or custom?
  2. Inputs: which sources and paths/ports (for example tail /var/log/containers/*.log)?
  3. Outputs: destination plugin(s) and endpoint(s) (host, port, uri/topic/index/bucket)?
  4. Reliability/security requirements: TLS on/off, retry expectations, buffering limits?
  5. Environment context: cluster name, environment name, cloud region (if applicable)?

Optional but important:

  1. Expected log format: json, regex, cri, docker, multiline stack traces?
  2. Throughput profile: low/medium/high and acceptable latency?
  3. Constraints: offline environment, missing binaries, read-only filesystem?

If any required answer is missing, ask focused follow-up questions before generating.

Stage 3: Decide Script vs Manual Generation

Use this decision table.

Condition Path
Request matches a built-in use case and only needs supported flags Script path (Stage 5)
Request needs uncommon plugin options not represented by script flags Manual path (Stage 4)
Complex multi-filter chain, custom parser/lua logic, or specialized plugin tuning Manual path (Stage 4)
Script cannot run in environment (missing Python/permissions) Manual path (Stage 4)
User explicitly requests hand-crafted config Manual path (Stage 4)

Supported script use cases:

  • kubernetes-elasticsearch
  • kubernetes-loki
  • kubernetes-cloudwatch
  • kubernetes-opentelemetry
  • application-multiline
  • syslog-forward
  • file-tail-s3
  • http-kafka
  • multi-destination
  • prometheus-metrics
  • lua-filtering
  • stream-processor
  • custom

Always state the decision explicitly, including why the other path was not used.

Stage 4: Manual Generation (When Script Is Not the Best Fit)

  1. Read the closest template in examples/ first.
  2. Read examples/parsers.conf before defining new parsers.
  3. Assemble config in this order:
  • [SERVICE]
  • [INPUT]
  • [FILTER]
  • [OUTPUT]
  • parser definitions (if needed)
  1. Reuse known-good sections from examples and only customize required parameters.
  2. Keep tags and parser references consistent across sections.

Required local template selection:

  • Kubernetes + Elasticsearch: examples/kubernetes-elasticsearch.conf
  • Kubernetes + Loki: examples/kubernetes-loki.conf
  • Kubernetes + CloudWatch: examples/cloudwatch.conf
  • Kubernetes + OpenTelemetry: examples/kubernetes-opentelemetry.conf
  • App multiline: examples/application-multiline.conf
  • Syslog forward: examples/syslog-forward.conf
  • File to S3: examples/file-tail-s3.conf
  • HTTP to Kafka: examples/http-input-kafka.conf
  • Multi destination: examples/multi-destination.conf
  • Metrics: examples/prometheus-metrics.conf
  • Lua filtering: examples/lua-filtering.conf
  • Stream processor: examples/stream-processor.conf
  • Parsers: examples/parsers.conf

Fallback:

  • If no matching example exists, start from scripts/generate_config.py --use-case custom output shape and extend manually.

Stage 5: Script Generation Commands (Deterministic Examples)

Run from skill directory unless output path is absolute.

cd /Users/akinozer/GolandProjects/cc-devops-skills/devops-skills-plugin/skills/fluentbit-generator

# Kubernetes -> Elasticsearch
python3 scripts/generate_config.py \
  --use-case kubernetes-elasticsearch \
  --cluster-name prod-cluster \
  --environment production \
  --es-host elasticsearch.logging.svc \
  --es-port 9200 \
  --output output/fluent-bit.conf

# Kubernetes -> OpenTelemetry
python3 scripts/generate_config.py \
  --use-case kubernetes-opentelemetry \
  --cluster-name prod-cluster \
  --environment production \
  --otlp-endpoint otel-collector.observability.svc:4318 \
  --output output/fluent-bit-otlp.conf

# File tail -> S3
python3 scripts/generate_config.py \
  --use-case file-tail-s3 \
  --log-path /var/log/app/*.log \
  --s3-bucket my-logs-bucket \
  --s3-region us-east-1 \
  --output output/fluent-bit-s3.conf

Fallback:

  • If a required option is unsupported by the script, document that gap and switch to Stage 4.

Stage 6: Plugin Documentation Lookup Fallback Chain

Use this strict order when plugin behavior or parameters are uncertain.

  1. Context7 (first choice)
  • Resolve library id for Fluent Bit docs.
  • Query plugin-specific configuration details.
  1. Official Fluent Bit docs (second choice)
  • Use https://docs.fluentbit.io/manual and plugin-specific pages.
  • Prefer official plugin reference sections over blogs.
  1. Web search (last choice)
  • Use only when Context7 and official docs are unavailable/incomplete.
  • Prioritize sources that quote or link official docs.

When to stop escalating:

  • Stop as soon as required parameters and one validated example are found.
  • If all sources are unavailable, proceed with local examples/ and clearly mark assumptions.

Stage 7: Validation and Fallback Behavior

Primary validation path:

  • Invoke fluentbit-validator after generation.

If validator is unavailable, run local fallback checks:

# Syntax/format smoke check when fluent-bit is installed
fluent-bit -c <generated-config> --dry-run

# Optional execution test
fluent-bit -c <generated-config>

If fluent-bit binary is missing:

  • Perform static checks manually:
    • section headers are valid ([SERVICE], [INPUT], [FILTER], [OUTPUT])
    • required plugin keys exist
    • tag/match patterns align
    • parser names/files referenced correctly
    • no hardcoded credentials
  • Report that runtime validation was skipped and why.

Stage 8: Response Contract

Always return:

  1. Generation path used (script or manual) and reason.
  2. Produced file(s) and key plugin choices.
  3. Validation results (or explicit skip reason with fallback checks performed).
  4. Assumptions, open risks, and what to customize next.

Done Criteria

This skill execution is complete only when all are true:

  • Trigger fit was explicitly confirmed.
  • Clarification questionnaire captured required fields or documented assumptions.
  • Script-vs-manual decision was explicit and justified.
  • Plugin lookup used deterministic chain: Context7 -> official docs -> web (as needed).
  • Commands were provided with cwd-safe examples.
  • Fallback behavior was applied for any missing tools/docs/network constraints.
  • Validation was executed (or skipped with explicit reason and fallback static checks).
  • Final response included generated artifacts, validation outcome, and next customization points.

Local Resources

  • Script: scripts/generate_config.py
  • Templates: examples/*.conf
  • Parsers baseline: examples/parsers.conf
  • Sample output directory: output/

Use these resources first before introducing new structure.

用于验证、检查和审计 Fluent Bit 经典模式配置。支持静态语法检查、标签路由分析、安全审查及性能评估,并可选择执行 dry-run 模拟运行,确保配置在部署前正确无误。
Validate this fluent-bit.conf before deploy Lint my Fluent Bit config and report issues Check tag routing and output matches in Fluent Bit Run security checks for Fluent Bit config Dry-run Fluent Bit config and tell me what failed
devops-skills-plugin/skills/fluentbit-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill fluentbit-validator -g -y
SKILL.md
Frontmatter
{
    "name": "fluentbit-validator",
    "description": "Validate, lint, audit, or check Fluent Bit configs (INPUT, FILTER, OUTPUT, tag routing)."
}

Fluent Bit Validator

Use this skill to run deterministic, repeatable validation for Fluent Bit classic-mode configs.

Trigger Phrases

Use this skill when prompts look like:

  • "Validate this fluent-bit.conf before deploy"
  • "Lint my Fluent Bit config and report issues"
  • "Check tag routing and output matches in Fluent Bit"
  • "Run security checks for Fluent Bit config"
  • "Dry-run Fluent Bit config and tell me what failed"

Execution Model

Run steps in order. Do not skip Stage 0.

Stage 0: Precheck (Required)

Run from skill directory:

cd devops-skills-plugin/skills/fluentbit-validator

Check required and optional binaries:

command -v python3 >/dev/null 2>&1 && echo "python3: available" || echo "python3: missing"
command -v fluent-bit >/dev/null 2>&1 && echo "fluent-bit: available" || echo "fluent-bit: missing (dry-run will be skipped)"

Precheck protocol:

  • If python3 is missing: stop script-based validation, report blocker, and switch to manual config review only.
  • If fluent-bit is missing: continue static checks, skip dry-run, and record a Recommendation explaining skip reason and next step.

Stage 1: Static Validation (Required)

Default command:

python3 scripts/validate_config.py --file <config-file> --check all

Use targeted checks only when requested:

python3 scripts/validate_config.py --file <config-file> --check structure
python3 scripts/validate_config.py --file <config-file> --check sections
python3 scripts/validate_config.py --file <config-file> --check tags
python3 scripts/validate_config.py --file <config-file> --check security
python3 scripts/validate_config.py --file <config-file> --check performance
python3 scripts/validate_config.py --file <config-file> --check best-practices
python3 scripts/validate_config.py --file <config-file> --check dry-run

Strict CI gate (optional):

python3 scripts/validate_config.py --file <config-file> --check all --fail-on-warning

Stage 2: Dry-Run Handling (Conditional)

Dry-run command:

fluent-bit -c <config-file> --dry-run

Skip protocol:

  • If fluent-bit is unavailable, do not fail static validation by default.
  • Emit one explicit finding:
    • Recommendation: Dry-run skipped because fluent-bit binary is not available in PATH; run dry-run in CI or a Fluent Bit runtime image.
  • If user explicitly requires dry-run as a release gate, run:
python3 scripts/validate_config.py --file <config-file> --check dry-run --require-dry-run
  • In release-gate mode, missing fluent-bit must be reported as Error.

Stage 3: Reference Lookup (Optional)

Use only when plugin/parameter behavior is unclear after local checks.

Lookup order:

  1. Context7 Fluent Bit docs.
  2. Official docs at docs.fluentbit.io.
  3. Broader web search limited to official/plugin sources.

Capture only:

  • required fields,
  • allowed values and defaults,
  • version caveats relevant to the user config.

Stage 4: Report and Remediation (Required)

Use exactly these severity labels:

  • Error
  • Warning
  • Recommendation

Do not introduce alternate labels (Info, Best Practice, Critical, etc.).

Report format:

Validation Report: <config-file>

Error:
- <blocking issue>

Warning:
- <non-blocking risk>

Recommendation:
- <improvement or skipped-step guidance>

Remediation flow:

  1. Present findings with file/line context when available.
  2. Ask for approval before changing user files.
  3. Apply approved changes.
  4. Re-run the same validation command(s).
  5. Return delta: what changed, what remains, and final status.

No-issue fast path:

  • If no findings exist, return a short pass summary and note whether dry-run was executed or skipped.

Fallback Matrix

Constraint Behavior
python3 missing Stop scripted validator, report blocker as Error, provide manual review-only output.
fluent-bit missing Continue static checks, skip dry-run, emit one Recommendation with next step.
No network/docs access Continue local validation, report unknown plugin details as Warning with explicit "doc lookup deferred".
User requests report-only Do not edit files; return findings and rerun command suggestion.

Canonical Flows

Full validation flow

bash scripts/validate.sh --precheck
python3 scripts/validate_config.py --file tests/valid-basic.conf --check all

Constrained environment flow (fluent-bit unavailable)

bash scripts/validate.sh --precheck
python3 scripts/validate_config.py --file tests/invalid-security-issues.conf --check all --json

Expected outcome:

  • Static findings still produced.
  • Dry-run skipped and reported under Recommendation.

Done Criteria

Work is done only when all are true:

  • Precheck was executed and binary availability was stated explicitly.
  • Validation command(s) and scope are clear and reproducible.
  • All findings use only Error, Warning, Recommendation.
  • Dry-run path is explicit: executed or skipped with reason.
  • Fallback behavior for tool/runtime constraints is documented in output.
  • If fixes were applied, validation was re-run and post-fix status was reported.

Local Assets

  • scripts/validate_config.py: main validator.
  • scripts/validate.sh: wrapper and environment precheck helper.
  • tests/*.conf: sample valid/invalid configs.
  • tests/test_validate_config.py: regression coverage for parser and severity behavior.
用于生成符合最佳实践和安全标准的 GitHub Actions 工作流、自定义操作及 CI/CD 流水线。通过决策树路由需求,自动加载参考文档与模板,并调用验证技能确保产出质量。
创建 .github/workflows/*.yml CI/CD 自动化流程 生成 action.yml 或可复用的步骤包 构建跨仓库共享的 reusable workflow
devops-skills-plugin/skills/github-actions-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill github-actions-generator -g -y
SKILL.md
Frontmatter
{
    "name": "github-actions-generator",
    "description": "Create, generate, or scaffold GitHub Actions workflows, action.yml, or .github\/workflows CI\/CD pipelines."
}

GitHub Actions Generator

Generate production-ready GitHub Actions workflows and custom actions following current best practices, security standards, and naming conventions. All generated resources are automatically validated using the devops-skills:github-actions-validator skill.

Quick Reference

Capability When to Use Reference
Workflows CI/CD, automation, testing references/best-practices.md
Composite Actions Reusable step combinations references/custom-actions.md
Docker Actions Custom environments/tools references/custom-actions.md
JavaScript Actions API interactions, complex logic references/custom-actions.md
Reusable Workflows Shared patterns across repos references/advanced-triggers.md
Security Scanning Dependency review, SBOM references/best-practices.md
Modern Features Summaries, environments references/modern-features.md

Trigger Decision Tree

Route every request through this decision tree before reading references or generating files:

  1. If the user asks for .github/workflows/*.yml CI/CD automation, choose Workflow Generation.
  2. If the user asks for action.yml or a reusable step package, choose Custom Action Generation.
  3. If the user asks for workflow_call or shared pipelines across repositories, choose Reusable Workflow Generation.
  4. If the request includes security-only scanning (dependency review, SBOM, CodeQL), stay on Workflow Generation with the security pattern.
  5. If intent is ambiguous, ask one disambiguation question: "Do you want a workflow, a custom action, or a reusable workflow?"

Progressive Disclosure Route

Load only what is needed for the selected route, in this order:

Route Load First (required) Load Next (only if needed) Primary Template
Workflow Generation references/best-practices.md references/common-actions.md, references/expressions-and-contexts.md, references/modern-features.md assets/templates/workflow/basic_workflow.yml
Custom Action Generation references/custom-actions.md references/best-practices.md assets/templates/action/composite/action.yml, assets/templates/action/docker/, assets/templates/action/javascript/
Reusable Workflow Generation references/advanced-triggers.md references/best-practices.md, references/common-actions.md assets/templates/workflow/reusable_workflow.yml

If a required reference/template is unavailable, continue with the closest available reference and report the fallback explicitly in output.


Core Capabilities

1. Generate Workflows

Triggers: "Create a workflow for...", "Build a CI/CD pipeline..."

Process:

  1. Understand requirements (triggers, runners, dependencies)
  2. Define trust boundaries (internal branches vs fork PRs vs external triggers)
  3. Set default permissions to read-only, then elevate only per job when required
  4. Reference references/best-practices.md for patterns
  5. Reference references/common-actions.md for action versions
  6. Generate workflow with:
    • Semantic names, pinned actions (SHA), explicit permissions
    • Concurrency controls, caching, matrix strategies
    • Fork-safe PR handling (no secrets in untrusted contexts)
  7. Validate with devops-skills:github-actions-validator skill
  8. Fix issues and re-validate if needed

Minimal Example:

name: CI Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
      - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0
        with:
          node-version: '24'
          cache: 'npm'
      - run: npm ci
      - run: npm test

Untrusted PR Guardrail (required for secret-using jobs):

jobs:
  deploy:
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository

2. Generate Custom Actions

Triggers: "Create a composite action...", "Build a Docker action...", "Create a JavaScript action..."

Types:

  • Composite: Combine multiple steps → Fast startup
  • Docker: Custom environment/tools → Isolated
  • JavaScript: API access, complex logic → Fastest

Process:

  1. Use templates from assets/templates/action/
  2. Follow structure in references/custom-actions.md
  3. Include branding, inputs/outputs, documentation
  4. Validate with devops-skills:github-actions-validator skill

See references/custom-actions.md for:

  • Action metadata and branding
  • Directory structure patterns
  • Versioning and release workflows

3. Generate Reusable Workflows

Triggers: "Create a reusable workflow...", "Make this workflow callable..."

Key Elements:

  • workflow_call trigger with typed inputs
  • Explicit secrets (avoid secrets: inherit)
  • Explicit trusted-caller expectations (document org/repo boundaries)
  • Outputs mapped from job outputs
  • Minimal permissions
on:
  workflow_call:
    inputs:
      environment:
        required: true
        type: string
    secrets:
      deploy-token:
        required: false
    outputs:
      result:
        value: ${{ jobs.build.outputs.result }}

When secrets are required, pass only the exact secret names needed and prefer environment protection rules for deployment stages.

See references/advanced-triggers.md for complete patterns.

4. Generate Security Workflows

Triggers: "Add security scanning...", "Add dependency review...", "Generate SBOM..."

Components:

  • Dependency Review: actions/dependency-review-action@v4
  • SBOM Attestations: actions/attest-sbom@v2
  • CodeQL Analysis: github/codeql-action

Permission Model: Use a read-only workflow-level baseline, then elevate only in the security job that requires write scopes.

permissions:
  contents: read

jobs:
  security-scan:
    permissions:
      contents: read
      security-events: write  # For CodeQL
      id-token: write         # For attestations
      attestations: write     # For attestations

See references/best-practices.md section on security.

5. Modern Features

Triggers: "Add job summaries...", "Use environments...", "Run in container..."

See references/modern-features.md for:

  • Job summaries ($GITHUB_STEP_SUMMARY)
  • Deployment environments with approvals
  • Container jobs with services
  • Workflow annotations

6. Third-Party Action Documentation and Citation

When using third-party actions (any uses: entry not in the same repository):

  1. Search for documentation:

    "[owner/repo] [version] github action documentation"
    
  2. Or use Context7 MCP:

    • mcp__context7__resolve-library-id to find action
    • mcp__context7__query-docs for documentation
  3. Pin to SHA with version comment:

    - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
    
  4. Cite source and version in the response:

    • Action source (repository URL)
    • Version source (release/tag/changelog URL)
    • Selected commit SHA and human-readable version
    • Access date for the source used

See references/common-actions.md for pre-verified action versions.


Validation Workflow

CRITICAL: Every generated resource MUST be validated.

  1. Generate workflow/action file
  2. Invoke devops-skills:github-actions-validator skill
  3. If errors: fix and re-validate
  4. If success: present with usage instructions

Skip validation only for:

  • Partial code snippets
  • Documentation examples
  • User explicitly requests skip

Fallback Behavior (Tooling and Environment Constraints)

If required tooling or network access is unavailable, use this deterministic fallback order:

  1. If devops-skills:github-actions-validator is unavailable, run local fallback checks:
    • actionlint (if installed)
    • yamllint (if installed)
    • manual YAML/schema review with a clear "not tool-validated" note
  2. If Context7 or internet access is unavailable:
    • use references/common-actions.md for known action versions
    • state that external version verification could not be completed
  3. If a template path is missing:
    • generate from the closest template pattern in assets/templates/
    • document which template was substituted

Fallback usage must always be reported in the final output.


Mandatory Standards

All generated resources must follow:

Standard Implementation
Security Pin to SHA, minimal permissions, mask secrets
Performance Caching, concurrency, shallow checkout
Naming Descriptive names, lowercase-hyphen files
Error Handling Timeouts, cleanup with if: always()

See references/best-practices.md for complete guidelines.


Resources

Reference Documents

Document Content When to Use
references/best-practices.md Security, performance, patterns Every workflow
references/common-actions.md Action versions, inputs, outputs Public action usage
references/expressions-and-contexts.md ${{ }} syntax, contexts, functions Complex conditionals
references/advanced-triggers.md workflow_run, dispatch, ChatOps Workflow orchestration
references/custom-actions.md Metadata, structure, versioning Custom action creation
references/modern-features.md Summaries, environments, containers Enhanced workflows

Templates

Template Location
Basic Workflow assets/templates/workflow/basic_workflow.yml
Reusable Workflow assets/templates/workflow/reusable_workflow.yml
Composite Action assets/templates/action/composite/action.yml
Docker Action assets/templates/action/docker/
JavaScript Action assets/templates/action/javascript/

Common Patterns

Matrix Testing

strategy:
  matrix:
    os: [ubuntu-latest, windows-latest]
    node: [18, 20, 22]
  fail-fast: false

Conditional Deployment

deploy:
  if: github.event_name == 'push' && github.ref == 'refs/heads/main'

Artifact Sharing

# Upload
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
  with:
    name: build-${{ github.sha }}
    path: dist/

# Download (in dependent job)
- uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
  with:
    name: build-${{ github.sha }}

Third-Party Action Citation Block

Third-party action citations:
- actions/checkout: https://github.com/actions/checkout (version: v6.0.2, sha: de0fac2e4500dabe0009e67214ff5f5447ce83dd, accessed: 2026-02-28)

Done Criteria

The task is complete only when all checks below pass:

  1. The request route was selected using the trigger decision tree.
  2. Only the minimum required references/templates were loaded first.
  3. Every third-party action is pinned to a commit SHA and has source/version citation.
  4. Validation was run, or a skip exception/fallback path was explicitly documented.
  5. Output includes assumptions, security-sensitive decisions (permissions/secrets), and generated file paths.

Workflow Summary

  1. Route the request using the trigger decision tree
  2. Load the minimum references/templates for that route
  3. Generate using mandatory security and naming standards
  4. Cite and pin third-party actions (source, version, SHA)
  5. Validate with devops-skills:github-actions-validator (or documented fallback)
  6. Fix and re-validate until clean
  7. Present validated output with citations, assumptions, and file paths
用于验证、修复和审计 GitHub Actions 工作流及自定义动作。通过 actionlint 和 act 进行语法检查、静态分析及本地执行测试,确保工作流符合最佳实践并解决版本依赖问题。
validate this GitHub Actions workflow check my `.github/workflows/*.yml` file debug actionlint errors test this workflow locally with act verify GitHub Action versions or deprecations
devops-skills-plugin/skills/github-actions-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill github-actions-validator -g -y
SKILL.md
Frontmatter
{
    "name": "github-actions-validator",
    "description": "Validate, lint, audit, fix GitHub Actions workflows (.github\/workflows)."
}

GitHub Actions Validator

Overview

Validate and test GitHub Actions workflows, custom actions, and public actions using industry-standard tools (actionlint and act). This skill provides comprehensive validation including syntax checking, static analysis, local workflow execution testing, and action verification with version-aware documentation lookup.

Trigger Phrases

Use this skill when the request includes phrases like:

  • "validate this GitHub Actions workflow"
  • "check my .github/workflows/*.yml file"
  • "debug actionlint errors"
  • "test this workflow locally with act"
  • "verify GitHub Action versions or deprecations"

When to Use This Skill

Use this skill when:

  • Validating workflow files: Checking .github/workflows/*.yml for syntax errors and best practices
  • Testing workflows locally: Running workflows with act before pushing to GitHub
  • Debugging workflow failures: Identifying issues in workflow configuration
  • Validating custom actions: Checking composite, Docker, or JavaScript actions
  • Verifying public actions: Validating usage of actions from GitHub Marketplace
  • Pre-commit validation: Ensuring workflows are valid before committing

Required Execution Flow

Every validation run should follow these steps in order.

Step 1: Set Skill Path and Run Validation

Run commands from the repository root that contains .github/workflows/.

SKILL_DIR="devops-skills-plugin/skills/github-actions-validator"
bash "$SKILL_DIR/scripts/validate_workflow.sh" <workflow-file-or-directory>

Step 2: Map Each Error to a Reference

For each actionlint/act error, consult the mapping table below, then extract the matching fix pattern.

Step 3: Apply Minimal-Quote Policy

For each issue:

  1. Include the exact error line from tool output.
  2. Quote only the smallest useful snippet from references/ (prefer <=8 lines).
  3. Paraphrase the rest and cite the source file/section.
  4. Show corrected workflow code.

Step 4: Handle Unmapped Errors Explicitly

If an error does not match any mapping:

  1. Label it as UNMAPPED.
  2. Capture exact tool output, workflow file, and line number (if available).
  3. Check references/common_errors.md general sections first.
  4. If still unresolved, search official docs with the exact error string.
  5. Mark the fix as provisional until post-fix rerun passes.

Step 5: Verify Public Action Versions

For each uses: owner/action@version:

  1. Check references/action_versions.md.
  2. For unknown actions, verify against official docs.
  3. Confirm required inputs and deprecations.

Offline mode behavior:

  • If network/doc lookup is unavailable, rely on references/action_versions.md only.
  • Mark unknown actions as UNVERIFIED-OFFLINE.
  • Do not claim "latest" version without an online verification pass.

Step 6: Mandatory Post-Fix Rerun

After applying fixes, rerun validation before finalizing:

SKILL_DIR="devops-skills-plugin/skills/github-actions-validator"
bash "$SKILL_DIR/scripts/validate_workflow.sh" <workflow-file-or-directory>

Step 7: Provide Final Summary

Final output should include:

  • Issues found and fixes applied
  • Any UNMAPPED or UNVERIFIED-OFFLINE items
  • Post-fix rerun command and result
  • Remaining warnings/risk notes

Error Type to Reference File Mapping

Error Pattern in Output Reference File to Read Section to Quote
runs-on:, runner, ubuntu, macos, windows references/runners.md Runner labels
cron, schedule references/common_errors.md Schedule Errors
${{, expression, if: references/common_errors.md Expression Errors
needs:, job, dependency references/common_errors.md Job Configuration Errors
uses:, action, input references/common_errors.md Action Errors
untrusted, injection, security references/common_errors.md Script Injection section
syntax, yaml, unexpected references/common_errors.md Syntax Errors
docker, container references/act_usage.md Troubleshooting
@v3, @v4, deprecated, outdated references/action_versions.md Version table
workflow_call, reusable, oidc references/modern_features.md Relevant section
glob, path, paths:, pattern references/common_errors.md Path Filter Errors

Example: Complete Error Handling Workflow

User's workflow has this error:

runs-on: ubuntu-lastest

Step 1 - Script output:

label "ubuntu-lastest" is unknown

Step 2 - Read references/runners.md or references/common_errors.md: Find the "Invalid Runner Label" section.

Step 3 - Quote the fix to user:

Error: label "ubuntu-lastest" is unknown

Cause: Typo in runner label (from references/common_errors.md):

# Bad
runs-on: ubuntu-lastest  # Typo

Fix (from references/common_errors.md):

# Good
runs-on: ubuntu-latest

Valid runner labels (from references/runners.md):

  • ubuntu-latest, ubuntu-24.04, ubuntu-22.04
  • windows-latest, windows-2025, windows-2022
  • macos-latest, macos-15, macos-14

Step 4 - Provide corrected code:

runs-on: ubuntu-latest

Quick Start

Set once per shell session:

SKILL_DIR="devops-skills-plugin/skills/github-actions-validator"

Initial Setup

bash "$SKILL_DIR/scripts/install_tools.sh"

This installs act (local workflow execution) and actionlint (static analysis) to scripts/.tools/.

Basic Validation

# Validate a single workflow
bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/ci.yml

# Validate all workflows
bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/

# Lint-only (fastest)
bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only .github/workflows/ci.yml

# Test-only with act (requires Docker)
bash "$SKILL_DIR/scripts/validate_workflow.sh" --test-only .github/workflows/

Core Validation Workflow

1. Static Analysis with actionlint

Start with static analysis to catch syntax errors and common issues:

bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only .github/workflows/ci.yml

What actionlint checks: YAML syntax, schema compliance, expression syntax, runner labels, action inputs/outputs, job dependencies, CRON syntax, glob patterns, shell scripts, security vulnerabilities.

2. Local Testing with act

After passing static analysis, test workflow execution:

bash "$SKILL_DIR/scripts/validate_workflow.sh" --test-only .github/workflows/

Note: act has limitations - see references/act_usage.md.

3. Full Validation

bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/ci.yml

Default behavior if tools/runtime are unavailable:

  • If act is missing, full validation falls back to actionlint-only.
  • If Docker is unavailable, full validation skips act and continues with actionlint.
  • --check-versions works in offline/local mode using references/action_versions.md.

Validating Resource Types

Workflows

# Single workflow
bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/ci.yml

# All workflows
bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/

Key validation points: triggers, job configurations, runner labels, environment variables, secrets, conditionals, matrix strategies.

Custom Local Actions

Create a test workflow that uses the custom action, then validate:

bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/test-custom-action.yml

Public Actions

When workflows use public actions (e.g., actions/checkout@v6):

  1. Check references/action_versions.md first
  2. Use official docs (or web search) for unknown actions
  3. Verify required inputs and version
  4. Check for deprecation warnings
  5. Run validation script

If offline:

  • Mark unknown versions as UNVERIFIED-OFFLINE
  • Avoid "latest/current" claims until online verification is possible

Search format: "[action-name] [version] github action documentation"

Reference File Consultation Guide

Mandatory Reference Consultation

Situation Reference File Action
actionlint reports any mapped error references/common_errors.md Find matching error and apply minimal quote policy
actionlint reports unmapped error references/common_errors.md + official docs Label as UNMAPPED, capture exact output and verify by rerun
act fails with Docker/runtime error references/act_usage.md Check Troubleshooting section
act fails but workflow works on GitHub references/act_usage.md Read Limitations section
User asks about actionlint config references/actionlint_usage.md Provide examples
User asks about act options references/act_usage.md Read Advanced Options
Security vulnerability detected references/common_errors.md Quote minimal safe fix snippet
Validating action versions references/action_versions.md Check version table and offline note
Using modern features references/modern_features.md Check syntax examples
Runner questions/errors references/runners.md Check labels and availability

Script Output to Reference Mapping

Output Pattern Reference File
[syntax-check], parse, YAML errors common_errors.md - Syntax Errors
[expression], ${{, condition parsing common_errors.md - Expression Errors
[action], uses:, input/output mismatch common_errors.md - Action Errors
[events] with CRON/schedule text common_errors.md - Schedule Errors
potentially untrusted, injection warnings common_errors.md - Security section
[runner-label] or unknown runs-on label runners.md
[job-needs] dependency errors common_errors.md - Job Configuration Errors
[glob], paths, pattern errors common_errors.md - Path Filter Errors
Docker/pull/image errors from act act_usage.md - Troubleshooting
No pattern match common_errors.md + official docs (label UNMAPPED)

Reference Files Summary

File Content
references/act_usage.md Act tool usage, commands, options, limitations, troubleshooting
references/actionlint_usage.md Actionlint validation categories, configuration, integration
references/common_errors.md Common errors catalog with fixes
references/action_versions.md Current action versions, deprecation timeline, SHA pinning
references/modern_features.md Reusable workflows, SBOM, OIDC, environments, containers
references/runners.md GitHub-hosted runners (ARM64, GPU, M2 Pro, deprecations)

Troubleshooting

Issue Solution
"Tools not found" Run bash "$SKILL_DIR/scripts/install_tools.sh"
"Docker daemon not running" Start Docker or use --lint-only
"Permission denied" Run chmod +x "$SKILL_DIR"/scripts/*.sh
act fails but GitHub works See references/act_usage.md Limitations

Debug Mode

actionlint -verbose .github/workflows/ci.yml  # Verbose actionlint
act -v                                         # Verbose act
act -n                                         # Dry-run (no execution)

Best Practices

  1. Always validate locally first - Catch errors before pushing
  2. Use actionlint in CI/CD - Automate validation in pipelines
  3. Pin action versions - Use @v6 not @main for stability; SHA pinning for security
  4. Keep tools updated - Regularly update actionlint and act
  5. Use official docs for unknown actions - Verify usage and versions
  6. Check version compatibility - See references/action_versions.md
  7. Enable shellcheck - Catch shell script issues early
  8. Review security warnings - Address script injection issues

Limitations

  • act limitations: Not all GitHub Actions features work locally
  • Docker requirement: act requires Docker to be running
  • Network actions: Some GitHub API actions may fail locally
  • Private actions: Cannot validate without access
  • Runtime behavior: Static analysis cannot catch all issues
  • File location: act can only validate workflows in .github/workflows/ directory; files outside (like examples/) can only be validated with actionlint

Quick Examples

Example 1: Pre-commit Validation

SKILL_DIR="devops-skills-plugin/skills/github-actions-validator"
bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/
git add .github/workflows/ && git commit -m "Update workflows"

Example 2: Debug Failing Workflow

bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only .github/workflows/failing.yml
# Fix issues
bash "$SKILL_DIR/scripts/validate_workflow.sh" .github/workflows/failing.yml

Complete Worked Example: Multi-Error Workflow

This example demonstrates the full assistant workflow for handling multiple errors.

User's Problematic Workflow

name: Broken CI
on:
  schedule:
    - cron: '0 0 * * 8'  # ERROR 1
jobs:
  build:
    runs-on: ubuntu-lastest  # ERROR 2
    steps:
      - uses: actions/checkout@v3  # ERROR 3 (outdated)
      - run: echo ${{ github.event.issue.title }}  # ERROR 4 (security)
  deploy:
    needs: biuld  # ERROR 5 (typo)
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying"

Step 1: Run Validation

bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only workflow.yml

Output:

[ERROR] invalid CRON format "0 0 * * 8"
[ERROR] label "ubuntu-lastest" is unknown
[WARN] "github.event.issue.title" is potentially untrusted
[ERROR] job "deploy" needs job "biuld" which does not exist

Step 2-3: Consult References and Quote Fixes


Error 1: Invalid CRON Expression

From references/common_errors.md - Schedule Errors:

Cause: Day of week 8 doesn't exist (valid: 0-6, where 0 = Sunday)

# Bad
schedule:
  - cron: '0 0 * * 8'  # Day 8 doesn't exist

# Good
schedule:
  - cron: '0 0 * * 0'  # Sunday

CRON format: minute hour day month weekday

  • Weekday: 0-6 (0 = Sunday)

Fix: Change 8 to 0 (Sunday) or 1-6 for Monday-Saturday.


Error 2: Invalid Runner Label

From references/common_errors.md - Job Configuration Errors and references/runners.md:

Cause: Typo in runner label

# Bad
runs-on: ubuntu-lastest  # Typo

# Good
runs-on: ubuntu-latest

Valid labels (from references/runners.md):

  • ubuntu-latest (Ubuntu 24.04)
  • ubuntu-24.04, ubuntu-22.04
  • macos-latest (macOS 15)
  • windows-latest (Windows Server 2022)

Fix: Change ubuntu-lastest to ubuntu-latest.


Error 3: Outdated Action Version

From references/action_versions.md:

Action Current Version Minimum Supported
actions/checkout v6 v4

SHA Pinning Best Practice:

# Recommended: SHA pinning with version comment
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3  # v6.0.0

Fix: Update from @v3 to @v6 (or SHA-pinned version).


Error 4: Security Vulnerability (Script Injection)

From references/common_errors.md - Expression Errors:

Warning: Potential script injection via untrusted input

# Bad - vulnerable to injection
run: echo ${{ github.event.issue.title }}

# Good - use environment variables
env:
  TITLE: ${{ github.event.issue.title }}
run: echo "$TITLE"

Why: Untrusted input (issue titles, PR bodies, commit messages) can contain malicious commands. Using environment variables sanitizes the input.

Fix: Pass untrusted input through environment variable.


Error 5: Undefined Job Dependency

From references/common_errors.md - Job Configuration Errors:

Error: Job 'deploy' depends on job 'biuld' which does not exist

# Bad
jobs:
  build:
    runs-on: ubuntu-latest
  deploy:
    needs: biuld  # Typo

# Good
jobs:
  build:
    runs-on: ubuntu-latest
  deploy:
    needs: build

Fix: Change biuld to build.


Step 4: Provide Corrected Workflow

name: Fixed CI
on:
  schedule:
    - cron: '0 0 * * 0'  # Fixed: Sunday (0-6 valid)
jobs:
  build:
    runs-on: ubuntu-latest  # Fixed: typo corrected
    steps:
      - uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3  # v6.0.0 - Fixed: updated version
      - name: Process issue
        env:
          TITLE: ${{ github.event.issue.title }}  # Fixed: use env var
        run: echo "$TITLE"
  deploy:
    needs: build  # Fixed: typo corrected
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying"

Step 5: Mandatory Rerun

bash "$SKILL_DIR/scripts/validate_workflow.sh" --lint-only workflow.yml

Expected rerun result:

  • No previous errors reproduced
  • Remaining warnings, if any, are documented explicitly

Step 6: Summary

Error Type Fix Applied
CRON 0 0 * * 8 Schedule Changed to 0 0 * * 0
ubuntu-lastest Runner Changed to ubuntu-latest
checkout@v3 Outdated Action Updated to @v6.0.0 (SHA-pinned)
Direct ${{ }} in run Security Wrapped in environment variable
needs: biuld Job Dependency Changed to needs: build

Recommendations:

  • Run bash "$SKILL_DIR/scripts/validate_workflow.sh" --check-versions regularly
  • Use SHA pinning for all actions in production workflows
  • Always pass untrusted input through environment variables

Done Criteria

Validation work is complete when all are true:

  • Trigger matched and correct validation mode selected.
  • Each mapped error includes source reference and minimal quote.
  • Each unmapped error is labeled UNMAPPED with exact output captured.
  • Public action versions are verified, or marked UNVERIFIED-OFFLINE.
  • Post-fix rerun executed and result reported.

Summary

  1. Setup: Install tools with install_tools.sh
  2. Validate: Run validate_workflow.sh on workflow files
  3. Fix: Address issues using reference documentation
  4. Rerun: Verify fixes with a mandatory post-fix validation run
  5. Search: Use official docs to verify unknown actions
  6. Commit: Push validated workflows with confidence

For detailed information, consult the appropriate reference file in references/.

用于生成符合最佳实践和标准的 GitLab CI/CD 管道配置。支持创建、生成或脚手架化 .gitlab-ci.yml,涵盖阶段、作业及多项目管道,并自动验证语法合规性。
创建 .gitlab-ci.yml 构建 Node/Python/Java 的 GitLab 管道 添加 Docker 构建和部署任务 设置父子或多项目管道 包含 SAST/依赖扫描模板
devops-skills-plugin/skills/gitlab-ci-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill gitlab-ci-generator -g -y
SKILL.md
Frontmatter
{
    "name": "gitlab-ci-generator",
    "description": "Create, generate, or scaffold .gitlab-ci.yml pipelines, stages, and jobs."
}

GitLab CI/CD Pipeline Generator

Overview

Generate production-ready GitLab CI/CD pipeline configurations following current best practices, security standards, and naming conventions. All generated resources are automatically validated using the devops-skills:gitlab-ci-validator skill to ensure syntax correctness and compliance with best practices.


Trigger Phrases

Use this skill when the user asks for GitLab CI/CD generation requests such as:

  • "Create a .gitlab-ci.yml for..."
  • "Build a GitLab pipeline for Node/Python/Java..."
  • "Add Docker build and deploy jobs in GitLab CI"
  • "Set up GitLab parent-child or multi-project pipelines"
  • "Include SAST/dependency scanning templates in GitLab CI"

Execution Model

Follow this deterministic flow in order:

  1. Classify request complexity (targeted, lightweight, or full).
  2. Load only the required reference tier for that complexity.
  3. Output the matching response profile for the selected mode.
  4. For complete pipeline generation, start from the closest template and customize.
  5. Validate complete pipelines with strict Critical/High gates.
  6. Present output with validation status and template/version notes.

If tooling is unavailable, use the documented fallback branch and report it explicitly.

Mode Routing (Quick Decision)

Request shape Mode Required references Output profile
Simple single-file pipeline with common jobs/stages and low risk Lightweight Tier 1 (+ Tier 2 only if needed) Lightweight confirmation + compact final sections
Multi-environment deploy, advanced rules, includes/templates, security/compliance-sensitive workflow, or unclear/risky requirement Full Tier 1 + Tier 2 (Tier 3 only if needed) Full confirmation + full final sections
Review/Q&A/snippet/focused fix (not full file generation) Targeted Only directly relevant files Concise targeted response (no full boilerplate)

When uncertain on a complete-generation request, route to Full mode.

MANDATORY PRE-GENERATION STEPS

CRITICAL: Before generating any complete GitLab CI/CD pipeline, complete these steps.

Step 1: Classify Complexity (REQUIRED)

Mode Use When Minimum Confirmation
Targeted Review/Q&A/snippet/focused fix where full pipeline generation is not requested Concise targeted response
Lightweight Simple single-file pipeline, common stages/jobs, no advanced GitLab features, no sensitive deploy/security customization Lightweight confirmation
Full Multi-environment deploys, includes/templates, advanced rules logic, security scanning customization, compliance-sensitive workflows, or any unclear/risky request Full confirmation

When uncertain on a complete-generation request, default to Full mode.

Step 2: Load References by Tier (REQUIRED)

Use an open/read action to load references based on the selected mode.

Targeted mode (review/Q&A/snippet/focused fix):

  • Load only directly relevant references/templates for the scoped request.
  • Do not enforce Full-generation Tier 1/Tier 2 checklist items.

Tier 1 (Required for complete pipeline generation in Lightweight and Full modes):

  1. references/best-practices.md - baseline security, performance, naming
  2. references/common-patterns.md - starting pattern selection
  3. Matching template from assets/templates/:
    • Docker pipelines -> assets/templates/docker-build.yml
    • Kubernetes deployments -> assets/templates/kubernetes-deploy.yml
    • Multi-project pipelines -> assets/templates/multi-project.yml
    • Basic pipelines -> assets/templates/basic-pipeline.yml

Tier 2 (Required for Full mode; optional for Lightweight mode):

  1. references/gitlab-ci-reference.md - keyword/syntax edge cases
  2. references/security-guidelines.md - security-sensitive controls

Tier 3 (Conditional external docs lookup):

  • Use only when local references do not cover requested features or version-specific behavior.
  • Follow the lookup flow in "Handling GitLab CI/CD Documentation Lookup."

If a required local reference or template is unavailable:

  • Report the exact missing path.
  • Continue with available references and mark assumptions explicitly.
  • Do not claim production-ready confidence until missing critical inputs are resolved.

Step 3: Confirm Understanding (EXPLICIT OUTPUT REQUIRED)

Lightweight Confirmation Mode

Use for simple requests only.

Required format:

## Reference Analysis Complete (Lightweight)

**Pattern:** [Pattern name] from common-patterns.md
**Template:** [Template file]
**Key standards to enforce:**
- [2-3 concrete standards]

Example:

## Reference Analysis Complete (Lightweight)

**Pattern:** Basic Build-Test-Deploy from common-patterns.md
**Template:** assets/templates/basic-pipeline.yml
**Key standards to enforce:**
- Pin runtime image versions (no `:latest`)
- Add explicit job timeouts
- Use `rules` instead of deprecated `only`/`except`

Full Confirmation Mode

Use for complex or security-sensitive requests.

Required format:

## Reference Analysis Complete (Full)

**Pipeline Pattern Identified:** [Pattern name] from common-patterns.md
- [Brief description of why this pattern fits]

**Best Practices to Apply:**
- [List 3-5 key best practices relevant to this pipeline]

**Security Guidelines:**
- [List security measures to implement]

**Template Foundation:** [Template file name]
- [What will be customized from this template]

Example:

## Reference Analysis Complete (Full)

**Pipeline Pattern Identified:** Docker Build + Kubernetes Deployment from common-patterns.md
- User needs containerized deployment to K8s clusters with staging/production environments

**Best Practices to Apply:**
- Pin all Docker images to specific versions (not `:latest`)
- Use caching for pip dependencies
- Implement DAG optimization with `needs` keyword
- Set explicit timeout on all jobs (15-20 minutes)
- Use `resource_group` for deployment jobs

**Security Guidelines:**
- Use masked CI/CD variables for secrets (KUBE_CONTEXT, registry credentials)
- Include container scanning with Trivy
- Never expose secrets in logs

**Template Foundation:** assets/templates/docker-build.yml + assets/templates/kubernetes-deploy.yml
- Combine Docker build pattern with K8s kubectl deployment
- Add Python-specific test jobs

Skipping confirmation is not allowed for complete pipeline generation.


Core Capabilities

1. Generate Basic CI/CD Pipelines

Create complete, production-ready .gitlab-ci.yml files with proper structure, security best practices, and efficient CI/CD patterns.

When to use:

  • User requests: "Create a GitLab pipeline for...", "Build a CI/CD pipeline...", "Generate GitLab CI config..."
  • Scenarios: CI/CD pipelines, automated testing, build automation, deployment pipelines

Process:

  1. Understand the user's requirements (what needs to be automated)
  2. Identify stages, jobs, dependencies, and artifacts
  3. Use assets/templates/basic-pipeline.yml as structural foundation
  4. Reference references/best-practices.md for implementation patterns
  5. Reference references/common-patterns.md for standard pipeline patterns
  6. Generate the pipeline following these principles:
    • Use semantic stage and job names
    • Pin Docker images to specific versions (not :latest)
    • Implement proper secrets management with masked variables
    • Use caching for dependencies to improve performance
    • Implement proper artifact handling with expiration
    • Use needs keyword for DAG optimization when appropriate
    • Add proper error handling with retry and allow_failure
    • Use rules instead of deprecated only/except
    • Set explicit timeout for all jobs (10-30 minutes typically)
    • Add meaningful job descriptions in comments
  7. ALWAYS validate the generated pipeline using the devops-skills:gitlab-ci-validator skill
  8. If validation fails, fix the issues and re-validate

Example structure:

# Basic CI/CD Pipeline
# Builds, tests, and deploys the application

stages:
  - build
  - test
  - deploy

# Global variables
variables:
  NODE_VERSION: "20"
  DOCKER_DRIVER: overlay2

# Default settings for all jobs
default:
  image: node:20-alpine
  timeout: 20 minutes  # Default timeout for all jobs
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  before_script:
    - echo "Starting job ${CI_JOB_NAME}"
  tags:
    - docker
  interruptible: true

# Build stage - Compiles the application
build-application:
  stage: build
  timeout: 15 minutes
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour
  rules:
    - changes:
        - src/**/*
        - package*.json
      when: always
    - when: on_success

# Test stage
test-unit:
  stage: test
  needs: [build-application]
  script:
    - npm run test:unit
  coverage: '/Coverage: \d+\.\d+%/'
  artifacts:
    reports:
      junit: junit.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml

test-lint:
  stage: test
  needs: []  # Can run immediately
  script:
    - npm run lint
  allow_failure: true

# Deploy stage
deploy-staging:
  stage: deploy
  needs: [build-application, test-unit]
  script:
    - npm run deploy:staging
  environment:
    name: staging
    url: https://staging.example.com
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"
  when: manual

deploy-production:
  stage: deploy
  needs: [build-application, test-unit]
  script:
    - npm run deploy:production
  environment:
    name: production
    url: https://example.com
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  when: manual
  resource_group: production

2. Generate Docker Build Pipelines

Create pipelines for building, testing, and pushing Docker images to container registries.

When to use:

  • User requests: "Create a Docker build pipeline...", "Build and push Docker images..."
  • Scenarios: Container builds, multi-stage Docker builds, registry pushes

Process:

  1. Understand the Docker build requirements (base images, registries, tags)
  2. Use assets/templates/docker-build.yml as foundation
  3. Implement Docker-in-Docker or Kaniko for builds
  4. Configure registry authentication
  5. Implement image tagging strategy
  6. Add security scanning if needed
  7. ALWAYS validate using devops-skills:gitlab-ci-validator skill

Example:

stages:
  - build
  - scan
  - push

variables:
  DOCKER_DRIVER: overlay2
  IMAGE_NAME: $CI_REGISTRY_IMAGE
  IMAGE_TAG: $CI_COMMIT_SHORT_SHA

# Build Docker image
docker-build:
  stage: build
  image: docker:24-dind
  timeout: 20 minutes
  services:
    - docker:24-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build
        --cache-from $IMAGE_NAME:latest
        --tag $IMAGE_NAME:$IMAGE_TAG
        --tag $IMAGE_NAME:latest
        .
    - docker push $IMAGE_NAME:$IMAGE_TAG
    - docker push $IMAGE_NAME:latest
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  retry:
    max: 2
    when:
      - runner_system_failure

# Scan for vulnerabilities
container-scan:
  stage: scan
  image: aquasec/trivy:0.49.0
  timeout: 15 minutes
  script:
    - trivy image --exit-code 0 --severity HIGH,CRITICAL $IMAGE_NAME:$IMAGE_TAG
  needs: [docker-build]
  allow_failure: true
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

3. Generate Kubernetes Deployment Pipelines

Create pipelines that deploy applications to Kubernetes clusters.

When to use:

  • User requests: "Deploy to Kubernetes...", "Create K8s deployment pipeline..."
  • Scenarios: Kubernetes deployments, Helm deployments, kubectl operations

Process:

  1. Identify the Kubernetes deployment method (kubectl, Helm, Kustomize)
  2. Use assets/templates/kubernetes-deploy.yml as foundation
  3. Configure cluster authentication (service accounts, kubeconfig)
  4. Implement proper environment management
  5. Add rollback capabilities
  6. ALWAYS validate using devops-skills:gitlab-ci-validator skill

Example:

stages:
  - build
  - deploy

# Kubernetes deployment job
deploy-k8s:
  stage: deploy
  image: bitnami/kubectl:1.29
  timeout: 10 minutes
  before_script:
    - kubectl config use-context $KUBE_CONTEXT
  script:
    - kubectl set image deployment/myapp myapp=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n $KUBE_NAMESPACE
    - kubectl rollout status deployment/myapp -n $KUBE_NAMESPACE --timeout=5m
  environment:
    name: production
    url: https://example.com
    kubernetes:
      namespace: production
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual
  resource_group: k8s-production
  retry:
    max: 2
    when:
      - runner_system_failure

4. Generate Multi-Project Pipelines

Create pipelines that trigger other projects or use parent-child pipeline patterns.

When to use:

  • User requests: "Create multi-project pipeline...", "Trigger other pipelines..."
  • Scenarios: Monorepos, microservices, orchestration pipelines

Process:

  1. Identify the pipeline orchestration needs
  2. Use assets/templates/multi-project.yml or parent-child templates
  3. Configure proper artifact passing
  4. Implement parallel execution where appropriate
  5. ALWAYS validate using devops-skills:gitlab-ci-validator skill

Example (Parent-Child):

# Parent pipeline
stages:
  - trigger

generate-child-pipeline:
  stage: trigger
  script:
    - echo "Generating child pipeline config"
    - |
      cat > child-pipeline.yml <<EOF
      stages:
        - build

      child-job:
        stage: build
        script:
          - echo "Running child job"
      EOF
  artifacts:
    paths:
      - child-pipeline.yml

trigger-child:
  stage: trigger
  trigger:
    include:
      - artifact: child-pipeline.yml
        job: generate-child-pipeline
    strategy: depend
  needs: [generate-child-pipeline]

5. Generate Template-Based Configurations

Create reusable templates using extends, YAML anchors, and includes.

When to use:

  • User requests: "Create reusable templates...", "Build modular pipeline config..."
  • Scenarios: Template libraries, DRY configurations, shared CI/CD logic

Process:

  1. Identify common patterns to extract
  2. Create hidden jobs (prefixed with .)
  3. Use extends keyword for inheritance
  4. Organize into separate files with include
  5. ALWAYS validate using devops-skills:gitlab-ci-validator skill

Example:

# Hidden template jobs (include timeout in templates)
.node-template:
  image: node:20-alpine
  timeout: 15 minutes  # Default timeout for jobs using this template
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  before_script:
    - npm ci
  interruptible: true

.deploy-template:
  timeout: 10 minutes  # Deploy jobs should have explicit timeout
  before_script:
    - echo "Deploying to ${ENVIRONMENT}"
  after_script:
    - echo "Deployment complete"
  retry:
    max: 2
    when:
      - runner_system_failure
      - stuck_or_timeout_failure
  interruptible: false  # Deploys should not be interrupted

# Actual jobs using templates
build:
  extends: .node-template
  stage: build
  script:
    - npm run build

deploy-staging:
  extends: .deploy-template
  stage: deploy
  variables:
    ENVIRONMENT: staging
  script:
    - ./deploy.sh staging
  resource_group: staging

6. Handling GitLab CI/CD Documentation Lookup

Use this flow only when local references do not cover requested features or version-sensitive behavior.

Detection:

  • User mentions specific GitLab features (e.g., "Auto DevOps", "SAST", "dependency scanning")
  • User requests integration with GitLab templates
  • Pipeline requires specific GitLab runner features

Process:

  1. Identify the feature:

    • Extract the GitLab feature or template name
    • Determine if version-specific information is needed
  2. Check local references first (Tier 1/Tier 2):

    • references/common-patterns.md
    • references/gitlab-ci-reference.md
    • references/security-guidelines.md
  3. Use Context7 first when external lookup is needed:

    • Resolve library: mcp__context7__resolve-library-id
    • Query docs: mcp__context7__query-docs
    • Prefer GitLab official/library docs over secondary sources
  4. Fallback to web search when Context7 is unavailable or insufficient:

    • Use web.search_query
    • Query pattern: "GitLab CI/CD [feature] documentation"
    • Prefer results from docs.gitlab.com
  5. Open and extract from specific docs pages when needed:

    • Use web.open for selected documentation pages
    • Capture required syntax, variables, and version constraints
  6. Analyze discovered documentation for:

    • Current recommended approach
    • Required variables and configuration
    • Template include syntax
    • Best practices and security recommendations
    • Example usage
  7. If network tools are unavailable (offline/constrained environment):

    • Continue using local references only
    • State that external version verification could not be performed
    • Add a version-assumption note in the final output
  8. Generate pipeline using discovered information:

    • Use correct template include syntax
    • Configure required variables
    • Add security best practices
    • Include comments about versions and choices

Example with GitLab templates:

# Include GitLab's security templates (use Jobs/ prefix for current templates)
include:
  - template: Jobs/SAST.gitlab-ci.yml
  - template: Jobs/Dependency-Scanning.gitlab-ci.yml

# Customize SAST behavior via global variables
# Note: Set variables globally rather than overriding template jobs
# to avoid validation issues with partial job definitions
variables:
  SAST_EXCLUDED_PATHS: "spec, test, tests, tmp, node_modules"
  DS_EXCLUDED_PATHS: "node_modules, vendor"
  SECURE_LOG_LEVEL: "info"

Important: When using include with GitLab templates, the included jobs are fully defined in the template. If you need to customize them, prefer setting variables globally rather than creating partial job overrides (which will fail local validation because the validator cannot resolve the included template). GitLab merges the configuration at runtime, but local validators only see your .gitlab-ci.yml file.

Validation Workflow

CRITICAL: Every generated GitLab CI/CD configuration MUST be validated before presenting to the user.

Validation Process

  1. Primary validation path: after generating a complete pipeline, invoke the devops-skills:gitlab-ci-validator skill:

    Skill: devops-skills:gitlab-ci-validator
    
  2. Script fallback path (if validator skill cannot be invoked):

    PIPELINE_FILE="<generated-output-path>"
    
    • Set PIPELINE_FILE to the exact generated file path (for example, pipelines/review.yml or .gitlab-ci.yml).
    • Fail fast if that file does not exist:
      if [[ ! -f "$PIPELINE_FILE" ]]; then
        echo "ERROR: CI file not found: $PIPELINE_FILE" >&2
        exit 1
      fi
      
    # From repository root
    bash devops-skills-plugin/skills/gitlab-ci-validator/scripts/validate_gitlab_ci.sh "$PIPELINE_FILE"
    
    # From skills/gitlab-ci-generator directory
    bash ../gitlab-ci-validator/scripts/validate_gitlab_ci.sh "$PIPELINE_FILE"
    
    • If the script is not executable:
      chmod +x devops-skills-plugin/skills/gitlab-ci-validator/scripts/validate_gitlab_ci.sh
      
    • Optional API lint fallback when GitLab project context is available:
      jq --null-input --arg yaml "$(<"$PIPELINE_FILE")" '.content=$yaml' \
      | curl --header "Content-Type: application/json" \
        --url "https://gitlab.com/api/v4/projects/:id/ci/lint?include_merged_yaml=true" \
        --data @-
      
  3. Manual fallback path (only if both primary and script paths are unavailable):

    • Run manual checks for YAML validity, stage/job references, and obvious secret exposure.
    • Mark output as Validation status: Manual fallback (not fully verified).
    • Do not claim production-ready status if Critical/High risk cannot be confidently ruled out.
  4. The validator skill/script checks:

    • Validate YAML syntax
    • Check GitLab CI/CD schema compliance
    • Verify job references and dependencies
    • Check for best practices violations
    • Perform security scanning
    • Report any errors, warnings, or issues
  5. Analyze validation results and take action based on severity:

    Severity Action Required
    CRITICAL MUST fix before presenting. Pipeline is broken or severely insecure.
    HIGH MUST fix before presenting. Significant security or functionality issues.
    MEDIUM SHOULD fix before presenting. Apply fixes or explain why not applicable.
    LOW MAY fix or acknowledge. Inform user of recommendations.
    SUGGESTIONS Review and apply if beneficial. No fix required.
  6. Fix-and-Revalidate Loop (MANDATORY for Critical/High issues):

    While validation has CRITICAL or HIGH issues:
      1. Edit the generated file to fix the issue
      2. Re-run validation
      3. Repeat until no CRITICAL or HIGH issues remain
    
  7. Before presenting to user, ensure:

    • Zero CRITICAL issues
    • Zero HIGH issues
    • MEDIUM issues either fixed OR explained why they're acceptable
    • LOW issues and suggestions acknowledged
  8. When presenting the validated configuration:

    • State validation status clearly
    • State validation path used (skill, script fallback, or manual fallback)
    • List any remaining MEDIUM/LOW issues with explanations
    • Include template/version freshness notes
    • Provide usage instructions
    • Mention any trade-offs made

Critical/High gate is strict and never optional for production-ready claims.

Validation Pass Criteria

Pipeline is READY to present when:

  • ✅ Validation path executed (validator skill or script fallback)
  • ✅ Syntax validation: PASSED
  • ✅ Security scan: No CRITICAL or HIGH issues
  • ✅ Best practices: Reviewed (warnings acceptable with explanation)

Pipeline is NOT READY when:

  • ❌ Any syntax errors exist
  • ❌ Any CRITICAL security issues exist
  • ❌ Any HIGH security issues exist
  • ❌ Job references are broken
  • ❌ Only manual fallback was used and Critical/High risks cannot be ruled out

When to Skip Validation

Only skip validation when:

  • Generating partial code snippets (not complete files)
  • Creating examples for documentation purposes
  • User explicitly requests to skip validation

Handling MEDIUM Severity Issues (REQUIRED OUTPUT)

When the validator reports MEDIUM severity issues, you MUST either fix them OR explain why they're acceptable. This explanation is REQUIRED in your output.

Required format for MEDIUM issue handling:

## Validation Issues Addressed

### MEDIUM Severity Issues

| Issue | Status | Explanation |
|-------|--------|-------------|
| [Issue code] | Fixed/Acceptable | [Why it was fixed OR why it's acceptable] |

Example MEDIUM issue explanations:

## Validation Issues Addressed

### MEDIUM Severity Issues

| Issue | Status | Explanation |
|-------|--------|-------------|
| `image-variable-no-digest` | Acceptable | Using `python:${PYTHON_VERSION}-alpine` allows flexible version management via CI/CD variables. The PYTHON_VERSION variable is controlled internally and pinned to "3.12". SHA digest pinning would require updating the digest with every image update, adding maintenance burden without significant security benefit for this use case. |
| `pip-without-hashes` | Acceptable | This pipeline installs well-known packages (pytest, flake8) from PyPI. Using `--require-hashes` would require maintaining hash files for all transitive dependencies. For internal CI/CD, the security trade-off is acceptable. For higher security environments, consider using a private PyPI mirror with verified packages. |
| `git-strategy-none` | Acceptable | The `stop-staging` and `rollback-production` jobs use `GIT_STRATEGY: none` because they only run kubectl commands that don't require source code. The scripts are inline in the YAML (not from the repo), so there's no risk of executing untrusted code. |

When to FIX vs ACCEPT:

Scenario Action
Production/high-security environment FIX the issue
Issue has simple fix with no downside FIX the issue
Fix adds significant complexity ACCEPT with explanation
Fix requires external changes (e.g., CI/CD variables) ACCEPT with explanation
Issue is false positive for this context ACCEPT with explanation

Reviewing Suggestions (REQUIRED OUTPUT)

When the validator provides suggestions, you MUST briefly acknowledge them and explain whether they should be applied.

Required format:

## Validator Suggestions Review

| Suggestion | Recommendation | Reason |
|------------|----------------|--------|
| [suggestion] | Apply/Skip | [Why] |

Example suggestions review:

## Validator Suggestions Review

| Suggestion | Recommendation | Reason |
|------------|----------------|--------|
| `missing-retry` on test jobs | Skip | Test jobs are deterministic and don't interact with external services. Retry would mask flaky tests rather than fail fast. |
| `parallel-opportunity` for test-unit | Apply if beneficial | Could be added if pytest supports sharding. Add `parallel: 3` with `pytest --shard=${CI_NODE_INDEX}/${CI_NODE_TOTAL}` if test suite is large enough to benefit. |
| `dag-optimization` for stop-staging | Skip | This job is manual and only runs on environment cleanup. DAG optimization wouldn't provide meaningful speedup. |
| `no-dependency-proxy` | Apply for production | Consider using `$CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX` to avoid Docker Hub rate limits. Requires GitLab Premium. |
| `environment-no-url` for rollback | Skip | Rollback jobs don't deploy new versions, so a URL would be misleading. |
| `missing-coverage` for lint job | Skip | Linting doesn't produce coverage data. This is a false positive. |

Template and Version Notes (REQUIRED OUTPUT)

After validation results, include a concise freshness note for templates and documentation assumptions.

Required format:

## Template and Version Notes

- **Template base:** [assets/templates/<file>.yml]
- **Template customization scope:** [what changed from template]
- **Version/doc basis:** [Context7, docs.gitlab.com, or local references only]
- **Freshness note:** [exact date checked, or "external lookup unavailable"]
- **Version-sensitive assumptions:** [if any]

Example:

## Template and Version Notes

- **Template base:** assets/templates/docker-build.yml
- **Template customization scope:** Added unit-test stage and environment-specific deploy rules
- **Version/doc basis:** docs.gitlab.com include-template docs + local references
- **Freshness note:** Verified template syntax on 2026-02-28
- **Version-sensitive assumptions:** Uses `Jobs/SAST.gitlab-ci.yml` template path

Usage Instructions Template (REQUIRED OUTPUT)

After presenting the validated pipeline, you MUST provide usage instructions. This is NOT optional.

Required format:

## Usage Instructions

### Required CI/CD Variables

Configure these variables in **Settings → CI/CD → Variables**:

| Variable | Description | Masked | Protected |
|----------|-------------|--------|-----------|
| [VARIABLE_NAME] | [Description] | Yes/No | Yes/No |

### Setup Steps

1. [First setup step]
2. [Second setup step]
...

### Pipeline Behavior

- **On push to `develop`:** [What happens]
- **On push to `main`:** [What happens]
- **On tag `vX.Y.Z`:** [What happens]

### Customization

[Any customization notes]

Example usage instructions:

## Usage Instructions

### Required CI/CD Variables

Configure these variables in **Settings → CI/CD → Variables**:

| Variable | Description | Masked | Protected |
|----------|-------------|--------|-----------|
| `KUBE_CONTEXT` | Kubernetes cluster context name | No | Yes |
| `KUBE_NAMESPACE_STAGING` | Staging namespace (default: staging) | No | No |
| `KUBE_NAMESPACE_PRODUCTION` | Production namespace (default: production) | No | Yes |

**Note:** `CI_REGISTRY_USER`, `CI_REGISTRY_PASSWORD`, and `CI_REGISTRY` are automatically provided by GitLab.

### Kubernetes Integration Setup

1. **Enable Kubernetes integration** in **Settings → Infrastructure → Kubernetes clusters**
2. **Add your cluster** using the agent-based or certificate-based method
3. **Create namespaces** for staging and production if they don't exist:
   ```bash
   kubectl create namespace staging
   kubectl create namespace production
  1. Ensure deployment exists in the target namespaces before running the pipeline

Pipeline Behavior

  • On push to develop: Runs tests → builds Docker image → deploys to staging automatically
  • On push to main: Runs tests → builds Docker image → manual deployment to production
  • On tag vX.Y.Z: Runs tests → builds Docker image → manual deployment to production

Customization

  • Update APP_NAME variable to match your Kubernetes deployment name
  • Modify environment URLs in deploy-staging and deploy-production jobs
  • Add Helm deployment by uncommenting the Helm jobs in the template

## Best Practices to Enforce

Reference `references/best-practices.md` for comprehensive guidelines. Key principles:

### Mandatory Standards

1. **Security First:**
   - Pin Docker images to specific versions (not :latest)
   - Use masked variables for secrets ($CI_REGISTRY_PASSWORD should be masked)
   - Never expose secrets in logs
   - Validate inputs and sanitize variables
   - Use protected variables for sensitive environments

2. **Performance:**
   - Implement caching for dependencies (ALWAYS for npm, pip, maven, etc.)
   - Use `needs` keyword for DAG optimization (ALWAYS when jobs have dependencies)
   - Set artifact expiration to avoid storage bloat (ALWAYS set `expire_in`)
   - Use `parallel` execution *when applicable* (only if test framework supports sharding)
   - Minimize unnecessary artifact passing (use `artifacts: false` in `needs` when not needed)

3. **Reliability:**
   - **Set explicit `timeout` for ALL jobs** (prevents hanging jobs, typically 10-30 minutes)
     - Even when using `default` or `extends` for timeout inheritance, add explicit `timeout` to each job
     - This improves readability and avoids validator warnings about missing timeout
     - Example: A job using `.deploy-template` should still have `timeout: 15 minutes` explicitly set
   - Add retry logic for flaky operations (network calls, external API interactions)
   - Use `allow_failure` appropriately for non-critical jobs (linting, optional scans)
   - Use `resource_group` for deployment jobs (prevents concurrent deployments)
   - Add `interruptible: true` for test jobs (allows cancellation when new commits push)

4. **Naming:**
   - Job names: Descriptive, kebab-case (e.g., "build-application", "test-unit")
   - Stage names: Short, clear (e.g., "build", "test", "deploy")
   - Variable names: UPPER_SNAKE_CASE for environment variables
   - Environment names: lowercase (e.g., "production", "staging")

5. **Configuration Organization:**
   - Use `extends` for reusable configuration (PREFERRED over YAML anchors for GitLab CI)
   - Use `include` for modular pipeline files (organize large pipelines into multiple files)
   - Use `rules` instead of deprecated only/except (ALWAYS)
   - Define `default` settings for common configurations (image, timeout, cache, tags)
   - Use YAML anchors *only when necessary* for complex repeated structures within a single file
     - Note: `extends` is preferred because it provides better visualization in GitLab UI

6. **Error Handling:**
   - Set appropriate timeout values (ALWAYS - prevents hanging jobs)
   - Configure retry behavior for flaky operations (network calls, external APIs)
   - Use `allow_failure: true` for non-blocking jobs (linting, optional scans)
   - Add cleanup steps with `after_script` *when needed* (e.g., stopping test containers, cleanup)
   - Implement notification mechanisms *when required* (e.g., Slack integration for deployment failures)

## Resources

### References (Tiered Loading)

- `references/best-practices.md` (**Tier 1: required for all**) - Comprehensive GitLab CI/CD best practices
  - Security patterns, performance optimization
  - Pipeline design, configuration organization
  - Common patterns and anti-patterns
  - **Use this:** When implementing any GitLab CI/CD resource

- `references/common-patterns.md` (**Tier 1: required for all**) - Frequently used pipeline patterns
  - Basic CI pipeline patterns
  - Docker build and push patterns
  - Deployment patterns (K8s, cloud platforms)
  - Multi-project and parent-child patterns
  - **Use this:** When selecting which pattern to use

- `references/gitlab-ci-reference.md` (**Tier 2: required for Full mode**) - GitLab CI/CD YAML syntax reference
  - Complete keyword reference
  - Job configuration options
  - Rules and conditional execution
  - Variables and environments
  - **Use this:** For syntax and keyword details

- `references/security-guidelines.md` (**Tier 2: required for Full mode**) - Security best practices
  - Secrets management
  - Image security
  - Script security
  - Artifact security
  - **Use this:** For security-sensitive configurations

### Assets (Templates to Customize)

- `assets/templates/basic-pipeline.yml` - Complete basic pipeline template
- `assets/templates/docker-build.yml` - Docker build pipeline template
- `assets/templates/kubernetes-deploy.yml` - Kubernetes deployment template
- `assets/templates/multi-project.yml` - Multi-project orchestration template

**How to use templates:**
1. Copy the relevant template structure
2. Replace all `[PLACEHOLDERS]` with actual values
3. Customize logic based on user requirements
4. Remove unnecessary sections
5. Validate the result

## Typical Workflow Example

**User request:** "Create a CI/CD pipeline for a Node.js app with testing and Docker deployment"

**Process:**
1. ✅ Understand requirements:
   - Node.js application
   - Run tests (unit, lint)
   - Build Docker image
   - Deploy to container registry
   - Trigger on push and merge requests

2. ✅ Reference resources:
   - Check `references/best-practices.md` for pipeline structure
   - Check `references/common-patterns.md` for Node.js + Docker pattern
   - Use `assets/templates/docker-build.yml` as base

3. ✅ Generate pipeline:
   - Define stages (build, test, dockerize, deploy)
   - Create build job with caching
   - Create test jobs (unit, lint) with needs optimization
   - Create Docker build job
   - Add proper artifact management
   - Pin Docker images to versions
   - Include proper secrets handling

4. ✅ Validate:
   - Invoke `devops-skills:gitlab-ci-validator` skill
   - Fix any reported issues
   - Re-validate if needed

5. ✅ Present to user:
   - Show validated pipeline
   - Explain key sections
   - Provide usage instructions
   - Mention successful validation

## Common Pipeline Patterns

### Basic Three-Stage Pipeline
```yaml
stages:
  - build
  - test
  - deploy

build-job:
  stage: build
  script: make build

test-job:
  stage: test
  script: make test

deploy-job:
  stage: deploy
  script: make deploy
  when: manual

DAG Pipeline with Needs

stages:
  - build
  - test
  - deploy

build-frontend:
  stage: build
  script: npm run build:frontend

build-backend:
  stage: build
  script: npm run build:backend

test-frontend:
  stage: test
  needs: [build-frontend]
  script: npm test:frontend

test-backend:
  stage: test
  needs: [build-backend]
  script: npm test:backend

deploy:
  stage: deploy
  needs: [test-frontend, test-backend]
  script: make deploy

Conditional Execution with Rules

deploy-staging:
  script: deploy staging
  rules:
    - if: $CI_COMMIT_BRANCH == "develop"
      when: always
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: manual

deploy-production:
  script: deploy production
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
      when: manual
    - when: never

Matrix Parallel Jobs

test:
  parallel:
    matrix:
      - NODE_VERSION: ['18', '20', '22']
        OS: ['ubuntu', 'alpine']
  image: node:${NODE_VERSION}-${OS}
  script:
    - npm test

Error Messages and Troubleshooting

If devops-skills:gitlab-ci-validator reports errors:

  1. Syntax errors: Fix YAML formatting, indentation, or structure
  2. Job reference errors: Ensure referenced jobs exist in needs/dependencies
  3. Stage errors: Verify all job stages are defined in stages list
  4. Rule errors: Check rules syntax and variable references
  5. Security warnings: Address hardcoded secrets and image pinning

If GitLab documentation is not found:

  1. Try Context7 first: mcp__context7__resolve-library-id -> mcp__context7__query-docs
  2. If needed, run web.search_query scoped to docs.gitlab.com
  3. Open specific pages with web.open and extract only required syntax/variables
  4. If offline, continue with local references and add version-assumption notes

PRE-DELIVERY CHECKLIST

MANDATORY: Before presenting ANY generated pipeline to the user, verify ALL items:

Mode and References

  • Complexity mode selected (Targeted, Lightweight, or Full)
  • For Targeted mode: only directly relevant files/references loaded
  • For Lightweight/Full modes: read references/best-practices.md before generating
  • For Lightweight/Full modes: read references/common-patterns.md before generating
  • For Lightweight/Full modes: read appropriate template from assets/templates/ for the pipeline type
  • For Full mode: read references/gitlab-ci-reference.md
  • For Full mode: read references/security-guidelines.md
  • Output explicit confirmation statement for Lightweight/Full modes

Generation Standards Applied

  • All Docker images pinned to specific versions (no :latest)
  • All jobs have explicit timeout (10-30 minutes typically)
  • default block includes timeout if defined
  • Hidden templates (.template-name) include timeout
  • Caching configured for dependency installation
  • needs keyword used for DAG optimization where appropriate
  • rules used (not deprecated only/except)
  • resource_group configured for deployment jobs
  • Artifacts have expire_in set
  • Secrets use masked CI/CD variables (not hardcoded)

Validation Completed

  • Validation executed via devops-skills:gitlab-ci-validator or script fallback
  • Zero CRITICAL issues
  • Zero HIGH issues
  • MEDIUM issues addressed (fixed OR explained in output using required format)
  • LOW issues acknowledged (listed in output)
  • Suggestions reviewed (using required format)
  • Re-validated after any fixes
  • If only manual fallback was available: output marked as not fully verified

Presentation Ready

  • Validation status stated clearly
  • Validation path stated clearly (skill, script fallback, or manual fallback)
  • MEDIUM/LOW issues explained (with table format)
  • Suggestions review provided (with table format)
  • Template and version notes provided (with required format)
  • Usage instructions provided (with required sections)
  • Key sections explained

If any checkbox is unchecked, DO NOT present the pipeline. Complete the missing steps first.

Required Output Sections

Use the smallest valid output profile for the selected mode.

Full mode (complete/complex pipeline):

  1. Reference Analysis Complete (from Step 3)
  2. Generated Pipeline (the .gitlab-ci.yml content)
  3. Validation Results Summary (pass/fail status)
  4. Validation Issues Addressed (MEDIUM issues table)
  5. Validator Suggestions Review (suggestions table)
  6. Template and Version Notes (template base + freshness/version assumptions)
  7. Usage Instructions (variables, setup, behavior)

Lightweight mode (complete/simple pipeline):

  1. Reference Analysis Complete (Lightweight)
  2. Generated Pipeline
  3. Validation Results Summary
  4. Template and Version Notes
  5. Usage Instructions
  • Add Validation Issues Addressed only when MEDIUM issues exist.
  • Add Validator Suggestions Review only when suggestions are present.

Targeted mode (review/Q&A/snippet/focused fix):

  • Provide only the directly requested artifact/answer and a concise rationale.
  • Include validation/fallback disclosure if validation was not run.
  • Do not force full pipeline-generation sections.

Done Criteria

This skill execution is done when:

  • Simple requests use Lightweight mode without unnecessary Tier 2 loading.
  • Complex requests use Full mode with Tier 2 references and complete confirmation.
  • Validation enforces strict Critical/High gates before production-ready claims.
  • Output includes template/version freshness notes plus usage instructions.
  • Any fallback path is explicit and does not hide verification gaps.

Summary

Always follow this sequence when generating GitLab CI/CD pipelines:

  1. Classify Complexity - choose Targeted, Lightweight, or Full mode.
  2. Load References - use tiered loading:
    • For Targeted mode, load only directly relevant files.
    • For Lightweight/Full modes, load:
      • references/best-practices.md
      • references/common-patterns.md
      • Plus the appropriate template from assets/templates/
    • For Full mode, also load:
      • references/gitlab-ci-reference.md
      • references/security-guidelines.md
  3. Confirm - Output targeted response or Lightweight/Full reference analysis as required by mode.
  4. Generate - Use templates and follow standards (security, caching, naming, explicit timeout on ALL jobs).
  5. Lookup Docs When Needed - Context7 first, then web.search_query/web.open, with offline fallback notes when constrained.
  6. Validate - Use devops-skills:gitlab-ci-validator, script fallback if needed.
  7. Fix - Resolve all Critical/High issues, address Medium issues.
  8. Verify Checklist - Confirm all pre-delivery checklist items.
  9. Present - Deliver output with validation summary, template/version notes, and usage instructions.

Generate GitLab CI/CD pipelines that are:

  • ✅ Secure with pinned images and proper secrets handling
  • ✅ Following current best practices and conventions
  • ✅ Using proper configuration organization (extends, includes)
  • ✅ Optimized for performance (caching, needs, DAG)
  • ✅ Properly documented with usage instructions
  • ✅ Validated with zero Critical/High issues
  • ✅ Production-ready and maintainable
用于验证、检查、审计和修复 GitLab CI/CD 配置文件。提供语法、最佳实践及安全审查,支持分阶段工作流确保流水线可靠与安全。
Validate this .gitlab-ci.yml Why is this GitLab pipeline failing? Run a security review for our GitLab CI Check pipeline best practices Lint GitLab CI config before merge
devops-skills-plugin/skills/gitlab-ci-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill gitlab-ci-validator -g -y
SKILL.md
Frontmatter
{
    "name": "gitlab-ci-validator",
    "description": "Validate, lint, audit, or fix .gitlab-ci.yml pipelines, stages, and jobs."
}

GitLab CI/CD Validator

Comprehensive toolkit for validating, linting, testing, and securing .gitlab-ci.yml configurations.

Trigger Phrases

Use this skill when requests include intent like:

  • "Validate this .gitlab-ci.yml"
  • "Why is this GitLab pipeline failing?"
  • "Run a security review for our GitLab CI"
  • "Check pipeline best practices"
  • "Lint GitLab CI config before merge"

Setup And Prerequisites (Run First)

All commands below assume repository root as current working directory.

# Ensure validator scripts are executable
chmod +x devops-skills-plugin/skills/gitlab-ci-validator/scripts/*.sh \
  devops-skills-plugin/skills/gitlab-ci-validator/scripts/*.py

# Required runtime
python3 --version

Use one canonical command path for orchestration:

VALIDATOR="bash devops-skills-plugin/skills/gitlab-ci-validator/scripts/validate_gitlab_ci.sh"

Optional local execution tooling (for --test-only):

bash devops-skills-plugin/skills/gitlab-ci-validator/scripts/install_tools.sh

Quick Start Commands

# 1) Full validation (syntax + best practices + security)
$VALIDATOR .gitlab-ci.yml

# 2) Syntax and schema only (required first gate)
$VALIDATOR .gitlab-ci.yml --syntax-only

# 3) Best-practices only (recommended)
$VALIDATOR .gitlab-ci.yml --best-practices

# 4) Security only (required before merge)
$VALIDATOR .gitlab-ci.yml --security-only

# 5) Optional local pipeline structure test (needs gitlab-ci-local + Docker)
$VALIDATOR .gitlab-ci.yml --test-only

# 6) Strict mode (treat best-practice warnings as failure)
$VALIDATOR .gitlab-ci.yml --strict

Deterministic Validation Workflow

Follow these gates in order:

  1. Run Quick Start command 2 (--syntax-only).
  2. If syntax fails, stop and fix errors before continuing.
  3. Run Quick Start command 3 (--best-practices) and apply relevant improvements.
  4. Run Quick Start command 4 (--security-only) and fix all critical/high findings before merge.
  5. Optionally run Quick Start command 5 (--test-only) for local execution checks.
  6. Run Quick Start command 6 (--strict) for final merge gate.

Required gates: syntax + security. Recommended gate: best practices. Optional gate: local execution test.

Rule Severity Rationale And Documentation Links

Severity Model

  • critical: Direct credential/secret exposure or high-confidence compromise path. Block merge.
  • high: Exploitable unsafe behavior or strong security regression. Fix before merge.
  • medium: Security hardening gap with realistic risk. Track and fix soon.
  • low/suggestion: Optimization or maintainability improvement.

Rule Classes And Why They Matter

  • Syntax rules (yaml-syntax, job-stage-undefined, dependencies-undefined-job): prevent pipeline parse and dependency failures.
  • Best-practice rules (cache-missing, artifact-no-expiration, dag-optimization): reduce runtime cost and improve pipeline throughput.
  • Security rules (hardcoded-password, curl-pipe-bash, include-remote-unverified): reduce credential leaks and supply-chain risk.

References

Fallbacks For Tool Or Environment Constraints

  • Missing python3:
    • Behavior: validator cannot run.
    • Fallback: install Python 3 and rerun.
  • Missing PyYAML:
    • Behavior: python_wrapper.sh auto-creates .venv and installs pyyaml when possible.
    • Fallback in restricted/offline environments: pre-install pyyaml from an internal mirror, then rerun.
  • Missing gitlab-ci-local, node, or docker:
    • Behavior: --test-only reports warning/failure.
    • Fallback: skip local execution testing and continue with syntax/best-practice/security gates.
  • No execute permission on scripts:
    • Behavior: shell permission errors.
    • Fallback: rerun the setup chmod command from the Setup section.

Examples

Example 1: New Pipeline Validation

$VALIDATOR examples/basic-pipeline.gitlab-ci.yml --syntax-only
$VALIDATOR examples/basic-pipeline.gitlab-ci.yml --security-only

Example 2: Pre-Merge Hard Gate

$VALIDATOR .gitlab-ci.yml --strict

Example 3: CI Integration

stages:
  - validate

validate_gitlab_ci:
  stage: validate
  script:
    - chmod +x devops-skills-plugin/skills/gitlab-ci-validator/scripts/*.sh devops-skills-plugin/skills/gitlab-ci-validator/scripts/*.py
    - bash devops-skills-plugin/skills/gitlab-ci-validator/scripts/validate_gitlab_ci.sh .gitlab-ci.yml --strict

Individual Validators (Advanced)

# Syntax validator (via wrapper for PyYAML fallback)
bash devops-skills-plugin/skills/gitlab-ci-validator/scripts/python_wrapper.sh \
  devops-skills-plugin/skills/gitlab-ci-validator/scripts/validate_syntax.py .gitlab-ci.yml

# Best-practices validator
bash devops-skills-plugin/skills/gitlab-ci-validator/scripts/python_wrapper.sh \
  devops-skills-plugin/skills/gitlab-ci-validator/scripts/check_best_practices.py .gitlab-ci.yml

# Security validator
bash devops-skills-plugin/skills/gitlab-ci-validator/scripts/python_wrapper.sh \
  devops-skills-plugin/skills/gitlab-ci-validator/scripts/check_security.py .gitlab-ci.yml

Done Criteria

  • Frontmatter name and description unchanged.
  • One canonical orchestrator path is used consistently.
  • Setup and chmod prerequisites appear before workflow/use examples.
  • Quick-start and workflow are non-duplicative (workflow references quick-start gates).
  • Severity rationale and rule-to-doc references are explicit.
  • Fallback behavior is documented for missing tools and constrained environments.
  • Examples are executable from repository root.

Notes

  • This skill validates configuration and static patterns; it does not execute production pipelines.
  • Use gitlab-ci-local or GitLab CI Lint for runtime behavior confirmation.
用于创建、生成或脚手架化生产级Helm Chart,包括Chart.yaml、values.yaml及模板。支持K8s清单转换,涵盖Deployment等组件配置,通过分阶段流程收集需求并遵循官方最佳实践。
create Helm chart scaffold Helm chart generate Helm templates convert manifests to Helm chart build chart with Deployment/Service/Ingress
devops-skills-plugin/skills/helm-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill helm-generator -g -y
SKILL.md
Frontmatter
{
    "name": "helm-generator",
    "description": "Create, scaffold, or generate Helm charts, Chart.yaml, values.yaml, templates, helpers."
}

Helm Chart Generator

Overview

Generate production-ready Helm charts with deterministic scaffolding, standard helpers, reusable templates, and validation loops.

Official Documentation:

When to Use This Skill

Use helm-generator Use OTHER skill
Create new Helm charts helm-validator: Validate/lint existing charts
Generate Helm templates k8s-yaml-generator: Raw K8s YAML (no Helm)
Convert K8s manifests to Helm k8s-debug: Debug deployed resources
Implement CRDs in Helm k8s-yaml-validator: Validate K8s manifests

Trigger Phrases

Use this skill when prompts include phrases like:

  • "create Helm chart"
  • "scaffold Helm chart"
  • "generate Helm templates"
  • "convert manifests to Helm chart"
  • "build chart with Deployment/Service/Ingress"

Execution Flow

Follow these stages in order. Do not skip required stages.

Stage 1: Gather Requirements (Required)

Collect:

  • Scope: full chart, specific templates, or conversion from manifests
  • Workload: deployment, statefulset, or daemonset
  • Image reference: repository, optional tag, or digest
  • Ports: service port and container target port (separate values)
  • Runtime settings: resources, probes, autoscaling, ingress, storage
  • Security: service account, security contexts, optional RBAC/network policies

Use request_user_input when critical fields are missing.

If request_user_input is unavailable, ask in normal chat and continue with explicit assumptions.

Missing Information Question to Ask
Image repository/tag "What container image should be used? (e.g., nginx:1.25)"
Service port "What service port should be exposed?"
Container target port "What container port should traffic be forwarded to?"
Resource limits "What CPU/memory limits should be set? (e.g., 500m CPU, 512Mi memory)"
Probe endpoints "What health check endpoints does the app expose? (e.g., /health, /ready)"
Scaling requirements "Should autoscaling be enabled? If yes, min/max replicas and target CPU%?"
Workload type "What workload type: Deployment, StatefulSet, or DaemonSet?"
Storage requirements "Does the application need persistent storage? Size and access mode?"

Do not silently assume critical settings.

Stage 2: Lookup CRD Documentation (Only if CRDs Are In Scope)

  1. Try Context7 first:
    • mcp__context7__resolve-library-id
    • mcp__context7__query-docs
  2. Fallback chain if Context7 is unavailable or incomplete:
    • Operator official docs (preferred)
    • General web search

Also consult references/crd_patterns.md for example patterns.

Stage 3: Scaffold Chart Structure (Required)

Run:

bash scripts/generate_chart_structure.sh <chart-name> <output-directory> [options]

Options:

  • --image <repo> - Supports repo-only, tagged image, registry ports, and digest refs
  • --port <number> - Service port (default: 80)
  • --target-port <number> - Container target port (default: 8080)
  • --type <type> - Workload type: deployment, statefulset, daemonset (default: deployment)
  • --with-templates - Generate resource templates (deployment.yaml, service.yaml, etc.)
  • --with-ingress - Include ingress template
  • --with-hpa - Include HPA template
  • --force - Overwrite existing chart without prompting

Image parsing behavior:

  • --image nginx:1.27 -> repository nginx, tag 1.27
  • --image registry.local:5000/team/app -> repository kept intact
  • --image ghcr.io/org/app@sha256:... -> digest mode (no tag concatenation)
  • --tag cannot be combined with digest image references

Idempotency and overwrite behavior:

  • generate_chart_structure.sh: prompts before overwrite; --force overwrites non-interactively.
  • generate_standard_helpers.sh: prompts before replacing templates/_helpers.tpl; --force bypasses prompt.

Expected scaffold shape:

mychart/
  Chart.yaml
  values.yaml
  templates/
    _helpers.tpl
    NOTES.txt
    serviceaccount.yaml
    service.yaml
    configmap.yaml
    secret.yaml
    deployment.yaml|statefulset.yaml|daemonset.yaml
    ingress.yaml (optional)
    hpa.yaml (optional)
  .helmignore

Stage 4: Generate Standard Helpers

Run:

bash scripts/generate_standard_helpers.sh <chart-name> <chart-directory>

Required helpers: name, fullname, chart, labels, selectorLabels, serviceAccountName.

Fallback:

  • If script execution is blocked, copy assets/_helpers-template.tpl and replace CHARTNAME with the chart name.

Stage 5: Consult References and Generate Templates (Required)

Consult relevant references once at this stage:

  • references/resource_templates.md for the resource patterns being generated
  • references/helm_template_functions.md for templating function usage
  • references/crd_patterns.md only when CRDs are in scope

Example file-open commands:

sed -n '1,220p' references/resource_templates.md
sed -n '1,220p' references/helm_template_functions.md

Resource coverage from references/resource_templates.md:

  • Workloads: Deployment, StatefulSet, DaemonSet, Job, CronJob
  • Services: Service, Ingress
  • Config: ConfigMap, Secret
  • RBAC: ServiceAccount, Role, RoleBinding, ClusterRole, ClusterRoleBinding
  • Network: NetworkPolicy
  • Autoscaling: HPA, PodDisruptionBudget

Required template patterns:

metadata:
  name: {{ include "mychart.fullname" . }}
  labels: {{- include "mychart.labels" . | nindent 4 }}

{{- with .Values.nodeSelector }}
nodeSelector: {{- toYaml . | nindent 2 }}
{{- end }}

annotations:
  {{- if and .Values.configMap .Values.configMap.enabled }}
  checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
  {{- end }}

Checksum annotations are required for workloads, but must be conditional and only reference generated templates (configmap.yaml, secret.yaml).

Stage 6: Create values.yaml

Structure guidelines:

  • Group related settings logically
  • Document every value with # -- comments
  • Provide sensible defaults
  • Include security contexts, resource limits, probes
  • Keep service.port and service.targetPort separate and explicit
  • Keep configMap.enabled / secret.enabled aligned with generated templates

See assets/values-schema-template.json for JSON Schema validation.

Stage 7: Validate

Preferred path: run the helm-validator skill.

If skill invocation is unavailable, run local commands directly:

helm lint <chart-dir>
helm template test <chart-dir>

If helm is unavailable, report the block clearly and perform partial checks:

  • bash -n scripts/generate_chart_structure.sh
  • bash -n scripts/generate_standard_helpers.sh
  • Verify generated files and key fields manually

Re-run validation after any fixes.

Template Functions Quick Reference

See references/helm_template_functions.md for complete guide.

Function Purpose Example
required Enforce required values {{ required "msg" .Values.x }}
default Fallback value {{ .Values.x | default 1 }}
quote Quote strings {{ .Values.x | quote }}
include Use helpers {{ include "name" . | nindent 4 }}
toYaml Convert to YAML {{ toYaml .Values.x | nindent 2 }}
tpl Render as template {{ tpl .Values.config . }}
nindent Newline + indent {{- include "x" . | nindent 4 }}

Working with CRDs

See references/crd_patterns.md for complete examples.

Key points:

  • CRDs you ship -> crds/ directory (not templated, not deleted on uninstall)
  • CR instances -> templates/ directory (fully templated)
  • Always look up documentation for CRD spec requirements
  • Document operator dependencies in Chart.yaml annotations

Converting Manifests to Helm

  1. Parameterize: Names -> helpers, values -> values.yaml
  2. Apply patterns: Labels, conditionals, toYaml for complex objects
  3. Add helpers: Create _helpers.tpl with standard helpers
  4. Validate: Run helm-validator (or local lint/template fallback), then test with different values

Error Handling

Issue Solution
Template syntax errors helm template test <chart-dir> --debug --show-only templates/<file>.yaml
Undefined values helm lint <chart-dir> --strict and add default/required
Checksum include errors Ensure templates/configmap.yaml and templates/secret.yaml exist and configMap.enabled / secret.enabled are set correctly
Port mismatch (Service vs container) Set both service.port and service.targetPort, then re-run helm template test <chart-dir>
CRD validation fails Verify apiVersion/spec fields with Context7 or operator docs, then re-render
Script argument failures Run bash scripts/generate_chart_structure.sh --help and pass required values for option flags

Example Flows

Full scaffold with templates, ingress, HPA, and explicit port mapping:

bash scripts/generate_chart_structure.sh webapp ./charts \
  --image ghcr.io/acme/webapp:2.3.1 \
  --port 80 \
  --target-port 8080 \
  --type deployment \
  --with-templates \
  --with-ingress \
  --with-hpa

Digest-based image scaffold:

bash scripts/generate_chart_structure.sh api ./charts \
  --image ghcr.io/acme/api@sha256:0123456789abcdef \
  --with-templates

Minimal scaffold without templates:

bash scripts/generate_chart_structure.sh starter ./charts

Scaffold Success Criteria

Mark complete only when all checks pass:

  • Chart.yaml, values.yaml, .helmignore, templates/NOTES.txt, and templates/_helpers.tpl exist
  • values.yaml contains explicit service.port and service.targetPort
  • If --with-templates was used, serviceaccount.yaml, service.yaml, configmap.yaml, secret.yaml, and one workload template exist
  • Generated workload template uses conditional checksum annotations for config/secret
  • Image rendering logic supports tag and digest modes
  • Validation completed (helm-validator skill or local fallback commands) and outcomes reported

Resources

Scripts

Script Usage
scripts/generate_chart_structure.sh bash scripts/generate_chart_structure.sh <chart-name> <output-dir> [options]
scripts/generate_standard_helpers.sh bash scripts/generate_standard_helpers.sh <chart-name> <chart-dir> [--force]

References

File Content
references/helm_template_functions.md Complete template function guide
references/resource_templates.md All K8s resource templates
references/crd_patterns.md CRD patterns (cert-manager, Prometheus, Istio, ArgoCD)

Assets

File Purpose
assets/_helpers-template.tpl Standard helpers template
assets/values-schema-template.json JSON Schema for values validation

Integration with helm-validator

After generating charts, invoke helm-validator and close the loop:

  1. Generate chart/templates
  2. Run helm-validator (or local fallback commands)
  3. Fix identified issues
  4. Re-validate until passing
Helm Chart 验证与分析工具,提供只读检查、模板渲染、YAML及CRD校验和安全性审计。支持本地与集群模式,按阶段执行并生成修复建议,不自动修改文件。
用户要求验证或调试 Helm Chart Helm 模板渲染失败或产生无效 YAML 需要部署前的质量门禁检查 需验证 CRD 字段是否符合文档
devops-skills-plugin/skills/helm-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill helm-validator -g -y
SKILL.md
Frontmatter
{
    "name": "helm-validator",
    "description": "Validate, lint, audit, check Helm charts — Chart.yaml, templates, values.yaml, CRDs, schemas."
}

Helm Chart Validator & Analysis Toolkit

Overview

This skill provides a comprehensive validation and analysis workflow for Helm charts, combining Helm-native linting, template rendering, YAML validation, schema validation, CRD documentation lookup, and security best practices checking.

IMPORTANT: This validator is read-only by default. It analyzes charts and proposes improvements. Only modify files when the user explicitly asks to apply fixes.

Trigger Cases

Use this skill when one or more of these top cases apply:

  • The user asks to validate, lint, check, test, or troubleshoot a Helm chart
  • Helm templates fail to render, lint, or produce valid Kubernetes YAML
  • A pre-deployment quality gate is needed (schema, dry-run, security checks)
  • CRD resources are present and their spec fields must be verified against docs
  • The user wants a severity-based validation report with proposed remediations

Trigger phrase examples:

  • "Validate this Helm chart before release"
  • "Why does helm template fail?"
  • "Check this chart for Kubernetes and security issues"

Out of scope by default:

  • New chart scaffolding or broad chart generation (use helm-generator)

Role Boundaries

  • This skill validates and reports; it does not silently rewrite user files.
  • It can propose concrete patches and apply them only when the user explicitly requests fixes.
  • If execution constraints block a stage, it must continue with reachable stages and document the skip reason.

Execution Model

  1. Run stages in order (1 through 10).
  2. Keep going after stage-level failures to collect complete findings, unless rendering fails and no manifests exist.
  3. If Stage 4 produces no manifests, mark Stages 5 to 9 as blocked and continue to Stage 10 reporting.
  4. Treat Stage 8 as environment-dependent optional; treat Stage 9 and Stage 10 as mandatory when manifests exist.
  5. For every skipped stage, record the exact tool/environment reason in the final summary table.

Quick Execution Modes

Mode A: Local Validation (no cluster required)

bash scripts/setup_tools.sh
bash scripts/validate_chart_structure.sh <chart-directory>
helm lint <chart-directory> --strict
helm template <release-name> <chart-directory> --values <values-file> --debug --output-dir ./rendered
find ./rendered -type f \( -name "*.yaml" -o -name "*.yml" \) -exec yamllint -c assets/.yamllint {} +
find ./rendered -type f \( -name "*.yaml" -o -name "*.yml" \) -exec kubeconform -summary -verbose {} +

Mode B: Full Validation (cluster available)

Run Mode A plus Stage 8 dry-run commands in this document.

Validation & Testing Workflow

Follow this sequential validation workflow. Each stage catches different types of issues:

Stage 1: Tool Check

Before starting validation, verify required tools are installed:

bash scripts/setup_tools.sh

Required tools:

  • helm: Helm package manager for Kubernetes (v3+)
  • yamllint: YAML syntax and style linting
  • kubeconform: Kubernetes schema validation with CRD support
  • kubectl: Cluster dry-run testing (optional but recommended)

Fallback policy for unavailable tools or environment constraints:

Condition Action Stage status
helm missing Run Stage 2 only, then report Stages 3 to 9 as skipped/blocked ⚠️ Warning
yamllint missing Use yq syntax checks if available; otherwise skip Stage 5 ⚠️ Warning
kubeconform missing Skip Stage 7 and rely on Stage 6 CRD/manual checks ⚠️ Warning
kubectl missing or no kube-context Skip Stage 8, continue with remaining stages ⚠️ Warning
No internet access for CRD docs Use local CRD manifests and kubeconform output, mark doc lookup incomplete ⚠️ Warning

If tools are missing, provide installation instructions from scripts/setup_tools.sh output and continue with the fallback path above.

Stage 2: Helm Chart Structure Validation

Verify the chart follows the standard Helm directory structure:

bash scripts/validate_chart_structure.sh <chart-directory>

Expected structure:

mychart/
  Chart.yaml          # Chart metadata (required)
  values.yaml         # Default values (required)
  values.schema.json  # JSON Schema for values validation (optional)
  templates/          # Template directory (required)
    _helpers.tpl      # Template helpers (recommended)
    NOTES.txt         # Post-install notes (recommended)
    *.yaml            # Kubernetes manifest templates
  charts/             # Chart dependencies (optional)
  crds/               # Custom Resource Definitions (optional)
  .helmignore         # Files to ignore during packaging (optional)

Common issues caught:

  • Missing required files (Chart.yaml, values.yaml, templates/)
  • Invalid Chart.yaml syntax or missing required fields
  • Malformed values.schema.json
  • Incorrect file permissions

Stage 3: Helm Lint

Run Helm's built-in linter to catch chart-specific issues:

helm lint <chart-directory> --strict

Optional flags:

  • --values <values-file>: Test with specific values
  • --set key=value: Override specific values
  • --debug: Show detailed error information

Common issues caught:

  • Invalid Chart.yaml metadata
  • Template syntax errors
  • Missing or undefined values
  • Deprecated Kubernetes API versions
  • Chart best practice violations

Auto-fix approach:

  • For template errors, identify the problematic template file
  • Show the user the specific line causing issues
  • Propose a patch/diff for the fix
  • Apply fixes only if the user explicitly asks
  • Re-run helm lint after fixes are applied

Stage 4: Template Rendering

Render templates locally to verify they produce valid YAML:

helm template <release-name> <chart-directory> \
  --values <values-file> \
  --debug \
  --output-dir ./rendered

Options to consider:

  • --values values.yaml: Use specific values file
  • --set key=value: Override individual values
  • --show-only templates/deployment.yaml: Render specific template
  • --validate: Validate against Kubernetes OpenAPI schema
  • --include-crds: Include CRDs in rendered output
  • --is-upgrade: Simulate upgrade scenario
  • --kube-version 1.28.0: Target specific Kubernetes version

Common issues caught:

  • Template syntax errors (Go template issues)
  • Undefined variables or values
  • Type mismatches (string vs. integer)
  • Missing required values
  • Logic errors in conditionals or loops
  • Incorrect indentation in nested templates

For template errors:

  • Identify the template file and line number
  • Check if values are properly defined in values.yaml
  • Verify template function usage (quote, required, default, include, etc.)
  • Test with different value combinations

Stage 5: YAML Syntax Validation

Validate YAML syntax and formatting of rendered templates:

find ./rendered -type f \( -name "*.yaml" -o -name "*.yml" \) \
  -exec yamllint -c assets/.yamllint {} +

Common issues caught:

  • Indentation errors (tabs vs spaces)
  • Trailing whitespace
  • Line length violations
  • Syntax errors
  • Duplicate keys
  • Document start/end markers

Auto-fix approach:

  • For simple issues (indentation, trailing spaces), propose fixes using the Edit tool
  • For template-generated issues, fix the source template, not rendered output
  • Always show the user what will be changed before applying fixes

Stage 6: CRD Detection and Documentation Lookup

Before schema validation, detect if the chart contains or renders Custom Resource Definitions:

# Check crds/ directory
if [ -d <chart-directory>/crds ]; then
  find <chart-directory>/crds -type f \( -name "*.yaml" -o -name "*.yml" \) \
    -exec bash scripts/detect_crd_wrapper.sh {} +
fi

# Check rendered templates
find ./rendered -type f \( -name "*.yaml" -o -name "*.yml" \) \
  -exec bash scripts/detect_crd_wrapper.sh {} +

The script outputs JSON with resource information:

[
  {
    "kind": "Certificate",
    "apiVersion": "cert-manager.io/v1",
    "group": "cert-manager.io",
    "version": "v1",
    "isCRD": true,
    "name": "example-cert"
  }
]

For each detected CRD:

  1. Try context7 MCP first (preferred):

    Use mcp__context7__resolve-library-id with the CRD project name
    Example: "cert-manager" for cert-manager.io CRDs
             "prometheus-operator" for monitoring.coreos.com CRDs
             "istio" for networking.istio.io CRDs
    
    Then use mcp__context7__query-docs with:
    - libraryId from resolve step
    - query: The CRD kind and relevant features (e.g., "Certificate spec required fields")
    
  2. Fallback to web.search_query (web search) if Context7 fails:

    Search query pattern:
    "<kind>" "<group>" kubernetes CRD "<version>" documentation spec
    
    Example:
    "Certificate" "cert-manager.io" kubernetes CRD "v1" documentation spec
    "Prometheus" "monitoring.coreos.com" kubernetes CRD "v1" documentation spec
    
  3. Extract key information:

    • Required fields in spec
    • Field types and validation rules
    • Examples from documentation
    • Version-specific changes or deprecations
    • Common configuration patterns

Why this matters: CRDs have custom schemas not available in standard Kubernetes validation tools. Understanding the CRD's spec requirements prevents validation errors and ensures correct resource configuration.

Stage 7: Schema Validation

Validate rendered templates against Kubernetes schemas:

find ./rendered -type f \( -name "*.yaml" -o -name "*.yml" \) -exec \
  kubeconform \
    -schema-location default \
    -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
    -summary \
    -verbose \
    {} +

Options to consider:

  • Add -strict to reject unknown fields (recommended for production)
  • Add -ignore-missing-schemas if working with custom/internal CRDs
  • Add -kubernetes-version 1.28.0 to validate against specific K8s version
  • Add -output json for programmatic processing

Common issues caught:

  • Invalid apiVersion or kind
  • Missing required fields
  • Wrong field types
  • Invalid enum values
  • Unknown fields (with -strict)

For CRDs: If kubeconform reports "no schema found", this is expected. Use the documentation from Stage 6 to manually validate the spec fields.

Stage 7 success criteria (explicit):

  • ✅ Passed: kubeconform exits 0, and no invalid resources are reported.
  • ⚠️ Warning: only CRD schema-missing findings remain and Stage 6 documentation/manual verification is completed.
  • ❌ Failed: any non-CRD schema violation, parse error, or unresolved required-field/type error.

Stage 8: Cluster Dry-Run (if available)

If kubectl is configured and cluster access is available, perform a server-side dry-run:

# Test installation
helm install <release-name> <chart-directory> \
  --dry-run=server \
  --debug \
  --values <values-file>

# Test upgrade
helm upgrade <release-name> <chart-directory> \
  --dry-run=server \
  --debug \
  --values <values-file>

If the Helm version does not support --dry-run=server, use --dry-run and document that only client-side Helm simulation was executed.

This catches:

  • Admission controller rejections
  • Policy violations (PSP, OPA, Kyverno, etc.)
  • Resource quota violations
  • Missing namespaces
  • Invalid ConfigMap/Secret references
  • Webhook validations
  • Existing resource conflicts

If dry-run is not possible:

  • Use kubectl with rendered templates: kubectl apply --dry-run=server -f ./rendered/
  • Skip if no cluster access
  • Document that cluster-specific validation was skipped

For updates to existing releases:

helm diff upgrade <release-name> <chart-directory>

This shows what would change, helping catch unintended modifications. (Requires helm-diff plugin)

Stage 8 success criteria (explicit):

  • ✅ Passed: dry-run install and upgrade commands exit 0 with no admission/policy errors.
  • ⚠️ Warning: stage skipped because kubectl/cluster context/access is unavailable, or only client-side fallback was possible.
  • ❌ Failed: dry-run commands return non-zero due to admission webhooks, policy violations, namespace/quota errors, or reference errors.

Stage 9: Security Best Practices Check (MANDATORY)

IMPORTANT: This stage is MANDATORY. Analyze rendered templates for security best practices compliance.

Check rendered Deployment/Pod templates for:

  1. Missing securityContext - Look for pods/containers without security settings:

    # Check if pod-level securityContext exists
    spec:
      securityContext:
        runAsNonRoot: true
        runAsUser: 1000
        fsGroup: 2000
    
  2. Missing container securityContext - Each container should have:

    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      runAsNonRoot: true
      capabilities:
        drop:
          - ALL
    
  3. Missing resource limits/requests - Check for:

    resources:
      limits:
        cpu: "100m"
        memory: "128Mi"
      requests:
        cpu: "100m"
        memory: "128Mi"
    
  4. Image tag issues - Flag if using :latest or no tag

  5. Missing probes - Check for liveness/readiness probes

How to check: Read the rendered deployment YAML files and grep for these patterns:

# Check for securityContext
find ./rendered -type f \( -name "*.yaml" -o -name "*.yml" \) \
  -exec grep -l "securityContext" {} +

# Check for resources
find ./rendered -type f \( -name "*.yaml" -o -name "*.yml" \) \
  -exec grep -l "resources:" {} +

# Check for latest tag
find ./rendered -type f \( -name "*.yaml" -o -name "*.yml" \) \
  -exec grep "image:.*:latest" {} +

Stage 10: Final Report (MANDATORY)

IMPORTANT: This stage is MANDATORY even if all validations pass. You MUST complete ALL of the following actions.

Default behavior is read-only. Do not modify files unless the user explicitly asks you to apply fixes.

Step 1: Load Reference Files (MANDATORY when warnings exist)

If ANY warnings, errors, or security issues were found, you MUST read:

Read references/helm_best_practices.md
Read references/k8s_best_practices.md

Use these references to provide context and recommendations for each issue found.

Step 2: Present Validation Summary

Always present a validation summary formatted as a table showing:

  • Each validation stage executed (Stages 1-9)
  • Status of each stage (✅ Passed, ⚠️ Warning, ❌ Failed)
  • Count of issues found per stage

Example:

| Stage | Status | Issues |
|-------|--------|--------|
| 1. Tool Check | ✅ Passed | All tools available |
| 2. Structure | ⚠️ Warning | Missing: .helmignore, NOTES.txt |
| 3. Helm Lint | ✅ Passed | 0 errors |
| 4. Template Render | ✅ Passed | 5 templates rendered |
| 5. YAML Syntax | ✅ Passed | No yamllint errors |
| 6. CRD Detection | ✅ Passed | 1 CRD documented |
| 7. Schema Validation | ✅ Passed | All resources valid |
| 8. Dry-Run | ✅ Passed | No cluster errors |
| 9. Security Check | ⚠️ Warning | Missing securityContext |

Step 3: Categorize All Issues

Group findings by severity:

❌ Errors (must fix):

  • Template syntax errors
  • Missing required fields
  • Schema validation failures
  • Dry-run failures

⚠️ Warnings (should fix):

  • Deprecated Kubernetes APIs
  • Missing securityContext
  • Missing resource limits/requests
  • Using :latest image tag
  • Missing recommended files (_helpers.tpl, .helmignore, NOTES.txt)

ℹ️ Info (recommendations):

  • Missing values.schema.json
  • Missing README.md
  • Optimization opportunities

Step 4: List Proposed Changes (DO NOT APPLY)

For each issue, provide a proposed fix with:

  • File path and line number (if applicable)
  • Before/after code blocks
  • Explanation of why this change is recommended

Example format:

## Proposed Changes

### 1. Add securityContext to Deployment
**File:** templates/deployment.yaml:25
**Severity:** ⚠️ Warning
**Reason:** Running containers as root is a security risk

**Current:**
```yaml
spec:
  containers:
    - name: app
      image: nginx:1.21

Proposed:

spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
  containers:
    - name: app
      image: nginx:1.21
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL

2. Add .helmignore file

File: .helmignore (new file) Severity: ⚠️ Warning Reason: Excludes unnecessary files from chart packaging

Proposed: Copy from assets/.helmignore


#### Step 5: Automation Opportunities

List all detected automation opportunities:
- If `_helpers.tpl` is missing → Recommend: `bash scripts/generate_helpers.sh <chart>`
- If `.helmignore` is missing → Recommend: Copy from `assets/.helmignore`
- If `values.schema.json` is missing → Recommend: Copy and customize from `assets/values.schema.json`
- If `NOTES.txt` is missing → Recommend: Create post-install notes template
- If `README.md` is missing → Recommend: Create chart documentation

#### Step 6: Final Summary

Provide a final summary:

Validation Summary

Chart: Status: ⚠️ Warnings Found (or ✅ Ready for Deployment)

Issues Found:

  • Errors: X
  • Warnings: Y
  • Info: Z

Proposed Changes: N changes recommended

Next Steps:

  1. Review proposed changes above
  2. Apply changes manually or use helm-generator skill
  3. Re-run validation to confirm fixes

## Workflow Done Criteria

Validation is complete only when all of the following are true:
- A Stage 1 to Stage 10 status table is present with `✅ Passed`, `⚠️ Warning`, `❌ Failed`, or `⏭️ Skipped` for each stage.
- Every skipped stage includes a concrete tool or environment reason.
- Stage 7 and Stage 8 are evaluated against their explicit success criteria above.
- Severity totals are reported (`Errors`, `Warnings`, `Info`) with proposed remediation actions.
- Role boundary is respected: no file edits unless explicitly requested by the user.

## Helm Templating Automation & Best Practices

This section covers advanced Helm templating techniques, helper functions, and automation strategies.

### Template Helpers (`_helpers.tpl`)

Template helpers are reusable functions defined in `templates/_helpers.tpl`. They promote DRY principles and consistency.

**Standard helper patterns:**

1. **Chart name helper:**
```yaml
{{/*
Expand the name of the chart.
*/}}
{{- define "mychart.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
  1. Fullname helper:
{{/*
Create a default fully qualified app name.
*/}}
{{- define "mychart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
  1. Chart reference helper:
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "mychart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
  1. Standard labels helper:
{{/*
Common labels
*/}}
{{- define "mychart.labels" -}}
helm.sh/chart: {{ include "mychart.chart" . }}
{{ include "mychart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
  1. Selector labels helper:
{{/*
Selector labels
*/}}
{{- define "mychart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "mychart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
  1. ServiceAccount name helper:
{{/*
Create the name of the service account to use
*/}}
{{- define "mychart.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "mychart.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

When to create helpers:

  • Values used in multiple templates
  • Complex logic that's repeated
  • Label sets that should be consistent
  • Name generation patterns
  • Conditional resource inclusion

Essential Template Functions

Reference and use these Helm template functions for robust charts:

  1. required - Enforce required values:
apiVersion: v1
kind: Service
metadata:
  name: {{ required "A valid service name is required!" .Values.service.name }}
  1. default - Provide fallback values:
replicas: {{ .Values.replicaCount | default 1 }}
  1. quote - Safely quote string values:
env:
  - name: DATABASE_HOST
    value: {{ .Values.database.host | quote }}
  1. include - Use helpers with pipeline:
metadata:
  labels:
    {{- include "mychart.labels" . | nindent 4 }}
  1. tpl - Render strings as templates:
{{- tpl .Values.customConfig . }}
  1. toYaml - Convert objects to YAML:
{{- with .Values.resources }}
resources:
  {{- toYaml . | nindent 2 }}
{{- end }}
  1. fromYaml - Parse YAML strings:
{{- $config := .Values.configYaml | fromYaml }}
  1. merge - Merge maps:
{{- $merged := merge .Values.override .Values.defaults }}
  1. lookup - Query cluster resources (use carefully):
{{- $secret := lookup "v1" "Secret" .Release.Namespace "my-secret" }}
{{- if $secret }}
  # Secret exists, use it
{{- else }}
  # Create new secret
{{- end }}

Advanced Template Patterns

  1. Conditional resource creation:
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
# ... ingress definition
{{- end }}
  1. Range over lists:
{{- range .Values.extraEnvVars }}
- name: {{ .name }}
  value: {{ .value | quote }}
{{- end }}
  1. Range over maps:
{{- range $key, $value := .Values.configMap }}
{{ $key }}: {{ $value | quote }}
{{- end }}
  1. With blocks for scoping:
{{- with .Values.nodeSelector }}
nodeSelector:
  {{- toYaml . | nindent 2 }}
{{- end }}
  1. Named templates with custom context:
{{- include "mychart.container" (dict "root" . "container" .Values.mainContainer) }}

Values Structure Best Practices

Prefer flat structures when possible:

# Good - Flat structure
serverName: nginx
serverPort: 80

# Acceptable - Nested structure for related settings
server:
  name: nginx
  port: 80
  replicas: 3

Always provide defaults in values.yaml:

replicaCount: 1

image:
  repository: nginx
  pullPolicy: IfNotPresent
  tag: "1.21.0"

service:
  type: ClusterIP
  port: 80

resources:
  limits:
    cpu: 100m
    memory: 128Mi
  requests:
    cpu: 100m
    memory: 128Mi

Document all values:

# replicaCount is the number of pod replicas for the deployment
replicaCount: 1

# image configures the container image
image:
  # image.repository is the container image registry and name
  repository: nginx
  # image.tag overrides the image tag (default is chart appVersion)
  tag: "1.21.0"

Template Comments and Documentation

Use Helm template comments for documentation:

{{- /*
mychart.fullname generates the fullname for resources.
It supports nameOverride and fullnameOverride values.
Usage: {{ include "mychart.fullname" . }}
*/ -}}
{{- define "mychart.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}

Use YAML comments for user-facing notes:

# WARNING: Changing the storage class will not migrate existing data
storageClass: "standard"

Whitespace Management

Use - to chomp whitespace in template directives:

{{- if .Values.enabled }}
  # Remove leading whitespace
{{- end }}

{{ .Values.name -}}
  # Remove trailing whitespace

Good formatting:

{{- if .Values.enabled }}
  key: value
{{- end }}

Bad formatting:

{{if .Values.enabled}}
key: value
{{end}}

Helper Patterns Reference

When analyzing charts, identify opportunities for helper functions:

  1. Identify repetition:

    • Same label sets across resources
    • Repeated name generation logic
    • Common conditional patterns
  2. Common helper patterns to recommend:

    • Chart name helper (.name)
    • Fullname helper (.fullname)
    • Chart version label (.chart)
    • Common labels (.labels)
    • Selector labels (.selectorLabels)
    • ServiceAccount name (.serviceAccountName)
  3. When to recommend helpers:

    • Missing _helpers.tpl file
    • Repeated code patterns across templates
    • Inconsistent label usage
    • Long resource names that need truncation

Best Practices Reference

For detailed Helm and Kubernetes best practices, load the references:

Read references/helm_best_practices.md
Read references/k8s_best_practices.md

These references include:

  • Chart structure and metadata
  • Template conventions and patterns
  • Values file organization
  • Security best practices
  • Resource limits and requests
  • Common validation issues and fixes

When to load: When validation reveals issues that need context, when implementing new features, or when the user asks about best practices.

Working with Chart Dependencies

When a chart has dependencies (in Chart.yaml or charts/ directory):

  1. Update dependencies:
helm dependency update <chart-directory>
  1. List dependencies:
helm dependency list <chart-directory>
  1. Validate dependencies:

    • Check that dependency versions are available
    • Verify dependency values are properly scoped
    • Test templates with dependency resources
  2. Override dependency values:

# values.yaml
postgresql:
  enabled: true
  postgresqlPassword: "secret"
  persistence:
    size: 10Gi

Error Handling Strategies

Tool Not Available

  • Run scripts/setup_tools.sh to check availability
  • Provide installation instructions
  • Skip optional stages but document what was skipped
  • Continue with available tools

Template Rendering Errors

  • Show the specific template file and line number
  • Check if values are defined in values.yaml
  • Verify template function syntax
  • Test with simpler value combinations
  • Use --debug flag for detailed error messages

Cluster Access Issues

  • Fall back to client-side validation
  • Use rendered templates with kubectl
  • Skip cluster validation if no kubectl config
  • Document limitations in validation report

CRD Documentation Not Found

  • Document that documentation lookup failed
  • Attempt validation with kubeconform CRD schemas
  • Suggest manual CRD inspection:
    kubectl get crd <crd-name>.group -o yaml
    kubectl explain <kind>
    

Validation Stage Failures

  • Continue to next stage even if one fails
  • Collect all errors before presenting to user
  • Prioritize fixing Helm lint errors first
  • Then fix template errors
  • Finally fix schema/validation errors

macOS Extended Attributes Issue

Symptom: Helm reports "Chart.yaml file is missing" even though the file exists and is readable.

Cause: On macOS, files created programmatically (via Write tool, scripts, or certain editors) may have extended attributes (e.g., com.apple.provenance, com.apple.quarantine) that interfere with Helm's file detection.

Diagnosis:

# Check for extended attributes
xattr /path/to/chart/Chart.yaml

# If attributes are present, you'll see output like:
# com.apple.provenance
# com.apple.quarantine

Solutions:

  1. Remove extended attributes:

    # Remove all extended attributes from a file
    xattr -c /path/to/chart/Chart.yaml
    
    # Remove all extended attributes recursively from chart directory
    xattr -cr /path/to/chart/
    
  2. Create files using shell commands instead:

    # Use cat with heredoc instead of direct file writes
    cat > Chart.yaml << 'EOF'
    apiVersion: v2
    name: mychart
    version: 0.1.0
    EOF
    
  3. Copy from helm-created chart:

    # Create a fresh chart and copy structure
    helm create temp-chart
    cp -r temp-chart/* /path/to/your/chart/
    rm -rf temp-chart
    

Prevention: When creating new chart files on macOS, prefer using helm create as a base or use shell heredocs (cat > file << 'EOF') rather than direct file creation tools.

Communication Guidelines

When presenting validation results and fixes:

  1. Be clear and concise about what was found
  2. Explain why issues matter (e.g., "This will cause pod creation to fail")
  3. Provide context from Helm best practices when relevant
  4. Group related issues (e.g., all missing helper issues together)
  5. Use file:line references when available
  6. Show confidence level for auto-fixes (high confidence = syntax, low = logic changes)
  7. Always provide a summary after proposing fixes (and after applying fixes when explicitly requested) including:
    • What was changed and why
    • File and line references for each fix
    • Total count of issues resolved
    • Final validation status
    • Any remaining warnings or recommendations

Version Awareness

Always consider Kubernetes and Helm version compatibility:

  • Check for deprecated Kubernetes APIs
  • Ensure Helm chart apiVersion is v2 (for Helm 3+)
  • For CRDs, ensure the apiVersion matches what's in the cluster
  • Use kubectl api-versions to list available API versions
  • Reference version-specific documentation when available
  • Set kubeVersion constraint in Chart.yaml if needed

Chart Testing

For comprehensive testing, use Helm test resources:

  1. Create test resources:
# templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
  name: "{{ include "mychart.fullname" . }}-test-connection"
  annotations:
    "helm.sh/hook": test
spec:
  containers:
    - name: wget
      image: busybox
      command: ['wget']
      args: ['{{ include "mychart.fullname" . }}:{{ .Values.service.port }}']
  restartPolicy: Never
  1. Run tests:
helm test <release-name>

Automation Opportunities Reference

During Stage 10 (Final Report), list all detected automation opportunities in the summary.

Do NOT ask user questions or modify files. Simply list recommendations.

Automation opportunities to detect and list:

Missing Item Recommendation
_helpers.tpl Run: bash scripts/generate_helpers.sh <chart>
.helmignore Copy from: assets/.helmignore
values.schema.json Copy and customize from: assets/values.schema.json
NOTES.txt Create post-install notes template
README.md Create chart documentation
Repeated patterns Extract to helper functions

Security recommendations to include when issues found:

Issue Recommendation
Missing pod securityContext Add runAsNonRoot: true, runAsUser: 1000, fsGroup: 2000
Missing container securityContext Add allowPrivilegeEscalation: false, readOnlyRootFilesystem: true, capabilities.drop: [ALL]
Missing resource limits Add CPU/memory limits and requests
Using :latest tag Pin to specific image version
Missing probes Add liveness and readiness probes

Template improvement recommendations:

Issue Recommendation
Using template instead of include Replace with include for pipeline support
Missing nindent Add nindent for proper YAML indentation
No default values Add default function for optional values
Missing required function Add required for critical values

Resources

scripts/

setup_tools.sh

  • Checks for required validation tools (helm, yamllint, kubeconform, kubectl)
  • Provides installation instructions for missing tools
  • Verifies versions of installed tools
  • Usage: bash scripts/setup_tools.sh

validate_chart_structure.sh

  • Validates Helm chart directory structure
  • Checks for required files (Chart.yaml, values.yaml, templates/)
  • Verifies file formats and syntax
  • Usage: bash scripts/validate_chart_structure.sh <chart-directory>

detect_crd_wrapper.sh

  • Wrapper script that handles Python dependency management
  • Automatically creates temporary venv if PyYAML is not available
  • Calls detect_crd.py to parse YAML files
  • Usage: bash scripts/detect_crd_wrapper.sh <file.yaml> [file2.yaml ...]

detect_crd.py

  • Parses YAML files to identify Custom Resource Definitions
  • Extracts kind, apiVersion, group, and version information
  • Outputs JSON for programmatic processing
  • Requires PyYAML (handled automatically by wrapper script)
  • Can be called directly: python3 scripts/detect_crd.py <file.yaml> [file2.yaml ...]

generate_helpers.sh

  • Generates standard Helm helpers (_helpers.tpl) for a chart
  • Creates fullname, labels, and selector helpers
  • Usage: bash scripts/generate_helpers.sh <chart-directory>

references/

helm_best_practices.md

  • Comprehensive guide to Helm chart best practices
  • Covers template patterns, helper functions, values structure
  • Common validation issues and how to fix them
  • Security and performance recommendations
  • Load when providing context for Helm-specific issues

k8s_best_practices.md

  • Comprehensive guide to Kubernetes YAML best practices
  • Covers metadata, labels, resource limits, security context
  • Common validation issues and how to fix them
  • Load when providing context for Kubernetes-specific issues

template_functions.md

  • Reference guide for Helm template functions
  • Examples of all built-in functions
  • Sprig function library reference
  • Custom function patterns
  • Load when implementing complex templates

assets/

.helmignore

  • Standard .helmignore file for excluding files from packaging
  • Pre-configured with common patterns

.yamllint

  • Pre-configured yamllint rules for Kubernetes YAML
  • Follows Kubernetes conventions (2-space indentation, line length, etc.)
  • Can be customized per project
  • Usage: yamllint -c assets/.yamllint <file.yaml>

values.schema.json

  • Example JSON Schema for values validation
  • Can be copied and customized for specific charts
  • Provides type safety and validation
用于生成生产级Jenkinsfile,支持声明式、脚本式及共享库。根据场景自动选择模板,遵循最佳实践,并集成验证器确保代码质量,适用于CI/CD流水线构建与部署。
生成Maven/Gradle/npm的CI流水线 创建带审批的Jenkins部署流水线 构建含并行测试阶段的Jenkinsfile 创建具有动态阶段逻辑的脚本式流水线 脚手架化Jenkins共享库 为Docker或Kubernetes代理生成Jenkinsfile
devops-skills-plugin/skills/jenkinsfile-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill jenkinsfile-generator -g -y
SKILL.md
Frontmatter
{
    "name": "jenkinsfile-generator",
    "description": "Generate\/create\/scaffold Jenkinsfile — declarative, scripted, shared library, CI\/CD pipelines."
}

Jenkinsfile Generator Skill

Generate production-ready Jenkinsfiles following best practices. All generated files are validated using devops-skills:jenkinsfile-validator skill.

Trigger Phrases

  • "Generate a CI pipeline for Maven/Gradle/npm"
  • "Create a Jenkins deployment pipeline with approvals"
  • "Build a Jenkinsfile with parallel test stages"
  • "Create a scripted pipeline with dynamic stage logic"
  • "Scaffold a Jenkins shared library"
  • "Generate a Jenkinsfile for Docker or Kubernetes agents"

When to Use

  • Creating new Jenkinsfiles (declarative or scripted)
  • CI/CD pipelines, Docker/Kubernetes deployments
  • Parallel execution, matrix builds, parameterized pipelines
  • DevSecOps pipelines with security scanning
  • Shared library scaffolding

Declarative vs Scripted Decision Tree

  1. Choose Declarative by default when stage order and behavior are mostly static.
  2. Choose Scripted when runtime-generated stages, complex loops, or dynamic control flow are required.
  3. Choose Shared Library scaffolding when request is about reusable pipeline functions (vars/, src/, resources/).
  4. If unsure, start Declarative and only switch to Scripted if requirements cannot be expressed cleanly.

Template Map

Template Path Use When
Declarative basic assets/templates/declarative/basic.Jenkinsfile Standard CI/CD with predictable stages
Declarative parallel example examples/declarative-parallel.Jenkinsfile Parallel test/build branches with fail-fast behavior
Declarative kubernetes example examples/declarative-kubernetes.Jenkinsfile Kubernetes agent execution using pod templates
Scripted basic assets/templates/scripted/basic.Jenkinsfile Complex conditional logic or generated stages
Shared library scaffold Generated by scripts/generate_shared_library.py Reusable pipeline functions and organization-wide patterns

Quick Reference

// Minimal Declarative Pipeline
pipeline {
    agent any
    stages {
        stage('Build') { steps { sh 'make' } }
        stage('Test') { steps { sh 'make test' } }
    }
}

// Error-tolerant stage
stage('Flaky Tests') {
    steps {
        catchError(buildResult: 'SUCCESS', stageResult: 'UNSTABLE') {
            sh 'run-flaky-tests.sh'
        }
    }
}

// Conditional deployment with approval
stage('Deploy') {
    when { branch 'main'; beforeAgent true }
    input { message 'Deploy to production?' }
    steps { sh './deploy.sh' }
}
Option Purpose
timeout(time: 1, unit: 'HOURS') Prevent hung builds
buildDiscarder(logRotator(numToKeepStr: '10')) Manage disk space
disableConcurrentBuilds() Prevent race conditions
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') Continue on error

Core Capabilities

1. Declarative Pipelines (RECOMMENDED)

Process:

  1. Read templates for structure reference:
    • Read assets/templates/declarative/basic.Jenkinsfile to understand the standard structure
    • Templates show the expected sections: pipeline → agent → environment → options → parameters → stages → post
    • For complex requests, adapt the structure rather than copying verbatim
  2. Consult reference documentation:
    • Read references/best_practices.md for performance, security, and reliability patterns
    • Read references/common_plugins.md for plugin-specific syntax
  3. Generate with required elements:
    • Proper stages with descriptive names
    • Environment block with credentials binding (never hardcode secrets)
    • Options: timeout, buildDiscarder, timestamps, disableConcurrentBuilds
    • Post conditions: always (cleanup), success (artifacts), failure (notifications)
    • Always add failFast true or parallelsAlwaysFailFast() for parallel blocks
    • Always include fingerprint: true when using archiveArtifacts
  4. ALWAYS validate using devops-skills:jenkinsfile-validator skill

2. Scripted Pipelines

When: Complex conditional logic, dynamic generation, full Groovy control Process:

  1. Read templates for structure reference:
    • Read assets/templates/scripted/basic.Jenkinsfile for node/stage patterns
    • Understand try-catch-finally structure for error handling
  2. Implement try-catch-finally for error handling
  3. ALWAYS validate using devops-skills:jenkinsfile-validator skill

3. Parallel/Matrix Pipelines

Use parallel {} block or matrix {} with axes {} for multi-dimensional builds.

  • Default behavior is fail-fast for generated parallel pipelines (parallelsAlwaysFailFast() or stage-level failFast true).

4. Security Scanning (DevSecOps)

Add SonarQube, OWASP Dependency-Check, Trivy stages with fail thresholds.

5. Shared Library Scaffolding

python3 scripts/generate_shared_library.py --name my-library --package org.example

Declarative Syntax Reference

Agent Types

agent any                                    // Any available agent
agent { label 'linux && docker' }           // Label-based
agent { docker { image 'maven:3.9.11-eclipse-temurin-21' } }
agent { kubernetes { yaml '...' } }         // K8s pod template
agent { kubernetes { yamlFile 'pod.yaml' } } // External YAML

Environment & Credentials

environment {
    VERSION = '1.0.0'
    AWS_KEY = credentials('aws-key-id')     // Creates _USR and _PSW vars
}

Options

options {
    buildDiscarder(logRotator(numToKeepStr: '10'))
    timeout(time: 1, unit: 'HOURS')
    disableConcurrentBuilds()
    timestamps()
    parallelsAlwaysFailFast()
    durabilityHint('PERFORMANCE_OPTIMIZED')  // 2-6x faster for simple pipelines
}

Parameters

parameters {
    string(name: 'VERSION', defaultValue: '1.0.0')
    choice(name: 'ENV', choices: ['dev', 'staging', 'prod'])
    booleanParam(name: 'SKIP_TESTS', defaultValue: false)
}

When Conditions

Condition Example
branch branch 'main' or branch pattern: 'release/*', comparator: 'GLOB'
tag tag pattern: 'v*', comparator: 'GLOB'
changeRequest changeRequest target: 'main'
changeset changeset 'src/**/*.java'
expression expression { env.DEPLOY == 'true' }
allOf/anyOf/not Combine conditions

Add beforeAgent true to skip agent allocation if condition fails.

Error Handling

catchError(buildResult: 'UNSTABLE', stageResult: 'FAILURE') { sh '...' }
warnError('msg') { sh '...' }      // Mark UNSTABLE but continue
unstable(message: 'Coverage low')   // Explicit UNSTABLE
error('Config missing')             // Fail without stack trace

Post Section

post {
    always { junit '**/target/*.xml'; cleanWs() }
    success { archiveArtifacts artifacts: '**/*.jar', fingerprint: true }
    failure { slackSend color: 'danger', message: 'Build failed' }
    fixed { echo 'Build fixed!' }
}

Order: always → changed → fixed → regression → failure → success → unstable → cleanup

NOTE: Always use fingerprint: true with archiveArtifacts for build traceability and artifact tracking.

Parallel & Matrix

IMPORTANT: Always ensure parallel blocks fail fast on first failure using one of these approaches:

Option 1: Global (RECOMMENDED) - Use parallelsAlwaysFailFast() in pipeline options:

options {
    parallelsAlwaysFailFast()  // Applies to ALL parallel blocks in pipeline
}

This is the preferred approach as it covers all parallel blocks automatically.

Option 2: Per-block - Use failFast true on individual parallel stages:

stage('Tests') {
    failFast true  // Only affects this parallel block
    parallel {
        stage('Unit') { steps { sh 'npm test:unit' } }
        stage('E2E') { steps { sh 'npm test:e2e' } }
    }
}

NOTE: When parallelsAlwaysFailFast() is set in options, explicit failFast true on individual parallel blocks is redundant.

stage('Matrix') {
    failFast true
    matrix {
        axes {
            axis { name 'PLATFORM'; values 'linux', 'windows' }
            axis { name 'BROWSER'; values 'chrome', 'firefox' }
        }
        excludes { exclude { axis { name 'PLATFORM'; values 'linux' }; axis { name 'BROWSER'; values 'safari' } } }
        stages { stage('Test') { steps { echo "Testing ${PLATFORM}/${BROWSER}" } } }
    }
}

Input (Manual Approval)

stage('Deploy') {
    input { message 'Deploy?'; ok 'Deploy'; submitter 'admin,ops' }
    steps { sh './deploy.sh' }
}

IMPORTANT: Place input outside steps to avoid holding agents.

Scripted Syntax Reference

node('agent-label') {
    try {
        stage('Build') { sh 'make build' }
        stage('Test') { sh 'make test' }
    } catch (Exception e) {
        currentBuild.result = 'FAILURE'
        throw e
    } finally {
        deleteDir()
    }
}

// Parallel
parallel(
    'Unit': { node { sh 'npm test:unit' } },
    'E2E': { node { sh 'npm test:e2e' } }
)

// Environment
withEnv(['VERSION=1.0.0']) { sh 'echo $VERSION' }
withCredentials([string(credentialsId: 'key', variable: 'KEY')]) { sh 'curl -H "Auth: $KEY" ...' }

@NonCPS for Non-Serializable Operations

@NonCPS
def parseJson(String json) {
    new groovy.json.JsonSlurper().parseText(json)
}

Rules: No pipeline steps (sh, echo) inside @NonCPS. Use for JsonSlurper, iterators, regex Matchers.

Docker & Kubernetes

Docker Agent

agent { docker { image 'maven:3.9.11'; args '-v $HOME/.m2:/root/.m2'; reuseNode true } }

Build & Push

def img = docker.build("myapp:${BUILD_NUMBER}")
docker.withRegistry('https://registry.example.com', 'creds') { img.push(); img.push('latest') }

Kubernetes Pod

agent {
    kubernetes {
        yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: maven
    image: maven:3.9.11-eclipse-temurin-21
    command: [sleep, 99d]
'''
    }
}
// Use: container('maven') { sh 'mvn package' }

Shared Libraries

@Library('my-shared-library') _
// or dynamically: library 'my-library@1.0.0'

// vars/log.groovy
def info(msg) { echo "INFO: ${msg}" }

// Usage
log.info 'Starting build'

Validation Workflow

CRITICAL: ALWAYS validate using devops-skills:jenkinsfile-validator skill:

  1. Generate Jenkinsfile
  2. Invoke devops-skills:jenkinsfile-validator skill
  3. Handle validation results by severity:
    • ERRORS: MUST fix before presenting to user - these break the pipeline
    • WARNINGS: SHOULD fix - these indicate potential issues
    • INFO/SUGGESTIONS: Consider applying based on use case:
      • failFast true for parallel blocks → apply by default
      • Build triggers → ask user if they want automated builds
      • Other optimizations → apply if they improve the pipeline
  4. Re-validate after fixes
  5. Only present validated Jenkinsfiles to user

Validation commands:

# Full validation (syntax + security + best practices)
bash ../jenkinsfile-validator/scripts/validate_jenkinsfile.sh Jenkinsfile

# Syntax only (fastest)
bash ../jenkinsfile-validator/scripts/validate_jenkinsfile.sh --syntax-only Jenkinsfile

Generator Scripts

When to use scripts vs manual generation:

  • Use scripts for: Simple, standard pipelines with common patterns (basic CI, straightforward CD)
  • Use manual generation for: Complex pipelines with multiple features (parallel tests + security scanning + Docker + K8s deployments), custom logic, or non-standard requirements

Script Arguments: Required vs Optional

  • generate_declarative.py
  • Required: --output
  • Optional: --stages, --agent, --build-tool, --build-cmd, --test-cmd, --deploy-*, --notification-*, --archive-artifacts, --k8s-yaml
  • Notes:
  • --k8s-yaml accepts either inline YAML content or a path to an existing .yaml/.yml file.
  • Stage keys are validated ([a-z0-9_-]) and shell commands are emitted as escaped Groovy literals.
  • generate_scripted.py
  • Required: --output
  • Optional: stage/agent/SCM/notification parameters depending on requested pipeline features.
  • generate_shared_library.py
  • Required: --name
  • Optional: --package, --output
  • Shared library deployment helper now includes explicit rollout target (deployment/<name>) and notification helper emits valid HTML email bodies.
# Declarative (simple pipelines)
python3 scripts/generate_declarative.py --output Jenkinsfile --stages build,test,deploy --agent docker

# Scripted (simple pipelines)
python3 scripts/generate_scripted.py --output Jenkinsfile --stages build,test --agent label:linux

# Shared Library (always use script for scaffolding)
python3 scripts/generate_shared_library.py --name my-library --package com.example

Done Criteria

  • Pipeline style selection (Declarative vs Scripted) is explicit and justified.
  • Generated Jenkinsfiles pass smoke validation with executable validator commands.
  • Parallel pipelines are fail-fast by default unless user explicitly requests otherwise.
  • Custom stage names and shell commands are safely emitted (no unescaped Groovy literals).
  • --k8s-yaml works with both inline YAML and existing file paths.
  • Notification-enabled post blocks still archive artifacts when requested.

Plugin Documentation Lookup

Always consult Context7 or WebSearch for:

  • Plugins NOT covered in references/common_plugins.md
  • Version-specific documentation requests
  • Complex plugin configurations or advanced options
  • When user explicitly asks for latest documentation

May skip external lookup when:

  • Using basic plugin syntax already documented in references/common_plugins.md
  • Simple, well-documented plugin steps (e.g., basic sh, checkout scm, junit)

Plugins covered in common_plugins.md: Git, Docker, Kubernetes, Credentials, JUnit, Slack, SonarQube, OWASP Dependency-Check, Email, AWS, Azure, HTTP Request, Microsoft Teams, Nexus, Artifactory, GitHub

Lookup methods (in order of preference):

  1. Context7: mcp__context7__resolve-library-id with /jenkinsci/<plugin-name>-plugin
  2. WebSearch: Jenkins [plugin-name] plugin documentation 2025
  3. Official: plugins.jenkins.io, jenkins.io/doc/pipeline/steps/

References

  • references/best_practices.md - Performance, security, reliability patterns
  • references/common_plugins.md - Git, Docker, K8s, credentials, notifications
  • assets/templates/ - Declarative and scripted templates
  • devops-skills:jenkinsfile-validator skill - Syntax and best practices validation

Always prefer Declarative unless scripted flexibility is required.

用于验证、检查和审计 Jenkinsfile 及共享库。支持声明式和脚本式管道,检测语法错误、硬编码凭证、安全问题及最佳实践,并提供多种验证模式选项。
Validate this Jenkinsfile Check this pipeline for security issues Lint my Declarative/Scripted pipeline Why is this Jenkins pipeline failing syntax checks? Validate vars/*.groovy or src/**/*.groovy shared library files
devops-skills-plugin/skills/jenkinsfile-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill jenkinsfile-validator -g -y
SKILL.md
Frontmatter
{
    "name": "jenkinsfile-validator",
    "description": "Validate, lint, audit, or check Jenkinsfiles and shared libraries."
}

Jenkinsfile Validator Skill

Use this skill to validate Jenkins pipelines and shared libraries with local scripts first, then optionally enrich findings with plugin documentation.

Trigger Phrases

Use this skill when requests look like:

  • "Validate this Jenkinsfile"
  • "Check this pipeline for security issues"
  • "Lint my Declarative/Scripted pipeline"
  • "Why is this Jenkins pipeline failing syntax checks?"
  • "Validate vars/.groovy or src/**/.groovy shared library files"

Scope

This skill validates:

  • Declarative pipelines (pipeline { ... })
  • Scripted pipelines (node { ... } and Groovy-style pipelines)
  • Shared library files (vars/*.groovy, src/**/*.groovy)
  • Hardcoded credential patterns
  • Pipeline best practices and maintainability signals

Prerequisites

Run commands from repository root unless noted.

Required tools

  • bash
  • grep
  • sed
  • awk
  • head
  • wc
  • find (needed for shared-library directory scans)

Recommended tools

  • jq (optional; improves JSON-heavy troubleshooting workflows)

Script prerequisites

  • Scripts live in devops-skills-plugin/skills/jenkinsfile-validator/scripts/
  • Main orchestrator can run child scripts even if +x is missing (it uses bash fallback)
  • If you want direct execution (./script.sh), make scripts executable:
chmod +x devops-skills-plugin/skills/jenkinsfile-validator/scripts/*.sh

Preflight check (recommended)

SKILL_DIR="devops-skills-plugin/skills/jenkinsfile-validator"

command -v bash grep sed awk head wc find >/dev/null && echo "required tools: ok" || echo "required tools: missing"
command -v jq >/dev/null && echo "jq: installed (optional)" || echo "jq: missing (optional)"

[ -d "$SKILL_DIR/scripts" ] && echo "scripts dir: ok" || echo "scripts dir: missing"
[ -f "$SKILL_DIR/scripts/validate_jenkinsfile.sh" ] && echo "main validator: ok" || echo "main validator: missing"

Quick Start (Normalized Paths)

Use a single base path variable to avoid path ambiguity.

SKILL_DIR="devops-skills-plugin/skills/jenkinsfile-validator"
TARGET_JENKINSFILE="Jenkinsfile"

# Full validation (recommended)
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" "$TARGET_JENKINSFILE"

Common options

SKILL_DIR="devops-skills-plugin/skills/jenkinsfile-validator"
TARGET_JENKINSFILE="Jenkinsfile"

bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" --syntax-only "$TARGET_JENKINSFILE"
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" --security-only "$TARGET_JENKINSFILE"
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" --best-practices "$TARGET_JENKINSFILE"
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" --no-security "$TARGET_JENKINSFILE"
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" --no-best-practices "$TARGET_JENKINSFILE"
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" --strict "$TARGET_JENKINSFILE"
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" --assume-declarative "$TARGET_JENKINSFILE"
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" --assume-scripted "$TARGET_JENKINSFILE"

Shared library validation

SKILL_DIR="devops-skills-plugin/skills/jenkinsfile-validator"

bash "$SKILL_DIR/scripts/validate_shared_library.sh" vars/myStep.groovy
bash "$SKILL_DIR/scripts/validate_shared_library.sh" vars/
bash "$SKILL_DIR/scripts/validate_shared_library.sh" src/
bash "$SKILL_DIR/scripts/validate_shared_library.sh" /path/to/shared-library

Regression and local CI checks

SKILL_DIR="devops-skills-plugin/skills/jenkinsfile-validator"
bash "$SKILL_DIR/tests/run_local_ci.sh"

run_local_ci.sh is the supported local/CI entrypoint for regression coverage. It runs:

  • bash -n syntax checks for all scripts/*.sh and tests/*.sh files
  • tests/test_validate_jenkinsfile.sh regression scenarios

Deterministic Validation Flow

1) Detect pipeline type

  • pipeline { => Declarative validator
  • node (...) or node { => Scripted validator
  • Unknown => fails closed by default (ERROR [TypeDetection])
  • Override intentionally ambiguous files with --assume-declarative or --assume-scripted

2) Run syntax validation

  • Declarative: validate_declarative.sh
  • Scripted: validate_scripted.sh

3) Run security scan

  • common_validation.sh check_credentials

4) Run best practices check

  • best_practices.sh

5) Aggregate and return final status

  • Unified summary with pass/fail per phase and final exit code

6) Run regression suite after script changes

  • bash tests/run_local_ci.sh
  • Intended for both local pre-commit checks and CI job wiring

Individual Script Commands (Advanced)

SKILL_DIR="devops-skills-plugin/skills/jenkinsfile-validator"
TARGET_JENKINSFILE="Jenkinsfile"

# Type detection
bash "$SKILL_DIR/scripts/common_validation.sh" detect_type "$TARGET_JENKINSFILE"

# Syntax-only by type
bash "$SKILL_DIR/scripts/validate_declarative.sh" "$TARGET_JENKINSFILE"
bash "$SKILL_DIR/scripts/validate_scripted.sh" "$TARGET_JENKINSFILE"

# Security-only
bash "$SKILL_DIR/scripts/common_validation.sh" check_credentials "$TARGET_JENKINSFILE"

# Best-practices-only
bash "$SKILL_DIR/scripts/best_practices.sh" "$TARGET_JENKINSFILE"

Exit Code and Log Interpretation

Main orchestrator: validate_jenkinsfile.sh

  • 0: Validation passed
  • 1: Validation failed (syntax/security errors, or warnings in --strict mode)
  • 2: Usage or environment error (bad args, missing file, missing required tools)

Sub-scripts

  • validate_declarative.sh: 0 pass (errors=0), 1 usage/file/validation failure
  • validate_scripted.sh: 0 pass (errors=0), 1 usage/file/validation failure
  • common_validation.sh check_credentials: 0 no credential errors, 1 credential issues found
  • validate_shared_library.sh: 0 pass, 1 validation errors found, 2 invalid input target
  • best_practices.sh: 1 only for usage/file errors; content findings are reported in logs and score output

Log severity patterns

  • ERROR [Line N]: ... => must fix
  • WARNING [Line N]: ... => should review
  • INFO [Line N]: ... => optional improvement
  • Summary banners (VALIDATION PASSED/FAILED) determine final interpretation quickly

Practical interpretation rules

  • For CI gating, rely on main orchestrator exit code.
  • Use --strict when warnings should fail pipelines.
  • When best_practices.sh is run standalone, read report sections (CRITICAL ISSUES, IMPROVEMENTS RECOMMENDED, score); do not rely only on exit code.

Fallback Behavior

Missing optional tools

  • If jq is missing, continue validation; treat as non-blocking.

Non-executable child scripts

  • Main orchestrator warns and falls back to bash <script> execution.

Missing child scripts

  • Main orchestrator reports runner error and returns failure for that phase.

Unknown plugin steps

Use this order:

  1. Check local reference: devops-skills-plugin/skills/jenkinsfile-validator/references/common_plugins.md
  2. Context7 lookup:
    • mcp__context7__resolve-library-id with query like jenkinsci <plugin-name>-plugin
    • mcp__context7__query-docs for usage and parameters
  3. Web fallback: plugins.jenkins.io and official Jenkins docs

Offline/air-gapped mode

  • Run all local validators.
  • If plugin docs cannot be fetched, report: "Plugin docs lookup skipped due to environment constraints; local validation only."

Plugin Documentation Lookup Workflow

When plugin-specific validation is requested:

  1. Identify unknown steps from Jenkinsfile or validator logs.
  2. Check references/common_plugins.md first.
  3. If missing, use Context7 (resolve-library-id then query-docs).
  4. If still missing, use web search against official plugin index/docs.
  5. Return required parameters, optional parameters, version-sensitive notes, and security guidance.

References

Local references:

  • devops-skills-plugin/skills/jenkinsfile-validator/references/declarative_syntax.md
  • devops-skills-plugin/skills/jenkinsfile-validator/references/scripted_syntax.md
  • devops-skills-plugin/skills/jenkinsfile-validator/references/best_practices.md
  • devops-skills-plugin/skills/jenkinsfile-validator/references/common_plugins.md

External references:

Reporting Template

Use this structure in validation responses:

Validation Target: <path>
Pipeline Type: <Declarative|Scripted|Shared Library|Unknown>

Findings:
- ERROR [Line X]: <issue>
- WARNING [Line Y]: <issue>
- INFO [Line Z]: <suggestion>

Phase Results:
- Syntax: <PASSED|FAILED|SKIPPED>
- Security: <PASSED|FAILED|SKIPPED>
- Best Practices: <PASSED|REVIEW NEEDED|SKIPPED>

Exit Code: <0|1|2>
Next Actions:
1. <highest-priority fix>
2. <second fix>

Example Flows

Example 1: Full Jenkinsfile validation

SKILL_DIR="devops-skills-plugin/skills/jenkinsfile-validator"
bash "$SKILL_DIR/scripts/validate_jenkinsfile.sh" Jenkinsfile

Expected behavior:

  • Runs syntax + security + best practices
  • Prints per-phase results and unified summary
  • Returns 0/1/2 per orchestrator rules

Example 2: Shared library directory validation

SKILL_DIR="devops-skills-plugin/skills/jenkinsfile-validator"
bash "$SKILL_DIR/scripts/validate_shared_library.sh" examples/shared-library

Expected behavior:

  • Validates both vars/ and src/ files
  • Aggregates issues with line references
  • Returns 1 when errors are present

Example 3: Unknown plugin step follow-up

Input step:

nexusArtifactUploader artifacts: [[...]], nexusUrl: 'https://nexus.example.com'

Flow:

  1. Validate locally first.
  2. If step behavior is unclear, resolve docs via Context7.
  3. If unavailable, use plugin site docs.
  4. Report usage guidance and security-safe parameter patterns.

Done Criteria

The skill usage is complete when all are true:

  • Commands use normalized paths ($SKILL_DIR/scripts/...) with no cwd ambiguity.
  • Prerequisites and optional dependencies are explicit.
  • Exit-code semantics and log-severity interpretation are documented.
  • Fallback behavior is defined for missing tools/docs and constrained environments.
  • At least one runnable example exists for full validation and shared-library validation.
  • Reporting format is deterministic and actionable.
提供Kubernetes集群、Pod、网络及存储故障的系统化诊断工具,遵循安全优先原则。支持CrashLoopBackOff等常见错误排查,强调只读诊断与破坏性操作的风险控制。
Pod状态异常如CrashLoopBackOff或Pending Service DNS解析或服务连通性问题 Deployment部署滚动更新卡住 PVC挂载失败或存储卷问题 集群健康度下降或资源耗尽
devops-skills-plugin/skills/k8s-debug/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill k8s-debug -g -y
SKILL.md
Frontmatter
{
    "name": "k8s-debug",
    "description": "Diagnose and fix Kubernetes pods, CrashLoopBackOff, Pending, DNS, networking, storage, and rollout failures with kubectl."
}

Kubernetes Debugging Skill

Overview

Systematic toolkit for debugging Kubernetes clusters, workloads, networking, and storage with a deterministic, safety-first workflow.

Trigger Phrases

Use this skill when requests resemble:

  • "My pod is in CrashLoopBackOff; help me find the root cause."
  • "Service DNS works in one pod but not another."
  • "Deployment rollout is stuck."
  • "Pods are Pending and not scheduling."
  • "Cluster health looks degraded after a change."
  • "PVC is pending and pods cannot mount storage."

Prerequisites

Run from the skill directory (devops-skills-plugin/skills/k8s-debug) so relative script paths work as written.

Required

  • kubectl installed and configured.
  • An active cluster context.
  • Read access to namespaces, pods, events, services, and nodes.

Quick preflight:

kubectl config current-context
kubectl auth can-i get pods -A
kubectl auth can-i get events -A
kubectl get ns

Optional but Recommended

  • jq for more precise filtering in ./scripts/cluster_health.sh.
  • Metrics API (metrics-server) for kubectl top.
  • In-container debug tools (nslookup, getent, curl, wget, ip) for deep network tests.

Fallback behavior:

  • If optional tools are missing, scripts continue and print warnings with reduced output.
  • If kubectl top is unavailable, continue with kubectl describe and events.

When to Use This Skill

Use this skill for:

  • Pod failures (CrashLoopBackOff, ImagePullBackOff, Pending, OOMKilled)
  • Service connectivity or DNS resolution issues
  • Network policy or ingress problems
  • Volume and storage mount failures
  • Deployment rollout issues
  • Cluster health or performance degradation
  • Resource exhaustion (CPU/memory)
  • Configuration problems (ConfigMaps, Secrets, RBAC)

Safety Rules for Disruptive Commands

Default mode is read-only diagnosis first. Only execute disruptive commands after confirming blast radius and rollback.

Commands requiring explicit confirmation:

  • kubectl delete pod ... --force --grace-period=0
  • kubectl drain ...
  • kubectl rollout restart ...
  • kubectl rollout undo ...
  • kubectl debug ... --copy-to=...

Before disruptive actions:

# Snapshot current state for rollback and incident notes
kubectl get deploy,rs,pod,svc -n <namespace> -o wide
kubectl get pod <pod-name> -n <namespace> -o yaml > before-<pod-name>.yaml
kubectl get events -n <namespace> --sort-by='.lastTimestamp' > before-events.txt

Reference Navigation Map

Load only the section needed for the observed symptom.

Symptom / Need Open Start section
You need an end-to-end diagnosis path ./references/troubleshooting_workflow.md General Debugging Workflow
Pod state is Pending, CrashLoopBackOff, or ImagePullBackOff ./references/troubleshooting_workflow.md Pod Lifecycle Troubleshooting
Service reachability or DNS failure ./references/troubleshooting_workflow.md Network Troubleshooting Workflow
Node pressure or performance regression ./references/troubleshooting_workflow.md Resource and Performance Workflow
PVC / PV / storage class issues ./references/troubleshooting_workflow.md Storage Troubleshooting Workflow
Quick symptom-to-fix lookup ./references/common_issues.md matching issue heading
Post-mortem fix options for known issues ./references/common_issues.md Solutions sections

Scripts Overview

Script Purpose Required args Optional args Output Fallback behavior
./scripts/cluster_health.sh Cluster-wide health snapshot (nodes, workloads, events, common failure states) None --strict, K8S_REQUEST_TIMEOUT env var Sectioned report to stdout Continues on check failures, tracks them in summary and exit code
./scripts/network_debug.sh Pod-centric network and DNS diagnostics <pod-name> (<namespace> defaults to default) --strict, --insecure, K8S_REQUEST_TIMEOUT env var Sectioned report to stdout Uses secure API probe by default; insecure TLS requires explicit --insecure
./scripts/pod_diagnostics.py Deep pod diagnostics (status, describe, YAML, events, per-container logs, node context) <pod-name> -n/--namespace, -o/--output Sectioned report to stdout or file Fails fast on missing access; skips optional metrics/log blocks with clear messages

Script Exit Codes

./scripts/cluster_health.sh and ./scripts/network_debug.sh share the same contract:

  • 0: checks completed with no check failures (warnings allowed unless --strict is set).
  • 1: one or more checks failed, or warnings occurred in --strict mode.
  • 2: blocked preconditions (for example: missing kubectl, no active context, inaccessible namespace/pod).

Deterministic Debugging Workflow

Follow this systematic approach for any Kubernetes issue:

1. Preflight and Scope

kubectl config current-context
kubectl get ns
kubectl auth can-i get pods -n <namespace>

If preflight fails, stop and fix access/context first.

2. Identify the Problem Layer

Categorize the issue:

  • Application Layer: Application crashes, errors, bugs
  • Pod Layer: Pod not starting, restarting, or pending
  • Service Layer: Network connectivity, DNS issues
  • Node Layer: Node not ready, resource exhaustion
  • Cluster Layer: Control plane issues, API problems
  • Storage Layer: Volume mount failures, PVC issues
  • Configuration Layer: ConfigMap, Secret, RBAC issues

3. Gather Diagnostics with the Right Script

Use the appropriate diagnostic script based on scope:

Pod-Level Diagnostics

Use ./scripts/pod_diagnostics.py for comprehensive pod analysis:

python3 ./scripts/pod_diagnostics.py <pod-name> -n <namespace>

This script gathers:

  • Pod status and description
  • Pod events
  • Container logs (current and previous)
  • Resource usage
  • Node information
  • YAML configuration

Output can be saved for analysis:

python3 ./scripts/pod_diagnostics.py <pod-name> -n <namespace> -o diagnostics.txt

Cluster-Level Health Check

Use ./scripts/cluster_health.sh for overall cluster diagnostics:

./scripts/cluster_health.sh > cluster-health-$(date +%Y%m%d-%H%M%S).txt

This script checks:

  • Cluster info and version
  • Node status and resources
  • Pods across all namespaces
  • Failed/pending pods
  • Recent events
  • Deployments, services, statefulsets, daemonsets
  • PVCs and PVs
  • Component health
  • Common error states (CrashLoopBackOff, ImagePullBackOff)

Network Diagnostics

Use ./scripts/network_debug.sh for connectivity issues:

./scripts/network_debug.sh <namespace> <pod-name>
# or force warning sensitivity / insecure TLS only when explicitly needed:
./scripts/network_debug.sh --strict <namespace> <pod-name>
./scripts/network_debug.sh --insecure <namespace> <pod-name>

This script analyzes:

  • Pod network configuration
  • DNS setup and resolution
  • Service endpoints
  • Network policies
  • Connectivity tests
  • CoreDNS logs

4. Follow Issue-Specific Reference Workflow

Based on the identified issue, consult ./references/troubleshooting_workflow.md:

  • Pod Pending: Resource/scheduling workflow
  • CrashLoopBackOff: Application crash workflow
  • ImagePullBackOff: Image pull workflow
  • Service issues: Network connectivity workflow
  • DNS failures: DNS troubleshooting workflow
  • Resource exhaustion: Performance investigation workflow
  • Storage issues: PVC binding workflow
  • Deployment stuck: Rollout workflow

5. Apply Targeted Fixes

Refer to ./references/common_issues.md for symptom-specific fixes.

6. Verify and Close

Run final verification:

kubectl get pods -n <namespace> -o wide
kubectl get events -n <namespace> --sort-by='.lastTimestamp' | tail -20
kubectl rollout status deployment/<name> -n <namespace>

Issue is done when user-visible behavior is healthy and no new critical warning events appear.

Example Flows

Example 1: CrashLoopBackOff in payments Namespace

python3 ./scripts/pod_diagnostics.py payments-api-7c97f95dfb-q9l7k -n payments -o payments-diagnostics.txt
kubectl logs payments-api-7c97f95dfb-q9l7k -n payments --previous --tail=100
kubectl get deploy payments-api -n payments -o yaml | grep -A 8 livenessProbe

Then open ./references/common_issues.md and apply the CrashLoopBackOff solutions.

Example 2: Service DNS/Connectivity Failure

./scripts/network_debug.sh checkout checkout-api-75f49c9d8f-z6qtm
kubectl get svc checkout-api -n checkout
kubectl get endpoints checkout-api -n checkout
kubectl get networkpolicies -n checkout

Then follow Service Connectivity Workflow in ./references/troubleshooting_workflow.md.

Essential Manual Commands

Pod Debugging

# View pod status
kubectl get pods -n <namespace> -o wide

# Detailed pod information
kubectl describe pod <pod-name> -n <namespace>

# View logs
kubectl logs <pod-name> -n <namespace>
kubectl logs <pod-name> -n <namespace> --previous  # Previous container
kubectl logs <pod-name> -n <namespace> -c <container>  # Specific container

# Execute commands in pod
kubectl exec <pod-name> -n <namespace> -it -- /bin/sh

# Get pod YAML
kubectl get pod <pod-name> -n <namespace> -o yaml

Service and Network Debugging

# Check services
kubectl get svc -n <namespace>
kubectl describe svc <service-name> -n <namespace>

# Check endpoints
kubectl get endpoints -n <namespace>

# Test DNS
kubectl exec <pod-name> -n <namespace> -- nslookup kubernetes.default

# View events
kubectl get events -n <namespace> --sort-by='.lastTimestamp'

Resource Monitoring

# Node resources
kubectl top nodes
kubectl describe nodes

# Pod resources
kubectl top pods -n <namespace>
kubectl top pod <pod-name> -n <namespace> --containers

Emergency Operations

# Restart deployment
kubectl rollout restart deployment/<name> -n <namespace>

# Rollback deployment
kubectl rollout undo deployment/<name> -n <namespace>

# Force delete stuck pod
kubectl delete pod <pod-name> -n <namespace> --force --grace-period=0

# Drain node (maintenance)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# Cordon node (prevent scheduling)
kubectl cordon <node-name>

Completion Criteria

Troubleshooting session is complete when all are true:

  • Cluster context and namespace are confirmed.
  • Relevant diagnostic script output is captured.
  • Root cause is identified and tied to evidence (events/logs/config/state).
  • Any disruptive action was preceded by snapshot and rollback plan.
  • Fix verification commands show healthy state.
  • Reference path used (./references/troubleshooting_workflow.md or ./references/common_issues.md) is documented in notes.

Related Tools

Useful additional tools for Kubernetes debugging:

  • kubectl-debug: Advanced debugging plugin
  • stern: Multi-pod log tailing
  • kubectx/kubens: Context and namespace switching
  • k9s: Terminal UI for Kubernetes
  • lens: Desktop IDE for Kubernetes
  • Prometheus/Grafana: Monitoring and alerting
  • Jaeger/Zipkin: Distributed tracing
用于生成或更新Kubernetes YAML清单,涵盖Deployment、Service等常见资源及CRD。遵循确定性步骤,包括前置检查、输入收集、CRD查询及强制验证,确保输出符合最佳实践且完整可用。
用户要求生成Kubernetes YAML(如Deployment、Service、ConfigMap) 用户需要创建StatefulSet、Ingress或Argo CD Application CRD 用户请求生产级Kubernetes配置
devops-skills-plugin/skills/k8s-yaml-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill k8s-yaml-generator -g -y
SKILL.md
Frontmatter
{
    "name": "k8s-yaml-generator",
    "description": "Generate\/create\/scaffold Kubernetes YAML — Deployment, Service, ConfigMap, Ingress, RBAC, StatefulSet, CRDs."
}

Kubernetes YAML Generator

Generate Kubernetes manifests with deterministic steps, bounded CRD research, and mandatory validation for full-resource output.

Trigger Guidance

Use this skill when the user asks to create or update Kubernetes YAML, for example:

  • "Generate a Deployment + Service manifest for my app."
  • "Create an Argo CD Application CRD."
  • "Write a StatefulSet with PVC templates."
  • "Produce production-ready Kubernetes YAML with best practices."

Do not use this skill for validation-only requests. For validation-only work, use k8s-yaml-validator.

Execution Model

Normative keywords:

  • MUST: required
  • SHOULD: default unless user requests otherwise
  • MAY: optional

Deterministic sequence:

  1. Preflight request and path/rendering sanity.
  2. Capture minimum required inputs.
  3. Resolve CRD references (bounded workflow only when CRD/custom API is involved).
  4. Generate YAML with baseline quality checks.
  5. Run mandatory validation (or documented fallback path when tooling is unavailable).
  6. Deliver YAML plus explicit validation report and assumptions.

If one step is blocked by environment constraints, execute that step's fallback and continue.

1) Preflight

Before generation:

  • Confirm whether output is full manifest(s) or snippet-only.
  • Confirm target Kubernetes version when provided.
  • Verify any referenced local file path exists before using it.
  • Normalize resource naming to DNS-1123-compatible names where applicable.

Preflight stop condition:

  • If required core inputs are missing (resource type, workload image for Pod-based resources, or CRD kind/apiVersion), ask for those first.

2) Capture Required Inputs

Collect:

  • Resource types (Deployment, Service, ConfigMap, CRD kind, etc.)
  • apiVersion + kind
  • Namespace/scoping requirements
  • Ports, replicas, images, probes, storage, and secret/config needs
  • Environment assumptions (dev/staging/prod)
  • For CRDs: project name and target CRD version if known

Safe defaults (state explicitly in output):

  • Namespace: default (namespace-scoped resources)
  • Deployment replicas: 2
  • Service type: ClusterIP
  • Image pull policy: IfNotPresent (unless user needs forced pulls)

3) CRD Lookup Workflow (Bounded)

Run this step only for custom APIs outside Kubernetes built-in groups.

3.1 Identify CRD target

Extract:

  • API group, version, kind (for example argoproj.io/v1alpha1, Application)
  • Requested product/version (for example Argo CD v2.9.x)

3.2 Context7 primary path

Use the correct Context7 tools and payloads:

  1. mcp__context7__resolve-library-id
  2. mcp__context7__query-docs

Sample payloads:

Tool: mcp__context7__resolve-library-id
libraryName: "argo-cd"
query: "Find Argo CD documentation for Application CRD schema compatibility"
Tool: mcp__context7__query-docs
libraryId: "/argoproj/argo-cd/v2.9.0"
query: "Application CRD required spec fields for apiVersion argoproj.io/v1alpha1 with minimal valid example"

Selection rules:

  • Prefer exact project/library name matches.
  • Prefer versioned libraryId when user specifies a version.
  • Otherwise use unversioned ID and note version uncertainty.

3.3 Thresholds and stop conditions

Bound the lookup to prevent unbounded retries:

  • resolve-library-id: max 2 attempts (primary name + one alternate name).
  • query-docs: max 3 focused queries total.
  • Web fallback: max 2 version-specific searches.

Stop early when all are true:

  • Required CRD fields are identified.
  • At least one authoritative example is found.
  • Version compatibility is known or explicitly marked unknown.

Hard stop when budgets are exhausted:

  • Generate only fields verified by sources.
  • Mark remaining fields as Needs confirmation.
  • Report residual risk and request one of:
    • exact CRD docs URL, or
    • cluster introspection output (for example kubectl explain <kind>.spec when available).

3.4 Fallback order

Use this order:

  1. Context7 (resolve-library-id -> query-docs)
  2. Official project docs via web search
  3. Cluster-local introspection (kubectl explain, if cluster access exists)

If none are available, provide a minimal, clearly marked draft and do not claim full CRD correctness.

4) YAML Generation Rules

Apply these checks:

  • Use explicit, non-deprecated API versions.
  • Include consistent labels (app.kubernetes.io/*) across related resources.
  • Include namespace for namespace-scoped resources.
  • Add resource requests/limits for Pod workloads unless user opts out.
  • Add readiness/liveness probes for long-running services where applicable.
  • Use securityContext to avoid root execution by default.
  • Keep multi-resource ordering dependency-safe (for example ConfigMap before Deployment consumers).

Minimal label baseline:

labels:
  app.kubernetes.io/name: myapp
  app.kubernetes.io/instance: myapp-prod
  app.kubernetes.io/part-of: myplatform
  app.kubernetes.io/managed-by: codex

5) Mandatory Validation and Contingencies

For full manifest generation, validation is mandatory.

Primary path:

  • Invoke k8s-yaml-validator.
  • Iterate fix -> revalidate until blocking issues are gone.

Required reporting after each validation pass:

  • Validation mode: k8s-yaml-validator | script fallback | manual fallback
  • Syntax: pass/fail
  • Schema: pass/fail/partial
  • CRD check: pass/fail/partial
  • Dry-run: server/client/skipped
  • Blocking issues remaining: yes/no

Contingency A: validator skill unavailable

Run direct commands:

bash devops-skills-plugin/skills/k8s-yaml-validator/scripts/setup_tools.sh
yamllint -c devops-skills-plugin/skills/k8s-yaml-validator/assets/.yamllint <file.yaml>
kubeconform -schema-location default -strict -ignore-missing-schemas -summary <file.yaml>
server_out="$(mktemp)"
client_out="$(mktemp)"
trap 'rm -f "$server_out" "$client_out"' EXIT

if kubectl apply --dry-run=server -f <file.yaml> >"$server_out" 2>&1; then
  echo "server_validation=passed"
elif grep -Eqi "connection refused|no such host|i/o timeout|tls handshake timeout|unable to connect to the server|no configuration has been provided|the server doesn't have a resource type" "$server_out"; then
  echo "server_validation=skipped"
  if kubectl apply --dry-run=client -f <file.yaml> >"$client_out" 2>&1; then
    echo "client_validation=passed"
  else
    echo "client_validation=failed"
    cat "$client_out"
    exit 1
  fi
else
  echo "server_validation=failed"
  cat "$server_out"
  exit 1
fi

Contingency B: local tools partially unavailable

  • Run available checks.
  • Record skipped checks explicitly.
  • Add residual risk for every skipped check.

Contingency C: repeated validation failure

  • Maximum 3 fix/revalidate cycles.
  • If still failing, stop and return:
    • current YAML,
    • exact failing errors,
    • smallest required user decision/input to unblock.

Validation exceptions:

  • Snippet-only or docs-only requests MAY skip full validation, but the output MUST state Validation status: Skipped (reason).

6) Delivery Contract

Final output MUST include:

  1. Generated YAML.
  2. What was generated (resource list, namespace/scoping).
  3. Validation report in the required format.
  4. Assumptions and defaults used.
  5. References used:
    • Context7 IDs/queries used (for CRDs)
    • external docs/searches used
    • items skipped/missing and impact

Suggested next commands:

kubectl apply -f <filename>.yaml
kubectl get <resource-type> <name> -n <namespace>
kubectl describe <resource-type> <name> -n <namespace>

7) Canonical Example Flows

Example A: Built-in resources (Deployment + Service)

  1. Capture app image, ports, replicas, namespace.
  2. Generate Deployment and Service with consistent labels/selectors.
  3. Validate with k8s-yaml-validator.
  4. Return YAML + validation report + assumptions.

Example B: CRD resource (Argo CD Application)

  1. Extract argoproj.io/v1alpha1 + Application.
  2. Run bounded Context7 lookup (resolve-library-id then query-docs).
  3. If needed, perform bounded web fallback.
  4. Generate CRD YAML only with verified fields.
  5. Validate, report any partial verification, and return residual risks.

8) Definition of Done

Execution is complete only when all applicable checks pass:

  • Trigger use case is correct (generation, not validation-only).
  • Required inputs are captured or explicit assumptions are documented.
  • CRD lookup follows bounded thresholds and stop conditions.
  • Tool names and command paths are valid and consistent.
  • Full manifests are validated (or fallback path is documented with residual risk).
  • Final response includes YAML, validation report, assumptions, and references.
提供Kubernetes YAML资源的只读验证工作流,涵盖语法检查、Schema校验、集群Dry-run及CRD文档查询。严格禁止修改文件,仅生成包含修复建议的报告供用户决策。
Validate this Kubernetes YAML before deploy. Lint these manifests and report what is broken. Check this CRD manifest and explain schema issues. Run dry-run checks on this manifest. Find line-level errors in the multi-document YAML.
devops-skills-plugin/skills/k8s-yaml-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill k8s-yaml-validator -g -y
SKILL.md
Frontmatter
{
    "name": "k8s-yaml-validator",
    "description": "Validate, lint, audit, or dry-run Kubernetes manifests (Deployment, Service, ConfigMap, CRD)."
}

Kubernetes YAML Validator

Overview

This skill provides a comprehensive validation workflow for Kubernetes YAML resources, combining syntax linting, schema validation, cluster dry-run testing, and intelligent CRD documentation lookup. Validate any Kubernetes manifest with confidence before applying it to the cluster.

IMPORTANT: This is a REPORT-ONLY validation tool. Do NOT modify files, do NOT use Edit tool, do NOT use AskUserQuestion to offer fixes. Generate a comprehensive validation report with suggested fixes shown as before/after code blocks, then let the user decide what to do next.

Trigger Phrases

Use this skill when prompts look like:

  • "Validate this Kubernetes YAML before deploy."
  • "Lint these manifests and report what is broken."
  • "Check this CRD manifest and explain schema issues."
  • "Run dry-run checks on this manifest."
  • "Find line-level errors in this multi-document YAML."

When to Use This Skill

Invoke this skill when:

  • Validating Kubernetes YAML files before applying to a cluster
  • Debugging YAML syntax or formatting errors
  • Working with Custom Resource Definitions (CRDs) and need documentation
  • Performing dry-run tests to catch admission controller errors
  • Ensuring YAML follows Kubernetes best practices
  • Understanding what validation errors exist in manifests (report-only, user fixes manually)
  • The user asks to "validate", "lint", "check", or "test" Kubernetes YAML files

Read-Only Boundary (Mandatory)

This skill is strictly report-only:

  • Do NOT modify any user files.
  • Do NOT run Edit for fixes.
  • Do NOT ask for permission to apply fixes.
  • Do provide before/after snippets as suggestions in the report.

Deterministic Path Setup

Run with explicit paths so commands are repeatable:

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
SKILL_DIR="$REPO_ROOT/devops-skills-plugin/skills/k8s-yaml-validator"
TARGET_FILE="$REPO_ROOT/<relative/path/to/file.yaml>"

Path checks:

  • If REPO_ROOT is empty, stop and ask for repository root.
  • If SKILL_DIR does not exist, stop and report path mismatch.
  • If TARGET_FILE does not exist, stop and ask for the correct file.

Validation Workflow

Follow this sequential validation workflow. Each stage catches different types of issues:

Stage 0: Pre-Validation Setup (Deterministic Resource Count)

Before running validators, count documents using the bundled script:

python3 "$SKILL_DIR/scripts/count_yaml_documents.py" "$TARGET_FILE"

Expected output (example):

{
  "file": ".../manifests.yaml",
  "documents": 3,
  "separators": 2
}

Gate rules:

  • If documents >= 3, load references/validation_workflow.md before Stage 1.
  • Always include the document count in the final report summary.
  • If python3 is unavailable, use fallback:
awk 'BEGIN{d=0;seen=0} /^[[:space:]]*---[[:space:]]*$/ {if(seen){d++;seen=0}; next} /^[[:space:]]*#/ {next} NF{seen=1} END{if(seen)d++; print d}' "$TARGET_FILE"

and mark the count as estimated in the report.

Stage 1: Tool Check

Before starting validation, verify required tools are installed:

bash "$SKILL_DIR/scripts/setup_tools.sh"

Required tools:

  • yamllint: YAML syntax and style linting
  • kubeconform: Kubernetes schema validation with CRD support
  • kubectl: Cluster dry-run testing (optional but recommended)

If tools are missing, display installation guidance from script output and continue with available tools. Document missing tools and skipped stages in the report.

Stage 2: YAML Syntax Validation

Validate YAML syntax and formatting using yamllint:

yamllint -c "$SKILL_DIR/assets/.yamllint" "$TARGET_FILE"

Common issues caught:

  • Indentation errors (tabs vs spaces)
  • Trailing whitespace
  • Line length violations
  • Syntax errors
  • Duplicate keys

Reporting approach:

  • Report all syntax issues with file:line references
  • For fixable issues, show suggested before/after code blocks
  • Continue to next validation stage to collect all issues before reporting

Stage 3: CRD Detection and Documentation Lookup

Before schema validation, detect if the YAML contains Custom Resource Definitions:

bash "$SKILL_DIR/scripts/detect_crd_wrapper.sh" "$TARGET_FILE"

The wrapper script automatically handles Python dependencies by creating a temporary virtual environment if PyYAML is not available.

Resilient Parsing: The script is resilient to syntax errors in individual documents. If a multi-document YAML file has some valid and some invalid documents, the script will:

  • Parse valid documents and detect their CRDs
  • Report errors for invalid documents but continue processing
  • This matches kubeconform's behavior of validating 2/3 resources even when 1/3 has syntax errors

The script outputs JSON with resource information and parse status:

{
  "resources": [
    {
      "kind": "Certificate",
      "apiVersion": "cert-manager.io/v1",
      "group": "cert-manager.io",
      "version": "v1",
      "isCRD": true,
      "name": "example-cert"
    }
  ],
  "parseErrors": [
    {
      "document": 1,
      "start_line": 2,
      "error_line": 6,
      "error": "mapping values are not allowed in this context"
    }
  ],
  "summary": {
    "totalDocuments": 3,
    "parsedSuccessfully": 2,
    "parseErrors": 1,
    "crdsDetected": 1
  }
}

For each detected CRD:

  1. Try Context7 MCP first (preferred):

    • Resolve library:
      • Tool: mcp__context7__resolve-library-id
      • libraryName: CRD project name (example: cert-manager for cert-manager.io)
    • Query docs:
      • Tool: mcp__context7__query-docs
      • libraryId: resolved library ID from previous step
      • query: include CRD kind, group, and version (example: Certificate cert-manager.io v1 required fields in spec)
  2. Fallback to web.search_query if Context7 fails or returns insufficient details:

    Search query pattern:
    "<kind>" "<group>" kubernetes CRD "<version>" documentation spec
    
    Example:
    "Certificate" "cert-manager.io" kubernetes CRD "v1" documentation spec
    
  3. Extract key information:

    • Required fields in spec
    • Field types and validation rules
    • Examples from documentation
    • Version-specific changes or deprecations

Secondary CRD Detection via kubeconform: If detect_crd_wrapper.sh cannot identify CRDs (for example, syntax errors in all documents), but kubeconform still validates a CRD resource, look up docs for that CRD anyway. Parse kubeconform output to identify validated CRDs and perform Context7/web.search_query lookups.

Why this matters: CRDs have custom schemas not available in standard Kubernetes validation tools. Understanding the CRD's spec requirements prevents validation errors and ensures correct resource configuration.

Stage 4: Schema Validation

Validate against Kubernetes schemas using kubeconform:

kubeconform \
  -schema-location default \
  -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
  -strict \
  -ignore-missing-schemas \
  -summary \
  -verbose \
  "$TARGET_FILE"

Options explained:

  • -strict: Reject unknown fields (recommended for production - catches typos)
  • -ignore-missing-schemas: Skip validation for CRDs without available schemas
  • -kubernetes-version 1.30.0: Validate against specific K8s version

Common issues caught:

  • Invalid apiVersion or kind
  • Missing required fields
  • Wrong field types
  • Invalid enum values
  • Unknown fields (with -strict)

For CRDs: If kubeconform reports "no schema found", this is expected. Use the documentation from Stage 3 to manually validate the spec fields.

kubeconform line number behavior — two distinct cases:

kubeconform does NOT report file-absolute line numbers. You must translate:

  1. Parse errors (e.g. error converting YAML to JSON: yaml: line N):

    • N is document-relative (line N within that document's content).
    • Convert to file-absolute: file_line = doc_start_line + N - 1
    • doc_start_line comes from the start_line field in detect_crd_wrapper.sh output.
    • Example: document starts at file line 4, kubeconform says yaml: line 5 → file-absolute line = 4 + 5 − 1 = line 8 (matches yamllint output).
  2. Schema validation errors (e.g. got string, want integer):

    • kubeconform reports JSON path only, no line number.
    • Example: at '/spec/template/spec/containers/0/ports/0/containerPort': got string, want integer
    • To find the line: search the YAML file for the field name (e.g. containerPort) within the relevant document section, using file-absolute line numbers from the surrounding context.

Always present line numbers as file-absolute in the validation report even when translating from kubeconform's document-relative output.

Stage 5: Cluster Dry-Run (if available)

IMPORTANT: Always try server-side dry-run first. Server-side validation catches more issues than client-side because it runs through admission controllers and webhooks.

Decision Tree:

1. Try server-side dry-run first:
   kubectl apply --dry-run=server -f "$TARGET_FILE"

   └─ If SUCCESS → Use results, continue to Stage 6

   └─ If FAILS with connection error (e.g., "connection refused",
      "unable to connect", "no configuration"):
      │
      ├─ 2. Attempt client-side dry-run (parse-only fallback):
      │     kubectl apply --dry-run=client --validate=false -f "$TARGET_FILE"
      │
      │     ├─ If SUCCESS:
      │     │    Document in report: "Server-side validation skipped (no cluster access); client fallback ran in parse-only mode"
      │     │
      │     └─ If FAILS with discovery/openapi error (e.g., "unable to recognize",
      │        "failed to download openapi", "couldn't get current server API group list"):
      │        Document in report: "Dry-run skipped (cluster discovery unavailable)"
      │        Continue to Stage 6
      │
      └─ If FAILS with validation error (e.g., "admission webhook denied",
         "resource quota exceeded", "invalid value"):
         └─ Record the error, continue to Stage 6

   └─ If FAILS with parse error (e.g., "error converting YAML to JSON",
      "yaml: line X: mapping values are not allowed"):
      └─ Record the error, skip client-side dry-run (same error will occur)
         Document in report: "Dry-run blocked by YAML syntax errors - fix syntax first"
         Continue to Stage 6

Note: Parse errors from earlier stages (yamllint, kubeconform) will also cause dry-run to fail. Do NOT attempt client-side dry-run as a fallback for parse errors - it will produce the same error. Parse errors must be fixed before dry-run validation can proceed.

Server-side dry-run catches:

  • Admission controller rejections
  • Policy violations (PSP, OPA, Kyverno, etc.)
  • Resource quota violations
  • Missing namespaces
  • Invalid ConfigMap/Secret references
  • Webhook validations

Client-side dry-run with --validate=false catches (fallback, when command succeeds):

  • YAML/JSON conversion and request-construction issues
  • Whether kubectl can process and submit the manifest shape in client mode
  • Note: --validate=false disables schema/type/required-field validation and still does NOT catch admission controller or policy issues.

Document in your report which mode was used:

  • If server-side: "Full cluster validation performed"
  • If client-side with --validate=false: "Limited parse-only validation (no cluster access) - schema and admission policies not checked"
  • If skipped: "Dry-run skipped - kubectl not available"
  • If skipped after client fallback attempt: "Dry-run skipped (cluster discovery unavailable)"

For updates to existing resources:

kubectl diff -f "$TARGET_FILE"

This shows what would change, helping catch unintended modifications.

Stage 6: Generate Detailed Validation Report (REPORT ONLY)

After completing all validation stages, generate a comprehensive report. This is a REPORT-ONLY stage.

NEVER do any of the following:

  • Do NOT use the Edit tool to modify files
  • Do NOT use AskUserQuestion to offer to fix issues
  • Do NOT prompt the user asking if they want fixes applied
  • Do NOT modify any YAML files

ALWAYS do the following:

  • Generate a comprehensive validation report
  • Show before/after code blocks as SUGGESTIONS only
  • Let the user decide what to do after reviewing the report
  • End with "Next Steps" for the user to take manually
  1. Summarize all issues found across all stages in a table format:

    | Severity | Stage | Location | Issue | Suggested Fix |
    |----------|-------|----------|-------|---------------|
    | Error | Syntax | file.yaml:5 | Indentation error | Use 2 spaces |
    | Error | Schema | file.yaml:21 | Wrong type | Change to integer |
    | Warning | Best Practice | file.yaml:30 | Missing labels | Add app label |
    
  2. Categorize by severity:

    • Errors (must fix): Syntax errors, missing required fields, dry-run failures
    • Warnings (should fix): Style issues, best practice violations
    • Info (optional): Suggestions for improvement
  3. Show before/after code blocks for each issue:

    For every issue, display explicit before/after YAML snippets showing the suggested fix:

    **Issue 1: deployment.yaml:21 - Wrong field type (Error)**
    
    Current:
    ```yaml
            - containerPort: "80"
    

    Suggested Fix:

            - containerPort: 80
    

    Why: containerPort must be an integer, not a string. Kubernetes will reject string values. Reference: See k8s_best_practices.md "Invalid Values" section.

    
    
  4. Provide validation summary:

    ## Validation Report Summary
    
    File: deployment.yaml
    Resources Analyzed: 3 (Deployment, Service, Certificate)
    
    | Stage | Status | Issues Found |
    |-------|--------|--------------|
    | YAML Syntax | ❌ Failed | 2 errors |
    | CRD Detection | ✅ Passed | 1 CRD detected (Certificate) |
    | Schema Validation | ❌ Failed | 1 error |
    | Dry-Run | ❌ Failed | 1 error |
    
    Total Issues: 4 errors, 2 warnings
    
    ## Detailed Findings
    
    [List each issue with before/after code blocks as shown above]
    
    ## Next Steps
    
    1. Fix the 4 errors listed above (deployment will fail without these)
    2. Consider addressing the 2 warnings for best practices
    3. Re-run validation after fixes to confirm resolution
    
  5. Do NOT modify files - this is a reporting tool only

    • Present all findings clearly
    • Let the user decide which fixes to apply
    • User can request fixes after reviewing the report

Objective Stage Gates (Repeatable)

Use this table to keep stage decisions deterministic:

Stage Required Command Pass/Fail Criteria Fallback
0 Resource Count Yes python3 "$SKILL_DIR/scripts/count_yaml_documents.py" "$TARGET_FILE" Pass when count output is produced and documents is recorded. Use AWK estimator and mark estimated.
1 Tool Check Yes bash "$SKILL_DIR/scripts/setup_tools.sh" Pass when command runs and tool availability is known. Continue with available tools and log skips.
2 YAML Syntax If yamllint available yamllint -c "$SKILL_DIR/assets/.yamllint" "$TARGET_FILE" Pass on exit code 0; fail on lint errors. Skip with explicit reason if missing binary.
3 CRD Detection If python3 available bash "$SKILL_DIR/scripts/detect_crd_wrapper.sh" "$TARGET_FILE" Pass when JSON output includes summary. Skip CRD extraction and rely on kubeconform clues.
4 Schema If kubeconform available kubeconform command from Stage 4 Pass when kubeconform reports valid resources. Skip and record as coverage gap if missing binary.
5 Dry-Run If kubectl available kubectl apply --dry-run=server -f "$TARGET_FILE" Pass on successful server dry-run. Attempt parse-only client fallback with --dry-run=client --validate=false; if discovery still fails, mark stage skipped.
6 Report Yes Report generation Pass when summary + per-issue snippets + next steps are provided. No fallback; this stage is mandatory.

Fallback Matrix

Constraint Action Report Language
python3 unavailable Skip count_yaml_documents.py and CRD parser scripts. Use AWK count only. Python runtime unavailable; CRD parser skipped, resource count is estimated.
yamllint unavailable Skip Stage 2; continue with schema/dry-run stages if available. YAML lint skipped because yamllint is not installed.
kubeconform unavailable Skip Stage 4; run lint and dry-run only. Schema validation skipped because kubeconform is not installed.
kubectl unavailable Skip Stage 5 entirely. Dry-run skipped because kubectl is not installed.
No cluster connectivity Run server-side first, then attempt parse-only client fallback with --dry-run=client --validate=false; if it still fails, skip dry-run and continue. Server-side dry-run unavailable due cluster access; parse-only client-side dry-run attempted (schema checks disabled).
Client dry-run still requires discovery Treat dry-run as unavailable and rely on lint + schema stages. Dry-run skipped (cluster discovery unavailable); lint and schema results used.
External docs unavailable Continue local validation and state documentation gap. CRD documentation lookup deferred due tooling/network limitation.

Best Practices Reference

For detailed Kubernetes YAML best practices, load the reference:

Read "$SKILL_DIR/references/k8s_best_practices.md"

This reference includes:

  • Metadata and label conventions
  • Resource limits and requests
  • Security context guidelines
  • Probe configurations
  • Common validation issues and fixes

When to load (ALWAYS load in these cases):

  • Schema validation fails with type errors (e.g., string vs integer, invalid values)
  • Schema validation reports missing required fields
  • kubeconform reports invalid field values or unknown fields
  • Dry-run fails with validation errors related to resources, probes, or security
  • When explaining why a fix is needed (to provide context from best practices)

Detailed Validation Workflow Reference

For in-depth workflow details and error handling strategies, load the reference:

Read "$SKILL_DIR/references/validation_workflow.md"

This reference includes:

  • Detailed command options for each tool
  • Error handling strategies
  • Multi-resource file handling
  • Complete workflow diagram
  • Troubleshooting guide

When to load (ALWAYS load in these cases):

  • File contains 3 or more resources (multi-document YAML)
  • Validation produces errors you haven't seen before or can't immediately diagnose
  • Need to understand the complete workflow for debugging
  • Errors span multiple validation stages

Working with Multiple Resources

When a YAML file contains multiple resources (separated by ---):

  1. Validate the entire file first with yamllint and kubeconform
  2. If errors occur, identify which resource has issues by checking line numbers
  3. For dry-run, the file is tested as a unit (Kubernetes processes in order)
  4. Track issues per-resource when presenting findings to the user

Partial Parsing Behavior

When a multi-document YAML file has some valid and some invalid documents:

Expected behavior:

  • The CRD detection script (detect_crd.py) will parse valid documents and skip invalid ones
  • kubeconform will validate resources it can parse and report errors for unparseable ones
  • The validation report should clearly show which documents parsed and which failed

Example scenario: A file with 3 documents where document 1 has a syntax error:

  • Document 1 (Deployment): Syntax error at line 8
  • Document 2 (Service): Valid
  • Document 3 (Certificate CRD): Valid

Expected output:

  • CRD detection: Finds Certificate CRD from document 3
  • kubeconform: Reports error for document 1, validates documents 2 and 3
  • Report: Shows syntax error for document 1, validation results for documents 2 and 3

In your report:

| Document | Resource | Parsing | Validation |
|----------|----------|---------|------------|
| 1 | Deployment | ❌ Syntax error (line 8) | Skipped |
| 2 | Service | ✅ Parsed | ✅ Valid |
| 3 | Certificate | ✅ Parsed | ✅ Valid |

Line Number Reference Style:

  • Always use file-absolute line numbers (line numbers relative to the start of the entire file)
  • This matches what yamllint, kubeconform, and kubectl report
  • Example: If a file has 3 documents and the error is in document 2 which starts at line 35, report as "line 42" (the absolute line in the file), not "line 7" (relative to document start)
  • This consistency makes it easy for users to navigate directly to the error in their editor

This ensures users get maximum validation feedback even when some documents have issues.

Error Handling Strategies

Tool Not Available

  • Run bash "$SKILL_DIR/scripts/setup_tools.sh" to check availability
  • Provide installation instructions
  • Skip optional stages but document what was skipped
  • Continue with available tools

Cluster Access Issues

  • Attempt parse-only client-side dry-run with --dry-run=client --validate=false
  • Treat this fallback as transport/parsing signal only (--validate=false disables schema/type/required-field checks)
  • If client dry-run still fails with API discovery/openapi errors, skip dry-run and rely on lint/schema stages
  • Document limitations in validation report

CRD Documentation Not Found

  • Document that documentation lookup failed
  • Attempt validation with kubeconform CRD schemas
  • Suggest manual CRD inspection:
    kubectl get crd <crd-name>.group -o yaml
    kubectl explain <kind>
    

Validation Stage Failures

  • Continue to next stage even if one fails
  • Collect all errors before presenting to user
  • Prioritize fixing earlier stage errors first

Communication Guidelines

When presenting validation results:

  1. Be clear and concise about what was found

  2. Explain why issues matter (e.g., "This will cause pod creation to fail")

  3. Provide context from best practices when relevant

  4. Group related issues (e.g., all missing label issues together)

  5. Use file:line references for all issues

  6. Show fix complexity - Include a complexity indicator in the issue header:

    • [Simple]: Single-line fixes like indentation, typos, or value changes
    • [Medium]: Multi-line changes or adding missing fields/sections
    • [Complex]: Logic changes, restructuring, or changes affecting multiple resources

    Example format in issue header:

    **Issue 1: deployment.yaml:8 - Wrong indentation (Error) [Simple]**
    **Issue 2: deployment.yaml:15-25 - Missing security context (Warning) [Medium]**
    **Issue 3: deployment.yaml - Selector mismatch with Service (Error) [Complex]**
    
  7. Always provide a comprehensive report including:

    • Summary table of all issues by stage
    • Before/after code blocks for each issue
    • Total count of errors and warnings
    • Clear next steps for the user
  8. NEVER offer to apply fixes - this is strictly a reporting tool

    • Do not ask "Would you like me to fix this?"
    • Do not use AskUserQuestion for fix confirmations
    • Present the report and let the user take action

Performance Optimization

Parallel Tool Execution

For improved validation speed, some stages can be executed in parallel:

Can run in parallel (no dependencies):

  • yamllint (Stage 2) and detect_crd_wrapper.sh (Stage 3) can run simultaneously
  • Both tools operate independently on the input file
  • Results from both are needed before proceeding to schema validation

Example parallel execution:

# Run these in parallel (using & and wait, or parallel tool calls):
yamllint -c "$SKILL_DIR/assets/.yamllint" "$TARGET_FILE"
bash "$SKILL_DIR/scripts/detect_crd_wrapper.sh" "$TARGET_FILE"

Must run sequentially:

  • Stage 0 (Resource Count Check) → Before all other stages
  • Stage 1 (Tool Check) → Before using any tools
  • Stage 4 (Schema Validation) → After CRD detection (needs CRD info for context)
  • Stage 5 (Dry-Run) → After schema validation
  • Stage 6 (Report) → After all validation stages complete

When to parallelize:

  • Files with more than 5 resources benefit most from parallel execution
  • For small files (1-2 resources), sequential execution is fine

Version Awareness

Always consider Kubernetes version compatibility:

  • Check for deprecated APIs (e.g., extensions/v1beta1apps/v1)
  • For CRDs, ensure the apiVersion matches what's in the cluster
  • Use kubectl api-versions to list available API versions in the cluster
  • Reference version-specific documentation when available

Test Coverage Guidance

The test/ directory contains example files to exercise all validation paths. Use these to verify skill behavior.

Test Files

Test File Purpose Expected Behavior
deployment-test.yaml Valid standard K8s resource All stages pass, no errors
certificate-crd-test.yaml Valid CRD resource CRD detected, Context7 lookup performed, no errors
comprehensive-test.yaml Multi-resource with intentional YAML syntax error Syntax error detected, partial parsing works, CRD found
schema-errors-test.yaml Valid YAML with intentional schema type errors yamllint passes; kubeconform fails with 2 JSON-path errors (replicas, containerPort)

Validation Paths to Test

  1. Happy Path (All Valid)
    • File: deployment-test.yaml
    • Expected: All stages pass, report shows "0 errors, 0 warnings"
    • Commands:
cd "$SKILL_DIR"
python3 scripts/count_yaml_documents.py test/deployment-test.yaml
yamllint -c assets/.yamllint test/deployment-test.yaml
bash scripts/detect_crd_wrapper.sh test/deployment-test.yaml
kubeconform \
  -schema-location default \
  -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
  -strict -ignore-missing-schemas -summary -verbose \
  test/deployment-test.yaml
kubectl apply --dry-run=server -f test/deployment-test.yaml
  1. CRD Detection Path
    • File: certificate-crd-test.yaml
    • Expected: CRD detected, mcp__context7__resolve-library-id and mcp__context7__query-docs used
    • Commands:
cd "$SKILL_DIR"
python3 scripts/count_yaml_documents.py test/certificate-crd-test.yaml
bash scripts/detect_crd_wrapper.sh test/certificate-crd-test.yaml
kubeconform \
  -schema-location default \
  -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
  -strict -ignore-missing-schemas -summary -verbose \
  test/certificate-crd-test.yaml
  1. Syntax Error Path
    • File: comprehensive-test.yaml
    • Expected: yamllint catches error, kubeconform reports partial validation, dry-run blocked
    • Commands:
cd "$SKILL_DIR"
python3 scripts/count_yaml_documents.py test/comprehensive-test.yaml
yamllint -c assets/.yamllint test/comprehensive-test.yaml
bash scripts/detect_crd_wrapper.sh test/comprehensive-test.yaml
kubeconform \
  -schema-location default \
  -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
  -strict -ignore-missing-schemas -summary -verbose \
  test/comprehensive-test.yaml
kubectl apply --dry-run=server -f test/comprehensive-test.yaml
  1. Multi-Resource Partial Parsing
    • File: comprehensive-test.yaml (has 3 resources, 1 with syntax error)
    • Expected: 2/3 resources validated, parse error reported for document 1
    • Commands:
cd "$SKILL_DIR"
python3 scripts/count_yaml_documents.py test/comprehensive-test.yaml
bash scripts/detect_crd_wrapper.sh test/comprehensive-test.yaml
  1. Schema Validation Error Path (type mismatches)
    • File: schema-errors-test.yaml
    • Expected: yamllint passes (valid YAML), kubeconform fails with 2 JSON-path schema errors
    • Note: kubeconform reports JSON paths, not line numbers — locate fields manually in the YAML
    • Commands:
cd "$SKILL_DIR"
python3 scripts/count_yaml_documents.py test/schema-errors-test.yaml
yamllint -c assets/.yamllint test/schema-errors-test.yaml
bash scripts/detect_crd_wrapper.sh test/schema-errors-test.yaml
kubeconform \
  -schema-location default \
  -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' \
  -strict -ignore-missing-schemas -summary -verbose \
  test/schema-errors-test.yaml
  1. No Cluster Access Path
    • Any valid file with no kubectl cluster configured
    • Expected: Server-side dry-run fails; parse-only client-side fallback is attempted (no schema guarantees) and may still fail if API discovery is unavailable
    • Commands:
cd "$SKILL_DIR"
KUBECONFIG=/tmp/nonexistent-kubeconfig kubectl apply --dry-run=server -f test/deployment-test.yaml
KUBECONFIG=/tmp/nonexistent-kubeconfig kubectl apply --dry-run=client --validate=false -f test/deployment-test.yaml
  1. Missing Tools Path
    • Test by temporarily removing a tool from PATH
    • Expected: setup_tools.sh reports missing tools and prints install instructions, validation continues with available tools
    • Commands:
cd "$SKILL_DIR"
PATH="/usr/bin:/bin" bash scripts/setup_tools.sh

Creating New Test Files

When adding test files:

  1. Name files descriptively: <scenario>-test.yaml
  2. Document expected behavior in comments at top of file
  3. Include intentional errors for error-path tests
  4. Test both standard K8s resources and CRDs

Expected Report Structure

For any validation, the report should include:

  • Summary table with issue counts by severity
  • Stage-by-stage status table (passed/failed/skipped)
  • Document parsing table (for multi-resource files)
  • Before/after code blocks for each issue
  • Fix complexity indicators ([Simple], [Medium], [Complex])
  • File-absolute line numbers
  • "Next Steps" section

Done Criteria

Validation is complete only when all conditions are true:

  • Stage gates were evaluated in order and every skipped stage includes a reason.
  • Resource count came from count_yaml_documents.py (or documented AWK fallback).
  • CRD lookups used mcp__context7__resolve-library-id + mcp__context7__query-docs, with web.search_query fallback only when needed.
  • Report-only boundary was preserved (no edits, no fix-application prompts).
  • Output includes exact commands run, findings by severity, and manual next steps.

Resources

scripts/

detect_crd_wrapper.sh

  • Wrapper script that handles Python dependency management
  • Automatically creates temporary venv if PyYAML is not available
  • Calls detect_crd.py to parse YAML files
  • Usage: bash "$SKILL_DIR/scripts/detect_crd_wrapper.sh" "$TARGET_FILE"

detect_crd.py

  • Parses YAML files to identify Custom Resource Definitions
  • Extracts kind, apiVersion, group, and version information
  • Outputs JSON for programmatic processing
  • Requires PyYAML (handled automatically by wrapper script)
  • Can be called directly: python3 "$SKILL_DIR/scripts/detect_crd.py" "$TARGET_FILE"

count_yaml_documents.py

  • Deterministically counts non-empty YAML documents in a multi-doc file
  • Returns JSON with document count and separators
  • Use before Stage 1 to decide whether to load deep workflow reference
  • Usage: python3 "$SKILL_DIR/scripts/count_yaml_documents.py" "$TARGET_FILE"

setup_tools.sh

  • Checks for required validation tools
  • Provides installation instructions for missing tools
  • Verifies versions of installed tools
  • Usage: bash "$SKILL_DIR/scripts/setup_tools.sh"

references/

k8s_best_practices.md

  • Comprehensive guide to Kubernetes YAML best practices
  • Covers metadata, labels, resource limits, security context
  • Common validation issues and how to fix them
  • Load when providing context for validation errors

validation_workflow.md

  • Detailed validation workflow with all stages
  • Command options and configurations
  • Error handling strategies
  • Complete workflow diagram
  • Load for complex validation scenarios

assets/

.yamllint

  • Pre-configured yamllint rules for Kubernetes YAML
  • Follows Kubernetes conventions (2-space indentation, line length, etc.)
  • Can be customized per project
  • Usage: yamllint -c "$SKILL_DIR/assets/.yamllint" "$TARGET_FILE"
交互式生成生产级 LogQL 查询、日志流选择器及告警规则。通过五阶段流程收集意图、源细节、版本信息,确保查询兼容性与准确性,支持调试与监控场景。
Write a LogQL query for error rate by service. Help me build a Loki alert query. Convert this troubleshooting requirement into LogQL. I need step-by-step LogQL query construction.
devops-skills-plugin/skills/logql-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill logql-generator -g -y
SKILL.md
Frontmatter
{
    "name": "logql-generator",
    "description": "Generate LogQL queries, log stream selectors, metric queries, and alerting rules for Grafana Loki."
}

LogQL Query Generator

Overview

Interactive workflow for generating production-ready LogQL queries. LogQL is Grafana Loki's query language with indexed label selection, line filtering, parsing, and metric aggregation.

Trigger Hints

  • "Write a LogQL query for error rate by service."
  • "Help me build a Loki alert query."
  • "Convert this troubleshooting requirement into LogQL."
  • "I need step-by-step LogQL query construction."

Use this skill for query generation, dashboard queries, alerting expressions, and troubleshooting with Loki logs.

Execution Flow (Deterministic)

Always run stages in order. Do not skip required stages.

Stage 1 (Required): Capture Intent

Use AskUserQuestion to collect goal and use case.

Template:

  • "What is your primary goal: debugging, alerting, dashboard metric, or investigation?"
  • "Do you need a log query (raw lines) or a metric query (numeric output)?"
  • "What time window should this cover (example: last 15m, 1h, 24h)?"

Fallback if AskUserQuestion is unavailable:

  • Ask the same questions in plain text and continue.

Stage 2 (Required): Capture Log Source Details

Collect:

  1. Labels for stream selectors (job, namespace, app, service_name, cluster)
  2. Log format (JSON, logfmt, plain text, mixed)
  3. Known fields to filter/aggregate (status, level, duration, path, trace_id)

Ambiguity and partial-answer handling:

  1. If a required field is missing, ask one focused follow-up question.
  2. If still missing, proceed with explicit assumptions.
  3. Prefix assumptions with Assumptions: in the output so the user can correct them quickly.

Stage 3 (Required): Discover Loki and Grafana Versions

Collect or infer:

  • Loki version (example: 2.9.x, 3.0+, unknown)
  • Grafana version (example: 10.x, 11.x, unknown)
  • Deployment context (self-hosted Loki, Grafana Cloud, unknown)

Version compatibility policy:

  1. If versions are known, use the newest compatible syntax only.
  2. If versions are unknown, use compatibility-first syntax and avoid 3.x-only features by default.
  3. For unknown versions, provide an optional "3.x optimized variant" separately.

Avoid by default when version is unknown:

  • Pattern match operators |> and !>
  • approx_topk
  • Structured metadata specific behavior (detected_level, accelerated metadata filtering assumptions)

Stage 4 (Required): Plan Confirmation and Output Mode

Present a plain-English plan, then ask the user to choose output mode.

Plan template:

LogQL Query Plan
Goal: <goal>
Query type: <log or metric>
Streams: <selector>
Filters/parsing: <filters + parser>
Aggregation window: <function and [range]>
Compatibility mode: <version-aware or compatibility-first>

Mode selection template:

  • "Do you want final query only (default) or incremental build (step-by-step)?"

If user does not choose, default to final query only.

Stage 5 (Conditional, Blocking): Reference Checkpoint for Complex Queries

Complex query triggers:

  • Nested aggregations (topk(sum by(...)), multiple sum by, percentiles)
  • Performance-sensitive queries (high volume streams, long ranges)
  • Alerting expressions
  • Template functions (line_format, label_format)
  • Regex-heavy extraction, IP matching, pattern parsing
  • Loki 3.x feature usage

Blocking checkpoint rule:

  1. Read relevant files before generation using explicit file-open/read actions.
  2. Minimum file set:
    • examples/common_queries.logql for syntax and query patterns
    • references/best_practices.md for performance and alerting guidance
  3. Do not generate the final query until this checkpoint is complete.

Fallback when file-read tools are unavailable:

  1. State that reference files could not be read in this environment.
  2. Generate a conservative query (compatibility-first, simpler operators).
  3. Mark result as Unverified against local references.

Stage 6 (Conditional): External Docs Lookup Policy (Context7 Before WebSearch)

Use external lookup only for version-specific behavior, unclear syntax, or advanced features not covered in local references.

Decision order:

  1. Context7 first:
    • mcp__context7__resolve-library-id with libraryName="grafana loki"
    • mcp__context7__query-docs for the exact topic
  2. WebSearch second (fallback only) when:
    • Context7 is unavailable
    • Context7 does not provide required version-specific detail
    • You need latest release/deprecation confirmation

WebSearch fallback constraints:

  • Prefer official Grafana/Loki docs and release notes.
  • Note which statement came from fallback search.

Stage 7 (Required): Generate Query

Stage 7A (Default): Final Query Only

Return one production-ready query plus short explanation.

Stage 7B (Optional): Incremental Build Mode

Use this when requested or when debugging complex pipelines.

Step-by-step template:

  1. Stream selector
  2. Line filter
  3. Parser
  4. Parsed-field filter
  5. Aggregation/window

Stage 8 (Required): Deliver Usage and Checks

Always include:

  1. Final query or incremental sequence
  2. How to run it (Grafana Explore/panel or logcli)
  3. Tunables (labels, thresholds, range)
  4. Any assumptions and compatibility notes

AskUserQuestion Templates

Intake Template

  • "What system/service should this query target?"
  • "Which labels are reliable for stream selection?"
  • "What defines a match (error text, status code, latency threshold, user path)?"
  • "Should output be raw logs or a metric for alert/dashboard?"

Version Template

  • "What Loki version are you running?"
  • "What Grafana version are you using?"
  • "If unknown, should I generate a compatibility-first query and add an optional 3.x variant?"

Ambiguity Follow-up Template

  • "I am missing <field>. Should I assume <default> so I can continue?"

Core Patterns

Stream Selection and Filtering

{job="app"} |= "error" |= "timeout"
{job="app"} |~ "error|fatal|critical"
{job="app"} != "debug"

Parsing

{app="api"} | json | level="error" | status_code >= 500
{app="api"} | logfmt | caller="database.go"
{job="nginx"} | pattern "<ip> - - [<_>] \"<method> <path>\" <status> <size>"

Metric Aggregation

rate({job="app"} | json | level="error" [5m])
sum by (app) (count_over_time({namespace="prod"} | json [5m]))
sum(rate({app="api"} | json | level="error" [5m])) / sum(rate({app="api"}[5m])) * 100
quantile_over_time(0.95, {app="api"} | json | unwrap duration [5m])
topk(10, sum by (error_type) (count_over_time({job="app"} | json | level="error" [1h])))

Formatting and IP Matching

{job="app"} | json | line_format "{{.level}}: {{.message}}"
{job="app"} | json | label_format env=`{{.environment}}`
{job="nginx"} | logfmt | remote_addr = ip("192.168.4.0/24")

Query Construction Rules

  1. Use specific stream selectors (indexed labels first).
  2. Prefer filter order: line filter -> parse -> parsed-field filter.
  3. Prefer parser cost order: pattern > logfmt > json > regexp.
  4. For unknown Loki version, stay on compatibility-first syntax.
  5. For complex/critical queries, complete Stage 5 checkpoint before final output.

Advanced Techniques

Multiple Parsers

{app="api"} | json | regexp "user_(?P<user_id>\\d+)"

Unwrap for Numeric Metrics

sum(sum_over_time({app="api"} | json | unwrap duration [5m]))

Pattern Match Operators (Loki 3.0+, 10x faster than regex)

{service_name=`app`} |> "<_> level=debug <_>"

Logical Operators

{app="api"} | json | (status_code >= 400 and status_code < 500) or level="error"

Offset Modifier

sum(rate({app="api"} | json | level="error" [5m])) - sum(rate({app="api"} | json | level="error" [5m] offset 1d))

Label Operations

{app="api"} | json | keep namespace, pod, level
{app="api"} | json | drop pod, instance

Note: LogQL has no dedup or distinct operators. Use metric aggregations like sum by (field) for programmatic deduplication.

Loki 3.x Key Features

Structured Metadata

High-cardinality data without indexing (trace_id, user_id, request_id):

# Filter AFTER stream selector, NOT in it
{app="api"} | trace_id="abc123" | json | level="error"

Query Acceleration (Bloom Filters)

Place structured metadata filters BEFORE parsers:

# ACCELERATED
{cluster="prod"} | detected_level="error" | logfmt | json
# NOT ACCELERATED
{cluster="prod"} | logfmt | json | detected_level="error"

approx_topk (Probabilistic)

approx_topk(10, sum by (endpoint) (rate({app="api"}[5m])))

vector() for Alerting

sum(count_over_time({app="api"} | json | level="error" [5m])) or vector(0)

Automatic Labels

  • service_name: Auto-populated from container name
  • detected_level: Auto-detected when discover_log_levels: true (stored as structured metadata)

Function Reference

Log Range Aggregations

Function Description
rate(log-range) Entries per second
count_over_time(log-range) Count entries
bytes_rate(log-range) Bytes per second
bytes_over_time(log-range) Total bytes in time range
absent_over_time(log-range) Returns 1 if no logs

Rule:

  • Use bytes_over_time(<log-range>) for raw log-byte volume.
  • Use | unwrap bytes(field) with unwrapped range aggregations for numeric byte fields extracted from log content.

Unwrapped Range Aggregations

Function Description
sum_over_time, avg_over_time, max_over_time, min_over_time Aggregate numeric values
quantile_over_time(φ, range) φ-quantile (0 ≤ φ ≤ 1)
first_over_time, last_over_time First/last value in interval
stddev_over_time Population standard deviation of unwrapped values
stdvar_over_time Population variance of unwrapped values
rate_counter Per-second rate treating values as a monotonically increasing counter

Aggregation Operators

sum, avg, min, max, count, stddev, topk, bottomk, approx_topk, sort, sort_desc

With grouping: sum by (label1, label2) or sum without (label1)

Conversion Functions

Function Description
duration_seconds(label) Convert duration string
bytes(label) Convert byte string (KB, MB)

label_replace()

label_replace(rate({job="api"} |= "err" [1m]), "foo", "$1", "service", "(.*):.*")

Parser Reference

logfmt

| logfmt [--strict] [--keep-empty]
  • --strict: Error on malformed entries
  • --keep-empty: Keep standalone keys

JSON

| json                                           # All fields
| json method="request.method", status="response.status"  # Specific fields
| json servers[0], headers="request.headers[\"User-Agent\"]"  # Nested/array

pattern

| pattern "<ip> - - [<timestamp>] \"<method> <path> <_>\" <status> <size>"

Named placeholders become extracted labels; <_> discards a field.

regexp

| regexp "(?P<level>\\w+): (?P<message>.+)"

Uses named capture groups (?P<name>). Slower than pattern/logfmt/json.

decolorize

| decolorize

Strips ANSI color escape codes. Apply before parsing when logs come from terminal output.

unpack

| unpack

Unpacks log entries that were packed by Promtail's pack pipeline stage. Restores the original log line and any embedded labels.

Template Functions

Common functions for line_format and label_format:

String: trim, upper, lower, replace, trunc, substr, printf, contains, hasPrefix Math: add, sub, mul, div, addf, subf, floor, ceil, round Date: date, now, unixEpoch, toDate, duration_seconds Regex: regexReplaceAll, count Other: fromJson, default, int, float64, __line__, __timestamp__

See examples/common_queries.logql for detailed usage.

Alerting Rules

# Alert when error rate exceeds 5%
(sum(rate({app="api"} | json | level="error" [5m])) / sum(rate({app="api"}[5m]))) > 0.05

# With vector() to avoid "no data"
sum(rate({app="api"} | json | level="error" [5m])) or vector(0) > 10

Error Handling

Issue Solution
No results Check labels exist, verify time range, test stream selector alone
Query slow Use specific selectors, filter before parsing, reduce time range
Parse errors Verify log format matches parser, test JSON validity
High cardinality Use line filters not label filters for unique values, aggregate

Documentation Lookup

Use Stage 6 policy. Trigger external docs for:

Trigger Topic to Search Tool to Use
User mentions Loki 3.x features structured metadata, bloom filters, detected_level Context7 first
approx_topk function needed approx_topk probabilistic Context7 first
Pattern match operators (|>, !>) pattern match operator Context7 first
vector() function for alerting vector function alerting Context7 first
Recording rules configuration recording rules loki Context7 first
Unclear syntax or edge cases Specific function/operator Context7 first
Version-specific behavior questions Version + feature WebSearch fallback
Grafana Alloy integration grafana alloy loki WebSearch fallback

Resources

  • examples/common_queries.logql: Query patterns, template function examples
  • references/best_practices.md: Optimization, anti-patterns, alerting guidance

Example Flows

Example A: Final Query Only (Default)

  1. User asks for 5xx rate by service over 15m.
  2. Capture labels and format (json).
  3. Confirm version and mode (final query only).
  4. Generate one query:
sum by (service) (rate({namespace="prod", app="api"} | json | status_code >= 500 [15m]))

Example B: Incremental Build (Optional)

  1. User asks to debug login failures and requests step-by-step mode.
  2. Provide staged build:
{app="auth"}
{app="auth"} |= "login failed"
{app="auth"} |= "login failed" | json
sum(count_over_time({app="auth"} |= "login failed" | json [5m]))
  1. Explain where to stop if any step returns zero results.

Done Criteria

Mark task done only when all checks pass:

  1. Required stages (1, 2, 3, 4, 7, 8) were completed.
  2. Stage 5 checkpoint was completed for any complex query.
  3. Stage 6 lookup order followed Context7 before WebSearch when external docs were needed.
  4. Output mode was explicitly selected or defaulted (final query only).
  5. Loki/Grafana compatibility assumptions were stated when versions were unknown.
  6. Final output includes query text, usage note, tunables, and assumptions.

Version Notes

  • Loki 3.0+: Bloom filters, structured metadata, pattern match operators (|>, !>)
  • Loki 3.3+: approx_topk function
  • Loki 3.5+: Promtail deprecated (use Grafana Alloy)
  • Loki 3.6+: Horizontally scalable compactor, Loki UI as Grafana plugin

Deprecations: Promtail (use Alloy), BoltDB store (use TSDB with v13 schema)

生成生产级Grafana Loki配置,支持多种部署模式与存储后端。提供脚本自动生成或手动配置,兼容K8s原生及Helm格式,适用于Loki部署、迁移及优化场景。
部署Loki服务 从零创建Loki配置 迁移至Loki系统 配置多租户日志 设置S3/GCS/Azure等存储后端
devops-skills-plugin/skills/loki-config-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill loki-config-generator -g -y
SKILL.md
Frontmatter
{
    "name": "loki-config-generator",
    "description": "Generate\/create Loki configs — ingester, querier, compactor, ruler, S3\/GCS\/Azure backends."
}

Loki Configuration Generator

Overview

Generate production-ready Grafana Loki server configurations with best practices. Supports monolithic, simple scalable, and microservices deployment modes with S3, GCS, Azure, or filesystem storage.

Current Stable: Loki 3.6.2 (November 2025) Important: Promtail deprecated in 3.4 - use Grafana Alloy instead. See examples/grafana-alloy.alloy for the Alloy pipeline and examples/grafana-alloy-daemonset.yaml for the Kubernetes deployment.

When to Use

Invoke when: deploying Loki, creating configs from scratch, migrating to Loki, implementing multi-tenant logging, configuring storage backends, or optimizing existing deployments.


Generation Methods

Method 1: Script Generation (Recommended)

Use scripts/generate_config.py for consistent, validated configurations:

# Simple Scalable with S3 (production)
python3 scripts/generate_config.py \
  --mode simple-scalable \
  --storage s3 \
  --bucket my-loki-bucket \
  --region us-east-1 \
  --retention-days 30 \
  --otlp-enabled \
  --output loki-config.yaml

# Monolithic with filesystem (development)
python3 scripts/generate_config.py \
  --mode monolithic \
  --storage filesystem \
  --no-auth-enabled \
  --output loki-dev.yaml

# Production with Thanos storage (Loki 3.4+)
python3 scripts/generate_config.py \
  --mode simple-scalable \
  --storage s3 \
  --thanos-storage \
  --otlp-enabled \
  --time-sharding \
  --output loki-thanos.yaml

Script Options:

Option Description
--mode monolithic, simple-scalable, microservices
--storage filesystem, s3, gcs, azure
--auth-enabled / --no-auth-enabled Explicitly enable/disable auth
--otlp-enabled Enable OTLP ingestion configuration
--thanos-storage Use Thanos object storage client (3.4+, cloud backends)
--time-sharding Enable out-of-order ingestion (simple-scalable)
--ruler Enable alerting/recording rules (not monolithic)
--horizontal-compactor main/worker mode (simple-scalable, 3.6+)
--zone-awareness Enable multi-AZ placement safeguards
--limits-dry-run Log limit rejections without enforcing

Method 2: Manual Configuration

Follow the staged workflow below when script generation doesn't meet specific requirements or when learning the configuration structure.

Output Formats

For Kubernetes deployments, generate BOTH formats:

  1. Native Loki config (loki-config.yaml) - For ConfigMap or direct use
  2. Helm values (values.yaml) - For Helm chart deployments

See examples/kubernetes-helm-values.yaml for Helm format.


Documentation Lookup

When to Use Context7/Web Search

REQUIRED - Use Context7 MCP for:

  • Configuring features from Loki 3.4+ (Thanos storage, time sharding)
  • Configuring features from Loki 3.6+ (horizontal compactor, enforced labels)
  • Bloom filter configuration (complex, experimental)
  • Custom OTLP attribute mappings beyond standard patterns
  • Troubleshooting configuration errors

OPTIONAL - Skip documentation lookup for:

  • Standard deployment modes (monolithic, simple-scalable)
  • Basic storage configuration (S3, GCS, Azure, filesystem)
  • Default limits and component settings
  • Configurations covered in references/ directory

Context7 MCP (preferred)

resolve-library-id: "grafana loki"
get-library-docs: /websites/grafana_loki, topic: [component]

Example topics: storage_config, limits_config, otlp, compactor, ruler, bloom

Web Search Fallback

Use when Context7 unavailable: "Grafana Loki 3.6 [component] configuration documentation site:grafana.com"


Configuration Workflow

Stage 1: Gather Requirements

Deployment Mode:

Mode Scale Use Case
Monolithic <100GB/day Testing, development
Simple Scalable 100GB-1TB/day Production
Microservices >1TB/day Large-scale, multi-tenant

Storage Backend: S3, GCS, Azure Blob, Filesystem, MinIO

Key Questions: Expected log volume? Retention period? Multi-tenancy needed? High availability requirements? Kubernetes deployment?

Ask the user directly if required information is missing.

Stage 2: Schema Configuration (CRITICAL)

For all new deployments (Loki 2.9+), use TSDB with v13 schema:

schema_config:
  configs:
    - from: "2025-01-01"  # Use deployment date
      store: tsdb
      object_store: s3     # s3, gcs, azure, filesystem
      schema: v13
      index:
        prefix: loki_index_
        period: 24h

Key: Schema cannot change after deployment without migration.

Stage 3: Storage Configuration

S3:

common:
  storage:
    s3:
      s3: s3://us-east-1/loki-bucket
      s3forcepathstyle: false

GCS: gcs: { bucket_name: loki-bucket } Azure: azure: { container_name: loki-container, account_name: ${AZURE_ACCOUNT_NAME} } Filesystem: filesystem: { chunks_directory: /loki/chunks, rules_directory: /loki/rules }

Stage 4: Component Configuration

Ingester:

ingester:
  chunk_encoding: snappy
  chunk_idle_period: 30m
  max_chunk_age: 2h
  chunk_target_size: 1572864  # 1.5MB
  lifecycler:
    ring:
      replication_factor: 3  # 3 for production

Querier:

querier:
  max_concurrent: 4
  query_timeout: 1m

Compactor:

compactor:
  working_directory: /loki/compactor
  compaction_interval: 10m
  retention_enabled: true
  retention_delete_delay: 2h

Stage 5: Limits Configuration

limits_config:
  ingestion_rate_mb: 10
  ingestion_burst_size_mb: 20
  max_streams_per_user: 10000
  max_entries_limit_per_query: 5000
  max_query_length: 721h
  retention_period: 30d
  allow_structured_metadata: true
  volume_enabled: true

Stage 6: Server & Auth

server:
  http_listen_port: 3100
  grpc_listen_port: 9096
  log_level: info

auth_enabled: true  # false for single-tenant

Stage 7: OTLP Ingestion (Loki 3.0+)

Native OpenTelemetry ingestion - use otlphttp exporter (NOT deprecated lokiexporter):

limits_config:
  allow_structured_metadata: true
  otlp_config:
    resource_attributes:
      attributes_config:
        - action: index_label  # Low-cardinality only!
          attributes: [service.name, service.namespace, deployment.environment]
        - action: structured_metadata  # High-cardinality
          attributes: [k8s.pod.name, service.instance.id]

Actions: index_label (searchable, low-cardinality), structured_metadata (queryable), drop

⚠️ NEVER use k8s.pod.name as index_label - use structured_metadata instead.

OTel Collector:

exporters:
  otlphttp:
    endpoint: http://loki:3100/otlp

Stage 8: Caching

chunk_store_config:
  chunk_cache_config:
    memcached_client:
      host: memcached-chunks
      timeout: 500ms

query_range:
  cache_results: true
  results_cache:
    cache:
      memcached_client:
        host: memcached-results

Stage 9: Advanced Features

Pattern Ingester (3.0+):

pattern_ingester:
  enabled: true

Bloom Filters (Experimental, 3.3+): Only for >75TB/month deployments. Works on structured metadata only. See examples/ for config.

Time Sharding (3.4+): For out-of-order ingestion:

limits_config:
  shard_streams:
    time_sharding_enabled: true

Thanos Storage (3.4+): New storage client, opt-in now, default later:

storage_config:
  use_thanos_objstore: true
  object_store:
    s3:
      bucket_name: my-bucket
      endpoint: s3.us-west-2.amazonaws.com

Stage 10: Ruler (Alerting)

ruler:
  storage:
    type: s3
    s3: { bucket_name: loki-ruler }
  alertmanager_url: http://alertmanager:9093
  enable_api: true
  enable_sharding: true

Stage 11: Loki 3.6 Features

  • Horizontally Scalable Compactor: horizontal_scaling_mode: main|worker
  • Policy-Based Enforced Labels: enforced_labels: [service.name]
  • FluentBit v4: structured_metadata parameter support

Stage 12: Validate Configuration (REQUIRED)

Always validate before deployment:

# Syntax and parameter validation
loki -config.file=loki-config.yaml -verify-config

# Print resolved configuration (shows defaults)
loki -config.file=loki-config.yaml -print-config-stderr 2>&1 | head -100

# Dry-run with Docker (if Loki not installed locally)
docker run --rm -v $(pwd)/loki-config.yaml:/etc/loki/config.yaml \
  grafana/loki:3.6.2 -config.file=/etc/loki/config.yaml -verify-config

Validation Checklist:

  • No syntax errors from -verify-config
  • Schema uses tsdb and v13
  • replication_factor: 3 for production
  • auth_enabled: true if multi-tenant
  • Storage credentials/IAM configured
  • Retention period matches requirements

Production Checklist

High Availability Requirements

Zone-Aware Replication (CRITICAL for production multi-AZ deployments):

When using replication_factor: 3, ALWAYS enable zone-awareness for multi-AZ deployments:

ingester:
  lifecycler:
    ring:
      replication_factor: 3
      zone_awareness_enabled: true  # CRITICAL for multi-AZ

# Set zone via environment variable or config
# Each pod should set its zone based on node topology
common:
  instance_availability_zone: ${AVAILABILITY_ZONE}

Why: Without zone-awareness, all 3 replicas may land in the same AZ. If that AZ fails, you lose data.

Kubernetes Implementation:

# In Helm values or pod spec
env:
  - name: AVAILABILITY_ZONE
    valueFrom:
      fieldRef:
        fieldPath: metadata.labels['topology.kubernetes.io/zone']

TLS Configuration (Production Required)

Enable TLS for all inter-component and client communication:

server:
  http_tls_config:
    cert_file: /etc/loki/tls/tls.crt
    key_file: /etc/loki/tls/tls.key
    client_ca_file: /etc/loki/tls/ca.crt  # For mTLS
  grpc_tls_config:
    cert_file: /etc/loki/tls/tls.crt
    key_file: /etc/loki/tls/tls.key
    client_ca_file: /etc/loki/tls/ca.crt

See examples/production-tls.yaml for complete TLS configuration.

Production Checklist Summary

Requirement Setting Required For
replication_factor: 3 common block All production
zone_awareness_enabled: true ingester.lifecycler.ring Multi-AZ
auth_enabled: true root level Multi-tenant
TLS enabled server block All production
IAM roles (not keys) storage config Cloud storage
Caching enabled chunk_store_config, query_range Performance
Pattern ingester pattern_ingester.enabled Observability
Retention configured compactor + limits_config Cost control

Monitoring Recommendations

Key Metrics to Monitor

Configure Prometheus to scrape Loki metrics and alert on these critical indicators:

# Prometheus scrape config
- job_name: 'loki'
  static_configs:
    - targets: ['loki:3100']

Critical Alerts

groups:
  - name: loki-critical
    rules:
      # Ingestion failures
      - alert: LokiIngestionFailures
        expr: sum(rate(loki_distributor_ingester_append_failures_total[5m])) > 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Loki ingestion failures detected"

      # High stream cardinality (performance killer)
      - alert: LokiHighStreamCardinality
        expr: loki_ingester_memory_streams > 100000
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "High stream cardinality - review labels"

      # Compaction not running (retention broken)
      - alert: LokiCompactionStalled
        expr: time() - loki_compactor_last_successful_run_timestamp_seconds > 7200
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Loki compaction stalled - retention not enforced"

      # Query latency
      - alert: LokiSlowQueries
        expr: histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket{route=~"loki_api_v1_query.*"}[5m])) by (le)) > 30
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Loki query P99 latency > 30s"

      # Ingester memory pressure
      - alert: LokiIngesterMemoryHigh
        expr: container_memory_usage_bytes{container="ingester"} / container_spec_memory_limit_bytes{container="ingester"} > 0.8
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Loki ingester memory usage > 80%"

Key Metrics Reference

Metric Description Action Threshold
loki_ingester_memory_streams Active streams in memory >100k: review cardinality
loki_distributor_ingester_append_failures_total Ingestion failures >0: investigate immediately
loki_request_duration_seconds Query latency P99 >30s: add caching/queriers
loki_ingester_chunks_flushed_total Chunk flush rate Low rate: check ingester health
loki_compactor_last_successful_run_timestamp_seconds Last compaction >2h ago: compaction broken

Grafana Dashboard

Import official Loki dashboards:

  • Dashboard ID: 13407 - Loki Logs
  • Dashboard ID: 14055 - Loki Operational

Log Collection with Grafana Alloy

Promtail is deprecated (support ends Feb 2026). Use Grafana Alloy for new deployments.

Basic Alloy Configuration

See examples/grafana-alloy.alloy for the Alloy pipeline and examples/grafana-alloy-daemonset.yaml for the Kubernetes deployment.

// Kubernetes log discovery
discovery.kubernetes "pods" {
  role = "pod"
}

// Relabeling for Kubernetes metadata
discovery.relabel "pods" {
  targets = discovery.kubernetes.pods.targets

  rule {
    source_labels = ["__meta_kubernetes_namespace"]
    target_label  = "namespace"
  }
  rule {
    source_labels = ["__meta_kubernetes_pod_name"]
    target_label  = "pod"
  }
  rule {
    source_labels = ["__meta_kubernetes_pod_container_name"]
    target_label  = "container"
  }
}

// Log collection
loki.source.kubernetes "pods" {
  targets    = discovery.relabel.pods.output
  forward_to = [loki.write.default.receiver]
}

// Send to Loki
loki.write "default" {
  endpoint {
    url = "http://loki-gateway.loki.svc.cluster.local/loki/api/v1/push"

    // For multi-tenant
    tenant_id = "default"
  }
}

Migration from Promtail

# Convert Promtail config to Alloy
alloy convert --source-format=promtail --output=alloy-config.alloy promtail.yaml

Complete Examples

See examples/ directory for full configurations:

  • monolithic-filesystem.yaml - Development/testing
  • simple-scalable-s3.yaml - Production with S3
  • microservices-s3.yaml - Large-scale distributed
  • multi-tenant.yaml - Multi-tenant with per-tenant limits
  • production-tls.yaml - TLS-enabled production config
  • grafana-alloy.alloy - Log collection pipeline with Alloy
  • grafana-alloy-daemonset.yaml - Kubernetes DaemonSet for Alloy
  • kubernetes-helm-values.yaml - Helm chart values

Minimal Monolithic:

auth_enabled: false
server:
  http_listen_port: 3100

common:
  path_prefix: /loki
  storage:
    filesystem:
      chunks_directory: /loki/chunks
      rules_directory: /loki/rules
  replication_factor: 1
  ring:
    kvstore:
      store: inmemory

schema_config:
  configs:
    - from: 2025-01-01
      store: tsdb
      object_store: filesystem
      schema: v13
      index:
        prefix: loki_index_
        period: 24h

limits_config:
  retention_period: 30d
  allow_structured_metadata: true

compactor:
  working_directory: /loki/compactor
  retention_enabled: true

Helm Deployment

helm repo add grafana https://grafana.github.io/helm-charts
helm install loki grafana/loki -f values.yaml

Generate both native config and Helm values for Kubernetes deployments.

# values.yaml
deploymentMode: SimpleScalable

loki:
  schemaConfig:
    configs:
      - from: "2025-01-01"
        store: tsdb
        object_store: s3
        schema: v13
        index:
          prefix: loki_index_
          period: 24h
  limits_config:
    retention_period: 30d
    allow_structured_metadata: true
  # Zone awareness for HA
  ingester:
    lifecycler:
      ring:
        zone_awareness_enabled: true

backend:
  replicas: 3
  # Spread across zones
  topologySpreadConstraints:
    - maxSkew: 1
      topologyKey: topology.kubernetes.io/zone
      whenUnsatisfiable: DoNotSchedule
read:
  replicas: 3
write:
  replicas: 3

Best Practices

Performance:

  • chunk_encoding: snappy, chunk_target_size: 1572864
  • Enable caching (chunks, results)
  • parallelise_shardable_queries: true

Security:

  • auth_enabled: true with reverse proxy auth
  • IAM roles for cloud storage (never hardcode keys)
  • TLS for all communications (see Production Checklist)

Reliability:

  • replication_factor: 3 for production
  • zone_awareness_enabled: true for multi-AZ (see Production Checklist)
  • Persistent volumes for ingesters
  • Monitor ingestion rate and query latency (see Monitoring section)

Limits: Set ingestion_rate_mb, max_streams_per_user to prevent overload


Common Issues

Issue Solution
High ingester memory Reduce max_streams_per_user, lower chunk_idle_period
Slow queries Increase max_concurrent, enable parallelization, add caching
Ingestion failures Check ingestion_rate_mb, verify storage connectivity
Storage growing fast Enable retention, check compression, review cardinality
Data loss in AZ failure Enable zone_awareness_enabled: true
Config validation fails Run loki -verify-config, check YAML syntax

Deprecated (Migrate Away)

  • boltdb-shippertsdb
  • lokiexporterotlphttp
  • Promtail → Grafana Alloy (support ends Feb 2026)

Resources

scripts/generate_config.py - Generate configs programmatically (RECOMMENDED) examples/ - Complete configuration examples for all modes references/ - Full parameter reference and best practices

Related Skills

  • logql-generator - LogQL query generation
  • fluentbit-generator - Log collection to Loki
生成符合最佳实践的C/C++/Python/Go/Java项目Makefile,支持自动化构建、安装及CI/CD集成。通过询问用户补充缺失信息,确保输出包含标准目标、安全加固及GNU规范合规性。
创建新项目Makefile 为特定语言(如Go、C)生成构建脚本 将手动构建流程转换为Makefile 添加标准GNU目标到现有文件
devops-skills-plugin/skills/makefile-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill makefile-generator -g -y
SKILL.md
Frontmatter
{
    "name": "makefile-generator",
    "description": "Create, generate, or scaffold Makefiles with .PHONY targets and build automation."
}

Makefile Generator

Overview

Generate production-ready Makefiles with best practices for C/C++, Python, Go, Java, and generic projects. Features GNU Coding Standards compliance, standard targets, security hardening, and automatic validation via devops-skills:makefile-validator skill.

When to Use

  • Creating new Makefiles from scratch
  • Setting up build systems for projects (C/C++, Python, Go, Java)
  • Implementing build automation and CI/CD integration
  • Converting manual build processes to Makefiles
  • The user asks to "create", "generate", or "write" a Makefile

Do NOT use for: Validating existing Makefiles (use devops-skills:makefile-validator), debugging (use make -d), or running builds.

Trigger Phrases

Use this skill when prompts look like:

  • "Generate a Makefile for a Go service"
  • "Create a production Makefile with install/test/help targets"
  • "Write a Makefile for a C project with dependency tracking"
  • "Add standard GNU targets to this existing Makefile"

Generation Workflow

Stage 1: Gather Requirements

Collect information for the following categories. Use AskUserQuestion when information is missing or ambiguous:

Category Information Needed
Project Language (C/C++/Python/Go/Java), structure (single/multi-directory)
Build Source files, output artifacts, dependencies, build order
Install PREFIX location, directories (bin/lib/share), files to install
Targets all, install, clean, test, dist, help (which are needed?)
Config Compiler, flags, pkg-config dependencies, cross-compilation

When to Use AskUserQuestion (MUST ask if any apply):

Condition Example Question
Language not specified "What programming language is this project? (C/C++/Go/Python/Java)"
Project structure unclear "Is this a single-directory or multi-directory project?"
Docker requested but registry unknown "Which container registry should be used? (docker.io/ghcr.io/custom)"
Multiple binaries possible "Should this build a single binary or multiple executables?"
Install targets needed but paths unclear "Where should binaries be installed? (default: /usr/local/bin)"
Cross-compilation mentioned "What is the target platform/architecture?"

When to Skip AskUserQuestion (proceed with defaults):

  • User explicitly provides all required information
  • Standard project type with obvious defaults (e.g., "Go project with Docker" → use standard Go+Docker patterns)
  • User says "use defaults" or "standard setup"

Default Assumptions (when not asking):

  • Single-directory project structure
  • PREFIX=/usr/local
  • Standard targets: all, build, test, clean, install, help
  • No cross-compilation

Stage 2: Documentation Lookup

When REQUIRED (MUST perform lookup):

  • User requests integration with unfamiliar tools, frameworks, or build systems
  • Complex build patterns not covered in Stage 3 examples (e.g., Bazel, Meson, custom toolchains)
  • Docker/container integration (Dockerfile builds, multi-stage, registry push)
  • CI/CD platform-specific integration (GitHub Actions, GitLab CI, Jenkins)
  • Cross-compilation for unusual targets or embedded systems
  • Package manager integration (Conan, vcpkg, Homebrew formulas)
  • Multi-binary or multi-library projects
  • Version embedding via ldflags or build-time variables

When OPTIONAL (may skip external lookup):

  • Standard language patterns already covered in Stage 3 (C/C++, Go, Python, Java)
  • Simple single-binary projects with no external dependencies
  • User provides complete requirements with no ambiguity
  • Internal docs already cover the required pattern comprehensively

Lookup Process (follow in order):

  1. ALWAYS consult internal docs first using explicit file-open commands (primary source of truth):

    Full doc path map (prefer full paths for deterministic access):

    Doc Full Path
    Structure guide devops-skills-plugin/skills/makefile-generator/docs/makefile-structure.md
    Variables guide devops-skills-plugin/skills/makefile-generator/docs/variables-guide.md
    Targets guide devops-skills-plugin/skills/makefile-generator/docs/targets-guide.md
    Patterns guide devops-skills-plugin/skills/makefile-generator/docs/patterns-guide.md
    Optimization guide devops-skills-plugin/skills/makefile-generator/docs/optimization-guide.md
    Security guide devops-skills-plugin/skills/makefile-generator/docs/security-guide.md
    Requirement Read This Doc
    Docker/container targets .../docs/patterns-guide.md (Pattern 8: Docker Integration)
    Multi-binary projects .../docs/patterns-guide.md (Pattern 7: Multi-Binary Project)
    Go projects with version embedding .../docs/patterns-guide.md (Pattern 5: Go Project)
    Parallel builds, caching, ccache .../docs/optimization-guide.md
    Credentials, secrets, API keys .../docs/security-guide.md
    Complex dependencies, pattern rules .../docs/patterns-guide.md
    Order-only prerequisites .../docs/optimization-guide.md or .../docs/targets-guide.md
    Variables, assignment operators .../docs/variables-guide.md

    Deterministic open/read commands:

    # From repository root:
    sed -n '1,220p' devops-skills-plugin/skills/makefile-generator/docs/patterns-guide.md
    rg -n "Pattern 5|Pattern 8" devops-skills-plugin/skills/makefile-generator/docs/patterns-guide.md
    
    # From skill directory:
    sed -n '1,220p' docs/security-guide.md
    

    If shell commands are unavailable, use the environment's file-open/read capability on the same paths.

    Required Workflow Example (Docker + Go with version embedding):

    # Step 1: Read Go pattern
    rg -n "Pattern 5" devops-skills-plugin/skills/makefile-generator/docs/patterns-guide.md
    
    # Step 2: Read Docker pattern
    rg -n "Pattern 8" devops-skills-plugin/skills/makefile-generator/docs/patterns-guide.md
    
    # Step 3: Read security guidance
    sed -n '1,220p' devops-skills-plugin/skills/makefile-generator/docs/security-guide.md
    

    Then generate Makefile and list consulted docs in a header comment.

  2. Try context7 for external tool documentation (when internal docs don't cover a specific tool):

    # Only needed for tools/frameworks NOT covered in internal docs
    mcp__context7__resolve-library-id: "<tool-name>"
    mcp__context7__query-docs: query="<integration-topic>"
    
    # Example queries:
    # - For Docker: query="dockerfile best practices"
    # - For Go: query="go build ldflags"
    # - For specific tools: query="<tool> makefile integration"
    

    Fallback: If context7 is unavailable or returns nothing useful, record that and continue to Step 3.

  3. Fallback to WebSearch (only if pattern not found in internal docs OR context7):

    "<specific-feature>" makefile best practices 2025
    Example: "docker makefile best practices 2025"
    Example: "go ldflags version makefile 2025"
    

    Trigger WebSearch when: Internal docs don't cover the specific integration AND context7 returns no relevant results.

Note: Document which internal docs you consulted in your response (add comment in generated Makefile header).

Stage 3: Generate Makefile

Optional helper-script fast path (for standard layouts):

# Generate template: TYPE NAME OUTPUT
bash scripts/generate_makefile_template.sh go myservice Makefile

# Add only selected standard targets
bash scripts/add_standard_targets.sh Makefile install clean help

Use manual authoring when requirements are complex (Docker release flow, multi-binary matrices, custom toolchains).

Header (choose one style)

Traditional (POSIX-compatible):

.DELETE_ON_ERROR:
.SUFFIXES:

Modern (GNU Make 4.0+, recommended):

SHELL := bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c
.DELETE_ON_ERROR:
.SUFFIXES:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules

Standard Variables

# User-overridable (use ?=)
CC ?= gcc
CFLAGS ?= -Wall -Wextra -O2
PREFIX ?= /usr/local
DESTDIR ?=

# GNU installation directories
BINDIR ?= $(PREFIX)/bin
LIBDIR ?= $(PREFIX)/lib
INCLUDEDIR ?= $(PREFIX)/include

# Project-specific (use :=)
PROJECT := myproject
VERSION := 1.0.0
SRCDIR := src
BUILDDIR := build
SOURCES := $(wildcard $(SRCDIR)/*.c)
OBJECTS := $(SOURCES:$(SRCDIR)/%.c=$(BUILDDIR)/%.o)

Language-Specific Build Rules

C/C++:

$(TARGET): $(OBJECTS)
	$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(BUILDDIR)/%.o: $(SRCDIR)/%.c
	@mkdir -p $(@D)
	$(CC) $(CPPFLAGS) $(CFLAGS) -MMD -MP -c $< -o $@

-include $(OBJECTS:.o=.d)

Go:

$(TARGET): $(shell find . -name '*.go') go.mod
	go build -o $@ ./cmd/$(PROJECT)

Python:

.PHONY: build
build:
	python -m build

.PHONY: develop
develop:
	pip install -e .[dev]

Java:

$(BUILDDIR)/%.class: $(SRCDIR)/%.java
	@mkdir -p $(@D)
	javac -d $(BUILDDIR) -sourcepath $(SRCDIR) $<

Standard Targets

.PHONY: all clean install uninstall test help

## Build all targets
all: $(TARGET)

## Install to PREFIX
install: all
	install -d $(DESTDIR)$(BINDIR)
	install -m 755 $(TARGET) $(DESTDIR)$(BINDIR)/

## Remove built files
clean:
	$(RM) -r $(BUILDDIR) $(TARGET)

## Run tests
test:
	# Add test commands

## Show help
help:
	@echo "$(PROJECT) v$(VERSION)"
	@echo "Targets: all, install, clean, test, help"
	@echo "Override: make CC=clang PREFIX=/opt"

Stage 4: Validate and Format

Validation is required for every generated Makefile.

Validation Tool Preflight (default + fallback)

  1. Preferred path: run devops-skills:makefile-validator.
  2. If validator skill is unavailable: run local fallback checks:
    # Required fallback check (if make exists)
    make -f <Makefile> -n --dry-run
    
    # Structural fallback checks
    rg -n '^ {1,}\S' <Makefile>         # suspicious space-indented recipe lines
    rg -n '^\.PHONY:' <Makefile>
    
  3. If make is unavailable: run structural checks only, report "partial validation due to missing make binary", and request user confirmation before claiming production readiness.

Required Validation Loop

1. Generate Makefile following stages above
2. Run validator skill (or fallback checks if unavailable)
3. Fix all errors (MUST have 0 errors before completion)
4. Apply formatting fixes (see "Formatting Step" below)
5. Fix warnings when feasible (SHOULD fix; explain if skipped)
6. Address info items for large/production projects
7. Re-run validation until checks pass
8. Output structured validation report (REQUIRED - see format below)

Formatting Step (REQUIRED)

When mbake reports formatting issues, you MUST either:

  1. Auto-apply formatting (preferred for minor issues):

    mbake format <Makefile>
    
  2. Explain why not applied (if formatting would break functionality):

    Formatting not applied because:
    - [specific reason, e.g., "heredoc syntax would be corrupted"]
    - Manual review recommended for: [specific lines]
    

If mbake is not installed or not executable, skip formatter execution and record: Formatting skipped: mbake unavailable in current environment.

Formatting Decision Guide:

mbake Report Action
"Would reformat" with no specific issues Auto-apply with mbake format
Specific whitespace/indentation issues Auto-apply with mbake format
Issues in complex heredocs or multi-line strings Skip formatting, explain in output
Issues in # bake-format off sections Skip (intentionally disabled)
mbake command unavailable Skip formatting, record tool-unavailable reason

Validation Pass Criteria:

Level Requirement Action
Errors (0 required) Syntax errors, missing tabs, invalid targets MUST fix before completion
Warnings (fix if feasible) Formatting issues, missing optimizations SHOULD fix; explain if skipped
Info (address for production) Enhancement suggestions, style preferences SHOULD address for production Makefiles

Known mbake False Positives (can be safely ignored):

The mbake validator may report warnings for valid GNU Make special targets. These are false positives and can be ignored:

mbake Warning Actual Status Explanation
"Unknown special target '.DELETE_ON_ERROR'" ✅ Valid Critical GNU Make target that deletes failed build artifacts
"Unknown special target '.SUFFIXES'" ✅ Valid Standard GNU Make target for disabling/setting suffix rules
"Unknown special target '.ONESHELL'" ✅ Valid GNU Make 3.82+ feature for single-shell recipe execution
"Unknown special target '.POSIX'" ✅ Valid POSIX compliance declaration

Validation Report Output (REQUIRED)

After validation completes, you MUST output a structured report in the following format. This is not optional.

Required Report Format:

## Validation Report

**Result:** [PASSED / PASSED with warnings / FAILED]
**Errors:** [count]
**Warnings:** [count]
**Info:** [count]

### Errors Fixed
- [List each error and how it was fixed, or "None" if 0 errors]

### Warnings Addressed
- [List each warning that was fixed]

### Warnings Skipped (with reasons)
- [List each warning that was NOT fixed and explain why]
- Example: "mbake reports '.DELETE_ON_ERROR' as unknown - this is a valid GNU Make
  special target (false positive)"

### Formatting Applied
- [Yes/No] - [If No, explain why formatting was skipped]

### Info Items Addressed
- [List info items that were addressed for production Makefiles]
- [Or "N/A - simple project" if not applicable]

### Remaining Issues (if any)
- [List any issues requiring user attention]
- [Or "None - Makefile is production-ready"]

Example Complete Report:

## Validation Report

**Result:** PASSED with warnings
**Errors:** 0
**Warnings:** 2
**Info:** 1

### Errors Fixed
- None

### Warnings Addressed
- Fixed: Added error handling to install target (|| exit 1)

### Warnings Skipped (with reasons)
- mbake reports ".DELETE_ON_ERROR" as unknown - this is a valid and critical
  GNU Make special target that ensures failed builds don't leave corrupt files.
  See: https://www.gnu.org/software/make/manual/html_node/Special-Targets.html

### Formatting Applied
- Yes - Applied `mbake format` to fix whitespace issues

### Info Items Addressed
- Added .NOTPARALLEL for Docker targets (parallel safety)
- Added error handling for docker-push target

### Remaining Issues
- None - Makefile is production-ready

Common Info Items to Address:

Info Item When to Fix How to Fix
"mkdir without order-only prerequisites" Large projects (>10 targets) Use target: prereqs | $(BUILDDIR) pattern
"recipe commands lack error handling" Critical operations (install, deploy) Add set -e in .SHELLFLAGS or use && chaining
"consider using ccache" Long compile times Add CC := ccache $(CC) pattern
"parallel-sensitive commands detected" Docker/npm/pip targets Add .NOTPARALLEL: for affected targets or proper dependencies

Production-Quality Requirements (MUST address for Docker/deploy targets):

When generating Makefiles with Docker or deployment targets, you MUST apply these production patterns:

  1. Error Handling for docker-push:

    ## Push Docker image to registry (with error handling)
    docker-push: docker-build
    	@echo "Pushing $(IMAGE)..."
    	docker push $(IMAGE) || { echo "Failed to push $(IMAGE)"; exit 1; }
    	docker push $(IMAGE_LATEST) || { echo "Failed to push $(IMAGE_LATEST)"; exit 1; }
    
  2. Parallel Safety for Docker targets:

    # Prevent parallel execution of Docker targets (race conditions)
    .NOTPARALLEL: docker-build docker-push docker-run
    

    Or use proper dependencies to serialize:

    docker-push: docker-build  # Ensures build completes before push
    docker-run: docker-build   # Ensures build completes before run
    
  3. Install target error handling:

    install: $(TARGET)
    	install -d $(DESTDIR)$(PREFIX)/bin || exit 1
    	install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/ || exit 1
    

Note: When validation shows info items about error handling or parallel safety, you MUST address them for any Makefile containing Docker, deploy, or install targets. Explain in your response which patterns were applied.

Validation Checklist:

  • Syntax correct (make -n passes)
  • All non-file targets have .PHONY
  • Tab indentation (not spaces)
  • No hardcoded credentials
  • User-overridable variables use ?=
  • .DELETE_ON_ERROR present
  • MAKEFLAGS optimizations included (Modern header)
  • Order-only prerequisites for build directories (large projects)
  • Error handling in critical recipes (install, deploy, docker-push)

Best Practices

Variables

  • ?= for user-overridable (CC, CFLAGS, PREFIX)
  • := for project-specific (SOURCES, OBJECTS)
  • Use pkg-config: CFLAGS += $(shell pkg-config --cflags lib)

Targets

  • Always declare .PHONY for non-file targets
  • Default target should be all
  • Use .DELETE_ON_ERROR for safety
  • Document with ## comments for help target

Directory Creation

Two approaches for creating build directories:

Simple (inline mkdir):

$(BUILDDIR)/%.o: $(SRCDIR)/%.c
	@mkdir -p $(@D)
	$(CC) $(CFLAGS) -c $< -o $@

Optimized (order-only prerequisites): Prevents unnecessary rebuilds when directory timestamps change.

$(BUILDDIR):
	@mkdir -p $@

$(BUILDDIR)/%.o: $(SRCDIR)/%.c | $(BUILDDIR)
	$(CC) $(CFLAGS) -c $< -o $@

Use order-only prerequisites (|) for large projects with many targets.

Recipes

  • Use tabs, never spaces
  • Quote variables in shell: $(RM) "$(TARGET)"
  • Use @ prefix for quiet commands
  • Test with make -n first

Helper Scripts (Optional)

These scripts are optional convenience tools for quick template generation.

When to Use Scripts vs Manual Generation

Scenario Recommendation
Simple, standard project (single binary, no special features) ✅ Use generate_makefile_template.sh for speed
Complex project (Docker, multi-binary, custom patterns) ❌ Use manual generation for full control
Adding targets to existing Makefile ✅ Use add_standard_targets.sh
User has specific formatting/style requirements ❌ Use manual generation
Rapid prototyping / proof-of-concept ✅ Use scripts, customize later
Production-ready Makefile ⚠️ Start with script, then customize manually

generate_makefile_template.sh

Generates a complete Makefile template for a specific project type. Script path: scripts/generate_makefile_template.sh

bash scripts/generate_makefile_template.sh [TYPE] [NAME] [OUTPUT_FILE]

Types: c, c-lib, cpp, go, python, java, generic

Example:

bash scripts/generate_makefile_template.sh go myservice
# Creates Makefile with Go patterns, version embedding, standard targets

bash scripts/generate_makefile_template.sh go myservice build/Makefile
# Writes template to build/Makefile (TYPE NAME OUTPUT)

add_standard_targets.sh

Adds missing standard GNU targets to an existing Makefile. Script path: scripts/add_standard_targets.sh

bash scripts/add_standard_targets.sh [MAKEFILE] [TARGETS...]
bash scripts/add_standard_targets.sh [TARGETS...]  # uses ./Makefile

Targets: all, install, uninstall, clean, distclean, test, check, help, dist

Example:

bash scripts/add_standard_targets.sh Makefile install uninstall help
# Adds install, uninstall, help targets if they don't exist

bash scripts/add_standard_targets.sh clean test
# Explicit-target mode: modifies ./Makefile

bash scripts/add_standard_targets.sh -n Makefile dist
# Dry-run mode: shows planned changes without editing files

Note: Manual generation following the Stage 3 patterns produces equivalent results but allows for more customization.

Helper Script Regression Smoke Tests

Run after modifying helper scripts or templates:

bash test/test_helper_scripts.sh

Done Criteria

Consider the task complete only when all checks below are satisfied:

  • Trigger matched and missing requirements were clarified (or documented defaults were applied).
  • Relevant internal docs were opened via explicit file paths before generation.
  • Generated Makefile has complete .PHONY coverage for non-file targets.
  • Go templates include optional go.sum handling and configurable GO_MAIN entrypoint.
  • Validation ran with makefile-validator (preferred) or documented fallback checks.
  • Formatting was applied with mbake, or skipped with an explicit tool-unavailable/compatibility reason.
  • Final response includes the required structured validation report.

Documentation

Detailed guides in docs/:

  • makefile-structure.md - Organization, layout, includes
  • variables-guide.md - Assignment operators, automatic variables
  • targets-guide.md - Standard targets, .PHONY, prerequisites
  • patterns-guide.md - Pattern rules, dependencies
  • optimization-guide.md - Parallel builds, caching
  • security-guide.md - Safe expansion, credential handling

Resources

用于验证、检查和修复 Makefile 及 .mk 文件。支持语法检查、安全审计、最佳实践审查及 CI 前校验,提供确定性执行流程和自动修复循环。
Validate this Makefile Lint my `.mk` file Find issues in this build Makefile Check Makefile security problems Review this Makefile before CI
devops-skills-plugin/skills/makefile-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill makefile-validator -g -y
SKILL.md
Frontmatter
{
    "name": "makefile-validator",
    "description": "Validate, lint, audit, or check Makefiles and .mk files for errors."
}

Makefile Validator

Overview

Use this skill to validate Makefiles with a local-first, deterministic flow.

Default validator entrypoint:

bash scripts/validate_makefile.sh <makefile-path>

Validation layers:

  1. Dependency preflight (python3, pip3, make)
  2. GNU make syntax check (make -n --dry-run) when make is available
  3. mbake validate
  4. mbake format --check
  5. Custom security, best-practice, and optimization checks
  6. Optional checkmake and unmake checks when installed

Trigger Guidance

Use this skill when the request includes Makefile quality, linting, validation, hardening, or troubleshooting.

Trigger Phrases

  • "Validate this Makefile"
  • "Lint my .mk file"
  • "Find issues in this build Makefile"
  • "Check Makefile security problems"
  • "Review this Makefile before CI"

Non-Trigger Examples

  • Creating a brand new Makefile from scratch (use makefile-generator)
  • Running build targets as part of delivery
  • General shell scripting work unrelated to Makefiles

Deterministic Execution Model

Run from this skill directory for shortest commands:

cd devops-skills-plugin/skills/makefile-validator

Step 1: Preflight

  1. Confirm target file exists and is readable.
  2. Confirm whether file edits are allowed (writable) or only suggestions can be returned (read-only).
  3. Prefer the default validator path first; use fallbacks only when blocked by environment constraints.

Step 2: Baseline Validation (Default Path)

# From skill directory
bash scripts/validate_makefile.sh <makefile-path>

# From repository root
bash devops-skills-plugin/skills/makefile-validator/scripts/validate_makefile.sh <makefile-path>

Always record:

  • command executed
  • exit code
  • summary counts (Errors, Warnings, Info)
  • issue locations reported by tools

Step 3: Interpret Output and Exit Code

Exit code Meaning Expected summary line Action
0 no blocking findings Validation PASSED optional improvements only
1 warning-only result Validation PASSED with warnings fix recommended; merge policy dependent
2 error result Validation FAILED - errors must be fixed fix required, then rerun

Step 4: Progressive Reference Loading

Open only the docs required by the current findings.

Finding type Reference doc
.PHONY, .DELETE_ON_ERROR, .ONESHELL, variable usage, performance structure docs/best-practices.md
tabs vs spaces, dependency mistakes, credential patterns, anti-patterns docs/common-mistakes.md
mbake behavior, formatter flags, known mbake caveats docs/bake-tool.md

Step 5: Fix + Rerun Loop

After applying fixes, rerun:

bash scripts/validate_makefile.sh <makefile-path>

Loop rules:

  1. Stop only when no new errors are introduced.
  2. If warnings remain intentionally, document why they are accepted.
  3. Always report the latest rerun exit code.

How to Open Docs

Use explicit file-open commands so paths are unambiguous.

From repository root:

sed -n '1,220p' devops-skills-plugin/skills/makefile-validator/docs/best-practices.md
sed -n '1,220p' devops-skills-plugin/skills/makefile-validator/docs/common-mistakes.md
sed -n '1,220p' devops-skills-plugin/skills/makefile-validator/docs/bake-tool.md
rg -n "PHONY|DELETE_ON_ERROR|ONESHELL|tab|credential|mbake" devops-skills-plugin/skills/makefile-validator/docs/*.md

From devops-skills-plugin/skills/makefile-validator:

sed -n '1,220p' docs/best-practices.md
sed -n '1,220p' docs/common-mistakes.md
sed -n '1,220p' docs/bake-tool.md
rg -n "PHONY|DELETE_ON_ERROR|ONESHELL|tab|credential|mbake" docs/*.md

If shell commands are unavailable, use the environment's file-open/read actions on the same paths.

Fallback Behavior

Use these only when the default validator path cannot run fully.

Constraint Fallback action Reporting requirement
python3 or pip3 unavailable Run limited checks (make -f <file> -n --dry-run if make exists, plus focused grep checks) State that mbake stages were skipped and coverage is reduced
pip3 install mbake fails (offline/proxy/index issue) Keep syntax/custom checks that still work; defer formatter/linter stages Report install failure and request rerun in a network-enabled environment
make unavailable Continue with non-syntax stages; script already downgrades syntax stage Explicitly note syntax coverage was skipped
checkmake or unmake unavailable Continue; these are optional stages Note optional lint/portability coverage not executed
target file is read-only Provide patch suggestions only Mark response as advisory only
command execution unavailable Provide static review from file contents and docs Mark result as non-executed analysis

Minimal fallback commands:

# Syntax only (when make exists)
make -f <makefile-path> -n --dry-run

# Focused quick checks
grep -n "^\\.DELETE_ON_ERROR:" <makefile-path>
grep -n "^\\.PHONY:" <makefile-path>
grep -nE "^(  |    |        )[a-zA-Z@\\$\\(]" <makefile-path>

Example Outcomes Mapped to Exit Codes

Clean Result (exit 0)

Errors:   0
Warnings: 0
Info:     2
✓ Validation PASSED

Warning-Only Result (exit 1)

Errors:   0
Warnings: 3
Info:     1
⚠ Validation PASSED with warnings

Error Result (exit 2)

Errors:   2
Warnings: 1
Info:     0
⚠ Validation FAILED - errors must be fixed

Troubleshooting Quick Start

  1. Verify required tools:
command -v python3 pip3 make
  1. Isolate GNU make syntax failures:
make -f <makefile-path> -n --dry-run
  1. Check likely tab-indentation violations:
grep -nE "^(  |    |        )[a-zA-Z@\\$\\(]" <makefile-path>
  1. Rerun validator with plain output and capture log:
NO_COLOR=1 bash scripts/validate_makefile.sh <makefile-path> > /tmp/makefile-validator.log 2>&1
echo "exit=$? log=/tmp/makefile-validator.log"
  1. If mbake install keeps failing, validate in a network-enabled shell or with an internal PyPI mirror, then rerun the full validator.

Skill Paths

makefile-validator/
├── SKILL.md
├── scripts/
│   └── validate_makefile.sh
├── docs/
│   ├── best-practices.md
│   ├── common-mistakes.md
│   └── bake-tool.md
└── examples/
    ├── good-makefile.mk
    └── bad-makefile.mk

Done Criteria

This skill update is complete when all are true:

  1. Trigger guidance is explicit and easy to identify.
  2. Execution flow is deterministic (preflight -> run -> interpret -> docs -> rerun).
  3. "How to open docs" instructions include exact commands and paths.
  4. Example outcomes are explicitly tied to exit codes (0, 1, 2).
  5. Fallback behavior is documented for missing tools and constrained environments.
  6. Troubleshooting quick-start is concise and runnable.
  7. Frontmatter name and description remain unchanged.
交互式生成生产级PromQL查询、告警及记录规则。通过协作式规划明确监控目标与指标,遵循最佳实践,适用于Grafana仪表盘构建、Alertmanager告警配置及故障排查分析。
创建新的PromQL查询 构建监控仪表盘 实现Prometheus告警规则 指标分析与容量规划 将监控需求转换为PromQL表达式
devops-skills-plugin/skills/promql-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill promql-generator -g -y
SKILL.md
Frontmatter
{
    "name": "promql-generator",
    "description": "Generate\/create\/write PromQL queries, metric expressions, alerting rules, recording rules, Prometheus dashboards."
}

PromQL Query Generator

Overview

This skill provides a comprehensive, interactive workflow for generating production-ready PromQL queries with best practices built-in. Generate queries for monitoring dashboards, alerting rules, and ad-hoc analysis with an emphasis on user collaboration and planning before code generation.

When to Use This Skill

Invoke this skill when:

  • Creating new PromQL queries from scratch
  • Building monitoring dashboards (Grafana, Prometheus UI, etc.)
  • Implementing alerting rules for Prometheus Alertmanager
  • Analyzing metrics for troubleshooting or capacity planning
  • Converting monitoring requirements into PromQL expressions
  • Learning PromQL or teaching others
  • The user asks to "create", "generate", "build", or "write" PromQL queries
  • Working with Prometheus metrics (counters, gauges, histograms, summaries)
  • Implementing RED (Rate, Errors, Duration) or USE (Utilization, Saturation, Errors) metrics

Interactive Query Planning Workflow

CRITICAL: This skill emphasizes interactive planning before query generation. Always engage the user in a collaborative planning process to ensure the generated query matches their exact intentions.

Follow this workflow when generating PromQL queries:

Stage 1: Understand the Monitoring Goal

Start by understanding what the user wants to monitor or measure. Ask clarifying questions to gather requirements:

  1. Primary Goal: What are you trying to monitor or measure?

    • Request rate (requests per second)
    • Error rate (percentage of failed requests)
    • Latency/duration (response times, percentiles)
    • Resource usage (CPU, memory, disk, network)
    • Availability/uptime
    • Queue depth, saturation, throughput
    • Custom business metrics
  2. Use Case: What will this query be used for?

    • Dashboard visualization (Grafana, Prometheus UI)
    • Alerting rule (firing when threshold exceeded)
    • Ad-hoc troubleshooting/analysis
    • Recording rule (pre-computed aggregation)
    • Capacity planning or SLO tracking
  3. Context: Any additional context?

    • Service/application name
    • Team or project
    • Priority level
    • Existing metrics or naming conventions

Use the AskUserQuestion tool to gather this information if not provided.

When to Ask vs. Infer: If the user's initial request already clearly specifies the goal, use case, and context (e.g., "Create an alert for P95 latency > 500ms for payment-service"), you may acknowledge these details in your response instead of re-asking. Only ask clarifying questions for information that is missing or ambiguous.

Stage 2: Identify Available Metrics

Determine which metrics are available and relevant:

  1. Metric Discovery: What metrics are available?

    • Ask the user for metric names
    • If uncertain, suggest common naming patterns
    • Check for metric type indicators in the name:
      • _total suffix → Counter
      • _bucket, _sum, _count suffix → Histogram
      • No suffix → Likely Gauge
      • _created suffix → Counter creation timestamp
  2. Metric Type Identification: Confirm the metric type(s)

    • Counter: Cumulative metric that only increases (or resets to zero)
      • Examples: http_requests_total, errors_total, bytes_sent_total
      • Use with: rate(), irate(), increase()
    • Gauge: Point-in-time value that can go up or down
      • Examples: memory_usage_bytes, cpu_temperature_celsius, queue_length
      • Use with: avg_over_time(), min_over_time(), max_over_time(), or directly
    • Histogram: Buckets of observations with cumulative counts
      • Examples: http_request_duration_seconds_bucket, response_size_bytes_bucket
      • Use with: histogram_quantile(), rate()
    • Summary: Pre-calculated quantiles with count and sum
      • Examples: rpc_duration_seconds{quantile="0.95"}
      • Use _sum and _count for averages; don't average quantiles
  3. Label Discovery: What labels are available on these metrics?

    • Common labels: job, instance, environment, service, endpoint, status_code, method
    • Ask which labels are important for filtering or grouping

Use the AskUserQuestion tool to confirm metric names, types, and available labels.

Stage 3: Determine Query Parameters

Gather specific requirements for the query.

Pre-confirmation for User-Provided Parameters

IMPORTANT: When the user has already specified parameters in their initial request (e.g., "5-minute window", "500ms threshold", "> 5% error rate"), you MUST:

  1. Acknowledge the provided values explicitly in your response
  2. Present them as pre-filled defaults in AskUserQuestion with the first option being "Use specified values"
  3. Allow quick confirmation rather than re-asking for information already given

Example: If user says "alert when P95 latency exceeds 500ms", use:

AskUserQuestion:
- Question: "Confirm the alert threshold?"
- Options:
  1. "500ms (as specified)" - Use the threshold from your request
  2. "Different threshold" - Let me specify a different value

This respects the user's input and speeds up the workflow while still allowing modifications.

  1. Time Range: What time window should the query cover?

    • Instant value (current)
    • Rate over time ([5m], [1h], [1d])
    • For rate calculations: typically [1m] to [5m] for real-time, [1h] to [1d] for trends
    • Rule of thumb: Rate range should be at least 4x the scrape interval
  2. Label Filtering: Which labels should filter the data?

    • Exact matches: job="api-server", status_code="200"
    • Negative matches: status_code!="200"
    • Regex matches: instance=~"prod-.*"
    • Multiple conditions: {job="api", environment="production"}
  3. Aggregation: Should the data be aggregated?

    • No aggregation: Return all time series as-is
    • Aggregate by labels: sum by (job, endpoint), avg by (instance)
    • Aggregate without labels: sum without (instance, pod), avg without (job)
    • Common aggregations: sum, avg, max, min, count, topk, bottomk
  4. Thresholds or Conditions: Are there specific conditions?

    • For alerting: threshold values (e.g., error rate > 5%)
    • For filtering: only show series above/below a value
    • For comparison: compare against historical data (offset)

Use the AskUserQuestion tool to gather or confirm these parameters. When the user has already provided values (e.g., "5-minute window", "> 5%"), present them as the default option for confirmation.

Stage 4: Present the Query Plan

BEFORE GENERATING ANY CODE, present a plain-English query plan and ask for user confirmation:

## PromQL Query Plan

Based on your requirements, here's what the query will do:

**Goal**: [Describe the monitoring goal in plain English]

**Query Structure**:
1. Start with metric: `[metric_name]`
2. Filter by labels: `{label1="value1", label2="value2"}`
3. Apply function: `[function_name]([metric][time_range])`
4. Aggregate: `[aggregation] by ([label_list])`
5. Additional operations: [any calculations, ratios, or transformations]

**Expected Output**:
- Data type: [instant vector/scalar]
- Labels in result: [list of labels]
- Value represents: [what the number means]
- Typical range: [expected value range]

**Example Interpretation**:
If the query returns `0.05`, it means: [plain English explanation]

**Does this match your intentions?**
- If yes, I'll generate the query and validate it
- If no, let me know what needs to change

Use the AskUserQuestion tool to confirm the plan with options:

  • "Yes, generate this query"
  • "Modify [specific aspect]"
  • "Show me alternative approaches"

When the user chooses:

  • "Modify [specific aspect]": ask one focused follow-up question about what to change (metric, labels, function, time range, threshold, or output shape), then present an updated plan before generating.
  • "Show me alternative approaches": provide at least two valid query plans with trade-offs (accuracy, cost, cardinality, readability), then ask the user to choose one before generating.

Stage 5: Generate the PromQL Query

Once the user confirms the plan, generate the actual PromQL query following best practices.

IMPORTANT: Consult Reference Files Before Generating

Before writing any query code, you MUST:

  1. Identify the query category first (histogram, RED, USE, function-specific, optimization, etc.).

  2. Read only the relevant reference section(s) using the Read tool:

    • For histogram queries → Read references/metric_types.md (Histogram section)
    • For error/latency patterns → Read references/promql_patterns.md (RED method section)
    • For resource monitoring → Read references/promql_patterns.md (USE method section)
    • For optimization questions → Read references/best_practices.md
    • For specific functions → Read references/promql_functions.md
    • Re-read a section only if requirements changed or you have not consulted it yet in the current thread.
  3. If a needed reference cannot be read, state the issue and continue with best-effort generation using the most applicable documented pattern you already have.

  4. Cite the applicable pattern or best practice in your response:

    As documented in references/promql_patterns.md (Pattern 3: Latency Percentile):
    # 95th percentile latency
    histogram_quantile(0.95, sum by (le) (rate(...)))
    
  5. Reference example files when generating similar queries:

    Based on examples/red_method.promql (lines 64-82):
    # P95 latency with proper histogram_quantile usage
    

This keeps generated queries aligned with documented patterns while avoiding unnecessary full-file rereads on iterative follow-ups.

Best Practices for Query Generation

  1. Always Use Label Filters

    # Good: Specific filtering reduces cardinality
    rate(http_requests_total{job="api-server", environment="prod"}[5m])
    
    # Bad: Matches all time series, high cardinality
    rate(http_requests_total[5m])
    
  2. Use Appropriate Functions for Metric Types

    # Counter: Use rate() or increase()
    rate(http_requests_total[5m])
    
    # Gauge: Use directly or with *_over_time()
    memory_usage_bytes
    avg_over_time(memory_usage_bytes[5m])
    
    # Histogram: Use histogram_quantile()
    histogram_quantile(0.95,
      sum by (le) (rate(http_request_duration_seconds_bucket[5m]))
    )
    
  3. Apply Aggregations with by() or without()

    # Aggregate by specific labels (keeps only these labels)
    sum by (job, endpoint) (rate(http_requests_total[5m]))
    
    # Aggregate without specific labels (removes these labels)
    sum without (instance, pod) (rate(http_requests_total[5m]))
    
  4. Use Exact Matches Over Regex When Possible

    # Good: Faster exact match
    http_requests_total{status_code="200"}
    
    # Bad: Slower regex match when not needed
    http_requests_total{status_code=~"200"}
    
  5. Calculate Ratios Properly

    # Error rate: errors / total requests
    sum(rate(http_requests_total{status_code=~"5.."}[5m]))
    /
    sum(rate(http_requests_total[5m]))
    
  6. Use Recording Rules for Complex Queries

    • If a query is used frequently or is computationally expensive
    • Pre-aggregate data to reduce query load
    • Follow naming convention: level:metric:operations
  7. Format for Readability

    # Good: Multi-line for complex queries
    histogram_quantile(0.95,
      sum by (le, job) (
        rate(http_request_duration_seconds_bucket{job="api-server"}[5m])
      )
    )
    

Common Query Patterns

Pattern 1: Request Rate

# Requests per second
rate(http_requests_total{job="api-server"}[5m])

# Total requests per second across all instances
sum(rate(http_requests_total{job="api-server"}[5m]))

Pattern 2: Error Rate

# Error ratio (0 to 1)
sum(rate(http_requests_total{job="api-server", status_code=~"5.."}[5m]))
/
sum(rate(http_requests_total{job="api-server"}[5m]))

# Error percentage (0 to 100)
(
  sum(rate(http_requests_total{job="api-server", status_code=~"5.."}[5m]))
  /
  sum(rate(http_requests_total{job="api-server"}[5m]))
) * 100

Pattern 3: Latency Percentile (Histogram)

# 95th percentile latency
histogram_quantile(0.95,
  sum by (le) (
    rate(http_request_duration_seconds_bucket{job="api-server"}[5m])
  )
)

Pattern 4: Resource Usage

# Current memory usage
process_resident_memory_bytes{job="api-server"}

# Average CPU usage over 5 minutes
avg_over_time(process_cpu_seconds_total{job="api-server"}[5m])

Pattern 5: Availability

# Percentage of up instances
(
  count(up{job="api-server"} == 1)
  /
  count(up{job="api-server"})
) * 100

Pattern 6: Saturation/Queue Depth

# Average queue length
avg_over_time(queue_depth{job="worker"}[5m])

# Maximum queue depth in the last hour
max_over_time(queue_depth{job="worker"}[1h])

Stage 6: Validate the Generated Query

ALWAYS attempt to validate the generated query first using the devops-skills:promql-validator skill:

After generating the query, automatically invoke:
Skill(devops-skills:promql-validator)

The devops-skills:promql-validator skill will:
1. Check syntax correctness
2. Validate semantic logic (correct functions for metric types)
3. Identify anti-patterns and inefficiencies
4. Suggest optimizations
5. Explain what the query does
6. Verify it matches user intent

Validation checklist:

  • Syntax is correct (balanced brackets, valid operators)
  • Metric type matches function usage
  • Label filters are specific enough
  • Aggregation is appropriate
  • Time ranges are reasonable
  • No known anti-patterns
  • Query is optimized for performance

If validation fails, fix issues and re-validate until all checks pass.

If the validator skill is unavailable, fails to run, or cannot complete after two fix/re-validate cycles:

  • Report the validator failure briefly (tool unavailable, timeout, parsing error, etc.).
  • Run a manual fallback check (syntax shape, metric/function compatibility, label filtering, aggregation, time range sanity).
  • Mark any unchecked areas as UNVERIFIED and ask the user whether to proceed with best-effort output or provide more context for another validation attempt.

IMPORTANT: Display Validation Results to User

After running validation, you MUST display the structured results to the user in this format:

## PromQL Validation Results

### Syntax Check
- Status: ✅ VALID / ⚠️ WARNING / ❌ ERROR / ⚠️ UNVERIFIED
- Issues: [list any syntax errors]

### Best Practices Check
- Status: ✅ OPTIMIZED / ⚠️ CAN BE IMPROVED / ❌ HAS ISSUES / ⚠️ UNVERIFIED
- Issues: [list any problems found]
- Suggestions: [list optimization opportunities]

### Validation Coverage
- Validator tool run: [successful / failed / unavailable]
- Checks completed: [syntax, semantics, anti-patterns, performance, intent-match]
- Checks skipped: [list any skipped checks, or "None"]

### Query Explanation
- **What it measures**: [plain English description]
- **Output labels**: [list labels in result, or "None (scalar)"]
- **Expected result structure**: [instant vector / scalar / etc.]

This transparency helps users understand the validation process and any recommendations.

Stage 7: Provide Usage Instructions

After generation and validation (or manual fallback validation), provide the user with:

  1. The Final Query:

    [Generated and validated PromQL query]
    
  2. Query Explanation:

    • What the query measures
    • How to interpret the results
    • Expected value range
    • Labels in the output
  3. How to Use It:

    • For Dashboards: Copy into Grafana/Prometheus UI panel query
    • For Alerts: Integrate into Alertmanager rule with threshold
    • For Recording Rules: Add to Prometheus recording rule config
    • For Ad-hoc: Run directly in Prometheus expression browser
  4. Customization Notes:

    • Time ranges that might need adjustment
    • Labels to modify for different environments
    • Threshold values to tune
    • Alternative functions if requirements change
  5. Related Queries:

    • Suggest complementary queries
    • Mention recording rule opportunities
    • Recommend dashboard panels

Native Histograms (Prometheus 3.x+)

Native histograms are now stable in Prometheus 3.0+ (released November 2024). They offer significant advantages over classic histograms:

  • Sparse bucket representation with near-zero cost for empty buckets
  • No configuration of bucket boundaries during instrumentation
  • Coverage of the full float64 range
  • Efficient mergeability across histograms
  • Simpler query syntax

Important: Starting with Prometheus v3.8.0, native histograms are fully stable. However, scraping native histograms still requires explicit activation via the scrape_native_histograms configuration setting. Starting with v3.9, no feature flag is needed but scrape_native_histograms must be set explicitly.

Native vs Classic Histogram Syntax

# Classic histogram (requires _bucket suffix and le label)
histogram_quantile(0.95,
  sum by (job, le) (rate(http_request_duration_seconds_bucket[5m]))
)

# Native histogram (simpler - no _bucket suffix, no le label needed)
histogram_quantile(0.95,
  sum by (job) (rate(http_request_duration_seconds[5m]))
)

Native Histogram Functions

# Get observation count rate from native histogram
histogram_count(rate(http_request_duration_seconds[5m]))

# Get sum of observations from native histogram
histogram_sum(rate(http_request_duration_seconds[5m]))

# Calculate fraction of observations between two values
histogram_fraction(0, 0.1, rate(http_request_duration_seconds[5m]))

# Average request duration from native histogram
histogram_sum(rate(http_request_duration_seconds[5m]))
/
histogram_count(rate(http_request_duration_seconds[5m]))

Detecting Native vs Classic Histograms

Native histograms are identified by:

  • No _bucket suffix on the metric name
  • No le label in the time series
  • The metric stores histogram data directly (not separate bucket counters)

When querying, check if your Prometheus instance has native histograms enabled:

# prometheus.yml - Enable native histogram scraping
scrape_configs:
  - job_name: 'my-app'
    scrape_native_histogram: true  # Prometheus 3.x+

Custom Bucket Native Histograms (NHCB)

Prometheus 3.4+ supports custom bucket native histograms (schema -53), allowing classic histogram to native histogram conversion. This is a key migration path for users with existing classic histograms.

Benefits of NHCB:

  • Keep existing instrumentation (no code changes needed)
  • Store classic histograms as native histograms for lower costs
  • Query with native histogram syntax
  • Improved reliability and compression

Configuration (Prometheus 3.4+):

# prometheus.yml - Convert classic histograms to NHCB on scrape
global:
  scrape_configs:
    - job_name: 'my-app'
      convert_classic_histograms_to_nhcb: true  # Prometheus 3.4+

Querying NHCB:

# Query NHCB metrics the same way as native histograms
histogram_quantile(0.95, sum by (job) (rate(http_request_duration_seconds[5m])))

# histogram_fraction also works with NHCB (Prometheus 3.4+)
histogram_fraction(0, 0.2, rate(http_request_duration_seconds[5m]))

Note: Schema -53 indicates custom bucket boundaries. These histograms with different custom bucket boundaries are generally not mergeable with each other.


SLO, Error Budget, and Burn Rate Patterns

Service Level Objectives (SLOs) are critical for modern SRE practices. These patterns help implement SLO-based monitoring and alerting.

Error Budget Calculation

# Error budget remaining (for 99.9% SLO over 30 days)
# Returns value between 0 and 1 (1 = full budget, 0 = exhausted)
1 - (
  sum(rate(http_requests_total{job="api", status_code=~"5.."}[30d]))
  /
  sum(rate(http_requests_total{job="api"}[30d]))
) / 0.001  # 0.001 = 1 - 0.999 (allowed error rate)

# Simplified: Availability over 30 days
sum(rate(http_requests_total{job="api", status_code!~"5.."}[30d]))
/
sum(rate(http_requests_total{job="api"}[30d]))

Burn Rate Calculation

Burn rate measures how fast you're consuming error budget. A burn rate of 1 means you'll exhaust the budget exactly at the end of the SLO window.

# Current burn rate (1 hour window, 99.9% SLO)
# Burn rate = (current error rate) / (allowed error rate)
(
  sum(rate(http_requests_total{job="api", status_code=~"5.."}[1h]))
  /
  sum(rate(http_requests_total{job="api"}[1h]))
) / 0.001  # 0.001 = allowed error rate for 99.9% SLO

# Burn rate > 1 means consuming budget faster than allowed
# Burn rate of 14.4 consumes 2% of monthly budget in 1 hour

Multi-Window, Multi-Burn-Rate Alerts (Google SRE Standard)

The recommended approach for SLO alerting uses multiple windows to balance detection speed and precision:

# Page-level alert: 2% budget in 1 hour (burn rate 14.4)
# Long window (1h) AND short window (5m) must both exceed threshold
(
  (
    sum(rate(http_requests_total{job="api", status_code=~"5.."}[1h]))
    /
    sum(rate(http_requests_total{job="api"}[1h]))
  ) > 14.4 * 0.001
)
and
(
  (
    sum(rate(http_requests_total{job="api", status_code=~"5.."}[5m]))
    /
    sum(rate(http_requests_total{job="api"}[5m]))
  ) > 14.4 * 0.001
)

# Ticket-level alert: 5% budget in 6 hours (burn rate 6)
(
  (
    sum(rate(http_requests_total{job="api", status_code=~"5.."}[6h]))
    /
    sum(rate(http_requests_total{job="api"}[6h]))
  ) > 6 * 0.001
)
and
(
  (
    sum(rate(http_requests_total{job="api", status_code=~"5.."}[30m]))
    /
    sum(rate(http_requests_total{job="api"}[30m]))
  ) > 6 * 0.001
)

SLO Recording Rules

Pre-compute SLO metrics for efficient alerting:

# Recording rules for SLO calculations
groups:
  - name: slo_recording_rules
    interval: 30s
    rules:
      # Error ratio over different windows
      - record: job:slo_errors_per_request:ratio_rate1h
        expr: |
          sum by (job) (rate(http_requests_total{status_code=~"5.."}[1h]))
          /
          sum by (job) (rate(http_requests_total[1h]))

      - record: job:slo_errors_per_request:ratio_rate5m
        expr: |
          sum by (job) (rate(http_requests_total{status_code=~"5.."}[5m]))
          /
          sum by (job) (rate(http_requests_total[5m]))

      # Availability (success ratio)
      - record: job:slo_availability:ratio_rate1h
        expr: |
          1 - job:slo_errors_per_request:ratio_rate1h

Latency SLO Queries

# Percentage of requests faster than SLO target (200ms)
(
  sum(rate(http_request_duration_seconds_bucket{le="0.2", job="api"}[5m]))
  /
  sum(rate(http_request_duration_seconds_count{job="api"}[5m]))
) * 100

# Requests violating latency SLO (slower than 500ms)
(
  sum(rate(http_request_duration_seconds_count{job="api"}[5m]))
  -
  sum(rate(http_request_duration_seconds_bucket{le="0.5", job="api"}[5m]))
)
/
sum(rate(http_request_duration_seconds_count{job="api"}[5m]))

Burn Rate Reference Table

Burn Rate Budget Consumed Time to Exhaust 30-day Budget Alert Severity
1 100% over 30d 30 days None
2 100% over 15d 15 days Low
6 5% in 6h 5 days Ticket
14.4 2% in 1h ~2 days Page
36 5% in 1h ~20 hours Page (urgent)

Advanced Query Techniques

Using Subqueries

Subqueries enable complex time-based calculations:

# Maximum 5-minute rate over the past 30 minutes
max_over_time(
  rate(http_requests_total[5m])[30m:1m]
)

Syntax: <query>[<range>:<resolution>]

  • <range>: Time window to evaluate over
  • <resolution>: Step size between evaluations

Using Offset Modifier

Compare current data with historical data:

# Compare current rate with rate from 1 week ago
rate(http_requests_total[5m])
-
rate(http_requests_total[5m] offset 1w)

Using @ Modifier

Query metrics at specific timestamps:

# Rate at the end of the range query
rate(http_requests_total[5m] @ end())

# Rate at specific Unix timestamp
rate(http_requests_total[5m] @ 1609459200)

Binary Operators and Vector Matching

Combine metrics with operators and control label matching:

# One-to-one matching (default)
metric_a + metric_b

# Many-to-one with group_left
rate(http_requests_total[5m])
* on (job, instance) group_left (version)
  app_version_info

# Ignoring specific labels
metric_a + ignoring(instance) metric_b

Logical Operators

Filter time series based on conditions:

# Return series only where value > 100
http_requests_total > 100

# Return series present in both
metric_a and metric_b

# Return series in A but not in B
metric_a unless metric_b

Documentation Lookup

If the user asks about specific Prometheus features, operators, or custom metrics:

  1. Try context7 MCP first (preferred):

    Use mcp__context7__resolve-library-id with "prometheus"
    Then use mcp__context7__get-library-docs with:
    - context7CompatibleLibraryID: /prometheus/docs
    - topic: [specific feature, function, or operator]
    - page: 1 (fetch additional pages if needed)
    
  2. Fallback to WebSearch:

    Search query pattern:
    "Prometheus PromQL [function/operator/feature] documentation [version] examples"
    
    Examples:
    "Prometheus PromQL rate function documentation examples"
    "Prometheus PromQL histogram_quantile documentation best practices"
    "Prometheus PromQL aggregation operators documentation"
    

Common Monitoring Scenarios

RED Method (for Request-Driven Services)

  1. Rate: Request throughput

    sum(rate(http_requests_total{job="api"}[5m])) by (endpoint)
    
  2. Errors: Error rate

    sum(rate(http_requests_total{job="api", status_code=~"5.."}[5m]))
    /
    sum(rate(http_requests_total{job="api"}[5m]))
    
  3. Duration: Latency percentiles

    histogram_quantile(0.95,
      sum by (le) (rate(http_request_duration_seconds_bucket{job="api"}[5m]))
    )
    

USE Method (for Resources)

  1. Utilization: Resource usage percentage

    (
      avg(rate(node_cpu_seconds_total{mode!="idle"}[5m]))
      /
      count(node_cpu_seconds_total{mode="idle"})
    ) * 100
    
  2. Saturation: Queue depth or resource contention

    avg_over_time(node_load1[5m])
    
  3. Errors: Error counters

    rate(node_network_receive_errs_total[5m])
    

Alerting Rules

When generating queries for alerting:

  1. Include the Threshold: Make the condition explicit

    # Alert when error rate exceeds 5%
    (
      sum(rate(http_requests_total{status_code=~"5.."}[5m]))
      /
      sum(rate(http_requests_total[5m]))
    ) > 0.05
    
  2. Use Boolean Operators: Return 1 (fire) or 0 (no alert)

    # Returns 1 when memory usage > 90%
    (process_resident_memory_bytes / node_memory_MemTotal_bytes) > 0.9
    
  3. Consider for Duration: Alerts typically use for clause

    alert: HighErrorRate
    expr: |
      (
        sum(rate(http_requests_total{status_code=~"5.."}[5m]))
        /
        sum(rate(http_requests_total[5m]))
      ) > 0.05
    for: 10m  # Only fire after 10 minutes of continuous violation
    

Recording Rules

When generating queries for recording rules:

  1. Follow Naming Convention: level:metric:operations

    # level: aggregation level (job, instance, etc.)
    # metric: base metric name
    # operations: functions applied
    
    - record: job:http_requests:rate5m
      expr: sum by (job) (rate(http_requests_total[5m]))
    
  2. Pre-aggregate Expensive Queries:

    # Recording rule for frequently-used latency query
    - record: job_endpoint:http_request_duration_seconds:p95
      expr: |
        histogram_quantile(0.95,
          sum by (job, endpoint, le) (
            rate(http_request_duration_seconds_bucket[5m])
          )
        )
    
  3. Use Recorded Metrics in Dashboards:

    # Instead of expensive query, use pre-recorded metric
    job_endpoint:http_request_duration_seconds:p95{job="api-server"}
    

Error Handling

Common Issues and Solutions

  1. Empty Results:

    • Check if metrics exist: up{job="your-job"}
    • Verify label filters are correct
    • Check time range is appropriate
    • Confirm metric is being scraped
  2. Too Many Series (High Cardinality):

    • Add more specific label filters
    • Use aggregation to reduce series count
    • Consider using recording rules
    • Check for label explosion (dynamic labels)
  3. Incorrect Values:

    • Verify metric type (counter vs gauge)
    • Check function usage (rate on counters, not gauges)
    • Verify time range is appropriate
    • Check for counter resets
  4. Performance Issues:

    • Reduce time range for range vectors
    • Add label filters to reduce cardinality
    • Use recording rules for complex queries
    • Avoid expensive regex patterns
    • Consider query timeout settings

Communication Guidelines

When generating queries:

  1. Explain the Plan: Always present a plain-English plan before generating
  2. Ask Questions: Use AskUserQuestion tool to gather requirements
  3. Confirm Intent: Verify the query matches user goals before finalizing
  4. Educate: Explain why certain functions or patterns are used
  5. Provide Context: Show how to interpret results
  6. Suggest Improvements: Offer optimizations or alternative approaches
  7. Validate Proactively: Always validate and fix issues
  8. Follow Up: Ask if adjustments are needed

Fallback When AskUserQuestion Is Unavailable

If a structured question tool is unavailable, continue with an explicit inline questionnaire in plain text:

  1. Ask for goal, metric names/types, labels, time range, aggregation, and use case in one compact prompt.
  2. If the user provides partial answers, proceed with conservative defaults and clearly mark assumptions.
  3. If core inputs are still ambiguous, offer 2-3 concrete query-plan options and ask the user to pick one.
  4. Do not block generation indefinitely waiting for perfect context; generate a best-effort query with assumption notes.

Relevant Reference Criteria and Trivial-Case Skip Rules

Use references deterministically, but avoid unnecessary reads for trivial requests.

Read references when ANY of the following is true:

  • Histogram or summary quantiles are requested
  • Query uses joins/vector matching, subqueries, offsets, or recording/alerting rules
  • Query is for SLO/burn-rate/error-budget workflows
  • Query includes optimization or cardinality concerns
  • Metric type is unknown or contested

Skip reference reads only when ALL of the following are true:

  • Single-metric, single-function query (rate, increase, sum, avg, max, min)
  • No joins, no recording/alert rules, no advanced functions
  • Metric type and labels are clearly provided by the user

When skipping, explicitly state: Reference read skipped (trivial case) and keep validation mandatory.

Integration with devops-skills:promql-validator

After generating any PromQL query, automatically invoke the devops-skills:promql-validator skill to ensure quality:

Steps:
1. Generate the PromQL query based on user requirements
2. Invoke devops-skills:promql-validator skill with the generated query
3. Review validation results (syntax, semantics, performance)
4. Fix any issues identified by the validator
5. Re-validate until all checks pass
6. Provide the final validated query with usage instructions
7. Ask user if further refinements are needed

This ensures all generated queries follow best practices and are production-ready.

Resources

IMPORTANT: Explicit Reference Consultation

When generating queries, you SHOULD explicitly read the relevant reference files using the Read tool and cite applicable best practices. This ensures generated queries follow documented patterns and helps users understand why certain approaches are recommended.

references/

promql_functions.md

  • Comprehensive reference of all PromQL functions
  • Grouped by category (aggregation, math, time, histogram, etc.)
  • Usage examples for each function
  • Read this file when: implementing specific function requirements or when user asks about function behavior

promql_patterns.md

  • Common query patterns for typical monitoring scenarios
  • RED method patterns (Rate, Errors, Duration)
  • USE method patterns (Utilization, Saturation, Errors)
  • Alerting and recording rule patterns
  • Read this file when: implementing standard monitoring patterns like error rates, latency, or resource usage

best_practices.md

  • PromQL best practices and anti-patterns
  • Performance optimization guidelines
  • Cardinality management
  • Query structure recommendations
  • Read this file when: optimizing queries, reviewing for anti-patterns, or when cardinality concerns arise

metric_types.md

  • Detailed guide to Prometheus metric types
  • Counter, Gauge, Histogram, Summary
  • When to use each type
  • Appropriate functions for each type
  • Read this file when: clarifying metric type questions or determining appropriate functions for a metric

examples/

common_queries.promql

  • Collection of commonly-used PromQL queries
  • Request rate, error rate, latency queries
  • Resource usage queries
  • Availability and uptime queries
  • Can be copied and customized

red_method.promql

  • Complete RED method implementation
  • Request rate queries
  • Error rate queries
  • Duration/latency queries

use_method.promql

  • Complete USE method implementation
  • Utilization queries
  • Saturation queries
  • Error queries

alerting_rules.yaml

  • Example Prometheus alerting rules
  • Various threshold-based alerts
  • Best practices for alert expressions

recording_rules.yaml

  • Example Prometheus recording rules
  • Pre-aggregated metrics
  • Naming conventions

slo_patterns.promql

  • SLO, error budget, and burn rate queries
  • Multi-window, multi-burn-rate alerting patterns
  • Latency SLO compliance queries

kubernetes_patterns.promql

  • Kubernetes monitoring patterns
  • kube-state-metrics queries (pods, deployments, nodes)
  • cAdvisor container metrics (CPU, memory)
  • Vector matching and joins for Kubernetes

Important Notes

  1. Always Plan Interactively: Never generate a query without confirming the plan with the user
  2. Use AskUserQuestion: Leverage the tool to gather requirements and confirm plans
  3. Validate Everything: Always invoke devops-skills:promql-validator after generation
  4. Educate Users: Explain what the query does and why it's structured that way
  5. Consider Use Case: Tailor the query based on whether it's for dashboards, alerts, or analysis
  6. Think About Performance: Always include label filters and consider cardinality
  7. Follow Metric Types: Use appropriate functions for counters, gauges, and histograms
  8. Format for Readability: Use multi-line formatting for complex queries

Success Criteria

A successful query generation session should meet these measurable checkpoints:

  1. Requirement capture completed: goal/use-case/metric/time-range/aggregation recorded.
  2. Plan confirmation completed: user approved plan OR explicit assumption set documented.
  3. Reference decision recorded: consulted with file names OR skipped (trivial case) with reason.
  4. Query validity completed: syntax passes validator or manual fallback check.
  5. Semantic sanity completed: function choice matches metric type (counter/gauge/histogram/summary).
  6. Cardinality guard completed: query includes explicit filters or aggregation rationale.
  7. Delivery completed: final query + interpretation + next-step customization guidance provided.

Remember

The goal is to collaboratively plan and generate PromQL queries that exactly match user intentions. Always prioritize clarity, correctness, and performance. The interactive planning phase is the most important part of this skill—never skip it!

验证、修复和审计PromQL查询及告警规则。检测语法错误、语义问题及反模式,提供优化建议并解释查询意图,辅助用户澄清需求并提升查询性能与正确性。
用户需要验证PromQL语法或语义 用户希望优化PromQL查询性能 用户请求解释PromQL查询含义 用户需要检查PromQL最佳实践
devops-skills-plugin/skills/promql-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill promql-validator -g -y
SKILL.md
Frontmatter
{
    "name": "promql-validator",
    "description": "Validate, lint, audit, or fix PromQL queries and alerting rules; detects anti-patterns."
}

How This Skill Works

This skill performs multi-level validation and provides interactive query planning:

  1. Syntax Validation: Checks for syntactically correct PromQL expressions
  2. Semantic Validation: Ensures queries make logical sense (e.g., rate() on counters, not gauges)
  3. Anti-Pattern Detection: Identifies common mistakes and inefficient patterns
  4. Optimization Suggestions: Recommends performance improvements
  5. Query Explanation: Translates PromQL to plain English
  6. Interactive Planning: Helps users clarify intent and refine queries

Workflow

When a user provides a PromQL query, follow this workflow:

Working Directory Requirement

Run validation commands from the repository root so relative paths resolve correctly:

cd "$(git rev-parse --show-toplevel)"

If running from another location, use absolute paths to scripts/ files.

Step 1: Validate Syntax

Run the syntax validation script to check for basic correctness:

python3 devops-skills-plugin/skills/promql-validator/scripts/validate_syntax.py "<query>"

Output parsing notes:

  • Exit 0: syntax valid
  • Exit non-zero: syntax failure; include stderr and pinpoint token/position
  • Prefer quoting the smallest failing fragment, then provide corrected query

The script will check for:

  • Valid metric names and label matchers
  • Correct operator usage
  • Proper function syntax
  • Valid time durations and ranges
  • Balanced brackets and quotes
  • Correct use of modifiers (offset, @)

Step 2: Check Best Practices

Run the best practices checker to detect anti-patterns and optimization opportunities:

python3 devops-skills-plugin/skills/promql-validator/scripts/check_best_practices.py "<query>"

Output parsing notes:

  • Treat script sections as independent findings (cardinality, metric-type misuse, regex misuse, etc.)
  • If script output is empty but query is complex, add a manual sanity pass and mark it as manual-review
  • Preserve script wording for finding labels, then add remediation in plain English

The script will identify:

  • High cardinality queries without label filters
  • Inefficient regex matchers that could be exact matches
  • Missing rate()/increase() on counter metrics
  • rate() used on gauge metrics
  • Averaging pre-calculated quantiles
  • Subqueries with excessive time ranges
  • irate() over long time ranges
  • Opportunities to add more specific label filters
  • Complex queries that should use recording rules

Step 3: Explain the Query

Parse and explain what the query does in plain English:

  • What metrics are being queried
  • What type of metrics they are (counter, gauge, histogram, summary)
  • What functions are applied and why
  • What the query calculates
  • What labels will be in the output
  • What the expected result structure looks like

Required Output Details (always include these explicitly):

**Output Labels**: [list labels that will be in the result, or "None (fully aggregated to scalar)"]
**Expected Result Structure**: [instant vector / range vector / scalar] with [N series / single value]

Example:

**Output Labels**: job, instance
**Expected Result Structure**: Instant vector with one series per job/instance combination

Line-Number Citation Method (Required)

When citing examples/docs in recommendations, include file path + 1-based line numbers:

examples/good_queries.promql:42
docs/best_practices.md:88

Rules:

  • Cite the most relevant single line (or start line if multi-line snippet)
  • Keep citations tight; do not cite full files
  • If line numbers are unavailable, state line number unavailable and provide file path

Step 4: Interactive Query Planning (Phase 1 - STOP AND WAIT)

Ask the user clarifying questions to verify the query matches their intent:

  1. Understand the Goal: "What are you trying to monitor or measure?"

    • Request rate, error rate, latency, resource usage, etc.
  2. Verify Metric Type: "Is this a counter (always increasing), gauge (can go up/down), histogram, or summary?"

    • This affects which functions to use
  3. Clarify Time Range: "What time window do you need?"

    • Instant value, rate over time, historical analysis
  4. Confirm Aggregation: "Do you need to aggregate data across labels? If so, which labels?"

    • by (job), by (instance), without (pod), etc.
  5. Check Output Intent: "Are you using this for alerting, dashboarding, or ad-hoc analysis?"

    • Affects optimization priorities

IMPORTANT: Two-Phase Dialogue

After presenting Steps 1-4 results (Syntax, Best Practices, Query Explanation, and Intent Questions):

⏸️ STOP HERE AND WAIT FOR USER RESPONSE

Do NOT proceed to Steps 5-7 until the user answers the clarifying questions. This ensures the subsequent recommendations are tailored to the user's actual intent.

Step 5: Compare Intent vs Implementation (Phase 2 - After User Response)

Only proceed to this step after the user has answered the clarifying questions from Step 4.

After understanding the user's intent:

  • Explain what the current query actually does
  • Highlight any mismatches between intent and implementation
  • Suggest corrections if the query doesn't match the goal
  • Offer alternative approaches if applicable

When relevant, mention known limitations:

  • Note when metric type detection is heuristic-based (e.g., "The script inferred this is a gauge based on the _bytes suffix. Please confirm if this is correct.")
  • Acknowledge when high-cardinality warnings might be false positives (e.g., "This warning may not apply if you're using a recording rule or know your cardinality is low.")

Step 6: Offer Optimizations

Based on validation results:

  • Suggest more efficient query patterns
  • Recommend recording rules for complex/repeated queries
  • Propose better label matchers to reduce cardinality
  • Advise on appropriate time ranges

Reference Examples: When suggesting corrections, cite relevant examples using this format:

As shown in `examples/bad_queries.promql` (lines 91-97):
❌ BAD: `avg(http_request_duration_seconds{quantile="0.95"})`
✅ GOOD: Use histogram_quantile() with histogram buckets

Citation sources:

  • examples/good_queries.promql - for well-formed patterns
  • examples/optimization_examples.promql - for before/after comparisons
  • examples/bad_queries.promql - for showing what to avoid
  • docs/best_practices.md - for detailed explanations
  • docs/anti_patterns.md - for anti-pattern deep dives

Citation Format: file_path (lines X-Y) with the relevant code snippet quoted

Step 7: Let User Plan/Refine

Give the user control:

  • Ask if they want to modify the query
  • Offer to help rewrite it for better performance
  • Provide multiple alternatives if applicable
  • Explain trade-offs between different approaches

Key Validation Rules

Syntax Rules

  1. Metric Names: Must match [a-zA-Z_:][a-zA-Z0-9_:]* or use UTF-8 quoting syntax (Prometheus 3.0+):
    • Quoted form: {"my.metric.with.dots"}
    • Using name label: {__name__="my.metric.with.dots"}
  2. Label Matchers: = (equal), != (not equal), =~ (regex match), !~ (regex not match)
  3. Time Durations: [0-9]+(ms|s|m|h|d|w|y) - e.g., 5m, 1h, 7d
  4. Range Vectors: metric_name[duration] - e.g., http_requests_total[5m]
  5. Offset Modifier: offset <duration> - e.g., metric_name offset 5m
  6. @ Modifier: @ <timestamp> or @ start() / @ end()

Semantic Rules

  1. rate() and irate(): Should only be used with counter metrics (metrics ending in _total, _count, _sum, or _bucket)
  2. Counters: Should typically use rate() or increase(), not raw values
  3. Gauges: Should not use rate() or increase()
  4. Histograms: Use histogram_quantile() with le label and rate() on _bucket metrics
  5. Summaries: Don't average quantiles; calculate from _sum and _count
  6. Aggregations: Use by() or without() to control output labels

Performance Rules

  1. Cardinality: Always use specific label matchers to reduce series count
  2. Regex: Use = instead of =~ when possible for exact matches
  3. Rate Range: Should be at least 4x the scrape interval (typically [2m] minimum)
  4. irate(): Best for short ranges (<5m); use rate() for longer periods
  5. Subqueries: Avoid excessive time ranges that process millions of samples
  6. Recording Rules: Use for complex queries accessed frequently

Anti-Patterns to Detect

High Cardinality Issues

Bad: http_requests_total{}

  • Matches all time series without filtering

Good: http_requests_total{job="api", instance="prod-1"}

  • Specific label filters reduce cardinality

Regex Overuse

Bad: http_requests_total{status=~"2.."}

  • Regex is slower and less precise

Good: http_requests_total{status="200"}

  • Exact match is faster

Missing rate() on Counters

Bad: http_requests_total

  • Counter raw values are not useful (always increasing)

Good: rate(http_requests_total[5m])

  • Rate shows requests per second

rate() on Gauges

Bad: rate(memory_usage_bytes[5m])

  • Gauges measure current state, not cumulative values

Good: memory_usage_bytes

  • Use gauge value directly or with avg_over_time()

Averaging Quantiles

Bad: avg(http_request_duration_seconds{quantile="0.95"})

  • Mathematically invalid to average pre-calculated quantiles

Good: histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

  • Calculate quantile from histogram buckets

Excessive Subquery Ranges

Bad: rate(metric[5m])[90d:1m]

  • Processes millions of samples, very slow

Good: Use recording rules or limit range to necessary duration

irate() Over Long Ranges

Bad: irate(metric[1h])

  • irate() only looks at last two samples, range is wasted

Good: rate(metric[1h]) or irate(metric[5m])

  • Use rate() for longer ranges or reduce irate() range

Mixed Metric Types

Bad: avg(http_request_duration_seconds{quantile="0.95"}) / rate(node_memory_usage_bytes[1h]) + sum(http_requests_total)

  • Combines summary quantiles, gauge metrics, and counters in arithmetic
  • Produces meaningless results

Good: Keep each metric type in separate, purpose-specific queries:

  • Latency: histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))
  • Memory: node_memory_usage_bytes{instance="prod-1"}
  • Request rate: rate(http_requests_total{job="api"}[5m])

Output Format

Provide validation results in this structure:

## PromQL Validation Results

### Syntax Check
- Status: ✅ VALID / ⚠️ WARNING / ❌ ERROR
- Issues: [list any syntax errors with line/position]

### Semantic Check
- Status: ✅ VALID / ⚠️ WARNING / ❌ ERROR
- Issues: [list any logical problems]

### Performance Analysis
- Status: ✅ OPTIMIZED / ⚠️ CAN BE IMPROVED / ❌ INEFFICIENT
- Issues: [list optimization opportunities]
- Suggestions: [specific improvements]

### Query Explanation
Your query: `<query>`

This query does:
- [Plain English explanation]
- Metrics: [list metrics and their types]
- Functions: [explain each function]
- Output: [describe result structure]

### Intent Verification
Let me verify this matches your needs:

1. What are you trying to measure? [your goal here]
2. Is this a counter/gauge/histogram/summary? [metric type]
3. What time range interests you? [time window]
4. Do you need aggregation? If so, by which labels? [aggregation needs]
5. Is this for alerting, dashboarding, or analysis? [use case]

### Recommendations
[Based on the analysis, suggest improvements or alternatives]

Interactive Dialogue

After validation, engage in dialogue:

Claude: "I've validated your query. It's syntactically correct, but I notice it queries http_requests_total without any label filters. This could match thousands of time series. What specific service or endpoint are you trying to monitor?"

User: [provides intent]

Claude: "Great! Based on that, here's an optimized version: rate(http_requests_total{job="api-service", path="/users"}[5m]). This calculates the per-second rate of requests to the /users endpoint over the last 5 minutes. Does this match what you need?"

User: [confirms or asks for changes]

Claude: [provides refined query or alternatives]

Examples

See the examples/ directory for:

  • good_queries.promql: Well-written queries following best practices
  • bad_queries.promql: Common mistakes and anti-patterns (with corrections)
  • optimization_examples.promql: Before/after optimization examples

Documentation

See the docs/ directory for:

  • best_practices.md: Comprehensive PromQL best practices guide
  • anti_patterns.md: Detailed anti-pattern reference with explanations

Important Notes

  1. Be Interactive: Always ask clarifying questions to understand user intent
  2. Be Educational: Explain WHY something is wrong, not just THAT it's wrong
  3. Be Helpful: Offer to rewrite queries, don't just criticize
  4. Be Context-Aware: Consider the user's use case (alerting vs dashboarding)
  5. Be Thorough: Check all four levels (syntax, semantics, performance, intent)
  6. Be Practical: Suggest realistic optimizations, not theoretical perfection

Integration

This skill can be used:

  • Standalone for query review
  • During monitoring setup to validate alert rules
  • When troubleshooting slow Prometheus queries
  • As part of code review for recording rules
  • For teaching PromQL to team members

Validation Tools

The skill uses two main Python scripts:

  1. validate_syntax.py: Pure syntax checking using regex patterns
  2. check_best_practices.py: Semantic and performance analysis

Both scripts output JSON for programmatic parsing and human-readable messages for display.

Success Criteria

A successful validation session should:

  1. Identify all syntax errors
  2. Detect semantic problems
  3. Suggest at least one optimization (if applicable)
  4. Clearly explain what the query does
  5. Verify the query matches user intent
  6. Provide actionable next steps

Known Limitations

The validation scripts have some limitations to be aware of:

Metric Type Detection

  • Heuristic-based: Metric types (counter, gauge, histogram, summary) are inferred from naming conventions (e.g., _total, _bytes)
  • Custom metrics: Metrics with non-standard names may not be correctly classified
  • Recommendation: When the script can't determine metric type, ask the user to clarify

High Cardinality Detection

  • Conservative approach: The script flags metrics without label selectors, but some use cases legitimately query all series
  • Recording rules: Queries using recording rule metrics (e.g., job:http_requests:rate5m) are valid without label filters
  • Recommendation: Use judgment - if the user knows their cardinality is manageable, the warning can be safely ignored

Semantic Validation

  • No runtime context: The scripts cannot verify if metrics actually exist or if label values are valid
  • Schema-agnostic: No knowledge of specific Prometheus deployments or metric schemas
  • Recommendation: For production validation, test queries against actual Prometheus instances

Script Detection Coverage

The scripts detect common anti-patterns but cannot catch:

  • Business logic errors (e.g., calculating the wrong KPI)
  • Context-specific optimizations (depends on scrape interval, retention, etc.)
  • Custom function behavior from extensions

Remember

The goal is not just to validate queries, but to help users write better PromQL and understand their monitoring data. Always be educational, interactive, and helpful!

生成符合最佳实践的 Terraform HCL 配置。需理解需求、查阅文档、遵循安全规范,并强制调用验证器修复错误直至通过,最后提供使用说明。
创建或生成 Terraform .tf 文件 编写基础设施即代码 (IaC) 脚手架 Terraform 资源模块
devops-skills-plugin/skills/terraform-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill terraform-generator -g -y
SKILL.md
Frontmatter
{
    "name": "terraform-generator",
    "description": "Create, generate, write, or scaffold Terraform .tf HCL — resources, modules, providers, variables, outputs."
}

Terraform Generator

Overview

This skill enables the generation of production-ready Terraform configurations following best practices and current standards. Automatically integrates validation and documentation lookup for custom providers and modules.

Critical Requirements Checklist

STOP: You MUST complete ALL steps in order. Do NOT skip any REQUIRED step.

Step Action Required
1 Understand requirements (providers, resources, modules) ✅ REQUIRED
2 Check for custom providers/modules and lookup documentation ✅ REQUIRED
3 Consult reference files before generation ✅ REQUIRED
4 Generate Terraform files with ALL best practices ✅ REQUIRED
5 Include data sources for dynamic values (region, account, AMIs) ✅ REQUIRED
6 Add lifecycle rules on critical resources (KMS, databases) ✅ REQUIRED
7 Invoke Skill(devops-skills:terraform-validator) ✅ REQUIRED
8 FIX all validation/security failures and RE-VALIDATE ✅ REQUIRED
9 Provide usage instructions (files, next steps, security) ✅ REQUIRED

IMPORTANT: If validation fails (terraform validate OR security scan), you MUST fix the issues and re-run validation until ALL checks pass. Do NOT proceed to Step 9 with failing checks.

Core Workflow

When generating Terraform configurations, follow this workflow:

Step 1: Understand Requirements

Analyze the user's request to determine:

  • What infrastructure resources need to be created
  • Which Terraform providers are required (AWS, Azure, GCP, custom, etc.)
  • Whether any modules are being used (official, community, or custom)
  • Version constraints for providers and modules
  • Variable inputs and outputs needed
  • State backend configuration (local, S3, remote, etc.)

Step 2: Check for Custom Providers/Modules

Before generating configurations, identify if custom or third-party providers/modules are involved:

Standard providers (no lookup needed):

  • hashicorp/aws
  • hashicorp/azurerm
  • hashicorp/google
  • hashicorp/kubernetes
  • Other official HashiCorp providers

Custom/third-party providers/modules (require documentation lookup):

  • Third-party providers (e.g., datadog/datadog, mongodb/mongodbatlas)
  • Custom modules from Terraform Registry
  • Private or company-specific modules
  • Community modules

When custom providers/modules are detected:

  1. Use WebSearch to find version-specific documentation:

    Search query format: "[provider/module name] terraform [version] documentation [specific resource]"
    Example: "datadog terraform provider v3.30 monitor resource documentation"
    Example: "terraform-aws-modules vpc version 5.0 documentation"
    
  2. Focus searches on:

    • Official documentation (registry.terraform.io, provider websites)
    • Required and optional arguments
    • Attribute references
    • Example usage
    • Version compatibility notes
  3. If Context7 MCP is available and the provider/module is supported, use it as an alternative:

    mcp__context7__resolve-library-id → mcp__context7__query-docs
    

Step 2.5: Consult Reference Files (REQUIRED)

Before generating configuration, you MUST consult reference files using this matrix:

Reference Requirement Read When
terraform_best_practices.md REQUIRED Always - contains baseline required patterns
provider_examples.md REQUIRED Any AWS, Azure, GCP, or Kubernetes resource generation
common_patterns.md OPTIONAL by default, REQUIRED for complex requests Multi-environment, workspace, composition, DR, or conditional patterns

Open references by path:

devops-skills-plugin/skills/terraform-generator/references/terraform_best_practices.md
devops-skills-plugin/skills/terraform-generator/references/provider_examples.md
devops-skills-plugin/skills/terraform-generator/references/common_patterns.md

Step 3: Generate Terraform Configuration

Generate HCL files following best practices:

File Organization:

terraform-project/
├── main.tf           # Primary resource definitions
├── variables.tf      # Input variable declarations
├── outputs.tf        # Output value declarations
├── versions.tf       # Provider version constraints
├── terraform.tfvars  # Variable values (optional, for examples)
└── backend.tf        # Backend configuration (optional)

Best Practices to Follow:

  1. Provider Configuration:

    terraform {
      required_version = ">= 1.10, < 2.0"
    
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = "~> 6.0"  # Major pin; verify exact current version when needed
        }
      }
    }
    
    provider "aws" {
      region = var.aws_region
    }
    
  2. Resource Naming:

    • Use descriptive resource names
    • Follow snake_case convention
    • Include resource type in name when helpful
    resource "aws_instance" "web_server" {
      # ...
    }
    
  3. Variable Declarations:

    variable "instance_type" {
      description = "EC2 instance type for web servers"
      type        = string
      default     = "t3.micro"
    
      validation {
        condition     = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
        error_message = "Instance type must be t3.micro, t3.small, or t3.medium."
      }
    }
    
  4. Output Values:

    output "instance_public_ip" {
      description = "Public IP address of the web server"
      value       = aws_instance.web_server.public_ip
    }
    
  5. Use Data Sources for References:

    data "aws_ami" "ubuntu" {
      most_recent = true
      owners      = ["099720109477"] # Canonical
    
      filter {
        name   = "name"
        values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
      }
    }
    
  6. Module Usage:

    module "vpc" {
      source  = "terraform-aws-modules/vpc/aws"
      version = "5.0.0"
    
      name = "my-vpc"
      cidr = "10.0.0.0/16"
    
      azs             = ["us-east-1a", "us-east-1b"]
      private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
      public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
    }
    
  7. Use locals for Computed Values:

    locals {
      common_tags = {
        Environment = var.environment
        ManagedBy   = "Terraform"
        Project     = var.project_name
      }
    }
    
  8. Lifecycle Rules When Appropriate:

    resource "aws_instance" "example" {
      # ...
    
      lifecycle {
        create_before_destroy = true
        prevent_destroy       = true
        ignore_changes        = [tags]
      }
    }
    
  9. Dynamic Blocks for Repeated Configuration:

    resource "aws_security_group" "example" {
      # ...
    
      dynamic "ingress" {
        for_each = var.ingress_rules
        content {
          from_port   = ingress.value.from_port
          to_port     = ingress.value.to_port
          protocol    = ingress.value.protocol
          cidr_blocks = ingress.value.cidr_blocks
        }
      }
    }
    
  10. Comments and Documentation:

    • Add comments explaining complex logic
    • Document why certain values are used
    • Include examples in variable descriptions

Security Best Practices:

  • Never hardcode sensitive values (use variables)
  • Use data sources for AMIs and other dynamic values
  • Implement least-privilege IAM policies
  • Enable encryption by default
  • Use secure backend configurations

Required: Data Sources for Dynamic Values (Provider-Aware)

You MUST include provider-appropriate data lookups for dynamic infrastructure values. Do NOT hardcode cloud/account/region/image IDs.

Provider Required Dynamic Context Typical Data Sources
AWS Region/account/AZ/image IDs aws_region, aws_caller_identity, aws_availability_zones, aws_ami
Azure Tenant/subscription/client context azurerm_client_config, azurerm_subscription
GCP Project/client context/zone discovery google_client_config, google_compute_zones, google_compute_image
Kubernetes Cluster endpoint/auth from trusted source Use module outputs or cloud data sources; avoid hardcoded tokens/endpoints
# AWS dynamic context
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}

# Azure dynamic context
data "azurerm_client_config" "current" {}
data "azurerm_subscription" "current" {}

# GCP dynamic context
data "google_client_config" "current" {}

Required: Lifecycle and Deletion Safeguards (Provider-Aware)

You MUST protect stateful and critical resources from accidental destruction/deletion using both Terraform lifecycle and provider-native safeguards.

Provider Critical Resource Classes Required Protection Mechanism
AWS KMS, RDS, S3 data buckets, DynamoDB, ElastiCache, secrets lifecycle { prevent_destroy = true } and service-specific deletion protection where supported
Azure Key Vaults, SQL, Storage, stateful compute prevent_destroy where appropriate plus provider feature flags/resource deletion protection
GCP Cloud SQL, GKE, storage, stateful compute prevent_destroy and resource-level deletion_protection = true where supported
Kubernetes Stateful workloads and persistent data Avoid destructive replacement patterns and protect backing cloud resources
resource "aws_db_instance" "main" {
  # ...
  deletion_protection = true
  lifecycle {
    prevent_destroy = true
  }
}

resource "google_sql_database_instance" "main" {
  # ...
  deletion_protection = true
}

Required: Object Storage Lifecycle Safeguards

When using AWS S3 lifecycle configuration, ALWAYS include a rule to abort incomplete multipart uploads:

resource "aws_s3_bucket_lifecycle_configuration" "main" {
  bucket = aws_s3_bucket.main.id

  # REQUIRED: Abort incomplete multipart uploads to prevent storage costs
  rule {
    id     = "abort-incomplete-uploads"
    status = "Enabled"

    # Filter applies to all objects (empty filter = all objects)
    filter {}

    abort_incomplete_multipart_upload {
      days_after_initiation = 7
    }
  }

  # Other lifecycle rules (e.g., transition to IA)
  rule {
    id     = "transition-to-ia"
    status = "Enabled"

    filter {
      prefix = ""  # Apply to all objects
    }

    transition {
      days          = 90
      storage_class = "STANDARD_IA"
    }

    noncurrent_version_transition {
      noncurrent_days = 30
      storage_class   = "STANDARD_IA"
    }

    noncurrent_version_expiration {
      noncurrent_days = 365
    }
  }
}

Why? Incomplete multipart uploads consume storage and incur costs. Checkov check CKV_AWS_300 enforces this for AWS.

For Azure/GCP object storage, add equivalent lifecycle/retention rules for stale objects and old versions.

Step 4: Validate Generated Configuration (REQUIRED)

After generating Terraform files, ALWAYS validate them using the devops-skills:terraform-validator skill:

Invoke: Skill(devops-skills:terraform-validator)

The devops-skills:terraform-validator skill will:

  1. Check HCL syntax with terraform fmt -check
  2. Initialize the configuration with terraform init
  3. Validate the configuration with terraform validate
  4. Run security scan with Checkov
  5. Perform dry-run testing (if requested) with terraform plan

CRITICAL: Fix-and-Revalidate Loop

If ANY validation or security check fails, you MUST:

  1. Review the error - Understand what failed and why
  2. Fix the issue - Edit the generated file to resolve the problem
  3. Re-run validation - Invoke Skill(devops-skills:terraform-validator) again
  4. Repeat until ALL checks pass - Do NOT proceed with failing checks
┌─────────────────────────────────────────────────────────┐
│  VALIDATION FAILED?                                      │
│                                                          │
│  ┌─────────┐    ┌─────────┐    ┌─────────────────────┐  │
│  │  Fix    │───▶│ Re-run  │───▶│ All checks pass?    │  │
│  │  Issue  │    │ Skill   │    │ YES → Step 5        │  │
│  └─────────┘    └─────────┘    │ NO  → Loop back     │  │
│       ▲                         └─────────────────────┘  │
│       │                                    │             │
│       └────────────────────────────────────┘             │
└─────────────────────────────────────────────────────────┘

Common validation failures to fix:

Check Issue Fix
CKV_AWS_300 Missing abort multipart upload Add abort_incomplete_multipart_upload rule
CKV_AWS_24 SSH open to 0.0.0.0/0 Restrict to specific CIDR
CKV_AWS_16 RDS encryption disabled Add storage_encrypted = true
terraform validate Invalid resource argument Check provider documentation

If custom providers are detected during validation:

  • The devops-skills:terraform-validator skill will automatically fetch documentation
  • Use the fetched documentation to fix any issues

Step 5: Provide Usage Instructions (REQUIRED)

After successful generation and validation with ALL checks passing, you MUST provide the user with:

Required Output Format:

## Generated Files

| File | Description |
|------|-------------|
| `<actual-file-path>` | What was generated in that file |

Only list files that were actually generated for this request. Do not include placeholder paths or files that do not exist.

## Next Steps

1. Review and customize `terraform.tfvars` with your values
2. Initialize Terraform:
   ```bash
   terraform init
  1. Review the execution plan:
    terraform plan
    
  2. Apply the configuration:
    terraform apply
    

Customization Notes

  • Update variable_name in terraform.tfvars
  • Configure backend in backend.tf for remote state
  • Adjust resource names/tags as needed

Security Reminders

⚠️ Before applying:

  • Review IAM policies and permissions
  • Ensure sensitive values are NOT committed to version control
  • Configure state backend with encryption enabled
  • Set up state locking for team collaboration

> **IMPORTANT:** Do NOT skip Step 5. The user needs actionable guidance on how to use the generated configuration.

## Common Generation Patterns

### Pattern 1: Simple Resource Creation

User request: "Create an AWS S3 bucket with versioning"

Generated files:
- `main.tf` - S3 bucket resource with versioning enabled
- `variables.tf` - Bucket name, tags variables
- `outputs.tf` - Bucket ARN and name outputs
- `versions.tf` - AWS provider version constraints

### Pattern 2: Module-Based Infrastructure

User request: "Set up a VPC using the official AWS VPC module"

Actions:
1. Identify module: terraform-aws-modules/vpc/aws
2. Web search for latest version and documentation
3. Generate configuration using module with appropriate inputs
4. Validate with devops-skills:terraform-validator

### Pattern 3: Multi-Provider Configuration

User request: "Create infrastructure across AWS and Datadog"

Actions:
1. Identify standard provider (AWS) and custom provider (Datadog)
2. Web search for Datadog provider documentation with version
3. Generate configuration with both providers properly configured
4. Ensure provider aliases if needed
5. Validate with devops-skills:terraform-validator

### Pattern 4: Complex Resource with Dependencies

User request: "Create an ECS cluster with ALB and auto-scaling"

Generated structure:
- Multiple resource blocks with proper dependencies
- Data sources for AMIs, availability zones, etc.
- Local values for computed configurations
- Comprehensive variables and outputs
- Proper dependency management using implicit references

## Error Handling

**Common Issues and Solutions:**

1. **Provider Not Found:**
   - Ensure provider is listed in `required_providers` block
   - Verify source address format: `namespace/name`
   - Check version constraint syntax

2. **Invalid Resource Arguments:**
   - Refer to web search results for custom providers
   - Check for required vs optional arguments
   - Verify attribute value types (string, number, bool, list, map)

3. **Circular Dependencies:**
   - Review resource references
   - Use `depends_on` explicit dependencies if needed
   - Consider breaking into separate modules

4. **Validation Failures:**
   - Run devops-skills:terraform-validator skill to get detailed errors
   - Fix issues one at a time
   - Re-validate after each fix

## Version Awareness

Always consider version compatibility:

1. **Terraform Version:**
   - Use `required_version` constraint with both lower and upper bounds
   - If generated configuration includes write-only arguments (`*_wo`): use `required_version = ">= 1.11, < 2.0"`.
   - Else if it uses ephemeral constructs (`ephemeral` blocks, ephemeral variables/outputs) without write-only arguments: use `required_version = ">= 1.10, < 2.0"`.
   - Else use the project baseline (default `>= 1.8, < 2.0` unless repository policy requires newer).
   - Use `>= 1.14, < 2.0` for latest features (actions, query command)
   - Document any version-specific features used (see below)

2. **Provider Version Policy (canonical):**
   - Pin provider major versions with `~>` constraints (for example `~> 6.0`, `~> 4.0`, `~> 7.0`).
   - Do not claim "latest" version unless verified online during the current run.
   - Keep cross-provider guidance consistent:
     - AWS family: major-pin policy (for example `~> 6.0`)
     - AzureRM: major-pin policy (for example `~> 4.0`)
     - Google: major-pin policy (for example `~> 7.0`)
     - Kubernetes: major/minor pin based on target cluster/provider compatibility
   - Use the same provider/version language in `SKILL.md`, `references/terraform_best_practices.md`, and template `assets/minimal-project/versions.tf`.

3. **Module Versions:**
   - Always pin module versions
   - Review module documentation for version compatibility
   - Test module updates in non-production first

### Required Version Decision Table

| Generated Output Contains | Required Version to Emit |
|---------------------------|--------------------------|
| Any write-only argument (`*_wo`) | `>= 1.11, < 2.0` |
| Ephemeral constructs only (no write-only) | `>= 1.10, < 2.0` |
| Neither write-only nor ephemeral | Project baseline (default `>= 1.8, < 2.0`) |

#### Feature-Gating Examples

```hcl
# Positive: write-only usage requires Terraform 1.11+
terraform {
  required_version = ">= 1.11, < 2.0"
}

ephemeral "random_password" "db_password" {
  length = 16
}

resource "aws_db_instance" "main" {
  identifier          = "mydb"
  instance_class      = "db.t3.micro"
  allocated_storage   = 20
  engine              = "postgres"
  username            = "admin"
  skip_final_snapshot = true

  password_wo         = ephemeral.random_password.db_password.result
  password_wo_version = 1
}
# Negative: reject this pattern (write-only with Terraform 1.10)
terraform {
  required_version = ">= 1.10, < 2.0"
}

resource "aws_db_instance" "invalid" {
  password_wo = "do-not-generate-this"
}

Terraform Version Feature Matrix

Feature Minimum Version
terraform_data resource 1.4+
import {} blocks 1.5+
check {} blocks 1.5+
Native testing (.tftest.hcl) 1.6+
Test mocking 1.7+
removed {} blocks 1.7+
Provider-defined functions 1.8+
Cross-type refactoring 1.8+
Enhanced variable validations 1.9+
templatestring function 1.9+
Ephemeral resources 1.10+
Write-only arguments 1.11+
S3 native state locking 1.11+
Import blocks with for_each 1.12+
Actions block 1.14+
List resources (tfquery.hcl) 1.14+
terraform query command 1.14+

Modern Terraform Features (1.8+)

Provider-Defined Functions (Terraform 1.8+)

Provider-defined functions extend Terraform's built-in functions with provider-specific logic.

Syntax: provider::<provider_name>::<function_name>(arguments)

# AWS Provider Functions (v5.40+)
locals {
  # Parse an ARN into components
  parsed_arn = provider::aws::arn_parse(aws_instance.web.arn)
  account_id = local.parsed_arn.account
  region     = local.parsed_arn.region

  # Build an ARN from components
  custom_arn = provider::aws::arn_build({
    partition = "aws"
    service   = "s3"
    region    = ""
    account   = ""
    resource  = "my-bucket/my-key"
  })
}

# Google Cloud Provider Functions (v5.23+)
locals {
  # Extract region from zone
  region = provider::google::region_from_zone(var.zone)  # "us-west1-a" → "us-west1"
}

# Kubernetes Provider Functions (v2.28+)
locals {
  # Encode HCL to Kubernetes manifest YAML
  manifest_yaml = provider::kubernetes::manifest_encode(local.deployment_config)
}

Ephemeral Resources (Terraform 1.10+)

Ephemeral resources provide temporary values that are never persisted in state or plan files. Critical for handling secrets securely.

# Generate a password that never touches state
ephemeral "random_password" "db_password" {
  length           = 16
  special          = true
  override_special = "!#$%&*()-_=+[]{}<>:?"
}

# Fetch secrets ephemerally from AWS Secrets Manager
ephemeral "aws_secretsmanager_secret_version" "api_key" {
  secret_id = aws_secretsmanager_secret.api_key.id
}

# Ephemeral variables (declare with ephemeral = true)
variable "temporary_token" {
  type      = string
  ephemeral = true  # Value won't be stored in state
}

# Ephemeral outputs
output "session_token" {
  value     = ephemeral.aws_secretsmanager_secret_version.api_key.secret_string
  ephemeral = true  # Won't be stored in state
}

Write-Only Arguments (Terraform 1.11+)

Write-only arguments accept ephemeral values and are never persisted. They use _wo suffix and require a version attribute.

terraform {
  required_version = ">= 1.11, < 2.0"
}

# Secure database password handling
ephemeral "random_password" "db_password" {
  length = 16
}

resource "aws_db_instance" "main" {
  identifier        = "mydb"
  instance_class    = "db.t3.micro"
  allocated_storage = 20
  engine            = "postgres"
  username          = "admin"

  # Write-only password - never stored in state!
  password_wo         = ephemeral.random_password.db_password.result
  password_wo_version = 1  # Increment to trigger password rotation

  skip_final_snapshot = true
}

# Secrets Manager with write-only
resource "aws_secretsmanager_secret_version" "db_password" {
  secret_id = aws_secretsmanager_secret.db_password.id

  # Write-only secret string
  secret_string_wo         = ephemeral.random_password.db_password.result
  secret_string_wo_version = 1
}

Enhanced Variable Validations (Terraform 1.9+)

Validation conditions can now reference other variables, data sources, and local values.

# Reference data sources in validation
data "aws_ec2_instance_type_offerings" "available" {
  filter {
    name   = "location"
    values = [var.availability_zone]
  }
}

variable "instance_type" {
  type        = string
  description = "EC2 instance type"

  validation {
    # NEW: Can reference data sources
    condition = contains(
      data.aws_ec2_instance_type_offerings.available.instance_types,
      var.instance_type
    )
    error_message = "Instance type ${var.instance_type} is not available in the selected AZ."
  }
}

# Cross-variable validation
variable "min_instances" {
  type    = number
  default = 1
}

variable "max_instances" {
  type    = number
  default = 10

  validation {
    # NEW: Can reference other variables
    condition     = var.max_instances >= var.min_instances
    error_message = "max_instances must be >= min_instances"
  }
}

S3 Native State Locking (Terraform 1.11+)

S3 now supports native state locking without DynamoDB.

terraform {
  backend "s3" {
    bucket       = "my-terraform-state"
    key          = "project/terraform.tfstate"
    region       = "us-east-1"
    encrypt      = true

    # NEW: S3-native locking (Terraform 1.11+)
    use_lockfile = true

    # DEPRECATED: DynamoDB locking (still works but no longer required)
    # dynamodb_table = "terraform-locks"
  }
}

Import Blocks (Terraform 1.5+)

Declarative resource imports without command-line operations.

# Import existing resources declaratively
import {
  to = aws_instance.web
  id = "i-1234567890abcdef0"
}

resource "aws_instance" "web" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.micro"
  # ... configuration must match existing resource
}

# Import with for_each
import {
  for_each = var.existing_bucket_names
  to       = aws_s3_bucket.imported[each.key]
  id       = each.value
}

Moved and Removed Blocks

Safely refactor resources without destroying them.

# Rename a resource
moved {
  from = aws_instance.old_name
  to   = aws_instance.new_name
}

# Move to a module
moved {
  from = aws_vpc.main
  to   = module.networking.aws_vpc.main
}

# Cross-type refactoring (1.8+)
moved {
  from = null_resource.example
  to   = terraform_data.example
}

# Remove resource from state without destroying (1.7+)
removed {
  from = aws_instance.legacy

  lifecycle {
    destroy = false  # Keep the actual resource, just remove from state
  }
}

Import Blocks with for_each (Terraform 1.12+)

Import multiple resources using for_each meta-argument.

# Import multiple S3 buckets using a map
locals {
  buckets = {
    "staging" = "bucket1"
    "uat"     = "bucket2"
    "prod"    = "bucket3"
  }
}

import {
  for_each = local.buckets
  to       = aws_s3_bucket.this[each.key]
  id       = each.value
}

resource "aws_s3_bucket" "this" {
  for_each = local.buckets
}

# Import across module instances using list of objects
locals {
  module_buckets = [
    { group = "one", key = "bucket1", id = "one_1" },
    { group = "one", key = "bucket2", id = "one_2" },
    { group = "two", key = "bucket1", id = "two_1" },
  ]
}

import {
  for_each = local.module_buckets
  id       = each.value.id
  to       = module.group[each.value.group].aws_s3_bucket.this[each.value.key]
}

Actions Block (Terraform 1.14+)

Actions enable provider-defined operations outside the standard CRUD model. Use for operations like Lambda invocations, cache invalidations, or database backups.

# Invoke a Lambda function (example syntax)
action "aws_lambda_invoke" "process_data" {
  function_name = aws_lambda_function.processor.function_name
  payload       = jsonencode({ action = "process" })
}

# Create CloudFront invalidation
action "aws_cloudfront_create_invalidation" "invalidate_cache" {
  distribution_id = aws_cloudfront_distribution.main.id
  paths           = ["/*"]
}

# Actions support for_each
action "aws_lambda_invoke" "batch_process" {
  for_each = toset(["task1", "task2", "task3"])

  function_name = aws_lambda_function.processor.function_name
  payload       = jsonencode({ task = each.value })
}

Triggering Actions via Lifecycle:

Use action_trigger within a resource's lifecycle block to automatically invoke actions:

resource "aws_lambda_function" "example" {
  function_name = "my-function"
  # ... other config ...

  lifecycle {
    action_trigger {
      events  = [after_create, after_update]
      actions = [action.aws_lambda_invoke.process_data]
    }
  }
}

action "aws_lambda_invoke" "process_data" {
  function_name = aws_lambda_function.example.function_name
  payload       = jsonencode({ action = "initialize" })
}

Manual Invocation:

Actions can also be invoked manually via CLI:

terraform apply -invoke action.aws_lambda_invoke.process_data

List Resources and Query Command (Terraform 1.14+)

Query and filter existing infrastructure using .tfquery.hcl files and the terraform query command.

# my-resources.tfquery.hcl
# Define list resources to query existing infrastructure

list "aws_instance" "web_servers" {
  filter {
    name   = "tag:Environment"
    values = [var.environment]
  }

  include_resource = true  # Include full resource details
}

list "aws_s3_bucket" "data_buckets" {
  filter {
    name   = "tag:Purpose"
    values = ["data-storage"]
  }
}
# Query infrastructure and output results
terraform query

# Generate import configuration from query results
terraform query -generate-config-out="import_config.tf"

# Output in JSON format
terraform query -json

# Use with variables
terraform query -var 'environment=prod'

Preconditions and Postconditions (Terraform 1.5+)

Add custom validation within resource lifecycle.

resource "aws_instance" "example" {
  instance_type = "t3.micro"
  ami           = data.aws_ami.example.id

  lifecycle {
    # Check before creation
    precondition {
      condition     = data.aws_ami.example.architecture == "x86_64"
      error_message = "The selected AMI must be for the x86_64 architecture."
    }

    # Verify after creation
    postcondition {
      condition     = self.public_dns != ""
      error_message = "EC2 instance must be in a VPC that has public DNS hostnames enabled."
    }
  }
}

# Preconditions on outputs
output "web_url" {
  value = "https://${aws_instance.web.public_dns}"

  precondition {
    condition     = aws_instance.web.public_dns != ""
    error_message = "Instance must have a public DNS name."
  }
}

Resources

references/

The references/ directory contains detailed documentation for reference:

  • terraform_best_practices.md - Comprehensive best practices guide
  • common_patterns.md - Common Terraform patterns and examples
  • provider_examples.md - Example configurations for popular providers

Open a reference directly by relative path:

devops-skills-plugin/skills/terraform-generator/references/[filename].md

assets/

The assets/ directory contains template files:

  • minimal-project/ - Minimal Terraform project template

Templates can be copied and customized for the user's specific needs.

Notes

  • Always run devops-skills:terraform-validator after generation
  • For feature/version drift checks in CI, run bash scripts/run_ci_checks.sh
  • Web search is essential for custom providers/modules
  • Follow the principle of least surprise in configurations
  • Make configurations readable and maintainable
  • Include helpful comments and documentation
  • Generate realistic examples in terraform.tfvars when helpful
用于验证、检查和审计Terraform配置的工具,执行语法校验、安全扫描及文档查询。需按顺序运行提取信息、查阅参考文档、格式化和多种工具检查,并生成包含修复建议的报告。
需要验证Terraform配置文件(.tf)的语法和结构 执行HCL代码的Linting和格式化 进行Terraform配置的安全合规性审计 调试Terraform错误或缺陷 生成Terraform基础设施的配置报告
devops-skills-plugin/skills/terraform-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill terraform-validator -g -y
SKILL.md
Frontmatter
{
    "name": "terraform-validator",
    "description": "Validate, lint, audit, or plan Terraform\/.tf\/HCL files; runs tflint, checkov, terraform validate."
}

Terraform Validator

Comprehensive toolkit for validating, linting, and testing Terraform configurations with automated workflows for syntax validation, security scanning, and intelligent documentation lookup.

⚠️ Critical Requirements Checklist

STOP: You MUST complete these steps in order. Do NOT skip any REQUIRED step.

Step Action Required
1 Run bash scripts/extract_tf_info_wrapper.sh <path> ✅ REQUIRED
2 Context7 lookup for ALL providers (explicit AND implicit); WebSearch fallback if not found ✅ REQUIRED
3 READ references/security_checklist.md ✅ REQUIRED
4 READ references/best_practices.md ✅ REQUIRED
5 Run terraform fmt ✅ REQUIRED
6 Run tflint (or note as skipped if unavailable) Recommended
7 Run terraform init (if not initialized) ✅ REQUIRED
8 Run terraform validate ✅ REQUIRED
9 Run bash scripts/run_checkov.sh <path> ✅ REQUIRED
10 Cross-reference findings with security_checklist.md sections ✅ REQUIRED
11 Generate report citing reference files ✅ REQUIRED
12 Run regression tests (bash tests/test_regression.sh) ✅ REQUIRED
13 Run lightweight CI checks (bash -n, py_compile, smoke) ✅ REQUIRED

IMPORTANT: Steps 3-4 (reading reference files) must be completed BEFORE running security scans. The reference files contain remediation patterns that MUST be cited in your report.

Context7 Fallback: If Context7 does not have a provider (common for: random, null, local, time, tls), use WebSearch: "terraform-provider-{name} hashicorp documentation"

When to Use This Skill

  • Working with Terraform files (.tf, .tfvars, .tfstate)
  • Validating Terraform configuration syntax and structure
  • Linting and formatting HCL code
  • Performing dry-run testing with terraform plan
  • Debugging Terraform errors or misconfigurations
  • Understanding custom Terraform providers or modules
  • Security validation of Terraform configurations

External Documentation

Tool Documentation
Terraform developer.hashicorp.com/terraform
TFLint github.com/terraform-linters/tflint
Checkov checkov.io
Trivy aquasecurity.github.io/trivy

Validation Workflow

IMPORTANT: Follow this workflow in order. Each step is REQUIRED unless explicitly marked optional.

1. Identify Terraform files in scope
   ├─> Single file, directory, or multi-environment

2. Extract Provider/Module Info (REQUIRED)
   ├─> MUST run: bash scripts/extract_tf_info_wrapper.sh <path>
   ├─> Parse output for providers and modules
   └─> Use for Context7 documentation lookup

3. Lookup Provider Documentation (REQUIRED)
   ├─> For EACH provider detected:
   │   ├─> mcp__context7__resolve-library-id with "terraform-provider-{name}"
   │   ├─> mcp__context7__query-docs for version-specific guidance
   │   └─> If NOT found in Context7: WebSearch fallback (see below)
   └─> Note any custom/private providers for WebSearch

4. Read Reference Files (REQUIRED before validation)
   ├─> MUST READ: references/security_checklist.md (before security scan)
   ├─> MUST READ: references/best_practices.md (for structure validation)
   └─> Reference common_errors.md if errors occur

5. Format and Lint (REQUIRED)
   ├─> MUST run: terraform fmt -recursive (auto-fix formatting)
   ├─> MUST run: terraform fmt -check -recursive (verify no drift)
   ├─> RUN: tflint (or note as skipped if unavailable)
   └─> Report formatting issues

6. Syntax Validation (REQUIRED)
   ├─> MUST run: terraform init (if not initialized)
   ├─> MUST run: terraform validate
   └─> Report syntax errors (consult common_errors.md)

7. Security Scanning (REQUIRED)
   ├─> MUST run: bash scripts/run_checkov.sh <path>
   ├─> Analyze policy violations against security_checklist.md
   └─> Suggest remediations from reference

8. Dry-Run Testing (if credentials available)
   ├─> terraform plan
   ├─> Analyze planned changes
   └─> Report potential issues

9. Regression and Wrapper Determinism Checks (REQUIRED)
   ├─> MUST run: bash tests/test_regression.sh
   ├─> Confirms parser error handling returns non-zero
   ├─> Confirms implicit provider detection for docs lookup
   ├─> Confirms wrapper argument handling is deterministic
   └─> Confirms checkov wrapper preserves scanner exit code

10. Lightweight CI Checks (REQUIRED)
   ├─> MUST run: bash -n scripts/*.sh
   ├─> MUST run: python3 -m py_compile scripts/*.py
   ├─> MUST run: smoke check for extract wrapper on sample fixture
   └─> Record command outputs and exit codes

11. Generate Comprehensive Report
   ├─> Include all findings with severity
   ├─> Reference best_practices.md for recommendations
   └─> Offer to fix issues if appropriate

Required Reference File Reading

You MUST read these reference files during validation:

When Reference File Action
Before security scan references/security_checklist.md Read to understand security checks and remediation patterns
During validation references/best_practices.md Read to validate project structure, naming, and patterns
If errors occur references/common_errors.md Read to find solutions for specific error messages
If using Terraform 1.10+ references/advanced_features.md Read to understand ephemeral values, actions, list resources

Required Script Usage

You MUST use these wrapper scripts instead of calling tools directly:

Task Script Command
Extract provider/module info extract_tf_info_wrapper.sh bash scripts/extract_tf_info_wrapper.sh <path>
Run security scan run_checkov.sh bash scripts/run_checkov.sh <path>
Install checkov (if missing) install_checkov.sh bash scripts/install_checkov.sh install

Note: extract_tf_info_wrapper.sh automatically handles the python-hcl2 dependency. If system Python lacks python-hcl2, it creates/reuses a cached virtual environment under ~/.cache/terraform-validator/ by default.

Script Run Context (REQUIRED)

  • Default working directory: devops-skills-plugin/skills/terraform-validator
  • If running from elsewhere, use absolute script paths:
    • bash /absolute/path/to/terraform-validator/scripts/extract_tf_info_wrapper.sh <path>
    • bash /absolute/path/to/terraform-validator/scripts/run_checkov.sh <path>
    • bash /absolute/path/to/terraform-validator/scripts/install_checkov.sh install

Context7 Provider Documentation Lookup (REQUIRED)

For EVERY provider detected, you MUST lookup documentation via Context7:

1. Run extract_tf_info_wrapper.sh to get provider list
2. For each provider (e.g., "aws", "google", "azurerm"):
   a. Call: mcp__context7__resolve-library-id with "terraform-provider-{name}"
   b. Call: mcp__context7__query-docs with the resolved ID
   c. Note version-specific features and constraints
3. Include relevant provider guidance in validation report

Example for AWS provider:

mcp__context7__resolve-library-id("terraform-provider-aws")
mcp__context7__query-docs(context7CompatibleLibraryID, "best practices")

Context7 Fallback to WebSearch (REQUIRED)

If Context7 does not find a provider, you MUST fall back to WebSearch:

1. If mcp__context7__resolve-library-id returns no results or provider not found:
   a. Use WebSearch with query: "terraform-provider-{name} hashicorp documentation"
   b. For specific version: "terraform-provider-{name} {version} documentation site:registry.terraform.io"
2. Common providers NOT in Context7 (use WebSearch directly):
   - random (hashicorp/random)
   - null (hashicorp/null)
   - local (hashicorp/local)
   - time (hashicorp/time)
   - tls (hashicorp/tls)
3. Document in report: "Provider docs via WebSearch (not in Context7)"

WebSearch Fallback Example:

# If Context7 fails for random provider:
WebSearch("terraform-provider-random hashicorp documentation site:registry.terraform.io")

Note: HashiCorp utility providers (random, null, local, time, tls, archive, external, http) may not be indexed in Context7. Always fall back to WebSearch for these.

Detecting Implicit Providers (REQUIRED)

IMPORTANT: Providers can be used without being declared in required_providers. You MUST detect ALL providers:

Detection Methods

  1. Explicit Providers: Listed in required_providers block (from extract_tf_info_wrapper.sh output)
  2. Implicit Providers: Inferred from resource type prefixes

Common Implicit Provider Patterns

Resource Type Prefix Provider Name Context7 Lookup
random_* random terraform-provider-random
null_* null terraform-provider-null
local_* local terraform-provider-local
tls_* tls terraform-provider-tls
time_* time terraform-provider-time
archive_* archive terraform-provider-archive
http (data source) http terraform-provider-http
external (data source) external terraform-provider-external

Workflow for Complete Provider Detection

1. Parse extract_tf_info_wrapper.sh output
2. Get providers from "providers" array (explicit)
3. Get resources from "resources" array
4. For EACH resource type:
   a. Extract prefix (e.g., "random" from "random_id")
   b. Check if already in providers list
   c. If NOT in providers: add as implicit provider
5. Perform Context7 lookup for ALL providers (explicit + implicit)

Example

If extract_tf_info_wrapper.sh returns:

{
  "providers": [{"name": "aws", ...}],
  "resources": [
    {"type": "aws_instance", ...},
    {"type": "random_id", ...}
  ]
}

You MUST lookup BOTH:

  • terraform-provider-aws (explicit)
  • terraform-provider-random (implicit - detected from random_id resource)

Quick Reference Commands

Format and Lint

# Check formatting (dry-run)
terraform fmt -check -recursive .

# Apply formatting
terraform fmt -recursive .

# Run tflint (requires .tflint.hcl config)
tflint --init              # Install plugins
tflint --recursive         # Lint all modules
tflint --format compact    # Compact output

TFLint Configuration: See TFLint Ruleset documentation for plugin setup.

Validate Configuration

# Initialize (downloads providers and modules)
terraform init

# Validate syntax
terraform validate

# Validate with JSON output
terraform validate -json

Security Scanning

MUST use wrapper script:

# Use the wrapper script (REQUIRED)
bash scripts/run_checkov.sh ./terraform

# With specific options
bash scripts/run_checkov.sh -f json ./terraform
bash scripts/run_checkov.sh --compact ./terraform

Detailed Security Scanning: You MUST read references/security_checklist.md before running security scans to understand the checks and remediation patterns.

Security Finding Cross-Reference (REQUIRED)

When reporting security findings, you MUST cite specific sections from security_checklist.md:

Cross-Reference Mapping

Checkov Check Pattern security_checklist.md Section
CKV_AWS_24 (SSH open) "Overly Permissive Security Groups"
CKV_AWS_260 (HTTP open) "Overly Permissive Security Groups"
CKV_AWS_16 (RDS encryption) "Encryption at Rest"
CKV_AWS_17 (RDS public) "RDS Databases"
CKV_AWS_130 (public subnet) "Network Security"
CKV_AWS_53-56 (S3 public access) "Public S3 Buckets"
CKV_AWS_* (IAM) "IAM Security"
CKV_AWS_79 (IMDSv1) "ECS/EKS"
Hardcoded passwords "Hardcoded Credentials"
Sensitive outputs "Sensitive Output Exposure"

Report Template for Security Findings

### Security Issue: [Check ID]

**Finding:** [Description from checkov]
**Resource:** [Resource name and file:line]
**Severity:** [HIGH/MEDIUM/LOW]

**Reference:** security_checklist.md - "[Section Name]"

**Remediation Pattern:**
[Copy relevant code example from security_checklist.md]

**Recommended Fix:**
[Specific fix for this configuration]

Example Cross-Referenced Report

### Security Issue: CKV_AWS_24

**Finding:** Security group allows SSH from 0.0.0.0/0
**Resource:** aws_security_group.web (main.tf:47-79)
**Severity:** HIGH

**Reference:** security_checklist.md - "Overly Permissive Security Groups"

**Remediation Pattern (from reference):**
```hcl
variable "admin_cidr" {
  description = "CIDR block for admin access"
  type        = string
}

resource "aws_security_group" "app" {
  ingress {
    description = "SSH from admin network only"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.admin_cidr]
  }
}
```

**Recommended Fix:** Replace `cidr_blocks = ["0.0.0.0/0"]` with a variable or specific CIDR range.

Dry-Run Testing

# Generate execution plan
terraform plan

# Save plan to file
terraform plan -out=tfplan

# Plan with specific var file
terraform plan -var-file="production.tfvars"

# Plan with target resource
terraform plan -target=aws_instance.example

Plan Output Symbols:

  • + Resources to be created
  • - Resources to be destroyed
  • ~ Resources to be modified
  • -/+ Resources to be replaced

Handling Missing Tools

When validation tools are not installed, follow this recovery workflow:

Recovery Workflow (REQUIRED)

1. Detect missing tool
2. Inform user what is missing and why it's needed
3. Provide installation command
4. ASK user: "Would you like me to install [tool] and continue?"
5. If yes: Run installation and RERUN the validation step
6. If no: Note as skipped in report, continue with available tools

Tool-Specific Recovery

If checkov is missing:

1. Inform: "Checkov is not installed. It's required for security scanning."
2. Ask: "Would you like me to install it? I'll use: bash scripts/install_checkov.sh install"
3. If yes: Run install script, then rerun security scan

If tflint is missing:

1. Inform: "TFLint is not installed. It provides advanced linting beyond terraform validate."
2. Ask: "Would you like me to install it?"
3. Provide: brew install tflint (macOS) or installation script (Linux)

If python-hcl2 is missing:

The extract_tf_info_wrapper.sh script handles this automatically by creating
or reusing a cached venv. No user action required.

Required tools: terraform fmt, terraform init, terraform validate Required for full security validation: checkov Optional but recommended: tflint

Scripts

Script Purpose Usage
extract_tf_info_wrapper.sh Parse Terraform files for providers/modules (auto-handles dependencies) bash scripts/extract_tf_info_wrapper.sh <path>
extract_tf_info.py Core parser (requires python-hcl2) Use wrapper instead
run_checkov.sh Wrapper for Checkov scans with enhanced output bash scripts/run_checkov.sh <path>
install_checkov.sh Install Checkov in isolated venv bash scripts/install_checkov.sh install

Reference Documentation

MUST READ during validation workflow:

Reference When to Read Content
references/security_checklist.md Before security scan Security validation, Checkov/Trivy usage, common policies, remediation patterns
references/best_practices.md During validation Project structure, naming conventions, module design, state management
references/common_errors.md When errors occur Error database with causes and solutions
references/advanced_features.md If Terraform >= 1.10 Ephemeral values (1.10+), Actions (1.14+), List Resources (1.14+)

Workflow Examples

Example 1: Validate Single File

1. MUST: bash scripts/extract_tf_info_wrapper.sh main.tf
2. MUST: Context7 lookup for each provider detected
3. MUST: Read references/security_checklist.md
4. MUST: Read references/best_practices.md
5. RUN: terraform fmt -check main.tf
6. RUN: terraform init (if needed) && terraform validate
7. MUST: bash scripts/run_checkov.sh -f json main.tf
8. Report issues with remediation from references
9. If custom providers: WebSearch for documentation

Example 2: Full Module Validation

1. Identify all .tf files in directory
2. MUST: bash scripts/extract_tf_info_wrapper.sh ./modules/vpc/
3. MUST: Context7 lookup for ALL providers
4. MUST: Read references/security_checklist.md
5. MUST: Read references/best_practices.md
6. RUN: terraform fmt -recursive
7. RUN: tflint --recursive (or note as skipped if unavailable)
8. RUN: terraform init && terraform validate
9. MUST: bash scripts/run_checkov.sh ./modules/vpc/
10. Analyze findings against security_checklist.md
11. Validate structure against best_practices.md
12. Provide comprehensive report with references

Example 3: Production Dry-Run

1. Verify terraform initialized
2. MUST: Read references/security_checklist.md (production focus)
3. RUN: terraform plan -var-file="production.tfvars"
4. Analyze for unexpected changes
5. Highlight create/modify/destroy operations
6. Flag security concerns (compare with security_checklist.md)
7. Recommend whether safe to apply

Advanced Features

Terraform 1.10+ introduces ephemeral values for secure secrets management. Terraform 1.14+ adds Actions for imperative operations and List Resources for querying infrastructure.

MUST READ: references/advanced_features.md when:

  • Terraform version >= 1.10 is detected
  • Configuration uses ephemeral blocks
  • Configuration uses action blocks
  • Configuration uses .tfquery.hcl files

Integration with Other Skills

  • k8s-yaml-validator - For Terraform Kubernetes provider validation
  • helm-validator - When Terraform manages Helm releases
  • k8s-debug - For debugging infrastructure provisioned by Terraform

Notes

  • Always run validation in order: extract info → lookup docs → read refs → format → lint → validate → security → plan
  • MUST use wrapper scripts for extract_tf_info and checkov
  • MUST run bash tests/test_regression.sh after script changes
  • MUST run lightweight CI checks: bash -n scripts/*.sh and python3 -m py_compile scripts/*.py
  • MUST read reference files before relevant validation steps
  • MUST lookup provider docs via Context7 for ALL providers
  • MUST offer recovery/rerun when tools are missing
  • Never commit without running terraform fmt
  • Always review plan output before applying
  • Use version constraints for all providers and modules
  • Use remote state for team collaboration
  • Enable state locking to prevent concurrent modifications

Done Criteria

  • Validation instructions are executable end-to-end with one deterministic command path.
  • Wrapper scripts behave predictably in both success and failure paths (including propagated non-zero exits).
  • Regression tests cover parser error handling, implicit provider detection, wrapper argument handling, and checkov exit-code behavior.
  • Lightweight CI checks (bash -n, py_compile, smoke checks) pass before final reporting.
生成符合最佳实践的Terragrunt HCL配置文件,支持根配置、子模块、多环境布局及Stacks。自动验证并遵循命名规范与安全标准,涵盖依赖连接、源设置及2025新特性如Feature Flags和OpenTofu引擎支持。
生成 root.hcl, terragrunt.hcl 或 stack 文件 创建多环境 Terragrunt 布局 配置 Terragrunt 依赖关系 设置模块来源 生成 Stack catalog 单元
devops-skills-plugin/skills/terragrunt-generator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill terragrunt-generator -g -y
SKILL.md
Frontmatter
{
    "name": "terragrunt-generator",
    "description": "Generate\/create\/scaffold Terragrunt HCL files — root.hcl, terragrunt.hcl, child modules, stacks, multi-env layouts."
}

Terragrunt Generator

Overview

Generate production-ready Terragrunt configurations following current best practices, naming conventions, and security standards. All generated configurations are automatically validated.

Trigger Phrases

Use this skill when the user asks for:

  • A new root.hcl, terragrunt.hcl, or terragrunt.stack.hcl
  • Multi-environment Terragrunt layouts (dev/staging/prod)
  • Terragrunt dependency wiring (dependency or dependencies blocks)
  • Terragrunt module source setup (local, Git, Terraform Registry via tfr:///)
  • Stack catalog unit generation under catalog/units/*

Terragrunt 2025 Features Supported:

  • Stacks - Infrastructure blueprints with terragrunt.stack.hcl (GA since v0.78.0)
  • Feature Flags - Runtime control via feature blocks
  • Exclude Blocks - Fine-grained execution control (replaces deprecated skip)
  • Errors Blocks - Advanced error handling (replaces deprecated retryable_errors)
  • OpenTofu Engine - Alternative IaC engine support

Root Configuration Naming

RECOMMENDED: Use root.hcl instead of terragrunt.hcl for root files per migration guide.

Approach Root File Include Syntax
Modern root.hcl find_in_parent_folders("root.hcl")
Legacy terragrunt.hcl find_in_parent_folders()

Include standard: Default to find_in_parent_folders("root.hcl") in all new examples and generated configs. Use find_in_parent_folders() only when explicitly targeting a legacy root file named terragrunt.hcl.

Architecture Patterns

CRITICAL: Before generating ANY configuration, you MUST determine the architecture pattern and understand its constraints.

Pattern A: Multi-Environment with Environment-Agnostic Root

Use when: Managing multiple environments (dev/staging/prod) with shared root configuration.

Key principle: root.hcl is environment-agnostic - it does NOT read environment-specific files.

infrastructure/
├── root.hcl              # Environment-AGNOSTIC (no env.hcl references)
├── dev/
│   ├── env.hcl           # Environment variables (locals block)
│   ├── vpc/terragrunt.hcl
│   └── rds/terragrunt.hcl
└── prod/
    ├── env.hcl           # Environment variables (locals block)
    ├── vpc/terragrunt.hcl
    └── rds/terragrunt.hcl

Root.hcl constraints:

  • ❌ CANNOT use read_terragrunt_config(find_in_parent_folders("env.hcl")) - env.hcl doesn't exist at root level
  • ❌ CANNOT reference local.environment or local.aws_region that come from env.hcl
  • ✅ CAN use static values or get_env() for runtime configuration
  • ✅ CAN use ${path_relative_to_include()} for state keys (this works dynamically)

Child modules read env.hcl:

# dev/vpc/terragrunt.hcl
include "root" {
  path = find_in_parent_folders("root.hcl")
}

locals {
  env = read_terragrunt_config(find_in_parent_folders("env.hcl"))
}

inputs = {
  name = "${local.env.locals.environment}-vpc"  # Works: env.hcl exists in dev/
}

Pattern B: Single Environment or Environment-Aware Root

Use when: Single environment OR all environments share the same root with environment detection.

infrastructure/
├── root.hcl              # Can be environment-aware via get_env() or directory parsing
├── account.hcl           # Account-level config (optional)
├── region.hcl            # Region-level config (optional)
└── vpc/
    └── terragrunt.hcl

Root.hcl can detect environment:

# root.hcl - environment detection via directory path
locals {
  # Parse environment from path (e.g., "prod/vpc" -> "prod")
  path_parts  = split("/", path_relative_to_include())
  environment = local.path_parts[0]

  # OR use environment variable
  environment = get_env("TG_ENVIRONMENT", "dev")
}

Pattern C: Shared Environment Variables (_env directory)

Use when: Centralizing environment variables with symlinks or direct references.

infrastructure/
├── root.hcl              # Environment-AGNOSTIC
├── _env/                 # Centralized environment definitions
│   ├── prod.hcl
│   ├── staging.hcl
│   └── dev.hcl
├── prod/
│   ├── env.hcl           # Reads from _env/prod.hcl
│   └── vpc/terragrunt.hcl
└── dev/
    ├── env.hcl           # Reads from _env/dev.hcl
    └── vpc/terragrunt.hcl

env.hcl reads from _env:

# prod/env.hcl
locals {
  env_vars = read_terragrunt_config("${get_repo_root()}/_env/prod.hcl")

  # Re-export for child modules
  environment        = local.env_vars.locals.environment
  aws_region         = local.env_vars.locals.aws_region
  vpc_cidr           = local.env_vars.locals.vpc_cidr
  # ... other variables
}

Architecture Pattern Selection Checklist (Canonical)

MANDATORY: Before writing any files, you MUST complete this checklist and OUTPUT it to the user with checkmarks filled in. This is not optional.

Output this completed checklist before generating any files:

## Architecture Pattern Selection

[x] Identified architecture pattern: Pattern ___ (A/B/C)
[x] Root.hcl scope: [ ] environment-agnostic  OR  [ ] environment-aware
[x] env.hcl location: ___________________
[x] Child modules access env via: ___________________
[x] Verified: No file references a path that doesn't exist from its location

Example completed checklist:

## Architecture Pattern Selection

[x] Identified architecture pattern: Pattern A (Multi-Environment with Environment-Agnostic Root)
[x] Root.hcl scope: [x] environment-agnostic  OR  [ ] environment-aware
[x] env.hcl location: dev/env.hcl, prod/env.hcl (one per environment)
[x] Child modules access env via: read_terragrunt_config(find_in_parent_folders("env.hcl"))
[x] Verified: No file references a path that doesn't exist from its location

Quick Variable Definition Examples

Use these starter files for Pattern B and account/region-aware setups.

env.hcl

locals {
  environment = "dev"
  aws_region  = "us-east-1"
  project     = "platform"
}

account.hcl

locals {
  account_id   = "123456789012"
  account_name = "shared-services"
}

region.hcl

locals {
  aws_region = "us-east-1"
}

When to Use

  • Creating new Terragrunt projects or configurations
  • Setting up multi-environment infrastructure (dev/staging/prod)
  • Implementing DRY Terraform configurations
  • Managing complex infrastructure with dependencies
  • Working with custom Terraform providers or modules

Core Capabilities

1. Generate Root Configuration

Create root-level root.hcl or terragrunt.hcl with remote state, provider config, and common variables.

MANDATORY: Before generating, READ the template file:

Read: assets/templates/root/terragrunt.hcl

Template: assets/templates/root/terragrunt.hcl Patterns: references/common-patterns.md → Root Configuration Patterns

Key placeholders to replace:

  • [BUCKET_NAME], [AWS_REGION], [DYNAMODB_TABLE]
  • [TERRAFORM_VERSION], [PROVIDER_NAME], [PROVIDER_SOURCE], [PROVIDER_VERSION]
  • [ENVIRONMENT], [PROJECT_NAME]

Root.hcl Design Principles:

  1. Environment-agnostic by default - Don't assume env.hcl exists at root level
  2. Use static values for provider/backend region - Or use get_env() for runtime config
  3. State key uses path_relative_to_include() - This automatically includes environment path
  4. Provider tags can be static - Environment-specific tags go in child modules

2. Generate Child Module Configuration

Create child modules with dependencies, mock outputs, and proper includes.

MANDATORY: Before generating, READ the template file:

Read: assets/templates/child/terragrunt.hcl

Template: assets/templates/child/terragrunt.hcl Patterns: references/common-patterns.md → Child Module Patterns

Module source options:

  • Local: "../../modules/vpc"
  • Git: "git::https://github.com/org/repo.git//path?ref=v1.0.0"
  • Registry: "tfr:///terraform-aws-modules/vpc/aws?version=5.1.0"

3. Generate Standalone Module

Self-contained modules without root dependency.

MANDATORY: Before generating, READ the template file:

Read: assets/templates/module/terragrunt.hcl

Template: assets/templates/module/terragrunt.hcl

Canonical Placeholder Replacement Map

Use this map for every generated output:

Placeholder Meaning Example Replacement Notes
[AWS_REGION] AWS region us-east-1 Canonical region placeholder in all templates
[ENVIRONMENT] Environment name dev Keep lowercase for directory naming
[PROJECT_NAME] Project/application name payments-platform Use the same value in tags and names
[BUCKET_NAME] Remote state S3 bucket acme-tfstate-prod Bucket must exist before first apply
[DYNAMODB_TABLE] State lock table acme-terraform-locks Table must exist before first apply
[PROVIDER_SOURCE] Terraform provider source hashicorp/aws Use fully qualified source
[TERRAFORM_VERSION] Required Terraform/OpenTofu version 1.8.5 Used in both terraform_version_constraint and required_version. Keep compatible with module constraints.

Legacy alias normalization: If you see [REGION] in older examples, treat it as [AWS_REGION] and replace it before validation.

4. Generate Multi-Environment Infrastructure

Complete directory structures for dev/staging/prod.

MANDATORY: Before generating:

  1. Determine architecture pattern (see Architecture Patterns section)
  2. Read relevant templates for root, env, and child modules
  3. Verify env.hcl placement and access patterns:
    Read: assets/templates/env/env.hcl
    

Patterns: references/common-patterns.md → Environment-Specific Patterns

Typical structure (Pattern A - Environment-Agnostic Root):

infrastructure/
├── root.hcl              # Environment-AGNOSTIC root config
├── dev/
│   ├── env.hcl           # Dev environment variables
│   └── vpc/terragrunt.hcl
└── prod/
    ├── env.hcl           # Prod environment variables
    └── vpc/terragrunt.hcl

5. Generate Terragrunt Stacks (2025)

Infrastructure blueprints using terragrunt.stack.hcl.

MANDATORY: Before generating, READ the template files:

Read: assets/templates/stack/terragrunt.stack.hcl
Read: assets/templates/catalog/terragrunt.hcl

Docs: Stacks Documentation Template: assets/templates/stack/terragrunt.stack.hcl Catalog Template: assets/templates/catalog/terragrunt.hcl Patterns: references/common-patterns.md → Stacks Patterns

Stack path rule: Keep no_dot_terragrunt_stack mode consistent across dependent units. Do not mix direct-path and .terragrunt-stack generation in the same dependency chain.

Commands:

terragrunt stack generate    # Generate unit configurations
terragrunt stack run plan    # Plan all units
terragrunt stack run apply   # Apply all units
terragrunt stack output      # Get aggregated outputs
terragrunt stack clean       # Clean generated directories

6. Generate Feature Flags (2025)

Runtime control without code changes.

Docs: Feature Flags Documentation Patterns: references/common-patterns.md → Feature Flags Patterns

CRITICAL: Feature flag default values MUST be static (boolean, string, number). They CANNOT reference local.* values. Use static defaults and override via CLI/env vars.

Correct:

feature "enable_monitoring" {
  default = false  # Static value - OK
}

Incorrect:

feature "enable_monitoring" {
  default = local.env.locals.enable_monitoring  # Dynamic reference - FAILS
}

Usage:

terragrunt apply --feature enable_monitoring=true
# or
export TG_FEATURE="enable_monitoring=true"

Environment-specific defaults: Use different static defaults per environment file, not dynamic references.

7. Generate Exclude Blocks (2025)

Fine-grained execution control (replaces deprecated skip).

Docs: Exclude Block Reference Patterns: references/common-patterns.md → Exclude Block Patterns

Actions: "plan", "apply", "destroy", "all", "all_except_output"

Production Recommendation: For critical production resources, add exclude blocks to prevent accidental destruction:

# Protect production databases from accidental destroy
exclude {
  if      = true
  actions = ["destroy"]
  exclude_dependencies = false
}

# Also use prevent_destroy for critical resources
prevent_destroy = true

8. Generate Errors Blocks (2025)

Advanced error handling (replaces deprecated retryable_errors).

Docs: Errors Block Reference Patterns: references/common-patterns.md → Errors Block Patterns

9. Generate OpenTofu Engine Configuration (2025)

Use OpenTofu as the IaC engine.

Docs: Engine Documentation Patterns: references/common-patterns.md → OpenTofu Engine Patterns

10. Handling Custom Providers/Modules

When generating configs with custom providers:

  1. Identify the provider name, source, and version
  2. Search using WebSearch: "[provider] terraform provider [version] documentation"
  3. Or use Context7 MCP if available for structured docs
  4. Generate with proper required_providers block
  5. Document authentication requirements in comments

Generation Workflow

CRITICAL: Follow this workflow for EVERY generation task. Skipping steps leads to validation errors.

Step 1: Understand Requirements

  • What type of configuration? (root, child, standalone, stack)
  • Single or multi-environment?
  • What dependencies exist between modules?
  • What providers/modules will be used?

Step 2: Determine Architecture Pattern

MANDATORY: Select and document the pattern BEFORE writing any files.

Scenario Pattern Root.hcl Scope
Multi-env with shared root Pattern A Environment-agnostic
Single environment Pattern B Environment-aware
Centralized env vars Pattern C Environment-agnostic

Complete the Architecture Pattern Selection Checklist (Canonical) above and include it in output before file generation.

Step 3: Read Required Templates

MANDATORY: Read the relevant template file(s) BEFORE generating each configuration type.

Configuration Type Template to Read Purpose
Root configuration assets/templates/root/terragrunt.hcl Shared state backend, providers, and common inputs
Environment variables assets/templates/env/env.hcl Per-environment locals read by child modules (Pattern A)
Child module assets/templates/child/terragrunt.hcl Environment module wired to root include
Standalone module assets/templates/module/terragrunt.hcl Independent Terragrunt module without root include
Stack file assets/templates/stack/terragrunt.stack.hcl Blueprint that generates multiple units
Catalog unit assets/templates/catalog/terragrunt.hcl Reusable unit template consumed by stacks

Also read:

  • references/common-patterns.md - Primary source for generation patterns

Step 4: Generate with Validation

Validation Strategy: Use a combination of inline checks during generation and batch validation at the end.

Generation order for multi-environment projects:

  1. Generate root.hcl first

    • Inline checks (during generation):
      • No read_terragrunt_config(find_in_parent_folders("env.hcl")) if environment-agnostic
      • remote_state block has encrypt = true
      • errors block used (not deprecated retryable_errors)
  2. Generate env.hcl files for each environment

    • Inline checks (during generation):
      • locals block contains environment, aws_region, and module-specific vars
      • No references to files that don't exist at that directory level
  3. Generate child modules (VPC, etc.) - modules with NO dependencies first

    • Inline checks (during generation):
      • include block uses find_in_parent_folders("root.hcl")
      • read_terragrunt_config(find_in_parent_folders("env.hcl")) present
      • terraform.source uses valid syntax (tfr:///, git::, or relative path)
  4. Generate dependent modules (RDS, EKS, etc.)

    • Inline checks (during generation):
      • dependency blocks have mock_outputs
      • mock_outputs_allowed_terraform_commands includes ["validate", "plan", "destroy"]
      • Production modules have prevent_destroy = true and/or exclude block
  5. Run batch validation after ALL files are generated

    Note: Full CLI validation (terragrunt hcl fmt, terragrunt dag graph) requires all files to exist, so these are batched at the end.

    # Batch validation commands (run after all files exist):
    terragrunt hcl fmt --check          # Format validation
    terragrunt dag graph                 # Dependency graph validation
    
    • Invoke Skill(devops-skills:terragrunt-validator) for comprehensive validation

Step 5: Fix and Re-Validate

If validation fails:

  1. Analyze errors (path resolution, missing variables, syntax errors)
  2. Fix issues in the specific file(s)
  3. Re-validate the fixed file(s)
  4. Repeat until ALL errors are resolved

Step 6: Present Results

Follow "Presentation Requirements" section below.

Validation Workflow

CRITICAL: Every generated configuration MUST be validated.

Incremental Validation Checks

After generating root.hcl:

cd <infrastructure-directory>
terragrunt hcl fmt --check

After generating each child module:

cd <module-directory>
terragrunt hcl fmt --check
# If no dependencies on other modules:
terragrunt hcl validate --inputs

Full Validation

After all files are generated:

  1. Invoke validation skill:

    Invoke: Skill(devops-skills:terragrunt-validator)
    
  2. If validation fails:

    • Analyze errors (missing placeholders, invalid syntax, wrong paths)
    • Fix issues
    • Re-validate (repeat until ALL errors are resolved)
  3. If validation succeeds: Present configurations with usage instructions

Skip validation only for: Partial snippets, documentation examples, or explicit user request

Validation Fallbacks (Environment Constraints)

If the normal validation path is unavailable, use this fallback order and report what was skipped:

  1. If terragrunt is unavailable:
    • Run static checks:
      rg -n "\[[A-Z0-9_]+\]" .
      rg -n "find_in_parent_folders\\(\"env\\.hcl\"\\)" .
      
    • Report that runtime Terragrunt validation is pending.
  2. If validator skill execution is unavailable:
    • Run direct Terragrunt checks instead:
      terragrunt hcl fmt --check
      terragrunt dag graph
      
  3. If tree is unavailable for presentation:
    • Use:
      find . -maxdepth 4 -type f | sort
      

Presentation Requirements

MANDATORY: After successful validation, you MUST present ALL of the following sections. Incomplete presentation is not acceptable. Copy and fill in the templates below.

1. Directory Structure Summary (MANDATORY)

# Show the generated structure
tree <infrastructure-directory>

2. Files Generated (MANDATORY)

Output this table with all generated files:

| File | Purpose |
|------|---------|
| root.hcl | Shared configuration for all child modules (state backend, provider) |
| dev/env.hcl | Development environment variables |
| prod/env.hcl | Production environment variables |
| dev/vpc/terragrunt.hcl | VPC module for development |
| ... | ... |

3. Usage Instructions (MANDATORY)

You MUST include this section. Copy the template below and fill in the actual values:

## Usage Instructions

### Prerequisites
Before running Terragrunt commands, ensure:
1. AWS credentials are configured (`aws configure` or environment variables)
2. S3 bucket `<BUCKET_NAME>` exists for state storage
3. DynamoDB table `<TABLE_NAME>` exists for state locking

### Commands

# Navigate to infrastructure directory
cd <INFRASTRUCTURE_DIR>

# Initialize all modules
terragrunt run --all init

# Preview changes for a specific environment
cd <ENV>/vpc && terragrunt plan

# Preview all changes
terragrunt run --all plan

# Apply changes (requires approval)
terragrunt run --all apply

# Destroy (use with extreme caution)
terragrunt run --all destroy

4. Placeholder Replacement and Secrets Check (MANDATORY)

You MUST include this section. Copy the template below and fill in the actual values:

## Placeholder and Secrets Check

### Placeholder Replacement
- [ ] All placeholders (`[AWS_REGION]`, `[BUCKET_NAME]`, `[DYNAMODB_TABLE]`, etc.) replaced with real values
- [ ] No legacy placeholder aliases left (for example `[REGION]`)
- [ ] `terraform.source` values point to real module sources and pinned versions

### Secrets Safety
- [ ] No plaintext credentials or access keys in `terragrunt.hcl`, `root.hcl`, `env.hcl`, `account.hcl`, or `region.hcl`
- [ ] Sensitive values sourced via environment variables, secret managers, or CI variables
- [ ] Example values kept non-sensitive and clearly marked as placeholders

5. Environment-Specific Notes (MANDATORY)

You MUST include this section. Copy the template below and fill in the actual values:

## Environment Notes

### Required Environment Variables
| Variable | Description | Example |
|----------|-------------|---------|
| AWS_PROFILE | AWS CLI profile to use | `my-profile` |
| AWS_REGION | AWS region (or set in provider) | `us-east-1` |

### Prerequisites
- [ ] S3 bucket `<BUCKET_NAME>` must exist before first run
- [ ] DynamoDB table `<TABLE_NAME>` must exist for state locking
- [ ] IAM permissions for Terraform state management

### Production-Specific Protections
| Module | Protection | Description |
|--------|------------|-------------|
| prod/rds | `prevent_destroy = true` | Prevents accidental database deletion |
| prod/rds | `exclude { actions = ["destroy"] }` | Blocks destroy commands |

6. Next Steps (Optional)

Suggest what the user might want to do next (add more modules, customize configurations, etc.)

Best Practices

Reference ../terragrunt-validator/references/best_practices.md for comprehensive guidelines.

Key principles:

  • Use include blocks to inherit root configuration (DRY)
  • Always provide mock outputs for dependencies
  • Enable state encryption (encrypt = true)
  • Use generate blocks for provider configuration
  • Specify bounded version constraints (~> 5.0, not >= 5.0) for local/Git modules
  • Never hardcode credentials or secrets
  • Configure retry logic for transient errors

Note on Version Constraints with Registry Modules: When using Terraform Registry modules (e.g., tfr:///terraform-aws-modules/vpc/aws?version=5.1.0), they typically define their own required_providers. In this case, you may omit generating required_providers in root.hcl to avoid conflicts. The module's pinned version (?version=X.X.X) provides the version constraint. See "Common Issues → Provider Conflict with Registry Modules" for details.

Anti-patterns to avoid:

  • Hardcoded account IDs, regions, or environment names
  • Missing mock outputs for dependencies
  • Duplicated configuration across modules
  • Unencrypted state storage
  • Missing or loose version constraints (except when using registry modules that define their own)
  • Root.hcl trying to read env.hcl that doesn't exist at root level

Deprecated Attributes

Deprecated Replacement Reference
skip exclude block Docs
retryable_errors errors.retry block Docs
run-all run --all Migration
--terragrunt-* flags Unprefixed flags CLI Reference
TERRAGRUNT_* env vars TG_* env vars CLI Reference

Resources

Templates - MUST Read Before Generating

Configuration Type Template File Purpose When to Read
Root configuration assets/templates/root/terragrunt.hcl Shared backend, provider, and common inputs Before generating any root.hcl
Environment variables assets/templates/env/env.hcl Per-environment locals (environment, region, sizing, feature toggles) Before generating any env.hcl (Pattern A)
Child module assets/templates/child/terragrunt.hcl Module include, source, and optional dependency scaffolding Before generating any child module
Standalone module assets/templates/module/terragrunt.hcl Module config without root inheritance Before generating standalone modules
Stack file assets/templates/stack/terragrunt.stack.hcl Stack blueprint and unit generation Before generating stacks
Catalog unit assets/templates/catalog/terragrunt.hcl Reusable unit consumed by stack definitions Before generating catalog units

References

Reference Content Purpose When to Read
references/common-patterns.md All generation patterns with examples Pick a compatible pattern before writing files Always, before generating
../terragrunt-validator/references/best_practices.md Comprehensive best practices Final quality and safety checks Always, before generating

Official Documentation

Common Issues

Root.hcl Cannot Find env.hcl

Symptom:

Error: Attempt to get attribute from null value
  on ./root.hcl line X:
  This value is null, so it does not have any attributes.

Cause: Root.hcl is trying to read env.hcl via find_in_parent_folders("env.hcl"), but env.hcl doesn't exist at the root level.

Solution: Make root.hcl environment-agnostic:

# DON'T do this in root.hcl for multi-environment setups:
locals {
  env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl"))  # FAILS
}

# DO use static values or get_env():
generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
provider "aws" {
  region = "us-east-1"  # Static value, or use get_env("AWS_REGION", "us-east-1")
}
EOF
}

Provider Conflict with Registry Modules

When using Terraform Registry modules (e.g., tfr:///terraform-aws-modules/vpc/aws), they may define their own required_providers block. This can conflict with provider configuration generated by root.hcl.

Symptoms:

Error: Duplicate required providers configuration

Solutions:

  1. Remove conflicting generate block - If using registry modules that manage their own providers, avoid generating duplicate required_providers:

    # In root.hcl - only generate provider config, not required_providers
    generate "provider" {
      path      = "provider.tf"
      if_exists = "overwrite_terragrunt"
      contents  = <<EOF
    provider "aws" {
      region = "us-east-1"
    }
    EOF
    }
    
  2. Use if_exists = "skip" - Skip generation if file already exists:

    generate "versions" {
      path      = "versions.tf"
      if_exists = "skip"  # Don't overwrite module's versions.tf
      contents  = "..."
    }
    
  3. Clear cache - If conflicts persist after fixes:

    rm -rf .terragrunt-cache
    terragrunt init
    

Feature Flag Validation Errors

If you see Unknown variable; There is no variable named "local" in feature blocks, ensure defaults are static values (see Feature Flags section above).

Child Module Cannot Find env.hcl

Symptom:

Error: Attempt to get attribute from null value
  on ./dev/vpc/terragrunt.hcl line X:

Cause: Child module's find_in_parent_folders("env.hcl") cannot find env.hcl.

Solution: Ensure env.hcl exists in the environment directory:

dev/
├── env.hcl           # This file MUST exist
└── vpc/
    └── terragrunt.hcl  # Calls find_in_parent_folders("env.hcl")

Quick Reference Card

File Reading Checklist

Before generating, READ these files in order:

  1. references/common-patterns.md - Understand available patterns
  2. ../terragrunt-validator/references/best_practices.md - Know the rules
  3. Relevant template(s) from assets/templates/ - Structural reference

Architecture Decision Tree

Q: Multiple environments (dev/staging/prod)?
├─ YES → Q: Shared root configuration?
│   ├─ YES → Pattern A: Environment-Agnostic Root
│   └─ NO  → Separate root.hcl per environment
└─ NO  → Q: Environment detection needed?
    ├─ YES → Pattern B: Environment-Aware Root
    └─ NO  → Pattern B: Simple single-environment

Validation Sequence

  1. Format check: terragrunt hcl fmt --check
  2. Input validation: terragrunt hcl validate --inputs
  3. Full validation: Invoke Skill(devops-skills:terragrunt-validator)
  4. Fix errors → Re-validate → Repeat until clean

Done Criteria

This skill execution is complete only when ALL are true:

  • One architecture checklist is completed and shown (the canonical checklist in this file)
  • Generated files consistently use modern root include syntax unless legacy was explicitly requested
  • Registry sources use canonical tfr:///NAMESPACE/NAME/PROVIDER?version=X.Y.Z format
  • Dependency blocks are added only where actually needed (not left as unresolved placeholders)
  • All placeholders are replaced and secrets checks are reported in output
  • Validation succeeded, or fallback checks ran with explicit limitations documented
提供Terragrunt配置文件的全面验证、Linting和安全扫描能力,支持HCL格式检查、依赖图分析及合规性审计。兼容0.93+版本,涵盖从语法校验到安全漏洞检测的完整工作流。
验证Terragrunt HCL文件语法与格式 执行代码Linting与安全扫描 调试配置问题或检查依赖关系 运行Dry-run测试以评估变更影响
devops-skills-plugin/skills/terragrunt-validator/SKILL.md
npx skills add akin-ozer/cc-devops-skills --skill terragrunt-validator -g -y
SKILL.md
Frontmatter
{
    "name": "terragrunt-validator",
    "description": "Validate, lint, audit, or check Terragrunt .hcl\/terragrunt.hcl files, stacks, modules, compliance."
}

Terragrunt Validator

Overview

This skill provides comprehensive validation, linting, and testing capabilities for Terragrunt configurations. Terragrunt is a thin wrapper for Terraform/OpenTofu that provides extra tools for keeping configurations DRY (Don't Repeat Yourself), working with multiple modules, and managing remote state.

Use this skill when:

  • Validating Terragrunt HCL files (*.hcl, terragrunt.hcl, terragrunt.stack.hcl)
  • Working with Terragrunt Stacks (unit/stack blocks, terragrunt stack generate/run)
  • Performing dry-run testing with terragrunt plan
  • Linting Terragrunt/Terraform code for best practices
  • Detecting and researching custom providers or modules
  • Debugging Terragrunt configuration issues
  • Checking dependency graphs
  • Formatting HCL files
  • Running security scans on infrastructure code (Trivy, Checkov)
  • Generating run reports and summaries

Terragrunt Version Compatibility

This skill is designed for Terragrunt 0.93+ which includes the new CLI redesign.

CLI Command Migration Reference

Deprecated Command New Command
run-all run --all
hclfmt hcl fmt
hclvalidate hcl validate
validate-inputs hcl validate --inputs
graph-dependencies dag graph
render-json render --json -w
terragrunt-info info print
plan-all, apply-all run --all plan, run --all apply

Key Changes in 0.93+:

  • terragrunt run --all replaces terragrunt run-all for multi-module operations
  • terragrunt dag graph replaces terragrunt graph-dependencies for dependency visualization
  • terragrunt hcl validate --inputs replaces validate-inputs for input validation
  • HCL syntax validation via terragrunt hcl fmt --check or terragrunt hcl validate
  • Full validation requires terragrunt init && terragrunt validate

If using an older Terragrunt version, some commands may need adjustment.

Core Capabilities

1. Comprehensive Validation Suite

Run the comprehensive validation script to perform all checks at once:

bash scripts/validate_terragrunt.sh [TARGET_DIR]

What it validates:

  • HCL formatting (terragrunt hcl fmt --check)
  • HCL input validation (terragrunt hcl validate --inputs)
  • Terragrunt configuration syntax
  • Terraform configuration validation
  • Linting with tflint
  • Security scanning with Trivy (or legacy tfsec)
  • Dependency graph validation
  • Dry-run planning

Environment variables:

  • SKIP_PLAN=true - Skip terragrunt plan step
  • SKIP_SECURITY=true - Skip security scanning (Trivy/tfsec)
  • SKIP_LINT=true - Skip tflint linting
  • SKIP_INIT=true - Skip terragrunt init before validation
  • SKIP_BACKEND_INIT=true - Run init with -backend=false (useful in CI/offline)
  • SOFT_FAIL_SECURITY=true - Report security findings without failing
  • TG_STRICT_MODE=true - Enable strict mode (errors on deprecated features)

Example usage:

# Full validation
bash scripts/validate_terragrunt.sh ./infrastructure/prod

# Skip plan generation (faster)
SKIP_PLAN=true bash scripts/validate_terragrunt.sh ./infrastructure

# Only validate, skip linting and security
SKIP_LINT=true SKIP_SECURITY=true bash scripts/validate_terragrunt.sh

2. Custom Provider and Module Detection

Use the detection script to identify custom providers and modules that may require documentation lookup:

python3 scripts/detect_custom_resources.py [DIRECTORY] [--format text|json]

What it detects:

  • Custom Terraform providers (non-HashiCorp)
  • Remote modules (Git, Terraform Registry, HTTP)
  • Provider versions
  • Module versions and sources

Output formats:

  • text - Human-readable report with search recommendations
  • json - Machine-readable format for automation

When custom resources are detected:

CRITICAL: You MUST look up documentation for EVERY detected custom resource (both providers AND modules). Do NOT skip any. This is mandatory, not optional.

  1. For custom providers:

    • Option A - WebSearch: Search for provider documentation
      • Query format: "{provider_source} terraform provider documentation version {version}"
      • Example: "mongodb/mongodbatlas terraform provider documentation version 1.14.0"
    • Option B - Context7 MCP (Preferred): Use Context7 for structured documentation lookup
      • Step 1: Resolve library ID: mcp__context7__resolve-library-id with provider name (e.g., "datadog terraform provider")
      • Step 2: REQUIRED - Fetch docs via mcp__context7__query-docs with the resolved library ID
      • Use queries like "authentication requirements" and "configuration examples"
  2. For custom modules (EQUALLY IMPORTANT - DO NOT SKIP):

    • Terraform Registry modules:
      • Use Context7: mcp__context7__resolve-library-id with module name (e.g., "terraform-aws-modules vpc")
      • Then fetch docs with mcp__context7__query-docs
      • Or visit https://registry.terraform.io/modules/{source}/{version}
    • Git modules: Use WebSearch with the repository URL to find README or documentation
    • HTTP modules: Investigate the source URL for documentation
    • Pay attention to version compatibility with your Terraform/Terragrunt version
  3. Documentation lookup workflow (MANDATORY for ALL detected resources):

    a) Run detect_custom_resources.py
    b) For EACH custom provider/module:
       - Note the exact version
       - Use Context7 MCP:
         1. mcp__context7__resolve-library-id with libraryName: "{provider/module name}"
         2. mcp__context7__query-docs with:
            - libraryId: "{resolved ID}"
            - query: "authentication requirements" (for auth requirements)
         3. mcp__context7__query-docs with:
            - libraryId: "{resolved ID}"
            - query: "configuration examples" (for setup requirements)
       - OR use WebSearch with version-specific queries
       - Review documentation for:
         * Required configuration blocks
         * Authentication requirements (API keys, credentials)
         * Available resources/data sources
         * Known issues or breaking changes in the version
    c) Apply learnings to validation/troubleshooting
    d) Document findings if issues are encountered
    

Example using Context7 MCP:

# 1. Detect custom resources
python3 scripts/detect_custom_resources.py ./infrastructure
# Output: Provider: datadog/datadog, Version: 3.30.0

# 2. Resolve library ID
mcp__context7__resolve-library-id with libraryName: "datadog terraform provider"
# Result: /datadog/terraform-provider-datadog

# 3. Fetch authentication docs (REQUIRED)
mcp__context7__query-docs with:
  libraryId: "/datadog/terraform-provider-datadog"
  query: "authentication requirements"

# 4. Fetch configuration docs
mcp__context7__query-docs with:
  libraryId: "/datadog/terraform-provider-datadog"
  query: "configuration examples"

Example using WebSearch:

# Detect custom resources
python3 scripts/detect_custom_resources.py ./infrastructure

# Then search for documentation:
# WebSearch: "datadog terraform provider 3.30.0 authentication configuration"
# WebSearch: "datadog terraform provider api_key app_key setup"

3. Step-by-Step Validation

For manual or granular validation, use these individual commands:

Format Validation

cd <target-directory>
terragrunt hcl fmt --check

# To auto-fix formatting
terragrunt hcl fmt

Configuration Validation

# Check HCL syntax and formatting
terragrunt hcl fmt --check

# Note: In Terragrunt 0.93+, for deeper configuration validation,
# initialize and validate (requires actual resources/credentials):
# terragrunt init && terragrunt validate

Terraform Validation

# Initialize if needed
terragrunt init

# Validate
terragrunt validate

Linting with tflint

# Initialize tflint (if .tflint.hcl exists)
tflint --init

# Run linting
tflint --recursive

Security Scanning with Trivy (Recommended)

Note: tfsec has been merged into Trivy and is no longer actively maintained. Use Trivy for all new projects.

# Using Trivy (recommended)
trivy config . --severity HIGH,CRITICAL

# With tfvars file
trivy config --tf-vars terraform.tfvars .

# Exclude downloaded modules
trivy config --tf-exclude-downloaded-modules .

# Legacy: Using tfsec (deprecated)
tfsec . --soft-fail

Alternative: Security Scanning with Checkov

# Scan directory
checkov -d . --framework terraform

# Scan with specific checks
checkov -d . --check CKV_AWS_21

# Output as JSON
checkov -d . --output json

Dependency Graph Validation

# Note: graph-dependencies command replaced with 'dag graph' in Terragrunt 0.93+
# Validate and display dependency graph
terragrunt dag graph

# Visualize dependencies (requires graphviz)
terragrunt dag graph | dot -Tpng > dependencies.png

Dry-Run Planning

# Single module
terragrunt plan

# All modules (new syntax - Terragrunt 0.93+)
terragrunt run --all plan

# Legacy syntax (deprecated)
# terragrunt run-all plan

4. Multi-Module Operations

For projects with multiple Terragrunt modules, use run --all (replaces deprecated run-all):

# Validate all modules
terragrunt run --all validate

# Plan all modules
terragrunt run --all plan

# Apply all modules
terragrunt run --all apply

# Destroy all modules
terragrunt run --all destroy

# Format all HCL files
terragrunt hcl fmt

# With parallelism
terragrunt run --all plan --parallelism 4

# With strict mode (errors on deprecated features)
terragrunt --strict-mode run --all plan

# Or via environment variable
TG_STRICT_MODE=true terragrunt run --all plan

5. HCL Input Validation (New in 0.93+)

Validate that all required inputs are set and no unused inputs exist:

# Validate inputs
terragrunt hcl validate --inputs

# Show paths of invalid files
terragrunt hcl validate --show-config-path

# Combine with run --all to exclude invalid files
terragrunt run --all plan --queue-excludes-file <(terragrunt hcl validate --show-config-path || true)

6. Strict Mode

Enable strict mode to catch deprecated features early:

# Via CLI flag
terragrunt --strict-mode run --all plan

# Via environment variable (recommended for CI/CD)
export TG_STRICT_MODE=true
terragrunt run --all plan

# Check available strict controls
terragrunt info strict

Specific Strict Controls:

For finer-grained control, use --strict-control to enable specific controls:

# Enable specific strict controls
terragrunt run --all plan --strict-control cli-redesign --strict-control deprecated-commands

# Via environment variable (comma-separated)
TG_STRICT_CONTROL='cli-redesign,deprecated-commands' terragrunt run --all plan

# Available strict controls:
# - cli-redesign: Errors on deprecated CLI syntax
# - deprecated-commands: Errors on deprecated commands (run-all, hclfmt, etc.)
# - root-terragrunt-hcl: Errors when using root terragrunt.hcl (use root.hcl instead)
# - skip-dependencies-inputs: Improves performance by not reading dependency inputs
# - bare-include: Errors on bare include blocks (use named includes)

7. New CLI Commands (0.93+)

Render Configuration

# Render configuration to JSON
terragrunt render --json

# Render and write to file
terragrunt render --json --write

# Output goes to terragrunt.rendered.json

Info Print (replaces terragrunt-info)

# Get contextual information about current configuration
terragrunt info print

# Output includes:
# - config_path
# - download_dir
# - terraform_binary
# - working_dir

Find and List Units

# Find all units/stacks in directory
terragrunt find

# Output as JSON
terragrunt find --json

# Include dependency information
terragrunt find --json --dag

# List units (simpler output)
terragrunt list

Run Summary and Reports

# Run with summary output (default in newer versions)
terragrunt run --all plan

# Disable summary output
terragrunt run --all plan --summary-disable

# Generate detailed report file
terragrunt run --all plan --report-file=report.json

# CSV format report
terragrunt run --all plan --report-file=report.csv

8. Terragrunt Stacks (GA in v0.78.0+)

Terragrunt Stacks provide declarative infrastructure generation using terragrunt.stack.hcl files.

Stack File Structure

# terragrunt.stack.hcl
locals {
  environment = "dev"
  aws_region  = "us-east-1"
}

# Define a unit (generates a single terragrunt.hcl)
unit "vpc" {
  source = "git::git@github.com:acme/infra-catalog.git//units/vpc?ref=v0.0.1"
  path   = "vpc"

  values = {
    environment = local.environment
    cidr        = "10.0.0.0/16"
  }
}

unit "database" {
  source = "git::git@github.com:acme/infra-catalog.git//units/database?ref=v0.0.1"
  path   = "database"

  values = {
    environment = local.environment
    vpc_path    = "../vpc"
  }
}

# Include reusable stacks
stack "monitoring" {
  source = "git::git@github.com:acme/infra-catalog.git//stacks/monitoring?ref=v0.0.1"
  path   = "monitoring"

  values = {
    environment = local.environment
  }
}

Stack Commands

# Generate stack (creates .terragrunt-stack directory)
terragrunt stack generate

# Generate stack without validation
terragrunt stack generate --no-stack-validate

# Run command on all stack units
terragrunt stack run plan
terragrunt stack run apply

# Clean generated stack directories
terragrunt stack clean

# Get stack outputs
terragrunt stack output

Stack Validation Control

Use no_validation attribute to skip validation for specific units:

unit "experimental" {
  source = "git::git@github.com:acme/infra-catalog.git//units/experimental?ref=v0.0.1"
  path   = "experimental"

  # Skip validation for this unit (useful for incomplete/experimental units)
  no_validation = true

  values = {
    environment = local.environment
  }
}

Benefits of Stacks

  • Clean working directory: Generated code in hidden .terragrunt-stack directory
  • Reusable patterns: Define infrastructure patterns once, deploy many times
  • Version pinning: Different environments can pin different versions
  • Atomic updates: Easy rollbacks of both modules and configurations

9. Exec Command (Run Arbitrary Programs)

The exec command allows you to run arbitrary programs against units with Terragrunt context. This is useful for integrating other tools like tflint, checkov, or AWS CLI with Terragrunt's configuration.

# Run tflint with unit context (TF_VAR_ env vars available)
terragrunt exec -- tflint

# Run checkov against specific unit
terragrunt exec -- checkov -d .

# Run AWS CLI with unit's configuration
terragrunt exec -- aws s3 ls s3://my-bucket

# Run custom scripts with Terragrunt context
terragrunt exec -- ./scripts/validate_terragrunt.sh

# Run across all units
terragrunt run --all exec -- tflint

Key Features:

  • Terragrunt loads the inputs for the unit and makes them available as TF_VAR_ prefixed environment variables
  • Works with any program that can use environment variables
  • Integrates with Terragrunt's authentication context (e.g., AWS profiles)
  • Can be combined with run --all for multi-unit operations

Use Cases:

  • Running security scanners (checkov, trivy) with unit context
  • Executing linters (tflint) per unit
  • Running operational commands (AWS CLI) with correct credentials
  • Custom validation scripts that need Terragrunt inputs

10. Feature Flags (Production Feature)

Terragrunt supports first-class Feature Flags for safe infrastructure changes. Feature flags allow you to integrate incomplete work without risk, decouple release from deployment, and codify IaC evolution.

Defining Feature Flags

# terragrunt.hcl
feature "enable_monitoring" {
  default = false
}

feature "use_new_vpc" {
  default = true
}

inputs = {
  monitoring_enabled = feature.enable_monitoring.value
  vpc_version       = feature.use_new_vpc.value ? "v2" : "v1"
}

Using Feature Flags via CLI

# Enable a feature flag
terragrunt plan --feature enable_monitoring=true

# Enable multiple feature flags
terragrunt plan --feature enable_monitoring=true --feature use_new_vpc=false

# Via environment variable
TG_FEATURE='enable_monitoring=true' terragrunt plan

Feature Flags with run --all

# Apply feature flag across all units
terragrunt run --all plan --feature enable_monitoring=true

Benefits:

  • Safe rollouts: Test changes on subset of infrastructure
  • Gradual migrations: Enable new features incrementally
  • A/B testing: Compare infrastructure configurations
  • Emergency rollbacks: Quickly disable problematic features

11. Experiments (Opt-in Unstable Features)

Terragrunt provides an experiments system for trying unstable features before they're GA:

# Enable all experiments (not recommended for production)
terragrunt --experiment-mode run --all plan

# Enable specific experiment
terragrunt --experiment symlinks run --all plan

# Enable CAS (Content Addressable Storage) for faster cloning
terragrunt --experiment cas run --all plan

Available Experiments:

  • symlinks - Support symlink resolution for Terragrunt units
  • cas - Content Addressable Storage for faster Git/module cloning
  • filter-flag - Advanced filtering capabilities (coming in 1.0)

Validation Workflow

Follow this workflow when validating Terragrunt configurations:

Canonical Executable Workflow (Default Path)

Use one executable path so docs and scripts stay aligned:

# Main validation
bash scripts/validate_terragrunt.sh <target-directory>

# Deterministic fixture tests (required after script changes)
python3 test/test_detect_custom_resources.py
bash test/test_validate_terragrunt.sh

Execution expectations:

  • Fixture tests should be deterministic (stable pass/fail outcomes).
  • Validation/security failures must surface as non-zero exits.

Step 0: Read Best Practices Reference (MANDATORY FIRST STEP)

You MUST read the best practices reference file BEFORE starting validation. This is not optional.

# Read the best practices reference file first
if [ -f references/best_practices.md ]; then
  cat references/best_practices.md
else
  echo "WARNING: references/best_practices.md not found; continue with built-in checklist below."
fi

This ensures you understand the patterns, anti-patterns, and checklists you will verify.

Initial Assessment

  1. Understand the structure:

    tree -L 3 <infrastructure-directory>
    
  2. Identify Terragrunt files:

    find . -name "*.hcl" -o -name "terragrunt.hcl"
    
  3. Detect custom resources:

    python3 scripts/detect_custom_resources.py .
    

Documentation Lookup (MANDATORY for ALL detected custom resources)

CRITICAL: If ANY custom providers or modules are detected, you MUST look up documentation for EACH ONE. Do not skip any.

  1. For EACH detected custom provider - look up documentation:

    • Use Context7 MCP (preferred):
      1. mcp__context7__resolve-library-id with provider name
      2. mcp__context7__query-docs with query: "authentication requirements"
      3. mcp__context7__query-docs with query: "configuration examples"
    • OR use WebSearch: "{provider} terraform provider {version} documentation"
  2. For EACH detected custom module - look up documentation:

    • Use Context7 MCP for Terraform Registry modules:
      1. mcp__context7__resolve-library-id with module name (e.g., "terraform-aws-modules vpc")
      2. mcp__context7__query-docs with relevant configuration query
    • For Git modules: Use WebSearch with repository URL
    • For HTTP modules: Investigate source URL for documentation
  3. Document findings for each resource:

    • Required configuration blocks
    • Authentication requirements
    • Known issues or breaking changes in the version

Validation Execution

  1. Run comprehensive validation:

    bash scripts/validate_terragrunt.sh <target-directory>
    
  2. Review output for errors:

    • Format errors → Fix with terragrunt hcl fmt
    • Configuration errors → Check terragrunt.hcl syntax and inputs
    • Terraform validation errors → Check .tf files or generated configs
    • Linting issues → Review tflint output and fix
    • Security issues → Review Trivy/Checkov/tfsec output and address
    • Dependency errors → Check dependency blocks and paths
    • Plan errors → Review Terraform configuration and provider setup

Best Practices Check (REQUIRED - Must Complete All Checklists)

You MUST verify each checklist item below and document the result (✅ pass or ❌ fail). Incomplete verification is not acceptable.

  1. Perform explicit best practices verification using references/best_practices.md:

    Configuration Pattern Checklist - verify each item:

    [ ] Include blocks: Child modules use `include "root" { path = find_in_parent_folders("root.hcl") }`
    [ ] Named includes: All include blocks have names (not bare `include {}`)
    [ ] Root file naming: Root config is named `root.hcl` (not `terragrunt.hcl`)
    [ ] Environment configs: Environment-level configs named `env.hcl` (not `terragrunt.hcl`)
    [ ] Common variables: Shared variables in `common.hcl` read via `read_terragrunt_config()`
    

    Dependency Management Checklist:

    [ ] Mock outputs: ALL dependency blocks have mock_outputs for validation
    [ ] Mock allowed commands: mock_outputs_allowed_terraform_commands includes ["validate", "plan", "init"]
    [ ] Explicit paths: Dependency config_path uses relative paths ("../vpc" not absolute)
    [ ] No circular deps: Run `terragrunt dag graph` to verify no cycles
    

    Security Checklist:

    [ ] State encryption: remote_state config has `encrypt = true`
    [ ] State locking: DynamoDB table configured for S3 backend
    [ ] No hardcoded credentials: Search for patterns like "AKIA", "password =", account IDs
    [ ] Sensitive variables: Passwords/keys use `sensitive = true` in variable blocks
    [ ] IAM roles: Provider uses assume_role instead of static credentials
    

    DRY Principle Checklist:

    [ ] Generate blocks: Provider and backend configs use `generate` blocks
    [ ] Version constraints: terragrunt_version_constraint and terraform_version_constraint set
    [ ] Reusable locals: Common values in shared files, not duplicated
    [ ] if_exists: Generate blocks use appropriate if_exists strategy
    

    Quick grep checks to run:

    # Check for hardcoded AWS account IDs
    grep -r "[0-9]\{12\}" --include="*.hcl" . | grep -v mock
    
    # Check for potential credentials
    grep -ri "password\s*=" --include="*.hcl" .
    grep -ri "api_key\s*=" --include="*.hcl" .
    
    # Check for dependencies without mock_outputs
    grep -l "dependency\s" --include="*.hcl" -r . | xargs grep -L "mock_outputs"
    
    # Check for terragrunt.hcl files in non-module directories (anti-pattern)
    find . -name "terragrunt.hcl" -not -path "*/.terragrunt-cache/*" | head -20
    

Troubleshooting

  1. Common issues and resolutions:

Issue: Module not found

rm -rf .terragrunt-cache
terragrunt init

Issue: Provider authentication errors

  • Check provider configuration in generated files
  • Verify environment variables or credentials
  • Review provider documentation from WebSearch

Issue: Dependency errors

  • Check dependency paths are correct
  • Ensure mock_outputs are provided for validation
  • Review dependency graph with terragrunt dag graph

Issue: State locking errors

terragrunt force-unlock <LOCK_ID>

Issue: S3 backend dynamodb_table deprecation warning

  • Recent Terraform versions may warn that dynamodb_table is deprecated for S3 backends.
  • Prefer use_lockfile = true in backend config when compatible with your workflow.
  • Keep dynamodb_table only for legacy compatibility needs.

Issue: Unknown provider or module parameters

  • Re-run custom resource detection
  • Use WebSearch to look up current documentation
  • Check version compatibility

Issue: Generate block conflicts (file already exists)

ERROR: The file path ./versions.tf already exists and was not generated by terragrunt.
Can not generate terraform file: ./versions.tf already exists

Solution: This occurs when static .tf files exist that conflict with Terragrunt's generate blocks. Either:

  • Remove the conflicting static files (versions.tf, provider.tf, backend.tf)
  • Or use if_exists = "skip" in the generate block to not overwrite existing files
# Remove conflicting files
rm -f versions.tf provider.tf backend.tf
rm -rf .terragrunt-cache

Issue: Root terragrunt.hcl anti-pattern warning

WARN: Using `terragrunt.hcl` as the root of Terragrunt configurations is an anti-pattern

Solution: In Terragrunt 0.93+, the root configuration file should be named root.hcl instead of terragrunt.hcl. Rename the file:

mv terragrunt.hcl root.hcl
# Update include blocks in child modules to reference root.hcl

Best Practices Integration

Reference the comprehensive best practices guide for detailed recommendations:

# Read the best practices reference
if [ -f references/best_practices.md ]; then
  cat references/best_practices.md
else
  echo "WARNING: references/best_practices.md not found; continue with checklist in this document."
fi

Key best practices to check:

  • ✅ Use include for shared configuration
  • ✅ Provide mock_outputs for dependencies
  • ✅ Use generate blocks for provider config
  • ✅ Enable state encryption and locking
  • ✅ Use environment variables for dynamic values
  • ✅ Specify version constraints
  • ✅ Avoid hardcoded values
  • ✅ Use meaningful directory structure
  • ✅ Enable security features (encryption, IAM roles)

When validating, check for anti-patterns:

  • ❌ Hardcoded credentials or account IDs
  • ❌ Missing mock outputs
  • ❌ Overly deep directory nesting
  • ❌ Duplicated configuration across modules
  • ❌ Missing version constraints
  • ❌ Unencrypted state

Refer to references/best_practices.md for complete examples and detailed guidance.

Tool Requirements

Required:

  • terragrunt (>= 0.93.0 recommended for new CLI)
  • terraform or opentofu (>= 1.6.0 recommended)

Optional but recommended:

  • tflint - HCL linting
  • trivy - Security scanning (replaces tfsec)
  • checkov - Alternative security scanner (750+ built-in policies)
  • graphviz (dot) - Dependency visualization
  • jq - JSON parsing
  • python3 - For custom resource detection script

Deprecated tools:

  • tfsec - Merged into Trivy, no longer actively maintained

Installation commands:

# macOS
brew install terragrunt terraform tflint trivy graphviz jq

# Install Trivy (recommended security scanner)
brew install trivy

# Install Checkov (alternative security scanner)
pip3 install checkov

# Legacy tfsec (deprecated - use trivy instead)
# brew install tfsec

# Linux - Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin

# Linux - Checkov
pip3 install checkov

# Verify installations
terragrunt --version
trivy --version
checkov --version

Integration with Context7 MCP

If Context7 MCP is available, use it for provider/module documentation lookup:

  1. Resolve library ID:

    mcp__context7__resolve-library-id with libraryName: "mongodb/mongodbatlas"
    
  2. Query documentation:

    mcp__context7__query-docs with libraryId: "/mongodb/mongodbatlas" and query: "authentication requirements"
    

This provides version-aware documentation directly, as an alternative to WebSearch.

Automated Workflows

CI/CD Integration

Use the deterministic skill-level CI gate as the blocking check:

bash scripts/run_ci_checks.sh --require-shellcheck

This gate runs:

  • Shell syntax checks (bash -n)
  • Python syntax checks (python3 -m py_compile)
  • Python regression tests (test/test_detect_custom_resources.py)
  • Shell regression tests (test/test_validate_terragrunt.sh)
  • ShellCheck linting (required in CI when --require-shellcheck is set)

After that gate passes, run environment-dependent validation in jobs that have Terragrunt/Terraform credentials configured:

#!/bin/bash
# ci-validate.sh

set -euo pipefail

echo "Running deterministic validator checks..."
bash scripts/run_ci_checks.sh --require-shellcheck

echo "Installing dependencies..."
# Install terragrunt, terraform, tflint, trivy/checkov

echo "Detecting custom resources..."
python3 scripts/detect_custom_resources.py . --format json > custom_resources.json

# Could integrate with automated documentation lookup here

echo "Running validation suite..."
SKIP_PLAN=true SKIP_BACKEND_INIT=true bash scripts/validate_terragrunt.sh .

echo "Validation complete!"

Pre-commit Hook

Example pre-commit hook for local development:

#!/bin/bash
# .git/hooks/pre-commit

# Format check
terragrunt hcl fmt --check || {
    echo "HCL formatting issues found. Run: terragrunt hcl fmt"
    exit 1
}

# Quick HCL syntax validation (Terragrunt 0.93+)
# Note: For full validation, use: terragrunt init && terragrunt validate
# But that requires credentials. HCL format check catches syntax errors.

echo "Pre-commit validation passed!"

Troubleshooting Guide

Validation Modes and Exit Semantics

validate_terragrunt.sh derives mode from the target directory and changes the Terragrunt command path accordingly:

Mode Directory shape Terragrunt HCL check Terraform check Exit semantics
single terragrunt.hcl (or terragrunt.stack.hcl) in target dir terragrunt hcl validate terragrunt validate (with terragrunt init unless skipped) Any syntax/validate failure exits non-zero
multi Nested units exist below target terragrunt hcl validate --all (fallback to plain hcl validate if --all is unsupported) terragrunt run --all validate (with run --all init unless skipped) Any unit failure exits non-zero
root-only root.hcl only, no unit in target dir Warn and skip Warn and skip Returns success (0) for these skipped steps
none No recognized Terragrunt config files Error Error Returns non-zero

Debug Mode

Enable debug output for troubleshooting:

# Terragrunt debug
TERRAGRUNT_DEBUG=1 terragrunt plan

# Terraform trace
TF_LOG=TRACE terragrunt plan

Common Error Patterns

"Error: Module not found"

  • Clear cache: rm -rf .terragrunt-cache
  • Re-initialize: terragrunt init

"Error: Provider not found"

  • Check provider configuration
  • Run custom resource detection
  • Use WebSearch to find correct provider source and version
  • Verify required_providers block

"Error: Invalid function call"

  • Check Terragrunt version compatibility
  • Review function syntax in documentation

"Cycle detected in dependency graph"

  • Review dependency chains
  • Consider refactoring into single module
  • Use data sources instead of dependencies

"Error acquiring state lock"

  • Check if another process is running
  • Verify DynamoDB table (for S3 backend)
  • Force unlock if safe: terragrunt force-unlock <LOCK_ID>

"Error: unknown command" (Terragrunt 0.93+)

Output Interpretation

Success Indicators

All checks passing:

  • All HCL files properly formatted
  • Inputs are valid
  • Terraform configuration is valid
  • No linting issues
  • No critical security issues
  • Valid dependency graph
  • Plan generated successfully

Warning Indicators

⚠️ Review needed:

  • Security warnings from Trivy/Checkov/tfsec (non-critical)
  • Linting suggestions (best practices)
  • Deprecated provider features
  • Missing recommended configurations

Error Indicators

Must fix:

  • Format errors
  • Invalid inputs
  • Terraform validation failures
  • Circular dependencies
  • Provider authentication failures
  • State locking errors

Advanced Usage

Custom Validation Rules

Create custom tflint rules by adding .tflint.hcl:

plugin "terraform" {
  enabled = true
  preset  = "recommended"
}

plugin "aws" {
  enabled = true
  version = "0.27.0"
  source  = "github.com/terraform-linters/tflint-ruleset-aws"
}

rule "terraform_naming_convention" {
  enabled = true
}

Custom Security Policies

Create custom tfsec policies by adding .tfsec/config.yml:

minimum_severity: MEDIUM
exclude:
  - AWS001  # Example: exclude specific rules

Dependency Graph Analysis

Analyze complex dependency chains:

# Generate detailed graph (Terragrunt 0.93+ syntax)
terragrunt dag graph > graph.dot

# Convert to visual format
dot -Tpng graph.dot > graph.png
dot -Tsvg graph.dot > graph.svg

# Analyze for circular dependencies
grep -A5 "cycle" <(terragrunt dag graph 2>&1)

Resources

Scripts

  • scripts/validate_terragrunt.sh - Comprehensive validation suite
  • scripts/detect_custom_resources.py - Custom provider/module detector

References

  • references/best_practices.md - Comprehensive best practices guide covering:
    • Directory structure patterns
    • DRY principles and configuration sharing
    • Dependency management
    • Security best practices
    • Testing and validation workflows
    • Common anti-patterns to avoid
    • Troubleshooting guides

External Documentation

Done Criteria

  • Docs and scripts agree on one canonical executable workflow.
  • Fixture runs are deterministic via:
  • python3 test/test_detect_custom_resources.py
  • bash test/test_validate_terragrunt.sh
  • Validation and security failures are reported with correct non-zero exits.

Главная - Вики-сайт
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-07-06 10:20
浙ICP备14020137号-1 $Гость$