PowerVS v1beta2 to v1beta3 Migration Guide
Overview
This guide helps you migrate from v1beta2 to v1beta3 PowerVS APIs. The v1beta3 API introduces significant improvements based on Kubernetes API best practices, including enhanced type safety, explicit intent declaration, and better GitOps compatibility.
Note: This migration guide covers the currently implemented changes. Additional API improvements will be documented as they are completed.
Table of Contents
| # | Section | Resource |
|---|---|---|
| 1 | Cluster Topology | IBMPowerVSCluster |
| 2 | Zone and Resource Group | IBMPowerVSCluster |
| 3 | Workspace Configuration | IBMPowerVSCluster |
| 4 | Network Configuration | IBMPowerVSCluster |
| 5 | TransitGateway Configuration | IBMPowerVSCluster |
| 6 | VPC Configuration | IBMPowerVSCluster |
| 7 | VPC Subnet Configuration | IBMPowerVSCluster |
| 8 | LoadBalancer Configuration | IBMPowerVSCluster |
| 9 | IBMPowerVSMachine Configuration | IBMPowerVSMachine |
| 10 | IBMPowerVSImage Configuration | IBMPowerVSImage |
| 11 | Status Field Changes | All resources |
| 12 | Conversion Webhook | All resources |
What’s Changed
The v1beta3 API introduces several major improvements across PowerVS resources. This guide documents the changes for:
- IBMPowerVSCluster - Topology, Zone, Resource Group, Workspace, Network, TransitGateway, VPC, VPC Subnets, and LoadBalancer configuration
- IBMPowerVSMachine - Workspace and Network references
- IBMPowerVSImage - Workspace reference
Each section below provides detailed before/after examples and migration guidance.
1. Cluster Topology
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSCluster
metadata:
name: my-cluster
annotations:
powervs.cluster.x-k8s.io/create-infra: "true" # Annotation-based
spec:
# Configuration implied by annotation
v1beta3 (New)
Option A: VirtualIP Topology (PowerVS)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
topology: VirtualIP # Explicit topology declaration
# No VPC/LoadBalancer configuration needed
Option B: LoadBalancer Topology (PowerVS + VPC)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
topology: LoadBalancer # Explicit topology declaration
zone: "wdc06" # Required for LoadBalancer topology
resourceGroup:
name: "my-resource-group" # Required for LoadBalancer topology
vpc:
name: "my-vpc"
region: "us-east"
# LoadBalancer will be automatically created
Key Points:
- The
topologyfield replaces the annotation-based approach. VirtualIPtopology: PowerVS network with Virtual IP.LoadBalancertopology: Integrates PowerVS with VPC and LoadBalancer.- The topology is explicit, required, and discoverable via
kubectl explain.
2. Zone and Resource Group (Data Type Enhancements)
In v1beta3, structural data types have been flattened to comply with standard Kubernetes API guidelines and prevent runtime errors.
v1beta2 (Deprecated)
In v1beta2, Zone and ResourceGroup used Go pointers (*string and *ResourceReference). This occasionally caused nil-pointer panics in the controller and required complex webhook validations.
# v1beta2 internal representation allowed nulls
zone: "wdc06" # evaluated as *string
v1beta3 (New)
In v1beta3, pointers have been removed in favor of strict value types (string).
Key Points:
- Pointer-Free API:
zoneis now a standard string, preventing nil-pointer exceptions. - Conditional Validation: If
topology: LoadBalanceris selected, Kubernetes native CEL (Common Expression Language) rules will strictly enforce that bothzoneandresourceGroupare provided and not empty. - Graceful Omission: If
topology: VirtualIPis selected,zoneandresourceGroupcan be safely omitted from the YAML without causing schema errors.
3. Workspace Configuration
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
serviceInstanceID: "3229a94c-af54-4212-bf60-6202b6fd0a07"
v1beta3 (New)
Option A: Reference an Existing Workspace
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
workspace:
type: Reference
reference:
id: "3229a94c-af54-4212-bf60-6202b6fd0a07"
# OR use name instead of id
# name: "my-existing-workspace"
Option B: Provision a New Workspace
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
workspace:
type: Provision
provision:
name: "my-new-workspace" # Optional: defaults to <cluster-name>-workspace
Key Points:
- The
typefield explicitly declares your intent (Reference or Provision). - Use
reference.idorreference.nameto identify existing workspaces. - When provisioning, the workspace name is optional and defaults to
<cluster-name>-workspace. - The controller will only delete workspaces it created (when
type: Provision).
4. Network Configuration
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
network:
name: "capi-test"
dhcpServer:
name: "DHCPSERVER-capi-test"
snat: true # Boolean pointer
v1beta3 (New)
Option A: Reference an Existing Network
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
network:
type: Reference
reference:
name: "capi-test"
# OR use id instead of name
# id: "network-id-12345"
Option B: Provision a New Network with DHCP Server
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
network:
type: Provision
provision:
dhcpServer:
name: "my-dhcp-server" # Optional: defaults to DHCPSERVER<cluster-name>_Private
cidr: "192.168.0.0/24" # Optional
dnsServer: "8.8.8.8" # Optional
snat: Enabled # Enum: Enabled or Disabled (default: Enabled)
Key Points:
- The
typefield explicitly declares whether to use an existing or create a new network. - SNAT is now an enum (
Enabled/Disabled) instead of a boolean pointer. - DHCP server configuration is only valid when
type: Provision. - The controller will only delete networks it created.
5. TransitGateway Configuration
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
transitGateway:
name: "my-transit-gateway" # OR use id
id: "tgw-id-123"
globalRouting: true # *bool pointer — true = Global, false = Local
v1beta3 (New)
Option A: Reference an Existing Transit Gateway
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
transitGateway:
type: Reference
reference:
id: "tgw-id-123"
# OR use name instead of id
# name: "my-transit-gateway"
Option B: Provision a New Transit Gateway
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
transitGateway:
type: Provision
provision:
name: "my-transit-gateway" # Optional: defaults to <cluster-name>-tgw
globalRouting: Global # Enum: Local or Global (auto-detected if omitted)
# Optionally control how VPC/PowerVS connections are sourced
vpcConnection:
type: Provision
powerVSConnection:
type: Provision
Key Points:
- The
typefield (Reference/Provision) replaces the flatname/idstruct. globalRoutingis now an enum (Local/Global) instead of a*bool.- When omitted, the system automatically selects routing based on PowerVS and VPC regions.
- Individual connections (
vpcConnection,powerVSConnection) can each independently reference an existing connection or provision a new one. - The controller only deletes Transit Gateways and connections it created (
type: Provision).
6. VPC Configuration
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
vpc:
id: "vpc-id-123" # OR use name
name: "my-vpc"
region: "us-east" # Required only when create-infra annotation is set
v1beta3 (New)
Option A: Reference an Existing VPC
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
vpc:
type: Reference
region: "us-east" # Required
reference:
id: "vpc-id-123"
# OR use name instead of id
# name: "my-vpc"
Option B: Provision a New VPC
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
vpc:
type: Provision
region: "us-east" # Required
provision:
name: "my-new-vpc" # Optional: defaults to <cluster-name>-vpc
Key Points:
type(Reference/Provision) is now required and replaces the implicit behavior of v1beta2.regionis always required in v1beta3 (was only required under the create-infra annotation in v1beta2).- The
typefield is immutable once set. - The controller only deletes VPCs it created (
type: Provision).
7. VPC Subnet Configuration
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
vpcSubnets:
- name: "my-subnet"
id: "subnet-id-123" # OR use name
zone: "us-east-1"
cidr: "10.0.0.0/24" # IPv4 CIDR block
v1beta3 (New)
Option A: Reference Existing Subnets
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
subnets: # Field renamed from vpcSubnets to subnets
- type: Reference
zone: "us-east-1"
reference:
id: "subnet-id-123"
# OR use name instead of id
# name: "my-subnet"
Option B: Provision New Subnets
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
subnets:
- type: Provision
zone: "us-east-1" # Optional: random zone picked if omitted
provision:
name: "my-subnet" # Optional: defaults to <cluster-name>-vpcsubnet-<INDEX>
Key Points:
- The field was renamed from
vpcSubnetstosubnets. - Each entry now requires a
typefield (Reference/Provision). - The
cidrfield from the v1beta2Subnetstruct has been removed in v1beta3. - When
type: Provisionandzoneis omitted, a random zone is selected from those available in the VPC region. - The controller only deletes subnets it created (
type: Provision).
8. LoadBalancer Configuration
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
loadBalancers:
- name: "my-lb"
id: "lb-id-123" # OR use name
public: true # *bool pointer — true = public, false = private
additionalListeners:
- port: 443
protocol: TCP
defaultPoolName: "my-pool" # *string pointer
backendPools:
- name: "my-pool" # *string pointer
algorithm: round_robin
protocol: tcp
healthMonitor:
delay: 10
retries: 3
timeout: 5
type: tcp
securityGroups:
- id: "sg-id-123"
name: "my-sg" # VPCResource struct
subnets:
- id: "subnet-id-123"
name: "my-subnet" # VPCResource struct
v1beta3 (New)
Option A: Reference an Existing Load Balancer
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
loadBalancers:
- type: Reference
reference:
id: "lb-id-123"
# OR use name instead of id
# name: "my-lb"
Option B: Provision a New Load Balancer
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSCluster
metadata:
name: my-cluster
spec:
loadBalancers:
- type: Provision
provision:
name: "my-lb" # Optional: defaults to <cluster-name>-loadbalancer
type: Public # Enum: Public or Private (default: Public)
additionalListeners:
- port: 443
protocol: TCP
defaultPoolName: "my-pool" # plain string (no longer a pointer)
backendPools:
- name: "my-pool" # plain string (no longer a pointer)
algorithm: round_robin
protocol: tcp
healthMonitor:
delay: 10
retries: 3
timeout: 5
type: tcp
securityGroups:
- id: "sg-id-123" # ResourceIdentifier: id or name
subnets:
- name: "my-subnet" # ResourceIdentifier: id or name
Key Points:
type(Reference/Provision) is now required at the top level of each entry.- The flat
id/namefields on a LoadBalancer entry have moved intoreference(whentype: Reference). - The
publicfield (*bool) is replaced byprovision.typeenum (Public/Private), defaulting toPublic. securityGroupsandsubnetsnow useResourceIdentifierinstead of the v1beta2VPCResourcestruct.additionalListeners[].defaultPoolNamechanged from*string(pointer) to a plainstring.backendPools[].namechanged from*string(pointer) to a plainstring.- The controller only deletes load balancers it created (
type: Provision).
9. IBMPowerVSMachine Configuration
Workspace Reference
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSMachine
metadata:
name: my-machine
spec:
serviceInstanceID: "workspace-id-123"
# OR
serviceInstance:
name: "my-workspace"
v1beta3 (New)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSMachine
metadata:
name: my-machine
spec:
workspace:
id: "workspace-id-123"
# OR use name
# name: "my-workspace"
Key Points:
- The
workspacefield usesResourceIdentifiertype. - Supports both
idandnameidentifiers. - If omitted, workspace is inherited from the associated IBMPowerVSCluster.
- Simplified from the v1beta2
serviceInstancestructure.
Network Reference
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSMachine
metadata:
name: my-machine
spec:
network:
name: "my-network"
v1beta3 (New)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSMachine
metadata:
name: my-machine
spec:
network:
id: "network-id-123"
# OR use name
# name: "my-network"
Key Points:
- The
networkfield usesResourceIdentifiertype. - Supports
idandnameidentifiers. - Simplified and consistent network reference pattern.
10. IBMPowerVSImage Configuration
Workspace Reference
v1beta2 (Deprecated)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: IBMPowerVSImage
metadata:
name: my-image
namespace: default
spec:
clusterName: "my-cluster"
serviceInstanceID: "workspace-id-123"
# OR
serviceInstance:
name: "my-workspace"
bucket: "my-cos-bucket"
object: "rhcos-image.ova.gz"
region: "us-south"
storageType: "tier1"
deletePolicy: "delete"
v1beta3 (New)
apiVersion: infrastructure.cluster.x-k8s.io/v1beta3
kind: IBMPowerVSImage
metadata:
name: my-image
namespace: default
spec:
clusterName: "my-cluster"
workspace:
id: "workspace-id-123"
# OR use name
# name: "my-workspace"
bucket: "my-cos-bucket"
object: "rhcos-image.ova.gz"
region: "us-south"
storageType: "tier1" # Options: tier0, tier1, tier3
deletePolicy: "delete" # Options: delete, retain
Key Points:
- Workspace reference changed from
serviceInstanceID/serviceInstancetoworkspaceusing ResourceIdentifier. - Workspace can be specified using
idorname. - If workspace is omitted, it’s automatically derived from the associated IBMPowerVSCluster’s status.
- Simplified and consistent with other v1beta3 resources.
Status Field Changes
v1beta2 Status
status:
serviceInstance:
id: "workspace-id"
controllerCreated: true # Boolean pointer in status
network:
id: "network-id"
controllerCreated: true
vpc:
id: "vpc-id"
controllerCreated: true
vpcSubnet: # keyed map
us-east-1: { id: "subnet-id", controllerCreated: true }
transitGateway:
id: "tgw-id"
controllerCreated: true
vpcConnection:
id: "conn-id"
controllerCreated: true
powerVSConnection:
id: "conn-id"
controllerCreated: true
loadBalancers: # keyed map
my-lb:
id: "lb-id"
hostname: "my-lb.example.com"
controllerCreated: true
v1beta3 Status
status:
workspace:
id: "workspace-id"
name: "my-workspace"
network:
id: "network-id"
name: "my-network"
dhcpServer:
id: "dhcp-id"
name: "my-dhcp"
vpc:
id: "vpc-id"
name: "my-vpc"
region: "us-east"
vpcSubnets: # renamed from vpcSubnet (map) to vpcSubnets (list)
- id: "subnet-id"
name: "my-subnet"
zone: "us-east-1"
transitGateway:
id: "tgw-id"
name: "my-tgw"
vpcConnection: # connection status includes state
id: "conn-id"
name: "my-vpc-conn"
state: "attached"
powerVSConnection:
id: "conn-id"
name: "my-pvs-conn"
state: "attached"
loadBalancers: # changed from map to list; hostname is a plain string
- name: "my-lb"
id: "lb-id"
state: "active"
hostname: "my-lb.example.com"
Key Points:
controllerCreatedremoved from all Status fields. Ownership is determined solely by thetypefield in Spec.- All Status resources expose both
idandnamefor better observability. - DHCP server status is nested under network status.
- VPC Status now includes
region. vpcSubnet(keyed map) renamed tovpcSubnets(ordered list), withzoneincluded per entry.- TransitGateway connection status now includes
state(e.g.,attached,pending). loadBalancerschanged from a keyed map (map[string]VPCLoadBalancerStatus) to an ordered list ([]LoadBalancerStatus).
Conversion Webhook
The v1beta3 API includes automatic conversion webhooks that handle migration:
-
v1beta2 → v1beta3: Automatically converts old format to new
Status.ControllerCreated: true→Spec.Type: ProvisionStatus.ControllerCreated: false→Spec.Type: Reference- Boolean SNAT → Enum SNAT (
true→Enabled,false→Disabled) *bool globalRoutingon TransitGateway → Enum routing (true→Global,false→Local)*bool publicon LoadBalancer → Enum type (true→Public,false→Private)- Annotation-based topology → Explicit
topologyfield - Pointer strings → Value types (for
zoneandresourceGroup) vpcSubnets[](flat Subnet struct) →subnets[]withtype/reference/provisionshapeloadBalancerskeyed map in status →loadBalancerslist in statusvpcSubnetkeyed map in status →vpcSubnetslist in status
-
v1beta3 → v1beta2: Converts back for compatibility
Spec.Type: Provision→Status.ControllerCreated: trueSpec.Type: Reference→Status.ControllerCreated: false- Explicit
topologyfield → Annotation-based configuration - Enum routing →
*bool globalRouting - Enum LB type →
*bool public
Note: While conversion webhooks provide compatibility, it’s recommended to migrate to v1beta3 explicitly for better maintainability.