From af3a557b5acbe906efdc72de6e4531b50b6b4e74 Mon Sep 17 00:00:00 2001 From: stafaniasaju Date: Wed, 30 Jul 2025 18:10:39 +0200 Subject: [PATCH 01/83] feat: openshift cluster deployment modules(dev code) --- modules/ansible/README.md | 47 ++++ modules/ansible/main.tf | 223 +++++++++++++++ modules/ansible/outputs.tf | 0 .../ansible_exec.sh.tftpl | 31 ++ .../playbook-configure-ocp-cluster.yml.tftpl | 169 +++++++++++ ...ook-create-ocp-cluster-manifests.yml.tftpl | 80 ++++++ .../playbook-deploy-ocp-cluster.yml.tftpl | 48 ++++ .../ansible/templates-ansible/inventory.tftpl | 1 + modules/ansible/variables.tf | 98 +++++++ modules/ansible/versions.tf | 9 + solutions/standard-openshift/main.tf | 173 ++++++++++++ solutions/standard-openshift/outputs.tf | 0 solutions/standard-openshift/provider.tf | 105 +++++++ solutions/standard-openshift/variables.tf | 266 ++++++++++++++++++ solutions/standard-openshift/versions.tf | 22 ++ 15 files changed, 1272 insertions(+) create mode 100644 modules/ansible/README.md create mode 100644 modules/ansible/main.tf create mode 100644 modules/ansible/outputs.tf create mode 100644 modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl create mode 100644 modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl create mode 100644 modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl create mode 100644 modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl create mode 100644 modules/ansible/templates-ansible/inventory.tftpl create mode 100644 modules/ansible/variables.tf create mode 100644 modules/ansible/versions.tf create mode 100644 solutions/standard-openshift/main.tf create mode 100644 solutions/standard-openshift/outputs.tf create mode 100644 solutions/standard-openshift/provider.tf create mode 100644 solutions/standard-openshift/variables.tf create mode 100644 solutions/standard-openshift/versions.tf diff --git a/modules/ansible/README.md b/modules/ansible/README.md new file mode 100644 index 00000000..45cf3a2f --- /dev/null +++ b/modules/ansible/README.md @@ -0,0 +1,47 @@ +# Module ansible + + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.9.0 | +| [random](#requirement\_random) | 3.6.1 | + +### Modules + +No modules. + +### Resources + +| Name | Type | +|------|------| +| [random_id.filename](https://registry.terraform.io/providers/hashicorp/random/3.6.1/docs/resources/id) | resource | +| [terraform_data.execute_playbooks](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | +| [terraform_data.execute_playbooks_with_vault](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | +| [terraform_data.setup_ansible_host](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | +| [terraform_data.trigger_ansible_vars](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [ansible\_host\_or\_ip](#input\_ansible\_host\_or\_ip) | Private IP of virtual server instance running RHEL OS on which ansible will be installed and configured to act as central ansible node. | `string` | n/a | yes | +| [ansible\_vault\_password](#input\_ansible\_vault\_password) | Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]\_{\|}~. | `string` | `null` | no | +| [bastion\_host\_ip](#input\_bastion\_host\_ip) | Jump/Bastion server public IP address to reach the ansible host which has private IP. | `string` | n/a | yes | +| [configure\_ansible\_host](#input\_configure\_ansible\_host) | If set to true, bash script will be executed to install and configure the collections and packages on ansible node. | `bool` | n/a | yes | +| [dst\_inventory\_file\_name](#input\_dst\_inventory\_file\_name) | Name for the inventory file to be generated on the Ansible host. | `string` | n/a | yes | +| [dst\_playbook\_file\_name](#input\_dst\_playbook\_file\_name) | Name for the playbook file to be generated on the Ansible host. | `string` | n/a | yes | +| [dst\_script\_file\_name](#input\_dst\_script\_file\_name) | Name for the bash file to be generated on the Ansible host. | `string` | n/a | yes | +| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | `null` | no | +| [inventory\_template\_vars](#input\_inventory\_template\_vars) | Map values for the inventory template. | `map(any)` | n/a | yes | +| [playbook\_template\_vars](#input\_playbook\_template\_vars) | Map values for the ansible playbook template. | `map(any)` | n/a | yes | +| [src\_inventory\_template\_name](#input\_src\_inventory\_template\_name) | Name of the inventory template file located within the 'templates-ansible' directory. | `string` | n/a | yes | +| [src\_playbook\_template\_name](#input\_src\_playbook\_template\_name) | Name of the playbook template file located within the 'templates-ansible' directory. | `string` | n/a | yes | +| [src\_script\_template\_name](#input\_src\_script\_template\_name) | Name of the bash script template file located within the 'templates-ansible' directory. | `string` | n/a | yes | +| [ssh\_private\_key](#input\_ssh\_private\_key) | Private SSH key used to login to jump/bastion server, also the ansible host and all the hosts on which tasks will be executed. This key will be written temporarily on ansible host and deleted after execution. | `string` | n/a | yes | + +### Outputs + +No outputs. + diff --git a/modules/ansible/main.tf b/modules/ansible/main.tf new file mode 100644 index 00000000..ba493813 --- /dev/null +++ b/modules/ansible/main.tf @@ -0,0 +1,223 @@ +locals { + src_ansible_templates_dir = "${path.module}/templates-ansible" + ansible_node_config_script = "${path.module}/ansible_node_packages.sh" + dst_files_dir = "/root/terraform_files" + + src_script_tftpl_path = "${local.src_ansible_templates_dir}/${var.src_script_template_name}" + dst_script_file_path = "${local.dst_files_dir}/${var.dst_script_file_name}" + src_playbook_tftpl_path = "${local.src_ansible_templates_dir}/${var.src_playbook_template_name}" + dst_playbook_file_path = "${local.dst_files_dir}/${var.dst_playbook_file_name}" + src_inventory_tftpl_path = "${local.src_ansible_templates_dir}/${var.src_inventory_template_name}" + dst_inventory_file_path = "${local.dst_files_dir}/${var.dst_inventory_file_name}" + ibmcloud_api_key = var.ibmcloud_api_key == null ? "" : nonsensitive(var.ibmcloud_api_key) +} + +resource "random_id" "filename" { + byte_length = 2 # 4 characters when encoded in base32, which will give you a lowercase alphabetic string +} + +locals { + private_key_file = "/root/.ssh/id_rsa_${substr(random_id.filename.b64_url, 0, 4)}" +} +############################################################## +# 1. Execute shell script to install ansible roles/collections +############################################################## + +resource "terraform_data" "setup_ansible_host" { + count = var.configure_ansible_host ? 1 : 0 + + connection { + type = "ssh" + user = "root" + bastion_host = var.bastion_host_ip + host = var.ansible_host_or_ip + private_key = var.ssh_private_key + agent = false + timeout = "5m" + } + + # Create terraform scripts directory + provisioner "remote-exec" { + inline = ["mkdir -p ${local.dst_files_dir}", "chmod 777 ${local.dst_files_dir}", ] + } + + # Copy ansible_node_packages.sh shell file to ansible host + provisioner "file" { + source = local.ansible_node_config_script + destination = "${local.dst_files_dir}/ansible_node_packages.sh" + } + + # Execute ansible_node_packages.sh shell script to configure ansible host + provisioner "remote-exec" { + inline = [ + "chmod +x ${local.dst_files_dir}/ansible_node_packages.sh", + "${local.dst_files_dir}/ansible_node_packages.sh", + ] + } +} + +############################################################## +# 2. Execute ansible playbooks +############################################################## + +resource "terraform_data" "trigger_ansible_vars" { + input = [var.playbook_template_vars, var.inventory_template_vars] +} + +resource "terraform_data" "execute_playbooks" { + depends_on = [terraform_data.setup_ansible_host] + count = var.ansible_vault_password != null ? 0 : 1 + + connection { + type = "ssh" + user = "root" + bastion_host = var.bastion_host_ip + host = var.ansible_host_or_ip + private_key = var.ssh_private_key + agent = false + timeout = "5m" + } + + triggers_replace = terraform_data.trigger_ansible_vars + + # Create terraform scripts directory + provisioner "remote-exec" { + inline = ["mkdir -p ${local.dst_files_dir}", "chmod 777 ${local.dst_files_dir}", ] + } + + # Copy and create ansible playbook template file on ansible host + provisioner "file" { + content = templatefile(local.src_playbook_tftpl_path, var.playbook_template_vars) + destination = local.dst_playbook_file_path + } + + # Copy and create ansible inventory template file on ansible host + provisioner "file" { + content = templatefile(local.src_inventory_tftpl_path, var.inventory_template_vars) + destination = local.dst_inventory_file_path + } + + # Copy and create ansible shell template file which will trigger the playbook on ansible host + provisioner "file" { + content = templatefile(local.src_script_tftpl_path, + { + "ansible_playbook_file" : local.dst_playbook_file_path, + "ansible_log_path" : local.dst_files_dir, + "ansible_inventory" : local.dst_inventory_file_path, + "ansible_private_key_file" : local.private_key_file + }) + destination = local.dst_script_file_path + } + + # Write ssh user's ssh private key + provisioner "remote-exec" { + inline = [ + "mkdir -p /root/.ssh/", + "chmod 700 /root/.ssh", + "echo '${var.ssh_private_key}' > ${local.private_key_file}", + "chmod 600 ${local.private_key_file}", + ] + } + + # Execute bash shell script to run ansible playbooks + provisioner "remote-exec" { + inline = [ + "chmod +x ${local.dst_script_file_path}", + "export IBMCLOUD_API_KEY=${local.ibmcloud_api_key} && ${local.dst_script_file_path}", + ] + } + + # Again delete private ssh key + provisioner "remote-exec" { + inline = [ + "rm -rf ${local.private_key_file}" + ] + } +} + +resource "terraform_data" "execute_playbooks_with_vault" { + depends_on = [terraform_data.setup_ansible_host] + count = var.ansible_vault_password != null ? 1 : 0 + + connection { + type = "ssh" + user = "root" + bastion_host = var.bastion_host_ip + host = var.ansible_host_or_ip + private_key = var.ssh_private_key + agent = false + timeout = "5m" + } + + triggers_replace = terraform_data.trigger_ansible_vars + + # Create terraform scripts directory + provisioner "remote-exec" { + inline = ["mkdir -p ${local.dst_files_dir}", "chmod 777 ${local.dst_files_dir}", ] + } + + # Copy and create ansible playbook template file on ansible host + provisioner "file" { + content = templatefile(local.src_playbook_tftpl_path, var.playbook_template_vars) + destination = local.dst_playbook_file_path + } + + ######### Encrypting the ansible playbook file with sensitive information using ansible vault ######### + provisioner "remote-exec" { + inline = [ + "echo ${var.ansible_vault_password} > password_file", + "ansible-vault encrypt ${local.dst_playbook_file_path} --vault-password-file password_file" + ] + } + + # Copy and create ansible inventory template file on ansible host + provisioner "file" { + content = templatefile(local.src_inventory_tftpl_path, var.inventory_template_vars) + destination = local.dst_inventory_file_path + } + + # Copy and create ansible shell template file which will trigger the playbook on ansible host + provisioner "file" { + content = templatefile(local.src_script_tftpl_path, + { + "ansible_playbook_file" : local.dst_playbook_file_path, + "ansible_log_path" : local.dst_files_dir, + "ansible_inventory" : local.dst_inventory_file_path, + "ansible_private_key_file" : local.private_key_file + }) + destination = local.dst_script_file_path + } + + # Write ssh user's ssh private key + provisioner "remote-exec" { + inline = [ + "mkdir -p /root/.ssh/", + "chmod 700 /root/.ssh", + "echo '${var.ssh_private_key}' > ${local.private_key_file}", + "chmod 600 ${local.private_key_file}", + ] + } + + # Execute bash shell script to run ansible playbooks + provisioner "remote-exec" { + inline = [ + "chmod +x ${local.dst_script_file_path}", + "export IBMCLOUD_API_KEY=${local.ibmcloud_api_key} && ${local.dst_script_file_path}", + ] + } + + # Again delete Ansible Vault password used to encrypt the var + # files with sensitive information and private ssh key + provisioner "remote-exec" { + inline = [ + "rm -rf password_file", + "rm -rf ${local.private_key_file}" + ] + } +} + + +moved { + from = terraform_data.setup_ansible_host + to = terraform_data.setup_ansible_host[0] +} diff --git a/modules/ansible/outputs.tf b/modules/ansible/outputs.tf new file mode 100644 index 00000000..e69de29b diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl new file mode 100644 index 00000000..80f2b4ba --- /dev/null +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl @@ -0,0 +1,31 @@ +#!/bin/bash + +### Using input variables from terraform +ansible_playbook=${ansible_playbook_file} +ansible_log_path=${ansible_log_path} +ansible_inventory=${ansible_inventory} +ansible_private_key_file=${ansible_private_key_file} + +ansible_playbook_name=$(basename $${ansible_playbook}) + +# Install ansible-core during the initial bootstrap +if [ "$ansible_playbook_name" == "ocp-cluster-bootstrap-playbook.yml" ]; then + echo "Installing ansible-core as a part of bootstrap..." + yum install -y expect ansible-core +fi + +# Create ansible.cfg file +echo -e "[defaults]\nhost_key_checking=False" >ansible.cfg +export ANSIBLE_LOG_PATH=$${ansible_log_path}/$${ansible_playbook_name}.$(date "+%Y.%m.%d-%H.%M.%S").log +export ANSIBLE_PRIVATE_KEY_FILE=$${ansible_private_key_file} +export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} + +#Execute ansible playbook +unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" +## On failure: +if [ $? -ne 0 ]; then + rm -rf $${ansible_private_key_file} + exit 1 +fi +echo \"Playbook command successful\" +rm -rf $${ansible_private_key_file} diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl new file mode 100644 index 00000000..9bb771a8 --- /dev/null +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl @@ -0,0 +1,169 @@ +- name: Install or upgrade OpenShift tools and create install-config.yaml file + hosts: all + vars: + openshift_release: "${OPENSHIFT_RELEASE}" + base_domain: "${BASE_DOMAIN}" + cluster_dir: "${CLUSTER_DIR}" + cluster_name: "${CLUSTER_NAME}" + cluster_network: "${CLUSTER_NETWORK}" + cluster_service_network: "${CLUSTER_SERVICE_NETWORK}" + worker_processors: "${WORKER_PROCESSORS}" + worker_system_type: "${WORKER_SYSTEM_TYPE}" + worker_proc_type: "${WORKER_PROC_TYPE}" + worker_replicas: ${WORKER_REPLICAS} + master_processors: "${MASTER_PROCESSORS}" + master_system_type: "${MASTER_SYSTEM_TYPE}" + master_proc_type: "${MASTER_PROC_TYPE}" + master_replicas: ${MASTER_REPLICAS} + user_id: "${USER_ID}" + transit_gateway_name: "${TRANSIT_GATEWAY_NAME}" + powervs_workspace_guid: "${POWERVS_WORKSPACE_GUID}" + resource_group: "${RESOURCE_GROUP}" + powervs_region: "${POWERVS_REGION}" + powervs_zone: "${POWERVS_ZONE}" + vpc_name: "${VPC_NAME}" + vpc_region: "${VPC_REGION}" + pull_secret: '${PULL_SECRET_FILE}' + ssh_key: "${SSH_KEY}" + base_path: "/tmp" + base_url: "https://mirror.openshift.com/pub/openshift-v4" + tools: + oc: + release_arch: "amd64" + file: "openshift-client-linux-{{ openshift_release }}.tar.gz" + openshift-install: + release_arch: "ppc64le" + file: "openshift-install-linux-amd64-{{ openshift_release }}.tar.gz" + ccoctl: + release_arch: "amd64" + file: "ccoctl-linux-{{ openshift_release }}.tar.gz" + + tools_with_version_check: "{{ tools | dict2items | rejectattr('key', 'equalto', 'ccoctl') | list }}" + + tasks: + - name: Ensure base path exists + file: + path: "{{ base_path }}" + state: directory + mode: '0755' + + - name: Check if binaries exist (excluding ccoctl) + stat: + path: "/usr/bin/{{ item.key }}" + register: binary_stat + loop: "{{ tools_with_version_check }}" + loop_control: + label: "{{ item.key }}" + + - name: Get installed version of each binary + command: "/usr/bin/{{ item.0.key }} version" + register: version_output + when: item.1.stat.exists + loop: "{{ tools_with_version_check | zip(binary_stat.results) }}" + loop_control: + label: "{{ item.0.key }}" + + - name: Extract versions + set_fact: + installed_versions: "{{ installed_versions | default({}) | combine({ item.0.key: (item.1.stdout_lines[0].split(' ')[1]) }) }}" + when: item.1.stdout_lines is defined and item.1.stdout_lines[0] is search(item.0.key) + loop: "{{ tools_with_version_check | zip(version_output.results) }}" + loop_control: + label: "{{ item.0.key }}" + + - name: Remove binary if version mismatch + file: + path: "/usr/bin/{{ item.key }}" + state: absent + when: > + (installed_versions[item.key] is not defined) or + (installed_versions[item.key] != openshift_release) + loop: "{{ tools_with_version_check }}" + loop_control: + label: "{{ item.key }}" + + - name: Always remove ccoctl binary if present + file: + path: /usr/bin/ccoctl + state: absent + + - name: Download tool archives + get_url: + url: "{{ base_url }}/{{ item.value.release_arch }}/clients/ocp/{{ openshift_release }}/{{ item.value.file }}" + dest: "{{ base_path }}/{{ item.value.file }}" + mode: '0644' + loop: "{{ tools | dict2items }}" + loop_control: + label: "{{ item.key }}" + + - name: Extract and install binaries + unarchive: + src: "{{ base_path }}/{{ item.value.file }}" + dest: /usr/bin/ + remote_src: yes + extra_opts: [ "{{ item.key }}" ] + loop: "{{ tools | dict2items }}" + loop_control: + label: "{{ item.key }}" + + - name: Ensure cluster directory exists + file: + path: "{{ cluster_dir }}" + state: directory + mode: '0755' + + - name: Create install-config.yaml in cluster_dir + copy: + dest: "{{ cluster_dir }}/install-config.yaml" + content: | + apiVersion: v1 + baseDomain: "{{ base_domain }}" + publish: Internal + metadata: + creationTimestamp: null + name: "{{ cluster_name }}" + + networking: + clusterNetwork: + - cidr: "{{ cluster_network }}" + hostPrefix: 23 + networkType: OVNKubernetes + serviceNetwork: + - "{{ cluster_service_network }}" + + platform: + powervs: + userID: {{ user_id }} + powervsResourceGroup: {{ resource_group }} + region: {{ powervs_region }} + zone: {{ powervs_zone }} + tgName: {{ transit_gateway_name }} + vpcName: {{ vpc_name }} + vpcRegion: {{ vpc_region }} + serviceInstanceGUID: {{ powervs_workspace_guid }} + + compute: + - architecture: ppc64le + hyperthreading: Enabled + name: worker + platform: + powervs: + processors: {{ worker_processors }} + sysType: "{{ worker_system_type }}" + procType: "{{ worker_proc_type }}" + replicas: {{ worker_replicas }} + + controlPlane: + architecture: ppc64le + hyperthreading: Enabled + name: master + platform: + powervs: + processors: {{ master_processors }} + sysType: "{{ master_system_type }}" + procType: "{{ master_proc_type }}" + replicas: {{ master_replicas }} + + pullSecret: '{{ pull_secret }}' + + sshKey: "{{ ssh_key }}" diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl new file mode 100644 index 00000000..a8bbbad4 --- /dev/null +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl @@ -0,0 +1,80 @@ +--- +- name: Execute OpenShift commands and IBM Cloud service creation + hosts: all + + vars: + release_image: "${RELEASE_IMAGE}" + requests_dir: "${REQUESTS_DIR}" + account_name: "${ACCOUNT_NAME}" + resource_group: "${RESOURCE_GROUP}" + cluster_name: "${CLUSTER_NAME}" + cluster_dir: "${CLUSTER_DIR}" + + tasks: + - name: Create manifests and extract image + block: + - name: Extract OpenShift release + command: > + oc adm release extract --cloud=powervs --credentials-requests {{ release_image }} --to={{ requests_dir }} + args: + chdir: "{{ cluster_dir }}" + register: release_extract_output + + - name: Create IBM Cloud service ID using ccoctl + command: > + ccoctl ibmcloud create-service-id + --credentials-requests-dir {{ requests_dir }} + --name {{ account_name }} + --resource-group-name {{ resource_group }} + args: + chdir: "{{ cluster_dir }}" + environment: + IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" + register: service_id_creation_output + + - name: Output result of release extraction + debug: + var: release_extract_output + + - name: Output result of IBM Cloud service creation + debug: + var: service_id_creation_output + + rescue: + - name: Rescue if failure occurred + ansible.builtin.shell: | + ccoctl ibmcloud delete-service-id --credentials-requests-dir {{requests_dir}} --name {{cluster_name}}; + args: + chdir: "{{ cluster_dir }}" + environment: + IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" + + - name: Mark that rescue was triggered + set_fact: + rescue_triggered: true + + - name: Create manifests + ansible.builtin.shell: | + openshift-install create manifests + args: + chdir: "{{ cluster_dir }}" + environment: + IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" + + - name: Find files matching openshift* in manifests dir + ansible.builtin.find: + paths: "{{ cluster_dir }}/manifests" + patterns: "openshift*" + file_type: file + register: found_files + + - name: Set permissions to 0640 + ansible.builtin.file: + path: "{{ item.path }}" + mode: '0640' + loop: "{{ found_files.files }}" + + - name: Fail if rescue was triggered + fail: + msg: "Rescue block was triggered; Task is now failing as a result." + when: rescue_triggered | default(false) diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl new file mode 100644 index 00000000..2376ab21 --- /dev/null +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl @@ -0,0 +1,48 @@ +--- +- name: Create .powervs folder + hosts: all + + vars: + powervs_config_path: "~/.powervs/config.json" + id: "${IBM_ID}" + region: "${POWERVS_REGION}" + zone: "${POWERVS_ZONE}" + resource_group: "${RESOURCE_GROUP}" + install_dir: "${CLUSTER_DIR}" + openshift_install_bootstrap_timeout: "${OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT}" + openshift_install_machine_wait_timeout: "${OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT}" + openshift_install_cluster_timeout: "${OPENSHIFT_INSTALL_CLUSTER_TIMEOUT}" + openshift_install_destroy_timeout: "${OPENSHIFT_INSTALL_DESTROY_TIMEOUT}" + + tasks: + - name: Ensure ~/.powervs directory exists + file: + path: "{{ powervs_config_path | dirname }}" + state: directory + mode: '0700' + + - name: Create ~/.powervs/config.json file securely + copy: + dest: "{{ powervs_config_path }}" + content: | + { + "id": "{{ id }}", + "apikey": "{{ lookup('env', 'IBMCLOUD_API_KEY') }}", + "region": "{{ region }}", + "zone": "{{ zone }}", + "resourcegroup": "{{ resource_group }}", + } + mode: '0600' + + - name: Run openshift-install create cluster + ansible.builtin.shell: | + openshift-install create cluster --dir={{ install_dir }} --log-level=debug + environment: + IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" + OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT: "{{ openshift_install_bootstrap_timeout }}" + OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT: "{{ openshift_install_machine_wait_timeout }}" + OPENSHIFT_INSTALL_CLUSTER_TIMEOUT: "{{ openshift_install_cluster_timeout }}" + OPENSHIFT_INSTALL_DESTROY_TIMEOUT: "{{ openshift_install_destroy_timeout }}" + + register: install_output + ignore_errors: false diff --git a/modules/ansible/templates-ansible/inventory.tftpl b/modules/ansible/templates-ansible/inventory.tftpl new file mode 100644 index 00000000..c445ebd5 --- /dev/null +++ b/modules/ansible/templates-ansible/inventory.tftpl @@ -0,0 +1 @@ +${host_or_ip} diff --git a/modules/ansible/variables.tf b/modules/ansible/variables.tf new file mode 100644 index 00000000..99aaae1c --- /dev/null +++ b/modules/ansible/variables.tf @@ -0,0 +1,98 @@ +variable "bastion_host_ip" { + description = "Jump/Bastion server public IP address to reach the ansible host which has private IP." + type = string +} + +variable "ansible_host_or_ip" { + description = "Private IP of virtual server instance running RHEL OS on which ansible will be installed and configured to act as central ansible node." + type = string +} + +variable "ssh_private_key" { + description = "Private SSH key used to login to jump/bastion server, also the ansible host and all the hosts on which tasks will be executed. This key will be written temporarily on ansible host and deleted after execution." + type = string + sensitive = true +} + +variable "configure_ansible_host" { + description = "If set to true, bash script will be executed to install and configure the collections and packages on ansible node." + type = bool +} + +variable "src_script_template_name" { + description = "Name of the bash script template file located within the 'templates-ansible' directory." + type = string +} + +variable "dst_script_file_name" { + description = "Name for the bash file to be generated on the Ansible host." + type = string +} + +variable "src_playbook_template_name" { + description = "Name of the playbook template file located within the 'templates-ansible' directory." + type = string +} + +variable "dst_playbook_file_name" { + description = "Name for the playbook file to be generated on the Ansible host." + type = string +} + +variable "playbook_template_vars" { + description = "Map values for the ansible playbook template." + type = map(any) +} + +variable "src_inventory_template_name" { + description = "Name of the inventory template file located within the 'templates-ansible' directory." + type = string +} + +variable "dst_inventory_file_name" { + description = "Name for the inventory file to be generated on the Ansible host." + type = string +} + +variable "inventory_template_vars" { + description = "Map values for the inventory template." + type = map(any) +} + +variable "ansible_vault_password" { + description = "Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]_{|}~." + type = string + sensitive = true + default = null + validation { + condition = var.ansible_vault_password == null ? true : (length(var.ansible_vault_password) >= 15 && length(var.ansible_vault_password) <= 100) + error_message = "ansible_vault_password needs to be between 15 and 100 characters in length." + } + validation { + condition = var.ansible_vault_password == null ? true : can(regex("[A-Z]", var.ansible_vault_password)) + error_message = "ansible_vault_password needs to contain at least one uppercase character (A-Z)." + } + validation { + condition = var.ansible_vault_password == null ? true : can(regex("[a-z]", var.ansible_vault_password)) + error_message = "ansible_vault_password needs to contain at least one lowercase character (a-z)." + } + validation { + condition = var.ansible_vault_password == null ? true : can(regex("[0-9]", var.ansible_vault_password)) + error_message = "ansible_vault_password needs to contain at least one number (0-9)." + } + validation { + condition = var.ansible_vault_password == null ? true : can(regex("[!#$%&()*+\\-.:;<=>?@[\\]_{|}~]", var.ansible_vault_password)) + error_message = "ansible_vault_password needs to contain at least one of the following special characters: !#$%&()*+-.:;<=>?@[]_{|}~" + } + validation { + condition = var.ansible_vault_password == null ? true : can(regex("^[A-Za-z0-9!#$%&()*+\\-.:;<=>?@[\\]_{|}~]+$", var.ansible_vault_password)) + error_message = "ansible_vault_password contains illegal characters. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]_{|}~" + } +} + +variable "ibmcloud_api_key" { + description = "IBM Cloud platform API key needed to deploy IAM enabled resources." + type = string + sensitive = true + default = null +} diff --git a/modules/ansible/versions.tf b/modules/ansible/versions.tf new file mode 100644 index 00000000..6f8a4d8d --- /dev/null +++ b/modules/ansible/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.9.0" + required_providers { + random = { + source = "hashicorp/random" + version = "3.6.1" + } + } +} diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf new file mode 100644 index 00000000..f7b7f0c6 --- /dev/null +++ b/solutions/standard-openshift/main.tf @@ -0,0 +1,173 @@ +##################################################### +# PowerVS with VPC landing zone module +##################################################### + +# module "standard" { +# source = "../../modules/powervs-vpc-landing-zone" + +# providers = { ibm.ibm-is = ibm.ibm-is, ibm.ibm-pi = ibm.ibm-pi, ibm.ibm-sm = ibm.ibm-sm } + +# powervs_zone = var.powervs_zone +# prefix = var.prefix +# external_access_ip = var.external_access_ip +# ssh_public_key = var.ssh_public_key +# ssh_private_key = var.ssh_private_key +# client_to_site_vpn = var.client_to_site_vpn +# vpc_intel_images = var.vpc_intel_images +# configure_dns_forwarder = false +# configure_ntp_forwarder = var.configure_ntp_forwarder +# configure_nfs_server = var.configure_nfs_server +# dns_forwarder_config = null +# nfs_server_config = var.nfs_server_config +# powervs_resource_group_name = var.powervs_resource_group_name +# powervs_management_network = null +# powervs_backup_network = null +# tags = var.tags +# sm_service_plan = var.sm_service_plan +# existing_sm_instance_guid = var.existing_sm_instance_guid +# existing_sm_instance_region = var.existing_sm_instance_region +# network_services_vsi_profile = var.network_services_vsi_profile +# enable_monitoring = var.enable_monitoring +# existing_monitoring_instance_crn = var.existing_monitoring_instance_crn +# enable_scc_wp = var.enable_scc_wp +# ansible_vault_password = var.ansible_vault_password +# } + +##################################################### +# DNS Service & Zone Creation +##################################################### + +resource "ibm_resource_instance" "ibm_dns_instance" { + provider = ibm.ibm-is + + name = "${var.cluster_name}-dns" + resource_group_id = "" # TODO: replace with module output + location = "global" + service = "dns-svcs" + plan = "standard-dns" +} + +resource "ibm_dns_zone" "dns_zone" { + provider = ibm.ibm-is + + name = var.cluster_base_domain + instance_id = ibm_resource_instance.ibm_dns_instance.guid + description = "IBM DNS instance created by deployable architecture for OpenShift IPI on Power Virtual Server" + label = var.cluster_name +} + +##################################################### +# Openshift Cluster Deployment modules +##################################################### + +locals { + powervs_region = lookup(local.openshift_region_map, var.powervs_zone, null) + vpc_region = lookup(local.ibm_powervs_zone_cloud_region_map, var.powervs_zone, null) +} + +module "ocp_cluster_install_configuration" { + source = "../../modules/ansible" + #depends_on = [ module.standard ] # TODO: uncomment during integration + + bastion_host_ip = "" # TODO: replace with module output + ansible_host_or_ip = "" # TODO: replace with module output + ssh_private_key = var.ssh_private_key + configure_ansible_host = false + + src_script_template_name = "deploy-openshift-cluster/ansible_exec.sh.tftpl" + dst_script_file_name = "bootstrap-ocp-cluster.sh" + + src_playbook_template_name = "deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl" + dst_playbook_file_name = "ocp-cluster-install-configuration-playbook.yml" + playbook_template_vars = { + OPENSHIFT_RELEASE : var.openshift_release, + BASE_DOMAIN : var.cluster_base_domain, + CLUSTER_DIR : var.cluster_dir, + CLUSTER_NAME : var.cluster_name, + CLUSTER_NETWORK : var.cluster_network_config.cluster_network_cidr, + CLUSTER_SERVICE_NETWORK : var.cluster_network_config.cluster_service_network_cidr, + WORKER_PROCESSORS : var.cluster_worker_node_config.processors, + WORKER_SYSTEM_TYPE : var.cluster_worker_node_config.system_type, + WORKER_PROC_TYPE : var.cluster_worker_node_config.proc_type, + WORKER_REPLICAS : var.cluster_worker_node_config.replicas, + MASTER_PROCESSORS : var.cluster_master_node_config.processors, + MASTER_SYSTEM_TYPE : var.cluster_master_node_config.system_type, + MASTER_PROC_TYPE : var.cluster_master_node_config.proc_type, + MASTER_REPLICAS : var.cluster_master_node_config.replicas, + USER_ID : var.user_id, + TRANSIT_GATEWAY_NAME : "", # TODO: replace with module output + POWERVS_WORKSPACE_GUID : "", # TODO: replace with module output + RESOURCE_GROUP : var.powervs_resource_group_name, + POWERVS_REGION : local.powervs_region, + POWERVS_ZONE : var.powervs_zone, + VPC_NAME : "", # TODO: replace with module output + VPC_REGION : local.vpc_region + PULL_SECRET_FILE : jsonencode(var.openshift_pull_secret), + SSH_KEY : var.ssh_public_key, + } + + src_inventory_template_name = "inventory.tftpl" + dst_inventory_file_name = "${var.cluster_name}-playbook-ocp-install-config-inventory" + inventory_template_vars = { "host_or_ip" : "" } #TODO: replace with module output (ansible_host_or_ip) +} + +module "ocp_cluster_manifest_creation" { + source = "../../modules/ansible" + depends_on = [module.ocp_cluster_install_configuration] + + bastion_host_ip = "" # TODO: replace with module output + ansible_host_or_ip = "" # TODO: replace with module output + ssh_private_key = var.ssh_private_key + configure_ansible_host = false + ibmcloud_api_key = var.ibmcloud_api_key + + src_script_template_name = "deploy-openshift-cluster/ansible_exec.sh.tftpl" + dst_script_file_name = "create-ocp-cluster-manifests.sh" + + src_playbook_template_name = "deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl" + dst_playbook_file_name = "ocp-cluster-manifest-creation-playbook.yml" + playbook_template_vars = { + RELEASE_IMAGE : "quay.io/openshift-release-dev/ocp-release:${var.openshift_release}-multi", + CLUSTER_NAME : var.cluster_name, + CLUSTER_DIR : "/root/${var.cluster_dir}", + REQUESTS_DIR : "./credreqs" + ACCOUNT_NAME : var.cluster_name, + RESOURCE_GROUP : var.powervs_resource_group_name, + } + + src_inventory_template_name = "inventory.tftpl" + dst_inventory_file_name = "${var.cluster_name}-playbook-ocp-install-config-inventory" + inventory_template_vars = { "host_or_ip" : "" } #TODO: replace with module output (ansible_host_or_ip) +} + +module "ocp_cluster_deployment" { + source = "../../modules/ansible" + depends_on = [module.ocp_cluster_manifest_creation] + + bastion_host_ip = "" # TODO: replace with module output + ansible_host_or_ip = "" # TODO: replace with module output + ssh_private_key = var.ssh_private_key + configure_ansible_host = false + ibmcloud_api_key = var.ibmcloud_api_key + + src_script_template_name = "deploy-openshift-cluster/ansible_exec.sh.tftpl" + dst_script_file_name = "deploy-ocp-cluster.sh" + + src_playbook_template_name = "deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl" + dst_playbook_file_name = "ocp-cluster-deployment-playbook.yml" + playbook_template_vars = { + IBM_ID : var.user_id + POWERVS_REGION : local.powervs_region, + POWERVS_ZONE : var.powervs_zone, + RESOURCE_GROUP : var.powervs_resource_group_name, + CLUSTER_DIR : var.cluster_dir, + OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT : "120m", + OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT : "35m", + OPENSHIFT_INSTALL_CLUSTER_TIMEOUT : "180m", + OPENSHIFT_INSTALL_DESTROY_TIMEOUT : "60m", + } + + src_inventory_template_name = "inventory.tftpl" + dst_inventory_file_name = "${var.cluster_name}-playbook-ocp-install-config-inventory" + inventory_template_vars = { "host_or_ip" : "" } #TODO: replace with module output (ansible_host_or_ip) +} diff --git a/solutions/standard-openshift/outputs.tf b/solutions/standard-openshift/outputs.tf new file mode 100644 index 00000000..e69de29b diff --git a/solutions/standard-openshift/provider.tf b/solutions/standard-openshift/provider.tf new file mode 100644 index 00000000..4061e139 --- /dev/null +++ b/solutions/standard-openshift/provider.tf @@ -0,0 +1,105 @@ +locals { + ibm_powervs_zone_region_map = { + "syd04" = "syd" + "syd05" = "syd" + "sao01" = "sao" + "sao04" = "sao" + "tor01" = "tor" + "mon01" = "mon" + "eu-de-1" = "eu-de" + "eu-de-2" = "eu-de" + "mad02" = "mad" + "mad04" = "mad" + "lon04" = "lon" + "lon06" = "lon" + "osa21" = "osa" + "tok04" = "tok" + "us-south" = "us-south" + "dal10" = "us-south" + "dal12" = "us-south" + "dal14" = "us-south" + "us-east" = "us-east" + "wdc06" = "us-east" + "wdc07" = "us-east" + } + + ibm_powervs_zone_cloud_region_map = { + "syd04" = "au-syd" + "syd05" = "au-syd" + "sao01" = "br-sao" + "sao04" = "br-sao" + "tor01" = "ca-tor" + "mon01" = "ca-tor" + "eu-de-1" = "eu-de" + "eu-de-2" = "eu-de" + "mad02" = "eu-es" + "mad04" = "eu-es" + "lon04" = "eu-gb" + "lon06" = "eu-gb" + "osa21" = "jp-osa" + "tok04" = "jp-tok" + "us-south" = "us-south" + "dal10" = "us-south" + "dal12" = "us-south" + "dal14" = "us-south" + "us-east" = "us-east" + "wdc06" = "us-east" + "wdc07" = "us-east" + } + + openshift_region_map = { + "syd04" = "syd" + "syd05" = "syd" + "sao01" = "sao" + "sao04" = "sao" + "tor01" = "tor" + #"mon01" = "ca-tor" + "eu-de-1" = "eu-de" + "eu-de-2" = "eu-de" + "mad02" = "mad" + "mad04" = "mad" + "lon04" = "lon" + "osa21" = "osa" + #"tok04" = "jp-tok" + "us-south" = "us-south" + "dal10" = "dal" + "dal12" = "dal" + "us-east" = "us-east" + "wdc06" = "wdc" + "wdc07" = "wdc" + } +} + +# There are discrepancies between the region inputs on the powervs terraform resource, and the vpc ("is") resources +provider "ibm" { + alias = "ibm-pi" + region = lookup(local.ibm_powervs_zone_region_map, var.powervs_zone, null) + zone = var.powervs_zone + ibmcloud_api_key = var.ibmcloud_api_key != null ? var.ibmcloud_api_key : null +} + +provider "ibm" { + alias = "ibm-is" + region = lookup(local.ibm_powervs_zone_cloud_region_map, var.powervs_zone, null) + zone = var.powervs_zone + ibmcloud_api_key = var.ibmcloud_api_key != null ? var.ibmcloud_api_key : null +} + +provider "ibm" { + alias = "ibm-sm" + region = var.existing_sm_instance_region == null ? lookup(local.ibm_powervs_zone_cloud_region_map, var.powervs_zone, null) : var.existing_sm_instance_region + zone = var.powervs_zone + ibmcloud_api_key = var.ibmcloud_api_key != null ? var.ibmcloud_api_key : null +} + +data "ibm_iam_auth_token" "auth_token" { + provider = ibm.ibm-is +} + +provider "restapi" { + uri = "https://resource-controller.cloud.ibm.com" + headers = { + Authorization = data.ibm_iam_auth_token.auth_token.iam_access_token + } + write_returns_object = true +} diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf new file mode 100644 index 00000000..f4d519c1 --- /dev/null +++ b/solutions/standard-openshift/variables.tf @@ -0,0 +1,266 @@ +variable "powervs_zone" { + description = "IBM Cloud data center location where IBM PowerVS infrastructure will be created." + type = string +} + +variable "prefix" { + description = "A unique identifier for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters." + type = string +} + +variable "ssh_public_key" { + description = "Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region." + type = string +} + +variable "ssh_private_key" { + description = "Private SSH key (RSA format) to login to Intel VSIs to configure network management services (SQUID, NTP, DNS and ansible). Should match to public SSH key referenced by 'ssh_public_key'. The key is not uploaded or stored. For more information about SSH keys, see [SSH keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys)." + type = string + sensitive = true +} + +variable "user_id" { + description = "The IBM Cloud login user ID associated with the account where the cluster will be deployed." + type = string +} + +variable "openshift_pull_secret" { + description = "Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries." + type = map(any) + sensitive = true +} + +variable "ibmcloud_api_key" { + description = "The IBM Cloud platform API key needed to deploy IAM enabled resources." + type = string + sensitive = true +} + +# required? +variable "ansible_vault_password" { + description = "Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]_{|}~." + type = string + sensitive = true +} + +variable "cluster_base_domain" { + description = "The base domain name that will be used by the cluster. (ie: example.com)" + type = string +} + +variable "cluster_name" { + description = "The name of the cluster." + type = string +} + +##################################################### +# Optional Parameters PowerVS Instance +##################################################### + +variable "custom_profile_instance_boot_image" { + description = "Override the t-shirt size specs of PowerVS Workspace instance by selecting an image name and providing valid 'custom_profile' optional parameter." + type = string + default = "none" +} + +##################################################### +# Optional Parameters Openshift Cluster +##################################################### + +variable "openshift_release" { + description = "The OpenShift IPI release version to deploy." + type = string + default = "4.19.5" +} + +variable "cluster_dir" { + description = "The directory that holds the artifacts of the OpenShift cluster creation." + type = string + default = "ocp-powervs-deploy" +} + +variable "cluster_network_config" { + description = "Configuration object for the OpenShift cluster and service network CIDRs." + type = object({ + cluster_network_cidr = string + cluster_service_network_cidr = string + }) + default = { + cluster_network_cidr = "172.168.0.0/22" + cluster_service_network_cidr = "10.67.0.0/24" + } +} + +variable "cluster_master_node_config" { + description = "Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count." + type = object({ + processors = number + system_type = string + proc_type = string + replicas = number + }) + default = { + processors = 4 + system_type = "s1022" + proc_type = "Dedicated" + replicas = 3 + } +} + +variable "cluster_worker_node_config" { + description = "Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count." + type = object({ + processors = number + system_type = string + proc_type = string + replicas = number + }) + default = { + processors = 4 + system_type = "s1022" + proc_type = "Dedicated" + replicas = 3 + } +} + +##################################################### +# Optional Parameters PowerVS Workspace +##################################################### + +variable "powervs_resource_group_name" { + description = "Existing IBM Cloud resource group name." + type = string + default = "Default" +} + +variable "tags" { + description = "List of tag names for the IBM Cloud PowerVS workspace" + type = list(string) + default = [] +} + +##################################################### +# Optional Parameters for intel VSI +##################################################### + +variable "vpc_intel_images" { + description = "Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring)." + type = object({ + rhel_image = string + sles_image = string + }) + default = { + "rhel_image" : "ibm-redhat-9-4-amd64-sap-applications-5" + "sles_image" : "ibm-sles-15-6-amd64-sap-applications-3" + } +} + +variable "network_services_vsi_profile" { + description = "Compute profile configuration of the network services vsi (cpu and memory configuration). Must be one of the supported profiles. See [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui)." + type = string + default = "cx2-2x4" +} + +variable "external_access_ip" { + description = "Specify the source IP address or CIDR for login through SSH to the environment after deployment. Access to the environment will be allowed only from this IP address. Can be set to 'null' if you choose to use client to site vpn." + type = string + default = "0.0.0.0/0" +} + +variable "configure_ntp_forwarder" { + description = "Specify if NTP forwarder will be configured. This will allow you to synchronize time between IBM PowerVS instances. NTP forwarder will be installed on the network-services vsi." + type = bool + default = true +} + +variable "configure_nfs_server" { + description = "Specify if NFS server will be configured. This will allow you easily to share files between PowerVS instances (e.g., SAP installation files). [File storage share and mount target](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-create&interface=ui) in VPC will be created.. If yes, ensure 'nfs_server_config' optional variable is set properly below. Default value is '200GB' which will be mounted on specified directory in network-service vsi." + type = bool + default = true +} + +variable "nfs_server_config" { + description = "Configuration for the NFS server. 'size' is in GB, 'iops' is maximum input/output operation performance bandwidth per second, 'mount_path' defines the target mount point on os. Set 'configure_nfs_server' to false to ignore creating file storage share." + type = object({ + size = number + iops = number + mount_path = string + }) + + default = { + "size" : 200, + "iops" : 600, + "mount_path" : "/nfs" + } +} + + +##################################################### +# Optional Parameters Monitoring and SCC WP Instance +##################################################### + +variable "enable_scc_wp" { + description = "Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. If set to true, then value for 'ansible_vault_password' in optional parameter must be set." + type = bool + default = true +} + +variable "enable_monitoring" { + description = "Specify whether Monitoring will be enabled. This includes the creation of an IBM Cloud Monitoring Instance and an Intel Monitoring Instance to host the services. If you already have an existing monitoring instance then specify in optional parameter 'existing_monitoring_instance_crn' and setting this parameter to true." + type = bool + default = false +} + +variable "existing_monitoring_instance_crn" { + description = "Existing CRN of IBM Cloud Monitoring Instance. If value is null, then an IBM Cloud Monitoring Instance will not be created but an intel VSI instance will be created if 'enable_monitoring' is true. " + type = string + default = null +} + +########################################################### +# Optional Parameters Secret Manager for client to site VPN +########################################################### + +variable "client_to_site_vpn" { + description = "VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance." + type = object({ + enable = bool + client_ip_pool = string + vpn_client_access_group_users = list(string) + }) + + default = { + "enable" : true, + "client_ip_pool" : "192.168.0.0/16", + "vpn_client_access_group_users" : [] + } +} + +variable "sm_service_plan" { + description = "The service/pricing plan to use when provisioning a new Secrets Manager instance. Allowed values: `standard` and `trial`. Only used if `existing_sm_instance_guid` is set to null." + type = string + default = "standard" +} + +variable "existing_sm_instance_guid" { + description = "An existing Secrets Manager GUID. If not provided a new instance will be provisioned." + type = string + default = null +} + +variable "existing_sm_instance_region" { + description = "Required if value is passed into `var.existing_sm_instance_guid`." + type = string + default = null +} + +############################################################################# +# Schematics Output +############################################################################# + +# tflint-ignore: terraform_naming_convention +variable "IC_SCHEMATICS_WORKSPACE_ID" { + description = "leave blank if running locally. This variable will be automatically populated if running from an IBM Cloud Schematics workspace" + type = string + default = "" +} diff --git a/solutions/standard-openshift/versions.tf b/solutions/standard-openshift/versions.tf new file mode 100644 index 00000000..28ea6758 --- /dev/null +++ b/solutions/standard-openshift/versions.tf @@ -0,0 +1,22 @@ +##################################################### +# PowerVS Standard Openshift solution +##################################################### + +terraform { + required_version = ">= 1.9" + required_providers { + ibm = { + source = "IBM-Cloud/ibm" + version = "1.80.4" + } + restapi = { + source = "Mastercard/restapi" + version = "2.0.1" + } + time = { + source = "hashicorp/time" + version = "0.13.1" + } + + } +} From d26959a3669329ac67320f2b63782ef23fd632fc Mon Sep 17 00:00:00 2001 From: stafaniasaju Date: Wed, 30 Jul 2025 18:15:12 +0200 Subject: [PATCH 02/83] feat: script update(dev code) --- .../deploy-openshift-cluster/ansible_exec.sh.tftpl | 2 +- solutions/standard-openshift/main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl index 80f2b4ba..7406db66 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl @@ -9,7 +9,7 @@ ansible_private_key_file=${ansible_private_key_file} ansible_playbook_name=$(basename $${ansible_playbook}) # Install ansible-core during the initial bootstrap -if [ "$ansible_playbook_name" == "ocp-cluster-bootstrap-playbook.yml" ]; then +if [ "$ansible_playbook_name" == "ocp-cluster-install-configuration-playbook.yml" ]; then echo "Installing ansible-core as a part of bootstrap..." yum install -y expect ansible-core fi diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index f7b7f0c6..b63c4d91 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -75,7 +75,7 @@ module "ocp_cluster_install_configuration" { configure_ansible_host = false src_script_template_name = "deploy-openshift-cluster/ansible_exec.sh.tftpl" - dst_script_file_name = "bootstrap-ocp-cluster.sh" + dst_script_file_name = "ocp-cluster-install-configuration.sh" src_playbook_template_name = "deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl" dst_playbook_file_name = "ocp-cluster-install-configuration-playbook.yml" From 27f95addda0272feb22845dc6c1adaadbf785cc3 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 18 Aug 2025 16:36:38 +0200 Subject: [PATCH 03/83] feat: expose vpn server dns ip addresses --- .secrets.baseline | 32 ++++++++++++++++++- modules/powervs-vpc-landing-zone/README.md | 1 + .../client2sitevpn.tf | 1 + modules/powervs-vpc-landing-zone/variables.tf | 10 ++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/.secrets.baseline b/.secrets.baseline index 25859af7..68895c6e 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-05-26T17:03:08Z", + "generated_at": "2025-08-18T14:30:58Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -87,6 +87,36 @@ "verified_result": null } ], + "modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl": [ + { + "hashed_secret": "6f803b24314c39062efe38d0c1da8c472f47eab3", + "is_secret": false, + "is_verified": false, + "line_number": 167, + "type": "Secret Keyword", + "verified_result": null + } + ], + "modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl": [ + { + "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", + "is_secret": false, + "is_verified": false, + "line_number": 62, + "type": "Secret Keyword", + "verified_result": null + } + ], + "modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl": [ + { + "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", + "is_secret": false, + "is_verified": false, + "line_number": 41, + "type": "Secret Keyword", + "verified_result": null + } + ], "modules/powervs-vpc-landing-zone/README.md": [ { "hashed_secret": "91199272d5d6a574a51722ca6f3d1148edb1a0e7", diff --git a/modules/powervs-vpc-landing-zone/README.md b/modules/powervs-vpc-landing-zone/README.md index 955cffa3..2f0bb312 100644 --- a/modules/powervs-vpc-landing-zone/README.md +++ b/modules/powervs-vpc-landing-zone/README.md @@ -166,6 +166,7 @@ Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastr | [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace | `list(string)` | `[]` | no | | [transit\_gateway\_global](#input\_transit\_gateway\_global) | Connect to the networks outside the associated region. | `bool` | `false` | no | | [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
| n/a | yes | +| [vpn\_dns\_ips](#input\_vpn\_dns\_ips) | IP of the DNS server to use in VPN configuration | `list(string)` | `null` | no | ### Outputs diff --git a/modules/powervs-vpc-landing-zone/client2sitevpn.tf b/modules/powervs-vpc-landing-zone/client2sitevpn.tf index 1424bc75..4b9098e7 100644 --- a/modules/powervs-vpc-landing-zone/client2sitevpn.tf +++ b/modules/powervs-vpc-landing-zone/client2sitevpn.tf @@ -136,6 +136,7 @@ module "client_to_site_vpn" { access_group_name = "${var.prefix}-client-to-site-vpn-access-group" subnet_ids = [for subnet in module.landing_zone.subnet_data : subnet.id if subnet.name == "${var.prefix}-edge-vpn-zone-1"] client_ip_pool = var.client_to_site_vpn.client_ip_pool + client_dns_server_ips = var.vpn_dns_ips server_cert_crn = module.secrets_manager_private_certificate[0].secret_crn vpn_client_access_group_users = var.client_to_site_vpn.vpn_client_access_group_users vpn_server_routes = local.vpn_server_routes diff --git a/modules/powervs-vpc-landing-zone/variables.tf b/modules/powervs-vpc-landing-zone/variables.tf index 0437389d..5cba24b4 100644 --- a/modules/powervs-vpc-landing-zone/variables.tf +++ b/modules/powervs-vpc-landing-zone/variables.tf @@ -302,3 +302,13 @@ variable "ansible_vault_password" { error_message = "ansible_vault_password is required when enable_scc_wp=true" } } + +################################################# +# Optional Parameters DNS IP +################################################# + +variable "vpn_dns_ips" { + description = "IP of the DNS server to use in VPN configuration" + type = list(string) + default = null +} From 0024c74bdffe71f4e847c1670f3ad6e97641ba39 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 20 Aug 2025 17:27:20 +0200 Subject: [PATCH 04/83] feat: add landing zone back in ocp, move dns instance to landing zone, move PowerVS routes to vpn config --- modules/powervs-vpc-landing-zone/README.md | 7 +- .../client2sitevpn.tf | 21 +-- modules/powervs-vpc-landing-zone/dns.tf | 49 +++++++ modules/powervs-vpc-landing-zone/variables.tf | 41 ++++-- solutions/standard-openshift/main.tf | 122 +++++++++--------- solutions/standard-openshift/variables.tf | 12 +- solutions/standard-openshift/versions.tf | 7 +- solutions/standard-plus-vsi/main.tf | 18 ++- solutions/standard/main.tf | 18 ++- 9 files changed, 180 insertions(+), 115 deletions(-) create mode 100644 modules/powervs-vpc-landing-zone/dns.tf diff --git a/modules/powervs-vpc-landing-zone/README.md b/modules/powervs-vpc-landing-zone/README.md index 2f0bb312..75e5f918 100644 --- a/modules/powervs-vpc-landing-zone/README.md +++ b/modules/powervs-vpc-landing-zone/README.md @@ -123,6 +123,8 @@ Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastr | Name | Type | |------|------| +| [ibm_dns_custom_resolver.dns_resolver](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/dns_custom_resolver) | resource | +| [ibm_dns_zone.dns_zone](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/dns_zone) | resource | | [ibm_is_lb.file_share_nlb](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_lb) | resource | | [ibm_is_lb_listener.nfs_front_end_listener](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_lb_listener) | resource | | [ibm_is_lb_pool.nfs_backend_pool](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_lb_pool) | resource | @@ -131,6 +133,7 @@ Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastr | [ibm_is_vpc_address_prefix.vpn_address_prefix](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_address_prefix) | resource | | [ibm_is_vpc_routing_table.routing_table](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_routing_table) | resource | | [ibm_is_vpc_routing_table_route.nfs_route](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_routing_table_route) | resource | +| [ibm_resource_instance.ibm_dns_instance](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance) | resource | | [ibm_resource_instance.monitoring_instance](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance) | resource | | [ibm_resource_instance.secrets_manager](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance) | resource | @@ -139,7 +142,7 @@ Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastr | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [ansible\_vault\_password](#input\_ansible\_vault\_password) | Vault password to encrypt ansible playbooks that contain sensitive information. Required when SCC workload Protection is enabled. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]\_{\|}~. | `string` | `null` | no | -| [client\_to\_site\_vpn](#input\_client\_to\_site\_vpn) | VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance. |
object({
enable = bool
client_ip_pool = string
vpn_client_access_group_users = list(string)
})
|
{
"client_ip_pool": "192.168.0.0/16",
"enable": false,
"vpn_client_access_group_users": []
}
| no | +| [client\_to\_site\_vpn](#input\_client\_to\_site\_vpn) | VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance. PowerVS server routes need to be created for the VPN so the PowerVS instances can be reached. Each route must have a unique name and destination CIDR. |
object({
enable = bool
client_ip_pool = string
vpn_client_access_group_users = list(string)
powervs_server_routes = list(object({
route_name = string
destination = string
action = string
}))
}
)
|
{
"client_ip_pool": "192.168.0.0/16",
"enable": false,
"powervs_server_routes": null,
"vpn_client_access_group_users": []
}
| no | | [configure\_dns\_forwarder](#input\_configure\_dns\_forwarder) | Specify if DNS forwarder will be configured. This will allow you to use central DNS servers (e.g. IBM Cloud DNS servers) sitting outside of the created IBM PowerVS infrastructure. If yes, ensure 'dns\_forwarder\_config' optional variable is set properly. DNS forwarder will be installed on the network-services vsi. | `bool` | `false` | no | | [configure\_nfs\_server](#input\_configure\_nfs\_server) | Specify if NFS server will be configured. This will allow you easily to share files between PowerVS instances (e.g., SAP installation files). [File storage share and mount target](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-create&interface=ui) in VPC will be created.. If yes, ensure 'nfs\_server\_config' optional variable is set properly below. Default value is '200GB' which will be mounted on specified directory in network-service vsi. | `bool` | `false` | no | | [configure\_ntp\_forwarder](#input\_configure\_ntp\_forwarder) | Specify if NTP forwarder will be configured. This will allow you to synchronize time between IBM PowerVS instances. NTP forwarder will be installed on the network-services vsi. | `bool` | `false` | no | @@ -150,6 +153,7 @@ Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastr | [existing\_sm\_instance\_guid](#input\_existing\_sm\_instance\_guid) | An existing Secrets Manager GUID. If not provided a new instance will be provisioned. | `string` | `null` | no | | [existing\_sm\_instance\_region](#input\_existing\_sm\_instance\_region) | Required if value is passed into `var.existing_sm_instance_guid`. | `string` | `null` | no | | [external\_access\_ip](#input\_external\_access\_ip) | Specify the source IP address or CIDR for login through SSH to the environment after deployment. Access to the environment will be allowed only from this IP address. Can be set to 'null' if you choose to use client to site vpn. | `string` | n/a | yes | +| [ibm\_dns\_service](#input\_ibm\_dns\_service) | Create IBM DNS service instance, DNS zone, and custom resolver. If set to false, then the DNS service and zone will not be created. Conflicts with 'configure\_dns\_forwarder'. |
object({
enable = bool
name = optional(string)
base_domain = optional(string)
label = optional(string)
})
|
{
"enable": false
}
| no | | [network\_services\_vsi\_profile](#input\_network\_services\_vsi\_profile) | Compute profile configuration of the network services vsi (cpu and memory configuration). Must be one of the supported profiles. See [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui). | `string` | `"cx2-2x4"` | no | | [nfs\_server\_config](#input\_nfs\_server\_config) | Configuration for the NFS server. 'size' is in GB, 'iops' is maximum input/output operation performance bandwidth per second, 'mount\_path' defines the target mount point on os. Set 'configure\_nfs\_server' to false to ignore creating file storage share. |
object({
size = number
iops = number
mount_path = string
})
|
{
"iops": 600,
"mount_path": "/nfs",
"size": 200
}
| no | | [powervs\_backup\_network](#input\_powervs\_backup\_network) | Name of the IBM Cloud PowerVS backup network and CIDR to create. |
object({
name = string
cidr = string
})
|
{
"cidr": "10.52.0.0/24",
"name": "bkp_net"
}
| no | @@ -166,7 +170,6 @@ Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastr | [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace | `list(string)` | `[]` | no | | [transit\_gateway\_global](#input\_transit\_gateway\_global) | Connect to the networks outside the associated region. | `bool` | `false` | no | | [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
| n/a | yes | -| [vpn\_dns\_ips](#input\_vpn\_dns\_ips) | IP of the DNS server to use in VPN configuration | `list(string)` | `null` | no | ### Outputs diff --git a/modules/powervs-vpc-landing-zone/client2sitevpn.tf b/modules/powervs-vpc-landing-zone/client2sitevpn.tf index 4b9098e7..f2f2d006 100644 --- a/modules/powervs-vpc-landing-zone/client2sitevpn.tf +++ b/modules/powervs-vpc-landing-zone/client2sitevpn.tf @@ -27,23 +27,10 @@ locals { } } - powervs_server_routes = [ - { - route_name = "mgmt_net" - destination = var.powervs_management_network.cidr - action = "deliver" - }, - { - route_name = "bkp_net" - destination = var.powervs_backup_network.cidr - action = "deliver" - } - ] - - vpn_server_routes = merge(local.default_server_routes, + vpn_server_routes = var.client_to_site_vpn.powervs_server_routes != null ? merge(local.default_server_routes, tomap( { - for instance in local.powervs_server_routes : + for instance in var.client_to_site_vpn.powervs_server_routes : instance.route_name => { destination = instance.destination action = instance.action @@ -51,7 +38,7 @@ locals { if !startswith(instance.destination, "10.") } ) - ) + ) : local.default_server_routes } @@ -136,7 +123,7 @@ module "client_to_site_vpn" { access_group_name = "${var.prefix}-client-to-site-vpn-access-group" subnet_ids = [for subnet in module.landing_zone.subnet_data : subnet.id if subnet.name == "${var.prefix}-edge-vpn-zone-1"] client_ip_pool = var.client_to_site_vpn.client_ip_pool - client_dns_server_ips = var.vpn_dns_ips + client_dns_server_ips = var.ibm_dns_service.enable ? [for location in ibm_dns_custom_resolver.dns_resolver[0].locations : location.dns_server_ip] : null server_cert_crn = module.secrets_manager_private_certificate[0].secret_crn vpn_client_access_group_users = var.client_to_site_vpn.vpn_client_access_group_users vpn_server_routes = local.vpn_server_routes diff --git a/modules/powervs-vpc-landing-zone/dns.tf b/modules/powervs-vpc-landing-zone/dns.tf new file mode 100644 index 00000000..f5e55d97 --- /dev/null +++ b/modules/powervs-vpc-landing-zone/dns.tf @@ -0,0 +1,49 @@ +##################################################### +# DNS Service & Zone Creation +##################################################### + +resource "ibm_resource_instance" "ibm_dns_instance" { + provider = ibm.ibm-is + count = var.ibm_dns_service.enable ? 1 : 0 + + name = var.ibm_dns_service.name + resource_group_id = module.landing_zone.resource_group_data["${var.prefix}-${local.second_rg_name}"] + location = "global" + service = "dns-svcs" + plan = "standard-dns" +} + +resource "ibm_dns_zone" "dns_zone" { + provider = ibm.ibm-is + count = var.ibm_dns_service.enable ? 1 : 0 + + name = var.ibm_dns_service.base_domain + instance_id = ibm_resource_instance.ibm_dns_instance[0].guid + description = "IBM DNS instance created by deployable architecture for OpenShift IPI on Power Virtual Server" + label = var.ibm_dns_service.label +} + +resource "ibm_dns_custom_resolver" "dns_resolver" { + provider = ibm.ibm-is + count = var.ibm_dns_service.enable ? 1 : 0 + + name = "${var.ibm_dns_service.name}-resolver" + instance_id = ibm_resource_instance.ibm_dns_instance[0].guid + description = "IBM DNS custom resolver for OpenShift IPI on Power Virtual Server" + high_availability = true + enabled = true + profile = "essential" + allow_disruptive_updates = false + locations { + subnet_crn = module.landing_zone.vpc_data[0].subnet_detail_map["zone-1"][0].crn + enabled = true + } + locations { + subnet_crn = module.landing_zone.vpc_data[0].subnet_detail_map["zone-1"][1].crn + enabled = true + } + locations { + subnet_crn = module.landing_zone.vpc_data[0].subnet_detail_map["zone-1"][2].crn + enabled = true + } +} diff --git a/modules/powervs-vpc-landing-zone/variables.tf b/modules/powervs-vpc-landing-zone/variables.tf index 5cba24b4..bb9822f0 100644 --- a/modules/powervs-vpc-landing-zone/variables.tf +++ b/modules/powervs-vpc-landing-zone/variables.tf @@ -55,6 +55,24 @@ variable "transit_gateway_global" { default = false } +variable "ibm_dns_service" { + description = "Create IBM DNS service instance, DNS zone, and custom resolver. If set to false, then the DNS service and zone will not be created. Conflicts with 'configure_dns_forwarder'." + type = object({ + enable = bool + name = optional(string) + base_domain = optional(string) + label = optional(string) + }) + default = { + "enable" = false + } + + validation { + condition = var.ibm_dns_service.enable != var.configure_dns_forwarder + error_message = "The 'ibm_dns_service' and 'configure_dns_forwarder' cannot both be true." + } +} + ##################################################### # Optional Parameter Network Services VSI Profile ##################################################### @@ -224,17 +242,24 @@ variable "powervs_custom_image_cos_service_credentials" { ##################################################### variable "client_to_site_vpn" { - description = "VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance." + description = "VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance. PowerVS server routes need to be created for the VPN so the PowerVS instances can be reached. Each route must have a unique name and destination CIDR." type = object({ enable = bool client_ip_pool = string vpn_client_access_group_users = list(string) - }) + powervs_server_routes = list(object({ + route_name = string + destination = string + action = string + })) + } + ) default = { "enable" : false, "client_ip_pool" : "192.168.0.0/16", - "vpn_client_access_group_users" : [] + "vpn_client_access_group_users" : [], + "powervs_server_routes" : null, } } @@ -302,13 +327,3 @@ variable "ansible_vault_password" { error_message = "ansible_vault_password is required when enable_scc_wp=true" } } - -################################################# -# Optional Parameters DNS IP -################################################# - -variable "vpn_dns_ips" { - description = "IP of the DNS server to use in VPN configuration" - type = list(string) - default = null -} diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index b63c4d91..5ffae11a 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -2,58 +2,52 @@ # PowerVS with VPC landing zone module ##################################################### -# module "standard" { -# source = "../../modules/powervs-vpc-landing-zone" - -# providers = { ibm.ibm-is = ibm.ibm-is, ibm.ibm-pi = ibm.ibm-pi, ibm.ibm-sm = ibm.ibm-sm } - -# powervs_zone = var.powervs_zone -# prefix = var.prefix -# external_access_ip = var.external_access_ip -# ssh_public_key = var.ssh_public_key -# ssh_private_key = var.ssh_private_key -# client_to_site_vpn = var.client_to_site_vpn -# vpc_intel_images = var.vpc_intel_images -# configure_dns_forwarder = false -# configure_ntp_forwarder = var.configure_ntp_forwarder -# configure_nfs_server = var.configure_nfs_server -# dns_forwarder_config = null -# nfs_server_config = var.nfs_server_config -# powervs_resource_group_name = var.powervs_resource_group_name -# powervs_management_network = null -# powervs_backup_network = null -# tags = var.tags -# sm_service_plan = var.sm_service_plan -# existing_sm_instance_guid = var.existing_sm_instance_guid -# existing_sm_instance_region = var.existing_sm_instance_region -# network_services_vsi_profile = var.network_services_vsi_profile -# enable_monitoring = var.enable_monitoring -# existing_monitoring_instance_crn = var.existing_monitoring_instance_crn -# enable_scc_wp = var.enable_scc_wp -# ansible_vault_password = var.ansible_vault_password -# } - -##################################################### -# DNS Service & Zone Creation -##################################################### - -resource "ibm_resource_instance" "ibm_dns_instance" { - provider = ibm.ibm-is - - name = "${var.cluster_name}-dns" - resource_group_id = "" # TODO: replace with module output - location = "global" - service = "dns-svcs" - plan = "standard-dns" +locals { + powervs_server_routes = [ + { + route_name = "cluster_network" + destination = var.cluster_network_config.cluster_network_cidr + action = "deliver" + }, + { + route_name = "cluster_service_network" + destination = var.cluster_network_config.cluster_service_network_cidr + action = "deliver" + } + ] + client_to_site_vpn = merge(var.client_to_site_vpn, { "powervs_server_routes" : local.powervs_server_routes }) } -resource "ibm_dns_zone" "dns_zone" { - provider = ibm.ibm-is - - name = var.cluster_base_domain - instance_id = ibm_resource_instance.ibm_dns_instance.guid - description = "IBM DNS instance created by deployable architecture for OpenShift IPI on Power Virtual Server" - label = var.cluster_name +module "standard" { + source = "../../modules/powervs-vpc-landing-zone" + + providers = { ibm.ibm-is = ibm.ibm-is, ibm.ibm-pi = ibm.ibm-pi, ibm.ibm-sm = ibm.ibm-sm } + + powervs_zone = var.powervs_zone + prefix = var.prefix + external_access_ip = var.external_access_ip + ssh_public_key = var.ssh_public_key + ssh_private_key = var.ssh_private_key + client_to_site_vpn = local.client_to_site_vpn + vpc_intel_images = var.vpc_intel_images + configure_dns_forwarder = false + configure_ntp_forwarder = var.configure_ntp_forwarder + configure_nfs_server = var.configure_nfs_server + dns_forwarder_config = null + nfs_server_config = var.nfs_server_config + powervs_resource_group_name = var.powervs_resource_group_name + powervs_management_network = null + powervs_backup_network = null + tags = var.tags + sm_service_plan = var.sm_service_plan + existing_sm_instance_guid = var.existing_sm_instance_guid + existing_sm_instance_region = var.existing_sm_instance_region + network_services_vsi_profile = var.network_services_vsi_profile + enable_monitoring = var.enable_monitoring + existing_monitoring_instance_crn = var.existing_monitoring_instance_crn + enable_scc_wp = var.enable_scc_wp + ansible_vault_password = var.ansible_vault_password + ibm_dns_service = { enable = true, name = "${var.cluster_name}-dns", base_domain = var.cluster_base_domain, label = var.cluster_name } } ##################################################### @@ -66,11 +60,11 @@ locals { } module "ocp_cluster_install_configuration" { - source = "../../modules/ansible" - #depends_on = [ module.standard ] # TODO: uncomment during integration + source = "../../modules/ansible" + depends_on = [module.standard] - bastion_host_ip = "" # TODO: replace with module output - ansible_host_or_ip = "" # TODO: replace with module output + bastion_host_ip = module.standard.access_host_or_ip + ansible_host_or_ip = module.standard.ansible_host_or_ip ssh_private_key = var.ssh_private_key configure_ansible_host = false @@ -95,12 +89,12 @@ module "ocp_cluster_install_configuration" { MASTER_PROC_TYPE : var.cluster_master_node_config.proc_type, MASTER_REPLICAS : var.cluster_master_node_config.replicas, USER_ID : var.user_id, - TRANSIT_GATEWAY_NAME : "", # TODO: replace with module output - POWERVS_WORKSPACE_GUID : "", # TODO: replace with module output + TRANSIT_GATEWAY_NAME : module.standard.transit_gateway_name, + POWERVS_WORKSPACE_GUID : module.standard.powervs_workspace_guid, RESOURCE_GROUP : var.powervs_resource_group_name, POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, - VPC_NAME : "", # TODO: replace with module output + VPC_NAME : module.standard.vpc_names[0], VPC_REGION : local.vpc_region PULL_SECRET_FILE : jsonencode(var.openshift_pull_secret), SSH_KEY : var.ssh_public_key, @@ -108,15 +102,15 @@ module "ocp_cluster_install_configuration" { src_inventory_template_name = "inventory.tftpl" dst_inventory_file_name = "${var.cluster_name}-playbook-ocp-install-config-inventory" - inventory_template_vars = { "host_or_ip" : "" } #TODO: replace with module output (ansible_host_or_ip) + inventory_template_vars = { "host_or_ip" : module.standard.ansible_host_or_ip } } module "ocp_cluster_manifest_creation" { source = "../../modules/ansible" depends_on = [module.ocp_cluster_install_configuration] - bastion_host_ip = "" # TODO: replace with module output - ansible_host_or_ip = "" # TODO: replace with module output + bastion_host_ip = module.standard.access_host_or_ip + ansible_host_or_ip = module.standard.ansible_host_or_ip ssh_private_key = var.ssh_private_key configure_ansible_host = false ibmcloud_api_key = var.ibmcloud_api_key @@ -137,15 +131,15 @@ module "ocp_cluster_manifest_creation" { src_inventory_template_name = "inventory.tftpl" dst_inventory_file_name = "${var.cluster_name}-playbook-ocp-install-config-inventory" - inventory_template_vars = { "host_or_ip" : "" } #TODO: replace with module output (ansible_host_or_ip) + inventory_template_vars = { "host_or_ip" : module.standard.ansible_host_or_ip } } module "ocp_cluster_deployment" { source = "../../modules/ansible" depends_on = [module.ocp_cluster_manifest_creation] - bastion_host_ip = "" # TODO: replace with module output - ansible_host_or_ip = "" # TODO: replace with module output + bastion_host_ip = module.standard.access_host_or_ip + ansible_host_or_ip = module.standard.ansible_host_or_ip ssh_private_key = var.ssh_private_key configure_ansible_host = false ibmcloud_api_key = var.ibmcloud_api_key @@ -169,5 +163,5 @@ module "ocp_cluster_deployment" { src_inventory_template_name = "inventory.tftpl" dst_inventory_file_name = "${var.cluster_name}-playbook-ocp-install-config-inventory" - inventory_template_vars = { "host_or_ip" : "" } #TODO: replace with module output (ansible_host_or_ip) + inventory_template_vars = { "host_or_ip" : module.standard.ansible_host_or_ip } } diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index f4d519c1..6d2fa24e 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -53,16 +53,6 @@ variable "cluster_name" { type = string } -##################################################### -# Optional Parameters PowerVS Instance -##################################################### - -variable "custom_profile_instance_boot_image" { - description = "Override the t-shirt size specs of PowerVS Workspace instance by selecting an image name and providing valid 'custom_profile' optional parameter." - type = string - default = "none" -} - ##################################################### # Optional Parameters Openshift Cluster ##################################################### @@ -258,7 +248,7 @@ variable "existing_sm_instance_region" { # Schematics Output ############################################################################# -# tflint-ignore: terraform_naming_convention +# tflint-ignore: all variable "IC_SCHEMATICS_WORKSPACE_ID" { description = "leave blank if running locally. This variable will be automatically populated if running from an IBM Cloud Schematics workspace" type = string diff --git a/solutions/standard-openshift/versions.tf b/solutions/standard-openshift/versions.tf index 28ea6758..0878d4cb 100644 --- a/solutions/standard-openshift/versions.tf +++ b/solutions/standard-openshift/versions.tf @@ -7,16 +7,11 @@ terraform { required_providers { ibm = { source = "IBM-Cloud/ibm" - version = "1.80.4" + version = "1.81.1" } restapi = { source = "Mastercard/restapi" version = "2.0.1" } - time = { - source = "hashicorp/time" - version = "0.13.1" - } - } } diff --git a/solutions/standard-plus-vsi/main.tf b/solutions/standard-plus-vsi/main.tf index 3a63b8e0..2d8dc9f4 100644 --- a/solutions/standard-plus-vsi/main.tf +++ b/solutions/standard-plus-vsi/main.tf @@ -2,6 +2,22 @@ # PowerVS with VPC landing zone module ##################################################### +locals { + powervs_server_routes = [ + { + route_name = var.powervs_management_network.name + destination = var.powervs_management_network.cidr + action = "deliver" + }, + { + route_name = var.powervs_backup_network.name + destination = var.powervs_backup_network.cidr + action = "deliver" + } + ] + client_to_site_vpn = merge(var.client_to_site_vpn, { "powervs_server_routes" : local.powervs_server_routes }) +} + module "standard" { source = "../../modules/powervs-vpc-landing-zone" @@ -12,7 +28,7 @@ module "standard" { external_access_ip = var.external_access_ip ssh_public_key = var.ssh_public_key ssh_private_key = var.ssh_private_key - client_to_site_vpn = var.client_to_site_vpn + client_to_site_vpn = local.client_to_site_vpn vpc_intel_images = var.vpc_intel_images configure_dns_forwarder = var.configure_dns_forwarder configure_ntp_forwarder = var.configure_ntp_forwarder diff --git a/solutions/standard/main.tf b/solutions/standard/main.tf index 23291462..6564dcd1 100644 --- a/solutions/standard/main.tf +++ b/solutions/standard/main.tf @@ -2,6 +2,22 @@ # PowerVS with VPC landing zone module #################################################### +locals { + powervs_server_routes = [ + { + route_name = var.powervs_management_network.name + destination = var.powervs_management_network.cidr + action = "deliver" + }, + { + route_name = var.powervs_backup_network.name + destination = var.powervs_backup_network.cidr + action = "deliver" + } + ] + client_to_site_vpn = merge(var.client_to_site_vpn, { "powervs_server_routes" : local.powervs_server_routes }) +} + module "standard" { source = "../../modules/powervs-vpc-landing-zone" @@ -12,7 +28,7 @@ module "standard" { external_access_ip = var.external_access_ip ssh_public_key = var.ssh_public_key ssh_private_key = var.ssh_private_key - client_to_site_vpn = var.client_to_site_vpn + client_to_site_vpn = local.client_to_site_vpn vpc_intel_images = var.vpc_intel_images transit_gateway_global = var.transit_gateway_global configure_dns_forwarder = var.configure_dns_forwarder From 1c1902848c54bc4f7adf5acd037b42637c637604 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 22 Aug 2025 17:15:46 +0200 Subject: [PATCH 05/83] fix: invalid powervs route names --- solutions/standard-openshift/main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 5ffae11a..65b7e08a 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -5,12 +5,12 @@ locals { powervs_server_routes = [ { - route_name = "cluster_network" + route_name = "cluster-network" destination = var.cluster_network_config.cluster_network_cidr action = "deliver" }, { - route_name = "cluster_service_network" + route_name = "cluster-service-network" destination = var.cluster_network_config.cluster_service_network_cidr action = "deliver" } From ef069c56de75d3eefa377d28aa768fc28d2d8fd9 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 25 Aug 2025 14:59:16 +0200 Subject: [PATCH 06/83] fix: vpn supports only two dns servers --- modules/powervs-vpc-landing-zone/client2sitevpn.tf | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/powervs-vpc-landing-zone/client2sitevpn.tf b/modules/powervs-vpc-landing-zone/client2sitevpn.tf index f2f2d006..1a7aa74b 100644 --- a/modules/powervs-vpc-landing-zone/client2sitevpn.tf +++ b/modules/powervs-vpc-landing-zone/client2sitevpn.tf @@ -118,12 +118,13 @@ module "client_to_site_vpn" { providers = { ibm = ibm.ibm-is } count = var.client_to_site_vpn.enable ? 1 : 0 - vpn_gateway_name = "${var.prefix}-vpc-pvs-vpn" - resource_group_id = module.landing_zone.resource_group_data["${var.prefix}-${local.second_rg_name}"] - access_group_name = "${var.prefix}-client-to-site-vpn-access-group" - subnet_ids = [for subnet in module.landing_zone.subnet_data : subnet.id if subnet.name == "${var.prefix}-edge-vpn-zone-1"] - client_ip_pool = var.client_to_site_vpn.client_ip_pool - client_dns_server_ips = var.ibm_dns_service.enable ? [for location in ibm_dns_custom_resolver.dns_resolver[0].locations : location.dns_server_ip] : null + vpn_gateway_name = "${var.prefix}-vpc-pvs-vpn" + resource_group_id = module.landing_zone.resource_group_data["${var.prefix}-${local.second_rg_name}"] + access_group_name = "${var.prefix}-client-to-site-vpn-access-group" + subnet_ids = [for subnet in module.landing_zone.subnet_data : subnet.id if subnet.name == "${var.prefix}-edge-vpn-zone-1"] + client_ip_pool = var.client_to_site_vpn.client_ip_pool + # vpn supports only 2 dns servers + client_dns_server_ips = var.ibm_dns_service.enable ? slice([for location in ibm_dns_custom_resolver.dns_resolver[0].locations : location.dns_server_ip], 0, 2) : null server_cert_crn = module.secrets_manager_private_certificate[0].secret_crn vpn_client_access_group_users = var.client_to_site_vpn.vpn_client_access_group_users vpn_server_routes = local.vpn_server_routes From 4d14b9f267811cdf2af3ca54cccd82df0c6acf0d Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 26 Aug 2025 15:05:00 +0200 Subject: [PATCH 07/83] fix: add lon06 to openshift region map --- solutions/standard-openshift/provider.tf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/provider.tf b/solutions/standard-openshift/provider.tf index 4061e139..2d77c632 100644 --- a/solutions/standard-openshift/provider.tf +++ b/solutions/standard-openshift/provider.tf @@ -58,8 +58,9 @@ locals { "eu-de-2" = "eu-de" "mad02" = "mad" "mad04" = "mad" - "lon04" = "lon" - "osa21" = "osa" + # "lon04" = "lon" not yet supported by IPI + "lon06" = "lon" + "osa21" = "osa" #"tok04" = "jp-tok" "us-south" = "us-south" "dal10" = "dal" From 1ee7430bbd5e8e29fd915777df3a5af802402601 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 26 Aug 2025 16:28:54 +0200 Subject: [PATCH 08/83] feat: automatically select supported system type if user passes null --- solutions/standard-openshift/main.tf | 23 +++++++++++++++-------- solutions/standard-openshift/variables.tf | 8 ++++---- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 65b7e08a..325ffde6 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -16,6 +16,13 @@ locals { } ] client_to_site_vpn = merge(var.client_to_site_vpn, { "powervs_server_routes" : local.powervs_server_routes }) + + # automatically pick the supported system type unless it's overwritten by the user + p10_unsupported_regions = ["che01", "lon04", "lon06", "mon01", "syd04", "syd05", "tor01", "us-east"] # datacenters that don't support P10 yet + system_type = contains(local.p10_unsupported_regions, var.powervs_zone) ? "s922" : "s1022" + + cluster_master_node_config = var.cluster_master_node_config.system_type != null ? var.cluster_master_node_config : merge(var.cluster_master_node_config, { system_type : local.system_type }) + cluster_worker_node_config = var.cluster_worker_node_config.system_type != null ? var.cluster_worker_node_config : merge(var.cluster_worker_node_config, { system_type : local.system_type }) } module "standard" { @@ -80,14 +87,14 @@ module "ocp_cluster_install_configuration" { CLUSTER_NAME : var.cluster_name, CLUSTER_NETWORK : var.cluster_network_config.cluster_network_cidr, CLUSTER_SERVICE_NETWORK : var.cluster_network_config.cluster_service_network_cidr, - WORKER_PROCESSORS : var.cluster_worker_node_config.processors, - WORKER_SYSTEM_TYPE : var.cluster_worker_node_config.system_type, - WORKER_PROC_TYPE : var.cluster_worker_node_config.proc_type, - WORKER_REPLICAS : var.cluster_worker_node_config.replicas, - MASTER_PROCESSORS : var.cluster_master_node_config.processors, - MASTER_SYSTEM_TYPE : var.cluster_master_node_config.system_type, - MASTER_PROC_TYPE : var.cluster_master_node_config.proc_type, - MASTER_REPLICAS : var.cluster_master_node_config.replicas, + WORKER_PROCESSORS : local.cluster_worker_node_config.processors, + WORKER_SYSTEM_TYPE : local.cluster_worker_node_config.system_type, + WORKER_PROC_TYPE : local.cluster_worker_node_config.proc_type, + WORKER_REPLICAS : local.cluster_worker_node_config.replicas, + MASTER_PROCESSORS : local.cluster_master_node_config.processors, + MASTER_SYSTEM_TYPE : local.cluster_master_node_config.system_type, + MASTER_PROC_TYPE : local.cluster_master_node_config.proc_type, + MASTER_REPLICAS : local.cluster_master_node_config.replicas, USER_ID : var.user_id, TRANSIT_GATEWAY_NAME : module.standard.transit_gateway_name, POWERVS_WORKSPACE_GUID : module.standard.powervs_workspace_guid, diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 6d2fa24e..9fd85acd 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -82,7 +82,7 @@ variable "cluster_network_config" { } variable "cluster_master_node_config" { - description = "Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count." + description = "Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'." type = object({ processors = number system_type = string @@ -91,14 +91,14 @@ variable "cluster_master_node_config" { }) default = { processors = 4 - system_type = "s1022" + system_type = null proc_type = "Dedicated" replicas = 3 } } variable "cluster_worker_node_config" { - description = "Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count." + description = "Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'." type = object({ processors = number system_type = string @@ -107,7 +107,7 @@ variable "cluster_worker_node_config" { }) default = { processors = 4 - system_type = "s1022" + system_type = null proc_type = "Dedicated" replicas = 3 } From a9486f1a36059d0df08c216aa64de3c52f3e7de0 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 27 Aug 2025 10:06:59 +0200 Subject: [PATCH 09/83] fix: add wait for install on cluster create --- .secrets.baseline | 4 +- .../playbook-deploy-ocp-cluster.yml.tftpl | 49 ++++++++++++++----- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 68895c6e..f081b4a3 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-08-18T14:30:58Z", + "generated_at": "2025-08-27T08:05:50Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -112,7 +112,7 @@ "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 41, + "line_number": 57, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl index 2376ab21..65564540 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl @@ -34,15 +34,40 @@ } mode: '0600' - - name: Run openshift-install create cluster - ansible.builtin.shell: | - openshift-install create cluster --dir={{ install_dir }} --log-level=debug - environment: - IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" - OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT: "{{ openshift_install_bootstrap_timeout }}" - OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT: "{{ openshift_install_machine_wait_timeout }}" - OPENSHIFT_INSTALL_CLUSTER_TIMEOUT: "{{ openshift_install_cluster_timeout }}" - OPENSHIFT_INSTALL_DESTROY_TIMEOUT: "{{ openshift_install_destroy_timeout }}" - - register: install_output - ignore_errors: false + - name: Create the Cluster + block: + - name: Run openshift-install create cluster + ansible.builtin.shell: | + openshift-install create cluster --dir={{ install_dir }} --log-level=debug + environment: + IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" + OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT: "{{ openshift_install_bootstrap_timeout }}" + OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT: "{{ openshift_install_machine_wait_timeout }}" + OPENSHIFT_INSTALL_CLUSTER_TIMEOUT: "{{ openshift_install_cluster_timeout }}" + OPENSHIFT_INSTALL_DESTROY_TIMEOUT: "{{ openshift_install_destroy_timeout }}" + + register: install_output + ignore_errors: false + + rescue: + - name: Wait for OpenShift install to complete + ansible.builtin.shell: | + openshift-install wait-for install-complete + environment: + IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" + OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT: "{{ openshift_install_bootstrap_timeout }}" + OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT: "{{ openshift_install_machine_wait_timeout }}" + OPENSHIFT_INSTALL_CLUSTER_TIMEOUT: "{{ openshift_install_cluster_timeout }}" + OPENSHIFT_INSTALL_DESTROY_TIMEOUT: "{{ openshift_install_destroy_timeout }}" + + register: wait_for_install_output + ignore_errors: false + + - name: Print wait_for_install_output + ansible.builtin.debug: + var: wait_for_install_output + + always: + - name: Print Create openshift-install create cluster install_output + ansible.builtin.debug: + var: install_output From f5cb58891aa2b2674ba3358f781661f06488bd28 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 27 Aug 2025 10:07:34 +0200 Subject: [PATCH 10/83] fix: use ocp-rg --- solutions/standard-openshift/main.tf | 8 ++++---- solutions/standard-openshift/variables.tf | 6 ------ 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 325ffde6..25fc9c71 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -42,7 +42,7 @@ module "standard" { configure_nfs_server = var.configure_nfs_server dns_forwarder_config = null nfs_server_config = var.nfs_server_config - powervs_resource_group_name = var.powervs_resource_group_name + powervs_resource_group_name = null powervs_management_network = null powervs_backup_network = null tags = var.tags @@ -98,7 +98,7 @@ module "ocp_cluster_install_configuration" { USER_ID : var.user_id, TRANSIT_GATEWAY_NAME : module.standard.transit_gateway_name, POWERVS_WORKSPACE_GUID : module.standard.powervs_workspace_guid, - RESOURCE_GROUP : var.powervs_resource_group_name, + RESOURCE_GROUP : "ocp-rg", POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, VPC_NAME : module.standard.vpc_names[0], @@ -133,7 +133,7 @@ module "ocp_cluster_manifest_creation" { CLUSTER_DIR : "/root/${var.cluster_dir}", REQUESTS_DIR : "./credreqs" ACCOUNT_NAME : var.cluster_name, - RESOURCE_GROUP : var.powervs_resource_group_name, + RESOURCE_GROUP : "ocp-rg", } src_inventory_template_name = "inventory.tftpl" @@ -160,7 +160,7 @@ module "ocp_cluster_deployment" { IBM_ID : var.user_id POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, - RESOURCE_GROUP : var.powervs_resource_group_name, + RESOURCE_GROUP : "ocp-rg", CLUSTER_DIR : var.cluster_dir, OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT : "120m", OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT : "35m", diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 9fd85acd..1db8441b 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -117,12 +117,6 @@ variable "cluster_worker_node_config" { # Optional Parameters PowerVS Workspace ##################################################### -variable "powervs_resource_group_name" { - description = "Existing IBM Cloud resource group name." - type = string - default = "Default" -} - variable "tags" { description = "List of tag names for the IBM Cloud PowerVS workspace" type = list(string) From 631d68629faccb3539d973f242cf633545d5562e Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 28 Aug 2025 10:21:34 +0200 Subject: [PATCH 11/83] fix: second rg wasn't used for PowerVS workspace --- modules/powervs-vpc-landing-zone/README.md | 2 +- modules/powervs-vpc-landing-zone/outputs.tf | 2 +- modules/powervs-vpc-landing-zone/powervs-ws.tf | 2 +- modules/powervs-vpc-landing-zone/variables.tf | 2 +- solutions/standard-openshift/main.tf | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/powervs-vpc-landing-zone/README.md b/modules/powervs-vpc-landing-zone/README.md index a1166f95..fec04010 100644 --- a/modules/powervs-vpc-landing-zone/README.md +++ b/modules/powervs-vpc-landing-zone/README.md @@ -161,7 +161,7 @@ Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastr | [powervs\_custom\_image\_cos\_service\_credentials](#input\_powervs\_custom\_image\_cos\_service\_credentials) | Service credentials for the Cloud Object Storage bucket containing the custom PowerVS images. The bucket must have HMAC credentials enabled. Click [here](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-service-credentials) for a json example of a service credential. | `string` | `null` | no | | [powervs\_custom\_images](#input\_powervs\_custom\_images) | Optionally import up to three custom images from Cloud Object Storage into PowerVS workspace. Requires 'powervs\_custom\_image\_cos\_configuration' to be set. image\_name: string, must be unique. Name of image inside PowerVS workspace. file\_name: string, object key of image inside COS bucket. storage\_tier: string, storage tier which image will be stored in after import. Supported values: tier0, tier1, tier3, tier5k. sap\_type: optional string, Supported values: null, Hana, Netweaver, use null for non-SAP image. |
object({
powervs_custom_image1 = object({
image_name = string
file_name = string
storage_tier = string
sap_type = optional(string)
}),
powervs_custom_image2 = object({
image_name = string
file_name = string
storage_tier = string
sap_type = optional(string)
}),
powervs_custom_image3 = object({
image_name = string
file_name = string
storage_tier = string
sap_type = optional(string)
})
})
|
{
"powervs_custom_image1": {
"file_name": "",
"image_name": "",
"sap_type": null,
"storage_tier": ""
},
"powervs_custom_image2": {
"file_name": "",
"image_name": "",
"sap_type": null,
"storage_tier": ""
},
"powervs_custom_image3": {
"file_name": "",
"image_name": "",
"sap_type": null,
"storage_tier": ""
}
}
| no | | [powervs\_management\_network](#input\_powervs\_management\_network) | Name of the IBM Cloud PowerVS management subnet and CIDR to create. |
object({
name = string
cidr = string
})
|
{
"cidr": "10.51.0.0/24",
"name": "mgmt_net"
}
| no | -| [powervs\_resource\_group\_name](#input\_powervs\_resource\_group\_name) | Existing IBM Cloud resource group name. Used for PowerVS related resources. If null, ocp-rg is created and used for TGW, VPC, and PowerVS resources. | `string` | n/a | yes | +| [powervs\_resource\_group\_name](#input\_powervs\_resource\_group\_name) | Existing IBM Cloud resource group name. Used for PowerVS related resources. If null, '-ocp-rg' is created and used for TGW, VPC, and PowerVS resources. | `string` | n/a | yes | | [powervs\_zone](#input\_powervs\_zone) | IBM Cloud data center location where IBM PowerVS infrastructure will be created. | `string` | n/a | yes | | [prefix](#input\_prefix) | A unique identifier for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters. | `string` | n/a | yes | | [sm\_service\_plan](#input\_sm\_service\_plan) | The service/pricing plan to use when provisioning a new Secrets Manager instance. Allowed values: `standard` and `trial`. Only used if `existing_sm_instance_guid` is set to null. | `string` | `"standard"` | no | diff --git a/modules/powervs-vpc-landing-zone/outputs.tf b/modules/powervs-vpc-landing-zone/outputs.tf index a6b1efd9..f00e61f1 100644 --- a/modules/powervs-vpc-landing-zone/outputs.tf +++ b/modules/powervs-vpc-landing-zone/outputs.tf @@ -113,7 +113,7 @@ output "powervs_zone" { output "powervs_resource_group_name" { description = "IBM Cloud resource group where PowerVS infrastructure is created." - value = var.powervs_resource_group_name + value = "${var.prefix}-${local.second_rg_name}" } output "powervs_workspace_name" { diff --git a/modules/powervs-vpc-landing-zone/powervs-ws.tf b/modules/powervs-vpc-landing-zone/powervs-ws.tf index 8176ee75..235c1730 100644 --- a/modules/powervs-vpc-landing-zone/powervs-ws.tf +++ b/modules/powervs-vpc-landing-zone/powervs-ws.tf @@ -32,7 +32,7 @@ module "powervs_workspace" { providers = { ibm = ibm.ibm-pi } pi_zone = var.powervs_zone - pi_resource_group_name = var.powervs_resource_group_name + pi_resource_group_id = module.landing_zone.resource_group_data["${var.prefix}-${local.second_rg_name}"] pi_workspace_name = "${var.prefix}-${var.powervs_zone}-power-workspace" pi_ssh_public_key = { "name" = "${var.prefix}-${var.powervs_zone}-pvs-ssh-key", value = var.ssh_public_key } pi_private_subnet_1 = var.powervs_management_network diff --git a/modules/powervs-vpc-landing-zone/variables.tf b/modules/powervs-vpc-landing-zone/variables.tf index bb9822f0..b921940d 100644 --- a/modules/powervs-vpc-landing-zone/variables.tf +++ b/modules/powervs-vpc-landing-zone/variables.tf @@ -4,7 +4,7 @@ variable "powervs_zone" { } variable "powervs_resource_group_name" { - description = "Existing IBM Cloud resource group name. Used for PowerVS related resources. If null, ocp-rg is created and used for TGW, VPC, and PowerVS resources." + description = "Existing IBM Cloud resource group name. Used for PowerVS related resources. If null, '-ocp-rg' is created and used for TGW, VPC, and PowerVS resources." type = string } diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 25fc9c71..d340995f 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -98,7 +98,7 @@ module "ocp_cluster_install_configuration" { USER_ID : var.user_id, TRANSIT_GATEWAY_NAME : module.standard.transit_gateway_name, POWERVS_WORKSPACE_GUID : module.standard.powervs_workspace_guid, - RESOURCE_GROUP : "ocp-rg", + RESOURCE_GROUP : module.standard.powervs_resource_group_name, POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, VPC_NAME : module.standard.vpc_names[0], @@ -133,7 +133,7 @@ module "ocp_cluster_manifest_creation" { CLUSTER_DIR : "/root/${var.cluster_dir}", REQUESTS_DIR : "./credreqs" ACCOUNT_NAME : var.cluster_name, - RESOURCE_GROUP : "ocp-rg", + RESOURCE_GROUP : module.standard.powervs_resource_group_name, } src_inventory_template_name = "inventory.tftpl" @@ -160,7 +160,7 @@ module "ocp_cluster_deployment" { IBM_ID : var.user_id POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, - RESOURCE_GROUP : "ocp-rg", + RESOURCE_GROUP : module.standard.powervs_resource_group_name, CLUSTER_DIR : var.cluster_dir, OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT : "120m", OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT : "35m", From 52cb07220e60fd766372132580225e0c187aafd3 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 28 Aug 2025 13:30:11 +0200 Subject: [PATCH 12/83] fix: switch from wait for install to wait for bootstrap and add missing arguments --- .../playbook-deploy-ocp-cluster.yml.tftpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl index 65564540..3d7adaa7 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl @@ -52,7 +52,7 @@ rescue: - name: Wait for OpenShift install to complete ansible.builtin.shell: | - openshift-install wait-for install-complete + openshift-install wait-for bootstrap-complete --dir={{ install_dir }} --log-level=debug environment: IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT: "{{ openshift_install_bootstrap_timeout }}" From 06a807a9d01aa709b505dd235d1376397cf4f2d3 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 29 Aug 2025 09:14:29 +0200 Subject: [PATCH 13/83] feat: add machine network to avoid conflict with vpn network --- .secrets.baseline | 4 ++-- .../playbook-configure-ocp-cluster.yml.tftpl | 3 +++ solutions/standard-openshift/main.tf | 1 + solutions/standard-openshift/variables.tf | 2 ++ 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index f081b4a3..88453f41 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-08-27T08:05:50Z", + "generated_at": "2025-08-29T07:12:50Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -92,7 +92,7 @@ "hashed_secret": "6f803b24314c39062efe38d0c1da8c472f47eab3", "is_secret": false, "is_verified": false, - "line_number": 167, + "line_number": 170, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl index 9bb771a8..700cdd16 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl @@ -7,6 +7,7 @@ cluster_name: "${CLUSTER_NAME}" cluster_network: "${CLUSTER_NETWORK}" cluster_service_network: "${CLUSTER_SERVICE_NETWORK}" + machine_network: "${MACHINE_NETWORK}" worker_processors: "${WORKER_PROCESSORS}" worker_system_type: "${WORKER_SYSTEM_TYPE}" worker_proc_type: "${WORKER_PROC_TYPE}" @@ -130,6 +131,8 @@ networkType: OVNKubernetes serviceNetwork: - "{{ cluster_service_network }}" + machineNetwork: + - cidr: {{ machine_network }} platform: powervs: diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index d340995f..585ead14 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -87,6 +87,7 @@ module "ocp_cluster_install_configuration" { CLUSTER_NAME : var.cluster_name, CLUSTER_NETWORK : var.cluster_network_config.cluster_network_cidr, CLUSTER_SERVICE_NETWORK : var.cluster_network_config.cluster_service_network_cidr, + MACHINE_NETWORK : var.cluster_network_config.cluster_machine_network_cidr WORKER_PROCESSORS : local.cluster_worker_node_config.processors, WORKER_SYSTEM_TYPE : local.cluster_worker_node_config.system_type, WORKER_PROC_TYPE : local.cluster_worker_node_config.proc_type, diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 1db8441b..eaa4de7e 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -74,10 +74,12 @@ variable "cluster_network_config" { type = object({ cluster_network_cidr = string cluster_service_network_cidr = string + cluster_machine_network_cidr = string }) default = { cluster_network_cidr = "172.168.0.0/22" cluster_service_network_cidr = "10.67.0.0/24" + cluster_machine_network_cidr = "10.72.0.0/24" } } From d8f22c3282bb2a2f00bad77d7c3c48d852663914 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 1 Sep 2025 09:50:40 +0200 Subject: [PATCH 14/83] fix: add vpc subnet to install-config --- .secrets.baseline | 4 ++-- .../playbook-configure-ocp-cluster.yml.tftpl | 2 ++ solutions/standard-openshift/main.tf | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 88453f41..5fcc4bdc 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-08-29T07:12:50Z", + "generated_at": "2025-09-01T07:44:40Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -92,7 +92,7 @@ "hashed_secret": "6f803b24314c39062efe38d0c1da8c472f47eab3", "is_secret": false, "is_verified": false, - "line_number": 170, + "line_number": 172, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl index 700cdd16..4df6bbe9 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl @@ -23,6 +23,7 @@ powervs_region: "${POWERVS_REGION}" powervs_zone: "${POWERVS_ZONE}" vpc_name: "${VPC_NAME}" + vpc_subnet_name: "${VPC_SUBNET_NAME}" vpc_region: "${VPC_REGION}" pull_secret: '${PULL_SECRET_FILE}' ssh_key: "${SSH_KEY}" @@ -142,6 +143,7 @@ zone: {{ powervs_zone }} tgName: {{ transit_gateway_name }} vpcName: {{ vpc_name }} + subnetName: {{ vpc_subnet_name }} vpcRegion: {{ vpc_region }} serviceInstanceGUID: {{ powervs_workspace_guid }} diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 585ead14..65cb7c7a 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -103,6 +103,7 @@ module "ocp_cluster_install_configuration" { POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, VPC_NAME : module.standard.vpc_names[0], + VPC_SUBNET_NAME : "${var.prefix}-edge-vsi-edge-zone-1" VPC_REGION : local.vpc_region PULL_SECRET_FILE : jsonencode(var.openshift_pull_secret), SSH_KEY : var.ssh_public_key, From 6ff37669c1e26dea12122d8cf3c02c7442632e67 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 1 Sep 2025 09:51:53 +0200 Subject: [PATCH 15/83] chore: add validation for proc_type --- solutions/standard-openshift/variables.tf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index eaa4de7e..6bbc178c 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -97,6 +97,10 @@ variable "cluster_master_node_config" { proc_type = "Dedicated" replicas = 3 } + validation { + condition = contains(["Capped", "Dedicated", "Shared"], var.cluster_master_node_config.proc_type) + error_message = "Unsupported value for cluster_master_node_config.proc_type. Allowed values: Capped, Dedicated, Shared." + } } variable "cluster_worker_node_config" { @@ -113,6 +117,10 @@ variable "cluster_worker_node_config" { proc_type = "Dedicated" replicas = 3 } + validation { + condition = contains(["Capped", "Dedicated", "Shared"], var.cluster_worker_node_config.proc_type) + error_message = "Unsupported value for cluster_worker_node_config.proc_type. Allowed values: Capped, Dedicated, Shared." + } } ##################################################### From ac9fd0ad2d2c5388b93c9758b66ac49f33f556d3 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 1 Sep 2025 10:40:10 +0200 Subject: [PATCH 16/83] chore add validation for system_type --- solutions/standard-openshift/variables.tf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 6bbc178c..a5912b65 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -97,6 +97,10 @@ variable "cluster_master_node_config" { proc_type = "Dedicated" replicas = 3 } + validation { + condition = var.cluster_master_node_config.system_type != null ? contains(["s1122", "s1022", "s922", "e980", "e1080", "e1050"], var.cluster_master_node_config.system_type) : true + error_message = "value" + } validation { condition = contains(["Capped", "Dedicated", "Shared"], var.cluster_master_node_config.proc_type) error_message = "Unsupported value for cluster_master_node_config.proc_type. Allowed values: Capped, Dedicated, Shared." @@ -117,6 +121,10 @@ variable "cluster_worker_node_config" { proc_type = "Dedicated" replicas = 3 } + validation { + condition = var.cluster_worker_node_config.system_type != null ? contains(["s1122", "s1022", "s922", "e980", "e1080", "e1050"], var.cluster_worker_node_config.system_type) : true + error_message = "value" + } validation { condition = contains(["Capped", "Dedicated", "Shared"], var.cluster_worker_node_config.proc_type) error_message = "Unsupported value for cluster_worker_node_config.proc_type. Allowed values: Capped, Dedicated, Shared." From c441b032f839bc00a96d1f06d8f858c5ee27b76e Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 3 Sep 2025 10:15:24 +0200 Subject: [PATCH 17/83] fix: wrong vpc subnet format --- .secrets.baseline | 4 ++-- .../playbook-configure-ocp-cluster.yml.tftpl | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 5fcc4bdc..77d7aeef 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-09-01T07:44:40Z", + "generated_at": "2025-09-03T08:15:16Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -92,7 +92,7 @@ "hashed_secret": "6f803b24314c39062efe38d0c1da8c472f47eab3", "is_secret": false, "is_verified": false, - "line_number": 172, + "line_number": 173, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl index 4df6bbe9..20191389 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl @@ -143,7 +143,8 @@ zone: {{ powervs_zone }} tgName: {{ transit_gateway_name }} vpcName: {{ vpc_name }} - subnetName: {{ vpc_subnet_name }} + vpcSubnets: + - {{ vpc_subnet_name }} vpcRegion: {{ vpc_region }} serviceInstanceGUID: {{ powervs_workspace_guid }} From 17e092dcc342719bace10baae5e4bb4df7eafed2 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 3 Sep 2025 10:18:52 +0200 Subject: [PATCH 18/83] debug: skip openshift playbooks for debugging purposes with pipeline --- .../deploy-openshift-cluster/ansible_exec.sh.tftpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl index 7406db66..24575c24 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl @@ -21,7 +21,7 @@ export ANSIBLE_PRIVATE_KEY_FILE=$${ansible_private_key_file} export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} #Execute ansible playbook -unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" +# unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" ## On failure: if [ $? -ne 0 ]; then rm -rf $${ansible_private_key_file} From 8226ce42ab16d81f1f943c63c9ec8bba82065e12 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 4 Sep 2025 10:18:51 +0200 Subject: [PATCH 19/83] fix: disable nfs and ntp forwarder by default --- solutions/standard-openshift/variables.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index a5912b65..010e3198 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -172,13 +172,13 @@ variable "external_access_ip" { variable "configure_ntp_forwarder" { description = "Specify if NTP forwarder will be configured. This will allow you to synchronize time between IBM PowerVS instances. NTP forwarder will be installed on the network-services vsi." type = bool - default = true + default = false } variable "configure_nfs_server" { description = "Specify if NFS server will be configured. This will allow you easily to share files between PowerVS instances (e.g., SAP installation files). [File storage share and mount target](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-create&interface=ui) in VPC will be created.. If yes, ensure 'nfs_server_config' optional variable is set properly below. Default value is '200GB' which will be mounted on specified directory in network-service vsi." type = bool - default = true + default = false } variable "nfs_server_config" { From f4f6b1b3f40f39d3f113e885da86ca232f145156 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 4 Sep 2025 13:11:15 +0200 Subject: [PATCH 20/83] fix: bad private subnet as default value --- solutions/standard-openshift/variables.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 010e3198..e7cc8eb5 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -77,7 +77,7 @@ variable "cluster_network_config" { cluster_machine_network_cidr = string }) default = { - cluster_network_cidr = "172.168.0.0/22" + cluster_network_cidr = "172.22.0.0/22" cluster_service_network_cidr = "10.67.0.0/24" cluster_machine_network_cidr = "10.72.0.0/24" } From d5aa9059b85cceadcb4c6e942dd09e123f5d54be Mon Sep 17 00:00:00 2001 From: Suraj Bharadwaj <101711050+surajsbharadwaj@users.noreply.github.com> Date: Mon, 8 Sep 2025 15:54:16 +0200 Subject: [PATCH 21/83] fix: ccp configs, remove ntp, nfs and DNS (#1152) * fix: configs; remove ntp, dns and nfs as services * fix: revert scc default value * chore: add readme.md * fix: remove task --- .secrets.baseline | 12 +++- .../ansible_exec.sh.tftpl | 2 +- .../playbook-configure-ocp-cluster.yml.tftpl | 21 ++++++- .../playbook-deploy-ocp-cluster.yml.tftpl | 21 ------- solutions/standard-openshift/README.md | 60 +++++++++++++++++++ solutions/standard-openshift/main.tf | 5 -- solutions/standard-openshift/variables.tf | 28 --------- 7 files changed, 91 insertions(+), 58 deletions(-) create mode 100644 solutions/standard-openshift/README.md diff --git a/.secrets.baseline b/.secrets.baseline index 77d7aeef..c14b5bf5 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-09-03T08:15:16Z", + "generated_at": "2025-09-08T13:32:00Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -95,6 +95,14 @@ "line_number": 173, "type": "Secret Keyword", "verified_result": null + }, + { + "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", + "is_secret": false, + "is_verified": false, + "line_number": 189, + "type": "Secret Keyword", + "verified_result": null } ], "modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl": [ @@ -112,7 +120,7 @@ "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 57, + "line_number": 55, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl index 24575c24..7406db66 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl @@ -21,7 +21,7 @@ export ANSIBLE_PRIVATE_KEY_FILE=$${ansible_private_key_file} export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} #Execute ansible playbook -# unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" +unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" ## On failure: if [ $? -ne 0 ]; then rm -rf $${ansible_private_key_file} diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl index 20191389..32ab89e5 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl @@ -133,7 +133,7 @@ serviceNetwork: - "{{ cluster_service_network }}" machineNetwork: - - cidr: {{ machine_network }} + - cidr: "{{ machine_network }}" platform: powervs: @@ -173,3 +173,22 @@ pullSecret: '{{ pull_secret }}' sshKey: "{{ ssh_key }}" + + - name: Ensure ~/.powervs directory exists + file: + path: "~/.powervs" + state: directory + mode: '0700' + + - name: Create ~/.powervs/config.json file securely + copy: + dest: "~/.powervs/config.json" + content: | + { + "id": "{{ user_id }}", + "apikey": "{{ lookup('env', 'IBMCLOUD_API_KEY') }}", + "region": "{{ powervs_region }}", + "zone": "{{ powervs_zone }}", + "resourcegroup": "{{ resource_group }}", + } + mode: '0600' diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl index 3d7adaa7..4bf0e578 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl @@ -3,8 +3,6 @@ hosts: all vars: - powervs_config_path: "~/.powervs/config.json" - id: "${IBM_ID}" region: "${POWERVS_REGION}" zone: "${POWERVS_ZONE}" resource_group: "${RESOURCE_GROUP}" @@ -15,25 +13,6 @@ openshift_install_destroy_timeout: "${OPENSHIFT_INSTALL_DESTROY_TIMEOUT}" tasks: - - name: Ensure ~/.powervs directory exists - file: - path: "{{ powervs_config_path | dirname }}" - state: directory - mode: '0700' - - - name: Create ~/.powervs/config.json file securely - copy: - dest: "{{ powervs_config_path }}" - content: | - { - "id": "{{ id }}", - "apikey": "{{ lookup('env', 'IBMCLOUD_API_KEY') }}", - "region": "{{ region }}", - "zone": "{{ zone }}", - "resourcegroup": "{{ resource_group }}", - } - mode: '0600' - - name: Create the Cluster block: - name: Run openshift-install create cluster diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md new file mode 100644 index 00000000..aca12cd4 --- /dev/null +++ b/solutions/standard-openshift/README.md @@ -0,0 +1,60 @@ + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.9 | +| [ibm](#requirement\_ibm) | 1.81.1 | +| [restapi](#requirement\_restapi) | 2.0.1 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| [ocp\_cluster\_deployment](#module\_ocp\_cluster\_deployment) | ../../modules/ansible | n/a | +| [ocp\_cluster\_install\_configuration](#module\_ocp\_cluster\_install\_configuration) | ../../modules/ansible | n/a | +| [ocp\_cluster\_manifest\_creation](#module\_ocp\_cluster\_manifest\_creation) | ../../modules/ansible | n/a | +| [standard](#module\_standard) | ../../modules/powervs-vpc-landing-zone | n/a | + +### Resources + +| Name | Type | +|------|------| +| [ibm_iam_auth_token.auth_token](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.81.1/docs/data-sources/iam_auth_token) | data source | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [IC\_SCHEMATICS\_WORKSPACE\_ID](#input\_IC\_SCHEMATICS\_WORKSPACE\_ID) | leave blank if running locally. This variable will be automatically populated if running from an IBM Cloud Schematics workspace | `string` | `""` | no | +| [ansible\_vault\_password](#input\_ansible\_vault\_password) | Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]\_{\|}~. | `string` | n/a | yes | +| [client\_to\_site\_vpn](#input\_client\_to\_site\_vpn) | VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance. |
object({
enable = bool
client_ip_pool = string
vpn_client_access_group_users = list(string)
})
|
{
"client_ip_pool": "192.168.0.0/16",
"enable": true,
"vpn_client_access_group_users": []
}
| no | +| [cluster\_base\_domain](#input\_cluster\_base\_domain) | The base domain name that will be used by the cluster. (ie: example.com) | `string` | n/a | yes | +| [cluster\_dir](#input\_cluster\_dir) | The directory that holds the artifacts of the OpenShift cluster creation. | `string` | `"ocp-powervs-deploy"` | no | +| [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. |
object({
processors = number
system_type = string
proc_type = string
replicas = number
})
|
{
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | +| [cluster\_name](#input\_cluster\_name) | The name of the cluster. | `string` | n/a | yes | +| [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "172.22.0.0/22",
"cluster_service_network_cidr": "10.67.0.0/24"
}
| no | +| [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. |
object({
processors = number
system_type = string
proc_type = string
replicas = number
})
|
{
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | +| [enable\_monitoring](#input\_enable\_monitoring) | Specify whether Monitoring will be enabled. This includes the creation of an IBM Cloud Monitoring Instance and an Intel Monitoring Instance to host the services. If you already have an existing monitoring instance then specify in optional parameter 'existing\_monitoring\_instance\_crn' and setting this parameter to true. | `bool` | `false` | no | +| [enable\_scc\_wp](#input\_enable\_scc\_wp) | Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. If set to true, then value for 'ansible\_vault\_password' in optional parameter must be set. | `bool` | `true` | no | +| [existing\_monitoring\_instance\_crn](#input\_existing\_monitoring\_instance\_crn) | Existing CRN of IBM Cloud Monitoring Instance. If value is null, then an IBM Cloud Monitoring Instance will not be created but an intel VSI instance will be created if 'enable\_monitoring' is true. | `string` | `null` | no | +| [existing\_sm\_instance\_guid](#input\_existing\_sm\_instance\_guid) | An existing Secrets Manager GUID. If not provided a new instance will be provisioned. | `string` | `null` | no | +| [existing\_sm\_instance\_region](#input\_existing\_sm\_instance\_region) | Required if value is passed into `var.existing_sm_instance_guid`. | `string` | `null` | no | +| [external\_access\_ip](#input\_external\_access\_ip) | Specify the source IP address or CIDR for login through SSH to the environment after deployment. Access to the environment will be allowed only from this IP address. Can be set to 'null' if you choose to use client to site vpn. | `string` | `"0.0.0.0/0"` | no | +| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | n/a | yes | +| [network\_services\_vsi\_profile](#input\_network\_services\_vsi\_profile) | Compute profile configuration of the network services vsi (cpu and memory configuration). Must be one of the supported profiles. See [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui). | `string` | `"cx2-2x4"` | no | +| [openshift\_pull\_secret](#input\_openshift\_pull\_secret) | Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries. | `map(any)` | n/a | yes | +| [openshift\_release](#input\_openshift\_release) | The OpenShift IPI release version to deploy. | `string` | `"4.19.5"` | no | +| [powervs\_zone](#input\_powervs\_zone) | IBM Cloud data center location where IBM PowerVS infrastructure will be created. | `string` | n/a | yes | +| [prefix](#input\_prefix) | A unique identifier for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters. | `string` | n/a | yes | +| [sm\_service\_plan](#input\_sm\_service\_plan) | The service/pricing plan to use when provisioning a new Secrets Manager instance. Allowed values: `standard` and `trial`. Only used if `existing_sm_instance_guid` is set to null. | `string` | `"standard"` | no | +| [ssh\_private\_key](#input\_ssh\_private\_key) | Private SSH key (RSA format) to login to Intel VSIs to configure network management services (SQUID, NTP, DNS and ansible). Should match to public SSH key referenced by 'ssh\_public\_key'. The key is not uploaded or stored. For more information about SSH keys, see [SSH keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys). | `string` | n/a | yes | +| [ssh\_public\_key](#input\_ssh\_public\_key) | Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region. | `string` | n/a | yes | +| [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace | `list(string)` | `[]` | no | +| [user\_id](#input\_user\_id) | The IBM Cloud login user ID associated with the account where the cluster will be deployed. | `string` | n/a | yes | +| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-4-amd64-sap-applications-5",
"sles_image": "ibm-sles-15-6-amd64-sap-applications-3"
}
| no | + +### Outputs + +No outputs. + diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 65cb7c7a..1fabb0b8 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -37,11 +37,6 @@ module "standard" { ssh_private_key = var.ssh_private_key client_to_site_vpn = local.client_to_site_vpn vpc_intel_images = var.vpc_intel_images - configure_dns_forwarder = false - configure_ntp_forwarder = var.configure_ntp_forwarder - configure_nfs_server = var.configure_nfs_server - dns_forwarder_config = null - nfs_server_config = var.nfs_server_config powervs_resource_group_name = null powervs_management_network = null powervs_backup_network = null diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index e7cc8eb5..20f5f100 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -169,34 +169,6 @@ variable "external_access_ip" { default = "0.0.0.0/0" } -variable "configure_ntp_forwarder" { - description = "Specify if NTP forwarder will be configured. This will allow you to synchronize time between IBM PowerVS instances. NTP forwarder will be installed on the network-services vsi." - type = bool - default = false -} - -variable "configure_nfs_server" { - description = "Specify if NFS server will be configured. This will allow you easily to share files between PowerVS instances (e.g., SAP installation files). [File storage share and mount target](https://cloud.ibm.com/docs/vpc?topic=vpc-file-storage-create&interface=ui) in VPC will be created.. If yes, ensure 'nfs_server_config' optional variable is set properly below. Default value is '200GB' which will be mounted on specified directory in network-service vsi." - type = bool - default = false -} - -variable "nfs_server_config" { - description = "Configuration for the NFS server. 'size' is in GB, 'iops' is maximum input/output operation performance bandwidth per second, 'mount_path' defines the target mount point on os. Set 'configure_nfs_server' to false to ignore creating file storage share." - type = object({ - size = number - iops = number - mount_path = string - }) - - default = { - "size" : 200, - "iops" : 600, - "mount_path" : "/nfs" - } -} - - ##################################################### # Optional Parameters Monitoring and SCC WP Instance ##################################################### From 3166bb98b6d713128f544c574ddd195d2fd9ecb0 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 8 Sep 2025 16:29:32 +0200 Subject: [PATCH 22/83] fix: change defaults to create bigger subnet ranges for the cluster networks --- solutions/standard-openshift/README.md | 6 +++--- solutions/standard-openshift/variables.tf | 4 ++-- solutions/standard-openshift/versions.tf | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index aca12cd4..885deec7 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -4,7 +4,7 @@ | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.9 | -| [ibm](#requirement\_ibm) | 1.81.1 | +| [ibm](#requirement\_ibm) | 1.82.1 | | [restapi](#requirement\_restapi) | 2.0.1 | ### Modules @@ -20,7 +20,7 @@ | Name | Type | |------|------| -| [ibm_iam_auth_token.auth_token](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.81.1/docs/data-sources/iam_auth_token) | data source | +| [ibm_iam_auth_token.auth_token](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.82.1/docs/data-sources/iam_auth_token) | data source | ### Inputs @@ -33,7 +33,7 @@ | [cluster\_dir](#input\_cluster\_dir) | The directory that holds the artifacts of the OpenShift cluster creation. | `string` | `"ocp-powervs-deploy"` | no | | [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. |
object({
processors = number
system_type = string
proc_type = string
replicas = number
})
|
{
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [cluster\_name](#input\_cluster\_name) | The name of the cluster. | `string` | n/a | yes | -| [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "172.22.0.0/22",
"cluster_service_network_cidr": "10.67.0.0/24"
}
| no | +| [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "10.128.0.0/14",
"cluster_service_network_cidr": "10.67.0.0/16"
}
| no | | [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. |
object({
processors = number
system_type = string
proc_type = string
replicas = number
})
|
{
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [enable\_monitoring](#input\_enable\_monitoring) | Specify whether Monitoring will be enabled. This includes the creation of an IBM Cloud Monitoring Instance and an Intel Monitoring Instance to host the services. If you already have an existing monitoring instance then specify in optional parameter 'existing\_monitoring\_instance\_crn' and setting this parameter to true. | `bool` | `false` | no | | [enable\_scc\_wp](#input\_enable\_scc\_wp) | Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. If set to true, then value for 'ansible\_vault\_password' in optional parameter must be set. | `bool` | `true` | no | diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 20f5f100..793b2d6a 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -77,8 +77,8 @@ variable "cluster_network_config" { cluster_machine_network_cidr = string }) default = { - cluster_network_cidr = "172.22.0.0/22" - cluster_service_network_cidr = "10.67.0.0/24" + cluster_network_cidr = "10.128.0.0/14" + cluster_service_network_cidr = "10.67.0.0/16" cluster_machine_network_cidr = "10.72.0.0/24" } } diff --git a/solutions/standard-openshift/versions.tf b/solutions/standard-openshift/versions.tf index 0878d4cb..d862a611 100644 --- a/solutions/standard-openshift/versions.tf +++ b/solutions/standard-openshift/versions.tf @@ -7,7 +7,7 @@ terraform { required_providers { ibm = { source = "IBM-Cloud/ibm" - version = "1.81.1" + version = "1.82.1" } restapi = { source = "Mastercard/restapi" From c266d04517c1e6f9485cad33ad91b4129af79373 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 8 Sep 2025 16:32:55 +0200 Subject: [PATCH 23/83] chore: remove vpcSubnets parameter since it's only kept for backwards compatibility --- .secrets.baseline | 6 +++--- .../playbook-configure-ocp-cluster.yml.tftpl | 3 --- solutions/standard-openshift/main.tf | 1 - 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index c14b5bf5..a75d2472 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-09-08T13:32:00Z", + "generated_at": "2025-09-08T14:32:35Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -92,7 +92,7 @@ "hashed_secret": "6f803b24314c39062efe38d0c1da8c472f47eab3", "is_secret": false, "is_verified": false, - "line_number": 173, + "line_number": 170, "type": "Secret Keyword", "verified_result": null }, @@ -100,7 +100,7 @@ "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 189, + "line_number": 186, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl index 32ab89e5..ab7af164 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl @@ -23,7 +23,6 @@ powervs_region: "${POWERVS_REGION}" powervs_zone: "${POWERVS_ZONE}" vpc_name: "${VPC_NAME}" - vpc_subnet_name: "${VPC_SUBNET_NAME}" vpc_region: "${VPC_REGION}" pull_secret: '${PULL_SECRET_FILE}' ssh_key: "${SSH_KEY}" @@ -143,8 +142,6 @@ zone: {{ powervs_zone }} tgName: {{ transit_gateway_name }} vpcName: {{ vpc_name }} - vpcSubnets: - - {{ vpc_subnet_name }} vpcRegion: {{ vpc_region }} serviceInstanceGUID: {{ powervs_workspace_guid }} diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 1fabb0b8..0ffa4377 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -98,7 +98,6 @@ module "ocp_cluster_install_configuration" { POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, VPC_NAME : module.standard.vpc_names[0], - VPC_SUBNET_NAME : "${var.prefix}-edge-vsi-edge-zone-1" VPC_REGION : local.vpc_region PULL_SECRET_FILE : jsonencode(var.openshift_pull_secret), SSH_KEY : var.ssh_public_key, From ce28c36f2babf97c15e7a01dff167ff823f616b1 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 8 Sep 2025 16:47:30 +0200 Subject: [PATCH 24/83] feat: expose node memory --- .secrets.baseline | 6 +++--- .../playbook-configure-ocp-cluster.yml.tftpl | 4 ++++ solutions/standard-openshift/README.md | 4 ++-- solutions/standard-openshift/main.tf | 2 ++ solutions/standard-openshift/variables.tf | 20 +++++++++++++++---- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index a75d2472..f87eb5ae 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-09-08T14:32:35Z", + "generated_at": "2025-09-08T14:44:39Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -92,7 +92,7 @@ "hashed_secret": "6f803b24314c39062efe38d0c1da8c472f47eab3", "is_secret": false, "is_verified": false, - "line_number": 170, + "line_number": 174, "type": "Secret Keyword", "verified_result": null }, @@ -100,7 +100,7 @@ "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 186, + "line_number": 190, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl index ab7af164..b8c1b51d 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl @@ -11,10 +11,12 @@ worker_processors: "${WORKER_PROCESSORS}" worker_system_type: "${WORKER_SYSTEM_TYPE}" worker_proc_type: "${WORKER_PROC_TYPE}" + worker_memory: "${WORKER_MEMORY}" worker_replicas: ${WORKER_REPLICAS} master_processors: "${MASTER_PROCESSORS}" master_system_type: "${MASTER_SYSTEM_TYPE}" master_proc_type: "${MASTER_PROC_TYPE}" + master_memory: "${MASTER_MEMORY}" master_replicas: ${MASTER_REPLICAS} user_id: "${USER_ID}" transit_gateway_name: "${TRANSIT_GATEWAY_NAME}" @@ -154,6 +156,7 @@ processors: {{ worker_processors }} sysType: "{{ worker_system_type }}" procType: "{{ worker_proc_type }}" + memoryGiB: "{{ worker_memory }}" replicas: {{ worker_replicas }} controlPlane: @@ -165,6 +168,7 @@ processors: {{ master_processors }} sysType: "{{ master_system_type }}" procType: "{{ master_proc_type }}" + memoryGiB: "{{ master_memory }}" replicas: {{ master_replicas }} pullSecret: '{{ pull_secret }}' diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 885deec7..8c0f9ad8 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -31,10 +31,10 @@ | [client\_to\_site\_vpn](#input\_client\_to\_site\_vpn) | VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance. |
object({
enable = bool
client_ip_pool = string
vpn_client_access_group_users = list(string)
})
|
{
"client_ip_pool": "192.168.0.0/16",
"enable": true,
"vpn_client_access_group_users": []
}
| no | | [cluster\_base\_domain](#input\_cluster\_base\_domain) | The base domain name that will be used by the cluster. (ie: example.com) | `string` | n/a | yes | | [cluster\_dir](#input\_cluster\_dir) | The directory that holds the artifacts of the OpenShift cluster creation. | `string` | `"ocp-powervs-deploy"` | no | -| [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. |
object({
processors = number
system_type = string
proc_type = string
replicas = number
})
|
{
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | +| [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [cluster\_name](#input\_cluster\_name) | The name of the cluster. | `string` | n/a | yes | | [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "10.128.0.0/14",
"cluster_service_network_cidr": "10.67.0.0/16"
}
| no | -| [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. |
object({
processors = number
system_type = string
proc_type = string
replicas = number
})
|
{
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | +| [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [enable\_monitoring](#input\_enable\_monitoring) | Specify whether Monitoring will be enabled. This includes the creation of an IBM Cloud Monitoring Instance and an Intel Monitoring Instance to host the services. If you already have an existing monitoring instance then specify in optional parameter 'existing\_monitoring\_instance\_crn' and setting this parameter to true. | `bool` | `false` | no | | [enable\_scc\_wp](#input\_enable\_scc\_wp) | Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. If set to true, then value for 'ansible\_vault\_password' in optional parameter must be set. | `bool` | `true` | no | | [existing\_monitoring\_instance\_crn](#input\_existing\_monitoring\_instance\_crn) | Existing CRN of IBM Cloud Monitoring Instance. If value is null, then an IBM Cloud Monitoring Instance will not be created but an intel VSI instance will be created if 'enable\_monitoring' is true. | `string` | `null` | no | diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 0ffa4377..120dd591 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -86,10 +86,12 @@ module "ocp_cluster_install_configuration" { WORKER_PROCESSORS : local.cluster_worker_node_config.processors, WORKER_SYSTEM_TYPE : local.cluster_worker_node_config.system_type, WORKER_PROC_TYPE : local.cluster_worker_node_config.proc_type, + WORKER_MEMORY : local.cluster_worker_node_config.memory, WORKER_REPLICAS : local.cluster_worker_node_config.replicas, MASTER_PROCESSORS : local.cluster_master_node_config.processors, MASTER_SYSTEM_TYPE : local.cluster_master_node_config.system_type, MASTER_PROC_TYPE : local.cluster_master_node_config.proc_type, + MASTER_MEMORY : local.cluster_master_node_config.memory, MASTER_REPLICAS : local.cluster_master_node_config.replicas, USER_ID : var.user_id, TRANSIT_GATEWAY_NAME : module.standard.transit_gateway_name, diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 793b2d6a..3a4c6d41 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -84,51 +84,63 @@ variable "cluster_network_config" { } variable "cluster_master_node_config" { - description = "Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'." + description = "Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB." type = object({ processors = number system_type = string proc_type = string + memory = number replicas = number }) default = { processors = 4 system_type = null proc_type = "Dedicated" + memory = 32 replicas = 3 } validation { condition = var.cluster_master_node_config.system_type != null ? contains(["s1122", "s1022", "s922", "e980", "e1080", "e1050"], var.cluster_master_node_config.system_type) : true - error_message = "value" + error_message = "system_type needs to be one of s1122, s1022, s922, e980, e1080, e1050." } validation { condition = contains(["Capped", "Dedicated", "Shared"], var.cluster_master_node_config.proc_type) error_message = "Unsupported value for cluster_master_node_config.proc_type. Allowed values: Capped, Dedicated, Shared." } + validation { + condition = var.cluster_master_node_config.memory >= 2 && var.cluster_master_node_config.memory <= 64 + error_message = "Memory needs to be at least 2 and at most 64." + } } variable "cluster_worker_node_config" { - description = "Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'." + description = "Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB." type = object({ processors = number system_type = string proc_type = string + memory = number replicas = number }) default = { processors = 4 system_type = null proc_type = "Dedicated" + memory = 32 replicas = 3 } validation { condition = var.cluster_worker_node_config.system_type != null ? contains(["s1122", "s1022", "s922", "e980", "e1080", "e1050"], var.cluster_worker_node_config.system_type) : true - error_message = "value" + error_message = "system_type needs to be one of s1122, s1022, s922, e980, e1080, e1050." } validation { condition = contains(["Capped", "Dedicated", "Shared"], var.cluster_worker_node_config.proc_type) error_message = "Unsupported value for cluster_worker_node_config.proc_type. Allowed values: Capped, Dedicated, Shared." } + validation { + condition = var.cluster_worker_node_config.memory >= 2 && var.cluster_worker_node_config.memory <= 64 + error_message = "Memory needs to be at least 2 and at most 64." + } } ##################################################### From c779bf3b8e8f50e65b7e7f858d59a9cc83e2ffde Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 9 Sep 2025 15:54:56 +0200 Subject: [PATCH 25/83] fix: remove quotes from memory (int) so it doesn't error out --- .../playbook-configure-ocp-cluster.yml.tftpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl index b8c1b51d..82b26ce9 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl @@ -156,7 +156,7 @@ processors: {{ worker_processors }} sysType: "{{ worker_system_type }}" procType: "{{ worker_proc_type }}" - memoryGiB: "{{ worker_memory }}" + memoryGiB: {{ worker_memory }} replicas: {{ worker_replicas }} controlPlane: @@ -168,7 +168,7 @@ processors: {{ master_processors }} sysType: "{{ master_system_type }}" procType: "{{ master_proc_type }}" - memoryGiB: "{{ master_memory }}" + memoryGiB: {{ master_memory }} replicas: {{ master_replicas }} pullSecret: '{{ pull_secret }}' From 0eccc4fc64cd5073e760495cc1cea6f7c94ddfca Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 9 Sep 2025 15:56:10 +0200 Subject: [PATCH 26/83] fix: add wait for cluster to complete --- .secrets.baseline | 4 ++-- .../playbook-deploy-ocp-cluster.yml.tftpl | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index f87eb5ae..70514c22 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-09-08T14:44:39Z", + "generated_at": "2025-09-09T13:56:02Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -120,7 +120,7 @@ "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 55, + "line_number": 53, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl index 4bf0e578..5b0e1392 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl @@ -29,7 +29,7 @@ ignore_errors: false rescue: - - name: Wait for OpenShift install to complete + - name: Wait for OpenShift API to become ready ansible.builtin.shell: | openshift-install wait-for bootstrap-complete --dir={{ install_dir }} --log-level=debug environment: @@ -39,6 +39,23 @@ OPENSHIFT_INSTALL_CLUSTER_TIMEOUT: "{{ openshift_install_cluster_timeout }}" OPENSHIFT_INSTALL_DESTROY_TIMEOUT: "{{ openshift_install_destroy_timeout }}" + register: wait_for_bootstrap_output + ignore_errors: false + + - name: Print wait_for_bootstrap_output + ansible.builtin.debug: + var: wait_for_bootstrap_output + + - name: Wait for OpenShift cluster to become ready + ansible.builtin.shell: | + openshift-install wait-for install-complete --dir={{ install_dir }} --log-level=debug + environment: + IBMCLOUD_API_KEY: "{{ lookup('env', 'IBMCLOUD_API_KEY') }}" + OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT: "{{ openshift_install_bootstrap_timeout }}" + OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT: "{{ openshift_install_machine_wait_timeout }}" + OPENSHIFT_INSTALL_CLUSTER_TIMEOUT: "{{ openshift_install_cluster_timeout }}" + OPENSHIFT_INSTALL_DESTROY_TIMEOUT: "{{ openshift_install_destroy_timeout }}" + register: wait_for_install_output ignore_errors: false From 5c75fb24764588fcb5d753e0d9c7a745e5b85690 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 9 Sep 2025 15:56:50 +0200 Subject: [PATCH 27/83] fix: execute first playbook with vault since it contains secrets --- solutions/standard-openshift/main.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 120dd591..31155137 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -68,6 +68,7 @@ module "ocp_cluster_install_configuration" { bastion_host_ip = module.standard.access_host_or_ip ansible_host_or_ip = module.standard.ansible_host_or_ip ssh_private_key = var.ssh_private_key + ansible_vault_password = var.ansible_vault_password configure_ansible_host = false src_script_template_name = "deploy-openshift-cluster/ansible_exec.sh.tftpl" From 000954ecaddfedf3e92bf42cac3359890d7af8b3 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 9 Sep 2025 20:33:04 +0200 Subject: [PATCH 28/83] fix: encrypted playbook wasn't using ansible vault during execution --- .../ansible_exec_vault.sh.tftpl | 31 +++++++++++++++++++ solutions/standard-openshift/main.tf | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl new file mode 100644 index 00000000..f899fab5 --- /dev/null +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl @@ -0,0 +1,31 @@ +#!/bin/bash + +### Using input variables from terraform +ansible_playbook=${ansible_playbook_file} +ansible_log_path=${ansible_log_path} +ansible_inventory=${ansible_inventory} +ansible_private_key_file=${ansible_private_key_file} + +ansible_playbook_name=$(basename $${ansible_playbook}) + +# Install ansible-core during the initial bootstrap +if [ "$ansible_playbook_name" == "ocp-cluster-install-configuration-playbook.yml" ]; then + echo "Installing ansible-core as a part of bootstrap..." + yum install -y expect ansible-core +fi + +# Create ansible.cfg file +echo -e "[defaults]\nhost_key_checking=False" >ansible.cfg +export ANSIBLE_LOG_PATH=$${ansible_log_path}/$${ansible_playbook_name}.$(date "+%Y.%m.%d-%H.%M.%S").log +export ANSIBLE_PRIVATE_KEY_FILE=$${ansible_private_key_file} +export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} + +#Execute ansible playbook +unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" --vault-password-file password_file +## On failure: +if [ $? -ne 0 ]; then + rm -rf $${ansible_private_key_file} + exit 1 +fi +echo \"Playbook command successful\" +rm -rf $${ansible_private_key_file} diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 31155137..840efa22 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -71,7 +71,7 @@ module "ocp_cluster_install_configuration" { ansible_vault_password = var.ansible_vault_password configure_ansible_host = false - src_script_template_name = "deploy-openshift-cluster/ansible_exec.sh.tftpl" + src_script_template_name = "deploy-openshift-cluster/ansible_exec_vault.sh.tftpl" dst_script_file_name = "ocp-cluster-install-configuration.sh" src_playbook_template_name = "deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl" From 21051295278361e4dd0f4d9947e9695a3cbd8d80 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 9 Sep 2025 20:36:32 +0200 Subject: [PATCH 29/83] refactor: consolidate prefix and cluster name by removing prefix and using cluster name as prefix --- solutions/standard-openshift/README.md | 3 +-- solutions/standard-openshift/main.tf | 2 +- solutions/standard-openshift/variables.tf | 9 ++------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 8c0f9ad8..f1fbcceb 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -32,7 +32,7 @@ | [cluster\_base\_domain](#input\_cluster\_base\_domain) | The base domain name that will be used by the cluster. (ie: example.com) | `string` | n/a | yes | | [cluster\_dir](#input\_cluster\_dir) | The directory that holds the artifacts of the OpenShift cluster creation. | `string` | `"ocp-powervs-deploy"` | no | | [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | -| [cluster\_name](#input\_cluster\_name) | The name of the cluster. | `string` | n/a | yes | +| [cluster\_name](#input\_cluster\_name) | The name of the cluster and a unique identifier used as prefix for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters. | `string` | n/a | yes | | [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "10.128.0.0/14",
"cluster_service_network_cidr": "10.67.0.0/16"
}
| no | | [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [enable\_monitoring](#input\_enable\_monitoring) | Specify whether Monitoring will be enabled. This includes the creation of an IBM Cloud Monitoring Instance and an Intel Monitoring Instance to host the services. If you already have an existing monitoring instance then specify in optional parameter 'existing\_monitoring\_instance\_crn' and setting this parameter to true. | `bool` | `false` | no | @@ -46,7 +46,6 @@ | [openshift\_pull\_secret](#input\_openshift\_pull\_secret) | Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries. | `map(any)` | n/a | yes | | [openshift\_release](#input\_openshift\_release) | The OpenShift IPI release version to deploy. | `string` | `"4.19.5"` | no | | [powervs\_zone](#input\_powervs\_zone) | IBM Cloud data center location where IBM PowerVS infrastructure will be created. | `string` | n/a | yes | -| [prefix](#input\_prefix) | A unique identifier for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters. | `string` | n/a | yes | | [sm\_service\_plan](#input\_sm\_service\_plan) | The service/pricing plan to use when provisioning a new Secrets Manager instance. Allowed values: `standard` and `trial`. Only used if `existing_sm_instance_guid` is set to null. | `string` | `"standard"` | no | | [ssh\_private\_key](#input\_ssh\_private\_key) | Private SSH key (RSA format) to login to Intel VSIs to configure network management services (SQUID, NTP, DNS and ansible). Should match to public SSH key referenced by 'ssh\_public\_key'. The key is not uploaded or stored. For more information about SSH keys, see [SSH keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys). | `string` | n/a | yes | | [ssh\_public\_key](#input\_ssh\_public\_key) | Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region. | `string` | n/a | yes | diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 840efa22..9f5e0198 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -31,7 +31,7 @@ module "standard" { providers = { ibm.ibm-is = ibm.ibm-is, ibm.ibm-pi = ibm.ibm-pi, ibm.ibm-sm = ibm.ibm-sm } powervs_zone = var.powervs_zone - prefix = var.prefix + prefix = var.cluster_name external_access_ip = var.external_access_ip ssh_public_key = var.ssh_public_key ssh_private_key = var.ssh_private_key diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 3a4c6d41..ea78b127 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -3,8 +3,8 @@ variable "powervs_zone" { type = string } -variable "prefix" { - description = "A unique identifier for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters." +variable "cluster_name" { + description = "The name of the cluster and a unique identifier used as prefix for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters." type = string } @@ -48,11 +48,6 @@ variable "cluster_base_domain" { type = string } -variable "cluster_name" { - description = "The name of the cluster." - type = string -} - ##################################################### # Optional Parameters Openshift Cluster ##################################################### From edd2b3be48a9bba2b8c3d6cf9da9ec28bc1396c7 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 9 Sep 2025 21:18:06 +0200 Subject: [PATCH 30/83] feat: cat openshift install log --- modules/ansible/main.tf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/ansible/main.tf b/modules/ansible/main.tf index ba493813..0ad75f1c 100644 --- a/modules/ansible/main.tf +++ b/modules/ansible/main.tf @@ -133,6 +133,14 @@ resource "terraform_data" "execute_playbooks" { "rm -rf ${local.private_key_file}" ] } + + # print output of openshift installation if applicable, else do nothing + provisioner "remote-exec" { + inline = [ + "if [ -f ${lookup(var.playbook_template_vars, "CLUSTER_DIR", "/tmp")}/.openshift_install.log ]; then cat ${lookup(var.playbook_template_vars, "CLUSTER_DIR", "/tmp")}/.openshift_install.log; fi" + ] + on_failure = continue + } } resource "terraform_data" "execute_playbooks_with_vault" { From c8a9f713bff0d8e971d84863f5b301ab6b6116fc Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 10 Sep 2025 11:47:08 +0200 Subject: [PATCH 31/83] feat: fill outputs.tf --- solutions/standard-openshift/README.md | 33 ++++- solutions/standard-openshift/outputs.tf | 172 ++++++++++++++++++++++++ 2 files changed, 204 insertions(+), 1 deletion(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index f1fbcceb..9a44161c 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -55,5 +55,36 @@ ### Outputs -No outputs. +| Name | Description | +|------|-------------| +| [access\_host\_or\_ip](#output\_access\_host\_or\_ip) | Access host(jump/bastion) for created PowerVS infrastructure. | +| [ansible\_host\_or\_ip](#output\_ansible\_host\_or\_ip) | Central Ansible node private IP address. | +| [cluster\_base\_domain](#output\_cluster\_base\_domain) | The base domain the cluster is using. | +| [cluster\_dir](#output\_cluster\_dir) | The directory on the network services VSI that holds the artifacts of the OpenShift cluster creation. | +| [cluster\_name](#output\_cluster\_name) | The name of the cluster and the prefix that is associated with all resources. | +| [cluster\_resource\_group](#output\_cluster\_resource\_group) | The resource group where all cluster resources, Transit Gateway, VPC, and PowerVS resources reside. | +| [dns\_host\_or\_ip](#output\_dns\_host\_or\_ip) | DNS forwarder host for created PowerVS infrastructure. | +| [kms\_key\_map](#output\_kms\_key\_map) | Map of ids and keys for KMS keys created | +| [monitoring\_instance](#output\_monitoring\_instance) | Details of the IBM Cloud Monitoring Instance: CRN, location, guid. | +| [network\_load\_balancer](#output\_network\_load\_balancer) | Details of network load balancer. | +| [network\_services\_config](#output\_network\_services\_config) | Complete configuration of network management services. | +| [nfs\_host\_or\_ip\_path](#output\_nfs\_host\_or\_ip\_path) | NFS host for created PowerVS infrastructure. | +| [ntp\_host\_or\_ip](#output\_ntp\_host\_or\_ip) | NTP host for created PowerVS infrastructure. | +| [powervs\_ssh\_public\_key](#output\_powervs\_ssh\_public\_key) | SSH public key name and value in created PowerVS infrastructure. | +| [powervs\_workspace\_guid](#output\_powervs\_workspace\_guid) | PowerVS infrastructure workspace guid. The GUID of the resource instance. | +| [powervs\_workspace\_id](#output\_powervs\_workspace\_id) | PowerVS infrastructure workspace id. The unique identifier of the new resource instance. | +| [powervs\_workspace\_name](#output\_powervs\_workspace\_name) | PowerVS infrastructure workspace name. | +| [powervs\_zone](#output\_powervs\_zone) | Zone where PowerVS infrastructure is created. | +| [proxy\_host\_or\_ip\_port](#output\_proxy\_host\_or\_ip\_port) | Proxy host:port for created PowerVS infrastructure. | +| [resource\_group\_data](#output\_resource\_group\_data) | List of resource groups data used within landing zone. | +| [scc\_wp\_instance](#output\_scc\_wp\_instance) | Details of the Security and Compliance Center Workload Protection Instance: guid, access key, api\_endpoint, ingestion\_endpoint. | +| [schematics\_workspace\_id](#output\_schematics\_workspace\_id) | ID of the IBM Cloud Schematics workspace. Returns null if not ran in Schematics. | +| [ssh\_public\_key](#output\_ssh\_public\_key) | The string value of the ssh public key used when deploying VPC. | +| [transit\_gateway\_id](#output\_transit\_gateway\_id) | The ID of transit gateway. | +| [transit\_gateway\_name](#output\_transit\_gateway\_name) | The name of the transit gateway. | +| [vpc\_data](#output\_vpc\_data) | List of VPC data. | +| [vpc\_names](#output\_vpc\_names) | A list of the names of the VPC. | +| [vsi\_list](#output\_vsi\_list) | A list of VSI with name, id, zone, and primary ipv4 address, VPC Name, and floating IP. | +| [vsi\_names](#output\_vsi\_names) | A list of the vsis names provisioned within the VPCs. | +| [vsi\_ssh\_key\_data](#output\_vsi\_ssh\_key\_data) | List of VSI SSH key data | diff --git a/solutions/standard-openshift/outputs.tf b/solutions/standard-openshift/outputs.tf index e69de29b..3f71e033 100644 --- a/solutions/standard-openshift/outputs.tf +++ b/solutions/standard-openshift/outputs.tf @@ -0,0 +1,172 @@ +######################################################################## +# Cluster outputs +######################################################################## + +output "cluster_name" { + description = "The name of the cluster and the prefix that is associated with all resources." + value = var.cluster_name +} + +output "cluster_base_domain" { + description = "The base domain the cluster is using." + value = var.cluster_base_domain +} + +output "cluster_dir" { + description = "The directory on the network services VSI that holds the artifacts of the OpenShift cluster creation." + value = var.cluster_dir +} + +output "cluster_resource_group" { + description = "The resource group where all cluster resources, Transit Gateway, VPC, and PowerVS resources reside." + value = module.standard.powervs_resource_group_name +} + +######################################################################## +# Landing Zone VPC outputs +######################################################################## + +output "vpc_names" { + description = "A list of the names of the VPC." + value = module.standard.vpc_names +} + +output "vsi_names" { + description = "A list of the vsis names provisioned within the VPCs." + value = module.standard.vsi_names +} + +output "vpc_data" { + description = "List of VPC data." + value = module.standard.vpc_data +} + +output "kms_key_map" { + description = "Map of ids and keys for KMS keys created" + value = module.standard.kms_key_map +} + +output "vsi_ssh_key_data" { + description = "List of VSI SSH key data" + value = module.standard.vsi_ssh_key_data +} + +output "network_load_balancer" { + description = "Details of network load balancer." + value = module.standard.network_load_balancer +} + +output "ssh_public_key" { + description = "The string value of the ssh public key used when deploying VPC." + value = var.ssh_public_key +} + +output "transit_gateway_name" { + description = "The name of the transit gateway." + value = module.standard.transit_gateway_name +} + +output "transit_gateway_id" { + description = "The ID of transit gateway." + value = module.standard.transit_gateway_id +} + +output "vsi_list" { + description = "A list of VSI with name, id, zone, and primary ipv4 address, VPC Name, and floating IP." + value = module.standard.vsi_list +} + +output "resource_group_data" { + description = "List of resource groups data used within landing zone." + value = module.standard.resource_group_data +} + +output "access_host_or_ip" { + description = "Access host(jump/bastion) for created PowerVS infrastructure." + value = module.standard.access_host_or_ip +} + +output "proxy_host_or_ip_port" { + description = "Proxy host:port for created PowerVS infrastructure." + value = module.standard.proxy_host_or_ip_port +} + +output "dns_host_or_ip" { + description = "DNS forwarder host for created PowerVS infrastructure." + value = module.standard.dns_host_or_ip +} + +output "ntp_host_or_ip" { + description = "NTP host for created PowerVS infrastructure." + value = module.standard.ntp_host_or_ip +} + +output "nfs_host_or_ip_path" { + description = "NFS host for created PowerVS infrastructure." + value = module.standard.nfs_host_or_ip_path +} + +output "ansible_host_or_ip" { + description = "Central Ansible node private IP address." + value = module.standard.ansible_host_or_ip +} + +output "network_services_config" { + description = "Complete configuration of network management services." + value = module.standard.network_services_config +} + +######################################################################## +# Monitoring Instance outputs +######################################################################## + +output "monitoring_instance" { + description = "Details of the IBM Cloud Monitoring Instance: CRN, location, guid." + value = module.standard.monitoring_instance +} + +######################################################################## +# SCC Workload Protection outputs +######################################################################## +output "scc_wp_instance" { + description = "Details of the Security and Compliance Center Workload Protection Instance: guid, access key, api_endpoint, ingestion_endpoint." + value = module.standard.scc_wp_instance +} + +######################################################################## +# PowerVS Infrastructure outputs +######################################################################## + +output "powervs_zone" { + description = "Zone where PowerVS infrastructure is created." + value = var.powervs_zone +} + +output "powervs_workspace_name" { + description = "PowerVS infrastructure workspace name." + value = module.standard.powervs_workspace_name +} + +output "powervs_workspace_id" { + description = "PowerVS infrastructure workspace id. The unique identifier of the new resource instance." + value = module.standard.powervs_workspace_id +} + +output "powervs_workspace_guid" { + description = "PowerVS infrastructure workspace guid. The GUID of the resource instance." + value = module.standard.powervs_workspace_guid +} + +output "powervs_ssh_public_key" { + description = "SSH public key name and value in created PowerVS infrastructure." + value = module.standard.powervs_ssh_public_key +} + +######################################################################## +# Schematics +######################################################################## + +output "schematics_workspace_id" { + description = "ID of the IBM Cloud Schematics workspace. Returns null if not ran in Schematics." + value = var.IC_SCHEMATICS_WORKSPACE_ID +} From 612957d7f4e36893b8faaa1b0b4cd6ba8c37bb52 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 10 Sep 2025 15:13:00 +0200 Subject: [PATCH 32/83] feat: remove cluster_dir and hardcode it to ocp-powervs-deploy to minimize required input params --- solutions/standard-openshift/README.md | 1 - solutions/standard-openshift/main.tf | 7 ++++--- solutions/standard-openshift/outputs.tf | 2 +- solutions/standard-openshift/variables.tf | 6 ------ 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 9a44161c..18e3c81d 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -30,7 +30,6 @@ | [ansible\_vault\_password](#input\_ansible\_vault\_password) | Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]\_{\|}~. | `string` | n/a | yes | | [client\_to\_site\_vpn](#input\_client\_to\_site\_vpn) | VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance. |
object({
enable = bool
client_ip_pool = string
vpn_client_access_group_users = list(string)
})
|
{
"client_ip_pool": "192.168.0.0/16",
"enable": true,
"vpn_client_access_group_users": []
}
| no | | [cluster\_base\_domain](#input\_cluster\_base\_domain) | The base domain name that will be used by the cluster. (ie: example.com) | `string` | n/a | yes | -| [cluster\_dir](#input\_cluster\_dir) | The directory that holds the artifacts of the OpenShift cluster creation. | `string` | `"ocp-powervs-deploy"` | no | | [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [cluster\_name](#input\_cluster\_name) | The name of the cluster and a unique identifier used as prefix for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters. | `string` | n/a | yes | | [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "10.128.0.0/14",
"cluster_service_network_cidr": "10.67.0.0/16"
}
| no | diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 9f5e0198..3eb82f31 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -3,6 +3,7 @@ ##################################################### locals { + cluster_dir = "/root/ocp-powervs-deploy" powervs_server_routes = [ { route_name = "cluster-network" @@ -79,7 +80,7 @@ module "ocp_cluster_install_configuration" { playbook_template_vars = { OPENSHIFT_RELEASE : var.openshift_release, BASE_DOMAIN : var.cluster_base_domain, - CLUSTER_DIR : var.cluster_dir, + CLUSTER_DIR : local.cluster_dir, CLUSTER_NAME : var.cluster_name, CLUSTER_NETWORK : var.cluster_network_config.cluster_network_cidr, CLUSTER_SERVICE_NETWORK : var.cluster_network_config.cluster_service_network_cidr, @@ -129,7 +130,7 @@ module "ocp_cluster_manifest_creation" { playbook_template_vars = { RELEASE_IMAGE : "quay.io/openshift-release-dev/ocp-release:${var.openshift_release}-multi", CLUSTER_NAME : var.cluster_name, - CLUSTER_DIR : "/root/${var.cluster_dir}", + CLUSTER_DIR : local.cluster_dir, REQUESTS_DIR : "./credreqs" ACCOUNT_NAME : var.cluster_name, RESOURCE_GROUP : module.standard.powervs_resource_group_name, @@ -160,7 +161,7 @@ module "ocp_cluster_deployment" { POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, RESOURCE_GROUP : module.standard.powervs_resource_group_name, - CLUSTER_DIR : var.cluster_dir, + CLUSTER_DIR : local.cluster_dir, OPENSHIFT_INSTALL_BOOTSTRAP_TIMEOUT : "120m", OPENSHIFT_INSTALL_MACHINE_WAIT_TIMEOUT : "35m", OPENSHIFT_INSTALL_CLUSTER_TIMEOUT : "180m", diff --git a/solutions/standard-openshift/outputs.tf b/solutions/standard-openshift/outputs.tf index 3f71e033..88c0b6f6 100644 --- a/solutions/standard-openshift/outputs.tf +++ b/solutions/standard-openshift/outputs.tf @@ -14,7 +14,7 @@ output "cluster_base_domain" { output "cluster_dir" { description = "The directory on the network services VSI that holds the artifacts of the OpenShift cluster creation." - value = var.cluster_dir + value = local.cluster_dir } output "cluster_resource_group" { diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index ea78b127..7f2bdc56 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -58,12 +58,6 @@ variable "openshift_release" { default = "4.19.5" } -variable "cluster_dir" { - description = "The directory that holds the artifacts of the OpenShift cluster creation." - type = string - default = "ocp-powervs-deploy" -} - variable "cluster_network_config" { description = "Configuration object for the OpenShift cluster and service network CIDRs." type = object({ From 07d4aba35266f305de9d8d271e59dd199be8e1bf Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 10 Sep 2025 15:58:47 +0200 Subject: [PATCH 33/83] chore: update intel images --- solutions/standard-openshift/README.md | 2 +- solutions/standard-openshift/variables.tf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 18e3c81d..53ed32b6 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -50,7 +50,7 @@ | [ssh\_public\_key](#input\_ssh\_public\_key) | Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region. | `string` | n/a | yes | | [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace | `list(string)` | `[]` | no | | [user\_id](#input\_user\_id) | The IBM Cloud login user ID associated with the account where the cluster will be deployed. | `string` | n/a | yes | -| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-4-amd64-sap-applications-5",
"sles_image": "ibm-sles-15-6-amd64-sap-applications-3"
}
| no | +| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-6-amd64-sap-applications-1",
"sles_image": "ibm-sles-15-7-amd64-sap-applications-1"
}
| no | ### Outputs diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 7f2bdc56..b4b653ac 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -153,8 +153,8 @@ variable "vpc_intel_images" { sles_image = string }) default = { - "rhel_image" : "ibm-redhat-9-4-amd64-sap-applications-5" - "sles_image" : "ibm-sles-15-6-amd64-sap-applications-3" + "rhel_image" : "ibm-redhat-9-6-amd64-sap-applications-1" + "sles_image" : "ibm-sles-15-7-amd64-sap-applications-1" } } From 69e811e3f1f1f3efda87ea60f9fbb8e8db089bb9 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 10 Sep 2025 16:21:46 +0200 Subject: [PATCH 34/83] fix: add validation for supported regions --- solutions/standard-openshift/README.md | 2 +- solutions/standard-openshift/variables.tf | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 53ed32b6..ed9850d2 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -44,7 +44,7 @@ | [network\_services\_vsi\_profile](#input\_network\_services\_vsi\_profile) | Compute profile configuration of the network services vsi (cpu and memory configuration). Must be one of the supported profiles. See [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui). | `string` | `"cx2-2x4"` | no | | [openshift\_pull\_secret](#input\_openshift\_pull\_secret) | Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries. | `map(any)` | n/a | yes | | [openshift\_release](#input\_openshift\_release) | The OpenShift IPI release version to deploy. | `string` | `"4.19.5"` | no | -| [powervs\_zone](#input\_powervs\_zone) | IBM Cloud data center location where IBM PowerVS infrastructure will be created. | `string` | n/a | yes | +| [powervs\_zone](#input\_powervs\_zone) | IBM Cloud data center location where IBM PowerVS infrastructure will be created. Supported regions are: dal10, dal12, eu-de-1, eu-de-2, lon04, lon06, mad02, mad04, osa21, sao01, sao04, syd04, syd05, us-east, us-south, wdc06, wdc07. | `string` | n/a | yes | | [sm\_service\_plan](#input\_sm\_service\_plan) | The service/pricing plan to use when provisioning a new Secrets Manager instance. Allowed values: `standard` and `trial`. Only used if `existing_sm_instance_guid` is set to null. | `string` | `"standard"` | no | | [ssh\_private\_key](#input\_ssh\_private\_key) | Private SSH key (RSA format) to login to Intel VSIs to configure network management services (SQUID, NTP, DNS and ansible). Should match to public SSH key referenced by 'ssh\_public\_key'. The key is not uploaded or stored. For more information about SSH keys, see [SSH keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys). | `string` | n/a | yes | | [ssh\_public\_key](#input\_ssh\_public\_key) | Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region. | `string` | n/a | yes | diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index b4b653ac..045fdf0f 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -1,6 +1,10 @@ variable "powervs_zone" { - description = "IBM Cloud data center location where IBM PowerVS infrastructure will be created." + description = "IBM Cloud data center location where IBM PowerVS infrastructure will be created. Supported regions are: dal10, dal12, eu-de-1, eu-de-2, lon04, lon06, mad02, mad04, osa21, sao01, sao04, syd04, syd05, us-east, us-south, wdc06, wdc07." type = string + validation { + condition = contains(["dal10", "dal12", "eu-de-1", "eu-de-2", "lon04", "lon06", "mad02", "mad04", "osa21", "sao01", "sao04", "syd04", "syd05", "us-east", "us-south", "wdc06", "wdc07"], var.powervs_zone) + error_message = "Unsupported powervs_zone. Supported zones are: dal10, dal12, eu-de-1, eu-de-2, lon04, lon06, mad02, mad04, osa21, sao01, sao04, syd04, syd05, us-east, us-south, wdc06, wdc07." + } } variable "cluster_name" { From 32c6b2178f780d4f695cb946f29d0c3ff7074dcd Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 10 Sep 2025 16:23:53 +0200 Subject: [PATCH 35/83] chore: change defaults to shared processors --- solutions/standard-openshift/README.md | 4 ++-- solutions/standard-openshift/variables.tf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index ed9850d2..6c636313 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -30,10 +30,10 @@ | [ansible\_vault\_password](#input\_ansible\_vault\_password) | Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]\_{\|}~. | `string` | n/a | yes | | [client\_to\_site\_vpn](#input\_client\_to\_site\_vpn) | VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance. |
object({
enable = bool
client_ip_pool = string
vpn_client_access_group_users = list(string)
})
|
{
"client_ip_pool": "192.168.0.0/16",
"enable": true,
"vpn_client_access_group_users": []
}
| no | | [cluster\_base\_domain](#input\_cluster\_base\_domain) | The base domain name that will be used by the cluster. (ie: example.com) | `string` | n/a | yes | -| [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | +| [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Shared",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [cluster\_name](#input\_cluster\_name) | The name of the cluster and a unique identifier used as prefix for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters. | `string` | n/a | yes | | [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "10.128.0.0/14",
"cluster_service_network_cidr": "10.67.0.0/16"
}
| no | -| [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Dedicated",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | +| [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Shared",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [enable\_monitoring](#input\_enable\_monitoring) | Specify whether Monitoring will be enabled. This includes the creation of an IBM Cloud Monitoring Instance and an Intel Monitoring Instance to host the services. If you already have an existing monitoring instance then specify in optional parameter 'existing\_monitoring\_instance\_crn' and setting this parameter to true. | `bool` | `false` | no | | [enable\_scc\_wp](#input\_enable\_scc\_wp) | Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. If set to true, then value for 'ansible\_vault\_password' in optional parameter must be set. | `bool` | `true` | no | | [existing\_monitoring\_instance\_crn](#input\_existing\_monitoring\_instance\_crn) | Existing CRN of IBM Cloud Monitoring Instance. If value is null, then an IBM Cloud Monitoring Instance will not be created but an intel VSI instance will be created if 'enable\_monitoring' is true. | `string` | `null` | no | diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 045fdf0f..33a4a729 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -88,7 +88,7 @@ variable "cluster_master_node_config" { default = { processors = 4 system_type = null - proc_type = "Dedicated" + proc_type = "Shared" memory = 32 replicas = 3 } @@ -118,7 +118,7 @@ variable "cluster_worker_node_config" { default = { processors = 4 system_type = null - proc_type = "Dedicated" + proc_type = "Shared" memory = 32 replicas = 3 } From 404441140d7656de83f10303c22da6ad567c0938 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 10 Sep 2025 20:24:05 +0200 Subject: [PATCH 36/83] chore: revert intel image back to rhel9-4 --- solutions/standard-openshift/README.md | 2 +- solutions/standard-openshift/variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 6c636313..e2e7a135 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -50,7 +50,7 @@ | [ssh\_public\_key](#input\_ssh\_public\_key) | Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region. | `string` | n/a | yes | | [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace | `list(string)` | `[]` | no | | [user\_id](#input\_user\_id) | The IBM Cloud login user ID associated with the account where the cluster will be deployed. | `string` | n/a | yes | -| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-6-amd64-sap-applications-1",
"sles_image": "ibm-sles-15-7-amd64-sap-applications-1"
}
| no | +| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-4-amd64-sap-applications-7",
"sles_image": "ibm-sles-15-7-amd64-sap-applications-1"
}
| no | ### Outputs diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 33a4a729..c53eac26 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -157,7 +157,7 @@ variable "vpc_intel_images" { sles_image = string }) default = { - "rhel_image" : "ibm-redhat-9-6-amd64-sap-applications-1" + "rhel_image" : "ibm-redhat-9-4-amd64-sap-applications-7" "sles_image" : "ibm-sles-15-7-amd64-sap-applications-1" } } From c9ad9eff521bb628d49d9cc7c3fe43793563809b Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 10 Sep 2025 21:37:52 +0200 Subject: [PATCH 37/83] chore(docs): var description --- solutions/standard-openshift/README.md | 2 +- solutions/standard-openshift/variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index e2e7a135..4be572d4 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -35,7 +35,7 @@ | [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "10.128.0.0/14",
"cluster_service_network_cidr": "10.67.0.0/16"
}
| no | | [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Shared",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [enable\_monitoring](#input\_enable\_monitoring) | Specify whether Monitoring will be enabled. This includes the creation of an IBM Cloud Monitoring Instance and an Intel Monitoring Instance to host the services. If you already have an existing monitoring instance then specify in optional parameter 'existing\_monitoring\_instance\_crn' and setting this parameter to true. | `bool` | `false` | no | -| [enable\_scc\_wp](#input\_enable\_scc\_wp) | Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. If set to true, then value for 'ansible\_vault\_password' in optional parameter must be set. | `bool` | `true` | no | +| [enable\_scc\_wp](#input\_enable\_scc\_wp) | Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. | `bool` | `true` | no | | [existing\_monitoring\_instance\_crn](#input\_existing\_monitoring\_instance\_crn) | Existing CRN of IBM Cloud Monitoring Instance. If value is null, then an IBM Cloud Monitoring Instance will not be created but an intel VSI instance will be created if 'enable\_monitoring' is true. | `string` | `null` | no | | [existing\_sm\_instance\_guid](#input\_existing\_sm\_instance\_guid) | An existing Secrets Manager GUID. If not provided a new instance will be provisioned. | `string` | `null` | no | | [existing\_sm\_instance\_region](#input\_existing\_sm\_instance\_region) | Required if value is passed into `var.existing_sm_instance_guid`. | `string` | `null` | no | diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index c53eac26..d4faeefa 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -179,7 +179,7 @@ variable "external_access_ip" { ##################################################### variable "enable_scc_wp" { - description = "Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. If set to true, then value for 'ansible_vault_password' in optional parameter must be set." + description = "Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment." type = bool default = true } From e788d31228c1d0d5e45a993d7152954364a8d902 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 10 Sep 2025 21:39:29 +0200 Subject: [PATCH 38/83] feat: add openshift DA to catalog manifest --- ibm_catalog.json | 474 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 474 insertions(+) diff --git a/ibm_catalog.json b/ibm_catalog.json index 65a9f2c8..8d2e325c 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1229,6 +1229,480 @@ }, "terraform_version": "1.10.5" }, + { + "label": "Quickstart Openshift", + "name": "standard-openshift", + "install_type": "fullstack", + "index": 3, + "working_directory": "solutions/standard-openshift", + "compliance": { + "authority": "scc-v3", + "profiles": [ + { + "profile_name": "IBM Cloud Framework for Financial Services", + "profile_version": "1.7.0" + } + ] + }, + "configuration": [ + { + "key": "cluster_name", + "type": "string", + "default_value": "", + "required": true + }, + { + "key": "powervs_zone", + "type": "string", + "required": true, + "default_value": "", + "options": [ + { + "displayname": "Dallas (dallas)", + "value": "us-south" + }, + { + "displayname": "Dallas 10 (dal10)", + "value": "dal10" + }, + { + "displayname": "Dallas 12 (dal12)", + "value": "dal12" + }, + { + "displayname": "Frankfurt 1 (eu-de-1)", + "value": "eu-de-1" + }, + { + "displayname": "Frankfurt 2 (eu-de-2)", + "value": "eu-de-2" + }, + { + "displayname": "London 04 (lon04)", + "value": "lon04" + }, + { + "displayname": "London 06 (lon06)", + "value": "lon06" + }, + { + "displayname": "Madrid 02 (mad02)", + "value": "mad02" + }, + { + "displayname": "Madrid 04 (mad04)", + "value": "mad04" + }, + { + "displayname": "Osaka 21 (osa21)", + "value": "osa21" + }, + { + "displayname": "Sao Paulo 01 (sao01)", + "value": "sao01" + }, + { + "displayname": "Sao Paulo 04 (sao04)", + "value": "sao04" + }, + { + "displayname": "Sydney 04 (syd04)", + "value": "syd04" + }, + { + "displayname": "Sydney 05 (syd05)", + "value": "syd05" + }, + { + "displayname": "Washington DC (us-east)", + "value": "us-east" + }, + { + "displayname": "Washington DC 06 (wdc06)", + "value": "wdc06" + }, + { + "displayname": "Washington DC 07 (wdc07)", + "value": "wdc07" + } + ], + "custom_config": {} + }, + { + "key": "external_access_ip", + "default_value": "__NULL__", + "required": true + }, + { + "key": "ssh_public_key", + "type": "multiline_secure_value", + "display_name": "ssh_public_key", + "required": true, + "custom_config": { + "grouping": "deployment", + "original_grouping": "deployment", + "type": "multiline_secure_value" + } + }, + { + "key": "ssh_private_key", + "type": "multiline_secure_value", + "display_name": "ssh_private_key", + "required": true, + "custom_config": { + "grouping": "deployment", + "original_grouping": "deployment", + "type": "multiline_secure_value" + } + }, + { + "key": "ibmcloud_api_key", + "type": "multiline_secure_value", + "display_name": "Multiline secure value", + "required": true, + "custom_config": { + "grouping": "deployment", + "original_grouping": "deployment", + "type": "multiline_secure_value" + } + }, + { + "key": "user_id", + "type": "string", + "display_name": "user_id", + "required": true + }, + { + "key": "openshift_pull_secret", + "type": "multiline_secure_value", + "display_name": "openshift_pull_secret", + "required": true + }, + { + "key": "cluster_base_domain", + "type": "string", + "display_name": "cluster_base_domain", + "required": true + }, + { + "key": "openshift_release", + "type": "string", + "display_name": "openshift_release" + }, + { + "key": "cluster_network_config", + "type": "code_editor", + "display_name": "cluster_network_config" + }, + { + "key": "cluster_master_node_config", + "type": "code_editor", + "display_name": "cluster_master_node_config" + }, + { + "key": "cluster_worker_node_config", + "type": "code_editor", + "display_name": "cluster_worker_node_config" + }, + { + "key": "tags" + }, + { + "key": "vpc_intel_images", + "hidden": true + }, + { + "key": "network_services_vsi_profile" + }, + { + "key": "enable_scc_wp" + }, + { + "key": "ansible_vault_password", + "type": "multiline_secure_value", + "display_name": "ansible_vault_password", + "required": true + }, + { + "key": "enable_monitoring" + }, + { + "key": "existing_monitoring_instance_crn" + }, + { + "key": "client_to_site_vpn" + }, + { + "key": "sm_service_plan" + }, + { + "key": "existing_sm_instance_guid" + }, + { + "key": "existing_sm_instance_region", + "type": "string", + "default_value": "__NULL__", + "options": [ + { + "displayname": "Null", + "value": "__NULL__" + }, + { + "displayname": "au-syd", + "value": "au-syd" + }, + { + "displayname": "br-sao", + "value": "br-sao" + }, + { + "displayname": "ca-tor", + "value": "ca-tor" + }, + { + "displayname": "eu-de", + "value": "eu-de" + }, + { + "displayname": "eu-gb", + "value": "eu-gb" + }, + { + "displayname": "jp-osa", + "value": "jp-osa" + }, + { + "displayname": "jp-tok", + "value": "jp-tok" + }, + { + "displayname": "us-east", + "value": "us-east" + }, + { + "displayname": "us-south", + "value": "us-south" + } + ], + "custom_config": {} + }, + { + "key": "IC_SCHEMATICS_WORKSPACE_ID", + "hidden": true + } + ], + "outputs": [ + { + "key": "prefix" + }, + { + "key": "vpc_names" + }, + { + "key": "vpc_data" + }, + { + "key": "vsi_names" + }, + { + "key": "kms_key_map" + }, + { + "key": "vsi_ssh_key_data" + }, + { + "key": "network_load_balancer" + }, + { + "key": "ssh_public_key" + }, + { + "key": "transit_gateway_name" + }, + { + "key": "transit_gateway_id" + }, + { + "key": "transit_gateway_global" + }, + { + "key": "vsi_list" + }, + { + "key": "resource_group_data" + }, + { + "key": "access_host_or_ip" + }, + { + "key": "proxy_host_or_ip_port" + }, + { + "key": "dns_host_or_ip" + }, + { + "key": "ntp_host_or_ip" + }, + { + "key": "nfs_host_or_ip_path" + }, + { + "key": "ansible_host_or_ip" + }, + { + "key": "network_services_config" + }, + { + "key": "powervs_zone" + }, + { + "key": "powervs_resource_group_name" + }, + { + "key": "powervs_workspace_name" + }, + { + "key": "powervs_workspace_id" + }, + { + "key": "powervs_workspace_guid" + }, + { + "key": "powervs_ssh_public_key" + }, + { + "key": "powervs_management_subnet" + }, + { + "key": "powervs_backup_subnet" + }, + { + "key": "powervs_images" + }, + { + "key": "monitoring_instance" + }, + { + "key": "schematics_workspace_id" + } + ], + "iam_permissions": [ + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager" + ], + "service_name": "appid" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager" + ], + "service_name": "cloud-object-storage" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager" + ], + "service_name": "hs-crypto" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Administrator" + ], + "service_name": "iam-identity" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager" + ], + "service_name": "kms" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Administrator" + ], + "service_name": "is.vpc" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "is.vpc" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "transit.gateway" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager" + ], + "service_name": "power-iaas" + } + ], + "architecture": { + "features": [ + { + "title": "Power Virtual Server Instance", + "description": "No" + }, + { + "title": "Number of Intel Virtual Server Instance", + "description": "2" + }, + { + "title": "Number of VPCs", + "description": "1" + }, + { + "title": "Number of Power Virtual Server Workspace", + "description": "1" + }, + { + "title": "Increases security with Key Management", + "description": "Yes" + }, + { + "title": "Internet proxy on VPC", + "description": "Proxy service to reach public internet from PowerVS Workspace" + }, + { + "title": "Additional management configurations on VPC", + "description": "NFS as service, NTP forwarder, and DNS forwarder reachable from PowerVS Workspace" + }, + { + "title": "Client to site VPN with new or existing Secrets Manager instance", + "description": "Optional" + }, + { + "title": "SCC Workload Protection instance", + "description": "Optional" + }, + { + "title": "Monitoring Instance and Monitoring Intel VSI Host", + "description": "Optional" + }, + { + "title": "Bring your own image to PowerVS", + "description": "Optional" + } + ], + "diagrams": [ + { + "diagram": { + "caption": "Power Virtual Server with VPC landing zone 'Standard Landscape' variation", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v9.0.0/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.svg", + "type": "image/svg+xml" + }, + "description": "The Power Virtual Server with VPC landing zone as variation 'Create a new architecture' deploys VPC services and a Power Virtual Server workspace and interconnects them.\n \nRequired and optional management components are configured." + } + ] + }, + "terraform_version": "1.10.5" + }, { "label": "Extend Standard Landscape", "name": "standard-extend", From b7b331aa6b44dc937bd8f28bbd5f35ab7d0dc927 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 11 Sep 2025 14:06:26 +0200 Subject: [PATCH 39/83] chore(docs): minor edits in catalog manifest --- ibm_catalog.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 8d2e325c..7ca8b0bd 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1693,11 +1693,11 @@ "diagrams": [ { "diagram": { - "caption": "Power Virtual Server with VPC landing zone 'Standard Landscape' variation", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v9.0.0/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.svg", + "caption": "Power Virtual Server with VPC landing zone 'Quickstart Openshift' variation", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v9.0.0/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard.svg", "type": "image/svg+xml" }, - "description": "The Power Virtual Server with VPC landing zone as variation 'Create a new architecture' deploys VPC services and a Power Virtual Server workspace and interconnects them.\n \nRequired and optional management components are configured." + "description": "The Power Virtual Server with VPC landing zone as variation 'Quickstart Openshift' deploys VPC services and an Openshift Cluster on PowerVS and interconnects them.\n \nRequired and optional management components are configured." } ] }, From d008ec2a67fdb0d091759859bcf60594c4bfdf70 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 11 Sep 2025 15:19:20 +0200 Subject: [PATCH 40/83] fix: add ca-mon to existing secrets manager regions --- ibm_catalog.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ibm_catalog.json b/ibm_catalog.json index 7ca8b0bd..e3937a38 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -322,6 +322,10 @@ "displayname": "br-sao", "value": "br-sao" }, + { + "displayname": "ca-mon", + "value": "ca-mon" + }, { "displayname": "ca-tor", "value": "ca-tor" @@ -975,6 +979,10 @@ "displayname": "br-sao", "value": "br-sao" }, + { + "displayname": "ca-mon", + "value": "ca-mon" + }, { "displayname": "ca-tor", "value": "ca-tor" @@ -1455,6 +1463,10 @@ "displayname": "br-sao", "value": "br-sao" }, + { + "displayname": "ca-mon", + "value": "ca-mon" + }, { "displayname": "ca-tor", "value": "ca-tor" From 63122a75fbef18249c4cce3f7575ae1d5d7ade13 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 12 Sep 2025 10:11:36 +0200 Subject: [PATCH 41/83] chore: reorder memory --- solutions/standard-openshift/README.md | 4 ++-- solutions/standard-openshift/variables.tf | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 4be572d4..337f2e76 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -30,10 +30,10 @@ | [ansible\_vault\_password](#input\_ansible\_vault\_password) | Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]\_{\|}~. | `string` | n/a | yes | | [client\_to\_site\_vpn](#input\_client\_to\_site\_vpn) | VPN configuration - the client ip pool and list of users email ids to access the environment. If enabled, then a Secret Manager instance is also provisioned with certificates generated. See optional parameters to reuse an existing Secrets manager instance. |
object({
enable = bool
client_ip_pool = string
vpn_client_access_group_users = list(string)
})
|
{
"client_ip_pool": "192.168.0.0/16",
"enable": true,
"vpn_client_access_group_users": []
}
| no | | [cluster\_base\_domain](#input\_cluster\_base\_domain) | The base domain name that will be used by the cluster. (ie: example.com) | `string` | n/a | yes | -| [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Shared",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | +| [cluster\_master\_node\_config](#input\_cluster\_master\_node\_config) | Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
memory = number
system_type = string
proc_type = string
replicas = number
})
|
{
"memory": 32,
"proc_type": "Shared",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [cluster\_name](#input\_cluster\_name) | The name of the cluster and a unique identifier used as prefix for resources. Must begin with a lowercase letter and end with a lowercase letter or number. Must contain only lowercase letters, numbers, and - characters. This prefix will be prepended to any resources provisioned by this template. Prefixes must be 16 or fewer characters. | `string` | n/a | yes | | [cluster\_network\_config](#input\_cluster\_network\_config) | Configuration object for the OpenShift cluster and service network CIDRs. |
object({
cluster_network_cidr = string
cluster_service_network_cidr = string
cluster_machine_network_cidr = string
})
|
{
"cluster_machine_network_cidr": "10.72.0.0/24",
"cluster_network_cidr": "10.128.0.0/14",
"cluster_service_network_cidr": "10.67.0.0/16"
}
| no | -| [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
system_type = string
proc_type = string
memory = number
replicas = number
})
|
{
"memory": 32,
"proc_type": "Shared",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | +| [cluster\_worker\_node\_config](#input\_cluster\_worker\_node\_config) | Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system\_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB. |
object({
processors = number
memory = number
system_type = string
proc_type = string
replicas = number
})
|
{
"memory": 32,
"proc_type": "Shared",
"processors": 4,
"replicas": 3,
"system_type": null
}
| no | | [enable\_monitoring](#input\_enable\_monitoring) | Specify whether Monitoring will be enabled. This includes the creation of an IBM Cloud Monitoring Instance and an Intel Monitoring Instance to host the services. If you already have an existing monitoring instance then specify in optional parameter 'existing\_monitoring\_instance\_crn' and setting this parameter to true. | `bool` | `false` | no | | [enable\_scc\_wp](#input\_enable\_scc\_wp) | Enable SCC Workload Protection and install and configure the SCC Workload Protection agent on all intel VSIs in this deployment. | `bool` | `true` | no | | [existing\_monitoring\_instance\_crn](#input\_existing\_monitoring\_instance\_crn) | Existing CRN of IBM Cloud Monitoring Instance. If value is null, then an IBM Cloud Monitoring Instance will not be created but an intel VSI instance will be created if 'enable\_monitoring' is true. | `string` | `null` | no | diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index d4faeefa..2e86d1b3 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -80,16 +80,16 @@ variable "cluster_master_node_config" { description = "Configuration for the master nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB." type = object({ processors = number + memory = number system_type = string proc_type = string - memory = number replicas = number }) default = { processors = 4 + memory = 32 system_type = null proc_type = "Shared" - memory = 32 replicas = 3 } validation { @@ -110,16 +110,16 @@ variable "cluster_worker_node_config" { description = "Configuration for the worker nodes of the OpenShift cluster, including CPU, system type, processor type, and replica count. If system_type is null, it's chosen based on whether it's supported in the region. This can be overwritten by passing a value, e.g. 's1022' or 's922'. Memory is in GB." type = object({ processors = number + memory = number system_type = string proc_type = string - memory = number replicas = number }) default = { processors = 4 + memory = 32 system_type = null proc_type = "Shared" - memory = 32 replicas = 3 } validation { From 1ae6ce60becf67cf46d08fbc6e07b0fc85525fa1 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 12 Sep 2025 10:22:32 +0200 Subject: [PATCH 42/83] fix: add validation to ensure subnets are sufficiently large --- solutions/standard-openshift/variables.tf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 2e86d1b3..ee87d4f1 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -74,6 +74,18 @@ variable "cluster_network_config" { cluster_service_network_cidr = "10.67.0.0/16" cluster_machine_network_cidr = "10.72.0.0/24" } + validation { + condition = can(regex("/([0-9]{1,2})$", var.cluster_network_config.cluster_network_cidr)) && tonumber(regex("/([0-9]{1,2})$", var.cluster_network_config.cluster_network_cidr)[0]) <= 14 + error_message = "The CIDR suffix must be /14 or less to ensure enough IP addresses are available in this subnet (e.g., 10.128.0.0/14)." + } + validation { + condition = can(regex("/([0-9]{1,2})$", var.cluster_network_config.cluster_service_network_cidr)) && tonumber(regex("/([0-9]{1,2})$", var.cluster_network_config.cluster_service_network_cidr)[0]) <= 16 + error_message = "The CIDR suffix must be /16 or less to ensure enough IP addresses are available in this subnet (e.g., 10.67.0.0/16)." + } + validation { + condition = can(regex("/([0-9]{1,2})$", var.cluster_network_config.cluster_network_cidr)) && tonumber(regex("/([0-9]{1,2})$", var.cluster_network_config.cluster_network_cidr)[0]) <= 24 + error_message = "The CIDR suffix must be /24 or less to ensure enough IP addresses are available in this subnet (e.g., 10.72.0.0/24)." + } } variable "cluster_master_node_config" { From 510c9b9b280a05920d96cb964b296ea2c409b0fc Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 12 Sep 2025 10:29:18 +0200 Subject: [PATCH 43/83] BREAKING CHANGE: remove extension variation --- .catalog-onboard-pipeline.yaml | 6 - README.md | 9 +- ibm_catalog.json | 328 ------------------ ...deploy-arch-ibm-pvs-inf-standard-extend.md | 89 ----- ...eploy-arch-ibm-pvs-inf-standard-extend.svg | 4 - ...eploy-arch-ibm-pvs-inf-standard-extend.svg | 4 - solutions/standard-extend/README.md | 104 ------ .../catalogValidationValues.json.template | 6 - .../standard-extend/locals_schematics_data.tf | 57 --- solutions/standard-extend/main.tf | 41 --- solutions/standard-extend/outputs.tf | 164 --------- solutions/standard-extend/provider.tf | 31 -- solutions/standard-extend/variables.tf | 132 ------- solutions/standard-extend/versions.tf | 13 - 14 files changed, 2 insertions(+), 986 deletions(-) delete mode 100644 reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md delete mode 100644 reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.svg delete mode 100644 reference-architectures/standard-extend/heat-map-deploy-arch-ibm-pvs-inf-standard-extend.svg delete mode 100644 solutions/standard-extend/README.md delete mode 100644 solutions/standard-extend/catalogValidationValues.json.template delete mode 100644 solutions/standard-extend/locals_schematics_data.tf delete mode 100644 solutions/standard-extend/main.tf delete mode 100644 solutions/standard-extend/outputs.tf delete mode 100644 solutions/standard-extend/provider.tf delete mode 100644 solutions/standard-extend/variables.tf delete mode 100644 solutions/standard-extend/versions.tf diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index dde5049e..16367f67 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -18,9 +18,3 @@ offerings: scc: instance_id: d9f6ba0c-dd0e-4348-a834-6002b675fe40 region: us-south - - name: standard-extend - mark_ready: false - install_type: extension - scc: - instance_id: d9f6ba0c-dd0e-4348-a834-6002b675fe40 - region: us-south diff --git a/README.md b/README.md index 30ba3847..8667da2a 100644 --- a/README.md +++ b/README.md @@ -9,20 +9,16 @@ ## Summary This repository contains deployable architecture solutions that help provision VPC landing zones, PowerVS workspaces, and interconnect them. The solutions are available in the IBM Cloud Catalog and can also be deployed without the catalog, except for the second solution below. -Three solutions are offered: +Two solutions are offered: 1. [Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard) - Creates a VPC and Power Virtual Server workspace, interconnects them, and configures OS network management services (SQUID proxy, NTP, NFS, and DNS services) using Ansible Galaxy collection roles [ibm.power_linux_sap collection](https://galaxy.ansible.com/ui/repo/published/ibm/power_linux_sap/). -2. [Extend Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-extend) - - Extends the standard landscape solution by creating a new Power Virtual Server workspace in a different zone and interconnects with the previous solution. - - This solution is typically used for **High Availability scenarios** where a single management VPC can be used to reach both PowerVS workspaces. -3. [Quickstart (Standard Landscape plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-plus-vsi) +2. [Quickstart (Standard Landscape plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-plus-vsi) - Creates a VPC and a Power Virtual Server workspace, interconnects them, and configures operating network management services (SQUID proxy, NTP, NFS, and DNS services) using Ansible Galaxy collection roles [ibm.power_linux_sap collection](https://galaxy.ansible.com/ui/repo/published/ibm/power_linux_sap/). - Additionally creates a Power Virtual Server Instance of a selected t-shirt size. Network management services, filesystems and SCC Workload protection agents are configured for AIX and Linux instances. - This solution is typically utilized for **PoCs, demos, and quick onboarding** to PowerVS Infrastructure. ## Reference architectures - [Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md) -- [Extend Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md) - [Quickstart (Standard Landscape plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md) ## Solutions @@ -30,7 +26,6 @@ Three solutions are offered: | Variation | Available on IBM Catalog | Requires IBM Schematics Workspace ID | Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastructure | Creates PowerVS Instance | Performs PowerVS OS Config | | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | | [Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard) | :heavy_check_mark: | N/A | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | -| [Extend Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-extend) | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | :heavy_check_mark: | N/A | N/A | | [Quickstart (Standard Landscape plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-plus-vsi) | :heavy_check_mark: | N/A | :heavy_check_mark:| :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | diff --git a/ibm_catalog.json b/ibm_catalog.json index e3937a38..5c4e195a 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1714,334 +1714,6 @@ ] }, "terraform_version": "1.10.5" - }, - { - "label": "Extend Standard Landscape", - "name": "standard-extend", - "install_type": "extension", - "index": 4, - "working_directory": "solutions/standard-extend", - "compliance": { - "authority": "", - "profiles": [] - }, - "dependencies": [ - { - "flavors": [ - "standard", - "standard-plus-vsi" - ], - "install_type": "fullstack", - "catalogID": "1082e7d2-5e2f-0a11-a3bc-f88a8e1931fc", - "id": "2dd486c7-b317-4aaa-907b-42671485ad96-global", - "name": "deploy-arch-ibm-pvs-inf", - "version": ">=5.0.0", - "optional": true - } - ], - "configuration": [ - { - "key": "prerequisite_workspace_id", - "required": true, - "custom_config": { - "config_constraints": { - "catalogID": "1082e7d2-5e2f-0a11-a3bc-f88a8e1931fc", - "offeringID": "2dd486c7-b317-4aaa-907b-42671485ad96-global", - "install_type": "fullstack", - "versionConstraint": ">=5.0.0" - }, - "grouping": "deployment", - "original_grouping": "deployment", - "type": "schematics_workspace" - } - }, - { - "key": "powervs_zone", - "type": "string", - "required": true, - "default_value": "", - "options": [ - { - "displayname": "Dallas (dallas)", - "value": "us-south" - }, - { - "displayname": "Dallas 10 (dal10)", - "value": "dal10" - }, - { - "displayname": "Dallas 12 (dal12)", - "value": "dal12" - }, - { - "displayname": "Dallas 14 (dal14)", - "value": "dal14" - }, - { - "displayname": "Frankfurt 1 (eu-de-1)", - "value": "eu-de-1" - }, - { - "displayname": "Frankfurt 2 (eu-de-2)", - "value": "eu-de-2" - }, - { - "displayname": "London 04 (lon04)", - "value": "lon04" - }, - { - "displayname": "London 06 (lon06)", - "value": "lon06" - }, - { - "displayname": "Madrid 02 (mad02)", - "value": "mad02" - }, - { - "displayname": "Madrid 04 (mad04)", - "value": "mad04" - }, - { - "displayname": "Osaka 21 (osa21)", - "value": "osa21" - }, - { - "displayname": "Sao Paulo 01 (sao01)", - "value": "sao01" - }, - { - "displayname": "Sao Paulo 04 (sao04)", - "value": "sao04" - }, - { - "displayname": "Sydney 04 (syd04)", - "value": "syd04" - }, - { - "displayname": "Sydney 05 (syd05)", - "value": "syd05" - }, - { - "displayname": "Tokyo 04 (tok04)", - "value": "tok04" - }, - { - "displayname": "Toronto 01 (tor01)", - "value": "tor01" - }, - { - "displayname": "Washington DC (us-east)", - "value": "us-east" - }, - { - "displayname": "Washington DC 06 (wdc06)", - "value": "wdc06" - }, - { - "displayname": "Washington DC 07 (wdc07)", - "value": "wdc07" - } - ], - "custom_config": {} - }, - { - "key": "powervs_resource_group_name", - "required": true, - "default_value": "", - "custom_config": { - "config_constraints": { - "identifier": "rg_name" - }, - "grouping": "deployment", - "original_grouping": "deployment", - "type": "resource_group" - } - }, - { - "key": "powervs_management_network", - "required": true - }, - { - "key": "powervs_backup_network", - "required": true - }, - { - "key": "ibmcloud_api_key", - "type": "multiline_secure_value", - "display_name": "Multiline secure value", - "required": true, - "custom_config": { - "grouping": "deployment", - "original_grouping": "deployment", - "type": "multiline_secure_value" - } - }, - { - "key": "powervs_custom_images", - "custom_config": { - "grouping": "deployment", - "original_grouping": "deployment", - "type": "code_editor" - } - }, - { - "key": "powervs_custom_image_cos_configuration", - "custom_config": { - "grouping": "deployment", - "original_grouping": "deployment", - "type": "code_editor" - } - }, - { - "key": "powervs_custom_image_cos_service_credentials", - "type": "multiline_secure_value", - "display_name": "powervs_custom_image_cos_service_credentials", - "custom_config": { - "grouping": "deployment", - "original_grouping": "deployment", - "type": "multiline_secure_value" - } - }, - { - "key": "tags" - }, - { - "key": "IC_SCHEMATICS_WORKSPACE_ID", - "hidden": true - } - ], - "outputs": [ - { - "key": "prefix" - }, - { - "key": "vpc_names" - }, - { - "key": "vpc_data" - }, - { - "key": "vsi_names" - }, - { - "key": "kms_key_map" - }, - { - "key": "vsi_ssh_key_data" - }, - { - "key": "network_load_balancer" - }, - { - "key": "ssh_public_key" - }, - { - "key": "transit_gateway_name" - }, - { - "key": "transit_gateway_id" - }, - { - "key": "vsi_list" - }, - { - "key": "access_host_or_ip" - }, - { - "key": "proxy_host_or_ip_port" - }, - { - "key": "dns_host_or_ip" - }, - { - "key": "ntp_host_or_ip" - }, - { - "key": "nfs_host_or_ip_path" - }, - { - "key": "ansible_host_or_ip" - }, - { - "key": "network_services_config" - }, - { - "key": "powervs_zone" - }, - { - "key": "powervs_resource_group_name" - }, - { - "key": "powervs_workspace_name" - }, - { - "key": "powervs_workspace_id" - }, - { - "key": "powervs_workspace_guid" - }, - { - "key": "powervs_ssh_public_key" - }, - { - "key": "powervs_management_subnet" - }, - { - "key": "powervs_backup_subnet" - }, - { - "key": "powervs_images" - }, - { - "key": "monitoring_instance" - }, - { - "key": "schematics_workspace_id" - } - ], - "iam_permissions": [ - { - "role_crns": [ - "crn:v1:bluemix:public:iam::::role:Editor" - ], - "service_name": "is.vpc" - }, - { - "role_crns": [ - "crn:v1:bluemix:public:iam::::role:Editor" - ], - "service_name": "transit.gateway" - }, - { - "role_crns": [ - "crn:v1:bluemix:public:iam::::serviceRole:Manager" - ], - "service_name": "power-iaas" - } - ], - "architecture": { - "features": [ - { - "title": "Power Virtual Server Workspace", - "description": "PowerVS Workspace with all required components in different zone. Used for HA scenario." - }, - { - "title": "Bring your own image to PowerVS", - "description": "Optional" - } - ], - "diagrams": [ - { - "diagram": { - "caption": "Power Virtual Server with VPC landing zone 'Extend Standard Landscape' variation", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v9.0.0/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.svg", - "type": "image/svg+xml" - }, - "description": "The Power Virtual Server with VPC landing zone as variation 'Extend Power Virtual Server with VPC landing zone' creates an additional Power Virtual Server workspace and connects it with already created Power Virtual Server with VPC landing zone. It builds on existing Power Virtual Server with VPC landing zone deployed as a variation 'Create a new architecture'." - } - ] - }, - "terraform_version": "1.10.5" } ] } diff --git a/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md b/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md deleted file mode 100644 index 7dd4c2f7..00000000 --- a/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -copyright: - years: 2024, 2025 -lastupdated: "2025-09-08" -keywords: -subcollection: deployable-reference-architectures -authors: - - name: Arnold Beilmann - - name: Suraj Bharadwaj - - name: Ludwig Mueller -production: true -deployment-url: https://cloud.ibm.com/catalog/architecture/deploy-arch-ibm-pvs-inf-2dd486c7-b317-4aaa-907b-42671485ad96-global -docs: https://cloud.ibm.com/docs/powervs-vpc -image_source: https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.svg -use-case: ITServiceManagement -industry: Technology -content-type: reference-architecture -version: v9.0.1 -compliance: SAPCertified - ---- - -{{site.data.keyword.attribute-definition-list}} - -# Power Virtual Server with VPC landing zone - 'Extend Standard Landscape Variation' -{: #deploy-arch-ibm-pvs-inf-extension} -{: toc-content-type="reference-architecture"} -{: toc-industry="Technology"} -{: toc-use-case="ITServiceManagement"} -{: toc-compliance="SAPCertified"} -{: toc-version="v9.0.1"} - -The Power Virtual Server with VPC landing zone as variation 'Extend Power Virtual Server with VPC landing zone' creates an additional Power Virtual Server workspace and connects it with the already created Power Virtual Server with VPC landing zone. It builds on the existing Power Virtual Server with VPC landing zone deployed as a variation 'Create a new architecture'. - -## Architecture diagram -{: #standard-extend-architecture-diagram} - -![Architecture diagram for 'Power Virtual Server with VPC landing zone' - variation 'Extend Standard Landscape'](deploy-arch-ibm-pvs-inf-standard-extend.svg "Architecture diagram"){: caption="Figure 1. Single-zone PowerVS workspace accessible over secure landing zone" caption-side="bottom"}{: external download="deploy-arch-ibm-pvs-inf-standard-extend.svg"} - -## Design requirements -{: #standard-extend-design-requirements} - -![Design requirements for 'Power Virtual Server with VPC landing zone' - variation 'Extend Standard Landscape'](heat-map-deploy-arch-ibm-pvs-inf-standard-extend.svg "Design requirements"){: caption="Figure 2. Scope of the solution requirements" caption-side="bottom"} - -IBM Cloud® Power Virtual Servers (PowerVS) is a public cloud offering that an enterprise can use to establish its own private IBM Power computing environment on shared public cloud infrastructure. PowerVS is logically isolated from all other public cloud tenants and infrastructure components, creating a private, secure place on the public cloud. This deployable architecture provides a framework to build a PowerVS offering according to the best practices and requirements from the IBM Cloud. - -## Components -{: #standard-extend-components} - -### PowerVS workspace architecture decisions -{: #standard-extend-pvs-components-workspace} - -| Requirement | Component | Choice | Alternative choice | -|-------------|-----------|--------------------|--------------------| -|* Connect PowerVS workspace with VPC services|Transit gateway| Set up a local transit gateway| | -|* Configure the network for management of all instances \n * Throughput and latency are not relevant|Management network|Configure private network with default configurations| | -|* Configure separate network for backup purposes with higher data throughput|Backup network|Configure separate private network with default configurations and attach it to both cloud connections. Networks characteristics might be adapted by the users manually (for example to improve throughput)| | -|* Allow optional import of custom OS images from Cloud Object Storage|Custom OS images|Import up to three images from COS into the PowerVS workspace.|Modify the optional input parameters that specify the list of custom OS images and the COS configuration and credentials .| -|* Preload a public SSH key that is injected into every OS deployment|Preloaded SSH public key|Preload customer specified SSH public key| | -{: caption="Table 2. PowerVS workspace architecture decisions" caption-side="bottom"} - -### PowerVS management services architecture decisions -{: #standard-extend-pvs-components-mgmt} - -| Requirement | Component | Choice | Alternative choice | -|-------------|-----------|--------------------|--------------------| -|* Ensure public internet connectivity from all the instances to be deployed in PowerVS workspace|SQUID proxy|Set up SQUID proxy software on Linux virtual server instance that is running in edge VPC| | -|* Provide shared NFS storage that might be directly attached to all the instances to be deployed in PowerVS workspace| File storage shares in VPC|Use the files storage share service running in VPC. Disk size is specified by the user.| | -|* Provide time synchronization to all instances to be deployed in PowerVS workspace|NTP forwarder|Synchronize time by using public NTP servers. Set up time synchronization on Linux virtual server instance that is running in workload VPC.|By using time synchronization servers directly reachable from PowerVS workspace, NTP forwarder is not required.| -|* Provide a DNS forwarder to a DNS server not directly reachable from PowerVS workspace (for example, running on-premises or in other isolated environment)|DNS forwarder|Configure DNS forwarder on Linux virtual server instance that is running in edge VPC| By using default IBM Cloud DNS service, DNS forwarder is not needed. Direct domain name resolution is possible.| -{: caption="Table 3. PowerVS management services architecture decisions" caption-side="bottom"} - -### Key and password management architecture decisions -{: #standard-extend-key-pw} - -| Requirement | Component | Choice | Alternative choice | -|-------------|-----------|--------------------|--------------------| -|* Use public/private SSH key to access virtual server instances by using SSH \n * Use SSH proxy to log in to all virtual server instances by using the bastion host \n * Do not store private ssh key on any virtual instances, also not on the bastion host \n * Do not allow any other SSH login methods except the one with specified private/public SSH key pair|Public SSH key - provided by customer. Private SSH key - provided by customer.|Ask customer to specify the keys. Accept the input as secure parameter or as reference to the key stored in IBM Cloud Secure Storage Manager. Do not print SSH keys in any log files. Do not persist private SSH key. Ask for private SSH key only if management components can be reconfigured, otherwise do not enforce private SSH key to be entered.| | -{: caption="Table 5. Key and passwords management architecture decisions" caption-side="bottom"} - -## Compliance -{: #standard-extend-compliance} - -This reference architecture is certified for SAP deployments. - -## Next steps -{: #standard-extend-next-steps} - -Install the SAP on Power deployable architecture on this infrastructure. diff --git a/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.svg b/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.svg deleted file mode 100644 index 7b9cc11f..00000000 --- a/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Consumer
Consumer
UserInternet
IBM Cloud
IBM Cloud
SCC WorkloadProtection
Cloud Services
Cloud Services
Edge VPC Flow Log CollectorSecretsManagerObject  StorageInstallation filesObject  StorageActivity trackerActivity TrackerAcitivity Tracker Event RoutingKey Protect Monitoring
Services Resource Group
Services Resource Group
Zone 1
Zone 1
TransitGateway
PowerVS Resource Group
PowerVS Resource Group
Secure PowerVS Workspace
Secure PowerVS Workspace
SSH Public Key
10.51.0.0/24: Management Subnet
10.51.0.0/24: Management Subnet
10.52.0.0/24: Backup Subnet
10.52.0.0/24: Backup Subnet
COSCustom Images
Zone 2
Zone 2
PowerVS Resource Group
PowerVS Resource Group
Secure PowerVS Workspace
Secure PowerVS Workspace
SSH Public Key
10.61.0.0/24: Management Subnet
10.61.0.0/24: Management Subnet
10.62.0.0/24: Backup Subnet
10.62.0.0/24: Backup Subnet
COSCustom Images
Edge Resource Group
Edge Resource Group
10.30.30.0/24: 
VPE Subnet
10.30.30.0/24:...
COS VPE
VPE SG
VPE SG
Edge VPC (Default ACL)
Edge VPC (Default ACL)
Management SG
Management SG
10.30.20.0/24: 
Mgmt VSI Subnet
10.30.20.0/24:...
Virtual Server
Virtual Server
FloatingIPBastionHost
Default SG
Default SG
10.30.10.0/24: 
VPN Subnet
10.30.10.0/24:...
Client to site VPN server
Network-services SG
Network-services SG
10.30.40.0/24: Edge VSI Subnet
10.30.40.0/24: Edge VSI Subnet
Virtual Server
Virtual Server
Proxy ServerDNSForwarderNTP ForwarderAnsible Node
PublicGatewayNetworkLoadBalancerFileStorage
Virtual Server
Virtual Server
Monitoring Host
Text is not SVG - cannot display
\ No newline at end of file diff --git a/reference-architectures/standard-extend/heat-map-deploy-arch-ibm-pvs-inf-standard-extend.svg b/reference-architectures/standard-extend/heat-map-deploy-arch-ibm-pvs-inf-standard-extend.svg deleted file mode 100644 index c5401366..00000000 --- a/reference-architectures/standard-extend/heat-map-deploy-arch-ibm-pvs-inf-standard-extend.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - -
Application
integration
Application...
Mobile
Mobile
Bare metal servers
Bare metal servers
Primary storage
Primary storage
Enterprise
connectivity
Enterprise...
Build & test
Build & test
Data security
Data security
Backup & restore
Backup & restore
Monitoring
Monitoring
Edge
Edge
Blockchain
Blockchain
Enterprise
applications
Enterprise...
Data Ops
Data Ops
Data analytics
Data analytics
Data storage
Data storage
Business intelligence
Business intelligence
Virtual servers
Virtual servers
Virtualization
Virtualization
Containers
Containers
Cloud Foundry
Cloud Foundry
Serverless
Serverless
Backup
Backup
Archive
Archive
Data migration
Data migration
BYOIP/Edge gateways
BYOIP/Edge gateways
Load balancing
Load balancing
Cloud native connectivity
Cloud native connecti...
Isolation
Isolation
Content delivery network
Content delivery netw...
Domain name service
Domain name service
Identity & access
Identity & access
Application security
Application security
Infrastructure & endpoints
Infrastructure & endp...
Threat detection & response
Threat detection & re...
Governance, risk & compliance
Governance, risk & co...
Delivery pipeline
Delivery pipeline
Code repository
Code repository
Disaster recovery
Disaster recovery
High availability
High availability
Logging
Logging
Auditing/tracking
Auditing/tracking
Alerting
Alerting
Event management
Event management
Automated deployment
Automated deployment
Management/
orchestration
Management/...
Domain
Domain
Aspect
Aspect
Application
platforms
Application...
Data
Data
Compute
Compute
Storage
Storage
Networking
Networking
Security
Security
DevOps
DevOps
Resiliency
Resiliency
Service
management
Service...
Included in this architecture
Included in this...
Artificial intelligence
Artificial intelligen...
Text is not SVG - cannot display
diff --git a/solutions/standard-extend/README.md b/solutions/standard-extend/README.md deleted file mode 100644 index c05bc211..00000000 --- a/solutions/standard-extend/README.md +++ /dev/null @@ -1,104 +0,0 @@ -# IBM Cloud Catalog Solution for Power Virtual Server with VPC Landing Zone Extend Standard Landscape Variation - -This example extends an existing PowerVS infrastructure for deployable architectures deployed as Standard Landscape Variation with an additional PowerVS workspace. -It provisions the following infrastructure on top of the deployed Full Stack solution: - -- A **Power Virtual Server workspace** with the following network topology: - - Creates two private networks: a management network and a backup network - - Attaches the PowerVS workspace to transit gateway - - Creates an SSH key. - - Optionally imports up to three custom images from Cloud Object Storage. - -### Notes: -- Make sure that you select a PowerVS zone that is different from the one used for the prerequisite infrastructure. -- This solution requires a schematics workspace ID as input. -- The catalog image names to be imported into the infrastructure can be found [here](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-workspace/blob/main/docs/catalog_images_list.md) - -### Before You Begin - -If you do not have a PowerVS infrastructure that is the [Standard Landscape Variation](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard) create it first. - - -| Variation | Available on IBM Catalog | Requires Schematics Workspace ID | Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastructure | Creates PowerVS Instance | Performs PowerVS OS Config | -| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | -| [Extend Standard Landscape](./) | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | :heavy_check_mark: | N/A | N/A | - - -## Reference architecture -[Extend Standard Landscape Variation](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/blob/main/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.md) - -## Architecture diagram -![Extend Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/blob/main/reference-architectures/standard-extend/deploy-arch-ibm-pvs-inf-standard-extend.svg) - - -### Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.9 | -| [ibm](#requirement\_ibm) | 1.82.1 | - -### Modules - -| Name | Source | Version | -|------|--------|---------| -| [powervs\_workspace](#module\_powervs\_workspace) | terraform-ibm-modules/powervs-workspace/ibm | 3.2.1 | - -### Resources - -| Name | Type | -|------|------| -| [ibm_schematics_output.schematics_output](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.82.1/docs/data-sources/schematics_output) | data source | -| [ibm_schematics_workspace.schematics_workspace](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.82.1/docs/data-sources/schematics_workspace) | data source | - -### Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [IC\_SCHEMATICS\_WORKSPACE\_ID](#input\_IC\_SCHEMATICS\_WORKSPACE\_ID) | leave blank if running locally. This variable will be automatically populated if running from an IBM Cloud Schematics workspace | `string` | `""` | no | -| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | n/a | yes | -| [powervs\_backup\_network](#input\_powervs\_backup\_network) | Name of the IBM Cloud PowerVS backup network and CIDR to create. |
object({
name = string
cidr = string
})
|
{
"cidr": "10.62.0.0/24",
"name": "bkp_net"
}
| no | -| [powervs\_custom\_image\_cos\_configuration](#input\_powervs\_custom\_image\_cos\_configuration) | Cloud Object Storage bucket containing custom PowerVS images. bucket\_name: string, name of the COS bucket. bucket\_access: string, possible values: public, private (private requires powervs\_custom\_image\_cos\_service\_credentials). bucket\_region: string, COS bucket region |
object({
bucket_name = string
bucket_access = string
bucket_region = string
})
|
{
"bucket_access": "",
"bucket_name": "",
"bucket_region": ""
}
| no | -| [powervs\_custom\_image\_cos\_service\_credentials](#input\_powervs\_custom\_image\_cos\_service\_credentials) | Service credentials for the Cloud Object Storage bucket containing the custom PowerVS images. The bucket must have HMAC credentials enabled. Click [here](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-service-credentials) for a json example of a service credential. | `string` | `null` | no | -| [powervs\_custom\_images](#input\_powervs\_custom\_images) | Optionally import up to three custom images from Cloud Object Storage into PowerVS workspace. Requires 'powervs\_custom\_image\_cos\_configuration' to be set. image\_name: string, must be unique. Name of image inside PowerVS workspace. file\_name: string, object key of image inside COS bucket. storage\_tier: string, storage tier which image will be stored in after import. Supported values: tier0, tier1, tier3, tier5k. sap\_type: optional string, Supported values: null, Hana, Netweaver, use null for non-SAP image. |
object({
powervs_custom_image1 = object({
image_name = string
file_name = string
storage_tier = string
sap_type = optional(string)
}),
powervs_custom_image2 = object({
image_name = string
file_name = string
storage_tier = string
sap_type = optional(string)
}),
powervs_custom_image3 = object({
image_name = string
file_name = string
storage_tier = string
sap_type = optional(string)
})
})
|
{
"powervs_custom_image1": {
"file_name": "",
"image_name": "",
"sap_type": null,
"storage_tier": ""
},
"powervs_custom_image2": {
"file_name": "",
"image_name": "",
"sap_type": null,
"storage_tier": ""
},
"powervs_custom_image3": {
"file_name": "",
"image_name": "",
"sap_type": null,
"storage_tier": ""
}
}
| no | -| [powervs\_management\_network](#input\_powervs\_management\_network) | Name of the IBM Cloud PowerVS management subnet and CIDR to create. |
object({
name = string
cidr = string
})
|
{
"cidr": "10.61.0.0/24",
"name": "mgmt_net"
}
| no | -| [powervs\_resource\_group\_name](#input\_powervs\_resource\_group\_name) | Existing IBM Cloud resource group name. | `string` | n/a | yes | -| [powervs\_zone](#input\_powervs\_zone) | IBM Cloud data center location where IBM PowerVS infrastructure will be created. | `string` | n/a | yes | -| [prerequisite\_workspace\_id](#input\_prerequisite\_workspace\_id) | IBM Cloud Schematics workspace ID of the prerequisite infrastructure. If you do not have an existing deployment yet, create a new architecture using the same catalog tile. | `string` | n/a | yes | -| [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace | `list(string)` | `[]` | no | - -### Outputs - -| Name | Description | -|------|-------------| -| [access\_host\_or\_ip](#output\_access\_host\_or\_ip) | Access host for created PowerVS infrastructure. | -| [ansible\_host\_or\_ip](#output\_ansible\_host\_or\_ip) | Central Ansible node private IP address. | -| [dns\_host\_or\_ip](#output\_dns\_host\_or\_ip) | DNS forwarder host for created PowerVS infrastructure. | -| [kms\_key\_map](#output\_kms\_key\_map) | Map of ids and keys for KMS keys created | -| [monitoring\_instance](#output\_monitoring\_instance) | Details of the IBM Cloud Monitoring Instance: CRN, location, guid. | -| [network\_load\_balancer](#output\_network\_load\_balancer) | Details of network load balancer. | -| [network\_services\_config](#output\_network\_services\_config) | Complete configuration of network management services. | -| [nfs\_host\_or\_ip\_path](#output\_nfs\_host\_or\_ip\_path) | NFS host for created PowerVS infrastructure. | -| [ntp\_host\_or\_ip](#output\_ntp\_host\_or\_ip) | NTP host for created PowerVS infrastructure. | -| [powervs\_backup\_subnet](#output\_powervs\_backup\_subnet) | Name, ID and CIDR of backup private network in created PowerVS infrastructure. | -| [powervs\_images](#output\_powervs\_images) | Object containing imported PowerVS image names and image ids. | -| [powervs\_management\_subnet](#output\_powervs\_management\_subnet) | Name, ID and CIDR of management private network in created PowerVS infrastructure. | -| [powervs\_resource\_group\_name](#output\_powervs\_resource\_group\_name) | IBM Cloud resource group where PowerVS infrastructure is created. | -| [powervs\_ssh\_public\_key](#output\_powervs\_ssh\_public\_key) | SSH public key name and value in created PowerVS infrastructure. | -| [powervs\_workspace\_guid](#output\_powervs\_workspace\_guid) | PowerVS infrastructure workspace guid. The GUID of the resource instance. | -| [powervs\_workspace\_id](#output\_powervs\_workspace\_id) | PowerVS infrastructure workspace id. The unique identifier of the new resource instance. | -| [powervs\_workspace\_name](#output\_powervs\_workspace\_name) | PowerVS infrastructure workspace name. | -| [powervs\_zone](#output\_powervs\_zone) | Zone where PowerVS infrastructure is created. | -| [prefix](#output\_prefix) | The prefix that is associated with all resources. | -| [proxy\_host\_or\_ip\_port](#output\_proxy\_host\_or\_ip\_port) | Proxy host:port for created PowerVS infrastructure. | -| [scc\_wp\_instance](#output\_scc\_wp\_instance) | Details of the Security and Compliance Center Workload Protection Instance: guid, access key, api\_endpoint, ingestion\_endpoint. | -| [schematics\_workspace\_id](#output\_schematics\_workspace\_id) | ID of the IBM Cloud Schematics workspace. Returns null if not ran in Schematics | -| [ssh\_public\_key](#output\_ssh\_public\_key) | The string value of the ssh public key used when deploying VPC | -| [transit\_gateway\_id](#output\_transit\_gateway\_id) | The ID of transit gateway. | -| [transit\_gateway\_name](#output\_transit\_gateway\_name) | The name of the transit gateway. | -| [vpc\_data](#output\_vpc\_data) | List of VPC data. | -| [vpc\_names](#output\_vpc\_names) | A list of the names of the VPC. | -| [vsi\_list](#output\_vsi\_list) | A list of VSI with name, id, zone, and primary ipv4 address, VPC Name, and floating IP. | -| [vsi\_names](#output\_vsi\_names) | A list of the vsis names provisioned within the VPCs. | -| [vsi\_ssh\_key\_data](#output\_vsi\_ssh\_key\_data) | List of VSI SSH key data | - diff --git a/solutions/standard-extend/catalogValidationValues.json.template b/solutions/standard-extend/catalogValidationValues.json.template deleted file mode 100644 index 8f7a6132..00000000 --- a/solutions/standard-extend/catalogValidationValues.json.template +++ /dev/null @@ -1,6 +0,0 @@ -{ - "ibmcloud_api_key": $VALIDATION_APIKEY, - "powervs_zone": "eu-de-2", - "powervs_resource_group_name": "Default", - "prerequisite_workspace_id": "us-south.workspace.DO-NOT-DELETE-Catalog-validate-onboarding-for-extend-landspace.679f97fd" -} diff --git a/solutions/standard-extend/locals_schematics_data.tf b/solutions/standard-extend/locals_schematics_data.tf deleted file mode 100644 index efa908e1..00000000 --- a/solutions/standard-extend/locals_schematics_data.tf +++ /dev/null @@ -1,57 +0,0 @@ -locals { - location = regex("^[a-z/-]+", var.prerequisite_workspace_id) -} - -data "ibm_schematics_workspace" "schematics_workspace" { - workspace_id = var.prerequisite_workspace_id - location = local.location -} - -data "ibm_schematics_output" "schematics_output" { - workspace_id = var.prerequisite_workspace_id - location = local.location - template_id = data.ibm_schematics_workspace.schematics_workspace.runtime_data[0].id -} - - -locals { - - standard_output = jsondecode(data.ibm_schematics_output.schematics_output.output_json) - prefix = local.standard_output[0].prefix.value == "" ? "ext" : local.standard_output[0].prefix.value - ssh_public_key = local.standard_output[0].powervs_ssh_public_key.value.value - transit_gateway_name = local.standard_output[0].transit_gateway_name.value - transit_gateway_id = local.standard_output[0].transit_gateway_id.value - ansible_host_or_ip = local.standard_output[0].ansible_host_or_ip.value - - access_host_or_ip_exists = contains(keys(local.standard_output[0]), "access_host_or_ip") ? true : false - access_host_or_ip = local.access_host_or_ip_exists ? local.standard_output[0].access_host_or_ip.value : "" - proxy_host_or_ip_exists = contains(keys(local.standard_output[0]), "proxy_host_or_ip_port") && local.access_host_or_ip != "" ? true : false - proxy_host_or_ip_port = local.proxy_host_or_ip_exists ? local.standard_output[0].proxy_host_or_ip_port.value : "" - dns_host_or_ip_exists = contains(keys(local.standard_output[0]), "dns_host_or_ip") && local.access_host_or_ip != "" ? true : false - dns_host_or_ip = local.dns_host_or_ip_exists ? local.standard_output[0].dns_host_or_ip.value : "" - nfs_host_or_ip_path_exists = contains(keys(local.standard_output[0]), "nfs_host_or_ip_path") && local.access_host_or_ip != "" ? true : false - nfs_host_or_ip_path = local.nfs_host_or_ip_path_exists ? local.standard_output[0].nfs_host_or_ip_path.value : "" - ntp_host_or_ip_exists = contains(keys(local.standard_output[0]), "ntp_host_or_ip") && local.access_host_or_ip != "" ? true : false - ntp_host_or_ip = local.ntp_host_or_ip_exists ? local.standard_output[0].ntp_host_or_ip.value : "" - network_services_config = local.standard_output[0].network_services_config.value - - valid_powervs_zone_used = local.standard_output[0].powervs_zone != var.powervs_zone ? true : false - validate_powervs_zone_msg = "A Power workspace already exists in the provided PowerVS zone. Please use a different zone." - # tflint-ignore: terraform_unused_declarations - validate_json_chk = regex("^${local.validate_powervs_zone_msg}$", (local.valid_powervs_zone_used ? local.validate_powervs_zone_msg : "")) - - standard_mgt_net = local.standard_output[0].powervs_management_subnet.value.cidr - standard_bkp_net = local.standard_output[0].powervs_backup_subnet.value.cidr - valid_mgt_subnet_used = local.standard_mgt_net != var.powervs_management_network["cidr"] ? true : false - validate_mgt_subnet_msg = "This management subnet CIDR already exists in the infrastructure. Please use another CIDR block." - # tflint-ignore: terraform_unused_declarations - validate_mgt_subnet_chk = regex("^${local.validate_mgt_subnet_msg}$", (local.valid_mgt_subnet_used ? local.validate_mgt_subnet_msg : "")) - - valid_bkp_subnet_used = local.standard_bkp_net != var.powervs_backup_network["cidr"] ? true : false - validate_bkp_subnet_msg = "This backup subnet CIDR already exists in the infrastructure. Please use another CIDR block." - # tflint-ignore: terraform_unused_declarations - validate_bkp_subnet_chk = regex("^${local.validate_bkp_subnet_msg}$", (local.valid_bkp_subnet_used ? local.validate_bkp_subnet_msg : "")) - - powervs_workspace_name = "${local.prefix}-${var.powervs_zone}-power-workspace" - powervs_ssh_public_key = { "name" = "${local.prefix}-${var.powervs_zone}-ssh-pvs-key", value = local.ssh_public_key } -} diff --git a/solutions/standard-extend/main.tf b/solutions/standard-extend/main.tf deleted file mode 100644 index 1d6e8c84..00000000 --- a/solutions/standard-extend/main.tf +++ /dev/null @@ -1,41 +0,0 @@ -locals { - powervs_custom_image1 = ( - var.powervs_custom_images.powervs_custom_image1.image_name == "" && - var.powervs_custom_images.powervs_custom_image1.file_name == "" && - var.powervs_custom_images.powervs_custom_image1.storage_tier == "" - ) ? null : var.powervs_custom_images.powervs_custom_image1 - powervs_custom_image2 = ( - var.powervs_custom_images.powervs_custom_image2.image_name == "" && - var.powervs_custom_images.powervs_custom_image2.file_name == "" && - var.powervs_custom_images.powervs_custom_image2.storage_tier == "" - ) ? null : var.powervs_custom_images.powervs_custom_image2 - powervs_custom_image3 = ( - var.powervs_custom_images.powervs_custom_image3.image_name == "" && - var.powervs_custom_images.powervs_custom_image3.file_name == "" && - var.powervs_custom_images.powervs_custom_image3.storage_tier == "" - ) ? null : var.powervs_custom_images.powervs_custom_image3 - powervs_custom_image_cos_configuration = ( - var.powervs_custom_image_cos_configuration.bucket_name == "" && - var.powervs_custom_image_cos_configuration.bucket_access == "" && - var.powervs_custom_image_cos_configuration.bucket_region == "" - ) ? null : var.powervs_custom_image_cos_configuration -} - -module "powervs_workspace" { - source = "terraform-ibm-modules/powervs-workspace/ibm" - version = "3.2.1" - - pi_zone = var.powervs_zone - pi_resource_group_name = var.powervs_resource_group_name - pi_workspace_name = local.powervs_workspace_name - pi_ssh_public_key = local.powervs_ssh_public_key - pi_private_subnet_1 = var.powervs_management_network - pi_private_subnet_2 = var.powervs_backup_network - pi_transit_gateway_connection = { "enable" : true, "transit_gateway_id" : local.transit_gateway_id } - pi_tags = var.tags - pi_custom_image1 = local.powervs_custom_image1 - pi_custom_image2 = local.powervs_custom_image2 - pi_custom_image3 = local.powervs_custom_image3 - pi_custom_image_cos_configuration = local.powervs_custom_image_cos_configuration - pi_custom_image_cos_service_credentials = var.powervs_custom_image_cos_service_credentials -} diff --git a/solutions/standard-extend/outputs.tf b/solutions/standard-extend/outputs.tf deleted file mode 100644 index 974305a5..00000000 --- a/solutions/standard-extend/outputs.tf +++ /dev/null @@ -1,164 +0,0 @@ -output "prefix" { - description = "The prefix that is associated with all resources." - value = local.prefix -} - -######################################################################## -# Landing Zone VPC outputs -######################################################################## - -output "vpc_names" { - description = "A list of the names of the VPC." - value = local.standard_output[0].vpc_names.value -} - -output "vsi_names" { - description = "A list of the vsis names provisioned within the VPCs." - value = local.standard_output[0].vsi_names.value -} - -output "vpc_data" { - description = "List of VPC data." - value = local.standard_output[0].vpc_data.value -} - -output "kms_key_map" { - description = "Map of ids and keys for KMS keys created" - value = local.standard_output[0].kms_key_map.value -} - -output "vsi_ssh_key_data" { - description = "List of VSI SSH key data" - value = local.standard_output[0].vsi_ssh_key_data.value -} -output "network_load_balancer" { - description = "Details of network load balancer." - value = local.standard_output[0].network_load_balancer.value -} - -output "ssh_public_key" { - description = "The string value of the ssh public key used when deploying VPC" - value = local.ssh_public_key -} - -output "transit_gateway_name" { - description = "The name of the transit gateway." - value = local.transit_gateway_name -} - -output "transit_gateway_id" { - description = "The ID of transit gateway." - value = local.transit_gateway_id -} - -output "vsi_list" { - description = "A list of VSI with name, id, zone, and primary ipv4 address, VPC Name, and floating IP." - value = local.standard_output[0].vsi_list.value -} - -output "access_host_or_ip" { - description = "Access host for created PowerVS infrastructure." - value = local.access_host_or_ip -} - -output "proxy_host_or_ip_port" { - description = "Proxy host:port for created PowerVS infrastructure." - value = local.proxy_host_or_ip_port -} - -output "dns_host_or_ip" { - description = "DNS forwarder host for created PowerVS infrastructure." - value = local.dns_host_or_ip -} - -output "ntp_host_or_ip" { - description = "NTP host for created PowerVS infrastructure." - value = local.ntp_host_or_ip -} - -output "nfs_host_or_ip_path" { - description = "NFS host for created PowerVS infrastructure." - value = local.nfs_host_or_ip_path -} - -output "ansible_host_or_ip" { - description = "Central Ansible node private IP address." - value = local.ansible_host_or_ip -} - -output "network_services_config" { - description = "Complete configuration of network management services." - value = local.network_services_config -} - -######################################################################## -# Monitoring Instance outputs -######################################################################## - -output "monitoring_instance" { - description = "Details of the IBM Cloud Monitoring Instance: CRN, location, guid." - value = local.standard_output[0].monitoring_instance.value -} - -######################################################################## -# SCC Workload Protection outputs -######################################################################## - -output "scc_wp_instance" { - description = "Details of the Security and Compliance Center Workload Protection Instance: guid, access key, api_endpoint, ingestion_endpoint." - value = local.standard_output[0].scc_wp_instance.value -} - -######################################################################## -# PowerVS Infrastructure outputs -######################################################################## - -output "powervs_zone" { - description = "Zone where PowerVS infrastructure is created." - value = var.powervs_zone -} - -output "powervs_resource_group_name" { - description = "IBM Cloud resource group where PowerVS infrastructure is created." - value = var.powervs_resource_group_name -} - -output "powervs_workspace_name" { - description = "PowerVS infrastructure workspace name." - value = local.powervs_workspace_name -} - -output "powervs_workspace_id" { - description = "PowerVS infrastructure workspace id. The unique identifier of the new resource instance." - value = module.powervs_workspace.pi_workspace_id -} - -output "powervs_workspace_guid" { - description = "PowerVS infrastructure workspace guid. The GUID of the resource instance." - value = module.powervs_workspace.pi_workspace_guid -} - -output "powervs_ssh_public_key" { - description = "SSH public key name and value in created PowerVS infrastructure." - value = module.powervs_workspace.pi_ssh_public_key -} - -output "powervs_management_subnet" { - description = "Name, ID and CIDR of management private network in created PowerVS infrastructure." - value = module.powervs_workspace.pi_private_subnet_1 -} - -output "powervs_backup_subnet" { - description = "Name, ID and CIDR of backup private network in created PowerVS infrastructure." - value = module.powervs_workspace.pi_private_subnet_2 -} - -output "powervs_images" { - description = "Object containing imported PowerVS image names and image ids." - value = module.powervs_workspace.pi_images -} - -output "schematics_workspace_id" { - description = "ID of the IBM Cloud Schematics workspace. Returns null if not ran in Schematics" - value = var.IC_SCHEMATICS_WORKSPACE_ID -} diff --git a/solutions/standard-extend/provider.tf b/solutions/standard-extend/provider.tf deleted file mode 100644 index 911ae2be..00000000 --- a/solutions/standard-extend/provider.tf +++ /dev/null @@ -1,31 +0,0 @@ -locals { - ibm_powervs_zone_region_map = { - "syd04" = "syd" - "syd05" = "syd" - "sao01" = "sao" - "sao04" = "sao" - "tor01" = "tor" - "mon01" = "mon" - "eu-de-1" = "eu-de" - "eu-de-2" = "eu-de" - "mad02" = "mad" - "mad04" = "mad" - "lon04" = "lon" - "lon06" = "lon" - "osa21" = "osa" - "tok04" = "tok" - "us-south" = "us-south" - "dal10" = "us-south" - "dal12" = "us-south" - "dal14" = "us-south" - "us-east" = "us-east" - "wdc06" = "us-east" - "wdc07" = "us-east" - } -} - -provider "ibm" { - region = lookup(local.ibm_powervs_zone_region_map, var.powervs_zone, null) - zone = var.powervs_zone - ibmcloud_api_key = var.ibmcloud_api_key != null ? var.ibmcloud_api_key : null -} diff --git a/solutions/standard-extend/variables.tf b/solutions/standard-extend/variables.tf deleted file mode 100644 index 4ea5f162..00000000 --- a/solutions/standard-extend/variables.tf +++ /dev/null @@ -1,132 +0,0 @@ -variable "prerequisite_workspace_id" { - description = "IBM Cloud Schematics workspace ID of the prerequisite infrastructure. If you do not have an existing deployment yet, create a new architecture using the same catalog tile." - type = string -} - -variable "powervs_zone" { - description = "IBM Cloud data center location where IBM PowerVS infrastructure will be created." - type = string -} - -variable "powervs_resource_group_name" { - description = "Existing IBM Cloud resource group name." - type = string -} - -variable "powervs_management_network" { - description = "Name of the IBM Cloud PowerVS management subnet and CIDR to create." - type = object({ - name = string - cidr = string - }) - - default = { - "name" : "mgmt_net", - "cidr" : "10.61.0.0/24" - } -} - -variable "powervs_backup_network" { - description = "Name of the IBM Cloud PowerVS backup network and CIDR to create." - type = object({ - name = string - cidr = string - }) - - default = { - "name" : "bkp_net", - "cidr" : "10.62.0.0/24" - } -} - -variable "ibmcloud_api_key" { - description = "The IBM Cloud platform API key needed to deploy IAM enabled resources." - type = string - sensitive = true -} - -##################################################### -# Optional Parameters -##################################################### -variable "tags" { - description = "List of tag names for the IBM Cloud PowerVS workspace" - type = list(string) - default = [] -} - -variable "powervs_custom_images" { - description = "Optionally import up to three custom images from Cloud Object Storage into PowerVS workspace. Requires 'powervs_custom_image_cos_configuration' to be set. image_name: string, must be unique. Name of image inside PowerVS workspace. file_name: string, object key of image inside COS bucket. storage_tier: string, storage tier which image will be stored in after import. Supported values: tier0, tier1, tier3, tier5k. sap_type: optional string, Supported values: null, Hana, Netweaver, use null for non-SAP image." - type = object({ - powervs_custom_image1 = object({ - image_name = string - file_name = string - storage_tier = string - sap_type = optional(string) - }), - powervs_custom_image2 = object({ - image_name = string - file_name = string - storage_tier = string - sap_type = optional(string) - }), - powervs_custom_image3 = object({ - image_name = string - file_name = string - storage_tier = string - sap_type = optional(string) - }) - }) - default = { - "powervs_custom_image1" : { - "image_name" : "", - "file_name" : "", - "storage_tier" : "", - "sap_type" : null - }, - "powervs_custom_image2" : { - "image_name" : "", - "file_name" : "", - "storage_tier" : "", - "sap_type" : null - }, - "powervs_custom_image3" : { - "image_name" : "", - "file_name" : "", - "storage_tier" : "", - "sap_type" : null - } - } -} - -variable "powervs_custom_image_cos_configuration" { - description = "Cloud Object Storage bucket containing custom PowerVS images. bucket_name: string, name of the COS bucket. bucket_access: string, possible values: public, private (private requires powervs_custom_image_cos_service_credentials). bucket_region: string, COS bucket region" - type = object({ - bucket_name = string - bucket_access = string - bucket_region = string - }) - default = { - "bucket_name" : "", - "bucket_access" : "", - "bucket_region" : "" - } -} - -variable "powervs_custom_image_cos_service_credentials" { - description = "Service credentials for the Cloud Object Storage bucket containing the custom PowerVS images. The bucket must have HMAC credentials enabled. Click [here](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-service-credentials) for a json example of a service credential." - type = string - sensitive = true - default = null -} - - -############################################################################# -# Schematics Output -############################################################################# - -# tflint-ignore: terraform_naming_convention -variable "IC_SCHEMATICS_WORKSPACE_ID" { - default = "" - type = string - description = "leave blank if running locally. This variable will be automatically populated if running from an IBM Cloud Schematics workspace" -} diff --git a/solutions/standard-extend/versions.tf b/solutions/standard-extend/versions.tf deleted file mode 100644 index 05ba7f6a..00000000 --- a/solutions/standard-extend/versions.tf +++ /dev/null @@ -1,13 +0,0 @@ -##################################################### -# Powervs extension solution -##################################################### - -terraform { - required_version = ">= 1.9" - required_providers { - ibm = { - source = "IBM-Cloud/ibm" - version = "1.82.1" - } - } -} From f0280433e93860692c83e38e4717e97ac4bd866a Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 12 Sep 2025 15:33:50 +0200 Subject: [PATCH 44/83] fix: add back support for lon04 --- solutions/standard-openshift/provider.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/solutions/standard-openshift/provider.tf b/solutions/standard-openshift/provider.tf index 2d77c632..06f21ad4 100644 --- a/solutions/standard-openshift/provider.tf +++ b/solutions/standard-openshift/provider.tf @@ -58,9 +58,9 @@ locals { "eu-de-2" = "eu-de" "mad02" = "mad" "mad04" = "mad" - # "lon04" = "lon" not yet supported by IPI - "lon06" = "lon" - "osa21" = "osa" + "lon04" = "lon" + "lon06" = "lon" + "osa21" = "osa" #"tok04" = "jp-tok" "us-south" = "us-south" "dal10" = "dal" From 5b2bcc30647a1c12f75ae0190bdf9043bc09c030 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 09:55:41 +0200 Subject: [PATCH 45/83] feat: expose user_data for cloud init on intel VSIs --- ibm_catalog.json | 5 +++++ modules/powervs-vpc-landing-zone/README.md | 1 + modules/powervs-vpc-landing-zone/main.tf | 1 + .../presets/slz-preset.json.tftpl | 12 ++++++++++++ modules/powervs-vpc-landing-zone/variables.tf | 6 ++++++ solutions/standard-openshift/README.md | 1 + solutions/standard-openshift/main.tf | 1 + solutions/standard-openshift/variables.tf | 6 ++++++ 8 files changed, 33 insertions(+) diff --git a/ibm_catalog.json b/ibm_catalog.json index 5c4e195a..ca85aa67 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1422,6 +1422,11 @@ { "key": "network_services_vsi_profile" }, + { + "key": "intel_user_data", + "type": "code_editor", + "display_name": "intel_user_data" + }, { "key": "enable_scc_wp" }, diff --git a/modules/powervs-vpc-landing-zone/README.md b/modules/powervs-vpc-landing-zone/README.md index 3c7958f7..2c2d8e83 100644 --- a/modules/powervs-vpc-landing-zone/README.md +++ b/modules/powervs-vpc-landing-zone/README.md @@ -169,6 +169,7 @@ Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastr | [ssh\_public\_key](#input\_ssh\_public\_key) | Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region. | `string` | n/a | yes | | [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace | `list(string)` | `[]` | no | | [transit\_gateway\_global](#input\_transit\_gateway\_global) | Connect to the networks outside the associated region. | `bool` | `false` | no | +| [user\_data](#input\_user\_data) | User data that automatically performs common configuration tasks or runs scripts. For more information, see https://cloud.ibm.com/docs/vpc?topic=vpc-user-data. For information on using the user\_data variable, please refer: https://cloud.ibm.com/docs/secure-infrastructure-vpc?topic=secure-infrastructure-vpc-user-data | `string` | `null` | no | | [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
| n/a | yes | ### Outputs diff --git a/modules/powervs-vpc-landing-zone/main.tf b/modules/powervs-vpc-landing-zone/main.tf index c20105bd..f77086cb 100644 --- a/modules/powervs-vpc-landing-zone/main.tf +++ b/modules/powervs-vpc-landing-zone/main.tf @@ -11,6 +11,7 @@ locals { external_access_ip = local.external_access_ip, rhel_image = var.vpc_intel_images.rhel_image, network_services_vsi_profile = var.network_services_vsi_profile, + user_data = replace(var.user_data, "\n", "\\n") transit_gateway_global = var.transit_gateway_global, enable_monitoring = var.enable_monitoring, sles_image = var.vpc_intel_images.sles_image, diff --git a/modules/powervs-vpc-landing-zone/presets/slz-preset.json.tftpl b/modules/powervs-vpc-landing-zone/presets/slz-preset.json.tftpl index b2a06d07..39f5cbc9 100644 --- a/modules/powervs-vpc-landing-zone/presets/slz-preset.json.tftpl +++ b/modules/powervs-vpc-landing-zone/presets/slz-preset.json.tftpl @@ -585,6 +585,10 @@ "subnet_names": ["vsi-management-zone-1"], "block_storage_volumes": [], "security_groups": ["management-sg"] + %{ if "${user_data}" != "" && "${user_data}" != null } + , + "user_data" : "${user_data}" + %{ endif } }, { "name": "network-services", @@ -599,6 +603,10 @@ "subnet_names": ["vsi-edge-zone-1"], "block_storage_volumes": [], "security_groups": ["network-services-sg"] + %{ if "${user_data}" != "" && "${user_data}" != null } + , + "user_data" : "${user_data}" + %{ endif } } %{ if "${enable_monitoring}" == true } , @@ -615,6 +623,10 @@ "subnet_names": ["vsi-edge-zone-1"], "block_storage_volumes": [], "security_groups": ["network-services-sg"] + %{ if "${user_data}" != "" && "${user_data}" != null } + , + "user_data" : "${user_data}" + %{ endif } } %{ endif } ], diff --git a/modules/powervs-vpc-landing-zone/variables.tf b/modules/powervs-vpc-landing-zone/variables.tf index b921940d..c3759178 100644 --- a/modules/powervs-vpc-landing-zone/variables.tf +++ b/modules/powervs-vpc-landing-zone/variables.tf @@ -83,6 +83,12 @@ variable "network_services_vsi_profile" { default = "cx2-2x4" } +variable "user_data" { + description = "User data that automatically performs common configuration tasks or runs scripts. For more information, see https://cloud.ibm.com/docs/vpc?topic=vpc-user-data. For information on using the user_data variable, please refer: https://cloud.ibm.com/docs/secure-infrastructure-vpc?topic=secure-infrastructure-vpc-user-data" + type = string + default = null +} + ##################################################### # Optional Parameters VSI OS Management Services ##################################################### diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 337f2e76..ccc56771 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -41,6 +41,7 @@ | [existing\_sm\_instance\_region](#input\_existing\_sm\_instance\_region) | Required if value is passed into `var.existing_sm_instance_guid`. | `string` | `null` | no | | [external\_access\_ip](#input\_external\_access\_ip) | Specify the source IP address or CIDR for login through SSH to the environment after deployment. Access to the environment will be allowed only from this IP address. Can be set to 'null' if you choose to use client to site vpn. | `string` | `"0.0.0.0/0"` | no | | [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | n/a | yes | +| [intel\_user\_data](#input\_intel\_user\_data) | User data that automatically performs common configuration tasks or runs scripts only on the intel VSIs. For more information, see https://cloud.ibm.com/docs/vpc?topic=vpc-user-data. For information on using the user\_data variable, please refer: https://cloud.ibm.com/docs/secure-infrastructure-vpc?topic=secure-infrastructure-vpc-user-data | `string` | `null` | no | | [network\_services\_vsi\_profile](#input\_network\_services\_vsi\_profile) | Compute profile configuration of the network services vsi (cpu and memory configuration). Must be one of the supported profiles. See [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui). | `string` | `"cx2-2x4"` | no | | [openshift\_pull\_secret](#input\_openshift\_pull\_secret) | Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries. | `map(any)` | n/a | yes | | [openshift\_release](#input\_openshift\_release) | The OpenShift IPI release version to deploy. | `string` | `"4.19.5"` | no | diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 3eb82f31..ea1b7716 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -38,6 +38,7 @@ module "standard" { ssh_private_key = var.ssh_private_key client_to_site_vpn = local.client_to_site_vpn vpc_intel_images = var.vpc_intel_images + user_data = var.intel_user_data powervs_resource_group_name = null powervs_management_network = null powervs_backup_network = null diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index ee87d4f1..c5b1a606 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -180,6 +180,12 @@ variable "network_services_vsi_profile" { default = "cx2-2x4" } +variable "intel_user_data" { + description = "User data that automatically performs common configuration tasks or runs scripts only on the intel VSIs. For more information, see https://cloud.ibm.com/docs/vpc?topic=vpc-user-data. For information on using the user_data variable, please refer: https://cloud.ibm.com/docs/secure-infrastructure-vpc?topic=secure-infrastructure-vpc-user-data" + type = string + default = null +} + variable "external_access_ip" { description = "Specify the source IP address or CIDR for login through SSH to the environment after deployment. Access to the environment will be allowed only from this IP address. Can be set to 'null' if you choose to use client to site vpn." type = string From 46a2acce5d34ad5a895e4d66efda7a60306ca87a Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 16:21:29 +0200 Subject: [PATCH 46/83] docs: add heatmap and architecture diagram --- .../deploy-arch-ibm-pvs-inf-standard-openshift.svg | 4 ++++ .../heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg | 4 ++++ 2 files changed, 8 insertions(+) create mode 100644 reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg create mode 100644 reference-architectures/standard-openshift/heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg diff --git a/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg new file mode 100644 index 00000000..386c5ae5 --- /dev/null +++ b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg @@ -0,0 +1,4 @@ + + + +
IBM Cloud
IBM Cloud
Zone 1
Zone 1
TransitGateway
PowerVS Resource Group
PowerVS Resource Group
Secure PowerVS Workspace
Secure PowerVS Workspace
SSH Public Key
10.67.0.0/14: Service Subnet
10.67.0.0/14: Service Subnet
10.72.0.0/24: Machine Subnet
10.72.0.0/24: Machine Subnet
Power Virtual Server Instance
Worker Nodes
Power Virtual Server Instance...
Block Storageveth: Management Networkveth: Backup Network
Power Virtual Server Instance
Master Nodes
Power Virtual Server Instanc...
Block Storageveth: Management Networkveth: Backup Network
Power Virtual Server Instance
Bootstrap Instance (temporary)
Power Virtual Server Instanc...
Block Storageveth: Management Networkveth: Backup Network
Cloud Services
Cloud Services
Edge VPC Flow Log CollectorSecretsManagerObject  StorageInstallation filesObject  StorageActivity tracker MonitoringKey ProtectAcitivity Tracker Event RoutingActivity TrackerSCC WorkloadProtectionDNS Service
Services Resource Group
Services Resource Group
Edge Resource Group
Edge Resource Group
Edge VPC (Default ACL)
Edge VPC (Default ACL)
Management SG
Management SG
10.30.20.0/24: 
Mgmt VSI Subnet
10.30.20.0/24:...
Virtual Server
Virtual Server
FloatingIPBastionHost
Network-services SG
Network-services SG
10.30.40.0/24: Edge VSI Subnet
10.30.40.0/24: Edge VSI Subnet
Virtual Server
Virtual Server
Proxy ServerAnsible Node
PublicGateway
Virtual Server
Virtual Server
Monitoring Host
Default SG
Default SG
10.30.10.0/24: 
VPN Subnet
10.30.10.0/24:...
Client to site VPN server
PublicApplicationLoad BalancerInternalApplicationLoad BalancerApplicationLoadBalancer
10.30.30.0/24: 
VPE Subnet
10.30.30.0/24:...
COS VPE
VPE SG
VPE SG
Consumer
Consumer
UserInternet
Text is not SVG - cannot display
\ No newline at end of file diff --git a/reference-architectures/standard-openshift/heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg b/reference-architectures/standard-openshift/heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg new file mode 100644 index 00000000..4ee6eab6 --- /dev/null +++ b/reference-architectures/standard-openshift/heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg @@ -0,0 +1,4 @@ + + + +
Application
integration
Application...
Mobile
Mobile
Bare metal servers
Bare metal servers
Primary storage
Primary storage
Enterprise
connectivity
Enterprise...
Build & test
Build & test
Data security
Data security
Backup & restore
Backup & restore
Monitoring
Monitoring
Edge
Edge
Blockchain
Blockchain
Enterprise
applications
Enterprise...
Data Ops
Data Ops
Data analytics
Data analytics
Data storage
Data storage
Business intelligence
Business intelligence
Virtual servers
Virtual servers
Virtualization
Virtualization
Containers
Containers
Cloud Foundry
Cloud Foundry
Serverless
Serverless
Backup
Backup
Archive
Archive
Data migration
Data migration
BYOIP/Edge gateways
BYOIP/Edge gateways
Load balancing
Load balancing
Cloud native connectivity
Cloud native connecti...
Isolation
Isolation
Content delivery network
Content delivery netw...
Domain name service
Domain name service
Identity & access
Identity & access
Application security
Application security
Infrastructure & endpoints
Infrastructure & endp...
Threat detection & response
Threat detection & re...
Governance, risk & compliance
Governance, risk & co...
Delivery pipeline
Delivery pipeline
Code repository
Code repository
Disaster recovery
Disaster recovery
High availability
High availability
Logging
Logging
Auditing/tracking
Auditing/tracking
Alerting
Alerting
Event management
Event management
Automated deployment
Automated deployment
Management/
orchestration
Management/...
Domain
Domain
Aspect
Aspect
Application
platforms
Application...
Data
Data
Compute
Compute
Storage
Storage
Networking
Networking
Security
Security
DevOps
DevOps
Resiliency
Resiliency
Service
management
Service...
Included in this architecture
Included in this...
Artificial intelligence
Artificial intelligen...
Text is not SVG - cannot display
From 6a5ea88fecca022f2ccf2fe93446aff58e4c9582 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 16:22:52 +0200 Subject: [PATCH 47/83] docs: update toc version --- ibm_catalog.json | 6 +- ...loy-arch-ibm-pvs-inf-standard-openshift.md | 114 ++++++++++++++++++ ...ploy-arch-ibm-pvs-inf-standard-plus-vsi.md | 8 +- .../deploy-arch-ibm-pvs-inf-standard.md | 6 +- 4 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md diff --git a/ibm_catalog.json b/ibm_catalog.json index ca85aa67..7d692ffb 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -565,7 +565,7 @@ { "diagram": { "caption": "Power Virtual Server with VPC landing zone 'Standard Landscape' variation", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v9.0.0/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.svg", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v10.0.0/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.svg", "type": "image/svg+xml" }, "description": "The Power Virtual Server with VPC landing zone as variation 'Create a new architecture' deploys VPC services and a Power Virtual Server workspace and interconnects them.\n \nRequired and optional management components are configured." @@ -1228,7 +1228,7 @@ { "diagram": { "caption": "Power Virtual Server with VPC landing zone 'Quickstart' variation", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v9.0.0/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.svg", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v10.0.0/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.svg", "type": "image/svg+xml" }, "description": "The Power Virtual Server with VPC landing zone as 'Quickstart' variation of 'Create a new architecture' option deploys VPC services and a Power Virtual Server workspace and interconnects them. It also creates one Power virtual server instance of chosen t-shirt size or custom configuration.\n \nRequired and optional management components are configured." @@ -1711,7 +1711,7 @@ { "diagram": { "caption": "Power Virtual Server with VPC landing zone 'Quickstart Openshift' variation", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v9.0.0/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard.svg", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/refs/tags/v10.0.0/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg", "type": "image/svg+xml" }, "description": "The Power Virtual Server with VPC landing zone as variation 'Quickstart Openshift' deploys VPC services and an Openshift Cluster on PowerVS and interconnects them.\n \nRequired and optional management components are configured." diff --git a/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md new file mode 100644 index 00000000..e9ee91e1 --- /dev/null +++ b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md @@ -0,0 +1,114 @@ +--- +copyright: + years: 2024, 2025 +lastupdated: "2025-09-15" +keywords: +subcollection: deployable-reference-architectures +authors: + - name: Arnold Beilmann + - name: Suraj Bharadwaj + - name: Ludwig Mueller +production: true +deployment-url: https://cloud.ibm.com/catalog/architecture/deploy-arch-ibm-pvs-inf-2dd486c7-b317-4aaa-907b-42671485ad96-global +docs: https://cloud.ibm.com/docs/powervs-vpc +image_source: https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/blob/main/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg +use-case: ITServiceManagement +industry: Technology +content-type: reference-architecture +version: v10.0.0 +compliance: + +--- + +{{site.data.keyword.attribute-definition-list}} + +# Power Virtual Server with VPC landing zone - 'Quickstart Openshift Variation' +{: #deploy-arch-ibm-pvs-inf-standard-openshift} +{: toc-content-type="reference-architecture"} +{: toc-industry="Technology"} +{: toc-use-case="ITServiceManagement"} +{: toc-version="v10.0.0"} + +The Quickstart OpenShift deployment on Power Virtual Server with a VPC landing zone uses the Red Hat IPI installer to set up an OpenShift cluster. Before the deployment begins, it provisions VPC services and creates a Power Virtual Server workspace, which together form the landing zone used to access and manage the cluster. + +The number of PowerVS master and worker nodes and their respective compute configurations can be freely configured during deployment. Optionally, Monitoring and Security and Compliance Center Workload Protection can also be configured. + +## Architecture diagram +{: #standard-openshift-architecture-diagram} + +![Architecture diagram for 'Power Virtual Server with VPC landing zone' - variation 'Quickstart Openshift'.](deploy-arch-ibm-pvs-inf-standard-openshift.svg "Architecture diagram"){: caption="Figure 1. Single-zone PowerVS workspace accessible over secure landing zone" caption-side="bottom"}{: external download="deploy-arch-ibm-pvs-inf-standard-openshift.svg"} + +## Design requirements +{: #standard-openshift-design-requirements} + +![Design requirements for 'Power Virtual Server with VPC landing zone' - variation 'Quickstart'](heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg "Design requirements"){: caption="Figure 2. Scope of the solution requirements" caption-side="bottom"} + +IBM Cloud® Power Virtual Servers (PowerVS) is a public cloud offering that an enterprise can use to establish its own private IBM Power computing environment on shared public cloud infrastructure. PowerVS is logically isolated from all other public cloud tenants and infrastructure components, creating a private, secure place on the public cloud. This deployable architecture provides a framework to build a PowerVS offering according to the best practices and requirements from the IBM Cloud. + +## Components +{: #standard-openshift-components} + +### VPC architecture decisions +{: #standard-openshift-vpc-components-arch} + +| Requirement | Component | Choice | Alternative choice | +|-------------|-----------|--------------------|--------------------| +|* Ensure public internet connectivity \n * Isolate most virtual instances to not be reachable directly from the public internet|Edge VPC service with network services security group.|Create a separate security group service where public internet connectivity is allowed to be configured| | +|* Provide infrastructure administration access \n * Limit the number of infrastructure administration entry points to ensure security audit|Edge VPC service with management security group.|Create a separate security group where SSH connectivity from outside is allowed| | +|* Provide infrastructure for service management components like backup, monitoring, IT service management, shared storage \n * Ensure you can reach all IBM Cloud and on-premises services|Client to site VPN and security groups |Create a client to site VPN and VPE full strict security groups rules without direct public internet connectivity and without direct SSH access| | +|* Allow customer to choose operating system from two most widely used commercial Linux operating system offerings \n * Support new OS releases|Linux operating system|Red Hat Enterprise Linux (RHEL)| | +|* Create a virtual server instance as the only management access point to the landscape|Bastion host VPC instance|Create a Linux VPC instance that acts as a bastion host. Configure ACL and security group rules to allow SSH connectivity (port 22). Add a public IP address to the VPC instance. Allow connectivity from a restricted and limited number of public IP addresses. Allow connectivity from IP addresses of the Schematics engine nodes| | +|* Create a virtual server instance that can act as an internet proxy server |Network services VPC instance|Create a Linux VPC instance that can host management components. Preconfigure ACL and security group rules to allow traffic over private networks only.|Configure application load balancer to act as proxy server manually, Modify number of virtual server instances and allowed ports in preset or perform the modifications manually| +|* Ensure financial services compliancy for VPC services \n * Perform network setup of all created services \n * Perform network isolation of all created services \n * Ensure all created services are interconnected |Secure landing zone components|Create a minimum set of required components for a secure landing zone|Create a modified set of required components for a secure landing zone in preset| +|* Allow customer to optionally enable monitoring in the deployment|IBM Cloud® monitoring instance and Monitoring Host VPC Instance|Optionally, create or import an existing IBM Cloud® monitoring instance (customer provided details) and create and pre-configure the Monitoring Host VPC instance to collect information and send it to the IBM Cloud® monitoring instance.| | +|* Allow customer to optionally enable [Security and Compliance Center Workload Protection](/docs/workload-protection) in the deployment \n * Collect posture management information, enable vulnerability scanning and threat detection|IBM Cloud® Security and Compliance Center Workload Protection and SCC Workload Protection agent on all VPC instances in the deployment.|Optionally, create an IBM Cloud® Security and Compliance Center Workload Protection instance and install and setup the SCC Workload Protection agent on all VPC instances in the deployment (bastion, network services, monitoring hosts).| | +{: caption="Table 1. VPC architecture decisions" caption-side="bottom"} + +### PowerVS workspace architecture decisions +{: #standard-openshift-pvs-components-workspace} + +| Requirement | Component | Choice | Alternative choice | +|-------------|-----------|--------------------|--------------------| +|* Connect PowerVS workspace with VPC services|Transit gateway| Set up a local transit gateway| | +|* Preload a public SSH key that is injected into every OS deployment|Preloaded SSH public key|Preload customer specified SSH public key| | +{: caption="Table 2. PowerVS workspace architecture decisions" caption-side="bottom"} + +### PowerVS management services architecture decisions +{: #standard-openshift-pvs-components-mgmt} + +| Requirement | Component | Choice | Alternative choice | +|-------------|-----------|--------------------|--------------------| +|* Ensure public internet connectivity from all the instances to be deployed in PowerVS workspace|SQUID proxy|Set up SQUID proxy software on Linux virtual server instance that is running in edge VPC| | +|* Provide shared NFS storage that might be directly attached to all the instances to be deployed in PowerVS workspace| File storage shares in VPC|Use the files storage share service running in VPC. Disk size is specified by the user.| | +|* Provide time synchronization to all instances to be deployed in PowerVS workspace|NTP forwarder|Synchronize time by using public NTP servers. Set up time synchronization on Linux virtual server instance that is running in workload VPC.|By using time synchronization servers directly reachable from PowerVS workspace, NTP forwarder is not required.| +|* Provide a DNS forwarder to a DNS server not directly reachable from PowerVS workspace (for example, running on-premises or in other isolated environment)|DNS forwarder|Configure DNS forwarder on Linux virtual server instance that is running in edge VPC| By using default IBM Cloud DNS service, DNS forwarder is not needed. Direct domain name resolution is possible.| +{: caption="Table 3. PowerVS management services architecture decisions" caption-side="bottom"} + +### Network security architecture decisions +{: #standard-openshift-net-sec} + +| Requirement | Component | Choice | Alternative choice | +|-------------|-----------|--------------------|--------------------| +|* Preload VPN configuration to simplify VPN setup|VPNs|VPN configuration is the responsibility of the customer. Automation creates a client to site VPN server| | +|* Enable floating IP on bastion host to execute deployment|Floating IPs on bastion host in management VPC|Use floating IP on bastion host from IBM Schematics to complete deployment| | +|* Isolate management VSI and allow only a limited number of network connections \n * All other connections from or to management VPC are forbidden|Security group rules for management VSI|Open following ports by default: 22 (for limited number of IPs). \n All ports to PowerVS workspace are open. \n All ports to other VPCs are open.|More ports might be opened in preset or added manually after deployment| +|* Isolate network services VSI, VPEs and NFSaaS |Security group rules in edge VPC|Separate security groups are created for each component and only certain IPs or Ports are allowed. |More ports might be opened in preset or added manually after deployment| +{: caption="Table 4. Network security architecture decisions" caption-side="bottom"} + +### PowerVS instance - architecture decisions +{: #standard-openshift-pvs-components} + +| Requirement | Component | Choice | Alternative choice | +|-------------|-----------|--------------------|--------------------| +|* Deploy PowerVS instance for POC or demo purposes \n * Use pre-defined t-shirt sizes with regards to memory, cpu, OS and storage | PowerVS instance | * Attach all required storage filesystems \n * Attach networks for management and backup \n * Connect instance with infrastructure management services like DNS, NTP, NFS | * Allow customer to specify memory, cpu, OS, storage and additional parameters \n * OS configuration is the responsibility of the customer | +{: caption="Table 5. PowerVS workspace architecture decisions" caption-side="bottom"} + + +### Key and password management architecture decisions +{: #standard-openshift-key-pw} + +| Requirement | Component | Choice | Alternative choice | +|-------------|-----------|--------------------|--------------------| +|* Use public/private SSH key to access virtual server instances by using SSH \n * Use SSH proxy to log in to all virtual server instances by using the bastion host \n * Do not store private ssh key on any virtual instances, also not on the bastion host \n * Do not allow any other SSH login methods except the one with specified private/public SSH key pair|Public SSH key - provided by customer. Private SSH key - provided by customer.|Ask customer to specify the keys. Accept the input as secure parameter or as reference to the key stored in IBM Cloud Secure Storage Manager. Do not print SSH keys in any log files. Do not persist private SSH key.| | +|* Use public/private SSH key to access virtual server instances by using SSH \n * Use SSH proxy to log in to all virtual server instances by using the private IPS of instances using a VPN client \n * Do not store private ssh key on any virtual instances \n * Do not allow any other SSH login methods except the one with specified private/public SSH key pair|Public SSH key - provided by customer. Private SSH key - provided by customer.|Ask customer to specify the keys. Accept the input as secure parameter or as reference to the key stored in IBM Cloud Secure Storage Manager. Do not print SSH keys in any log files. Do not persist private SSH key.| | +{: caption="Table 5. Key and passwords management architecture decisions" caption-side="bottom"} diff --git a/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md b/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md index d785356c..6a07c9b7 100644 --- a/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md +++ b/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md @@ -1,7 +1,7 @@ --- copyright: years: 2024, 2025 -lastupdated: "2025-09-08" +lastupdated: "2025-09-15" keywords: subcollection: deployable-reference-architectures authors: @@ -16,7 +16,7 @@ image_source: https://github.com/terraform-ibm-modules/terraform-ibm-powervs-inf use-case: ITServiceManagement industry: Technology content-type: reference-architecture -version: v9.0.1 +version: v10.0.0 compliance: --- @@ -28,11 +28,11 @@ compliance: {: toc-content-type="reference-architecture"} {: toc-industry="Technology"} {: toc-use-case="ITServiceManagement"} -{: toc-version="v9.0.1"} +{: toc-version="v10.0.0"} Quickstart deployment of the Power Virtual Server with VPC landing zone creates VPC services, a Power Virtual Server workspace, and interconnects them. It also deploys a Power Virtual Server of chosen T-shirt size or custom configuration. Supported Os are Aix, IBM i, and Linux images. -A proxy service for public internet access from the PowerVS workspace is configured. You can optionally configure some management components on VPC (such as an NFS service, NTP forwarder, and DNS forwarder), as well as Monitoring and Security and Compliance Center Workload Protection.. +A proxy service for public internet access from the PowerVS workspace is configured. You can optionally configure some management components on VPC (such as an NFS service, NTP forwarder, and DNS forwarder), as well as Monitoring and Security and Compliance Center Workload Protection. ## Architecture diagram {: #standard-plus-vsi-architecture-diagram} diff --git a/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md b/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md index fa95a5fc..8ac8dd97 100644 --- a/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md +++ b/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md @@ -1,7 +1,7 @@ --- copyright: years: 2024, 2025 -lastupdated: "2025-09-08" +lastupdated: "2025-09-15" keywords: subcollection: deployable-reference-architectures authors: @@ -15,7 +15,7 @@ image_source: https://github.com/terraform-ibm-modules/terraform-ibm-powervs-inf use-case: ITServiceManagement industry: Technology content-type: reference-architecture -version: v9.0.1 +version: v10.0.0 compliance: SAPCertified --- @@ -28,7 +28,7 @@ compliance: SAPCertified {: toc-industry="Technology"} {: toc-use-case="ITServiceManagement"} {: toc-compliance="SAPCertified"} -{: toc-version="v9.0.1"} +{: toc-version="v10.0.0"} The Standard deployment of the Power Virtual Server with VPC landing zone creates VPC services and a Power Virtual Server workspace and interconnects them. From 6efd24df543e54b495dadc25a5d6d68375b907f4 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 21:02:34 +0200 Subject: [PATCH 48/83] ci: add standard-openshift to catalog onboarding pipeline --- .catalog-onboard-pipeline.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index 16367f67..b24ba904 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -18,3 +18,9 @@ offerings: scc: instance_id: d9f6ba0c-dd0e-4348-a834-6002b675fe40 region: us-south + - name: standard-openshift + mark_ready: false + install_type: fullstack + scc: + instance_id: d9f6ba0c-dd0e-4348-a834-6002b675fe40 + region: us-south From 92bca23df520a73522719243b1cc05224c76f2cf Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 21:14:43 +0200 Subject: [PATCH 49/83] docs: add openshift entries to readme --- README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8667da2a..f3214b3d 100644 --- a/README.md +++ b/README.md @@ -9,24 +9,31 @@ ## Summary This repository contains deployable architecture solutions that help provision VPC landing zones, PowerVS workspaces, and interconnect them. The solutions are available in the IBM Cloud Catalog and can also be deployed without the catalog, except for the second solution below. -Two solutions are offered: +Three solutions are offered: 1. [Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard) - Creates a VPC and Power Virtual Server workspace, interconnects them, and configures OS network management services (SQUID proxy, NTP, NFS, and DNS services) using Ansible Galaxy collection roles [ibm.power_linux_sap collection](https://galaxy.ansible.com/ui/repo/published/ibm/power_linux_sap/). 2. [Quickstart (Standard Landscape plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-plus-vsi) - Creates a VPC and a Power Virtual Server workspace, interconnects them, and configures operating network management services (SQUID proxy, NTP, NFS, and DNS services) using Ansible Galaxy collection roles [ibm.power_linux_sap collection](https://galaxy.ansible.com/ui/repo/published/ibm/power_linux_sap/). - Additionally creates a Power Virtual Server Instance of a selected t-shirt size. Network management services, filesystems and SCC Workload protection agents are configured for AIX and Linux instances. - This solution is typically utilized for **PoCs, demos, and quick onboarding** to PowerVS Infrastructure. +3. [Quickstart Openshift](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-openshift) + - Creates a VPC and a Power Virtual Server workspace and then deploys an OpenShift Cluster in them by using the [RedHat IPI Installer](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html-single/installing_on_ibm_power_virtual_server/index) for IBM PowerVS. + - The number of PowerVS Master and Worker nodes and their compute configuration is fully customizable. + - Optionally creates IBM Cloud Monitoring and a SCC Workload protection instances. + - This solution is typically utilized for **PoCs, demos, and quick onboarding** of OpenShift on PowerVS Infrastructure. ## Reference architectures - [Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/reference-architectures/standard/deploy-arch-ibm-pvs-inf-standard.md) - [Quickstart (Standard Landscape plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md) +- [Quickstart Openshift](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md) ## Solutions -| Variation | Available on IBM Catalog | Requires IBM Schematics Workspace ID | Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastructure | Creates PowerVS Instance | Performs PowerVS OS Config | -| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | -| [Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard) | :heavy_check_mark: | N/A | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | -| [Quickstart (Standard Landscape plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-plus-vsi) | :heavy_check_mark: | N/A | :heavy_check_mark:| :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| Variation | Available on IBM Catalog | Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastructure | Creates PowerVS Instance | Performs PowerVS OS Config | +| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | +| [Standard Landscape](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard) | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | N/A | N/A | +| [Quickstart (Standard Landscape plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-plus-vsi) | :heavy_check_mark: | :heavy_check_mark:| :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | +| [Quickstart OpenShift](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/tree/main/solutions/standard-openshift) | :heavy_check_mark: | :heavy_check_mark:| :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | ## Required IAM access policies From 9dd918c19e26adb979a5ade8d8be9e3cb3ae1f92 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 21:17:31 +0200 Subject: [PATCH 50/83] chore: hide user_data attribute --- ibm_catalog.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 7d692ffb..83753fae 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1424,8 +1424,7 @@ }, { "key": "intel_user_data", - "type": "code_editor", - "display_name": "intel_user_data" + "hidden": true }, { "key": "enable_scc_wp" From 799c99f998be0b8cabdd01dfe0ae805d85a130b7 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 21:22:47 +0200 Subject: [PATCH 51/83] fix: remove dns, ntp, nfs from outputs --- solutions/standard-openshift/README.md | 3 --- solutions/standard-openshift/outputs.tf | 15 --------------- 2 files changed, 18 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index ccc56771..ad96abd1 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -63,13 +63,10 @@ | [cluster\_dir](#output\_cluster\_dir) | The directory on the network services VSI that holds the artifacts of the OpenShift cluster creation. | | [cluster\_name](#output\_cluster\_name) | The name of the cluster and the prefix that is associated with all resources. | | [cluster\_resource\_group](#output\_cluster\_resource\_group) | The resource group where all cluster resources, Transit Gateway, VPC, and PowerVS resources reside. | -| [dns\_host\_or\_ip](#output\_dns\_host\_or\_ip) | DNS forwarder host for created PowerVS infrastructure. | | [kms\_key\_map](#output\_kms\_key\_map) | Map of ids and keys for KMS keys created | | [monitoring\_instance](#output\_monitoring\_instance) | Details of the IBM Cloud Monitoring Instance: CRN, location, guid. | | [network\_load\_balancer](#output\_network\_load\_balancer) | Details of network load balancer. | | [network\_services\_config](#output\_network\_services\_config) | Complete configuration of network management services. | -| [nfs\_host\_or\_ip\_path](#output\_nfs\_host\_or\_ip\_path) | NFS host for created PowerVS infrastructure. | -| [ntp\_host\_or\_ip](#output\_ntp\_host\_or\_ip) | NTP host for created PowerVS infrastructure. | | [powervs\_ssh\_public\_key](#output\_powervs\_ssh\_public\_key) | SSH public key name and value in created PowerVS infrastructure. | | [powervs\_workspace\_guid](#output\_powervs\_workspace\_guid) | PowerVS infrastructure workspace guid. The GUID of the resource instance. | | [powervs\_workspace\_id](#output\_powervs\_workspace\_id) | PowerVS infrastructure workspace id. The unique identifier of the new resource instance. | diff --git a/solutions/standard-openshift/outputs.tf b/solutions/standard-openshift/outputs.tf index 88c0b6f6..2ff8306d 100644 --- a/solutions/standard-openshift/outputs.tf +++ b/solutions/standard-openshift/outputs.tf @@ -91,21 +91,6 @@ output "proxy_host_or_ip_port" { value = module.standard.proxy_host_or_ip_port } -output "dns_host_or_ip" { - description = "DNS forwarder host for created PowerVS infrastructure." - value = module.standard.dns_host_or_ip -} - -output "ntp_host_or_ip" { - description = "NTP host for created PowerVS infrastructure." - value = module.standard.ntp_host_or_ip -} - -output "nfs_host_or_ip_path" { - description = "NFS host for created PowerVS infrastructure." - value = module.standard.nfs_host_or_ip_path -} - output "ansible_host_or_ip" { description = "Central Ansible node private IP address." value = module.standard.ansible_host_or_ip From d21787dc5f029ed84b807191ac9f6d33ebe0e979 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 21:47:49 +0200 Subject: [PATCH 52/83] docs: add features to catalog manifest --- ibm_catalog.json | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 83753fae..326303f8 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1662,8 +1662,16 @@ "architecture": { "features": [ { - "title": "Power Virtual Server Instance", - "description": "No" + "title": "Power Virtual Server Control Plane Instances", + "description": "1 or 3" + }, + { + "title": "Power Virtual Server Compute Instances", + "description": "2...N" + }, + { + "title": "Number of OpenShift Clusters on PowerVS", + "description": "1" }, { "title": "Number of Intel Virtual Server Instance", @@ -1678,7 +1686,7 @@ "description": "1" }, { - "title": "Increases security with Key Management", + "title": "Increased security with Key Management", "description": "Yes" }, { @@ -1686,8 +1694,12 @@ "description": "Proxy service to reach public internet from PowerVS Workspace" }, { - "title": "Additional management configurations on VPC", - "description": "NFS as service, NTP forwarder, and DNS forwarder reachable from PowerVS Workspace" + "title": "IBM Cloud DNS Service", + "description": "Configure DNS server for internal resolution of the Cluster domain" + }, + { + "title": "Number of Application load balancers to ensure Cluster API availability", + "description": "3" }, { "title": "Client to site VPN with new or existing Secrets Manager instance", From 4ac46c8ea81ddac2aadcda4d0ee6f19c74b5356f Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 21:52:01 +0200 Subject: [PATCH 53/83] refactor: fix account_name wrong variable name --- .../playbook-create-ocp-cluster-manifests.yml.tftpl | 4 ++-- solutions/standard-openshift/main.tf | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl index a8bbbad4..43abc249 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl @@ -5,7 +5,7 @@ vars: release_image: "${RELEASE_IMAGE}" requests_dir: "${REQUESTS_DIR}" - account_name: "${ACCOUNT_NAME}" + service_id_prefix: "${SERVICE_ID_PREFIX}" resource_group: "${RESOURCE_GROUP}" cluster_name: "${CLUSTER_NAME}" cluster_dir: "${CLUSTER_DIR}" @@ -24,7 +24,7 @@ command: > ccoctl ibmcloud create-service-id --credentials-requests-dir {{ requests_dir }} - --name {{ account_name }} + --name {{ service_id_prefix }} --resource-group-name {{ resource_group }} args: chdir: "{{ cluster_dir }}" diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index ea1b7716..dfa89d94 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -133,7 +133,7 @@ module "ocp_cluster_manifest_creation" { CLUSTER_NAME : var.cluster_name, CLUSTER_DIR : local.cluster_dir, REQUESTS_DIR : "./credreqs" - ACCOUNT_NAME : var.cluster_name, + SERVICE_ID_PREFIX : var.cluster_name, RESOURCE_GROUP : module.standard.powervs_resource_group_name, } From d269d4648fd2f3459e60476bbf9cf36eba177ce0 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 21:55:10 +0200 Subject: [PATCH 54/83] refactor: rename wrong playbook task --- .../playbook-deploy-ocp-cluster.yml.tftpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl index 5b0e1392..955fd80c 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl @@ -1,5 +1,5 @@ --- -- name: Create .powervs folder +- name: Deploy the OpenShift Cluster hosts: all vars: From 556284a88143ef5e002c338cabd4f959234e9312 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 22:03:58 +0200 Subject: [PATCH 55/83] fix: landing zone module outputting wrong powervs workspace name --- modules/powervs-vpc-landing-zone/outputs.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/powervs-vpc-landing-zone/outputs.tf b/modules/powervs-vpc-landing-zone/outputs.tf index f00e61f1..2857038c 100644 --- a/modules/powervs-vpc-landing-zone/outputs.tf +++ b/modules/powervs-vpc-landing-zone/outputs.tf @@ -113,7 +113,7 @@ output "powervs_zone" { output "powervs_resource_group_name" { description = "IBM Cloud resource group where PowerVS infrastructure is created." - value = "${var.prefix}-${local.second_rg_name}" + value = module.powervs_workspace.pi_resource_group_name } output "powervs_workspace_name" { From 0404f5c07846e90302f856bff4a0404519de6a42 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 15 Sep 2025 22:13:20 +0200 Subject: [PATCH 56/83] fix: powervs rg compatibility with standard and quickstart --- modules/powervs-vpc-landing-zone/powervs-ws.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/powervs-vpc-landing-zone/powervs-ws.tf b/modules/powervs-vpc-landing-zone/powervs-ws.tf index 235c1730..3b00eb75 100644 --- a/modules/powervs-vpc-landing-zone/powervs-ws.tf +++ b/modules/powervs-vpc-landing-zone/powervs-ws.tf @@ -32,7 +32,8 @@ module "powervs_workspace" { providers = { ibm = ibm.ibm-pi } pi_zone = var.powervs_zone - pi_resource_group_id = module.landing_zone.resource_group_data["${var.prefix}-${local.second_rg_name}"] + pi_resource_group_name = var.powervs_resource_group_name != null ? var.powervs_resource_group_name : null + pi_resource_group_id = var.powervs_resource_group_name != null ? null : module.landing_zone.resource_group_data["${var.prefix}-${local.second_rg_name}"] pi_workspace_name = "${var.prefix}-${var.powervs_zone}-power-workspace" pi_ssh_public_key = { "name" = "${var.prefix}-${var.powervs_zone}-pvs-ssh-key", value = var.ssh_public_key } pi_private_subnet_1 = var.powervs_management_network From dc8d8133e4326b0afa95d13e5ebc22df3c19fa67 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 16 Sep 2025 09:56:43 +0200 Subject: [PATCH 57/83] fix: add user_data null check --- modules/powervs-vpc-landing-zone/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/powervs-vpc-landing-zone/main.tf b/modules/powervs-vpc-landing-zone/main.tf index a9fb0190..f6a014c8 100644 --- a/modules/powervs-vpc-landing-zone/main.tf +++ b/modules/powervs-vpc-landing-zone/main.tf @@ -11,7 +11,7 @@ locals { external_access_ip = local.external_access_ip, rhel_image = var.vpc_intel_images.rhel_image, network_services_vsi_profile = var.network_services_vsi_profile, - user_data = replace(var.user_data, "\n", "\\n") + user_data = var.user_data != null ? replace(var.user_data, "\n", "\\n") : null transit_gateway_global = var.transit_gateway_global, enable_monitoring = var.enable_monitoring, sles_image = var.vpc_intel_images.sles_image, From f0e5e960e3d42e7208de2c94576b49b29c6576dd Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 16 Sep 2025 10:06:40 +0200 Subject: [PATCH 58/83] refactor: remove service id prefix as it's just the cluster name --- .secrets.baseline | 4 ++-- .../playbook-create-ocp-cluster-manifests.yml.tftpl | 3 +-- solutions/standard-openshift/main.tf | 1 - 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 70514c22..b55fd733 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-09-09T13:56:02Z", + "generated_at": "2025-09-16T08:06:31Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -110,7 +110,7 @@ "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 62, + "line_number": 61, "type": "Secret Keyword", "verified_result": null } diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl index 43abc249..0789c0ce 100644 --- a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl +++ b/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl @@ -5,7 +5,6 @@ vars: release_image: "${RELEASE_IMAGE}" requests_dir: "${REQUESTS_DIR}" - service_id_prefix: "${SERVICE_ID_PREFIX}" resource_group: "${RESOURCE_GROUP}" cluster_name: "${CLUSTER_NAME}" cluster_dir: "${CLUSTER_DIR}" @@ -24,7 +23,7 @@ command: > ccoctl ibmcloud create-service-id --credentials-requests-dir {{ requests_dir }} - --name {{ service_id_prefix }} + --name {{ cluster_name }} --resource-group-name {{ resource_group }} args: chdir: "{{ cluster_dir }}" diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index dfa89d94..9b9a19f6 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -133,7 +133,6 @@ module "ocp_cluster_manifest_creation" { CLUSTER_NAME : var.cluster_name, CLUSTER_DIR : local.cluster_dir, REQUESTS_DIR : "./credreqs" - SERVICE_ID_PREFIX : var.cluster_name, RESOURCE_GROUP : module.standard.powervs_resource_group_name, } From 2303038e8bd3029f5efb87b49237e8016b26d3e0 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Tue, 16 Sep 2025 14:27:41 +0200 Subject: [PATCH 59/83] refactor: move ansible module into openshift variation --- .secrets.baseline | 54 +++++++++---------- solutions/standard-openshift/README.md | 6 +-- .../standard-openshift}/ansible/README.md | 0 .../standard-openshift}/ansible/main.tf | 0 .../standard-openshift}/ansible/outputs.tf | 0 .../ansible_exec.sh.tftpl | 0 .../ansible_exec_vault.sh.tftpl | 0 .../playbook-configure-ocp-cluster.yml.tftpl | 0 ...ook-create-ocp-cluster-manifests.yml.tftpl | 0 .../playbook-deploy-ocp-cluster.yml.tftpl | 0 .../ansible/templates-ansible/inventory.tftpl | 0 .../standard-openshift}/ansible/variables.tf | 0 .../standard-openshift}/ansible/versions.tf | 0 solutions/standard-openshift/main.tf | 6 +-- 14 files changed, 33 insertions(+), 33 deletions(-) rename {modules => solutions/standard-openshift}/ansible/README.md (100%) rename {modules => solutions/standard-openshift}/ansible/main.tf (100%) rename {modules => solutions/standard-openshift}/ansible/outputs.tf (100%) rename {modules => solutions/standard-openshift}/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl (100%) rename {modules => solutions/standard-openshift}/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl (100%) rename {modules => solutions/standard-openshift}/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl (100%) rename {modules => solutions/standard-openshift}/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl (100%) rename {modules => solutions/standard-openshift}/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl (100%) rename {modules => solutions/standard-openshift}/ansible/templates-ansible/inventory.tftpl (100%) rename {modules => solutions/standard-openshift}/ansible/variables.tf (100%) rename {modules => solutions/standard-openshift}/ansible/versions.tf (100%) diff --git a/.secrets.baseline b/.secrets.baseline index b55fd733..b6332d39 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-09-16T08:06:31Z", + "generated_at": "2025-09-16T12:27:11Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -87,74 +87,74 @@ "verified_result": null } ], - "modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl": [ + "modules/powervs-vpc-landing-zone/README.md": [ { - "hashed_secret": "6f803b24314c39062efe38d0c1da8c472f47eab3", + "hashed_secret": "91199272d5d6a574a51722ca6f3d1148edb1a0e7", "is_secret": false, "is_verified": false, - "line_number": 174, + "line_number": 45, "type": "Secret Keyword", "verified_result": null }, { - "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", + "hashed_secret": "a67ef662b9a11a96b15936764d77e118c9f155dd", "is_secret": false, "is_verified": false, - "line_number": 190, + "line_number": 60, "type": "Secret Keyword", "verified_result": null - } - ], - "modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl": [ + }, { - "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", + "hashed_secret": "6aa42ddb8d86de967d322e6fdde293bf1344c852", "is_secret": false, "is_verified": false, - "line_number": 61, + "line_number": 73, "type": "Secret Keyword", "verified_result": null - } - ], - "modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl": [ + }, { - "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", + "hashed_secret": "9ceaacf8f9b3c35bd235b307d91a5bf7cff2c669", "is_secret": false, "is_verified": false, - "line_number": 53, + "line_number": 81, "type": "Secret Keyword", "verified_result": null } ], - "modules/powervs-vpc-landing-zone/README.md": [ + "solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl": [ { - "hashed_secret": "91199272d5d6a574a51722ca6f3d1148edb1a0e7", + "hashed_secret": "6f803b24314c39062efe38d0c1da8c472f47eab3", "is_secret": false, "is_verified": false, - "line_number": 45, + "line_number": 174, "type": "Secret Keyword", "verified_result": null }, { - "hashed_secret": "a67ef662b9a11a96b15936764d77e118c9f155dd", + "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 60, + "line_number": 190, "type": "Secret Keyword", "verified_result": null - }, + } + ], + "solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl": [ { - "hashed_secret": "6aa42ddb8d86de967d322e6fdde293bf1344c852", + "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 73, + "line_number": 61, "type": "Secret Keyword", "verified_result": null - }, + } + ], + "solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl": [ { - "hashed_secret": "9ceaacf8f9b3c35bd235b307d91a5bf7cff2c669", + "hashed_secret": "d2e2ab0f407e4ee3cf2ab87d61c31b25a74085e5", "is_secret": false, "is_verified": false, - "line_number": 81, + "line_number": 53, "type": "Secret Keyword", "verified_result": null } diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index ad96abd1..6d85c5dc 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -11,9 +11,9 @@ | Name | Source | Version | |------|--------|---------| -| [ocp\_cluster\_deployment](#module\_ocp\_cluster\_deployment) | ../../modules/ansible | n/a | -| [ocp\_cluster\_install\_configuration](#module\_ocp\_cluster\_install\_configuration) | ../../modules/ansible | n/a | -| [ocp\_cluster\_manifest\_creation](#module\_ocp\_cluster\_manifest\_creation) | ../../modules/ansible | n/a | +| [ocp\_cluster\_deployment](#module\_ocp\_cluster\_deployment) | ./ansible | n/a | +| [ocp\_cluster\_install\_configuration](#module\_ocp\_cluster\_install\_configuration) | ./ansible | n/a | +| [ocp\_cluster\_manifest\_creation](#module\_ocp\_cluster\_manifest\_creation) | ./ansible | n/a | | [standard](#module\_standard) | ../../modules/powervs-vpc-landing-zone | n/a | ### Resources diff --git a/modules/ansible/README.md b/solutions/standard-openshift/ansible/README.md similarity index 100% rename from modules/ansible/README.md rename to solutions/standard-openshift/ansible/README.md diff --git a/modules/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf similarity index 100% rename from modules/ansible/main.tf rename to solutions/standard-openshift/ansible/main.tf diff --git a/modules/ansible/outputs.tf b/solutions/standard-openshift/ansible/outputs.tf similarity index 100% rename from modules/ansible/outputs.tf rename to solutions/standard-openshift/ansible/outputs.tf diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl similarity index 100% rename from modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl rename to solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl similarity index 100% rename from modules/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl rename to solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl similarity index 100% rename from modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl rename to solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-configure-ocp-cluster.yml.tftpl diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl similarity index 100% rename from modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl rename to solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-create-ocp-cluster-manifests.yml.tftpl diff --git a/modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl similarity index 100% rename from modules/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl rename to solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/playbook-deploy-ocp-cluster.yml.tftpl diff --git a/modules/ansible/templates-ansible/inventory.tftpl b/solutions/standard-openshift/ansible/templates-ansible/inventory.tftpl similarity index 100% rename from modules/ansible/templates-ansible/inventory.tftpl rename to solutions/standard-openshift/ansible/templates-ansible/inventory.tftpl diff --git a/modules/ansible/variables.tf b/solutions/standard-openshift/ansible/variables.tf similarity index 100% rename from modules/ansible/variables.tf rename to solutions/standard-openshift/ansible/variables.tf diff --git a/modules/ansible/versions.tf b/solutions/standard-openshift/ansible/versions.tf similarity index 100% rename from modules/ansible/versions.tf rename to solutions/standard-openshift/ansible/versions.tf diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index 9b9a19f6..dd99211b 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -64,7 +64,7 @@ locals { } module "ocp_cluster_install_configuration" { - source = "../../modules/ansible" + source = "./ansible" depends_on = [module.standard] bastion_host_ip = module.standard.access_host_or_ip @@ -114,7 +114,7 @@ module "ocp_cluster_install_configuration" { } module "ocp_cluster_manifest_creation" { - source = "../../modules/ansible" + source = "./ansible" depends_on = [module.ocp_cluster_install_configuration] bastion_host_ip = module.standard.access_host_or_ip @@ -142,7 +142,7 @@ module "ocp_cluster_manifest_creation" { } module "ocp_cluster_deployment" { - source = "../../modules/ansible" + source = "./ansible" depends_on = [module.ocp_cluster_manifest_creation] bastion_host_ip = module.standard.access_host_or_ip From 7bb9cda4c8ab471eaa4441d69742e81e3337fbaa Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 18 Sep 2025 14:42:52 +0200 Subject: [PATCH 60/83] fix: powervs resource group name output in landing zone module --- modules/powervs-vpc-landing-zone/outputs.tf | 2 +- solutions/standard-openshift/main.tf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/powervs-vpc-landing-zone/outputs.tf b/modules/powervs-vpc-landing-zone/outputs.tf index 2857038c..d65edcdb 100644 --- a/modules/powervs-vpc-landing-zone/outputs.tf +++ b/modules/powervs-vpc-landing-zone/outputs.tf @@ -113,7 +113,7 @@ output "powervs_zone" { output "powervs_resource_group_name" { description = "IBM Cloud resource group where PowerVS infrastructure is created." - value = module.powervs_workspace.pi_resource_group_name + value = var.powervs_resource_group_name != null ? var.powervs_resource_group_name : "${var.prefix}-ocp-rg" } output "powervs_workspace_name" { diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index dd99211b..e69ccc99 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -85,7 +85,7 @@ module "ocp_cluster_install_configuration" { CLUSTER_NAME : var.cluster_name, CLUSTER_NETWORK : var.cluster_network_config.cluster_network_cidr, CLUSTER_SERVICE_NETWORK : var.cluster_network_config.cluster_service_network_cidr, - MACHINE_NETWORK : var.cluster_network_config.cluster_machine_network_cidr + MACHINE_NETWORK : var.cluster_network_config.cluster_machine_network_cidr, WORKER_PROCESSORS : local.cluster_worker_node_config.processors, WORKER_SYSTEM_TYPE : local.cluster_worker_node_config.system_type, WORKER_PROC_TYPE : local.cluster_worker_node_config.proc_type, @@ -103,7 +103,7 @@ module "ocp_cluster_install_configuration" { POWERVS_REGION : local.powervs_region, POWERVS_ZONE : var.powervs_zone, VPC_NAME : module.standard.vpc_names[0], - VPC_REGION : local.vpc_region + VPC_REGION : local.vpc_region, PULL_SECRET_FILE : jsonencode(var.openshift_pull_secret), SSH_KEY : var.ssh_public_key, } From d1633c1dbcaf30b21a9f50d1d2a86f5a8e7d429f Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 19 Sep 2025 13:51:28 +0200 Subject: [PATCH 61/83] chore(deps): update intel images --- solutions/standard-plus-vsi/README.md | 2 +- solutions/standard-plus-vsi/variables.tf | 4 ++-- solutions/standard/README.md | 2 +- solutions/standard/variables.tf | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/solutions/standard-plus-vsi/README.md b/solutions/standard-plus-vsi/README.md index 588e8403..ab159a4e 100644 --- a/solutions/standard-plus-vsi/README.md +++ b/solutions/standard-plus-vsi/README.md @@ -98,7 +98,7 @@ This example sets up the following infrastructure: | [ssh\_public\_key](#input\_ssh\_public\_key) | Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region. | `string` | n/a | yes | | [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace | `list(string)` | `[]` | no | | [tshirt\_size](#input\_tshirt\_size) | PowerVS instance profiles. These profiles can be overridden by specifying 'custom\_profile\_instance\_boot\_image' and 'custom\_profile' values in optional parameters. |
object({
tshirt_size = string
image = string
})
| n/a | yes | -| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-4-amd64-sap-applications-5",
"sles_image": "ibm-sles-15-6-amd64-sap-applications-3"
}
| no | +| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-6-amd64-sap-applications-1",
"sles_image": "ibm-sles-15-7-amd64-sap-applications-1"
}
| no | ### Outputs diff --git a/solutions/standard-plus-vsi/variables.tf b/solutions/standard-plus-vsi/variables.tf index 8fe182de..7f049320 100644 --- a/solutions/standard-plus-vsi/variables.tf +++ b/solutions/standard-plus-vsi/variables.tf @@ -138,8 +138,8 @@ variable "vpc_intel_images" { sles_image = string }) default = { - "rhel_image" : "ibm-redhat-9-4-amd64-sap-applications-5" - "sles_image" : "ibm-sles-15-6-amd64-sap-applications-3" + "rhel_image" : "ibm-redhat-9-6-amd64-sap-applications-1" + "sles_image" : "ibm-sles-15-7-amd64-sap-applications-1" } } diff --git a/solutions/standard/README.md b/solutions/standard/README.md index a44e8b4e..921ecd5a 100644 --- a/solutions/standard/README.md +++ b/solutions/standard/README.md @@ -95,7 +95,7 @@ This example sets up the following infrastructure: | [ssh\_public\_key](#input\_ssh\_public\_key) | Public SSH Key for VSI creation. Must be an RSA key with a key size of either 2048 bits or 4096 bits (recommended). Must be a valid SSH key that does not already exist in the deployment region. | `string` | n/a | yes | | [tags](#input\_tags) | List of tag names for the IBM Cloud PowerVS workspace. | `list(string)` | `[]` | no | | [transit\_gateway\_global](#input\_transit\_gateway\_global) | Connect to the networks outside the associated region. | `bool` | `false` | no | -| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-4-amd64-sap-applications-5",
"sles_image": "ibm-sles-15-6-amd64-sap-applications-3"
}
| no | +| [vpc\_intel\_images](#input\_vpc\_intel\_images) | Stock OS image names for creating VPC landing zone VSI instances: RHEL (management and network services) and SLES (monitoring). |
object({
rhel_image = string
sles_image = string
})
|
{
"rhel_image": "ibm-redhat-9-6-amd64-sap-applications-1",
"sles_image": "ibm-sles-15-7-amd64-sap-applications-1"
}
| no | ### Outputs diff --git a/solutions/standard/variables.tf b/solutions/standard/variables.tf index 46e1d26e..3b8cdbaf 100644 --- a/solutions/standard/variables.tf +++ b/solutions/standard/variables.tf @@ -157,8 +157,8 @@ variable "vpc_intel_images" { sles_image = string }) default = { - "rhel_image" : "ibm-redhat-9-4-amd64-sap-applications-5" - "sles_image" : "ibm-sles-15-6-amd64-sap-applications-3" + "rhel_image" : "ibm-redhat-9-6-amd64-sap-applications-1" + "sles_image" : "ibm-sles-15-7-amd64-sap-applications-1" } } From 3655f4d44ec334c2f1f820cfd03638db2d968c72 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 19 Sep 2025 15:25:33 +0200 Subject: [PATCH 62/83] docs: arch diagram dhcp subnet and load balancer names --- .../deploy-arch-ibm-pvs-inf-standard-openshift.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg index 386c5ae5..2b656555 100644 --- a/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg +++ b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg @@ -1,4 +1,4 @@ -
IBM Cloud
IBM Cloud
Zone 1
Zone 1
TransitGateway
PowerVS Resource Group
PowerVS Resource Group
Secure PowerVS Workspace
Secure PowerVS Workspace
SSH Public Key
10.67.0.0/14: Service Subnet
10.67.0.0/14: Service Subnet
10.72.0.0/24: Machine Subnet
10.72.0.0/24: Machine Subnet
Power Virtual Server Instance
Worker Nodes
Power Virtual Server Instance...
Block Storageveth: Management Networkveth: Backup Network
Power Virtual Server Instance
Master Nodes
Power Virtual Server Instanc...
Block Storageveth: Management Networkveth: Backup Network
Power Virtual Server Instance
Bootstrap Instance (temporary)
Power Virtual Server Instanc...
Block Storageveth: Management Networkveth: Backup Network
Cloud Services
Cloud Services
Edge VPC Flow Log CollectorSecretsManagerObject  StorageInstallation filesObject  StorageActivity tracker MonitoringKey ProtectAcitivity Tracker Event RoutingActivity TrackerSCC WorkloadProtectionDNS Service
Services Resource Group
Services Resource Group
Edge Resource Group
Edge Resource Group
Edge VPC (Default ACL)
Edge VPC (Default ACL)
Management SG
Management SG
10.30.20.0/24: 
Mgmt VSI Subnet
10.30.20.0/24:...
Virtual Server
Virtual Server
FloatingIPBastionHost
Network-services SG
Network-services SG
10.30.40.0/24: Edge VSI Subnet
10.30.40.0/24: Edge VSI Subnet
Virtual Server
Virtual Server
Proxy ServerAnsible Node
PublicGateway
Virtual Server
Virtual Server
Monitoring Host
Default SG
Default SG
10.30.10.0/24: 
VPN Subnet
10.30.10.0/24:...
Client to site VPN server
PublicApplicationLoad BalancerInternalApplicationLoad BalancerApplicationLoadBalancer
10.30.30.0/24: 
VPE Subnet
10.30.30.0/24:...
COS VPE
VPE SG
VPE SG
Consumer
Consumer
UserInternet
Text is not SVG - cannot display
\ No newline at end of file +
IBM Cloud
IBM Cloud
Zone 1
Zone 1
TransitGateway
PowerVS Resource Group
PowerVS Resource Group
Secure PowerVS Workspace
Secure PowerVS Workspace
SSH Public Key
10.72.0.0/24: Machine Subnet with DHCP Server
10.72.0.0/24: Machine Subnet with DHCP Server
Power Virtual Server Instance
Worker Nodes
Power Virtual Server Instance...
Block Storageveth: Management Networkveth: Backup Network
Power Virtual Server Instance
Master Nodes
Power Virtual Server Instanc...
Block Storageveth: Management Networkveth: Backup Network
Power Virtual Server Instance
Bootstrap Instance (temporary)
Power Virtual Server Instanc...
Block Storageveth: Management Networkveth: Backup Network
Cloud Services
Cloud Services
Edge VPC Flow Log CollectorSecretsManagerObject  StorageInstallation filesObject  StorageActivity tracker MonitoringKey ProtectAcitivity Tracker Event RoutingActivity TrackerSCC WorkloadProtectionDNS Service
Services Resource Group
Services Resource Group
Edge Resource Group
Edge Resource Group
Edge VPC (Default ACL)
Edge VPC (Default ACL)
Management SG
Management SG
10.30.20.0/24: 
Mgmt VSI Subnet
10.30.20.0/24:...
Virtual Server
Virtual Server
FloatingIPBastionHost
Network-services SG
Network-services SG
10.30.40.0/24: Edge VSI Subnet
10.30.40.0/24: Edge VSI Subnet
Virtual Server
Virtual Server
Proxy ServerAnsible Node
PublicGateway
Virtual Server
Virtual Server
Monitoring Host
Default SG
Default SG
10.30.10.0/24: 
VPN Subnet
10.30.10.0/24:...
Client to site VPN server
ApplicationLoad BalancerPublic APIApplicationLoad BalancerInternal APIApplicationLoad BalancerCluster Applications
10.30.30.0/24: 
VPE Subnet
10.30.30.0/24:...
COS VPE
VPE SG
VPE SG
Consumer
Consumer
UserInternet
Text is not SVG - cannot display
\ No newline at end of file From b3db007725bdf21b060dc6f04444893e0ab327b6 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 19 Sep 2025 16:05:12 +0200 Subject: [PATCH 63/83] feat: add validation for node replicas --- solutions/standard-openshift/variables.tf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index c5b1a606..a6445861 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -116,6 +116,10 @@ variable "cluster_master_node_config" { condition = var.cluster_master_node_config.memory >= 2 && var.cluster_master_node_config.memory <= 64 error_message = "Memory needs to be at least 2 and at most 64." } + validation { + condition = var.cluster_master_node_config.replicas == 1 || var.cluster_master_node_config.replicas == 3 + error_message = "The number of master nodes needs to be 3 or 1 for single-node openshift." + } } variable "cluster_worker_node_config" { @@ -146,6 +150,10 @@ variable "cluster_worker_node_config" { condition = var.cluster_worker_node_config.memory >= 2 && var.cluster_worker_node_config.memory <= 64 error_message = "Memory needs to be at least 2 and at most 64." } + validation { + condition = var.cluster_worker_node_config.replicas >= 2 + error_message = "The number of worker nodes needs to be 2 or more." + } } ##################################################### From 9a0dd03c975f8f5633d4417818f4af6abfe2eb6a Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 19 Sep 2025 16:07:16 +0200 Subject: [PATCH 64/83] docs: add readmes --- ...loy-arch-ibm-pvs-inf-standard-openshift.md | 45 +++++++++---------- solutions/standard-openshift/README.md | 42 +++++++++++++++++ 2 files changed, 62 insertions(+), 25 deletions(-) diff --git a/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md index e9ee91e1..f8ab963b 100644 --- a/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md +++ b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md @@ -31,7 +31,7 @@ compliance: The Quickstart OpenShift deployment on Power Virtual Server with a VPC landing zone uses the Red Hat IPI installer to set up an OpenShift cluster. Before the deployment begins, it provisions VPC services and creates a Power Virtual Server workspace, which together form the landing zone used to access and manage the cluster. -The number of PowerVS master and worker nodes and their respective compute configurations can be freely configured during deployment. Optionally, Monitoring and Security and Compliance Center Workload Protection can also be configured. +The number of PowerVS master and worker nodes and their respective compute configurations can be configured during deployment. Optionally, Monitoring and Security and Compliance Center Workload Protection can also be configured. ## Architecture diagram {: #standard-openshift-architecture-diagram} @@ -45,8 +45,8 @@ The number of PowerVS master and worker nodes and their respective compute confi IBM Cloud® Power Virtual Servers (PowerVS) is a public cloud offering that an enterprise can use to establish its own private IBM Power computing environment on shared public cloud infrastructure. PowerVS is logically isolated from all other public cloud tenants and infrastructure components, creating a private, secure place on the public cloud. This deployable architecture provides a framework to build a PowerVS offering according to the best practices and requirements from the IBM Cloud. -## Components -{: #standard-openshift-components} +## Landing Zone Components +{: #standard-openshift-landing-zone-components} ### VPC architecture decisions {: #standard-openshift-vpc-components-arch} @@ -59,6 +59,7 @@ IBM Cloud® Power Virtual Servers (PowerVS) is a public cloud offering that an e |* Allow customer to choose operating system from two most widely used commercial Linux operating system offerings \n * Support new OS releases|Linux operating system|Red Hat Enterprise Linux (RHEL)| | |* Create a virtual server instance as the only management access point to the landscape|Bastion host VPC instance|Create a Linux VPC instance that acts as a bastion host. Configure ACL and security group rules to allow SSH connectivity (port 22). Add a public IP address to the VPC instance. Allow connectivity from a restricted and limited number of public IP addresses. Allow connectivity from IP addresses of the Schematics engine nodes| | |* Create a virtual server instance that can act as an internet proxy server |Network services VPC instance|Create a Linux VPC instance that can host management components. Preconfigure ACL and security group rules to allow traffic over private networks only.|Configure application load balancer to act as proxy server manually, Modify number of virtual server instances and allowed ports in preset or perform the modifications manually| +|* Create DNS Service instance as pre-requisite for IPI installer | DNS Service Instance | Create a DNS Service instance and a custom resolver to internally resolve the cluster domain. | | |* Ensure financial services compliancy for VPC services \n * Perform network setup of all created services \n * Perform network isolation of all created services \n * Ensure all created services are interconnected |Secure landing zone components|Create a minimum set of required components for a secure landing zone|Create a modified set of required components for a secure landing zone in preset| |* Allow customer to optionally enable monitoring in the deployment|IBM Cloud® monitoring instance and Monitoring Host VPC Instance|Optionally, create or import an existing IBM Cloud® monitoring instance (customer provided details) and create and pre-configure the Monitoring Host VPC instance to collect information and send it to the IBM Cloud® monitoring instance.| | |* Allow customer to optionally enable [Security and Compliance Center Workload Protection](/docs/workload-protection) in the deployment \n * Collect posture management information, enable vulnerability scanning and threat detection|IBM Cloud® Security and Compliance Center Workload Protection and SCC Workload Protection agent on all VPC instances in the deployment.|Optionally, create an IBM Cloud® Security and Compliance Center Workload Protection instance and install and setup the SCC Workload Protection agent on all VPC instances in the deployment (bastion, network services, monitoring hosts).| | @@ -73,17 +74,6 @@ IBM Cloud® Power Virtual Servers (PowerVS) is a public cloud offering that an e |* Preload a public SSH key that is injected into every OS deployment|Preloaded SSH public key|Preload customer specified SSH public key| | {: caption="Table 2. PowerVS workspace architecture decisions" caption-side="bottom"} -### PowerVS management services architecture decisions -{: #standard-openshift-pvs-components-mgmt} - -| Requirement | Component | Choice | Alternative choice | -|-------------|-----------|--------------------|--------------------| -|* Ensure public internet connectivity from all the instances to be deployed in PowerVS workspace|SQUID proxy|Set up SQUID proxy software on Linux virtual server instance that is running in edge VPC| | -|* Provide shared NFS storage that might be directly attached to all the instances to be deployed in PowerVS workspace| File storage shares in VPC|Use the files storage share service running in VPC. Disk size is specified by the user.| | -|* Provide time synchronization to all instances to be deployed in PowerVS workspace|NTP forwarder|Synchronize time by using public NTP servers. Set up time synchronization on Linux virtual server instance that is running in workload VPC.|By using time synchronization servers directly reachable from PowerVS workspace, NTP forwarder is not required.| -|* Provide a DNS forwarder to a DNS server not directly reachable from PowerVS workspace (for example, running on-premises or in other isolated environment)|DNS forwarder|Configure DNS forwarder on Linux virtual server instance that is running in edge VPC| By using default IBM Cloud DNS service, DNS forwarder is not needed. Direct domain name resolution is possible.| -{: caption="Table 3. PowerVS management services architecture decisions" caption-side="bottom"} - ### Network security architecture decisions {: #standard-openshift-net-sec} @@ -92,17 +82,8 @@ IBM Cloud® Power Virtual Servers (PowerVS) is a public cloud offering that an e |* Preload VPN configuration to simplify VPN setup|VPNs|VPN configuration is the responsibility of the customer. Automation creates a client to site VPN server| | |* Enable floating IP on bastion host to execute deployment|Floating IPs on bastion host in management VPC|Use floating IP on bastion host from IBM Schematics to complete deployment| | |* Isolate management VSI and allow only a limited number of network connections \n * All other connections from or to management VPC are forbidden|Security group rules for management VSI|Open following ports by default: 22 (for limited number of IPs). \n All ports to PowerVS workspace are open. \n All ports to other VPCs are open.|More ports might be opened in preset or added manually after deployment| -|* Isolate network services VSI, VPEs and NFSaaS |Security group rules in edge VPC|Separate security groups are created for each component and only certain IPs or Ports are allowed. |More ports might be opened in preset or added manually after deployment| -{: caption="Table 4. Network security architecture decisions" caption-side="bottom"} - -### PowerVS instance - architecture decisions -{: #standard-openshift-pvs-components} - -| Requirement | Component | Choice | Alternative choice | -|-------------|-----------|--------------------|--------------------| -|* Deploy PowerVS instance for POC or demo purposes \n * Use pre-defined t-shirt sizes with regards to memory, cpu, OS and storage | PowerVS instance | * Attach all required storage filesystems \n * Attach networks for management and backup \n * Connect instance with infrastructure management services like DNS, NTP, NFS | * Allow customer to specify memory, cpu, OS, storage and additional parameters \n * OS configuration is the responsibility of the customer | -{: caption="Table 5. PowerVS workspace architecture decisions" caption-side="bottom"} - +|* Isolate network services VSI and VPEs |Security group rules in edge VPC|Separate security groups are created for each component and only certain IPs or Ports are allowed. |More ports might be opened in preset or added manually after deployment| +{: caption="Table 3. Network security architecture decisions" caption-side="bottom"} ### Key and password management architecture decisions {: #standard-openshift-key-pw} @@ -112,3 +93,17 @@ IBM Cloud® Power Virtual Servers (PowerVS) is a public cloud offering that an e |* Use public/private SSH key to access virtual server instances by using SSH \n * Use SSH proxy to log in to all virtual server instances by using the bastion host \n * Do not store private ssh key on any virtual instances, also not on the bastion host \n * Do not allow any other SSH login methods except the one with specified private/public SSH key pair|Public SSH key - provided by customer. Private SSH key - provided by customer.|Ask customer to specify the keys. Accept the input as secure parameter or as reference to the key stored in IBM Cloud Secure Storage Manager. Do not print SSH keys in any log files. Do not persist private SSH key.| | |* Use public/private SSH key to access virtual server instances by using SSH \n * Use SSH proxy to log in to all virtual server instances by using the private IPS of instances using a VPN client \n * Do not store private ssh key on any virtual instances \n * Do not allow any other SSH login methods except the one with specified private/public SSH key pair|Public SSH key - provided by customer. Private SSH key - provided by customer.|Ask customer to specify the keys. Accept the input as secure parameter or as reference to the key stored in IBM Cloud Secure Storage Manager. Do not print SSH keys in any log files. Do not persist private SSH key.| | {: caption="Table 5. Key and passwords management architecture decisions" caption-side="bottom"} + +## OpenShift Components +{: #standard-openshift-openshift-components} + +Once the landing zone components are deployed, this architecture leverages the [RedHat IPI installer](https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html-single/installing_on_ibm_power_virtual_server/index){: external} to create an OpenShift cluster. + +| Requirement | Component | Choice | Alternative choice | +|-------------|-----------|--------|--------------------| +|* Deploy PowerVS instances for Bootstrap (temporary), Master, and Worker nodes. | PowerVS instances | The customer can specify the number of master and worker nodes and customize their compute profiles. | +|* Modify the DNS Service instance to correctly resolve the cluster API | DNS Service instance | Add CNAME entries to DNS zone to resolve internal and external cluster APIs. | +|* Application Load Balancers to establish connectivity to the cluster API. | Three Application Load Balancers | One for internal API, one for external api, and one for the applications deployed in the cluster. | +|* Use DHCP to dynamically assign IP addresses to the nodes | DHCP Subnet in PowerVS | Machine network dynamically assigns IP addresses to the nodes. | +|* Modify security groups to allow network traffic to API. | Default Security Group | The default security group is attached to the load balancers and configured so the required network traffic is able to pass. | +{: caption="Table 6. OpenShift architecture decisions" caption-side="bottom"} diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 6d85c5dc..0455fcdc 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -1,3 +1,45 @@ +# IBM Cloud Solution for Power Virtual Server with VPC Landing Zone Quickstart Openshift Variation + +This example sets up an OpenShift Cluster on PowerVS following infrastructure: +- A **VPC Infrastructure** with the following components: + - One VSI for management (jump/bastion) + - One VSI for network-services configured as squid proxy (using Ansible Galaxy collection roles [ibm.power_linux_sap collection](https://galaxy.ansible.com/ui/repo/published/ibm/power_linux_sap/). This VSI also acts as central ansible execution node. + - Optional VSI for Monitoring host + - Optional [Client to site VPN server](https://cloud.ibm.com/docs/vpc?topic=vpc-vpn-client-to-site-overview) + - Optional [IBM Cloud Security and Compliance Center Workload Protection](https://cloud.ibm.com/docs/workload-protection) and SCC Workload Protection agent configuration on the VSIs in the deployment + - IBM Cloud Object storage(COS) Virtual Private endpoint gateway(VPE) + - IBM Cloud Object storage(COS) Instance and buckets + - VPC flow logs + - KMS keys + - Activity tracker + - Optional Secrets Manager Instance Instance with private certificate. + +- A local **transit gateway** +- An IBM Cloud DNS Service Instance +- An optional IBM Cloud Monitoring Instance + +- A **Power Virtual Server** workspace with the following features: + - A DHCP machine subnet to which all nodes are assigned. + - Attaches the PowerVS workspace to transit gateway. + - Creates an SSH key. + +- A configurable number of **PowerVS Instances**: + - 1 or 3 master nodes + - 2 or more worker nodes + - Custom profile (cores, memory, machine type, core type) + +## Solutions + +| Variation | Available on IBM Catalog | Requires Schematics Workspace ID | Creates VPC Landing Zone | Performs VPC VSI OS Config | Creates PowerVS Infrastructure | Creates PowerVS Instance | Creates OpenShift Cluster on PowerVS | +| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | ------------- | +| [Quickstart Openshift](./) | :heavy_check_mark: | N/A | :heavy_check_mark:| :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | + +## Reference architecture +[Quickstart Openshift](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/blob/main/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.md) + +## Architecture diagram +![Quickstart Openshift](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/blob/main/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg) + ### Requirements From 4757fdad44f4d2fbc0e33d17119572723efd1b5a Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 19 Sep 2025 16:07:50 +0200 Subject: [PATCH 65/83] fix: broken link --- solutions/standard-plus-vsi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/solutions/standard-plus-vsi/README.md b/solutions/standard-plus-vsi/README.md index ab159a4e..728c9af9 100644 --- a/solutions/standard-plus-vsi/README.md +++ b/solutions/standard-plus-vsi/README.md @@ -37,7 +37,7 @@ This example sets up the following infrastructure: | [Quickstart (Standard plus VSI)](./) | :heavy_check_mark: | N/A | :heavy_check_mark:| :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | ## Reference architecture -[Quickstart (Standard plus VSI) variation](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/blob/main/reference-architectures/standard-with.instance/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md) +[Quickstart (Standard plus VSI) variation](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/blob/main/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.md) ## Architecture diagram ![Quickstart (Standard plus VSI)](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-infrastructure/blob/main/reference-architectures/standard-plus-vsi/deploy-arch-ibm-pvs-inf-standard-plus-vsi.svg) From b1a9a521420dcb1c42469a86cf31b7b1226787d1 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 19 Sep 2025 17:19:05 +0200 Subject: [PATCH 66/83] docs: wrong subnets --- .../deploy-arch-ibm-pvs-inf-standard-openshift.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg index 2b656555..5b8767f6 100644 --- a/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg +++ b/reference-architectures/standard-openshift/deploy-arch-ibm-pvs-inf-standard-openshift.svg @@ -1,4 +1,4 @@ -
IBM Cloud
IBM Cloud
Zone 1
Zone 1
TransitGateway
PowerVS Resource Group
PowerVS Resource Group
Secure PowerVS Workspace
Secure PowerVS Workspace
SSH Public Key
10.72.0.0/24: Machine Subnet with DHCP Server
10.72.0.0/24: Machine Subnet with DHCP Server
Power Virtual Server Instance
Worker Nodes
Power Virtual Server Instance...
Block Storageveth: Management Networkveth: Backup Network
Power Virtual Server Instance
Master Nodes
Power Virtual Server Instanc...
Block Storageveth: Management Networkveth: Backup Network
Power Virtual Server Instance
Bootstrap Instance (temporary)
Power Virtual Server Instanc...
Block Storageveth: Management Networkveth: Backup Network
Cloud Services
Cloud Services
Edge VPC Flow Log CollectorSecretsManagerObject  StorageInstallation filesObject  StorageActivity tracker MonitoringKey ProtectAcitivity Tracker Event RoutingActivity TrackerSCC WorkloadProtectionDNS Service
Services Resource Group
Services Resource Group
Edge Resource Group
Edge Resource Group
Edge VPC (Default ACL)
Edge VPC (Default ACL)
Management SG
Management SG
10.30.20.0/24: 
Mgmt VSI Subnet
10.30.20.0/24:...
Virtual Server
Virtual Server
FloatingIPBastionHost
Network-services SG
Network-services SG
10.30.40.0/24: Edge VSI Subnet
10.30.40.0/24: Edge VSI Subnet
Virtual Server
Virtual Server
Proxy ServerAnsible Node
PublicGateway
Virtual Server
Virtual Server
Monitoring Host
Default SG
Default SG
10.30.10.0/24: 
VPN Subnet
10.30.10.0/24:...
Client to site VPN server
ApplicationLoad BalancerPublic APIApplicationLoad BalancerInternal APIApplicationLoad BalancerCluster Applications
10.30.30.0/24: 
VPE Subnet
10.30.30.0/24:...
COS VPE
VPE SG
VPE SG
Consumer
Consumer
UserInternet
Text is not SVG - cannot display
\ No newline at end of file +
IBM Cloud
IBM Cloud
Zone 1
Zone 1
TransitGateway
PowerVS Resource Group
PowerVS Resource Group
Secure PowerVS Workspace
Secure PowerVS Workspace
SSH Public Key
10.72.0.0/24: Machine Subnet with DHCP Server
10.72.0.0/24: Machine Subnet with DHCP Server
Power Virtual Server Instance
Worker Nodes
Power Virtual Server Instance...
Block Storageveth: DHCP Machine Subnet
Power Virtual Server Instance
Master Nodes
Power Virtual Server Instanc...
Block Storageveth: DHCP Machine Subnet
Power Virtual Server Instance
Bootstrap Instance (temporary)
Power Virtual Server Instanc...
Block Storageveth: DHCP Machine Subnet
Cloud Services
Cloud Services
Edge VPC Flow Log CollectorSecretsManagerObject  StorageInstallation filesObject  StorageActivity tracker MonitoringKey ProtectAcitivity Tracker Event RoutingActivity TrackerSCC WorkloadProtectionDNS Service
Services Resource Group
Services Resource Group
Edge Resource Group
Edge Resource Group
Edge VPC (Default ACL)
Edge VPC (Default ACL)
Management SG
Management SG
10.30.20.0/24: 
Mgmt VSI Subnet
10.30.20.0/24:...
Virtual Server
Virtual Server
FloatingIPBastionHost
Network-services SG
Network-services SG
10.30.40.0/24: Edge VSI Subnet
10.30.40.0/24: Edge VSI Subnet
Virtual Server
Virtual Server
Proxy ServerAnsible Node
PublicGateway
Virtual Server
Virtual Server
Monitoring Host
Default SG
Default SG
10.30.10.0/24: 
VPN Subnet
10.30.10.0/24:...
Client to site VPN server
ApplicationLoad BalancerPublic APIApplicationLoad BalancerInternal APIApplicationLoad BalancerCluster Applications
10.30.30.0/24: 
VPE Subnet
10.30.30.0/24:...
COS VPE
VPE SG
VPE SG
Consumer
Consumer
UserInternet
Text is not SVG - cannot display
\ No newline at end of file From c5345454b443311af280a4d4b3761ae3b7a7d331 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 22 Sep 2025 13:49:37 +0200 Subject: [PATCH 67/83] fix: remove outputs sections from catalog manifest --- ibm_catalog.json | 291 ----------------------------------------------- 1 file changed, 291 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index ff938000..73ee86bf 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -362,101 +362,6 @@ "hidden": true } ], - "outputs": [ - { - "key": "prefix" - }, - { - "key": "vpc_names" - }, - { - "key": "vpc_data" - }, - { - "key": "vsi_names" - }, - { - "key": "kms_key_map" - }, - { - "key": "vsi_ssh_key_data" - }, - { - "key": "network_load_balancer" - }, - { - "key": "ssh_public_key" - }, - { - "key": "transit_gateway_name" - }, - { - "key": "transit_gateway_id" - }, - { - "key": "transit_gateway_global" - }, - { - "key": "vsi_list" - }, - { - "key": "resource_group_data" - }, - { - "key": "access_host_or_ip" - }, - { - "key": "proxy_host_or_ip_port" - }, - { - "key": "dns_host_or_ip" - }, - { - "key": "ntp_host_or_ip" - }, - { - "key": "nfs_host_or_ip_path" - }, - { - "key": "ansible_host_or_ip" - }, - { - "key": "network_services_config" - }, - { - "key": "powervs_zone" - }, - { - "key": "powervs_resource_group_name" - }, - { - "key": "powervs_workspace_name" - }, - { - "key": "powervs_workspace_id" - }, - { - "key": "powervs_workspace_guid" - }, - { - "key": "powervs_ssh_public_key" - }, - { - "key": "powervs_management_subnet" - }, - { - "key": "powervs_backup_subnet" - }, - { - "key": "powervs_images" - }, - { - "key": "monitoring_instance" - }, - { - "key": "schematics_workspace_id" - } - ], "iam_permissions": [ { "role_crns": [ @@ -1019,107 +924,6 @@ "hidden": true } ], - "outputs": [ - { - "key": "prefix" - }, - { - "key": "vpc_names" - }, - { - "key": "vpc_data" - }, - { - "key": "vsi_names" - }, - { - "key": "network_load_balancer" - }, - { - "key": "ssh_public_key" - }, - { - "key": "transit_gateway_name" - }, - { - "key": "transit_gateway_id" - }, - { - "key": "vsi_list" - }, - { - "key": "kms_key_map" - }, - { - "key": "vsi_ssh_key_data" - }, - { - "key": "resource_group_data" - }, - { - "key": "access_host_or_ip" - }, - { - "key": "proxy_host_or_ip_port" - }, - { - "key": "dns_host_or_ip" - }, - { - "key": "ntp_host_or_ip" - }, - { - "key": "nfs_host_or_ip_path" - }, - { - "key": "ansible_host_or_ip" - }, - { - "key": "network_services_config" - }, - { - "key": "powervs_zone" - }, - { - "key": "powervs_resource_group_name" - }, - { - "key": "powervs_workspace_name" - }, - { - "key": "powervs_workspace_id" - }, - { - "key": "powervs_workspace_guid" - }, - { - "key": "powervs_ssh_public_key" - }, - { - "key": "powervs_management_subnet" - }, - { - "key": "powervs_backup_subnet" - }, - { - "key": "powervs_images" - }, - { - "key": "powervs_instance_management_ip" - }, - { - "key": "powervs_instance_private_ips" - }, - { - "key": "powervs_storage_configuration" - }, - { - "key": "monitoring_instance" - }, - { - "key": "schematics_workspace_id" - } - ], "iam_permissions": [ { "role_crns": [ @@ -1507,101 +1311,6 @@ "hidden": true } ], - "outputs": [ - { - "key": "prefix" - }, - { - "key": "vpc_names" - }, - { - "key": "vpc_data" - }, - { - "key": "vsi_names" - }, - { - "key": "kms_key_map" - }, - { - "key": "vsi_ssh_key_data" - }, - { - "key": "network_load_balancer" - }, - { - "key": "ssh_public_key" - }, - { - "key": "transit_gateway_name" - }, - { - "key": "transit_gateway_id" - }, - { - "key": "transit_gateway_global" - }, - { - "key": "vsi_list" - }, - { - "key": "resource_group_data" - }, - { - "key": "access_host_or_ip" - }, - { - "key": "proxy_host_or_ip_port" - }, - { - "key": "dns_host_or_ip" - }, - { - "key": "ntp_host_or_ip" - }, - { - "key": "nfs_host_or_ip_path" - }, - { - "key": "ansible_host_or_ip" - }, - { - "key": "network_services_config" - }, - { - "key": "powervs_zone" - }, - { - "key": "powervs_resource_group_name" - }, - { - "key": "powervs_workspace_name" - }, - { - "key": "powervs_workspace_id" - }, - { - "key": "powervs_workspace_guid" - }, - { - "key": "powervs_ssh_public_key" - }, - { - "key": "powervs_management_subnet" - }, - { - "key": "powervs_backup_subnet" - }, - { - "key": "powervs_images" - }, - { - "key": "monitoring_instance" - }, - { - "key": "schematics_workspace_id" - } - ], "iam_permissions": [ { "role_crns": [ From 1074110ea8b5aedd5dcda62680e7d9d9e79613a8 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 22 Sep 2025 14:11:05 +0200 Subject: [PATCH 68/83] docs: update ref arch --- .../heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reference-architectures/standard-openshift/heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg b/reference-architectures/standard-openshift/heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg index 4ee6eab6..f074ca79 100644 --- a/reference-architectures/standard-openshift/heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg +++ b/reference-architectures/standard-openshift/heat-map-deploy-arch-ibm-pvs-inf-standard-openshift.svg @@ -1,4 +1,4 @@ - + -
Application
integration
Application...
Mobile
Mobile
Bare metal servers
Bare metal servers
Primary storage
Primary storage
Enterprise
connectivity
Enterprise...
Build & test
Build & test
Data security
Data security
Backup & restore
Backup & restore
Monitoring
Monitoring
Edge
Edge
Blockchain
Blockchain
Enterprise
applications
Enterprise...
Data Ops
Data Ops
Data analytics
Data analytics
Data storage
Data storage
Business intelligence
Business intelligence
Virtual servers
Virtual servers
Virtualization
Virtualization
Containers
Containers
Cloud Foundry
Cloud Foundry
Serverless
Serverless
Backup
Backup
Archive
Archive
Data migration
Data migration
BYOIP/Edge gateways
BYOIP/Edge gateways
Load balancing
Load balancing
Cloud native connectivity
Cloud native connecti...
Isolation
Isolation
Content delivery network
Content delivery netw...
Domain name service
Domain name service
Identity & access
Identity & access
Application security
Application security
Infrastructure & endpoints
Infrastructure & endp...
Threat detection & response
Threat detection & re...
Governance, risk & compliance
Governance, risk & co...
Delivery pipeline
Delivery pipeline
Code repository
Code repository
Disaster recovery
Disaster recovery
High availability
High availability
Logging
Logging
Auditing/tracking
Auditing/tracking
Alerting
Alerting
Event management
Event management
Automated deployment
Automated deployment
Management/
orchestration
Management/...
Domain
Domain
Aspect
Aspect
Application
platforms
Application...
Data
Data
Compute
Compute
Storage
Storage
Networking
Networking
Security
Security
DevOps
DevOps
Resiliency
Resiliency
Service
management
Service...
Included in this architecture
Included in this...
Artificial intelligence
Artificial intelligen...
Text is not SVG - cannot display
+
Application
integration
Application...
Mobile
Mobile
Bare metal servers
Bare metal servers
Primary storage
Primary storage
Enterprise
connectivity
Enterprise...
Build & test
Build & test
Data security
Data security
Backup & restore
Backup & restore
Monitoring
Monitoring
Edge
Edge
Blockchain
Blockchain
Enterprise
applications
Enterprise...
Data Ops
Data Ops
Data analytics
Data analytics
Data storage
Data storage
Business intelligence
Business intelligence
Virtual servers
Virtual servers
Virtualization
Virtualization
Containers
Containers
Cloud Foundry
Cloud Foundry
Serverless
Serverless
Backup
Backup
Archive
Archive
Data migration
Data migration
BYOIP/Edge gateways
BYOIP/Edge gateways
Load balancing
Load balancing
Cloud native connectivity
Cloud native connecti...
Isolation
Isolation
Content delivery network
Content delivery netw...
Domain name service
Domain name service
Identity & access
Identity & access
Application security
Application security
Infrastructure & endpoints
Infrastructure & endp...
Threat detection & response
Threat detection & re...
Governance, risk & compliance
Governance, risk & co...
Delivery pipeline
Delivery pipeline
Code repository
Code repository
Disaster recovery
Disaster recovery
High availability
High availability
Logging
Logging
Auditing/tracking
Auditing/tracking
Alerting
Alerting
Event management
Event management
Automated deployment
Automated deployment
Management/
orchestration
Management/...
Domain
Domain
Aspect
Aspect
Application
platforms
Application...
Data
Data
Compute
Compute
Storage
Storage
Networking
Networking
Security
Security
DevOps
DevOps
Resiliency
Resiliency
Service
management
Service...
Included in this architecture
Included in this...
Artificial intelligence
Artificial intelligen...
RedHat OpenShift
RedHat OpenShift
Text is not SVG - cannot display
\ No newline at end of file From aa38887261933deb606b03cab4304da14183998e Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Mon, 22 Sep 2025 14:20:23 +0200 Subject: [PATCH 69/83] fix: remove default value for cluster name --- ibm_catalog.json | 1 - 1 file changed, 1 deletion(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 73ee86bf..57ecf9a1 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1060,7 +1060,6 @@ { "key": "cluster_name", "type": "string", - "default_value": "", "required": true }, { From a55d5569f48aaff6ead040ea38d874bae0cf712f Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 24 Sep 2025 15:51:12 +0200 Subject: [PATCH 70/83] feat: encrypt ocp config when not in use --- .../standard-openshift/ansible/README.md | 3 +- solutions/standard-openshift/ansible/main.tf | 40 ++++++++++++++++++- .../standard-openshift/ansible/variables.tf | 18 +++++---- solutions/standard-openshift/main.tf | 5 +++ 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/solutions/standard-openshift/ansible/README.md b/solutions/standard-openshift/ansible/README.md index 45cf3a2f..7a077f15 100644 --- a/solutions/standard-openshift/ansible/README.md +++ b/solutions/standard-openshift/ansible/README.md @@ -27,12 +27,13 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [ansible\_host\_or\_ip](#input\_ansible\_host\_or\_ip) | Private IP of virtual server instance running RHEL OS on which ansible will be installed and configured to act as central ansible node. | `string` | n/a | yes | -| [ansible\_vault\_password](#input\_ansible\_vault\_password) | Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]\_{\|}~. | `string` | `null` | no | +| [ansible\_vault\_password](#input\_ansible\_vault\_password) | Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]\_{\|}~. | `string` | n/a | yes | | [bastion\_host\_ip](#input\_bastion\_host\_ip) | Jump/Bastion server public IP address to reach the ansible host which has private IP. | `string` | n/a | yes | | [configure\_ansible\_host](#input\_configure\_ansible\_host) | If set to true, bash script will be executed to install and configure the collections and packages on ansible node. | `bool` | n/a | yes | | [dst\_inventory\_file\_name](#input\_dst\_inventory\_file\_name) | Name for the inventory file to be generated on the Ansible host. | `string` | n/a | yes | | [dst\_playbook\_file\_name](#input\_dst\_playbook\_file\_name) | Name for the playbook file to be generated on the Ansible host. | `string` | n/a | yes | | [dst\_script\_file\_name](#input\_dst\_script\_file\_name) | Name for the bash file to be generated on the Ansible host. | `string` | n/a | yes | +| [encrypt\_playbook](#input\_encrypt\_playbook) | Whether to encrypt the playbook using ansible vault. The ocp configuration will always be encrypted, this only applies to the playbooks. | `bool` | n/a | yes | | [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | `null` | no | | [inventory\_template\_vars](#input\_inventory\_template\_vars) | Map values for the inventory template. | `map(any)` | n/a | yes | | [playbook\_template\_vars](#input\_playbook\_template\_vars) | Map values for the ansible playbook template. | `map(any)` | n/a | yes | diff --git a/solutions/standard-openshift/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf index 0ad75f1c..17b4cbb5 100644 --- a/solutions/standard-openshift/ansible/main.tf +++ b/solutions/standard-openshift/ansible/main.tf @@ -66,7 +66,7 @@ resource "terraform_data" "trigger_ansible_vars" { resource "terraform_data" "execute_playbooks" { depends_on = [terraform_data.setup_ansible_host] - count = var.ansible_vault_password != null ? 0 : 1 + count = var.encrypt_playbook ? 0 : 1 connection { type = "ssh" @@ -119,6 +119,15 @@ resource "terraform_data" "execute_playbooks" { ] } + # Decrypt ocp config if it already exists + provisioner "remote-exec" { + inline = [ + "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file", + "rm -f password_file" + ] + } + # Execute bash shell script to run ansible playbooks provisioner "remote-exec" { inline = [ @@ -134,6 +143,15 @@ resource "terraform_data" "execute_playbooks" { ] } + # Encrypt ocp config if it already exists + provisioner "remote-exec" { + inline = [ + "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file", + "rm -f password_file" + ] + } + # print output of openshift installation if applicable, else do nothing provisioner "remote-exec" { inline = [ @@ -145,7 +163,7 @@ resource "terraform_data" "execute_playbooks" { resource "terraform_data" "execute_playbooks_with_vault" { depends_on = [terraform_data.setup_ansible_host] - count = var.ansible_vault_password != null ? 1 : 0 + count = var.encrypt_playbook ? 1 : 0 connection { type = "ssh" @@ -206,6 +224,15 @@ resource "terraform_data" "execute_playbooks_with_vault" { ] } + # Decrypt ocp config if it already exists + provisioner "remote-exec" { + inline = [ + "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file", + "rm -f password_file" + ] + } + # Execute bash shell script to run ansible playbooks provisioner "remote-exec" { inline = [ @@ -222,6 +249,15 @@ resource "terraform_data" "execute_playbooks_with_vault" { "rm -rf ${local.private_key_file}" ] } + + # Encrypt ocp config if it already exists + provisioner "remote-exec" { + inline = [ + "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file", + "rm -f password_file" + ] + } } diff --git a/solutions/standard-openshift/ansible/variables.tf b/solutions/standard-openshift/ansible/variables.tf index 99aaae1c..d7dd49e0 100644 --- a/solutions/standard-openshift/ansible/variables.tf +++ b/solutions/standard-openshift/ansible/variables.tf @@ -63,33 +63,37 @@ variable "ansible_vault_password" { description = "Vault password to encrypt ansible playbooks that contain sensitive information. Password requirements: 15-100 characters and at least one uppercase letter, one lowercase letter, one number, and one special character. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]_{|}~." type = string sensitive = true - default = null validation { - condition = var.ansible_vault_password == null ? true : (length(var.ansible_vault_password) >= 15 && length(var.ansible_vault_password) <= 100) + condition = (length(var.ansible_vault_password) >= 15 && length(var.ansible_vault_password) <= 100) error_message = "ansible_vault_password needs to be between 15 and 100 characters in length." } validation { - condition = var.ansible_vault_password == null ? true : can(regex("[A-Z]", var.ansible_vault_password)) + condition = can(regex("[A-Z]", var.ansible_vault_password)) error_message = "ansible_vault_password needs to contain at least one uppercase character (A-Z)." } validation { - condition = var.ansible_vault_password == null ? true : can(regex("[a-z]", var.ansible_vault_password)) + condition = can(regex("[a-z]", var.ansible_vault_password)) error_message = "ansible_vault_password needs to contain at least one lowercase character (a-z)." } validation { - condition = var.ansible_vault_password == null ? true : can(regex("[0-9]", var.ansible_vault_password)) + condition = can(regex("[0-9]", var.ansible_vault_password)) error_message = "ansible_vault_password needs to contain at least one number (0-9)." } validation { - condition = var.ansible_vault_password == null ? true : can(regex("[!#$%&()*+\\-.:;<=>?@[\\]_{|}~]", var.ansible_vault_password)) + condition = can(regex("[!#$%&()*+\\-.:;<=>?@[\\]_{|}~]", var.ansible_vault_password)) error_message = "ansible_vault_password needs to contain at least one of the following special characters: !#$%&()*+-.:;<=>?@[]_{|}~" } validation { - condition = var.ansible_vault_password == null ? true : can(regex("^[A-Za-z0-9!#$%&()*+\\-.:;<=>?@[\\]_{|}~]+$", var.ansible_vault_password)) + condition = can(regex("^[A-Za-z0-9!#$%&()*+\\-.:;<=>?@[\\]_{|}~]+$", var.ansible_vault_password)) error_message = "ansible_vault_password contains illegal characters. Allowed characters: A-Z, a-z, 0-9, !#$%&()*+-.:;<=>?@[]_{|}~" } } +variable "encrypt_playbook" { + description = "Whether to encrypt the playbook using ansible vault. The ocp configuration will always be encrypted, this only applies to the playbooks." + type = bool +} + variable "ibmcloud_api_key" { description = "IBM Cloud platform API key needed to deploy IAM enabled resources." type = string diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index e69ccc99..fabd2227 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -71,6 +71,7 @@ module "ocp_cluster_install_configuration" { ansible_host_or_ip = module.standard.ansible_host_or_ip ssh_private_key = var.ssh_private_key ansible_vault_password = var.ansible_vault_password + encrypt_playbook = true configure_ansible_host = false src_script_template_name = "deploy-openshift-cluster/ansible_exec_vault.sh.tftpl" @@ -120,6 +121,8 @@ module "ocp_cluster_manifest_creation" { bastion_host_ip = module.standard.access_host_or_ip ansible_host_or_ip = module.standard.ansible_host_or_ip ssh_private_key = var.ssh_private_key + ansible_vault_password = var.ansible_vault_password + encrypt_playbook = false configure_ansible_host = false ibmcloud_api_key = var.ibmcloud_api_key @@ -148,6 +151,8 @@ module "ocp_cluster_deployment" { bastion_host_ip = module.standard.access_host_or_ip ansible_host_or_ip = module.standard.ansible_host_or_ip ssh_private_key = var.ssh_private_key + ansible_vault_password = var.ansible_vault_password + encrypt_playbook = false configure_ansible_host = false ibmcloud_api_key = var.ibmcloud_api_key From 14ba28ac625ae233223fc488165b1404ba9f95fe Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 24 Sep 2025 16:09:20 +0200 Subject: [PATCH 71/83] fix: add encrypting to ansible exec scripts --- solutions/standard-openshift/ansible/main.tf | 24 +++++++++---------- .../ansible_exec.sh.tftpl | 4 ++++ .../ansible_exec_vault.sh.tftpl | 4 ++++ 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/solutions/standard-openshift/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf index 17b4cbb5..65ad48d9 100644 --- a/solutions/standard-openshift/ansible/main.tf +++ b/solutions/standard-openshift/ansible/main.tf @@ -123,8 +123,7 @@ resource "terraform_data" "execute_playbooks" { provisioner "remote-exec" { inline = [ "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file", - "rm -f password_file" + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file" ] } @@ -227,9 +226,7 @@ resource "terraform_data" "execute_playbooks_with_vault" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file", - "rm -f password_file" + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file" ] } @@ -241,23 +238,24 @@ resource "terraform_data" "execute_playbooks_with_vault" { ] } - # Again delete Ansible Vault password used to encrypt the var - # files with sensitive information and private ssh key + # Encrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "rm -rf password_file", - "rm -rf ${local.private_key_file}" + "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file", + "rm -f password_file" ] } - # Encrypt ocp config if it already exists + # Again delete Ansible Vault password used to encrypt the var + # files with sensitive information and private ssh key provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file", - "rm -f password_file" + "rm -rf password_file", + "rm -rf ${local.private_key_file}" ] } + } diff --git a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl index 7406db66..7519b832 100644 --- a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl +++ b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl @@ -24,8 +24,12 @@ export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" ## On failure: if [ $? -ne 0 ]; then + if [ -f "~/.powervs/config.json" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file + rm -f password_file rm -rf $${ansible_private_key_file} exit 1 fi echo \"Playbook command successful\" rm -rf $${ansible_private_key_file} +if [ -f "~/.powervs/config.json" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file +rm -f password_file diff --git a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl index f899fab5..9791229c 100644 --- a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl +++ b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl @@ -24,8 +24,12 @@ export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" --vault-password-file password_file ## On failure: if [ $? -ne 0 ]; then + if [ -f "~/.powervs/config.json" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file + rm -f password_file rm -rf $${ansible_private_key_file} exit 1 fi echo \"Playbook command successful\" rm -rf $${ansible_private_key_file} +if [ -f "~/.powervs/config.json" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file +rm -f password_file From 04c0b1c400b4b3857df395405b7615e8662d8b67 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Wed, 24 Sep 2025 17:40:09 +0200 Subject: [PATCH 72/83] fix: close if statements --- solutions/standard-openshift/ansible/main.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/solutions/standard-openshift/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf index 65ad48d9..325d056a 100644 --- a/solutions/standard-openshift/ansible/main.tf +++ b/solutions/standard-openshift/ansible/main.tf @@ -122,8 +122,8 @@ resource "terraform_data" "execute_playbooks" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file" + "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file; fi", + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file; fi" ] } @@ -145,8 +145,8 @@ resource "terraform_data" "execute_playbooks" { # Encrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file", + "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file; fi", + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file; fi", "rm -f password_file" ] } @@ -226,7 +226,7 @@ resource "terraform_data" "execute_playbooks_with_vault" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file" + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file; fi" ] } @@ -241,8 +241,8 @@ resource "terraform_data" "execute_playbooks_with_vault" { # Encrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file", + "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file; fi", + "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file; fi", "rm -f password_file" ] } From 5dfbb04fabed1b2ed0df73d2662ed084d19672b4 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 25 Sep 2025 12:43:17 +0200 Subject: [PATCH 73/83] fix: add check if file is already encrypted to prevent ansible vault from throwing an error --- solutions/standard-openshift/ansible/main.tf | 22 +++++++++++++------ .../ansible_exec.sh.tftpl | 4 ++-- .../ansible_exec_vault.sh.tftpl | 4 ++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/solutions/standard-openshift/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf index 325d056a..134633f8 100644 --- a/solutions/standard-openshift/ansible/main.tf +++ b/solutions/standard-openshift/ansible/main.tf @@ -122,8 +122,8 @@ resource "terraform_data" "execute_playbooks" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file; fi", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file; fi" + "if [ -f \"/root/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file; fi", + "if [ -f \"/root/.powervs/config.json\" ]; then ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file; fi" ] } @@ -145,8 +145,12 @@ resource "terraform_data" "execute_playbooks" { # Encrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file; fi", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file; fi", + "if [ -f \"/root/.powervs/config.json\" ]; then", + " if ! ( head -n 1 | grep -q '^\\$ANSIBLE_VAULT' ); then", + " echo ${var.ansible_vault_password} > password_file", + " ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file", + " fi", + "fi", "rm -f password_file" ] } @@ -226,7 +230,7 @@ resource "terraform_data" "execute_playbooks_with_vault" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault decrypt ~/.powervs/config.json --vault-password-file password_file; fi" + "if [ -f \"/root/.powervs/config.json\" ]; then ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file; fi" ] } @@ -241,8 +245,12 @@ resource "terraform_data" "execute_playbooks_with_vault" { # Encrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"~/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file; fi", - "if [ -f \"~/.powervs/config.json\" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file; fi", + "if [ -f \"/root/.powervs/config.json\" ]; then", + " if ! ( head -n 1 | grep -q '^\\$ANSIBLE_VAULT' ); then", + " echo ${var.ansible_vault_password} > password_file", + " ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file", + " fi", + "fi", "rm -f password_file" ] } diff --git a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl index 7519b832..8831cb76 100644 --- a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl +++ b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl @@ -24,12 +24,12 @@ export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" ## On failure: if [ $? -ne 0 ]; then - if [ -f "~/.powervs/config.json" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file + if [ -f "/root/.powervs/config.json" ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi rm -f password_file rm -rf $${ansible_private_key_file} exit 1 fi echo \"Playbook command successful\" rm -rf $${ansible_private_key_file} -if [ -f "~/.powervs/config.json" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file +if [ -f "/root/.powervs/config.json" ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi rm -f password_file diff --git a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl index 9791229c..c461f550 100644 --- a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl +++ b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl @@ -24,12 +24,12 @@ export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" --vault-password-file password_file ## On failure: if [ $? -ne 0 ]; then - if [ -f "~/.powervs/config.json" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file + if [ -f "/root/.powervs/config.json" ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi rm -f password_file rm -rf $${ansible_private_key_file} exit 1 fi echo \"Playbook command successful\" rm -rf $${ansible_private_key_file} -if [ -f "~/.powervs/config.json" ]; then ansible-vault encrypt ~/.powervs/config.json --vault-password-file password_file +if [ -f "/root/.powervs/config.json" ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi rm -f password_file From a3ce2a807d0860d47d76f55978053ac07a64262b Mon Sep 17 00:00:00 2001 From: Suraj Bharadwaj <101711050+surajsbharadwaj@users.noreply.github.com> Date: Thu, 25 Sep 2025 12:49:48 +0200 Subject: [PATCH 74/83] chore: include schematics IPs (#1159) Co-authored-by: ludwig-mueller --- .../presets/slz-preset.json.tftpl | 137 +++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/modules/powervs-vpc-landing-zone/presets/slz-preset.json.tftpl b/modules/powervs-vpc-landing-zone/presets/slz-preset.json.tftpl index 39f5cbc9..3b35533d 100644 --- a/modules/powervs-vpc-landing-zone/presets/slz-preset.json.tftpl +++ b/modules/powervs-vpc-landing-zone/presets/slz-preset.json.tftpl @@ -399,7 +399,7 @@ "port_min": 22 } }, - { + { "name": "allow-ssh-inbound-schematics28", "direction": "inbound", "source": "163.75.88.96/32", @@ -408,6 +408,141 @@ "port_min": 22 } }, + { + "name": "allow-ssh-inbound-schematics29", + "direction": "inbound", + "source": "52.117.126.44/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics30", + "direction": "inbound", + "source": "169.59.190.179/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics31", + "direction": "inbound", + "source": "169.63.103.233/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics32", + "direction": "inbound", + "source": "67.18.90.188/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics33", + "direction": "inbound", + "source": "52.116.193.125/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics34", + "direction": "inbound", + "source": "52.118.145.125/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics35", + "direction": "inbound", + "source": "158.176.179.166/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics36", + "direction": "inbound", + "source": "141.125.162.185/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics37", + "direction": "inbound", + "source": "158.175.188.210/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics38", + "direction": "inbound", + "source": "149.81.15.201/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics39", + "direction": "inbound", + "source": "158.176.1.26/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics40", + "direction": "inbound", + "source": "149.81.159.90/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics41", + "direction": "inbound", + "source": "64.5.41.76/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics42", + "direction": "inbound", + "source": "64.5.47.225/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, + { + "name": "allow-ssh-inbound-schematics43", + "direction": "inbound", + "source": "64.5.49.94/32", + "tcp": { + "port_max": 22, + "port_min": 22 + } + }, %{ if "${external_access_ip}" != "" && "${external_access_ip}" != null } { "direction": "inbound", From f879c5a02f0b1adabc9ede6c1ce3c184ab73f223 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 25 Sep 2025 12:52:50 +0200 Subject: [PATCH 75/83] feat: lon06 now support p10 --- solutions/standard-openshift/main.tf | 2 +- solutions/standard-plus-vsi/locals.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/main.tf b/solutions/standard-openshift/main.tf index fabd2227..083cee9c 100644 --- a/solutions/standard-openshift/main.tf +++ b/solutions/standard-openshift/main.tf @@ -19,7 +19,7 @@ locals { client_to_site_vpn = merge(var.client_to_site_vpn, { "powervs_server_routes" : local.powervs_server_routes }) # automatically pick the supported system type unless it's overwritten by the user - p10_unsupported_regions = ["che01", "lon04", "lon06", "mon01", "syd04", "syd05", "tor01", "us-east"] # datacenters that don't support P10 yet + p10_unsupported_regions = ["che01", "lon04", "mon01", "syd04", "syd05", "tor01", "us-east"] # datacenters that don't support P10 yet system_type = contains(local.p10_unsupported_regions, var.powervs_zone) ? "s922" : "s1022" cluster_master_node_config = var.cluster_master_node_config.system_type != null ? var.cluster_master_node_config : merge(var.cluster_master_node_config, { system_type : local.system_type }) diff --git a/solutions/standard-plus-vsi/locals.tf b/solutions/standard-plus-vsi/locals.tf index a5bcd243..c72bde16 100644 --- a/solutions/standard-plus-vsi/locals.tf +++ b/solutions/standard-plus-vsi/locals.tf @@ -3,7 +3,7 @@ ##################################################### locals { - p10_unsupported_regions = ["che01", "lon04", "lon06", "mon01", "syd04", "syd05", "tor01", "us-east"] # datacenters that don't support P10 yet + p10_unsupported_regions = ["che01", "lon04", "mon01", "syd04", "syd05", "tor01", "us-east"] # datacenters that don't support P10 yet server_type = contains(local.p10_unsupported_regions, var.powervs_zone) ? "s922" : "s1022" sap_profile_id = contains(local.p10_unsupported_regions, var.powervs_zone) ? "ush1-4x256" : "sh2-4x256" # sap_profile_id for P9 and P10 From 3579c230b7342ff8046ab55b8ff795c06292e21b Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 25 Sep 2025 13:24:29 +0200 Subject: [PATCH 76/83] fix: check if file is encrypted before decrypting --- solutions/standard-openshift/ansible/main.tf | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/solutions/standard-openshift/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf index 134633f8..8c29d000 100644 --- a/solutions/standard-openshift/ansible/main.tf +++ b/solutions/standard-openshift/ansible/main.tf @@ -122,8 +122,12 @@ resource "terraform_data" "execute_playbooks" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"/root/.powervs/config.json\" ]; then echo ${var.ansible_vault_password} > password_file; fi", - "if [ -f \"/root/.powervs/config.json\" ]; then ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file; fi" + "if [ -f \"/root/.powervs/config.json\" ]; then", + " if ! ( head -n 1 | grep -q '^\\$ANSIBLE_VAULT' ); then", + " echo ${var.ansible_vault_password} > password_file", + " ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file", + " fi", + "fi" ] } @@ -230,7 +234,11 @@ resource "terraform_data" "execute_playbooks_with_vault" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"/root/.powervs/config.json\" ]; then ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file; fi" + "if [ -f \"/root/.powervs/config.json\" ]; then", + " if ! ( head -n 1 | grep -q '^\\$ANSIBLE_VAULT' ); then", + " ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file", + " fi", + "fi" ] } From e5ad0b3b7df3f224f537171abbadced256d507cc Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 25 Sep 2025 14:18:08 +0200 Subject: [PATCH 77/83] fix: missing file name --- solutions/standard-openshift/ansible/main.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/solutions/standard-openshift/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf index 8c29d000..f6a1aacd 100644 --- a/solutions/standard-openshift/ansible/main.tf +++ b/solutions/standard-openshift/ansible/main.tf @@ -123,7 +123,7 @@ resource "terraform_data" "execute_playbooks" { provisioner "remote-exec" { inline = [ "if [ -f \"/root/.powervs/config.json\" ]; then", - " if ! ( head -n 1 | grep -q '^\\$ANSIBLE_VAULT' ); then", + " if ! ( head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT' ); then", " echo ${var.ansible_vault_password} > password_file", " ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file", " fi", @@ -150,7 +150,7 @@ resource "terraform_data" "execute_playbooks" { provisioner "remote-exec" { inline = [ "if [ -f \"/root/.powervs/config.json\" ]; then", - " if ! ( head -n 1 | grep -q '^\\$ANSIBLE_VAULT' ); then", + " if ! ( head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT' ); then", " echo ${var.ansible_vault_password} > password_file", " ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file", " fi", @@ -235,7 +235,7 @@ resource "terraform_data" "execute_playbooks_with_vault" { provisioner "remote-exec" { inline = [ "if [ -f \"/root/.powervs/config.json\" ]; then", - " if ! ( head -n 1 | grep -q '^\\$ANSIBLE_VAULT' ); then", + " if ! ( head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT' ); then", " ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file", " fi", "fi" @@ -254,7 +254,7 @@ resource "terraform_data" "execute_playbooks_with_vault" { provisioner "remote-exec" { inline = [ "if [ -f \"/root/.powervs/config.json\" ]; then", - " if ! ( head -n 1 | grep -q '^\\$ANSIBLE_VAULT' ); then", + " if ! ( head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT' ); then", " echo ${var.ansible_vault_password} > password_file", " ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file", " fi", From 3fb256f2044229aabde1d35079185e684c788121 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 25 Sep 2025 15:21:11 +0200 Subject: [PATCH 78/83] fix: logic error during decryption --- solutions/standard-openshift/ansible/main.tf | 15 +++++++++------ .../ansible_exec.sh.tftpl | 4 ++-- .../ansible_exec_vault.sh.tftpl | 4 ++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/solutions/standard-openshift/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf index f6a1aacd..724f63a3 100644 --- a/solutions/standard-openshift/ansible/main.tf +++ b/solutions/standard-openshift/ansible/main.tf @@ -122,8 +122,8 @@ resource "terraform_data" "execute_playbooks" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"/root/.powervs/config.json\" ]; then", - " if ! ( head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT' ); then", + "if [ -f /root/.powervs/config.json ]; then", + " if head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT'; then", " echo ${var.ansible_vault_password} > password_file", " ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file", " fi", @@ -132,10 +132,13 @@ resource "terraform_data" "execute_playbooks" { } # Execute bash shell script to run ansible playbooks + # create password file so the script can encrypt the ocp config provisioner "remote-exec" { inline = [ + "echo ${var.ansible_vault_password} > password_file", "chmod +x ${local.dst_script_file_path}", "export IBMCLOUD_API_KEY=${local.ibmcloud_api_key} && ${local.dst_script_file_path}", + "rm -f password_file" ] } @@ -149,7 +152,7 @@ resource "terraform_data" "execute_playbooks" { # Encrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"/root/.powervs/config.json\" ]; then", + "if [ -f /root/.powervs/config.json ]; then", " if ! ( head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT' ); then", " echo ${var.ansible_vault_password} > password_file", " ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file", @@ -234,8 +237,8 @@ resource "terraform_data" "execute_playbooks_with_vault" { # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"/root/.powervs/config.json\" ]; then", - " if ! ( head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT' ); then", + "if [ -f /root/.powervs/config.json ]; then", + " if head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT'; then", " ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file", " fi", "fi" @@ -253,7 +256,7 @@ resource "terraform_data" "execute_playbooks_with_vault" { # Encrypt ocp config if it already exists provisioner "remote-exec" { inline = [ - "if [ -f \"/root/.powervs/config.json\" ]; then", + "if [ -f /root/.powervs/config.json ]; then", " if ! ( head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT' ); then", " echo ${var.ansible_vault_password} > password_file", " ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file", diff --git a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl index 8831cb76..fde9d461 100644 --- a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl +++ b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec.sh.tftpl @@ -24,12 +24,12 @@ export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" ## On failure: if [ $? -ne 0 ]; then - if [ -f "/root/.powervs/config.json" ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi + if [ -f /root/.powervs/config.json ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi rm -f password_file rm -rf $${ansible_private_key_file} exit 1 fi echo \"Playbook command successful\" rm -rf $${ansible_private_key_file} -if [ -f "/root/.powervs/config.json" ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi +if [ -f /root/.powervs/config.json ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi rm -f password_file diff --git a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl index c461f550..0ff8637d 100644 --- a/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl +++ b/solutions/standard-openshift/ansible/templates-ansible/deploy-openshift-cluster/ansible_exec_vault.sh.tftpl @@ -24,12 +24,12 @@ export IBMCLOUD_API_KEY=$${IBMCLOUD_API_KEY} unbuffer ansible-playbook -i $${ansible_inventory} $${ansible_playbook} --extra-vars "IBMCLOUD_API_KEY=$IBMCLOUD_API_KEY" --vault-password-file password_file ## On failure: if [ $? -ne 0 ]; then - if [ -f "/root/.powervs/config.json" ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi + if [ -f /root/.powervs/config.json ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi rm -f password_file rm -rf $${ansible_private_key_file} exit 1 fi echo \"Playbook command successful\" rm -rf $${ansible_private_key_file} -if [ -f "/root/.powervs/config.json" ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi +if [ -f /root/.powervs/config.json ]; then ansible-vault encrypt /root/.powervs/config.json --vault-password-file password_file; fi rm -f password_file From 2302bf714db0177a0ea603b74d24a7b34705389e Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Thu, 25 Sep 2025 15:25:05 +0200 Subject: [PATCH 79/83] feat: upgrade instance module to 2.8.0 --- solutions/standard-plus-vsi/README.md | 2 +- solutions/standard-plus-vsi/main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-plus-vsi/README.md b/solutions/standard-plus-vsi/README.md index 728c9af9..5eeb7772 100644 --- a/solutions/standard-plus-vsi/README.md +++ b/solutions/standard-plus-vsi/README.md @@ -57,7 +57,7 @@ This example sets up the following infrastructure: |------|--------|---------| | [pi\_aix\_configure\_services](#module\_pi\_aix\_configure\_services) | ../../modules/powervs-vpc-landing-zone/submodules/ansible | n/a | | [pi\_scc\_wp\_agent](#module\_pi\_scc\_wp\_agent) | ../../modules/powervs-vpc-landing-zone/submodules/ansible | n/a | -| [powervs\_instance](#module\_powervs\_instance) | terraform-ibm-modules/powervs-instance/ibm | 2.7.0 | +| [powervs\_instance](#module\_powervs\_instance) | terraform-ibm-modules/powervs-instance/ibm | 2.8.0 | | [standard](#module\_standard) | ../../modules/powervs-vpc-landing-zone | n/a | ### Resources diff --git a/solutions/standard-plus-vsi/main.tf b/solutions/standard-plus-vsi/main.tf index a80ed0d1..c696048b 100644 --- a/solutions/standard-plus-vsi/main.tf +++ b/solutions/standard-plus-vsi/main.tf @@ -55,7 +55,7 @@ module "standard" { module "powervs_instance" { source = "terraform-ibm-modules/powervs-instance/ibm" - version = "2.7.0" + version = "2.8.0" providers = { ibm = ibm.ibm-pi } pi_workspace_guid = module.standard.powervs_workspace_guid From f33c78b59ce9c4d800a5ab1074cdaad2d5364d03 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 26 Sep 2025 09:26:04 +0200 Subject: [PATCH 80/83] fix: split password file creation and deletion to ensure terraform fails on playbook failure --- solutions/standard-openshift/README.md | 1 + solutions/standard-openshift/ansible/main.tf | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index 0455fcdc..bfb9be71 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -13,6 +13,7 @@ This example sets up an OpenShift Cluster on PowerVS following infrastructure: - KMS keys - Activity tracker - Optional Secrets Manager Instance Instance with private certificate. + - Three application load balancers for internal OpenShift API, public OpenShift API, and OpenShift applications - A local **transit gateway** - An IBM Cloud DNS Service Instance diff --git a/solutions/standard-openshift/ansible/main.tf b/solutions/standard-openshift/ansible/main.tf index 724f63a3..2a215b52 100644 --- a/solutions/standard-openshift/ansible/main.tf +++ b/solutions/standard-openshift/ansible/main.tf @@ -119,12 +119,16 @@ resource "terraform_data" "execute_playbooks" { ] } + # Create the vault password_file to be used for decryption and encryption of ocp config + provisioner "remote-exec" { + inline = ["echo ${var.ansible_vault_password} > password_file"] + } + # Decrypt ocp config if it already exists provisioner "remote-exec" { inline = [ "if [ -f /root/.powervs/config.json ]; then", " if head -n 1 /root/.powervs/config.json | grep -q '^$ANSIBLE_VAULT'; then", - " echo ${var.ansible_vault_password} > password_file", " ansible-vault decrypt /root/.powervs/config.json --vault-password-file password_file", " fi", "fi" @@ -135,13 +139,16 @@ resource "terraform_data" "execute_playbooks" { # create password file so the script can encrypt the ocp config provisioner "remote-exec" { inline = [ - "echo ${var.ansible_vault_password} > password_file", "chmod +x ${local.dst_script_file_path}", - "export IBMCLOUD_API_KEY=${local.ibmcloud_api_key} && ${local.dst_script_file_path}", - "rm -f password_file" + "export IBMCLOUD_API_KEY=${local.ibmcloud_api_key} && ${local.dst_script_file_path}" ] } + # Again delete the password_file + provisioner "remote-exec" { + inline = ["rm -f password_file"] + } + # Again delete private ssh key provisioner "remote-exec" { inline = [ From 6e72dde8b8e0caf1a0c16f73ffc68e8dd56b207e Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 26 Sep 2025 12:03:41 +0200 Subject: [PATCH 81/83] fix: upgrade instance module to 2.8.1 --- solutions/standard-plus-vsi/README.md | 2 +- solutions/standard-plus-vsi/main.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-plus-vsi/README.md b/solutions/standard-plus-vsi/README.md index 5eeb7772..fb4d273a 100644 --- a/solutions/standard-plus-vsi/README.md +++ b/solutions/standard-plus-vsi/README.md @@ -57,7 +57,7 @@ This example sets up the following infrastructure: |------|--------|---------| | [pi\_aix\_configure\_services](#module\_pi\_aix\_configure\_services) | ../../modules/powervs-vpc-landing-zone/submodules/ansible | n/a | | [pi\_scc\_wp\_agent](#module\_pi\_scc\_wp\_agent) | ../../modules/powervs-vpc-landing-zone/submodules/ansible | n/a | -| [powervs\_instance](#module\_powervs\_instance) | terraform-ibm-modules/powervs-instance/ibm | 2.8.0 | +| [powervs\_instance](#module\_powervs\_instance) | terraform-ibm-modules/powervs-instance/ibm | 2.8.1 | | [standard](#module\_standard) | ../../modules/powervs-vpc-landing-zone | n/a | ### Resources diff --git a/solutions/standard-plus-vsi/main.tf b/solutions/standard-plus-vsi/main.tf index c696048b..73c67e61 100644 --- a/solutions/standard-plus-vsi/main.tf +++ b/solutions/standard-plus-vsi/main.tf @@ -55,7 +55,7 @@ module "standard" { module "powervs_instance" { source = "terraform-ibm-modules/powervs-instance/ibm" - version = "2.8.0" + version = "2.8.1" providers = { ibm = ibm.ibm-pi } pi_workspace_guid = module.standard.powervs_workspace_guid From 4e3a67ef23a21c412af51baf5303ea8fa3a50b5c Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 26 Sep 2025 12:08:50 +0200 Subject: [PATCH 82/83] docs: add pull secret link --- solutions/standard-openshift/README.md | 2 +- solutions/standard-openshift/variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index bfb9be71..c08825e9 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -86,7 +86,7 @@ This example sets up an OpenShift Cluster on PowerVS following infrastructure: | [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud platform API key needed to deploy IAM enabled resources. | `string` | n/a | yes | | [intel\_user\_data](#input\_intel\_user\_data) | User data that automatically performs common configuration tasks or runs scripts only on the intel VSIs. For more information, see https://cloud.ibm.com/docs/vpc?topic=vpc-user-data. For information on using the user\_data variable, please refer: https://cloud.ibm.com/docs/secure-infrastructure-vpc?topic=secure-infrastructure-vpc-user-data | `string` | `null` | no | | [network\_services\_vsi\_profile](#input\_network\_services\_vsi\_profile) | Compute profile configuration of the network services vsi (cpu and memory configuration). Must be one of the supported profiles. See [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui). | `string` | `"cx2-2x4"` | no | -| [openshift\_pull\_secret](#input\_openshift\_pull\_secret) | Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries. | `map(any)` | n/a | yes | +| [openshift\_pull\_secret](#input\_openshift\_pull\_secret) | Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries. A RedHat account is required. It can be obtained on https://console.redhat.com/openshift/install/pull-secret. | `map(any)` | n/a | yes | | [openshift\_release](#input\_openshift\_release) | The OpenShift IPI release version to deploy. | `string` | `"4.19.5"` | no | | [powervs\_zone](#input\_powervs\_zone) | IBM Cloud data center location where IBM PowerVS infrastructure will be created. Supported regions are: dal10, dal12, eu-de-1, eu-de-2, lon04, lon06, mad02, mad04, osa21, sao01, sao04, syd04, syd05, us-east, us-south, wdc06, wdc07. | `string` | n/a | yes | | [sm\_service\_plan](#input\_sm\_service\_plan) | The service/pricing plan to use when provisioning a new Secrets Manager instance. Allowed values: `standard` and `trial`. Only used if `existing_sm_instance_guid` is set to null. | `string` | `"standard"` | no | diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index a6445861..53a4d602 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -29,7 +29,7 @@ variable "user_id" { } variable "openshift_pull_secret" { - description = "Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries." + description = "Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries. A RedHat account is required. It can be obtained on https://console.redhat.com/openshift/install/pull-secret." type = map(any) sensitive = true } From b086307e306b1274a14021bce04c2369439ab2c5 Mon Sep 17 00:00:00 2001 From: ludwig-mueller Date: Fri, 26 Sep 2025 15:57:57 +0200 Subject: [PATCH 83/83] chore(deps): update openshift release to 4.19.13 --- solutions/standard-openshift/README.md | 2 +- solutions/standard-openshift/variables.tf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/solutions/standard-openshift/README.md b/solutions/standard-openshift/README.md index c08825e9..e887c3b3 100644 --- a/solutions/standard-openshift/README.md +++ b/solutions/standard-openshift/README.md @@ -87,7 +87,7 @@ This example sets up an OpenShift Cluster on PowerVS following infrastructure: | [intel\_user\_data](#input\_intel\_user\_data) | User data that automatically performs common configuration tasks or runs scripts only on the intel VSIs. For more information, see https://cloud.ibm.com/docs/vpc?topic=vpc-user-data. For information on using the user\_data variable, please refer: https://cloud.ibm.com/docs/secure-infrastructure-vpc?topic=secure-infrastructure-vpc-user-data | `string` | `null` | no | | [network\_services\_vsi\_profile](#input\_network\_services\_vsi\_profile) | Compute profile configuration of the network services vsi (cpu and memory configuration). Must be one of the supported profiles. See [here](https://cloud.ibm.com/docs/vpc?topic=vpc-profiles&interface=ui). | `string` | `"cx2-2x4"` | no | | [openshift\_pull\_secret](#input\_openshift\_pull\_secret) | Pull secret from Red Hat OpenShift Cluster Manager for authenticating OpenShift image downloads from Red Hat container registries. A RedHat account is required. It can be obtained on https://console.redhat.com/openshift/install/pull-secret. | `map(any)` | n/a | yes | -| [openshift\_release](#input\_openshift\_release) | The OpenShift IPI release version to deploy. | `string` | `"4.19.5"` | no | +| [openshift\_release](#input\_openshift\_release) | The OpenShift IPI release version to deploy. | `string` | `"4.19.13"` | no | | [powervs\_zone](#input\_powervs\_zone) | IBM Cloud data center location where IBM PowerVS infrastructure will be created. Supported regions are: dal10, dal12, eu-de-1, eu-de-2, lon04, lon06, mad02, mad04, osa21, sao01, sao04, syd04, syd05, us-east, us-south, wdc06, wdc07. | `string` | n/a | yes | | [sm\_service\_plan](#input\_sm\_service\_plan) | The service/pricing plan to use when provisioning a new Secrets Manager instance. Allowed values: `standard` and `trial`. Only used if `existing_sm_instance_guid` is set to null. | `string` | `"standard"` | no | | [ssh\_private\_key](#input\_ssh\_private\_key) | Private SSH key (RSA format) to login to Intel VSIs to configure network management services (SQUID, NTP, DNS and ansible). Should match to public SSH key referenced by 'ssh\_public\_key'. The key is not uploaded or stored. For more information about SSH keys, see [SSH keys](https://cloud.ibm.com/docs/vpc?topic=vpc-ssh-keys). | `string` | n/a | yes | diff --git a/solutions/standard-openshift/variables.tf b/solutions/standard-openshift/variables.tf index 53a4d602..402d09ea 100644 --- a/solutions/standard-openshift/variables.tf +++ b/solutions/standard-openshift/variables.tf @@ -59,7 +59,7 @@ variable "cluster_base_domain" { variable "openshift_release" { description = "The OpenShift IPI release version to deploy." type = string - default = "4.19.5" + default = "4.19.13" } variable "cluster_network_config" {