Skip to content

feat: add istio-upgrade tool for AKS-managed mesh canary upgrades - #271

Merged
janboll merged 25 commits into
Azure:mainfrom
trevorwilliams2025:istio-upgrade-tool
Jul 27, 2026
Merged

feat: add istio-upgrade tool for AKS-managed mesh canary upgrades#271
janboll merged 25 commits into
Azure:mainfrom
trevorwilliams2025:istio-upgrade-tool

Conversation

@trevorwilliams2025

Copy link
Copy Markdown
Contributor

Summary

  • Lift the Istio upgrade engine out of ARO-HCP tooling/templatize into a shared tools/istio-upgrade module in ARO-Tools.
  • Provides a reusable CLI (istio run) and library API for AKS-managed Istio canary upgrades (decide → install/canary → migrate workloads → verify).
  • Lets ARO-HCP (and later sdp-pipelines) depend on one implementation instead of carrying a private copy under templatize.

Why

The upgrade logic is infrastructure tooling, not HCP-service code. Keeping it in ARO-HCP blocked reuse from other repos and duplicated ownership. Moving it to ARO-Tools so that it lives along other shared tools (cmdutils, grafanactl, etc.)

What’s included

  • ARM client for mesh profile / canary start+complete
  • Decision engine (install / upgrade / resume / cleanup / skip)
  • In-cluster ConfigMap, revision-tag webhooks, workload migration, health/verify
  • Unit tests for decide, upgrade, health, webhooks, workloads

Test plan

  • make -C tools/istio-upgrade test (or package tests) pass
  • Dry-run against a personal/dev SVC cluster: istio run ... --dry-run
  • Confirm ARO-HCP follow-up can import github.com/Azure/ARO-Tools/tools/istio-upgrade/...

Copilot AI review requested due to automatic review settings July 20, 2026 01:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a new shared tools/istio-upgrade Go module in ARO-Tools that encapsulates AKS-managed Istio canary upgrade orchestration (decisioning, ARM operations, in-cluster migration/restarts, health/verification), intended for reuse by ARO-HCP and other repos.

Changes:

  • Adds an AKS service-mesh upgrade engine (pkg/istio) covering decision logic, ARM client operations, revision-tag webhook management, workload migration/restarts, rollout waiting, health checks, and post-upgrade verification.
  • Adds a Cobra command tree (istio run) wiring options → clients → RunUpgrade (but currently no binary entry point).
  • Adds extensive unit tests for decisioning, webhooks, workloads/restarts, health/verify, and upgrade flows.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tools/istio-upgrade/pkg/istio/workloads.go Namespace label/tag flipping, stale-sidecar detection, workload restarts, rollout waiting, ingress annotation helpers.
tools/istio-upgrade/pkg/istio/workloads_test.go Unit tests for namespace selection/labeling, ingress status/annotations, restart logic, and rollout waiting.
tools/istio-upgrade/pkg/istio/webhooks.go Revision-tag webhook creation/update logic (istioctl tag-set equivalent behavior).
tools/istio-upgrade/pkg/istio/webhooks_test.go Unit tests covering tag webhook create/update/no-op and failure conditions.
tools/istio-upgrade/pkg/istio/upgrade.go Primary upgrade orchestration state machine and safety/rollback handling.
tools/istio-upgrade/pkg/istio/upgrade_test.go End-to-end-ish unit tests for install/upgrade/resume/cleanup/rollback/verification flows using fakes/reactors.
tools/istio-upgrade/pkg/istio/mesh-config.yaml Embedded mesh ConfigMap payload used per revision.
tools/istio-upgrade/pkg/istio/inspect.go Mesh state inspection logging used during upgrades for observability.
tools/istio-upgrade/pkg/istio/health.go Health check + upgrade verification + orphaned workload detection helpers.
tools/istio-upgrade/pkg/istio/health_test.go Unit tests for health/verify/orphan detection and helper behaviors.
tools/istio-upgrade/pkg/istio/decide.go Decision engine to choose install/upgrade/resume/cleanup/skip actions.
tools/istio-upgrade/pkg/istio/decide_test.go Unit tests validating decision outcomes and revision comparison.
tools/istio-upgrade/pkg/istio/configmap.go Kube client creation + revision ConfigMap create/update/delete (with embedded mesh config).
tools/istio-upgrade/pkg/istio/aks.go ARM client wrapper for mesh profile enable/start/complete + provisioning polling.
tools/istio-upgrade/cmd/run/options.go CLI flag binding/validation and conversion into UpgradeOptions.
tools/istio-upgrade/cmd/run/cmd.go run subcommand wiring options to AKS/K8s clients and RunUpgrade.
tools/istio-upgrade/cmd/cmd.go Root Cobra command (istio) and subcommand registration.
tools/istio-upgrade/Makefile Build/test targets for the new module.
tools/istio-upgrade/go.mod New module definition + dependencies.
tools/istio-upgrade/go.sum Dependency checksums for the new module.
tools/istio-upgrade/.gitignore Ignores local build outputs.
go.work Adds ./tools/istio-upgrade to the workspace.
go.work.sum Workspace dependency checksum updates.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tools/istio-upgrade/Makefile
Comment thread tools/istio-upgrade/pkg/istio/webhooks.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/workloads.go
Comment thread tools/istio-upgrade/pkg/istio/workloads.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/workloads.go Outdated
Copilot AI review requested due to automatic review settings July 20, 2026 03:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated 3 comments.

Comment thread tools/istio-upgrade/pkg/istio/workloads.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/workloads.go
Comment thread tools/istio-upgrade/pkg/istio/health.go
Copilot AI review requested due to automatic review settings July 20, 2026 03:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated 2 comments.

Comment thread tools/istio-upgrade/pkg/istio/workloads.go
Comment thread tools/istio-upgrade/pkg/istio/mesh-config.yaml

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 20, 2026 09:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 22 out of 23 changed files in this pull request and generated no new comments.

Comment thread tools/istio-upgrade/cmd/run/cmd.go
Comment thread tools/istio-upgrade/cmd/run/cmd.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/decide.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/decide.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/decide.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/upgrade.go
Comment thread tools/istio-upgrade/pkg/istio/workloads.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/health.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/configmap.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/workloads.go Outdated
Copilot AI review requested due to automatic review settings July 21, 2026 06:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 24 changed files in this pull request and generated 6 comments.

Comment thread tools/istio-upgrade/pkg/istio/decide_test.go
Comment thread tools/istio-upgrade/pkg/istio/workloads_test.go
Comment thread tools/istio-upgrade/pkg/istio/workloads_test.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/workloads_test.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/webhooks_test.go
Comment thread tools/istio-upgrade/pkg/istio/health_test.go Outdated
Copilot AI review requested due to automatic review settings July 21, 2026 06:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 24 changed files in this pull request and generated 4 comments.

Comment thread tools/istio-upgrade/pkg/istio/kubeclient.go
Comment thread tools/istio-upgrade/pkg/istio/kubeclient.go
Comment thread tools/istio-upgrade/pkg/istio/kubeclient.go Outdated
Comment thread tools/istio-upgrade/pkg/istio/upgrade.go
Copilot AI review requested due to automatic review settings July 21, 2026 06:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 24 changed files in this pull request and generated 1 comment.

Comment thread tools/istio-upgrade/pkg/istio/health.go
Copilot AI review requested due to automatic review settings July 21, 2026 07:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 34 out of 46 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 21, 2026 08:16
Adds Step N/M markers to all orchestration functions so pipeline logs
are self-documenting. runCanaryPostInstall shows Steps 1-9/9,
runCleanupAndUpgrade shows Phases 1-3/3, runInitialInstall shows
Steps 1-4/4. An operator reading failure logs can immediately see
which step failed and where in the sequence they are.
The Step N/M markers are now in logger.Info calls (Task 3). The inline
comments that previously carried step numbers now describe what the
step does without numbering — the logger line is the canonical source
for step sequence.
The scenarioNotReady case covered both "cluster provisioning failed" and
"ARM upgrading to a different revision." These have different operational
implications. The ARM-busy case now logs with configTarget and installed
revisions so the operator immediately sees the mismatch without needing
to correlate with cluster state.
Adds testClusterBuilder to reduce test setup boilerplate from 80-120
lines to 5-10 lines per test. Builder handles system namespaces,
istiod deployments, gateway objects, webhooks, and AKS error injection.

Migrates 4 tests as proof of concept. Remaining tests can be migrated
incrementally — the builder and manual setup coexist.
The function was renamed from runActionSkip to runReconcile in the
ActionReconcile split, but three error log messages still said
"on skip." Updated to "on reconcile" for consistency.
…and upgrade tests

Add error injection and edge-case tests to bring five key functions to
100% statement coverage: CreateRevisionConfigMap, VerifyUpgrade,
CheckOrphanedWorkloads, migrateWorkloads, and runReconcile. Also adds
stableRevisionFrom reverse-order tests and HealthCheck error path tests.
Overall package coverage 75.5% → 79.2%.
Copilot AI review requested due to automatic review settings July 23, 2026 02:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 47 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

tools/istio-upgrade/pkg/istio/mesh-config.yaml:5

  • envoyExtAuthzHttp.service should be a DNS name (typically <svc>.<ns>.svc.cluster.local) so Envoy/Istio can resolve it. The current value contains a / (mise/mise.mise.svc.cluster.local), which is not a valid service DNS name and will likely break ext-authz resolution. Also, port is expected to be numeric; quoting it makes it a string in YAML.
  envoyExtAuthzHttp:
    service: "mise/mise.mise.svc.cluster.local"
    port: "8080"

Copilot AI review requested due to automatic review settings July 24, 2026 00:59

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 47 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

tools/istio-upgrade/pkg/istio/mesh-config.yaml:5

  • The service value contains a / ("mise/mise.mise.svc.cluster.local"), which is not a valid DNS hostname for Envoy ext-authz. This will likely make the mesh ConfigMap invalid or cause the extension provider to fail to resolve the backend service.
  envoyExtAuthzHttp:
    service: "mise/mise.mise.svc.cluster.local"
    port: "8080"

Copilot AI review requested due to automatic review settings July 24, 2026 02:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 47 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (2)

tools/istio-upgrade/pkg/istio/workloads.go:131

  • GetIngressGatewayStatus only populates ExternalIP from LoadBalancer.Ingress[0].IP. For some AKS load balancers, the ingress address may be provided via Hostname instead of IP, which will incorrectly mark gateways unhealthy in HealthCheck/Verify flows.
    tools/istio-upgrade/Makefile:11
  • The PR description/test plan mention a reusable CLI (e.g. istio run ...), but this module currently has no package main entrypoint and the Makefile explicitly states there’s no main.go. As-is, go build ./... will not produce an istio binary, so consumers can’t actually run istio run without adding their own main wrapper.
# Build all packages (no main.go — binary entry point is in sdp-pipelines)
build: $(SOURCES)
	go build ./...

- name: "ext-authz"
envoyExtAuthzHttp:
service: "mise/mise.mise.svc.cluster.local"
port: "8080"
Comment on lines +3 to +7
envoyExtAuthzHttp:
service: "mise/mise.mise.svc.cluster.local"
port: "8080"
includeRequestHeadersInCheck: ["x-ext-authz", "mise-inbound-policies-to-filter"]
pathPrefix: "/v1/EnvoyValidateRequest"
Copilot AI review requested due to automatic review settings July 27, 2026 08:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 47 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

tools/istio-upgrade/pkg/istio/workloads.go:240

  • The goroutine in this loop closes over the range variables i and ns. Because those variables are reused across iterations, concurrent goroutines can write to the wrong outcomes index / use the wrong namespace, and can also race by all writing the final i value. Capture per-iteration copies before starting the goroutine (or pass them as parameters).
    tools/istio-upgrade/pkg/istio/workloads.go:477
  • Same closure-capture issue as in ExecuteRestartAllNamespaces: the goroutine closes over i and ns, so errs[i] may be written to the wrong slot (often the final i) and the wrong namespace may be checked. Capture iteration-local copies before spawning the goroutine.
    tools/istio-upgrade/pkg/istio/mesh-config.yaml:5
  • The envoyExtAuthzHttp.service value contains a / and the port is quoted. In Istio mesh config this service is expected to be a resolvable DNS name (no /), and port is a numeric field. As written, AKS/Istio may reject the mesh config or Envoy may fail to resolve the ext-authz destination.
    service: "mise/mise.mise.svc.cluster.local"
    port: "8080"

Copilot AI review requested due to automatic review settings July 27, 2026 11:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 35 out of 47 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

tools/istio-upgrade/pkg/istio/mesh-config.yaml:7

  • The embedded mesh config looks malformed for an Istio meshConfig: service includes a slash (mise/mise...) and port is quoted as a string. This is likely to be rejected by Istio/AKS mesh config parsing and could break installs/upgrades that create the revision ConfigMap.
extensionProviders:
- name: "ext-authz"
  envoyExtAuthzHttp:
    service: "mise/mise.mise.svc.cluster.local"
    port: "8080"
    includeRequestHeadersInCheck: ["x-ext-authz", "mise-inbound-policies-to-filter"]
    pathPrefix: "/v1/EnvoyValidateRequest"

Comment on lines +31 to +46
//go:embed mesh-config.yaml
var meshConfig string

func revisionConfigMapName(revision string) string {
return fmt.Sprintf("istio-shared-configmap-%s", revision)
}

func istiodServiceName(revision string) string {
return fmt.Sprintf("istiod-%s", revision)
}

// https://learn.microsoft.com/en-us/azure/aks/istio-meshconfig#set-up-configuration-on-cluster
func CreateRevisionConfigMap(ctx context.Context, kubeClient *KubeClient, revision string) error {
logger := logr.FromContextOrDiscard(ctx).WithName("revision-configmap")
cmName := revisionConfigMapName(revision)
meshData := strings.TrimSpace(meshConfig)
Comment on lines +88 to +96
if o.Versions == "" {
return nil, fmt.Errorf("--versions is required")
}
if !istio.RevisionPattern.MatchString(o.Versions) {
return nil, fmt.Errorf("invalid --versions %q: must match %s", o.Versions, istio.RevisionPattern.String())
}
if (o.IngressIPName == "") != (o.RegionRG == "") {
return nil, fmt.Errorf("--ingress-ip-name and --region-rg must both be set or both be empty (got ingress-ip-name=%q, region-rg=%q)", o.IngressIPName, o.RegionRG)
}
@janboll
janboll enabled auto-merge (squash) July 27, 2026 12:19
@janboll
janboll merged commit 6ea2301 into Azure:main Jul 27, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants