-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathinventory-clusters.yml
More file actions
168 lines (155 loc) · 7.98 KB
/
Copy pathinventory-clusters.yml
File metadata and controls
168 lines (155 loc) · 7.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# AZLOCAL-PIPELINE-ID: inventory-clusters
# Inventory Azure Local Clusters
# This workflow queries all Azure Local clusters and exports inventory with UpdateRing tag status
#
# OUTPUT COLUMNS:
# ClusterName, ResourceGroup, SubscriptionId, SubscriptionName,
# UpdateRing, HasUpdateRingTag, UpdateStartWindow, UpdateExclusions,
# UpdateSideloaded, UpdateVersionInProgress, ResourceId
#
# - UpdateSideloaded (operator-set): True/False/1/0 - sideloaded-payload gate
# - UpdateVersionInProgress (module-managed; do not edit): staged update name
# See main module README, section "Sideloaded Payload Workflow".
#
# AUTHENTICATION OPTIONS:
# This workflow supports two authentication methods:
# 1. OpenID Connect (OIDC) - RECOMMENDED - No secrets, uses federated credentials
# 2. Client Secret - LEGACY - Requires AZURE_CLIENT_SECRET (see commented section)
#
# For OIDC setup, see: https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure-openid-connect
# Workflow name carries the same Step.N - prefix as the filename so the GitHub
# Actions sidebar (which sorts workflows alphabetically by this `name:` field)
# lists the eight pipelines in execution order.
name: Step.01 - Inventory Azure Local Clusters
on:
workflow_dispatch:
inputs:
subscription_filter:
description: 'Subscription ID to filter (leave empty for all subscriptions)'
required: false
default: ''
module_version:
description: 'Pin AzLocal.UpdateManagement version (empty = latest from PSGallery). See Automation-Pipeline-Examples/README.md section 5 "Optional configuration".'
required: false
default: ''
# BEGIN-AZLOCAL-CUSTOMIZE:schedule-triggers
# Content between BEGIN/END markers is preserved by
# Update-AzLocalPipelineExample across module upgrades. Edit the cron
# below or add more `- cron:` entries to suit your maintenance windows.
schedule:
# Run weekly on Monday at 6:00 AM UTC
- cron: '0 6 * * 1'
# END-AZLOCAL-CUSTOMIZE:schedule-triggers
env:
# Module version this workflow YAML was generated against. The install step compares
# this to the version actually installed and to the latest on PSGallery, and emits a
# ::notice annotation if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample. See Automation-Pipeline-Examples/README.md section 5.
GENERATED_AGAINST_MODULE_VERSION: '0.8.77'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): manual workflow_dispatch input >
# repository variable 'REQUIRED_MODULE_VERSION' > empty (latest).
REQUIRED_MODULE_VERSION: ${{ github.event.inputs.module_version || vars.REQUIRED_MODULE_VERSION || '' }}
# v0.8.4 - opt this workflow into Node.js 24 for all JavaScript actions
# (actions/checkout, actions/download-artifact, actions/upload-artifact,
# azure/login, dorny/test-reporter, etc). Per GitHub's 2025-09-19 deprecation
# notice Node 20 is forced off by default on 2026-06-16 and removed from the
# runner on 2026-09-16. Setting this env var silences the deprecation warnings
# and exercises Node 24 ahead of the cut-over. To temporarily opt back out,
# set ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION=true.
# https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
inventory-clusters:
name: Inventory Azure Local Clusters
runs-on: windows-latest
# Required for OIDC authentication
permissions:
id-token: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v5
# OPTION 1: OpenID Connect (OIDC) - RECOMMENDED
# No client secret required - uses federated credentials
- name: Azure CLI Login (OIDC)
uses: azure/login@v3
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
# AZURE_SUBSCRIPTION_ID is a repository *Variable* (vars.*), not a Secret. It
# is consumed ONLY here: azure/login@v3 runs `az account set --subscription
# <id>` after the OIDC token exchange so the runner has a default
# `az account` context. It is NOT used to scope Azure Resource Graph queries
# (those run fleet-wide across every subscription the federated identity can
# read) and is NOT interpolated into Azure portal deep-link URLs (those use
# the per-row `subscriptionId` returned by ARG).
# Set it via: gh variable set AZURE_SUBSCRIPTION_ID --body <subId>
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
# OPTION 2: Client Secret - LEGACY (uncomment if OIDC not available)
# - name: Azure CLI Login (Client Secret)
# uses: azure/login@v3
# with:
# creds: '{"clientId":"${{ secrets.AZURE_CLIENT_ID }}","clientSecret":"${{ secrets.AZURE_CLIENT_SECRET }}","subscriptionId":"${{ vars.AZURE_SUBSCRIPTION_ID }}","tenantId":"${{ vars.AZURE_TENANT_ID }}"}'
- name: Install Azure CLI Resource Graph Extension
shell: pwsh
run: |
az extension add --name resource-graph --yes
- name: Install AzLocal.UpdateManagement from PSGallery
# v0.8.5 thin-YAML: drift detection + banner + step outputs are all
# produced by Add-AzLocalPipelineVersionBanner (Public cmdlet).
shell: pwsh
id: module-version
run: |
$ErrorActionPreference = 'Stop'
$installArgs = @{ Name = 'AzLocal.UpdateManagement'; Scope = 'CurrentUser'; Force = $true; AllowClobber = $true }
if ($env:REQUIRED_MODULE_VERSION) {
$installArgs.RequiredVersion = $env:REQUIRED_MODULE_VERSION
Write-Host "REQUIRED_MODULE_VERSION is set - pinning install to v$($env:REQUIRED_MODULE_VERSION)."
} else {
Write-Host "REQUIRED_MODULE_VERSION is empty - installing the latest version from PSGallery (default fix-forward behaviour)."
}
Install-Module @installArgs
Import-Module AzLocal.UpdateManagement -Force
Add-AzLocalPipelineVersionBanner `
-GeneratedAgainstVersion $env:GENERATED_AGAINST_MODULE_VERSION `
-PinnedVersion $env:REQUIRED_MODULE_VERSION
- name: Run Cluster Inventory
id: inventory
shell: pwsh
env:
INPUT_SUBSCRIPTION_FILTER: ${{ github.event.inputs.subscription_filter }}
INSTALLED_MODULE_VERSION: ${{ steps.module-version.outputs.installed_module_version }}
# v0.8.5 thin-YAML: the inline run block (inventory query, dual
# CSV/JSON export, canonical CSV copy, README_Instructions.txt,
# step outputs, separate "Summary" step) has been condensed into
# the Public cmdlet Invoke-AzLocalClusterInventory. The cmdlet
# writes the four artifacts to -OutputDirectory, emits the
# markdown step summary via GITHUB_STEP_SUMMARY, and sets the
# four step outputs (cluster_count, with_tag_count,
# without_tag_count, csv_path).
run: |
$ErrorActionPreference = 'Stop'
Import-Module AzLocal.UpdateManagement -Force
Invoke-AzLocalClusterInventory `
-OutputDirectory './artifacts' `
-SubscriptionFilter $env:INPUT_SUBSCRIPTION_FILTER `
-InstalledModuleVersion $env:INSTALLED_MODULE_VERSION
- name: Compute Artifact Timestamp
id: artifact-stamp
shell: pwsh
# every downloadable artifact gets a UTC timestamp suffix so multiple runs on
# the same day produce distinct zip names.
run: |
$stamp = (Get-Date).ToUniversalTime().ToString('yyyyMMdd_HHmmss')
"timestamp=$stamp" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
Write-Host "Artifact timestamp: $stamp"
- name: Upload Inventory Artifact
uses: actions/upload-artifact@v6
with:
name: azlocal-step.1-cluster-inventory_${{ steps.artifact-stamp.outputs.timestamp }}
path: |
./artifacts/*.csv
./artifacts/*.json
./artifacts/README_Instructions.txt
retention-days: 30