|  | 
|  | 1 | +--- | 
|  | 2 | +description: Extract OpenShift installer from release image and create an OCP cluster | 
|  | 3 | +argument-hint: [release-image] [platform] [options] | 
|  | 4 | +--- | 
|  | 5 | + | 
|  | 6 | +## Name | 
|  | 7 | +openshift:create-cluster | 
|  | 8 | + | 
|  | 9 | +## Synopsis | 
|  | 10 | +``` | 
|  | 11 | +/openshift:create-cluster [release-image] [platform] [options] | 
|  | 12 | +``` | 
|  | 13 | + | 
|  | 14 | +## Description | 
|  | 15 | + | 
|  | 16 | +The `create-cluster` command automates the process of extracting the OpenShift installer from a release image (if not already present) and creating a new OpenShift Container Platform (OCP) cluster. It handles installer extraction from OCP release images, configuration preparation, and cluster creation in a streamlined workflow. | 
|  | 17 | + | 
|  | 18 | +This command is useful for: | 
|  | 19 | +- Setting up development/test clusters quickly | 
|  | 20 | + | 
|  | 21 | +## ⚠️ When to Use This Tool | 
|  | 22 | + | 
|  | 23 | +**IMPORTANT**: This is a last resort tool for advanced use cases. For most development workflows, you should use one of these better alternatives: | 
|  | 24 | + | 
|  | 25 | +### Recommended Alternatives | 
|  | 26 | + | 
|  | 27 | +1. **Cluster Bot**: Request ephemeral test clusters without managing infrastructure | 
|  | 28 | +   - No cloud credentials needed | 
|  | 29 | +   - Supports dependent PR testing | 
|  | 30 | +   - Automatically cleaned up | 
|  | 31 | + | 
|  | 32 | +2. **Gangway** | 
|  | 33 | + | 
|  | 34 | +3. **Multi-PR Testing in CI**: Test multiple dependent PRs together using `/test-with` commands | 
|  | 35 | + | 
|  | 36 | +### When to Use create-cluster | 
|  | 37 | + | 
|  | 38 | +Only use this command when: | 
|  | 39 | +- You need full control over cluster configuration | 
|  | 40 | +- You're testing installer changes that aren't suitable for CI | 
|  | 41 | +- You need a long-lived development cluster on your own cloud account | 
|  | 42 | +- The alternatives don't meet your specific requirements | 
|  | 43 | + | 
|  | 44 | +**Note**: This command requires significant setup (cloud credentials, pull secrets, DNS configuration, understanding of OCP versions). If you're new to OpenShift development, start with Cluster Bot or Gangway instead. | 
|  | 45 | + | 
|  | 46 | +## Prerequisites | 
|  | 47 | + | 
|  | 48 | +Before using this command, ensure you have: | 
|  | 49 | + | 
|  | 50 | +1. **OpenShift CLI (`oc`)**: Required to extract the installer from the release image | 
|  | 51 | +   - Install from: https://mirror.openshift.com/pub/openshift-v4/clients/ocp/ | 
|  | 52 | +   - Or use your package manager: `brew install openshift-cli` (macOS) | 
|  | 53 | +   - Verify with: `oc version` | 
|  | 54 | + | 
|  | 55 | +2. **Cloud Provider Credentials** configured for your chosen platform: | 
|  | 56 | +   - **AWS**: `~/.aws/credentials` configured with appropriate permissions | 
|  | 57 | +   - **Azure**: Azure CLI authenticated (`az login`) | 
|  | 58 | +   - **GCP**: Service account key configured | 
|  | 59 | +   - **vSphere**: vCenter credentials | 
|  | 60 | +   - **OpenStack**: clouds.yaml configured | 
|  | 61 | + | 
|  | 62 | +3. **Pull Secret**: Download from [Red Hat Console](https://console.redhat.com/openshift/install/pull-secret) | 
|  | 63 | + | 
|  | 64 | +4. **Domain/DNS Configuration**: | 
|  | 65 | +   - AWS: Route53 hosted zone | 
|  | 66 | +   - Other platforms: Appropriate DNS setup | 
|  | 67 | + | 
|  | 68 | +## Arguments | 
|  | 69 | + | 
|  | 70 | +The command accepts arguments in multiple ways: | 
|  | 71 | + | 
|  | 72 | +### Positional Arguments | 
|  | 73 | +``` | 
|  | 74 | +/openshift:create-cluster [release-image] [platform] | 
|  | 75 | +``` | 
|  | 76 | + | 
|  | 77 | +### Interactive Mode | 
|  | 78 | +If arguments are not provided, the command will interactively prompt for: | 
|  | 79 | +- OpenShift release image | 
|  | 80 | +- Platform (aws, azure, gcp, vsphere, openstack, none/baremetal) | 
|  | 81 | +- Cluster name | 
|  | 82 | +- Base domain | 
|  | 83 | +- Pull secret location | 
|  | 84 | + | 
|  | 85 | +### Argument Details | 
|  | 86 | + | 
|  | 87 | +- **release-image** (required): OpenShift release image to extract the installer from | 
|  | 88 | +  - Production release: `quay.io/openshift-release-dev/ocp-release:4.21.0-ec.2-x86_64` | 
|  | 89 | +  - CI build: `registry.ci.openshift.org/ocp/release:4.21.0-0.ci-2025-10-27-031915` | 
|  | 90 | +  - Stable release: `quay.io/openshift-release-dev/ocp-release:4.20.1-x86_64` | 
|  | 91 | +  - The command will prompt for this if not provided | 
|  | 92 | + | 
|  | 93 | +- **platform** (optional): Target platform for the cluster | 
|  | 94 | +  - `aws`: Amazon Web Services | 
|  | 95 | +  - `azure`: Microsoft Azure | 
|  | 96 | +  - `gcp`: Google Cloud Platform | 
|  | 97 | +  - `vsphere`: VMware vSphere | 
|  | 98 | +  - `openstack`: OpenStack | 
|  | 99 | +  - `none`: Bare metal / platform-agnostic | 
|  | 100 | +  - Default: Prompts user to select | 
|  | 101 | + | 
|  | 102 | +- **cluster-name** (optional): Name for the cluster | 
|  | 103 | +  - Default: `ocp-cluster` | 
|  | 104 | +  - Must be DNS-compatible | 
|  | 105 | + | 
|  | 106 | +- **base-domain** (required): Base domain for the cluster | 
|  | 107 | +  - Example: `example.com` → Cluster API will be `api.{cluster-name}.{base-domain}` | 
|  | 108 | + | 
|  | 109 | +- **pull-secret** (optional): Path to pull secret file | 
|  | 110 | +  - Default: `~/pull-secret.txt` | 
|  | 111 | + | 
|  | 112 | +- **installer-dir** (optional): Directory to store/find installer binaries | 
|  | 113 | +  - Default: `~/.openshift-installers` | 
|  | 114 | + | 
|  | 115 | +## Implementation | 
|  | 116 | + | 
|  | 117 | +The command performs the following steps: | 
|  | 118 | + | 
|  | 119 | +### 1. Validate Prerequisites | 
|  | 120 | + | 
|  | 121 | +Check that required tools and credentials are available: | 
|  | 122 | +- Verify `oc` CLI is installed and available | 
|  | 123 | +- Verify cloud provider credentials are configured (if applicable) | 
|  | 124 | +- Confirm domain/DNS requirements | 
|  | 125 | + | 
|  | 126 | +If any prerequisites are missing, provide clear instructions on how to configure them. | 
|  | 127 | + | 
|  | 128 | +### 2. Get Release Image from User | 
|  | 129 | + | 
|  | 130 | +If not provided as an argument, **prompt the user** for the OpenShift release image: | 
|  | 131 | + | 
|  | 132 | +``` | 
|  | 133 | +Please provide the OpenShift release image: | 
|  | 134 | +
 | 
|  | 135 | +Examples: | 
|  | 136 | +  - Production release: quay.io/openshift-release-dev/ocp-release:4.21.0-ec.2-x86_64 | 
|  | 137 | +  - CI build:          registry.ci.openshift.org/ocp/release:4.21.0-0.ci-2025-10-27-031915 | 
|  | 138 | +  - Stable release:    quay.io/openshift-release-dev/ocp-release:4.20.1-x86_64 | 
|  | 139 | +
 | 
|  | 140 | +Release image: | 
|  | 141 | +``` | 
|  | 142 | + | 
|  | 143 | +Store the user's input as `$RELEASE_IMAGE`. | 
|  | 144 | + | 
|  | 145 | +**Extract version from image** for naming: | 
|  | 146 | +```bash | 
|  | 147 | +# Parse version from image tag (e.g., "4.21.0-ec.2" or "4.21.0-0.ci-2025-10-27-031915") | 
|  | 148 | +VERSION=$(echo "$RELEASE_IMAGE" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+[^"]*' | head -1) | 
|  | 149 | +``` | 
|  | 150 | + | 
|  | 151 | +### 3. Determine Installer Location and Extract if Needed | 
|  | 152 | + | 
|  | 153 | +```bash | 
|  | 154 | +INSTALLER_DIR="${installer-dir:-$HOME/.openshift-installers}" | 
|  | 155 | +INSTALLER_PATH="$INSTALLER_DIR/openshift-install-${VERSION}" | 
|  | 156 | +``` | 
|  | 157 | + | 
|  | 158 | +**Check if installer directory exists**: | 
|  | 159 | +- If `$INSTALLER_DIR` does not exist: | 
|  | 160 | +  - **Ask user for confirmation**: "The installer directory `$INSTALLER_DIR` does not exist. Would you like to create it?" | 
|  | 161 | +  - If user confirms (yes): Create the directory with `mkdir -p "$INSTALLER_DIR"` | 
|  | 162 | +  - If user declines (no): Exit with error message suggesting an alternative path | 
|  | 163 | + | 
|  | 164 | +**Check if the installer already exists** at `$INSTALLER_PATH`: | 
|  | 165 | +- If present: Verify it works with `"$INSTALLER_PATH" version` | 
|  | 166 | +  - If version matches the release image: Skip extraction | 
|  | 167 | +  - If different or fails: Proceed with extraction | 
|  | 168 | +- If not present: Proceed with extraction | 
|  | 169 | + | 
|  | 170 | +**Extract installer from release image**: | 
|  | 171 | + | 
|  | 172 | +1. **Verify `oc` CLI is available**: | 
|  | 173 | +   ```bash | 
|  | 174 | +   if ! command -v oc &> /dev/null; then | 
|  | 175 | +       echo "Error: 'oc' CLI not found. Please install the OpenShift CLI." | 
|  | 176 | +       exit 1 | 
|  | 177 | +   fi | 
|  | 178 | +   ``` | 
|  | 179 | + | 
|  | 180 | +2. **Extract the installer binary**: | 
|  | 181 | +   ```bash | 
|  | 182 | +   oc adm release extract \ | 
|  | 183 | +       --tools \ | 
|  | 184 | +       --from="$RELEASE_IMAGE" \ | 
|  | 185 | +       --to="$INSTALLER_DIR" | 
|  | 186 | +   ``` | 
|  | 187 | + | 
|  | 188 | +   This extracts the `openshift-install` binary and other tools from the release image. | 
|  | 189 | + | 
|  | 190 | +3. **Locate and rename the extracted installer**: | 
|  | 191 | +   ```bash | 
|  | 192 | +   # The extract command creates a tar.gz with the tools | 
|  | 193 | +   # Find the most recently extracted openshift-install tar (compatible with both GNU and BSD find) | 
|  | 194 | +   INSTALLER_TAR=$(find "$INSTALLER_DIR" -name "openshift-install-*.tar.gz" -type f -exec ls -t {} + | head -1) | 
|  | 195 | + | 
|  | 196 | +   # Extract from tar and rename | 
|  | 197 | +   cd "$INSTALLER_DIR" | 
|  | 198 | +   tar -xzf "$INSTALLER_TAR" openshift-install | 
|  | 199 | +   mv openshift-install "openshift-install-${VERSION}" | 
|  | 200 | +   chmod +x "openshift-install-${VERSION}" | 
|  | 201 | + | 
|  | 202 | +   # Clean up the tar file | 
|  | 203 | +   rm "$INSTALLER_TAR" | 
|  | 204 | +   ``` | 
|  | 205 | + | 
|  | 206 | +4. **Verify the installer**: | 
|  | 207 | +   ```bash | 
|  | 208 | +   "$INSTALLER_PATH" version | 
|  | 209 | +   ``` | 
|  | 210 | + | 
|  | 211 | +   Expected output should show the version matching `$VERSION`. | 
|  | 212 | + | 
|  | 213 | +### 4. Prepare Installation Directory | 
|  | 214 | + | 
|  | 215 | +Create a clean installation directory: | 
|  | 216 | +```bash | 
|  | 217 | +INSTALL_DIR="${cluster-name}-install-$(date +%Y%m%d-%H%M%S)" | 
|  | 218 | +mkdir -p "$INSTALL_DIR" | 
|  | 219 | +cd "$INSTALL_DIR" | 
|  | 220 | +``` | 
|  | 221 | + | 
|  | 222 | +### 5. Generate install-config.yaml | 
|  | 223 | + | 
|  | 224 | +Run the installer's interactive config generation: | 
|  | 225 | +```bash | 
|  | 226 | +"$INSTALLER_PATH" create install-config --dir=. | 
|  | 227 | +``` | 
|  | 228 | + | 
|  | 229 | +This will interactively prompt for: | 
|  | 230 | +- SSH public key | 
|  | 231 | +- Platform selection | 
|  | 232 | +- Platform-specific details (region, instance types, etc.) | 
|  | 233 | +- Base domain | 
|  | 234 | +- Cluster name | 
|  | 235 | +- Pull secret | 
|  | 236 | + | 
|  | 237 | +**IMPORTANT**: Always backup install-config.yaml before proceeding: | 
|  | 238 | +```bash | 
|  | 239 | +cp install-config.yaml install-config.yaml.backup | 
|  | 240 | +``` | 
|  | 241 | + | 
|  | 242 | +The installer consumes this file, so the backup is essential for reference. | 
|  | 243 | + | 
|  | 244 | +### 6. Create the Cluster | 
|  | 245 | + | 
|  | 246 | +Run the installer: | 
|  | 247 | +```bash | 
|  | 248 | +"$INSTALLER_PATH" create cluster --dir=. | 
|  | 249 | +``` | 
|  | 250 | + | 
|  | 251 | +Monitor the installation progress. This typically takes 30-45 minutes. | 
|  | 252 | + | 
|  | 253 | +### 7. Post-Installation | 
|  | 254 | + | 
|  | 255 | +Once installation completes: | 
|  | 256 | + | 
|  | 257 | +1. **Display kubeconfig location**: | 
|  | 258 | +   ``` | 
|  | 259 | +   Kubeconfig: $INSTALL_DIR/auth/kubeconfig | 
|  | 260 | +   ``` | 
|  | 261 | + | 
|  | 262 | +2. **Display cluster credentials**: | 
|  | 263 | +   ``` | 
|  | 264 | +   Console URL: https://console-openshift-console.apps.${cluster-name}.${base-domain} | 
|  | 265 | +   Username: kubeadmin | 
|  | 266 | +   Password: (from $INSTALL_DIR/auth/kubeadmin-password) | 
|  | 267 | +   ``` | 
|  | 268 | + | 
|  | 269 | +3. **Export KUBECONFIG** (offer to add to shell profile): | 
|  | 270 | +   ```bash | 
|  | 271 | +   export KUBECONFIG="$PWD/auth/kubeconfig" | 
|  | 272 | +   ``` | 
|  | 273 | + | 
|  | 274 | +4. **Verify cluster access**: | 
|  | 275 | +   ```bash | 
|  | 276 | +   oc get nodes | 
|  | 277 | +   oc get co  # cluster operators | 
|  | 278 | +   ``` | 
|  | 279 | + | 
|  | 280 | +5. **Save cluster information** to a summary file: | 
|  | 281 | +   ``` | 
|  | 282 | +   Cluster: ${cluster-name} | 
|  | 283 | +   Version: ${VERSION} | 
|  | 284 | +   Release Image: ${RELEASE_IMAGE} | 
|  | 285 | +   Platform: ${platform} | 
|  | 286 | +   Console: https://console-openshift-console.apps.${cluster-name}.${base-domain} | 
|  | 287 | +   API: https://api.${cluster-name}.${base-domain}:6443 | 
|  | 288 | +   Kubeconfig: $INSTALL_DIR/auth/kubeconfig | 
|  | 289 | +   Created: $(date) | 
|  | 290 | +   ``` | 
|  | 291 | + | 
|  | 292 | +### 8. Error Handling | 
|  | 293 | + | 
|  | 294 | +If installation fails: | 
|  | 295 | + | 
|  | 296 | +1. **Capture logs**: Installation logs are in `.openshift_install.log` | 
|  | 297 | +2. **Provide diagnostics**: Check common failure points: | 
|  | 298 | +   - Quota limits on cloud provider | 
|  | 299 | +   - DNS configuration issues | 
|  | 300 | +   - Invalid pull secret | 
|  | 301 | +   - Network/firewall issues | 
|  | 302 | +3. **Cleanup guidance**: Inform user about cleanup: | 
|  | 303 | +   ```bash | 
|  | 304 | +   "$INSTALLER_PATH" destroy cluster --dir=. | 
|  | 305 | +   ``` | 
|  | 306 | + | 
|  | 307 | +## Examples | 
|  | 308 | + | 
|  | 309 | +### Example 1: Basic cluster creation (interactive) | 
|  | 310 | +``` | 
|  | 311 | +/openshift:create-cluster | 
|  | 312 | +``` | 
|  | 313 | +The command will prompt for release image and all necessary information. | 
|  | 314 | + | 
|  | 315 | +### Example 2: Create AWS cluster with production release | 
|  | 316 | +``` | 
|  | 317 | +/openshift:create-cluster quay.io/openshift-release-dev/ocp-release:4.21.0-ec.2-x86_64 aws | 
|  | 318 | +``` | 
|  | 319 | + | 
|  | 320 | +### Example 3: Create cluster with CI build | 
|  | 321 | +``` | 
|  | 322 | +/openshift:create-cluster registry.ci.openshift.org/ocp/release:4.21.0-0.ci-2025-10-27-031915 gcp | 
|  | 323 | +``` | 
|  | 324 | + | 
|  | 325 | +## Cleanup | 
|  | 326 | + | 
|  | 327 | +To destroy the cluster after testing: | 
|  | 328 | +```bash | 
|  | 329 | +cd $INSTALL_DIR | 
|  | 330 | +"$INSTALLER_PATH" destroy cluster --dir=. | 
|  | 331 | +``` | 
|  | 332 | + | 
|  | 333 | +**WARNING**: This will permanently delete all cluster resources. | 
|  | 334 | + | 
|  | 335 | +## Common Issues | 
|  | 336 | + | 
|  | 337 | +1. **Pull secret not found**: | 
|  | 338 | +   - Download from https://console.redhat.com/openshift/install/pull-secret | 
|  | 339 | +   - Save to `~/pull-secret.txt` | 
|  | 340 | + | 
|  | 341 | +2. **Insufficient cloud quotas**: | 
|  | 342 | +   - Check cloud provider quota limits | 
|  | 343 | +   - Request quota increase if needed | 
|  | 344 | + | 
|  | 345 | +3. **DNS issues**: | 
|  | 346 | +   - Ensure base domain is properly configured | 
|  | 347 | +   - For AWS, verify Route53 hosted zone exists | 
|  | 348 | + | 
|  | 349 | +4. **SSH key not found**: | 
|  | 350 | +   - Generate with `ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa` | 
|  | 351 | + | 
|  | 352 | +5. **Unauthorized access to release image**: | 
|  | 353 | +   - Error: `error: unable to read image quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256:...: unauthorized: access to the requested resource is not authorized` | 
|  | 354 | +   - For `quay.io/openshift-release-dev/ocp-v4.0-art-dev` you can get the pull secret from https://console.redhat.com/openshift/install/pull-secret and save it in a file and provide it here. | 
|  | 355 | + | 
|  | 356 | +## Security Considerations | 
|  | 357 | + | 
|  | 358 | +- **Pull secret**: Contains authentication for Red Hat registries. Keep secure. | 
|  | 359 | +- **kubeadmin password**: Stored in plaintext in auth directory. Rotate after cluster creation. | 
|  | 360 | +- **kubeconfig**: Contains cluster admin credentials. Protect appropriately. | 
|  | 361 | +- **Cloud credentials**: Never commit to version control. | 
|  | 362 | + | 
|  | 363 | +## Return Value | 
|  | 364 | + | 
|  | 365 | +- **Success**: Returns 0 and displays cluster information including kubeconfig path | 
|  | 366 | +- **Failure**: Returns non-zero and displays error diagnostics | 
|  | 367 | + | 
|  | 368 | +## See Also | 
|  | 369 | + | 
|  | 370 | +- OpenShift Documentation: https://docs.openshift.com/container-platform/latest/installing/ | 
|  | 371 | +- OpenShift Install: https://mirror.openshift.com/pub/openshift-v4/clients/ocp/ | 
|  | 372 | +- Platform-specific installation guides | 
|  | 373 | + | 
|  | 374 | +## Arguments: | 
|  | 375 | + | 
|  | 376 | +- **$1** (release-image): OpenShift release image to extract the installer from (e.g., `quay.io/openshift-release-dev/ocp-release:4.21.0-ec.2-x86_64`) | 
|  | 377 | +- **$2** (platform): Target cloud platform for cluster deployment (aws, azure, gcp, vsphere, openstack, none) | 
0 commit comments