-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathauthentication-test.yml
More file actions
175 lines (162 loc) · 9.6 KB
/
Copy pathauthentication-test.yml
File metadata and controls
175 lines (162 loc) · 9.6 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
168
169
170
171
172
173
174
# AZLOCAL-PIPELINE-ID: authentication-test
# Step.00 - Authentication Validation and Subscription Scope Report
#
# PURPOSE:
# Validates that the service connection (Workload Identity Federation), App Registration,
# and RBAC role assignments all line up, AND produces a Subscription Scope report that
# lists every subscription the pipeline identity can see. Run this:
# - BEFORE importing the seven real pipelines (inventory, tags, readiness, apply,
# status, fleet-status, fleet-health). It narrows any failure to one small pipeline
# rather than seven interacting pipelines.
# - PERIODICALLY (recommended monthly, or after every RBAC change in the tenant) to
# confirm the pipeline identity's subscription scope has not silently widened or
# narrowed - new subscriptions get onboarded, MG-level role assignments inherit,
# leavers / re-orgs change tenant scope. A drift in this report is the earliest
# signal that downstream fleet reports are about to under- or over-count clusters.
#
# WHAT THIS PIPELINE PROBES:
# 1. AzureCLI@2 task auth against the service connection (Workload Identity
# Federation auto-managed by ADO).
# 2. Service-connection -> App Registration -> subscription wiring.
# 3. Azure RBAC on the App Registration's service principal.
# 4. Resource Graph reachability (proves the SP can actually see clusters).
# 5. Subscription scope: total count and full Subscription ID / Name table
# visible to the pipeline identity.
#
# Unlike the GitHub Actions twin (authentication-test.yml in github-actions/), ADO
# does not expose env-scoped federated credentials at the auth layer - the service
# connection IS the federation. So this pipeline only validates one auth path. Environment
# approval gates (Pipelines -> Environments) are a separate concern and are not exercised
# here.
#
# REPORTS GENERATED:
# - JUnit XML published via PublishTestResults@2 (renders in the ADO Tests tab).
# - Markdown summary uploaded via ##vso[task.uploadsummary] (renders in the run Summary tab).
# - Pipeline artifact (auth-report) containing JUnit XML + subscriptions.json + .csv.
#
# HOW TO RUN (after the file is committed and the pipeline is imported):
# Pipelines -> Step.00 - Authentication Validation and Subscription Scope Report -> Run pipeline.
#
# See Automation-Pipeline-Examples/README.md, section 5.2, for the full setup story.
name: Step.00 - Authentication Validation and Subscription Scope Report
# BEGIN-AZLOCAL-CUSTOMIZE:schedule-triggers
# Add or modify `schedules:` blocks here to enable cron-driven runs. Content
# between BEGIN/END markers is preserved by Update-AzLocalPipelineExample
# across module upgrades.
trigger: none
# END-AZLOCAL-CUSTOMIZE:schedule-triggers
parameters:
- name: moduleVersion
displayName: 'Pin AzLocal.UpdateManagement version (empty = latest from PSGallery). See Automation-Pipeline-Examples/README.md section 5 "Optional configuration".'
type: string
default: ''
variables:
# Module version this YAML was generated against. The install step compares this to
# the version actually installed and to the latest on PSGallery, and emits a warning
# log if the YAML appears stale - prompting you to refresh via
# Copy-AzLocalPipelineExample -Update. See Automation-Pipeline-Examples/README.md section 5.
- name: GENERATED_AGAINST_MODULE_VERSION
value: '0.8.76'
# Resolution order for the module version pin (leave all unset to install the latest,
# which is the default "fix-forward" behaviour): queue-time parameter > pipeline variable
# 'REQUIRED_MODULE_VERSION' overridden at queue time > empty (latest).
- name: REQUIRED_MODULE_VERSION
value: '${{ parameters.moduleVersion }}'
# No further parameters - this pipeline is deliberately fixed: one service connection,
# one identity, four probes. If the service connection name does not match your
# environment, update `azureSubscription` below.
pool:
vmImage: 'windows-latest'
stages:
- stage: Validate
displayName: 'Validate Workload Identity Federation + RBAC + Subscription Scope'
jobs:
- job: ValidateAuthAndScope
displayName: 'Run auth, RBAC, and Subscription Scope probes'
steps:
- task: PowerShell@2
displayName: 'Install AzLocal.UpdateManagement from PSGallery'
# Step.0 itself relies on the module (Export-AzLocalAuthValidationReport
# runs the four auth/RBAC/ARG probes); installing here also gives
# operators an early, consistent drift signal *before* the rest of
# the seven pipelines run. If the banner reports the YAML is stale
# or the installed module is older than expected, refresh the
# YAMLs via Copy-AzLocalPipelineExample -Platform AzureDevOps -Update
# and re-run.
# v0.8.5 thin-YAML: drift detection + banner + step outputs are all
# produced by Add-AzLocalPipelineVersionBanner (Public cmdlet).
env:
REQUIRED_MODULE_VERSION: $(REQUIRED_MODULE_VERSION)
GENERATED_AGAINST_MODULE_VERSION: $(GENERATED_AGAINST_MODULE_VERSION)
inputs:
targetType: 'inline'
pwsh: true
script: |
$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
$banner = Add-AzLocalPipelineVersionBanner `
-GeneratedAgainstVersion $env:GENERATED_AGAINST_MODULE_VERSION `
-PinnedVersion $env:REQUIRED_MODULE_VERSION `
-PassThru
# Forward to ADO job-scoped variables so the report step (below) can
# surface the three versions in its JUnit + markdown summary.
$latestStr = if ($banner.LatestOnPSGallery) { $banner.LatestOnPSGallery } else { '' }
Write-Host "##vso[task.setvariable variable=installedModuleVersion;isOutput=false]$($banner.InstalledVersion)"
Write-Host "##vso[task.setvariable variable=generatedAgainstVersion;isOutput=false]$($banner.GeneratedAgainstVersion)"
Write-Host "##vso[task.setvariable variable=latestOnPsGallery;isOutput=false]$latestStr"
- task: AzureCLI@2
displayName: 'Collect Authentication and Subscription Scope Report'
inputs:
azureSubscription: 'AzureLocal-ServiceConnection' # Update if your service connection has a different name.
scriptType: 'pscore'
scriptLocation: 'inlineScript'
# v0.8.5 thin-YAML: the ~200-line inline run block (az probes,
# XML scaffolding, markdown summary, ##vso writes) has been
# condensed into the Public cmdlet Export-AzLocalAuthValidationReport.
# The cmdlet performs all four probes (az account show / role
# assignment list / az account list / Resource Graph query),
# writes the JUnit XML + subscriptions.json + subscriptions.csv,
# uploads the markdown summary via ##vso[task.uploadsummary],
# and emits the three pipeline variables (subscription_count,
# cluster_count, auth_valid) via Set-AzLocalPipelineOutput.
inlineScript: |
$ErrorActionPreference = 'Stop'
Import-Module AzLocal.UpdateManagement -Force
$reportDir = Join-Path $env:BUILD_ARTIFACTSTAGINGDIRECTORY 'auth-report'
Export-AzLocalAuthValidationReport `
-ReportDirectory $reportDir `
-InstalledModuleVersion "$(installedModuleVersion)" `
-GeneratedAgainstVersion "$(generatedAgainstVersion)" `
-LatestOnPSGallery "$(latestOnPsGallery)"
- task: PublishTestResults@2
displayName: 'Publish Authentication Validation JUnit Diagnostics'
condition: always()
inputs:
testResultsFormat: 'JUnit'
testResultsFiles: '$(Build.ArtifactStagingDirectory)/auth-report/auth-report.xml'
testRunTitle: '[JUnit Debug] Authentication Validation and Subscription Scope'
failTaskOnFailedTests: false
mergeTestResults: false
# artifact convention: compute a UTC timestamp variable so every downloadable artifact name is unique per run.
- pwsh: |
$stamp = (Get-Date).ToUniversalTime().ToString('yyyyMMdd_HHmmss')
Write-Host "##vso[task.setvariable variable=artifactStamp;isOutput=true]$stamp"
Write-Host "Artifact timestamp: $stamp"
displayName: 'Compute Artifact Timestamp'
condition: always()
name: stamp
- task: PublishPipelineArtifact@1
displayName: 'Publish auth-report artifact'
condition: always()
inputs:
targetPath: '$(Build.ArtifactStagingDirectory)/auth-report'
artifact: 'azlocal-step.0-auth-report_$(stamp.artifactStamp)'
publishLocation: 'pipeline'