Upgrade CNFs from 2.3.x to 2.4.0 using F5 Lifecycle Operator

This document describes how to upgrade the F5 Lifecycle Operator (FLO), migrate CPCL ConfigMaps to Secrets, upgrade the CNE Instance, and apply the License custom resource.

Important

Ensure that license content (JWT values) are removed from any values files before sharing or committing them.

Upgrade the F5 Lifecycle Operator (FLO)

  1. Create or update the FLO values file.

    Example: flo-values_2.4.0.yaml

    global:
    imagePullSecrets:
        - name: far-secret
    certmgr:
        clusterIssuer: arm-ca-cluster-issuer
    
    image:
    repository: repo.f5.com/images
    pullPolicy: IfNotPresent
    
    f5-spk-crds-common:
    versionValidator:
        image:
        repository: repo.f5.com/images
    
    f5-spk-crds-service-proxy:
    versionValidator:
        image:
        repository: repo.f5.com/images
    
    f5-ipam-operator:
    image:
        repository: repo.f5.com/images
        pullPolicy: IfNotPresent
    namespace: "default"
    nameOverride: "f5-ipam-operator"
    fullnameOverride: "f5-ipam-operator"
    
    sharedComponentNamespace: "f5-utils"
    
  2. Execute the Helm upgrade using the values file.

    $ helm upgrade f5-lifecycle-operator tar/f5-lifecycle-operator-v2.30.0-0.5.2.tgz -f flo-values_2.4.0.yaml
    
  3. Verify the upgrade.

    $ helm list
    

Apply the CNE Instance

  1. Create the CNE Instance custom resource after the FLO upgrade completes.

    Example: cnegatewayclass-cr.yaml

    apiVersion: v1
    items:
    - apiVersion: k8s.f5.com/v1
      kind: CNEInstance
      metadata:
        annotations:
          cneinstance.k8s.f5.com/disable-session-state: "true"
          kubectl.kubernetes.io/last-applied-configuration: |
            {"apiVersion":"k8s.f5.com/v1","kind":"CNEInstance","metadata":{"annotations":{"cneinstance.k8s.f5.com/disable-session-state":"true"},"labels":{"app.kubernetes.io/managed-by":"kustomize","app.kubernetes.io/name":"f5-lifecycle-operator"},"name":"f5-alpha-cneinstcr","namespace":"f5-alpha"},"spec":{"advanced":{"cneController":{"env":[{"name":"CLOUD_ENV","value":"true"},{"name":"CLOUD_PROVIDER","value":"ibm"},{"name":"CLOUD_TRUSTED_PROFILE","value":"Profile-8222f7db-34b4-470c-9ace-8b1405f01931"},{"name":"USE_GATEWAY_SETTINGS","value":"true"},{"name":"GSLB_DATACENTER_NAME","value":"roks-s5-7-datacenter"}]},"coremon":{"env":[{"name":"COREMOND_OVERRIDE_CORE_PATTERN","value":"true"}],"hostPath":true},"demoMode":{"enabled":false},"envDiscovery":{"enabled":false},"externalBigip":{"env":[{"name":"EXT_BIGIP_REGISTRY_CR","value":"external-bigip-registry"}]},"ipamController":{"env":[{"name":"PROVIDER","value":"infoblox"},{"name":"INFOBLOX_GRID_HOST","value":"52.197.167.88"},{"name":"INFOBLOX_WAPI_VERSION","value":"2.11.2"},{"name":"INFOBLOX_WAPI_PORT","value":"443"},{"name":"INSECURE","value":"false"},{"name":"CREDENTIAL_SECRET","value":"infoblox-login-secret"},{"name":"CERTIFICATE_SECRET","value":"infoblox-ca-cert-secret"}]},"maintenanceMode":{"enabled":false},"pseudoCNI":{"env":[{"name":"DISABLE_CHECKSUM_OFFLOAD","value":"true"}]},"tmm":{"env":[{"name":"TMM_CALICO_ROUTER","value":"default"},{"name":"ENABLE_K8S_ROUTES","value":"true"},{"name":"TMM_IGNORE_GATEWAYS","value":"true"},{"name":"TMM_MAPRES_ADDL_VETHS_ON_DP","value":"TRUE"}],"rollingUpdate":{"maxSurge":0,"maxUnavailable":1}}},"certificate":{"clusterIssuer":"ibm-rok-issuer"},"coreCollection":{"enabled":true},"deploymentSize":"Tiny","dpu":{"enabled":false},"dynamicRouting":{"enabled":false},"externalBigip":{"enabled":true},"firewallACL":{"enabled":true},"intelligentLB":{"enabled":false},"manifestVersion":"2.4.0","networkAttachments":["ens3-ipvlan-l2"],"placement":{"dataPlane":{"affinity":{"podAntiAffinity":{"requiredDuringSchedulingIgnoredDuringExecution":[{"labelSelector":{"matchLabels":{"app":"f5-tmm"}},"topologyKey":"kubernetes.io/hostname"}]}},"topologySpreadConstraints":[{"labelSelector":{"matchLabels":{"app":"f5-tmm"}},"maxSkew":1,"topologyKey":"topology.kubernetes.io/zone","whenUnsatisfiable":"DoNotSchedule"}]}},"product":{"gatewayAPI":true,"type":"BNK"},"pseudoCNI":{"enabled":true},"registry":{"imagePullPolicy":"Always","imagePullSecrets":[{"name":"farimagesecret"}],"uri":"devrepo.f5.com"},"telemetry":{"loggingSubsystem":{"enabled":true},"metricSubsystem":{"enabled":true}},"tmmReplicas":2,"watchNamespaces":["All"],"wholeCluster":false}}
        creationTimestamp: "2026-09-10T08:37:44Z"
        finalizers:
        - k8s.f5.com/CNEInstanceFinalizer
        generation: 3
        labels:
          app.kubernetes.io/managed-by: kustomize
          app.kubernetes.io/name: f5-lifecycle-operator
        name: f5-alpha-cneinstcr
        namespace: f5-alpha
        resourceVersion: "13367225"
        uid: 9aee3c84-c8d0-4a1f-aa39-bf2f20c8ddea
      spec:
        access: {}
        advanced:
          analyzer: {}
          bdosd: {}
          cneController:
            env:
            - name: CLOUD_ENV
              value: "true"
            - name: CLOUD_PROVIDER
              value: ibm
            - name: CLOUD_TRUSTED_PROFILE
              value: Profile-8222f7db-34b4-470c-9ace-8b1405f01931
            - name: USE_GATEWAY_SETTINGS
              value: "true"
            - name: GSLB_DATACENTER_NAME
              value: roks-s5-7-datacenter
          coremon:
            env:
            - name: COREMOND_OVERRIDE_CORE_PATTERN
              value: "true"
            hostPath: true
          crdConversion: {}
          crdInstaller: {}
          cwc:
            kal: {}
          demoMode:
            enabled: false
          downloader: {}
          dssm: {}
          dwbld: {}
          envDiscovery:
            enabled: false
          externalBigip:
            env:
            - name: EXT_BIGIP_REGISTRY_CR
              value: external-bigip-registry
          firewallACL: {}
          fluentd: {}
          ipamController:
            env:
            - name: PROVIDER
              value: infoblox
            - name: INFOBLOX_GRID_HOST
              value: 52.197.167.88
            - name: INFOBLOX_WAPI_VERSION
              value: 2.11.2
            - name: INFOBLOX_WAPI_PORT
              value: "443"
            - name: INSECURE
              value: "false"
            - name: CREDENTIAL_SECRET
              value: infoblox-login-secret
            - name: CERTIFICATE_SECRET
              value: infoblox-ca-cert-secret
          ipsd: {}
          ipsec: {}
          maintenanceMode:
            enabled: false
          nodeLabeler: {}
          observer: {}
          otel: {}
          otelCollector: {}
          pseudoCNI:
            env:
            - name: DISABLE_CHECKSUM_OFFLOAD
              value: "true"
          rabbitmq: {}
          tmm:
            env:
            - name: TMM_CALICO_ROUTER
              value: default
            - name: ENABLE_K8S_ROUTES
              value: "true"
            - name: TMM_IGNORE_GATEWAYS
              value: "true"
            - name: TMM_MAPRES_ADDL_VETHS_ON_DP
              value: "TRUE"
            rollingUpdate:
              maxSurge: 0
              maxUnavailable: 1
        behavioralDoS: {}
        certificate:
          clusterIssuer: ibm-rok-issuer
        cgnat: {}
        coreCollection:
          enabled: true
        deploymentSize: Tiny
        dpu:
          enabled: false
        dynamicRouting:
          enabled: false
        externalBigip:
          enabled: true
        firewallACL:
          enabled: true
        intelligentLB:
          enabled: false
        intrusionPrevention: {}
        ipIntelligence: {}
        manifestVersion: 2.4.0
        networkAttachments:
        - ens3-ipvlan-l2
        placement:
          controlPlane: {}
          dataPlane:
            affinity:
              podAntiAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                - labelSelector:
                    matchLabels:
                      app: f5-tmm
                  topologyKey: kubernetes.io/hostname
            topologySpreadConstraints:
            - labelSelector:
                matchLabels:
                  app: f5-tmm
              maxSkew: 1
              topologyKey: topology.kubernetes.io/zone
              whenUnsatisfiable: DoNotSchedule
          observability: {}
          sessionState: {}
        policyEnforcement: {}
        product:
          gatewayAPI: true
          type: BNK
        pseudoCNI:
          enabled: true
        registry:
          imagePullPolicy: Always
          imagePullSecrets:
          - name: farimagesecret
          uri: devrepo.f5.com
        telemetry:
          loggingSubsystem:
            enabled: true
          metricSubsystem:
            enabled: true
        tmmReplicas: 2
        watchNamespaces:
        - All
        wholeCluster: false
      status:
        conditions:
        - lastTransitionTime: "2026-09-10T08:37:44Z"
          message: Initial processing performed
          observedGeneration: 3
          reason: Accepted
          status: "True"
          type: Accepted
        - lastTransitionTime: "2026-09-10T08:37:44Z"
          message: ""
          observedGeneration: 3
          reason: Reconciled
          status: "True"
          type: Reconciled
        - lastTransitionTime: "2026-09-10T11:01:00Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: Available
        - lastTransitionTime: "2026-09-10T08:38:05Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: CRDInstallerAvailable
        - lastTransitionTime: "2026-09-10T09:16:01Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: CNEControllerAvailable
        - lastTransitionTime: "2026-09-10T11:01:00Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: F5TmmAvailable
        - lastTransitionTime: "2026-09-10T08:38:29Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: AfmAvailable
        - lastTransitionTime: "2026-09-10T08:38:11Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: ExternalBigIPControllerAvailable
        - lastTransitionTime: "2026-09-10T08:38:25Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: FluentdAvailable
        - lastTransitionTime: "2026-09-10T08:38:16Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: RabbitmqAvailable
        - lastTransitionTime: "2026-09-10T08:38:53Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: CRDConversionAvailable
        - lastTransitionTime: "2026-09-10T08:39:33Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: CwcAvailable
        - lastTransitionTime: "2026-09-10T08:38:16Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: IPAMControllerAvailable
        - lastTransitionTime: "2026-09-10T08:38:20Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: CoremondAvailable
        - lastTransitionTime: "2026-09-10T08:38:39Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: CSRCAvailable
        - lastTransitionTime: "2026-09-10T08:38:45Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: ObserverAvailable
        - lastTransitionTime: "2026-09-10T08:38:10Z"
          message: ""
          observedGeneration: 3
          reason: Available
          status: "True"
          type: OtelCollectorAvailable
        sessionStore:
          desiredDBPods: 3
    kind: List
    metadata:
      resourceVersion: ""
    
  2. Apply the resource:

    $ kubectl apply -f arm/tmp/cnegatewayclass-cr.yaml -n f5-alpha
    

Verify CNE Pods

  1. Verify Pods in f5-utils

    $ kubectl get pods -n f5-utils
    
  2. Verify Pods in f5-alpha

    $ kubectl get pods -n f5-alpha