-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathapply-updates-schedule.example.yml
More file actions
192 lines (184 loc) · 9.27 KB
/
Copy pathapply-updates-schedule.example.yml
File metadata and controls
192 lines (184 loc) · 9.27 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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# =====================================================================
# AzLocal.UpdateManagement - Apply-Updates ring schedule (schema v2)
# =====================================================================
#
# This is the single source of truth for "which UpdateRing(s) is/are
# eligible to apply updates on a given UTC date". It is consumed by:
#
# * apply-updates.yml - reads it at every cron firing and
# resolves the UpdateRingValue (and,
# schema v2+, the AllowedUpdateVersions
# allow-list) to use for that run.
# * apply-updates-schedule-audit.yml
# - audits this file against the live
# fleet (UpdateRing + UpdateStartWindow
# tags) and emits a two-way coverage
# delta.
#
# KEY CONCEPT - three independent layers control "what runs when":
#
# 1. This file (day-grain): the calendar week / day of week says
# WHICH UpdateRing tag values are eligible TODAY in UTC.
# 2. The apply-updates.yml cron schedule (intra-day-grain): says HOW
# OFTEN the apply-updates job wakes up (e.g. hourly).
# 3. Per-cluster `UpdateStartWindow` tag (minute-grain): says WHEN, during
# an eligible day, the actual update is allowed to start.
#
# A cron firing that lands on a day with NO matching schedule rows is
# logged and exits 0 - no errors, no failures.
#
# This file is REQUIRED for the "Fleet: 04 - Apply Updates"
# (apply-updates.yml) pipeline when triggered by a schedule (not
# workflow_dispatch). If the file is missing, apply-updates.yml throws
# with the exact remediation command.
#
# Generate a starter file from your current fleet via:
# New-AzLocalApplyUpdatesScheduleConfig -OutputPath .\config\apply-updates-schedule.yml
# =====================================================================
schemaVersion: 2
# ---- Cycle anchor --------------------------------------------------
# Every cron firing in UTC is mapped to a (cycleWeek, dayOfWeek) pair
# relative to this anchor. After `cycleWeeks` weeks the calendar loops
# back to cycleWeek=1.
#
# ISO reference: https://en.wikipedia.org/wiki/ISO_week_date
#
# Example anchor: ISO Week 1 of 2026 began on Monday,
# 29 December 2025 and ended on Sunday, 4 January 2026.
#
# Example cycle duration: with cycleWeeks = 8 the schedule repeats
# every 8 weeks (56 days). Once the cycle completes, the resolver
# wraps back to cycleWeek = 1.
#
# cycleAnchorISOWeek + cycleAnchorYear identify the ISO-8601 week that
# is "week 1" of the cycle. cycleWeeks tells the resolver when to wrap.
cycleWeeks: 8
cycleAnchorISOWeek: 1
cycleAnchorYear: 2026
# ---- AllowedUpdateVersions (schema v2, MANDATORY top-level) -------
# >>> ALLOWED-UPDATE-VERSIONS-V2 <<<
# Fleet-wide allow-list of Azure Local update identifiers that
# apply-updates.yml is permitted to install.
#
# Default 'Latest' (case-insensitive) is a reserved sentinel meaning
# 'no constraint - install the latest Ready update on each cluster'
# (the historic v0.7.88 default). Leave it as 'Latest' to keep that
# behaviour. When set to an explicit list, apply-updates.yml only
# installs updates whose `name` OR `properties.version` is an EXACT
# (case-insensitive) match for one of the entries. If a cluster has
# no Ready update that matches, that cluster is SKIPPED with status
# 'NotInAllowList' (strict no-op; never falls back to 'latest').
#
# Format: semicolon-separated string (same convention as 'rings:').
#
# WHICH STRING DO I PUT IN HERE? - You can use EITHER the full update
# `name` (recommended - this is the value the Azure portal Updates
# blade shows in the 'Name' column) OR the bare `properties.version`
# string. The matcher checks both columns and accepts either.
#
# Microsoft Solution updates - name: 'Solution12.2604.1003.1005'
# version: '12.2604.1003.1005'
# OEM SBE (Solution Builder - name: 'SBE5.0.2603.1522'
# Extension) updates version: '5.0.2603.1522'
#
# OEM SBE updates appear in the same Ready-update list as Microsoft
# Solution updates and are matched by exactly the same rule - the
# allow-list does NOT care whether the entry is a Solution or an SBE.
# To pin BOTH the Microsoft solution AND a specific vendor SBE for a
# given release, list both names in the same allowedUpdateVersions
# field (example below).
#
# Discover valid names per-cluster via:
# Get-AzLocalAvailableUpdates -ClusterName <name> -PassThru |
# Select-Object ClusterName, UpdateName, UpdateState
#
# Typical use - 'minimum updates' policy (~4 updates per year,
# customer ask in v0.7.89): install ONLY the YY04 + YY10 feature
# updates plus the cumulative updates immediately preceding each
# feature update (YY03 + YY09). With v2 schema you list those four
# update names here once and apply-updates.yml ignores every other
# 'Ready' update. Example using real Azure Local update names:
# allowedUpdateVersions: 'Solution12.2603.1002.15;Solution12.2604.1003.1005;Solution12.2609.1002.XX;Solution12.2610.1003.XX'
#
# Mixed Solution + OEM SBE example - allow the YY04 cumulative AND a
# specific vendor SBE that ships alongside it:
# allowedUpdateVersions: 'Solution12.2604.1003.1005;SBE5.0.2603.1522'
#
# Bare-version equivalent (no 'Solution' / 'SBE' prefix) - matches
# via properties.version instead of name:
# allowedUpdateVersions: '12.2604.1003.1005;5.0.2603.1522'
#
# Per-row override: any schedule row below may set its own
# `allowedUpdateVersions:` field. Per-row beats top-level; multiple
# matching rows UNION their lists; rows WITHOUT the field on a UNION
# day are treated as "no opinion" (not "allow nothing"). If any
# matching row contributes 'Latest', the effective allow-list is
# 'Latest' (no constraint).
#
# Reserved sentinel 'Latest' must appear alone (mixing 'Latest' with
# explicit versions in the same field is rejected by the validator).
allowedUpdateVersions: 'Latest'
# ---- Schedule entries ----------------------------------------------
# UNION semantics: if multiple rows match the current (cycleWeek, dow)
# tuple, the resolver concatenates their `rings` columns with ';' and
# passes the result to -UpdateRingValue. Wildcards: '*' on weeksInCycle
# or daysOfWeek means "every week" / "every day". Ranges (1-4) and
# comma lists (1,3,5) are both supported.
#
# Fields:
# weeksInCycle '*' | 'N' | 'N-M' | 'N,M,P,...' (1..cycleWeeks)
# daysOfWeek '*' | 'Mon' | 'Mon-Fri' | 'Tue,Thu' | 0-6 form
# (0=Sun, 1=Mon, ... 6=Sat)
# rings ';'-separated UpdateRing tag values, or '***' for
# every cluster carrying an UpdateRing tag (use with
# care - matches the Set/Start cmdlet semantics).
# notes Free text. Surfaced in audit reports and ITSM
# tickets. Recommended: change-control reference.
# allowedUpdateVersions OPTIONAL (schema v2). ';'-separated allow-list
# of update names or version strings, OR the reserved
# sentinel 'Latest' (= "no constraint - install latest
# Ready update"). When set on a row, it OVERRIDES the
# top-level allowedUpdateVersions for that (cycleWeek,
# dayOfWeek) match. Useful for per-ring policies
# (canary gets new cumulative immediately, prod ring
# waits for the feature update).
schedule:
- weeksInCycle: '1'
daysOfWeek: 'Mon-Fri'
rings: 'Canary'
notes: 'Phase 1 - canary ring soaks new build for a week'
- weeksInCycle: '2'
daysOfWeek: 'Mon-Fri'
rings: 'Canary;DevTest'
notes: 'Phase 2 - DevTest joins canary'
- weeksInCycle: '3-4'
daysOfWeek: 'Mon-Thu'
rings: 'Ring1;Ring2'
notes: 'Phase 3 - early production rings (excludes Fri so any incident has the weekend to recover)'
- weeksInCycle: '5-8'
daysOfWeek: 'Tue,Wed,Thu'
rings: 'Prod'
notes: 'Phase 4 - full production - mid-week only'
# Per-row override example: production ring is restricted to feature
# updates only - cumulative updates (YY03 / YY09) are installed on
# earlier rings, but Prod waits for the YY04 / YY10 feature drop.
# Comment this row override out (or omit it) to fall back to the
# top-level allowedUpdateVersions. Set the row to 'Latest' to
# explicitly opt this row out of any fleet-wide allow-list (the
# row will install the latest Ready update regardless of the
# top-level setting).
# allowedUpdateVersions: 'Solution12.2604.1003.1005;Solution12.2610.1003.XX'
#
# Mixed Solution + OEM SBE override (matches both the YY04
# cumulative AND a specific vendor SBE that ships alongside it):
# allowedUpdateVersions: 'Solution12.2604.1003.1005;SBE5.0.2603.1522'
# Example: ALWAYS-ON canary that runs every Monday throughout the
# whole 8-week cycle in addition to the phase-specific rows above.
# Demonstrates UNION semantics: in week 1 Monday, both this row and
# the 'Phase 1' row above match, so the resolver returns 'Canary'
# (deduplicated). In week 5 Tuesday only 'Phase 4' matches, so it
# returns 'Prod'.
- weeksInCycle: '*'
daysOfWeek: 'Mon'
rings: 'Canary'
notes: 'Permanent Monday canary sweep across the entire cycle'