Skip to content
Open
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
303 changes: 203 additions & 100 deletions docs/book/src/topics/rosa/creating-a-cluster.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,41 @@
# Creating a ROSA HCP cluster

## Prerequisites

1. Create a management cluster using the [Quick Start Guide.](https://cluster-api-aws.sigs.k8s.io/quick-start)


2. Install the required tools and set up the prerequisite infrastructure using the [ROSA Setup guide](https://docs.aws.amazon.com/rosa/latest/userguide/set-up.html).

Once these steps are complete, you are ready to create a ROSA HCP cluster.


## Authentication
Comment thread
tinaafitz marked this conversation as resolved.
The CAPA controller requires service account credentials to provision ROSA HCP clusters.
If you already have a service account, you can skip these steps.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If you already have a service account, you can skip these steps.
**Note:** If you already have a service account, you can skip these steps.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

1. Create a service account by visiting [https://console.redhat.com/iam/service-accounts](https://console.redhat.com/iam/service-accounts).


2. For every newly created service account, make sure to activate the account using the [ROSA command line tool](https://github.com/openshift/rosa).
First, log in using your newly created service account:
```shell
rosa login --client-id ... --client-secret ...
```
3. Then activate your service account:
```shell
rosa whoami
```
## Permissions
### Authentication using service account credentials
CAPA controller requires service account credentials to be able to provision ROSA HCP clusters:
1. Visit [https://console.redhat.com/iam/service-accounts](https://console.redhat.com/iam/service-accounts) and create a service account. If you already have a service account, you can skip this step.

For every newly created service account, make sure to activate the account using the [ROSA command line tool](https://github.com/openshift/rosa). First, log in using your newly created service account
```shell
rosa login --client-id ... --client-secret ...
```
Then activate your service account
```shell
rosa whoami
```

1. Create a new kubernetes secret with the service account credentials to be referenced later by `ROSAControlPlane`


1. Create a new kubernetes secret with the service account credentials to be referenced later by the `ROSAControlPlane`
```shell
kubectl create secret generic rosa-creds-secret \
--from-literal=ocmClientID='....' \
--from-literal=ocmClientSecret='eyJhbGciOiJIUzI1NiIsI....' \
--from-literal=ocmApiUrl='https://api.openshift.com'
```
Note: to consume the secret without the need to reference it from your `ROSAControlPlane`, name your secret as `rosa-creds-secret` and create it in the CAPA manager namespace (usually `capa-system`)
Note: to consume the secret without the need to reference it from your `ROSAControlPlane`, name your secret `rosa-creds-secret` and create it in the CAPA manager namespace (usually `capa-system`)
```shell
kubectl -n capa-system create secret generic rosa-creds-secret \
--from-literal=ocmClientID='....' \
Expand All @@ -30,132 +44,198 @@ CAPA controller requires service account credentials to be able to provision ROS
```


### Authentication using SSO offline token (DEPRECATED)
The SSO offline token is being deprecated and it is recommended to use service account credentials instead, as described above.
## Creating the cluster

1. Visit https://console.redhat.com/openshift/token to retrieve your SSO offline authentication token
1. Create the `ROSARoleConfig` and `ROSANetwork` resources.

1. Create a credentials secret within the target namespace with the token to be referenced later by `ROSAControlePlane`
```shell
kubectl create secret generic rosa-creds-secret \
--from-literal=ocmToken='eyJhbGciOiJIUzI1NiIsI....' \
--from-literal=ocmApiUrl='https://api.openshift.com'
```
Alternatively, you can edit the CAPA controller deployment to provide the credentials
```shell
kubectl edit deployment -n capa-system capa-controller-manager
```
and add the following environment variables to the manager container
```yaml
env:
- name: OCM_TOKEN
value: "<token>"
- name: OCM_API_URL
value: "https://api.openshift.com" # or https://api.stage.openshift.com
```
The `ROSARoleConfig` automates the creation of the AWS IAM resources required by ROSA HCP clusters:
- **Account roles**: Installer, Support, and Worker IAM roles (e.g. `<prefix>-HCP-ROSA-Installer-Role`)
- **Operator roles**: IAM roles for cluster operators including ingress, image registry, storage, network, kube cloud controller, node pool management, control plane operator, and KMS provider
- **OIDC provider**: A managed OpenID Connect provider used for operator role authentication

### Migration from offline token to service account authentication
The `ROSANetwork` automates the creation of the VPC networking infrastructure via an AWS CloudFormation stack, including:
- A VPC with the specified CIDR block
- Public and private subnet pairs for each availability zone
- Associated networking resources (internet gateway, NAT gateways, route tables)

1. Visit [https://console.redhat.com/iam/service-accounts](https://console.redhat.com/iam/service-accounts) and create a new service account.
Save the following to a file `rosa-role-network.yaml`:

1. If you previously used kubernetes secret to specify the OCM credentials secret, edit the secret:
```shell
kubectl edit secret rosa-creds-secret
```
where you will remove the `ocmToken` credentials and add base64 encoded `ocmClientID` and `ocmClientSecret` credentials like so:
```yaml
apiVersion: v1
data:
ocmApiUrl: aHR0cHM6Ly9hcGkub3BlbnNoaWZ0LmNvbQ==
ocmClientID: Y2xpZW50X2lk...
ocmClientSecret: Y2xpZW50X3NlY3JldA==...
kind: Secret
type: Opaque
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: ROSARoleConfig
metadata:
name: "role-config"
spec:
accountRoleConfig:
prefix: "rosa"
version: "4.19.0"
operatorRoleConfig:
prefix: "rosa"
credentialsSecretRef:
name: rosa-creds-secret
oidcProviderType: Managed
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
Comment on lines +103 to +105
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the --- separator is missing from here

kind: ROSANetwork
metadata:
name: "rosa-vpc"
spec:
region: "us-west-2"
stackName: "rosa-hcp-net"
availabilityZones:
- "us-west-2a"
- "us-west-2b"
- "us-west-2c"
cidrBlock: 10.0.0.0/16
```

1. If you previously used capa manager deployment to specify the OCM offline token as environment variable, edit the manager deployment
```shell
kubectl -n capa-system edit deployment capa-controller-manager
```
and remove the `OCM_TOKEN` and `OCM_API_URL` variables, followed by `kubectl -n capa-system rollout restart deploy capa-controller-manager`. Then create the new default secret in the `capa-system` namespace with
Apply the manifest:

```shell
kubectl -n capa-system create secret generic rosa-creds-secret \
--from-literal=ocmClientID='....' \
--from-literal=ocmClientSecret='eyJhbGciOiJIUzI1NiIsI....' \
--from-literal=ocmApiUrl='https://api.openshift.com'
kubectl apply -f rosa-role-network.yaml
```

## Prerequisites

Follow the guide [here](https://docs.aws.amazon.com/ROSA/latest/userguide/getting-started-hcp.html) up until ["Create a ROSA with HCP Cluster"](https://docs.aws.amazon.com/ROSA/latest/userguide/getting-started-hcp.html#create-hcp-cluster-cli) to install the required tools and setup the prerequisite infrastructure. Once Step 3 is done, you will be ready to proceed with creating a ROSA HCP cluster using cluster-api.
Verify the `ROSARoleConfig` was successfully created. The status should contain the `accountRolesRef`, `oidcID`, `oidcProviderARN` and `operatorRolesRef`:

Note; Skip the "Create the required IAM roles and OpenID Connect configuration" step from the prerequisites url above and use the templates/cluster-template-rosa-role-config.yaml to generate a ROSARoleConfig CR to create the required account roles, operator roles & managed OIDC provider.
```shell
kubectl get rosaroleconfig role-config -o yaml
Comment thread
tinaafitz marked this conversation as resolved.
```

## Creating the cluster
Example expected status:

1. Prepare the environment:
```bash
export OPENSHIFT_VERSION="4.19.0"
export AWS_REGION="us-west-2"
export AWS_AVAILABILITY_ZONE="us-west-2a"
export AWS_ACCOUNT_ID="<account_id>"
export AWS_CREATOR_ARN="<user_arn>" # can be retrieved e.g. using `aws sts get-caller-identity`

# Note: if using templates/cluster-template-rosa.yaml set the below env variables
export OIDC_CONFIG_ID="<oidc_id>" # OIDC config id creating previously with `rosa create oidc-config`
export ACCOUNT_ROLES_PREFIX="ManagedOpenShift-HCP" # prefix used to create account IAM roles with `rosa create account-roles`
export OPERATOR_ROLES_PREFIX="capi-rosa-quickstart" # prefix used to create operator roles with `rosa create operator-roles --prefix <PREFIX_NAME>`

# Note: if using templates/cluster-template-rosa-role-config.yaml set the below env variables
export ACCOUNT_ROLES_PREFIX="capa" # prefix can be change to preferable prefix with max 4 chars
export OPERATOR_ROLES_PREFIX="capa" # prefix can be change to preferable prefix with max 4 chars

# subnet IDs created earlier
export PUBLIC_SUBNET_ID="subnet-0b54a1111111111111"
export PRIVATE_SUBNET_ID="subnet-05e72222222222222"
```yaml
status:
Comment thread
tinaafitz marked this conversation as resolved.
accountRolesRef:
installerRoleARN: arn:aws:iam::123456789012:role/rosa-HCP-ROSA-Installer-Role
supportRoleARN: arn:aws:iam::123456789012:role/rosa-HCP-ROSA-Support-Role
workerRoleARN: arn:aws:iam::123456789012:role/rosa-HCP-ROSA-Worker-Role
conditions:
- lastTransitionTime: "2025-11-03T18:12:09Z"
status: "True"
type: Ready
- lastTransitionTime: "2025-11-03T18:12:09Z"
message: RosaRoleConfig is ready
reason: Created
severity: Info
status: "True"
type: RosaRoleConfigReady
oidcID: anyoidcanyoidctuq4b
oidcProviderARN: arn:aws:iam::123456789012:oidc-provider/oidc.os1.devshift.org/anyoidcanyoidctuq4b
operatorRolesRef:
controlPlaneOperatorARN: arn:aws:iam::123456789012:role/rosa-kube-system-control-plane-operator
imageRegistryARN: arn:aws:iam::123456789012:role/rosa-openshift-image-registry-installer-cloud-credentials
ingressARN: arn:aws:iam::123456789012:role/rosa-openshift-ingress-operator-cloud-credentials
kmsProviderARN: arn:aws:iam::123456789012:role/rosa-kube-system-kms-provider
kubeCloudControllerARN: arn:aws:iam::123456789012:role/rosa-kube-system-kube-controller-manager
networkARN: arn:aws:iam::123456789012:role/rosa-openshift-cloud-network-config-controller-cloud-credentials
nodePoolManagementARN: arn:aws:iam::123456789012:role/rosa-kube-system-capa-controller-manager
storageARN: arn:aws:iam::123456789012:role/rosa-openshift-cluster-csi-drivers-ebs-cloud-credentials
```

1. Render the cluster manifest using the ROSA HCP cluster template:
Verify the `ROSANetwork` was successfully created. The status should contain the created subnets:

a. Using templates/cluster-template-rosa.yaml

Note: The AWS role name must be no more than 64 characters in length. Otherwise an error will be returned. Truncate values exceeding 64 characters.
```shell
clusterctl generate cluster <cluster-name> --from templates/cluster-template-rosa.yaml > rosa-capi-cluster.yaml
kubectl get rosanetwork rosa-vpc -o yaml
Comment thread
tinaafitz marked this conversation as resolved.
```

b. Using templates/cluster-template-rosa-role-config.yaml
```shell
clusterctl generate cluster <cluster-name> --from templates/cluster-template-rosa-role-config.yaml > rosa-capi-cluster.yaml
Example expected status:

```yaml
status:
Comment thread
tinaafitz marked this conversation as resolved.
conditions:
- lastTransitionTime: "2025-11-03T18:15:05Z"
reason: Created
severity: Info
status: "True"
type: ROSANetworkReady
subnets:
- availabilityZone: us-west-2a
privateSubnet: subnet-084ebac3893fc14ff
publicSubnet: subnet-0ec9fa706a26519ee
- availabilityZone: us-west-2b
privateSubnet: subnet-07727689065612f6e
publicSubnet: subnet-0bb2220505b16f606
- availabilityZone: us-west-2c
privateSubnet: subnet-002e071b9624727f3
publicSubnet: subnet-049fa2a528d896356
```

1. Save the following to a file `rosa-cluster.yaml`:

1. If a credentials secret was created earlier, edit `ROSAControlPlane` to reference it:
```yaml
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
name: "rosa-hcp-1"
spec:
clusterNetwork:
pods:
cidrBlocks: ["192.168.0.0/16"]
infrastructureRef:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: ROSACluster
name: "rosa-hcp-1"
controlPlaneRef:
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: ROSAControlPlane
name: "rosa-hcp-1-control-plane"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the --- separator is missing from here

---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: ROSACluster
metadata:
name: "rosa-hcp-1"
spec: {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the --- separator is missing from here

---
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: ROSAControlPlane
metadata:
name: "capi-rosa-quickstart-control-plane"
name: "rosa-hcp-1-control-plane"
spec:
credentialsSecretRef:
name: rosa-creds-secret
...
rosaClusterName: rosa-hcp-1
domainPrefix: rosa-hcp
rosaRoleConfigRef:
name: role-config
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name: role-config
name: role-config # reference to the ROSARoleConfig created above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

version: "4.19.0"
region: "us-west-2"
rosaNetworkRef:
name: "rosa-vpc"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
name: "rosa-vpc"
name: "rosa-vpc" # reference to the ROSANetwork created above

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

network:
machineCIDR: "10.0.0.0/16"
podCIDR: "10.128.0.0/14"
serviceCIDR: "172.30.0.0/16"
defaultMachinePoolSpec:
instanceType: "m5.xlarge"
autoscaling:
maxReplicas: 6
minReplicas: 3
additionalTags:
env: "demo"
```

1. Provide an AWS identity reference
Apply the manifest:

```shell
kubectl apply -f rosa-cluster.yaml
```

1. Provide an AWS identity reference by adding an `identityRef` to the `ROSAControlPlane` spec:

```yaml
apiVersion: controlplane.cluster.x-k8s.io/v1beta2
kind: ROSAControlPlane
metadata:
name: "capi-rosa-quickstart-control-plane"
name: "rosa-hcp-1-control-plane"
spec:
identityRef:
kind: <IdentityType>
name: <IdentityName>
...
```

Otherwise, make sure the following `AWSClusterControllerIdentity` singleton exists in your management cluster:
Otherwise, make sure the following `AWSClusterControllerIdentity` singleton exists in your management cluster. Save it to a file and apply it:

```yaml
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: AWSClusterControllerIdentity
Expand All @@ -165,11 +245,34 @@ Note; Skip the "Create the required IAM roles and OpenID Connect configuration"
allowedNamespaces: {} # matches all namespaces
```

```shell
kubectl apply -f <filename>.yaml
```

see [Multi-tenancy](../multitenancy.md) for more details

1. Finally apply the manifest to create your ROSA cluster:
1. Check the `ROSAControlPlane` status:

```shell
kubectl apply -f rosa-capi-cluster.yaml
kubectl get ROSAControlPlane rosa-hcp-1-control-plane

NAME CLUSTER READY
rosa-hcp-1-control-plane rosa-hcp-1 true
```

The ROSA HCP cluster can take around 40 minutes to be fully provisioned.

1. After provisioning has completed, verify the `ROSAMachinePool` resources were successfully created:

```shell
kubectl get ROSAMachinePool

NAME READY REPLICAS
workers-0 true 1
workers-1 true 1
workers-2 true 1
```

**Note:** The number of default `ROSAMachinePool` resources corresponds to the number of availability zones configured.

Comment thread
tinaafitz marked this conversation as resolved.
see [ROSAControlPlane CRD Reference](https://cluster-api-aws.sigs.k8s.io/crd/#controlplane.cluster.x-k8s.io/v1beta2.ROSAControlPlane) for all possible configurations.