ansible-lockdown/github_windows_IaC
:computer: Workflow Data For Github Actions & Windows Server Testing of Lockdown Enterprise Content :computer:
GitHub Windows IaC
Infrastructure as Code (IaC) modules and automation for use with the Lockdown Enterprise (LE) Windows-based pipelines. This central repository supports Windows benchmarking, deployment automation, and security hardening for CI workflows using Terraform (OpenTofu) and Ansible.
π Table of Contents
- π¦ Features
- π Required Secrets
- π Repository Variables (Required)
- ποΈ IaC Modules
- π§ͺ Pipeline Validation
- π§ͺ Pipeline Validation Workflows
- π₯οΈ Run Locally (Test Terraform + Ansible)
- π Reusable GitHub Actions Workflows
- π·οΈ Badge Types and Their Sources
- π Benchmark Tracker & Teams/Discord Notifications
- π Benchmark Tracker Workflow Details
- π¬ Notification Examples
- π§ Linux Benchmark Badge Support
- π GitHub Pages Deploy (~70m cadence)
π Shared Workflows (Windows + Linux)
1. π¦ Features
- Centralized IaC logic for all Windows benchmark pipelines (CIS/STIG)
- Dynamic provisioning of Hyper-V Windows runners using OpenTofu
- Self-hosted runner workflows with automatic Terraform + Ansible flow
- GPO testing support via alternate variable files (e.g.,
WIN2022GPO.tfvars) - Discord onboarding notifications for first-time contributors
- Shared GitHub Actions workflows for badge export and testing
- Support for local testing of IaC outside GitHub Actions
2. π Required Secrets (Required)
These secrets must be configured under Settings β Secrets β Actions (repo or org level).
The Private repos will need to be configured in the individual repos because the org secrets
do not function in private on our current plan.:
| Secret Name | Description |
|---|---|
AZURE_AD_CLIENT_ID |
Azure AD app registration client ID |
AZURE_AD_CLIENT_SECRET |
Azure AD app secret |
AZURE_AD_TENANT_ID |
Azure AD tenant ID |
AZURE_SUBSCRIPTION_ID |
Azure subscription ID |
WIN_USERNAME |
Admin username for the Windows VM |
WIN_PASSWORD |
Admin password for the Windows VM |
3. π Repository Variables (Required)
These must be added under Settings β Actions β Variables in benchmark repos (e.g., Windows-2022-CIS):
| Variable Name | Description | Example |
|---|---|---|
ANSIBLE_RUNNER_VERSION |
Version of Ansible used by the CI runner | 2.16.2 |
BENCHMARK_TYPE |
Benchmark under test (CIS, STIG, etc.) |
CIS |
ENABLE_DEBUG |
Enable debug output and disable auto-destroy (true/false) |
false |
IAC_BRANCH |
GitHub branch to load IaC modules from | main or devel |
OSVAR |
OS tfvars file base name (e.g., WIN2025) |
WIN2025 |
GPO_OSVAR |
OS tfvars for GPO variant (e.g., WIN2025GPO) |
WIN2025GPO |
4. ποΈ IaC Modules
This repo uses OpenTofu to provision Windows test runners locally or inside GitHub Actions for compliance validation.
Terraform Files
| File | Description |
|---|---|
main.tf |
Creates Hyper-V-based Windows VMs with required networking and provisioning logic |
vars.tf |
Defines all input variables used by main Terraform plan |
WIN2022.tfvars |
Variable file for standard Windows Server 2022 runner setup |
WIN2022GPO.tfvars |
GPO testing variant for Windows Server 2022 |
5. π§ͺ Pipeline Validation Workflows
This repository supports automated validation pipelines that run on every push to main or devel branches of Windows benchmark repositories. These workflows are split by purpose:
- Standard validation (
main_pipeline_validation.yml,devel_pipeline_validation.yml) - Group Policy (GPO) validation (
main_pipeline_validation_gpo.yml,devel_pipeline_validation_gpo.yml)
6. π§ͺ Pipeline Validation Workflows
6.1 π§Ό Standard Benchmark Validation
Provision β Apply β Validate β Destroy
These workflows provision a fresh Windows environment, apply the benchmark using Ansible, and validate compliance.
6.1.1 Trigger Files:
.github/workflows/main_pipeline_validation.yml.github/workflows/devel_pipeline_validation.yml
graph TD;
A[Push to Main or Devel] --> B[Trigger Pipeline Workflow]
B --> C[Load IaC repo]
C --> D[Import Variables and Secrets]
D --> E[Setup Environment: Terraform + Ansible]
E --> F[Run terraform init]
F --> G[Run terraform validate]
G --> H[Run terraform apply β provision Windows host]
H --> I[Wait 60s if ENABLE_DEBUG is set]
I --> J[Run ansible-playbook β apply hardening]
J --> K[Validate results]
K --> L[Run terraform destroy to clean up]
6.2 π GPO Benchmark Validation
These workflows use a GPO-specific configuration to validate settings enforced through Group Policy Objects.
6.2.1 Trigger Files:
.github/workflows/main_pipeline_validation_gpo.yml.github/workflows/devel_pipeline_validation_gpo.yml
graph TD;
A[Push to Main or Devel GPO] --> B[Trigger GPO Pipeline Workflow]
B --> C[Load IaC repo for GPO testing]
C --> D[Import GPO-specific tfvars e.g., WIN2022GPO]
D --> E[Setup Terraform + Ansible for GPO run]
E --> F[Run terraform init]
F --> G[Run terraform validate]
G --> H[terraform apply to launch GPO test VM]
H --> I[Inject Group Policy settings via Ansible]
I --> J[Audit or validate policy impact]
J --> K[Run terraform destroy to clean up]
Each workflow is fully integrated with badge export automation and can be extended with extra validation stages (e.g., log parsing, custom output diffing) as needed.
6.3 π Workflow Matrix
| Workflow Filename | Description | Trigger Branches | OSVAR Source |
|---|---|---|---|
main_pipeline_validation.yml |
Validates Ansible remediation on main release | main, latest |
${OSVAR} |
main_pipeline_validation_gpo.yml |
Validates GPO settings using Ansible | main, latest |
${GPO_OSVAR} |
devel_pipeline_validation.yml |
Validates draft PRs and benchmark experiments | devel, benchmark_* |
${OSVAR} |
devel_pipeline_validation_gpo.yml |
GPO validation for draft/benchmark branches | devel, benchmark_* |
${GPO_OSVAR} |
6.3.1 π§ͺ Example Workflow Usage
These workflows are automatically triggered, but you can simulate them via PRs.
6.3.1.1 π§ main_pipeline_validation.yml
# Triggers on PR to main/latest
# Uses: ${OSVAR}.tfvars6.3.1.2 π main_pipeline_validation_gpo.yml
# Triggers on PR to main/latest for GPO testing
# Uses: ${GPO_OSVAR}.tfvars6.3.1.3 π§ͺ devel_pipeline_validation.yml
# Triggers on PR to devel or any 'benchmark_*' branch
# Uses: ${OSVAR}.tfvars6.3.1.4π devel_pipeline_validation_gpo.yml
# Triggers on PR to devel or 'benchmark_*' for GPO enforcement
# Uses: ${GPO_OSVAR}.tfvars7. π₯οΈ Run Locally (Test Terraform + Ansible)
export BENCHMARK_TYPE="CIS"
export OSVAR="WIN2022"
export TF_VAR_repository="${OSVAR}-${BENCHMARK_TYPE}"
export TF_VAR_BENCHMARK_TYPE="${BENCHMARK_TYPE}"
terraform init
terraform validate
terraform apply -var-file="WIN2022.tfvars" --auto-approve
terraform destroy -var-file="WIN2022.tfvars" --auto-approve8. π Reusable GitHub Actions Workflows
This repository (github_windows_IaC) maintains shared GitHub Actions workflows that are reused by Windows benchmark repos to manage badge exports and automation logic.
8.1 π Available Shared Workflows
| Workflow Filename | Purpose |
|---|---|
.github/workflows/export_badges_private.yml |
Used in private repos for badge JSON export |
.github/workflows/export_badges_public.yml |
Used in public repos for shields.io badge endpoints |
8.2 π§© Usage in Benchmark Repositories
Benchmark repos include a wrapper workflow like:
# .github/workflows/export_badges_private.yml
name: Export Badges to Private Repo
on:
push:
branches: [ latest ]
jobs:
export-badges:
uses: ansible-lockdown/github_windows_IaC/.github/workflows/export_badges_private.yml@main
secrets:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BADGE_PUSH_TOKEN: ${{ secrets.BADGE_PUSH_TOKEN }}The reusable logic lives in the
github_windows_IaCrepo. This makes badge generation portable and consistent.
8.3 π Badge Secret Note
| Secret Name | Where Needed | Notes |
|---|---|---|
BADGE_PUSH_TOKEN |
π Private Repos | Must be set manually even if it exists at the org level |
GH_TOKEN |
All repos | Provided automatically by GitHub Actions |
8.4 π§ Workflow Flow
graph TD;
A[Push to latest or main branch] --> B[Triggers local wrapper workflow]
B --> C[Calls reusable IaC workflow using 'uses']
C --> D[Generates JSON badge data]
D --> E[Pushes to badge cache or GitHub Pages]
E --> F[Badge rendered via shields.io or embedded in README]
9. π·οΈ Badge Types and Their Sources
This repository supports a wide variety of badges across public and private benchmark repositories. These badges serve different purposes and come from different systems.
9.1 π§· Recommended Badge Format
[](https://results.pre-commit.ci/latest/github/ansible-lockdown/Windows-2022-CIS/devel)9.2 π§° Badge Integration Guidance
- Dynamic badges use
.jsonfiles hosted in thegithub_windows_IaCbadges/folder. - They are updated using the
export_badges_public.ymlandexport_badges_private.ymlworkflows. - Public repos use pre-built shields.io URLs.
- Private repos consume the same badge format but must manually set the
BADGE_PUSH_TOKEN.
9.3 β Recommended Placement in README.md
You can structure your badge sections like this:
## Public Repository π£



[](...)

[](...)
...
## Subscriber Release Information π

[](...)
...10. π Benchmark Tracker & Teams/Discord Notifications
The github_windows_IaC repository contains a shared workflow system that automates benchmark version tracking across private repositories. Once a benchmark reaches 90 days in a private repo, it is eligible for auto-promotion to its corresponding public repository. Notifications are sent via Microsoft Teams and Discord.
10.1 π§© Workflow Files
| Workflow File | Description |
|---|---|
benchmark_track.yml |
Called by private repos to initiate tracking. Determines if a benchmark version is missing from the public repo, and opens a 90-day issue if so. Sends Teams and Discord notifications. |
benchmark_promote.yml |
Called daily from a central repo. Monitors all tracking issues. If 90+ days old, closes issues (if already promoted) or auto-creates PRs. Sends milestone reminders and promotion alerts. |
10.2 π Required Secrets
These secrets must be configured in the GitHub repositories involved:
| Secret Name | Scope | Purpose |
|---|---|---|
GH_TOKEN |
All repos | Required for GitHub CLI operations (issues, PRs, comments, etc.) |
TEAMS_WEBHOOK_URL |
All repos | Used to send Adaptive Card notifications to Microsoft Teams |
DISCORD_WEBHOOK_URL |
All repos | Sends milestone, promotion, and closure alerts to Discord channels |
BADGE_PUSH_TOKEN |
All repos | Grants write access to push badge files to github_windows_IaC |
Add these under:
Settings β Secrets β Actionsfor each participating repository.
π 10.3 Setup Checklist
Set the required secrets in each Private repo:
GH_TOKENTEAMS_WEBHOOK_URLDISCORD_WEBHOOK_URLBADGE_PUSH_TOKEN
Private Repo:
- Call
benchmark_track.ymlfrom PR merges or scheduled runs.
IaC Repo:
- Schedule
benchmark_promote.ymlto run daily.
Public Repo:
- Ensure
develbranch andREADME.mdexist to validate versions.
Teams/Discord Webhooks:
- Ensure your automation supports HTTP POST with full JSON payloads.
π 10.4 Additional Notes
- Benchmarks must follow naming conventions (
Private-Windows-*βWindows-*). README.mdformat must include a recognizable version string (e.g.,vX.Y.ZorVersion X, Rel Y).- All workflows are modular and intended to be reused across repos.
- Discord support is now included in all milestones and promotion actions.
β This setup ensures full traceability and timely promotion of compliance benchmarks while keeping all stakeholders informed.
11 π Benchmark Tracker Workflow Details
11.1 π benchmark-tracker Workflow
Triggered when a pull request from a branch matching benchmark_* is merged into the latest branch of a Private repo.
π What it does:
- Extract version from PR branch name
Example:benchmark_v2.0.0becomesv2.0.0 - Create a GitHub issue in the same repo with a 90-day countdown
- Assign labels, version tags, and metadata to the issue
- Post a confirmation comment in the PR for traceability
This tracks the need to promote this version publicly after 90 days.
11.2 β± monitor-90day-promotions Workflow
Runs daily from the IaC repo. Monitors issues created by the tracker workflow.
π What it does:
- Scan all private repos for open issues labeled as benchmark trackers
- Parse the issue body to extract the version, repo name, and date created
- Calculate the age of each issue
- If the issue is older than 90 days:
- Clones the corresponding public repo
- Creates a PR to add the benchmark version to the
mainbranch - Uses
gh pr createandgh pr mergeto automate promotion - Pushes new badge files to
github_windows_IaC - Sends a Teams notification with summary info
- Closes the original issue with a comment
If the issue is not yet 90 days old, it is skipped and checked again on the next scheduled run.
11.3 π οΈ Code Highlights
Each step is modularized inside the workflow YAML:
benchmark-tracker.yml- name: Detect PR branch and extract version- name: Create 90-day tracking issue- name: Label and annotate PR
monitor-90day-promotions.yml- name: Search for benchmark tracker issues- name: Compare age against 90-day threshold- name: Promote version if qualified- name: Send Teams notification via webhook- name: Update badge JSON in IaC
11.4 π οΈ How the Tracker System Works
graph TD;
A[Private Repo Calls benchmark_track.yml] --> B{Is Public Repo Missing Version?}
B -- No --> C[No Action Needed]
B -- Yes --> D[Open 90-Day Tracking Issue]
D --> E[Send Tracking Start Notifications]
E --> F[benchmark_promote.yml Runs Daily]
F --> G{Is Issue 90+ Days Old?}
G -- No --> H[Send Milestone Reminders 30/60/90 Days]
G -- Yes --> I{Already Promoted?}
I -- Yes --> J[Close Issue, Send Notifications]
I -- No --> K[Create PR to Public Repo]
K --> L[Send PR Notifications to Teams & Discord]
12. π¬ Notification Examples
The system supports Teams and Discord alerts for all key events during benchmark tracking and promotion. These include:
- β Tracking Started
- π¨ Public Repo Missing
- β° Milestone Reminders (30, 60, 90 days)
β οΈ Overdue Warnings- β Already Promoted Notices
- β Promotion Blocked Alerts
- π¨ Auto-Promotion PR Created
Each message is customized for Teams and Discord formatting, with links to issues and PRs where applicable.
β Tracking Started β Teams
π Tracking Initiated - v2.0.0
π Subscriber Repo: ansible-lockdown/Private-Windows-2022-CIS
π¦ Subscriber Version: v2.0.0
π Community Target: ansible-lockdown/Windows-2022-CIS
π¦ Community Version: v1.9.0
β³ Subscriber Review Ends: Approx: 2025-09-07
ποΈ Auto-Promotion Date To Community: Approx: 2025-09-12
π
Promotion In: 90 daysπ¨ Public Repo Missing β Teams
π¨ Tracking Started β But There's A Problem π¨
Benchmark version 'v2.0.0' from **Private-Windows-2022-CIS** has entered the 90-day window.
β οΈ However, the public repo **Windows-2022-CIS** is missing or incomplete.
π’ Please create and prepare the community repo.β Tracking Started β Discord
π Benchmark Release To Community Tracking Started
π Subscriber Repo: ansible-lockdown/Private-Windows-2022-CIS
π¦ Subscriber Version: v2.0.0
π Community Repo: ansible-lockdown/Windows-2022-CIS
π¦ Community Version: v1.9.0
β³ Review Ends: 2025-09-07
ποΈ Auto-Promotion Date: 2025-09-12β° 30/60/90 Day Reminder β Discord
β° Benchmark Promotion Milestone
π’ 60-Day Reminder: Benchmark `v2.0.0` is scheduled for promotion in 30 days.
β οΈ If not promoted manually, auto-promotion occurs on Day 95.
π Subscriber Repo: Private-Windows-2022-CIS
π¦ Version: v2.0.0
π Target: Windows-2022-CIS
β±οΈ Days Tracked: 60
π Scheduled Auto-Promotion: 2025-09-12β οΈ Overdue Reminder β Teams
β° Benchmark Promotion Reminder
β οΈ Benchmark v2.0.0 from `Private-Windows-2022-CIS` is overdue by 3 days.
β²οΈ Auto-promotion will occur in 2 days.
π View Issue #43β Already Promoted β Teams
β
Benchmark Already Promoted
Benchmark version v2.0.0 is already in Windows-2022-CIS.
π
Auto-closed on: 2025-09-05
π View Issue #43β Already Promoted β Discord
β
Benchmark Promoted To Community
Benchmark v2.0.0 from `Private-Windows-2022-CIS` is already in `Windows-2022-CIS`
πΏ Branch: devel
π
Auto-closed: 2025-09-05
π Issue: View Issue #43β Promotion Blocked β Teams
β Benchmark Promotion Will Be Blocked
π« The community repo **Windows-2022-CIS** does not exist or is missing `devel`.
π’ Please resolve this to enable promotion.
π Repo: Private-Windows-2022-CIS
π¦ Version: v2.0.0π¨ Auto-Promotion PR Created β Teams
π¨ Benchmark PR Automatically Created π¨
Version v2.0.0 from Private-Windows-2022-CIS has been proposed for promotion.
π PR: https://github.com/ansible-lockdown/Windows-2022-CIS/pull/99
π
Days Tracked: 95
π Branch: promote_benchmark_v2_0_0π¦ Auto-Promotion PR Created β Discord
π¦ Benchmark Promotion PR Created: Promote v2.0.0
π Repo: Private-Windows-2022-CIS
π Target: Windows-2022-CIS
πΏ Branch: [promote_benchmark_v2_0_0](https://github.com/ansible-lockdown/Windows-2022-CIS/tree/promote_benchmark_v2_0_0)
π PR: https://github.com/ansible-lockdown/Windows-2022-CIS/pull/99
π
Days Tracked: 9513. π§ Linux Benchmark Badge Support
The Linux IaC repository also acts as the central badge hub for Linux-based benchmark pipelines.
- All badge JSON files for Linux CIS and Linux STIG benchmarks are written to the
badges/directory in this repo - The same export workflows (
export_badges_public.yml,export_badges_private.yml) handle both Windows and Linux badge publication - Example: A benchmark like
UBUNTU22-CISwill have badges stored at:
https://ansible-lockdown.github.io/github_linux_IaC/badges/UBUNTU22-CIS/pre-commit-ci.json
This keeps badge generation consistent and centralized across all platforms for Lockdown.
14. π GitHub Pages Deploy (~70m cadence)
This repository includes a scheduled GitHub Pages deployment workflow (.github/workflows/pages_deploy.yml) that publishes the entire repo root to GitHub Pages on a ~70-minute cadence, with one intentional long gap per day.
Key Details:
- Purpose: Push updated site content (including
/badges/*.json) to GitHub Pages. - Cadence: Runs ~every 70 minutes, except for a ~110-minute gap overnight in the Eastern Time zone.
- Gap Placement: UTC schedule is arranged so the long gap (~03:10β05:00 UTC) corresponds to ~11:10 pmβ1:00 am ET during Daylight Saving Time.
- .nojekyll: Ensures raw JSON endpoints and other non-Jekyll assets are served correctly.
- Concurrency: Deploy jobs are never canceled once started, preventing partial publishes.
Mermaid Workflow Diagram
flowchart TD
A[Scheduled Trigger ~70m cadence \n UTC cron times] --> B[Checkout repo root self_hosted branch]
B --> C[Create .nojekyll to preserve JSON/raw files]
C --> D[Upload site as Pages artifact]
D --> E[Deploy to GitHub Pages environment]
E --> F[Public site updated \n e.g., /badges/*.json endpoints]
Cron Schedule Overview
| UTC Time(s) | Approx. ET Time(s)* | Notes |
|---|---|---|
02:00, 05:00, 12:00, 19:00 |
10:00 pm, 1:00 am, 8:00 am, 3:00 pm | Major deploys |
03:10, 06:10, 13:10, 20:10 |
11:10 pm, 2:10 am, 9:10 am, 4:10 pm | Staggered deploys |
07:20, 14:20, 21:20 |
3:20 am, 10:20 am, 5:20 pm | Staggered deploys |
08:30, 15:30, 22:30 |
4:30 am, 11:30 am, 6:30 pm | Staggered deploys |
09:40, 16:40, 23:40 |
5:40 am, 12:40 pm, 7:40 pm | Staggered deploys |
00:50, 10:50, 17:50 |
8:50 pm, 6:50 am, 1:50 pm | Staggered deploys |
*Times adjust by +1 hour during Eastern Standard Time (EST).
π§© Contributing
Pull requests are welcome. When you open your first PR, a Discord invite will be sent automatically (if enabled). Ensure your repo is configured with the appropriate variables and secrets to execute workflows.
π Shared Workflows (Windows + Linux)
The following sections (15 & 16) describe workflows that are not Windows-specific.
They are shared across both Windows and Linux IaC repos.
- To keep documentation consistent, the Windows repo (
github_windows_IaC) hosts the canonical docs. - Linux IaC repos and the org profile
.githubpage link here for reference. - Although examples use Windows repo names, the same workflows run in Linux repos as well.
15. π Export Audit Repo Badges (IaC)
This workflow automates how we track, display, and publish audit repository availability across all CIS and STIG baselines. It guarantees that both CIS and STIG tables always have corresponding audit badge entries, even if one counterpart doesnβt yet exist.
Why we did this
- Eliminate manual badge upkeep β no more checking if audit repos exist or contain
latest/goss.yml. - Ensure table coverage β CIS/ STIG counterparts are always represented.
- Increase transparency β consumers instantly see Available vs Not Available.
- Lifecycle safety β prunes invalid/legacy badges automatically.
- Publish stability β concurrency + single publisher prevents race conditions.
Workflow Breakdown
-
Discover Repos
- Lists all
*-CIS/*-STIGrepos inansible-lockdown(non-archived, non-forked). - Normalizes names, excludes
-Audit. - Adds counterparts (CIS β STIG).
- Lists all
-
Build Badges (Matrix)
- For each base repo, check
<Base>-Audit. - Conditions: repo exists,
latestbranch exists,goss.ymlpresent. - Generates badge JSON:
- Available β brightgreen
- Not Available β lightgrey
- For each base repo, check
-
Aggregate Results
- Collects badge artifacts into
output/badges/audit. - Adds
.nojekyllfor GitHub Pages.
- Collects badge artifacts into
-
Publish to IaC Repo
- Clones target IaC repo (default:
ansible-lockdown/github_windows_IaC@self_hosted). - Rsyncs badges β
badges/audit/. - Prunes invalid files.
- Commits + pushes with retry on race.
- Clones target IaC repo (default:
Schedule & Inputs
- Runs daily β
cron: "15 4 * * *"(04:15 UTC). - Manual trigger:
repo_nameβ process single CIS/STIG repo.target_iac_repoβ override target repo.target_branchβ override publish branch.
Required Secret
BADGE_PUSH_TOKENβ GitHub token with repo access.
Badge Schema
{ "schemaVersion": 1, "label": "Repo", "message": "Available", "color": "brightgreen" }
Message: Available / Not Available
Color: brightgreen / lightgrey
File name: <Base>-Audit-Badge.json
Example Output
Windows-2022-CIS β badges/audit/Windows-2022-CIS-Audit-Badge.json
Windows-2022-STIG β badges/audit/Windows-2022-STIG-Audit-Badge.jsonWorkflow
graph TD;
A[Start Workflow] --> B[Discover Repos]
B --> C[Expand CIS/STIG Counterparts]
C --> D[Matrix Fanout: Build Badges]
D -->|Available| E[brightgreen JSON Badge]
D -->|Not Available| F[lightgrey JSON Badge]
E --> G[Upload Artifacts]
F --> G[Upload Artifacts]
G --> H[Aggregate Results]
H --> I[Clone Target IaC Repo]
I --> J[Sync Badges β badges/audit/]
J --> K[Prune Legacy Files]
K --> L[Commit + Push]
L --> M[Published to Pages]
16. π·οΈ Create Temp Badges for README
This workflow seeds safe placeholder badges for repos so our README tables always renderβeven before real versions or releases exist. It never overwrites real badges, cleans up invalid legacy JSON, and fills gaps across both public and Private- repos.
Why we did this
- Continuous readability: README tables shouldnβt break or show blanks while teams are bootstrapping repos.
- Safety-first: Placeholders wonβt overwrite any legit (βrealβ) badge files.
- Coverage parity: Ensures both
-CISand-STIGfamilies (plusPrivate-counterparts) have minimal badges from day one. - Housekeeping: Removes old/invalid JSON so future workflows donβt trip on bad files.
What it does (step-by-step)
-
Checkout target badges branch
- Checks out the
self_hostedbranch (configurable viaTARGET_BRANCH) where badges live.
- Checks out the
-
Install tools
- Installs
jq; verifiesghavailability.
- Installs
-
Discover CIS/STIG repos
- Lists all org repos (
ansible-lockdown), excludes audits and this repo (github_windows_IaC). - Keeps names that end in
-CISor-STIG. - Builds four targets per baseline:
<Base>-CIS,<Base>-STIG,Private-<Base>-CIS,Private-<Base>-STIG.
- Lists all org repos (
-
Generate placeholders (without overwriting real badges)
- Public repos create/maintain:
badges/<Repo>/benchmark-version-main.json(label: βBenchmark Version (main)β)badges/<Repo>/benchmark-version-devel.json(label: βBenchmark Version (devel)β)badges/<Repo>/lockdown-release.json(label: βLockdown Releaseβ β populated from latest GitHub release if present, else placeholder)
- Private repos create/maintain:
badges/<Repo>/benchmark-version.json(label: βBenchmark Versionβ)
- Public repos create/maintain:
-
Schema cleanup
- Scans
badges/<Repo>/*.jsonand deletes invalid JSON (wrong/missing keys or extra keys). - Fresh placeholders are recreated automatically next run.
- Scans
-
Commit & push (only when changes occur)
- Fast-forwards before push; commits with a concise message.
Schedule & Triggers
- Daily:
cron: "45 4 * * *"(04:45 UTC) - Manual:
workflow_dispatchavailable via Actions UI
Permissions
permissions:
contents: writeSecrets
- Uses the default
secrets.GITHUB_TOKENfor discovery and pushes.
Badge schemas (placeholders)
Generic placeholder (used for most seeded files):
{ "schemaVersion": 1, "label": "<varies>", "message": "Not Available", "color": "lightgrey" }Lockdown Release (public repos):
- If a latest release exists:
{ "schemaVersion": 1, "label": "Lockdown Release", "message": "<tag or name>", "color": "blue" }- If no release:
{ "schemaVersion": 1, "label": "Lockdown Release", "message": "No Release", "color": "lightgrey" }π Safety: A file is considered a placeholder only if its
.messageis"Not Available"or"No Release". Real badges (anything else) are never overwritten.
Outputs & File Layout
Public repo example (Windows-2022-CIS):
badges/
Windows-2022-CIS/
benchmark-version-main.json
benchmark-version-devel.json
lockdown-release.json
Private repo example (Private-Windows-2022-STIG):
badges/
Private-Windows-2022-STIG/
benchmark-version.json
Example README Table (consuming these endpoints)
| Repo | Main Version | Devel Version | Lockdown Release |
|---|---|---|---|
| Windows-2022-CIS | |||
| Private-Windows-2022-STIG | β | β |
Diagram
flowchart TD
A[Start 04:45 UTC / manual] --> B[Checkout self_hosted branch]
B --> C[Install jq / verify gh]
C --> D[Discover -CIS / -STIG repos exclude -Audit, IaC]
D --> E[Expand targets incl. Private- counterparts]
E --> F[Clean invalid JSON schemas]
F --> G[Seed placeholders if missing or placeholder]
G --> H[Populate Lockdown Release from latest tag if available]
H --> I[Commit & Push if changed]
I --> J[Placeholders available for README tables]
β Result: READMEs remain fully populated and consistent from day one, while real pipelines can safely replace placeholders over time without risk of being overwritten.