---
title: v1.0.0
weight: 999000000
---

This is the first major version release of `operator-sdk`, which comes with a project structure rewrite
and many breaking CLI changes that are incompatible with all prior minor versions (except for Go projects,
which changed in [v0.19.0][go-mig-guide-v0-19]).

Each project type has an appropriate migration guide, which we recommend following before reading
this guide:
- [Go][go-mig-guide]
- [Ansible][ansible-mig-guide]
- [Helm][helm-mig-guide]

### CLI changes

The following subcommands were removed:

| Command                       | Guidance                                                                                                 | PR(s)
|-------------------------------|----------------------------------------------------------------------------------------------------------|-------
| `operator-sdk new`            | Use `operator-sdk init`                                                                                  | [#3385](https://github.com/operator-framework/operator-sdk/pull/3385), [#3343](https://github.com/operator-framework/operator-sdk/pull/3343), [#3531](https://github.com/operator-framework/operator-sdk/pull/3531)
| `operator-sdk add api`        | Use `operator-sdk create api`                                                                            | [#3385](https://github.com/operator-framework/operator-sdk/pull/3385), [#3343](https://github.com/operator-framework/operator-sdk/pull/3343), [#3531](https://github.com/operator-framework/operator-sdk/pull/3531)
| `operator-sdk add controller` | Use `operator-sdk create api`                                                                            | [#3385](https://github.com/operator-framework/operator-sdk/pull/3385)
| `operator-sdk add crd`        | Use `operator-sdk create api`                                                                            | [#3547](https://github.com/operator-framework/operator-sdk/pull/3547)
| `operator-sdk build`          | Use `make docker-build`                                                                                  | [#3566](https://github.com/operator-framework/operator-sdk/pull/3566)
| `operator-sdk bundle create`  | Use `make bundle`                                                                                        | [#3414](https://github.com/operator-framework/operator-sdk/pull/3414)
| `operator-sdk generate k8s`   | Use `make generate`                                                                                      | [#3385](https://github.com/operator-framework/operator-sdk/pull/3385)
| `operator-sdk generate crds`  | Use `make manifests`                                                                                     | [#3385](https://github.com/operator-framework/operator-sdk/pull/3385)
| `operator-sdk generate csv`   | Use `operator-sdk generate kustomize manifests`                                                          | [#3414](https://github.com/operator-framework/operator-sdk/pull/3414)
| `operator-sdk migrate`        | Removed support for hybrid operators, no migration                                                       | [#3385](https://github.com/operator-framework/operator-sdk/pull/3385)
| `operator-sdk print-deps`     | Removed, no migration                                                                                    | [#3385](https://github.com/operator-framework/operator-sdk/pull/3385)
| `operator-sdk run local`      | Use `make run`                                                                                           | [#3406](https://github.com/operator-framework/operator-sdk/pull/3406)
| `operator-sdk test`           | Use controller-runtime's [envtest](https://book.kubebuilder.io/reference/envtest.html) framework          | [#3409](https://github.com/operator-framework/operator-sdk/pull/3409)

### Library changes

Subpackages of the `pkg/` directory have either been removed or moved from the `operator-sdk` repo
to the [`operator-lib` repo][operator-lib].

Removed packages:
- [`pkg/k8sutil`](#removed-package-pkgk8sutil)
- [`pkg/kube-metrics`](#removed-packages-pkgkube-metrics-and-pkgmetrics)
- [`pkg/metrics`](#removed-packages-pkgkube-metrics-and-pkgmetrics)
- [`pkg/ready`](#removed-package-pkgready)
- [`pkg/tls`](#removed-package-pkgtls)

Packages that have been moved can be used by making the following changes:
- The `EnqueueRequestForAnnotation` watch handler is now available in package `github.com/operator-framework/operator-lib/handler`
- The `GenerationChangedPredicate` was refactored and moved. Rewrite it as a composite predicate like the following:

    ```go
    import (
      crpredicate "sigs.k8s.io/controller-runtime/pkg/predicate"
      libpredicate "github.com/operator-framework/operator-lib/predicate"
    )

    ...

    crpredicate.Or(
      crpredicate.GenerationChangedPredicate{},
      libpredicate.NoGenerationPredicate{},
    )
    ```
- The leader-for-life leader election library at `pkg/leader` was moved to `github.com/operator-framework/operator-lib/leader`.
- The `pkg/status` library with status conditions helpers was moved to `github.com/operator-framework/operator-lib/status`.

See the following PRs for details:
- [#3506](https://github.com/operator-framework/operator-sdk/pull/3506)
- [#3532](https://github.com/operator-framework/operator-sdk/pull/3532)
- [#3503](https://github.com/operator-framework/operator-sdk/pull/3503)

[go-mig-guide-v0-19]:/docs/upgrading-sdk-version/v0.19.0#migrating-go-projects-to-the-new-kubebuilder-aligned-project-layout
[go-mig-guide]:/docs/building-operators/golang/migration
[ansible-mig-guide]:/docs/building-operators/ansible/migration
[helm-mig-guide]:/docs/building-operators/helm/migration
[operator-lib]:https://github.com/operator-framework/operator-lib

### Upgrade your project from version "2" to "3-alpha"

The SDK's default Go plugin no longer supports OLM- or scorecard-related project files
nor writes a `plugins` PROJECT field for projects scaffolded previously with `operator-sdk init --project-version=2`,
Please migrate to project version "3-alpha" for support of these features by adding the following to your `PROJECT` file:
```yaml
version: "3-alpha" # Updated from "2"
projectName: <output of "$(basename $(pwd))">
layout: go.kubebuilder.io/v2
plugins:
  go.sdk.operatorframework.io/v2-alpha: {}
```

_See [#3438](https://github.com/operator-framework/operator-sdk/pull/3438) and [#3697](https://github.com/operator-framework/operator-sdk/pull/3697) for more details._

### Add the samples scaffold marker to your `config/samples/kustomization.yaml`

Add the `+kubebuilder:scaffold:manifestskustomizesamples` to your `config/samples/kustomization.yaml` file like so (using an example sample file):
```yaml
resources:
- cache_v1alpha1_memcached.yaml
#+kubebuilder:scaffold:manifestskustomizesamples
```

_See [#3645](https://github.com/operator-framework/operator-sdk/pull/3645) for more details._

### Update your Makefile's `bundle` recipe to inject an operator image tag.

Make the following update to your Makefile's `bundle` recipe, which will allow you to set `make bundle IMG=<tag>`:
```make
bundle:
  ...
  operator-sdk generate kustomize manifests -q
  cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) # Add this line
  ...
```

_See [#3634](https://github.com/operator-framework/operator-sdk/pull/3634) for more details._

### Update usage of `operator-sdk cleanup`

The `operator-sdk cleanup packagemanifests` command has been
removed and replaced with a simpler `operator-sdk cleanup`
command.

Update usages of `operator-sdk cleanup packagemanifests` to
use `operator-sdk cleanup <packageName>`.

The value for `<packageName>` can be found in the `*.package.yaml`
file in the root of your packagemanifests folder. It is typically
your project name.

_See [#3644](https://github.com/operator-framework/operator-sdk/pull/3644) for more details._

### Remove `olm-namespace` flag from `operator-sdk olm install` command

The `olm-namespace` flag has been removed from `operator-sdk olm install`
command, as the olm manifests published in github have a hardcoded
namespace value. Hence, the olm operators can only be installed in `olm`
namespace using this command.

_See [#3670](https://github.com/operator-framework/operator-sdk/pull/3670) for more details._

### Docker images for `s390x` are no longer created automatically

If you require an `s390x` image for a particular release, please open an issue in the operator-sdk GitHub project, and the maintainers will manually build and push an s390x image for supported versions

_See [#3710](https://github.com/operator-framework/operator-sdk/pull/3710) for more details._

### Default install mode for `run packagemanifests` changed from `OwnNamespace` to `AllNamespaces`

By default all operators are scaffolded to run at the cluster scope and watch all namespaces.
However, if you are relying on the default behavior of the `run packagemanifests` command to use the default `OwnNamespace` install mode, you must now specify it explicitly with `--install-mode=OwnNamespace`.

_See [#3663](https://github.com/operator-framework/operator-sdk/pull/3663) for more details._

### Use new logging flags when running the Ansible and Helm operators

The Ansible and Helm operators now use controller-runtime's zap package
to define logging flags.

The `--zap-sample` and `--zap-time-encoding` flag have been removed since
they are not present in controller-runtime's flagset. These flags are no
longer supported.

The `--zap-level` flag is called `--zap-log-level` now. Rename any usage of
`--zap-level` to `--zap-log-level`

_See [#3596](https://github.com/operator-framework/operator-sdk/pull/3596) for more details._

### Core Ansible and Helm operator logic moved to `<ansible-operator|helm-operator> run` subcommand

If you are using the `ansible-operator` and `helm-operator` binaries
directly, update your usage to call `ansible-operator run` and
`helm-operator run` (e.g. in your Makefile's `make run` target).

If you are using the base image and you are not overriding the operator
entrypoint, no change is necessary because the base image has been updated
to call the `run` subcommand by default.

_See [#3596](https://github.com/operator-framework/operator-sdk/pull/3596) for more details._

### Rename `--update-crds` flag to `--update-objects` in `generate packagemanifests` invocations

This flag has been renamed to account for all objects that can be written to the package directory, ex. Roles.

_See [#3610](https://github.com/operator-framework/operator-sdk/pull/3610) for more details._

### Update scorecard API Go import paths

The scorecard v1alpha3 API has been moved to a separate repo. Update your Go import paths:

Old:
```go
import "github.com/operator-framework/operator-framework/pkg/apis/scorecard/v1alpha3"
```

New:
```go
import "github.com/operator-framework/api/pkg/apis/scorecard/v1alpha3"
```

_See [#3622](https://github.com/operator-framework/operator-sdk/pull/3622) for more details._

### Package `version` is no longer public

It is no longer possible to import package `version`. To
determine the version of operator-sdk, run `operator-sdk version`.

_See [#3617](https://github.com/operator-framework/operator-sdk/pull/3617) for more details._

### Remove `--operator-name` from scripts

The `--operator-name` flag has been removed from `generate bundle` and `generate packagemanifests` subcommands. Remove this flag from your scripts, and make sure the `projectName` key is set in your PROJECT file. If this key is not set, the current working directory's base name will be used.

_See [#3530](https://github.com/operator-framework/operator-sdk/pull/3530) for more details._

### Create resources manually that were passed to `run packagemanifests --include-paths`

The `run packagemanifests` subcommand no longer has the `--include-paths` flag to create additional resources. Instead, use `kubectl apply -f <paths>` before invoking `run packagemanifests`.

_See [#3599](https://github.com/operator-framework/operator-sdk/pull/3599) for more details._

### Change the `run packagemanifests` flag `--operator-version` to `--version`

`--operator-version` is now `--version`.

_See [#3599](https://github.com/operator-framework/operator-sdk/pull/3599) for more details._

### Remove `--olm-namespace` from `run packagemanifests` invocations

OLM namespace is no longer required by this command.

_See [#3601](https://github.com/operator-framework/operator-sdk/pull/3601) for more details._

### Change the `run packagemanifests` flag `--operator-namespace` to `--namespace`

`--operator-namespace` is now `--namespace`.

_See [#3601](https://github.com/operator-framework/operator-sdk/pull/3601) for more details._

### `pkg/log/zap` is no longer a public API

Migrate to the upstream controller-runtime implementation in [sigs.k8s.io/controller-runtime/pkg/log/zap](https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.6.1/pkg/log/zap?tab=doc#Options.BindFlags).

_See [#3525](https://github.com/operator-framework/operator-sdk/pull/3525) for more details._

### Default Ansible and Helm operator metrics port has changed

To continue using port 8383, specify `--metrics-bind-address=:8383` when you start the operator.

_See [#3489](https://github.com/operator-framework/operator-sdk/pull/3489) and [#3440](https://github.com/operator-framework/operator-sdk/pull/3440) for more details._

### Update references to legacy operator-sdk domain strings

Update various usages of domains in plugin keys and annotations:

  * In Kubebuilder-style projects, change the `.operator-sdk.io` suffix to `.sdk.operatorframework.io` in the `PROJECT` file.

  * In Ansible and Helm projects, change legacy annotation keys to new annotation keys in sample CR files in your repository.

  * In live clusters containing CRs for Ansible and Helm-based operators:
    1. Patch all existing CRs that use a legacy annotation to ADD the new equivalent annotations alongside the legacy annotations.
    2. Upgrade the operator
    3. Patch all existing CRs that used a legacy annotation to REMOVE the legacy annotations.

| Location         | Legacy                                      | New                                                     |
|------------------|---------------------------------------------|---------------------------------------------------------|
| `PROJECT` file   | `go.operator-sdk.io`                        | `go.sdk.operatorframework.io`                           |
| Custom resources | `ansible.operator-sdk/reconcile-period`     | `ansible.sdk.operatorframework.io/reconcile-period`     |
| Custom resources | `ansible.operator-sdk/max-runner-artifacts` | `ansible.sdk.operatorframework.io/max-runner-artifacts` |
| Custom resources | `ansible.operator-sdk/verbosity`            | `ansible.sdk.operatorframework.io/verbosity`            |
| Custom resources | `helm.operator-sdk/upgrade-force`           | `helm.sdk.operatorframework.io/upgrade-force`           |

_See [#3527](https://github.com/operator-framework/operator-sdk/pull/3527) for more details._

### Hybrid Ansible and Helm operator use cases are not supported

There is no migration path that enables continued use of the Ansible-based or Helm-based operator Go libraries.

_See [#3560](https://github.com/operator-framework/operator-sdk/pull/3560) and [#3537](https://github.com/operator-framework/operator-sdk/pull/3537) for more details._

### Changes to Ansible and Helm configuration of max workers

- Flag `max-workers` was renamed to `max-concurrent-reconciles` in Ansible and Helm operators.
  Change all usage of `--max-workers` to `--max-concurrent-reconciles`. Functionality is identical; this
  is just a name change to align more with controller runtime terminology.

- The `WORKERS_<Kind>_<Group>` environment variable was deprecated. Change all usage of these
  environment variables to `MAX_CONCURRENT_RECONCILES_<Kind>_<Group>`.

_See [#3435](https://github.com/operator-framework/operator-sdk/pull/3435), [#3452](https://github.com/operator-framework/operator-sdk/pull/3452), and [#3456](https://github.com/operator-framework/operator-sdk/pull/3456) for more details._

### Ansible Operator `meta` variable renamed to `ansible_operator_meta`

All existing references to the `meta` variable in your Ansible content will
no longer work. Instead, your Ansible content should reference the
`ansible_operator_meta` variable.

Alternatively, you can use the `vars` keyword in your `watches.yaml` in order
to map the new `ansible_operator_meta` variable to `meta`. Below is a sample
`watches.yaml` that has made this change:

```yaml
    - version: v1alpha1
      group: test.example.com
      kind: Example
      role: test
      vars:
        meta: '{{ ansible_operator_meta }}'
```

_See [#3562](https://github.com/operator-framework/operator-sdk/pull/3562) for more details._

### Migrated Ansible and Helm operators to use new Kubebuilder-style metrics

- Replaced kube-state-metrics style metrics on port `:8686` with a similar `resource_created_at` metric
  registered with the controller-runtime metrics registry

- Replace runtime creation of the metrics `Service` and `ServiceMonitor` with deploy-time kustomize manifests

_See [#3466](https://github.com/operator-framework/operator-sdk/pull/3466) and [#3451](https://github.com/operator-framework/operator-sdk/pull/3451) for more details._

### Removed package `pkg/k8sutil`

With the transition to Kubebuilder-style projects, `pkg/k8sutil` is no longer used in the default scaffolding
for Go operators. Migrate your project to the new Kubebuilder-style layout to remove the need for this
package.

_See [#3475](https://github.com/operator-framework/operator-sdk/pull/3475) for more details._

### Removed packages `pkg/kube-metrics` and `pkg/metrics`

Remove the call to `addMetrics` in your `main.go` file and begin using the
`InstrumentedEnqueueRequestForObject` handler when setting up controller-runtime
watches for your primary CRs.

`InstrumentedEnqueueRequestForObject` can be imported from `github.com/operator-framework/operator-lib/handler`.

_See [#3484](https://github.com/operator-framework/operator-sdk/pull/3484) for more details._

### Removed package `pkg/ready`

Use `controller-runtime`'s readyz server that supports custom http handlers. Add add a `healthz.Checker` (e.g. [`healthz.Ping`](
https://github.com/kubernetes-sigs/controller-runtime/blob/229c3c357d9e6b07c3d6774010c35161a82b08f9/pkg/healthz/healthz.go#L187-L188))
using [`manager.AddReadyzCheck`](https://github.com/kubernetes-sigs/controller-runtime/blob/229c3c357d9e6b07c3d6774010c35161a82b08f9/pkg/manager/manager.go#L73-L74).

_See [#3476](https://github.com/operator-framework/operator-sdk/pull/3476) for more details._

### Removed package `pkg/tls`

See the [Kubebuilder docs](https://book.kubebuilder.io/cronjob-tutorial/cert-manager.html#deploying-the-cert-manager) on
how to deploy and manage TLS certificates with cert-manager.

_See [#3468](https://github.com/operator-framework/operator-sdk/pull/3468) for more details._

### Update your scorecard config file to the new format

See the updated scorecard [config documentation](/docs/advanced-topics/scorecard/scorecard/#config-file)
for details.

_See [#3434](https://github.com/operator-framework/operator-sdk/pull/3434) and
[#3490](https://github.com/operator-framework/operator-sdk/pull/3490) for more details._

### Use `scorecard` instead of `alpha scorecard`

If you have been using `operator-sdk alpha scorecard`, update to use `operator-sdk scorecard`.
If you have been using `operator-sdk scorecard`, migrate to the new scorecard. See the new
[scorecard documentation](/docs/advanced-topics/scorecard/scorecard/).

_See [#3444](https://github.com/operator-framework/operator-sdk/pull/3444) for more details._

### Scorecard output formatting has changed

Update any scripts interpretting the scorecard output to
understand the `v1alpha3.TestList` format.

See the [`json`](/docs/advanced-topics/scorecard/scorecard/#json-format) and
[`text`](/docs/advanced-topics/scorecard/scorecard/#text-format) format
descriptions for details.

_See [#3427](https://github.com/operator-framework/operator-sdk/pull/3427) for more details._
