Next Release Preview
Please make a pull request to describe any changes you wish to highlight in the next release of Spinnaker. These notes will be prepended to the release changelog.
Coming Soon in Release 2026.3.0
Breaking Changes
AWS V2 SDK migration
The caching agents and code have been moved to the AWS V2 SDK. Any V1 usage via plugins or similar will no longer work going forward.
GCE: Compute API beta to stable v1
Spinnaker PR #7510 migrates the Google provider from the Compute beta API to stable v1. Before upgrading, check saved GCE Deploy stages for the fields below.
partnerMetadata is no longer propagated
Stable Compute v1 instance template requests do not support the beta-only
partnerMetadata field. Clouddriver continues to accept saved deploy and clone
payloads that contain the field, but removes it before creating the instance
template and logs a warning. The pipeline can still run, but the partner
metadata is not applied.
Remove partnerMetadata from saved pipeline JSON. If an integration depends on
its namespaced structured data, consult that integration’s migration guidance;
there is no automatic conversion to a stable-v1 field.
Use Resource Manager tags when they match the use case
resourceManagerTags is not a drop-in replacement for partnerMetadata.
Resource Manager tags bind pre-created GCP tag keys and values to instances for
organization, policy, and access-control use cases. They do not carry arbitrary
partner-integration data.
For a tag key named environment under organization 123456789012, with a tag
value named production, use this deploy-stage field:
{
"resourceManagerTags": {
"123456789012/environment": "production"
}
}
GCP also accepts numeric resource names such as tagKeys/123456789 and
tagValues/987654321. The tag keys and values must exist before the pipeline
runs. See the
Compute v1 instance template resourceManagerTags contract
for accepted key and value formats.
Remove autoHealingPolicy.maxUnavailable
Stable Compute v1 MIG auto-healing policies support healthCheck and
initialDelaySec; they do not support maxUnavailable. Clouddriver rejects a
saved deploy stage containing any non-null maxUnavailable value, including an
empty object, rather than silently discarding a safety setting.
Before:
{
"autoHealingPolicy": {
"healthCheck": "example-health-check",
"healthCheckKind": "healthCheck",
"initialDelaySec": 300,
"maxUnavailable": {
"fixed": 2
}
}
}
After:
{
"autoHealingPolicy": {
"healthCheck": "example-health-check",
"healthCheckKind": "healthCheck",
"initialDelaySec": 300
}
}
In updated Deck, edit and save each affected GCE Deploy stage; Deck rebuilds
the command with supported fields and removes maxUnavailable. Pipelines
managed through the API or as custom JSON must remove the field explicitly.
Do not move this value to updatePolicy.maxUnavailable as a mechanical
migration. That setting controls rolling updates, not auto-healing repair
concurrency.
See the
stable v1 instance group manager contract
for the supported autoHealingPolicies fields.
Angular removed
Angular has been removed from the Spinnaker project. For any plugins or forks, please migrate to React. This is a substantial migration — a big thank you to the contributors, primarily Matt Gogerly.
SAML configuration has moved to Spring configuration
A few properties remain that enable parsing users and translating custom fields, but all content has moved to native Spring SAML configuration. Full migration docs are available .
For a minimal example:
saml:
enabled: true
user-attribute-mapping:
email: email
roles: memberOf
# This is defaulted and not required, but you MUST set the ACS URL below
login-processing-url: /saml/SSO
spring:
security:
saml2:
relyingparty:
registration:
SSO: # registration ID (arbitrary key, used in URLs, set here to SSO to mimic Spinnaker behavior)
acs:
# Keeps older login URLs for now.
location: "{baseUrl}/saml/SSO"
entity-id: spinnaker
assertingparty:
metadata-uri: https://idp.example.com/saml/metadata
singlesignon:
sign-request: true
signing:
credentials:
- private-key-location: /etc/gate/saml/private_key.pem
certificate-location: /etc/gate/saml/certificate.pem
Removals and Deprecations
Binaries & core utilities upgraded/removed
Upgrades/removal of old versions — many older libraries and SDKs have been upgraded and/or removed. Some of these (like Helmfile) do not receive as much testing as we’d like, so please verify if you use these libraries.
- Kustomize 5 is added. Kustomize 4 is updated to the latest supported version.
- Helmfile is upgraded to 1.7.0.
- Packer is upgraded to the latest release (1.14).
- kubectl binaries used for operations are updated to 1.30. Older versions are removed. You can select a newer version.
- aws-iam-authenticator binary is upgraded to the latest supported version.
- Base images are upgraded from Alpine 3.20 to 3.24. Ubuntu is moved to the latest release.
Native metric feeds to stackdriver will removed in 2026.4.0
Native feeds of spectator to stackdriver are deprecated and will be removed in 2026.4.0. Spectator as a whole hasn’t been supported in the project since the observability plugin and will be migrated to native spring metrics based (which uses micrometer) for metric handling.
Spectator to beremoved in 2027.0.0
There’s already work in progress to migrate from spectator to native spring metrics based upon micrometer. This will be fully removed in 2027.0.0
Old Kubernetes resource types removed
Very old API specs are removed . Specifically:
extensions/v1beta1networking.k8s.io/v1beta1
Associated libraries for Kubernetes are also upgraded to a currently supported release. This removes support for any resources using these types — please update your plugins as appropriate. These API versions were removed in Kubernetes 1.22.
Halyard removed
Halyard is removed from the codebase as of this release. For emergency fixes, PRs can be made to the 2026.2.x release branch. Halyard will no longer be released or actively supported, though it may continue to work as we will continue publishing BOMs for now. As of 2027.0.0, we will stop publishing Halyard BOMs.
Kustomize version 3 deprecated — will be removed in 2027.0.0
Kustomize V3 is deprecated. When using Kustomize in a pipeline, this is what’s referenced when you select KUSTOMIZE as the rendering type. Kustomize 5 is being added, and Kustomize 4 will continue to be supported. With 2027.0.0, Kustomize 3 will be removed. Please upgrade your pipelines to Kustomize 4 or 5 before that release.
SQL is the only supported storage for execution data — Redis will be removed in 2027.0.0
In Orca (the execution engine), we are deprecating support for any pipeline storage other than SQL. Please migrate your executions to SQL as soon as possible. Redis-based storage of pipeline execution state will be removed in 2027.0.0. Note: this only impacts storage of pipelines, not the queue system. It is recommended to stay on Redis for the queue system at this time.
Titus deprecated — will be removed in 2027.0.0
Given the lack of contributions, the Titus cloud provider will be removed in an upcoming release. It is marked deprecated as of this release.
SQL is the only supported storage for pipelines/templates — blob storage will be removed in 2027.0.0
Front50 currently supports S3/GCS/etc. storage for pipelines and templates. This will be removed in 2027.0.0. See the instructions on how Netflix migrated to move before that release. All non-SQL storage for Front50 is now marked deprecated.
Features
New stage to run multiple child pipelines from one call
There’s a new stage to invoke multiple child pipelines in a single stage vs creating multiple stages to invoke those child pipelines. Add this stage, and add the following config to invoke multiple child pipelines with this:
bundle_web:
appName1:
arguments:
app: app1
deploymentFrezeOverride: true
skipCanary: true
tag: 1.1.1
targetEnv: targetEnv
child_pipeline: childPipeline
appName2:
arguments:
app: app2
deploymentFrezeOverride: true
skipCanary: true
tag: 1.1.1
targetEnv: targetEnv
child_pipeline: childPipeline
depends_on:
- appName1
This will then call the appName1 pipeline “childPipeline” as well as the appName2 childPipeline AFTER the appName1 pipeleine completes. This enables you to invoke multiple pipelines with different arguments as needed to do a more dynamic invocation of child pipeline executions. For rollback on failure handling, YOU MUST create in that down stream application a pipeline named “rollbackOnFailure” to handle rollbacks.
Evaluate Artifacts stage
Evaluate Artifacts
— A new pipeline stage that evaluates SpEL expressions inside artifact contents and produces embedded/base64 artifacts. Each artifact is evaluated sequentially, so a later artifact can reference the evaluated value of an earlier one. This makes it easier to generate artifacts dynamically within a pipeline.
To use the stage, add one or more artifacts with a display name and contents. Contents may include any SpEL expression available in the pipeline context. The stage outputs the resulting artifacts so they can be consumed by downstream stages.
Configurable timeout on manifest stable checks
Kubernetes manifest stable time — Kubernetes deploys previously had a fixed 30-minute timeout before Deployments were considered “stable.” This timeout is now configurable via a pipeline parameter.
Multi-pipeline runner
Multi-pipeline runner — This plugin enables calling several child pipelines dynamically via a configuration block. For more information and configuration options, see the linked PR.
New scheduler system (Alpha)
Pub/Sub Cloud Account Scheduler — A new scheduler that processes requests for caching and agent operations in order. The current Redis scheduler is non-deterministic about when agents are processed, so users with large numbers of accounts may not get their data processed in a timely manner. This new scheduler exposes endpoints, stores agent state, and surfaces more detailed metrics on agent executions.
To try it out, disable the current Redis scheduler and enable this via:
spring:
data:
redis:
url: redis://valkey:6379
cats:
pubsub:
enabled: true
# Interval between state checks and re-queuing requests for additional processing.
delayBetweenSchedulerRunsMs: 15000
# When an agent is removed (e.g. account deletion), it is marked for deletion. This controls when it is actually removed. Time is in minutes. Defaults to 3 hours.
minutesBeforeDeletingMarkedForDeletion: 180
# If an agent hasn't been processed for some reason (e.g. lost in the queue), requeue it after this period.
minutesBeforeReQueueOfAgents: 20
# Strict concurrency limit on how many agents will run simultaneously. Similar to max-concurrent-agents in other schedulers.
maxConcurrentAgents: 100
# Max length of the Redis streams used for picking up agents to run. Set this large if you have many agents.
# Rough estimate: every AWS account adds ~15 agents per region. 100 accounts × 4 regions × 15 = 6,000 agents minimum.
# This defaults to 100,000. Note: this value directly affects Redis memory usage.
streamMaxLength: 100_000
This is an initial step toward using streams to request information rather than polling on a fixed cycle, and enables future alternative agent operation strategies.
Global banner for admins
Global banner — Admins can create and set banners visible across all Spinnaker applications for global notifications.
Spin CLI API token support
The new API token can be used with the Spin CLI. This is available in current main images.
UI support for adding/removing accounts
Admin-restricted. Adds a new UI panel to add and remove accounts with example payloads.
GitHub App authentication for git/repo and github/file artifacts
Clouddriver artifact accounts of type git/repo and github/file can now authenticate as a
GitHub App
instead of using a personal access token, username/password, or SSH key. Installation tokens are minted automatically, cached, and refreshed before they expire — no external token rotation is needed.
artifacts:
git-repo:
enabled: true
accounts:
- name: my-github-app-repo
githubApp:
appId: "123456"
# Plain path or an encrypted secret URI, e.g. encryptedFile:secrets-manager!r:us-west-2!s:gh-app-private-key
appPrivateKeyPath: /secrets/gh-app-key.pem
# optional - when omitted, the installation is derived from the repository being
# accessed, so one account can serve repositories across several organizations
appInstallationId: "789012"
# optional - when the installation is derived, restricts which repository owners
# this account may access. Omitting it allows any organization where the app is installed.
allowedOrganizations:
- my-org
- my-other-org
# apiBaseUrl: https://ghe.example.com/api/v3 # optional, for GitHub Enterprise
The same githubApp block is supported under artifacts.github.accounts. When present, GitHub App authentication takes precedence over the other auth methods on the account.
Installation tokens are cached per installation and refreshed shortly before they expire, so cached tokens are served without any GitHub API calls. When appInstallationId is omitted, the installation is resolved from the repository being accessed (organization- and user-owned repositories are both supported), which requires the app to be installed there with access to that repository; that resolution also happens only when a token is minted.
Because the repository is chosen by whoever defines the artifact, an account without appInstallationId can reach every organization where the app is installed. Set allowedOrganizations to restrict it to a known set of repository owners; a warning is logged at startup for accounts that derive installations without one. The list is matched case-insensitively and is ignored when appInstallationId pins a single installation.
Note that GitHub App clones use HTTPS (via x-access-token), so SSH-style repo URLs (git@...) are not supported with this auth method. For github/file accounts without a pinned appInstallationId, setting useContentAPI: true is recommended so that downloads are served by a single contents-API request that identifies the repository.
For plugin and fork authors: supporting this required a change to clouddriver’s shared artifact base class. BaseHttpArtifactCredentials.getHeaders(T account) now declares throws IOException, and a getHeaders(T account, HttpUrl url) overload was added for credentials whose auth material depends on the URL being fetched (it delegates to the URL-agnostic method by default). This is binary-compatible, but any out-of-tree subclass that overrides getHeaders and calls super.getHeaders(...) needs the same throws IOException on its signature to recompile. The GitHub App support itself lives in the new kork-github module, which clouddriver’s github/file and git/repo artifact modules now depend on.
Fixes
PostgreSQL compression issue
PostgreSQL compression failures — When using PostgreSQL with Orca database compression, failures occurred due to library upgrades. This is now fixed.
Large YAML support
Large YAMLs could fail to load — Following prior snakeyaml upgrades, some parts of Spinnaker did not allow customization of the maximum YAML size (for example, Helm repo indexes). These configurable limits are now universally applied.
Fixed a bug on account APIs
In certain edge cases, newly created accounts would not be read or updated across all pods after creation. This is now fixed.