# Migration: Steps needed between the versions

## v2.0 to v2.1

### Kubernetes CRD

In v2.1, a new Kubernetes CRD called `TraefikService` was added.
While updating an installation to v2.1,
one should apply that CRD, and update the existing `ClusterRole` definition to allow Traefik to use that CRD.

To add that CRD and enhance the permissions, following definitions need to be applied to the cluster.

```yaml tab="TraefikService"
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: traefikservices.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TraefikService
    plural: traefikservices
    singular: traefikservice
  scope: Namespaced
```

```yaml tab="ClusterRole"
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller

rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - traefik.containo.us
    resources:
      - middlewares
      - ingressroutes
      - traefikservices
      - ingressroutetcps
      - tlsoptions
    verbs:
      - get
      - list
      - watch
```

After having both resources applied, Traefik will work properly.

## v2.1 to v2.2

### Headers middleware: accessControlAllowOrigin

`accessControlAllowOrigin` is deprecated.
This field will be removed in future 2.x releases.
Please configure your allowed origins in `accessControlAllowOriginList` instead.

### Kubernetes CRD

In v2.2, new Kubernetes CRDs called `TLSStore` and `IngressRouteUDP` were added.
While updating an installation to v2.2,
one should apply that CRDs, and update the existing `ClusterRole` definition to allow Traefik to use that CRDs.

To add that CRDs and enhance the permissions, following definitions need to be applied to the cluster.

```yaml tab="TLSStore"
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: tlsstores.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: TLSStore
    plural: tlsstores
    singular: tlsstore
  scope: Namespaced

```

```yaml tab="IngressRouteUDP"
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: ingressrouteudps.traefik.containo.us

spec:
  group: traefik.containo.us
  version: v1alpha1
  names:
    kind: IngressRouteUDP
    plural: ingressrouteudps
    singular: ingressrouteudp
  scope: Namespaced

```

```yaml tab="ClusterRole"
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller

rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses/status
    verbs:
      - update
  - apiGroups:
      - traefik.containo.us
    resources:
      - middlewares
      - ingressroutes
      - traefikservices
      - ingressroutetcps
      - ingressrouteudps
      - tlsoptions
      - tlsstores
    verbs:
      - get
      - list
      - watch

```

After having both resources applied, Traefik will work properly.

### Kubernetes Ingress

To enable HTTPS, it is not sufficient anymore to only rely on a TLS section in the Ingress.

#### Expose an Ingress on 80 and 443

Define the default TLS configuration on the HTTPS entry point. 

```yaml tab="Ingress"
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: example

spec:
  tls:
  - secretName: myTlsSecret

  rules:
  - host: example.com
    http:
      paths:
      - path: "/foo"
        backend:
          serviceName: example-com
          servicePort: 80
```

Entry points definition and enable Ingress provider:

```yaml tab="File (YAML)"
# Static configuration

entryPoints:
  web:
    address: :80
  websecure:
    address: :443
    http:
      tls: {}

providers:
  kubernetesIngress: {}
```

```toml tab="File (TOML)"
# Static configuration

[entryPoints.web]
  address = ":80"

[entryPoints.websecure]
  address = ":443"
  [entryPoints.websecure.http]
    [entryPoints.websecure.http.tls]

[providers.kubernetesIngress]
```

```bash tab="CLI"
# Static configuration

--entryPoints.web.address=:80
--entryPoints.websecure.address=:443
--entryPoints.websecure.http.tls=true
--providers.kubernetesIngress=true
```

#### Use TLS only on one Ingress

Define the TLS restriction with annotations.

```yaml tab="Ingress"
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
  name: example-tls
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
    traefik.ingress.kubernetes.io/router.tls: "true"

spec:
  tls:
  - secretName: myTlsSecret

  rules:
  - host: example.com
    http:
      paths:
      - path: ""
        backend:
          serviceName: example-com
          servicePort: 80
```

Entry points definition and enable Ingress provider:

```yaml tab="File (YAML)"
# Static configuration

entryPoints:
  web:
    address: :80
  websecure:
    address: :443

providers:
  kubernetesIngress: {}
```

```toml tab="File (TOML)"
# Static configuration

[entryPoints.web]
  address = ":80"

[entryPoints.websecure]
  address = ":443"

[providers.kubernetesIngress]
```

```bash tab="CLI"
# Static configuration

--entryPoints.web.address=:80
--entryPoints.websecure.address=:443
--providers.kubernetesIngress=true
```

## v2.2.2 to v2.2.5

### InsecureSNI removal

In `v2.2.2` we introduced a new flag (`insecureSNI`) which was available as a global option to disable domain fronting.
Since `v2.2.5` this global option has been removed, and you should not use it anymore.

### HostSNI rule matcher removal

In `v2.2.2` we introduced a new rule matcher (`HostSNI`) for HTTP routers which was allowing to match the Server Name Indication at the router level.
Since `v2.2.5` this rule has been removed for HTTP routers, and you should not use it anymore.

## v2.2 to v2.3

### X.509 CommonName Deprecation

The deprecated, legacy behavior of treating the CommonName field on X.509 certificates as a host name when no Subject Alternative Names are present, is now disabled by default.

It means that if one is using https with your backend servers, and a certificate with only a CommonName,
Traefik will not try to match the server name indication with the CommonName anymore.

It can be temporarily re-enabled by adding the value `x509ignoreCN=0` to the `GODEBUG` environment variable.

More information: https://golang.org/doc/go1.15#commonname

### File Provider

The file parser has been changed, since v2.3 the unknown options/fields in a dynamic configuration file are treated as errors.

### IngressClass

In `v2.3`, the support of `IngressClass`, which is available since Kubernetes version `1.18`, has been introduced.
In order to be able to use this new resource the [Kubernetes RBAC](../reference/dynamic-configuration/kubernetes-crd.md#rbac) must be updated. 
