Upgrading a ROSA HCP cluster with Terraform
This content is authored by Red Hat experts, but has not yet been tested on every supported configuration. This guide has been validated on OpenShift 4.22. Operator CRD names, API versions, and console paths may differ on other versions.
Learn how to upgrade Red Hat OpenShift Service on AWS (ROSA) Hosted Control Plane (HCP) clusters with the supported Terraform RHCS provider and the terraform-redhat/rosa-hcp module. Upgrade the control plane first, then additional machine pools, then the default installer worker pools. Do not change channel and version in the same apply.
This is a practical day-2 guide for z-stream and y-stream upgrades with the official RHCS Terraform stack. For cluster creation, see Deploying a ROSA HCP cluster with Terraform .
Why this matters
On ROSA Hosted Control Plane, the control plane and machine pools upgrade independently. The OpenShift version on a machine pool must never exceed the control plane version, and you cannot upgrade both to the same target in one Terraform apply. Teams that only bump openshift_version and run a full terraform apply often hit empty “available upgrades” lists on pools, or leave the installer-created workers-* pools behind while additional pools move forward.
This article follows the supported Terraform path:
- Provider:
terraform-redhat/rhcs - Module:
terraform-redhat/rosa-hcp/rhcs(and itsrosa-cluster-hcp/machine-poolsubmodules) - Official guides: Upgrading HCP with Terraform , Default / worker machine pool , ROSA HCP upgrading
Three upgrade surfaces
| Surface | What it is | Typical Terraform resource | How to upgrade |
|---|---|---|---|
| Control plane (CP) | Hosted control plane version | rhcs_cluster_rosa_hcp (module rosa-cluster-hcp) |
Change version / openshift_version, apply CP only |
| Additional machine pools | Pools you declared in Terraform after create | rhcs_hcp_machine_pool (module machine-pool) |
Change each pool’s version (or shared variable), apply after CP |
| Default machine pools | Installer-created pools (HCP: usually workers-0, workers-1, … per AZ) |
Not managed until you import them | Import into rhcs_hcp_machine_pool, then set version |
Pools may lag the control plane by up to two minor (y-stream) versions.
Before you upgrade
Prerequisites
- A ROSA HCP cluster managed with Terraform (
terraform-redhat/rosa-hcpor equivalentrhcs_cluster_rosa_hcp/rhcs_hcp_machine_poolresources) rosaCLI logged interraformCLI with access to the same state used to create the cluster
Confirm a supported path
-
List available upgrades for the cluster and for each machine pool:
If a machine pool shows no available upgrades ( []) while the CP target exists, the control plane has not finished moving to a version that unlocks that pool upgrade. Wait for the CP, then retry.
Z-stream vs y-stream
- Z-stream (for example
4.21.15to4.21.27): bump version only.upgrade_acknowledgements_foris usually not required. - Y-stream (for example
4.21.zto4.22.z): set channel (for examplestable-4.22) andupgrade_acknowledgements_for = "4.22", but not in the same API request as the version bump (see below).
Acknowledge only after you validate
Setting upgrade_acknowledgements_for means you accept the administrative agreements for that minor upgrade. Before you set it:
- Review OpenShift / ROSA release notes and life cycle for the target y-stream
- Check API deprecations and removed APIs (operators, CRDs, GitOps manifests)
- Confirm workloads and operators support the target version
upgrade_acknowledgements_for permanently set as a standing default for every apply. Add it for the upgrade that needs it.Part 1: Upgrade the control plane only
With the rosa-hcp root module (or an equivalent that wraps modules/rosa-cluster-hcp), target the cluster module so machine pools are not updated in the same apply.
Z-stream example
-
Set the target version:
-
Apply only the cluster module:
-
Wait until the control plane is ready:
Y-stream: channel and version cannot change together
The OCM API returns:
if you update both in one request. Use two control-plane applies.
-
Apply A: channel only (keep the current CP version):
-
Apply B: version (channel already
stable-4.22):
channel and version_channel_group / channel_group together. Pick one channel model per the RHCS provider docs.Part 2: Upgrade additional machine pools
Additional pools are the ones you created with the machine-pool submodule (or rhcs_hcp_machine_pool resources) after cluster create, for example GPU, metal, or extra compute pools.
After the control plane is on the target version:
-
Set each pool’s
openshift_version/versionto the same target (or use a shared variable the module passes through). -
For y-stream, set
upgrade_acknowledgements_foron the pool if the provider requires it (same minor acknowledgement pattern as the cluster). -
Apply pools only (or a full apply now that CP is done):
-
Verify:
You want pool VERSION to match the CP (or show a scheduled upgrade), and eventually “no available upgrades” once caught up.
Part 3: Default machine pools
What the official module does (and does not)
When you create a ROSA cluster with Terraform, a default worker machine pool is created by the installer so the cluster can become ready. After create, cluster attributes such as compute_machine_type / replicas on rhcs_cluster_rosa_hcp no longer drive day-2 pool changes.
Per the RHCS worker machine pool guide :
- You must import a machine pool resource that points at the default pool before you can change or delete it via Terraform.
- Classic docs often refer to a pool named
worker. - On ROSA HCP multi-AZ, you typically get one pool per AZ:
workers-0,workers-1,workers-2, and so on, not a singleworkername. Magic import for the nameworkerdoes not cover those HCP pools; use explicitterraform importfor each.
Until you import them, bumping openshift_version on the cluster and on additional pools will not upgrade default workers-* pools. That is expected, not a Terraform bug.
Manual steps (supported RHCS pattern)
-
List pools and note subnet / replicas / instance type:
-
Declare
rhcs_hcp_machine_poolresources that match live settings (names andsubnet_idare immutable after create): -
If the provider rejects updates to installer
aws_node_poolfields (for example tags changing from null), add:so Terraform can still manage version without fighting create-time node-pool attributes.
-
Import into state (HCP import id is
cluster_id,machine_pool_id): -
Align config with
terraform planuntil you only see intended changes (usuallyversion). -
Upgrade default pools after the CP is on the target version:
-
Confirm:
Destroy / day-2 safety tips
- ROSA requires at least one machine pool; deleting the last pool is rejected by the API. Use
ignore_deletion_error = truewhen the cluster and pools are destroyed in the same root module. - To stop managing default pools in Terraform without deleting them in AWS/OCM:
terraform state rmthe resources, then remove them from configuration. Setting a “manage default pools” flag to false while resources remain in config will plan a destroy.
Recommended upgrade sequence
Common errors
| Error / symptom | Meaning | Fix |
|---|---|---|
Pool: desired version not in available upgrades [] |
CP not yet on a version that unlocks that pool upgrade, or CP+pools applied together | Finish CP upgrade; wait; apply pools second |
Cannot change channel and version simultaneously |
Channel and version in one update | Two CP applies: channel, then version |
| Missing upgrade acknowledgements | Y-stream requires admin ack | Set upgrade_acknowledgements_for to the target minor (for example "4.22") after validating APIs |
Default workers-* still on old version |
Not imported / not in Terraform | Import rhcs_hcp_machine_pool for each pool, then set version |
Attribute aws_node_pool.tags cannot be changed |
Installer pool attrs are sticky | lifecycle.ignore_changes on aws_node_pool; manage version only |