Skip to content

Ensono/stacks-eirctl-configurations

Repository files navigation

Stacks Eirctl Configurations

Reusable eirctl task configurations - enabling streamlined CI/CD workflows across Azure DevOps and GitHub Actions pipelines.

Overview

This repository provides task definitions that can be imported into your eirctl task runner. These configurations cover common Platform Engineering operations:

  • Infrastructure as Code - Terraform formatting, validation, planning, and deployment
  • Security and Quality - Static analysis with Checkov, PSScriptAnalyzer, YAML linting
  • Pipeline Management - Azure DevOps pipeline retention and build numbering
  • Git Operations - Automated tagging and GitHub releases
  • Documentation - AsciiDoc to Markdown conversion and documentation builds
  • Module Packaging - Terraform module build, copy, and zip packaging

Tasks run inside containerised execution contexts using Ensono Independent Runner (EIR) Docker images. Several tasks invoke PowerShell functions provided by the EIR containers (Invoke-Terraform, Invoke-YamlLint, Import-TerraformOutputsToAdoVariableGroup, Update-BuildNumber, Publish-GitHubRelease, Build-Documentation) rather than calling CLI tools directly.

Getting Started

Prerequisites

  • eirctl installed (v0.9.11+)
  • Docker (for containerised task execution)
  • Azure CLI credentials (for Azure-related tasks)

Installation

Import configurations directly from this repository into your eirctl.yaml file:

Terraform Example

# yaml-language-server: $schema=https://raw.githubusercontent.com/Ensono/eirctl/refs/heads/main/schemas/schema_v1.json

import:
  - https://raw.githubusercontent.com/Ensono/stacks-eirctl-configurations/main/shared/contexts/eirctl.yaml
  - https://raw.githubusercontent.com/Ensono/stacks-eirctl-configurations/main/shared/infra/terraform.yaml
  - https://raw.githubusercontent.com/Ensono/stacks-eirctl-configurations/main/shared/security/eirctl.yaml

watchers:
  lint:
    watch: ["*.yml"]
    events: [create, write]
    task: lint:yaml
  terraform:
    watch: ["*.tf", "*.tfvars"]
    events: [create, write]
    task: lint:terraform:format

pipelines:
  lint:
    - task: lint:yaml
    - task: lint:terraform:format
      depends_on: lint:yaml
    - task: lint:terraform:validate
      depends_on: lint:terraform:format
    - task: lint:terraform:tflint
      depends_on: lint:terraform:validate

  scan:
    - task: scan:terraform:checkov

  tests:
    - task: terraform:init:false
    - task: terraform:tests
      depends_on: terraform:init:false

  infrastructure:plan:
    - task: terraform:init
    - task: terraform:plan
      depends_on: terraform:init

  infrastructure:apply:
    - task: terraform:init
    - task: terraform:apply
      depends_on: terraform:init

Tip

Pin to a specific tag instead of main to prevent breaking changes.

Usage

Once imported, run tasks using eirctl:

# Linting
eirctl lint

# Security scanning
eirctl scan

# Terraform
eirctl tests
eirctl infrastructure:plan
eirctl infrastructure:apply

Project Structure

stacks-eirctl-configurations/
├── .github/
│   ├── copilot-instructions.md    # AI assistant guidelines
│   └── pull_request_template.md
├── build/
│   └── ado/
│       ├── pipeline.yml           # Azure DevOps CI pipeline
│       ├── templates/
│       │   └── setup.yml          # Eirctl installation template
│       └── variables.yml          # Pipeline variables
├── shared/                        # All task configurations
│   ├── ado/
│   │   └── eirctl.yaml            # Azure DevOps tasks
│   ├── contexts/
│   │   └── eirctl.yaml            # Execution contexts (EIR Docker images)
│   ├── docs/
│   │   └── eirctl.yaml            # Documentation tasks
│   ├── git/
│   │   └── eirctl.yaml            # Git tagging tasks
│   ├── github/
│   │   └── eirctl.yaml            # GitHub release tasks
│   ├── infra/
│   │   └── terraform.yaml         # Terraform workflow tasks
│   └── security/
│       └── eirctl.yaml            # Linting and scanning tasks
├── test/
│   └── eirctl.yaml                # Combined config for CI validation
├── eirctl.yaml                    # Root config (imports for local dev)
├── yamllint.conf                  # YAML linting configuration
├── LICENSE
└── README.md

Domain Organisation

Domain Directory Description
Azure DevOps shared/ado/ Pipeline retention, build numbering
Contexts shared/contexts/ EIR Docker execution contexts
Documentation shared/docs/ AsciiDoc/Markdown generation
Git shared/git/ Tagging and push operations
GitHub shared/github/ Release publishing
Infrastructure shared/infra/ Terraform lifecycle tasks
Security shared/security/ Linting and static analysis
Validation test/ Combined config for CI validation

Available Tasks

Infrastructure (shared/infra/terraform.yaml)

Task Description
lint:terraform:format Perform Terraform format check (set TF_DEBUG=true for debug output)
lint:terraform:validate Perform Terraform validate (set TF_DEBUG=true for debug output)
lint:terraform:tflint Perform Terraform linting using TFLint (JUnit XML output)
terraform:docs:asciidoc Generate Terraform module documentation into AsciiDoc format (requires TF_MODULE_NAME and docs/readme directory)
terraform:docs:asciidoc:readme Copy the AsciiDoc-generated README to the module source directory (runs after docs:markdown)
terraform:init Initialise Terraform (supports optional backend args, workspace, and TF_DEBUG)
terraform:init:false Initialise Terraform with -backend=false
terraform:tests Run Terraform tests with JUnit XML output (supports TF_TEST_FILTER)
terraform:plan Terraform plan (set TF_DEBUG=true for debug output)
terraform:apply Apply Terraform plan (set TF_DEBUG=true for debug output)
terraform:destroy:plan Terraform destroy plan (set TF_DEBUG=true for debug output)
terraform:destroy:apply Terraform destroy apply (set TF_DEBUG=true for debug output)
terraform:build:clean Clean outputs folder
terraform:build:copy Copy module files into outputs/module/ (supports nested and flat module layouts)
terraform:build:package Create zip package for Terraform module (requires TF_MODULE_NAME)
terraform:outputs:ado Add Terraform outputs to Azure DevOps variable group

Security and Quality (shared/security/eirctl.yaml)

Task Description
lint:yaml YAML linting using yamllint (set YAMLLINT_FAIL_ON_WARNINGS=true for strict mode)
lint:powershell PSScriptAnalyzer on embedded PowerShell in eirctl YAML files (JUnit XML output)
scan:terraform:checkov Terraform static code analysis using Checkov (JUnit XML output)

Documentation (shared/docs/eirctl.yaml)

Task Description
docs:docbook Convert AsciiDoc documentation to Docbook for conversion to Markdown (requires ADOC_INDEX_FILE, docs/readme directory)
docs:markdown Convert the Docbook README to Markdown (extracts title, adjusts headings, cleans up terraform-docs markers)
docs:generate Build AsciiDoc documentation

Azure DevOps (shared/ado/eirctl.yaml)

Task Description
ado:build:number Update the build number in Azure DevOps
ado:pipeline:retain Retain an Azure DevOps pipeline run (configurable via RETENTION_YEARS)

Git (shared/git/eirctl.yaml)

Task Description
git:tag Tag a commit and push to origin (ADO and GitHub)

GitHub (shared/github/eirctl.yaml)

Task Description
github:release Publish a GitHub Release

Configuration

User-Configured Environment Variables

Variable Used By Description
TF_FILE_LOCATION Terraform tasks Path to Terraform files
TF_DEBUG Terraform tasks Set to true to enable debug output
TF_BACKEND_INIT terraform:init Backend initialisation arguments
TF_TEST_FILTER terraform:tests Optional filter for a specific test file
TFLINT_CONFIG lint:terraform:tflint Path to TFLint configuration file
ENVIRONMENT_NAME terraform:init Target environment/workspace name
WORKSPACE_VARS_FILE terraform:plan, terraform:destroy:plan Optional tfvars file path
ADO_ACCESS_TOKEN ADO tasks Azure DevOps pipeline OAuth token ($(System.AccessToken))
ADO_ORGANISATION terraform:outputs:ado Azure DevOps organisation name
ADO_VARIABLE_GROUP_NAME terraform:outputs:ado Variable group name for Terraform outputs
ADO_VARIABLE_NAME_PREFIX terraform:outputs:ado Prefix for variable names in ADO
RETENTION_YEARS ado:pipeline:retain Years to retain pipeline runs (default: 1)
CHECKOV_VERSION scan:terraform:checkov Optional specific Checkov version
TF_MODULE_NAME terraform:docs:asciidoc, terraform:build:package Module name used for docs/readme/<module> output folder and zip package filename
ARTIFACTS_DIR github:release Release assets directory (default: outputs/assets)
PUBLISH_RELEASE github:release Set to true to publish a release (default: true, handled by Publish-GitHubRelease)
UPLOAD_ARTIFACTS github:release Set to false to skip artifact upload (default: true)
PRERELEASE github:release Set to true to publish as a pre-release
ADOC_INDEX_FILE docs:docbook Path to the AsciiDoc index file
BUILDNUMBER docs:generate Build number for documentation generation
YAMLLINT_FAIL_ON_WARNINGS lint:yaml Set to true to enable strict mode (default: false)
PSSCRIPTANALYZER_EXCLUDE_RULES lint:powershell Comma-separated rule names to exclude
PSSCRIPTANALYZER_PATH lint:powershell Override search directory (default: .)

Automatic Platform Variables

These are set automatically by the CI platform and do not need to be configured:

Variable Platform Description
SYSTEM_TEAMPROJECT ADO Project name
SYSTEM_COLLECTIONURI ADO Organisation URI
SYSTEM_DEFINITIONID ADO Pipeline definition ID
SYSTEM_ACCESSTOKEN ADO Pipeline OAuth token
BUILD_BUILDID ADO Build run ID
BUILD_BUILDNUMBER ADO Build number
BUILD_SOURCEVERSION ADO Commit SHA
BUILD_REQUESTEDFORID ADO User who queued the build
BUILD_REPOSITORY_NAME ADO Repository full name
BUILD_REPOSITORY_URI ADO Repository URI
GITHUB_SHA GitHub Actions Commit SHA
GITHUB_REPOSITORY GitHub Actions Owner/repo name
GITHUB_RUN_NUMBER GitHub Actions Workflow run number
GITHUB_TOKEN GitHub Actions Automatic authentication token

Execution Contexts

Tasks run inside Ensono Independent Runner (EIR) Docker containers defined in shared/contexts/eirctl.yaml:

Context Container Purpose
infra ensono/eir-infrastructure:1.2.45 Terraform, linting, scanning, PSScriptAnalyzer
asciidoc ensono/eir-asciidoctor:1.2.45 Documentation generation
powershell ensono/eir-foundation-powershell:1.2.45 ADO tasks, git operations, build/package

EIR images provide PowerShell modules and CLI tools used by the tasks. Functions such as Invoke-Terraform, Invoke-YamlLint, Import-TerraformOutputsToAdoVariableGroup, Update-BuildNumber, Publish-GitHubRelease, and Build-Documentation are built into the containers.

Test Results

Tasks that produce JUnit XML test results:

Task Output File
lint:terraform:tflint test-results/tflint-results.xml
lint:powershell test-results/psscriptanalyzer-results.xml
terraform:tests test-results/terraform-test-results.xml
scan:terraform:checkov test-results/checkov-results.xml

Development

Prerequisites

Install the pre-commit hooks before making changes:

pre-commit install

Adding New Tasks

  1. Create or update a YAML file in the appropriate shared/ subdirectory
  2. Follow the task naming convention: category:subcategory:action (lowercase, colon-separated)
  3. If a new file is added, add the file to test/eirctl.yaml imports
  4. Ensure all tasks have a description field
  5. Update this README with the new task

Validation

All changes are validated in CI:

# YAML linting
eirctl lint:yaml

# PowerShell static analysis
eirctl lint:powershell

# Verify all import paths resolve
# (checks that every file listed in test/eirctl.yaml imports exists on disk)

# Configuration validation
eirctl validate --config test/eirctl.yaml

# Verify tasks loaded
# (confirms at least one task was registered after validation)

Coding Standards

  • YAML indentation: 2 spaces (enforced by yamllint)
  • Task naming: Colon-separated namespaces in lowercase
  • PowerShell: Use $env:VARIABLE_NAME for environment variables
  • Descriptions: Required for all tasks; use pipe (|) for multi-line
  • Error handling: Use Write-Error and exit 1 for failures
  • EIR functions: Prefer EIR-provided functions over raw CLI invocations
  • Test results: Write JUnit XML to test-results/ directory
  • Multi-platform: Use fallback pattern for ADO/GitHub variables (e.g. BUILD_BUILDNUMBER / GITHUB_RUN_NUMBER)

Testing

The test/eirctl.yaml file imports all configuration files for combined validation. CI runs eirctl validate against this configuration on every pull request, alongside YAML linting and PSScriptAnalyzer checks.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Follow the coding standards above
  4. Add your file to test/eirctl.yaml
  5. Update this README with any new tasks
  6. Open a Pull Request

Links

License

MIT License - see LICENSE for details.

About

Reusable eirctl task configurations for Ensono Stacks

Topics

Resources

License

Stars

Watchers

Forks

Contributors