diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index 3191d23d..eddebd0d 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -4,7 +4,7 @@ offerings: - name: deploy-arch-ibm-watsonx-self-managed kind: solution catalog_id: 7df1e4ca-d54c-4fd0-82ce-3d13247308cd - offering_id: 86425cf1-a763-4d17-9bb9-75276274a5f6 + offering_id: 3b9ffe49-80e7-417b-9179-a2882d3c2517 variations: - name: fully-configurable mark_ready: true diff --git a/.secrets.baseline b/.secrets.baseline index a472fcdf..d91df2dc 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-02-11T22:49:04Z", + "generated_at": "2025-06-27T16:17:07Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -76,7 +76,46 @@ "name": "TwilioKeyDetector" } ], - "results": {}, + "results": { + "README.md": [ + { + "hashed_secret": "bcf22dfc6fb76b7366b1f1675baf2332a0e6a7ce", + "is_secret": false, + "is_verified": false, + "line_number": 43, + "type": "Secret Keyword", + "verified_result": null + }, + { + "hashed_secret": "2254481e1661d8f017a712b0d1ad9a14fd9460a3", + "is_secret": false, + "is_verified": false, + "line_number": 105, + "type": "Secret Keyword", + "verified_result": null + } + ], + "modules/cpd-image-build/README.md": [ + { + "hashed_secret": "49901d945ad6da0f0af47691f305daf994d9d2c9", + "is_secret": false, + "is_verified": false, + "line_number": 11, + "type": "Secret Keyword", + "verified_result": null + } + ], + "solutions/fully-configurable/DA-types.md": [ + { + "hashed_secret": "fdd55a32cde0ab9bbb89037c7ab4203633cf5558", + "is_secret": false, + "is_verified": false, + "line_number": 21, + "type": "Secret Keyword", + "verified_result": null + } + ] + }, "version": "0.13.1+ibm.62.dss", "word_list": { "file": null, diff --git a/README.md b/README.md index 5f856618..9134b7d3 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,22 @@ Deploy Watsonx services on an existing Red Hat OpenShift cluster. - - +Cluster must meet the minimum requirements to deploy Cloud Pak for Data [Learn more](https://www.ibm.com/docs/en/cloud-paks/cp-data/5.1.x?topic=overview-cloud-pak-data). + +The following services are currently supported: +- watsonx.ai +- Watson Assistant +- Watson Discovery +- Watson Data + + ## Overview * [terraform-ibm-watsonx-self-managed-ocp](#terraform-ibm-watsonx-self-managed-ocp) * [Submodules](./modules) + * [cpd-image-build](./modules/cpd-image-build) * [Examples](./examples) * [Basic example](./examples/basic) * [Contributing](#contributing) @@ -35,19 +38,10 @@ module "watsonx_self_managed_ocp" { source = "terraform-ibm-modules/watsonx-self-managed-ocp/ibm" version = "X.X.X" # Replace "X.X.X" with a release version to lock into a specific release ibmcloud_api_key = "xxxxxxxxxxxxxxxxx" # pragma: allowlist secret - resource_group_id = "xxxxxxxxxxxxxxxxx" - region = "us-south" - prefix = "cp4d" cluster_name = "my-ocp-cluster" - cluster_rg_id = "xxxxxxxxxxxxxxxxx" - install_odf_cluster_addon = true - watsonx_ai_install = true - watsonx_data_install = true - watson_assistant_install = true - watson_discovery_install = true - cpd_admin_password = "Passw0rd!" # pragma: allowlist secret - cpd_entitlement_key = "entitlementKey" - # Add other configuration options as needed + cluster_resource_group_id = "xxxxxxxxxxxxxxxxx" + cpd_admin_password = "XXXXXXXX" + cpd_entitlement_key = "XXXXXXXX" } ``` @@ -59,15 +53,18 @@ You need the following permissions to run this module. * **All Resource Groups** service * `Viewer` platform access * IAM Services - * **Kubernetes Service** (OpenShift) + * **Kubernetes Service** * `Administrator` platform access * `Manager` service access * **VPC Infrastructure** * `Administrator` platform access * `Manager` service access - * **Container Registry** + * **Container Registry** (if building image) * `Administrator` platform access * `Manager` service access + * **Code Engine service** (if building image) + * `Editor` platform access + * `Writer` service access For more information on access and permissions, see [IBM Cloud IAM service roles and actions](https://cloud.ibm.com/docs/account?topic=account-iam-service-roles-actions). @@ -78,7 +75,7 @@ For more information on access and permissions, see [IBM Cloud IAM service roles | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.9.0 | -| [ibm](#requirement\_ibm) | >=1.79.1 | +| [ibm](#requirement\_ibm) | >=1.79.1, <2.0.0 | ### Modules @@ -101,28 +98,31 @@ For more information on access and permissions, see [IBM Cloud IAM service roles | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [cloud\_pak\_deployer\_image](#input\_cloud\_pak\_deployer\_image) | Cloud Pak Deployer image to use. If `null`, the image will be built using Code Engine. | `string` | `null` | no | -| [cloud\_pak\_deployer\_release](#input\_cloud\_pak\_deployer\_release) | Release of Cloud Pak Deployer version to use. View releases at: https://github.com/IBM/cloud-pak-deployer/releases. | `string` | `"v3.1.8"` | no | -| [cloud\_pak\_deployer\_secret](#input\_cloud\_pak\_deployer\_secret) | Secret for accessing the Cloud Pak Deployer image. If `null`, a default secret will be created # pragma: allowlist secret. |
object({
username = string
password = string
server = string
email = string
}) | `null` | no |
-| [cluster\_name](#input\_cluster\_name) | Name of Red Hat OpenShift cluster to install watsonx onto | `string` | n/a | yes |
-| [cluster\_rg\_id](#input\_cluster\_rg\_id) | Resource group id of the cluster | `string` | n/a | yes |
-| [code\_engine\_project\_id](#input\_code\_engine\_project\_id) | If you want to use an existing project, you can pass the code engine project ID and the Cloud Pak Deployer build will be built within the existing project instead of creating a new one. | `string` | `null` | no |
-| [code\_engine\_project\_name](#input\_code\_engine\_project\_name) | If `cloud_pak_deployer_image` is `null`, it will build the image with code engine and store it within a private ICR registry. Provide a name if you want to set the name. If not defined, default will be `{prefix}-cpd-{random-suffix}`. | `string` | `null` | no |
+| [add\_random\_suffix\_code\_engine\_project](#input\_add\_random\_suffix\_code\_engine\_project) | Whether to add a randomly generated 4-character suffix to the newly created Code Engine project. Only applies if `code_engine_project_id` is `null`. | `bool` | `true` | no |
+| [add\_random\_suffix\_icr\_namespace](#input\_add\_random\_suffix\_icr\_namespace) | Whether to add a randomly generated 4-character suffix to the newly created ICR namespace. | `bool` | `true` | no |
+| [cloud\_pak\_deployer\_image](#input\_cloud\_pak\_deployer\_image) | Cloud Pak Deployer image to use. If `null`, the image will be built using Code Engine and publish to a private Container Registry namespace. | `string` | `"quay.io/cloud-pak-deployer/cloud-pak-deployer:v3.1.8@sha256:e9cde204359a3014a3cee6a43c1e945a7dcb31d5fa92439326d4e5ab2191b48f"` | no |
+| [cloud\_pak\_deployer\_release](#input\_cloud\_pak\_deployer\_release) | The GIT release of Cloud Pak Deployer version to build from. Only applies if `cloud_pak_deployer_image` is `null`. View releases at: https://github.com/IBM/cloud-pak-deployer/releases. | `string` | `"v3.1.8"` | no |
+| [cloud\_pak\_deployer\_secret](#input\_cloud\_pak\_deployer\_secret) | Secret for accessing the Cloud Pak Deployer image. If `null`, a default secret will be created. | object({
username = string
password = string
server = string
email = string
}) | `null` | no |
+| [cluster\_name](#input\_cluster\_name) | Name of an existing Red Hat OpenShift cluster to install watsonX onto | `string` | n/a | yes |
+| [cluster\_resource\_group\_id](#input\_cluster\_resource\_group\_id) | The resource group ID of the cluster provided in `cluster_name` | `string` | n/a | yes |
+| [code\_engine\_project\_id](#input\_code\_engine\_project\_id) | If you want to use an existing project, you can pass the Code Engine project ID. Alternatively use `code_engine_project_name` to create a new project. Only applies if `cloud_pak_deployer_image` is `null`. | `string` | `null` | no |
+| [code\_engine\_project\_name](#input\_code\_engine\_project\_name) | The name of the Code Engine project to be created for the image build. Alternatively use `code_engine_project_id` to use existing project. Only applies if `cloud_pak_deployer_image` is `null`. If `add_random_suffix_code_engine_project` is set to true, a randomly generated 4-character suffix will be added to this value. | `string` | `"cpd"` | no |
+| [container\_registry\_namespace](#input\_container\_registry\_namespace) | The name of the Container Registry namespace to create. Only applies if `cloud_pak_deployer_image` is `null`. If `add_random_suffix_icr_namespace` is set to true, a randomly generated 4-character suffix will be added to this value. | `string` | `"cpd"` | no |
| [cpd\_accept\_license](#input\_cpd\_accept\_license) | When set to 'true', it is understood that the user has read the terms of the Cloud Pak license(s) and agrees to the terms outlined. | `bool` | `true` | no |
| [cpd\_admin\_password](#input\_cpd\_admin\_password) | Password for the Cloud Pak for Data admin user. | `string` | n/a | yes |
| [cpd\_entitlement\_key](#input\_cpd\_entitlement\_key) | Cloud Pak for Data entitlement key for access to the IBM Entitled Registry. Can be fetched from https://myibm.ibm.com/products-services/containerlibrary. | `string` | n/a | yes |
| [cpd\_version](#input\_cpd\_version) | Cloud Pak for Data version to install. Only version 5.x.x is supported, latest versions can be found [here](https://www.ibm.com/docs/en/cloud-paks/cp-data?topic=versions-cloud-pak-data). | `string` | `"5.0.3"` | no |
| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources. | `string` | n/a | yes |
-| [install\_odf\_cluster\_addon](#input\_install\_odf\_cluster\_addon) | Install the ODF cluster addon. | `bool` | `true` | no |
-| [odf\_config](#input\_odf\_config) | Configuration for the ODF addon. | `map(string)` | {
"addSingleReplicaPool": "false",
"billingType": "essentials",
"clusterEncryption": "false",
"disableNoobaaLB": "false",
"enableNFS": "false",
"encryptionInTransit": "false",
"hpcsBaseUrl": "",
"hpcsEncryption": "false",
"hpcsInstanceId": "",
"hpcsSecretName": "",
"hpcsServiceName": "",
"hpcsTokenUrl": "",
"ignoreNoobaa": "true",
"numOfOsd": "1",
"ocsUpgrade": "false",
"odfDeploy": "true",
"osdDevicePaths": "",
"osdSize": "512Gi",
"osdStorageClassName": "ibmc-vpc-block-metro-10iops-tier",
"prepareForDisasterRecovery": "false",
"resourceProfile": "balanced",
"taintNodes": "false",
"useCephRBDAsDefaultStorageClass": "false",
"workerNodes": "all",
"workerPool": ""
} | no |
-| [odf\_version](#input\_odf\_version) | Version of ODF to install. | `string` | `"4.16.0"` | no |
-| [prefix](#input\_prefix) | A unique identifier for resources that is prepended to resources that are provisioned. Must begin with a lowercase letter and end with a lowercase letter or number. Must be 16 or fewer characters. | `string` | `null` | no |
-| [region](#input\_region) | Region where resources will be created. To find your VPC region, use `ibmcloud is regions` command to find available regions. | `string` | n/a | yes |
-| [resource\_group](#input\_resource\_group) | Resource group to provision services within. If not defined, a resource group called `{prefix}-cpd` will be created. | `string` | `null` | no |
+| [install\_odf\_cluster\_addon](#input\_install\_odf\_cluster\_addon) | Install the ODF cluster add-on. | `bool` | `true` | no |
+| [odf\_config](#input\_odf\_config) | Configuration for the ODF addon. Only applies if `install_odf_cluster_addon` is true. | `map(string)` | {
"addSingleReplicaPool": "false",
"billingType": "essentials",
"clusterEncryption": "false",
"disableNoobaaLB": "false",
"enableNFS": "false",
"encryptionInTransit": "false",
"hpcsBaseUrl": "",
"hpcsEncryption": "false",
"hpcsInstanceId": "",
"hpcsSecretName": "",
"hpcsServiceName": "",
"hpcsTokenUrl": "",
"ignoreNoobaa": "true",
"numOfOsd": "1",
"ocsUpgrade": "false",
"odfDeploy": "true",
"osdDevicePaths": "",
"osdSize": "512Gi",
"osdStorageClassName": "ibmc-vpc-block-metro-10iops-tier",
"prepareForDisasterRecovery": "false",
"resourceProfile": "balanced",
"taintNodes": "false",
"useCephRBDAsDefaultStorageClass": "false",
"workerNodes": "all",
"workerPool": ""
} | no |
+| [odf\_version](#input\_odf\_version) | Version of OpenShift Data Foundation (ODF) add-on to install. Only applies if `install_odf_cluster_addon` is true. | `string` | `"4.16.0"` | no |
+| [region](#input\_region) | Region where Code Engine and Container Registry resources will be provisioned. Only applies if `cloud_pak_deployer_image` is `null`. To use the 'Global' Container Registry location set `use_global_container_registry_location` to true. | `string` | `"us-south"` | no |
+| [resource\_group\_id](#input\_resource\_group\_id) | The ID of the resource group where Code Engine and Container Registry resources will be provisioned. Only applies if `cloud_pak_deployer_image` is `null`. If not set, Default resource group will be used. | `string` | `null` | no |
+| [use\_global\_container\_registry\_location](#input\_use\_global\_container\_registry\_location) | Set to true to create the Container Registry namespace in the 'Global' location. If set to false, the namespace will be created in the region provided in the `region` input value. Only applies if `cloud_pak_deployer_image` is `null`. | `bool` | `false` | no |
| [watson\_assistant\_install](#input\_watson\_assistant\_install) | If watsonx.ai is being installed, also install watson assistant | `bool` | `false` | no |
| [watson\_discovery\_install](#input\_watson\_discovery\_install) | If watsonx.ai is being installed, also install watson discovery | `bool` | `false` | no |
| [watsonx\_ai\_install](#input\_watsonx\_ai\_install) | Determine whether the watsonx.ai cartridge for the deployer will be installed | `bool` | `false` | no |
-| [watsonx\_ai\_models](#input\_watsonx\_ai\_models) | List of watsonx.ai models to install. Information on the foundation models including pre-reqs can be found here - https://www.ibm.com/docs/en/cloud-paks/cp-data/5.0.x?topic=install-foundation-models. Use the ModelID as input | `list(string)` | [| no | +| [watsonx\_ai\_models](#input\_watsonx\_ai\_models) | List of watsonx.ai models to install. Information on the foundation models including pre-reqs can be found here - https://www.ibm.com/docs/en/cloud-paks/cp-data/5.0.x?topic=install-foundation-models. Use the ModelID as input | `list(string)` |
"ibm-granite-13b-instruct-v2"
]
[| no | | [watsonx\_data\_install](#input\_watsonx\_data\_install) | Determine whether the watsonx.data cartridge for the deployer will be installed | `bool` | `false` | no | ### Outputs diff --git a/examples/basic/main.tf b/examples/basic/main.tf index f80bf129..afc39754 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -1,8 +1,10 @@ ############################################################################## +# Locals +############################################################################## + locals { cluster_name = var.existing_cluster_name != null ? var.existing_cluster_name : module.ocp_base[0].cluster_name } -############################################################################### ############################################################################## # Resource Group @@ -93,7 +95,7 @@ module "ocp_base" { vpc_id = ibm_is_vpc.vpc.id vpc_subnets = local.cluster_vpc_subnets worker_pools = local.worker_pools - disable_outbound_traffic_protection = true # set as True to enable outbound traffic + disable_outbound_traffic_protection = true # set as True to enable outbound traffic to allow image to be pulled from quay.io } ############################################################################## @@ -103,13 +105,9 @@ module "ocp_base" { module "watsonx_self_managed_ocp" { source = "../.." ibmcloud_api_key = var.ibmcloud_api_key - prefix = var.prefix region = var.region cluster_name = local.cluster_name - cluster_rg_id = module.resource_group.resource_group_id - cloud_pak_deployer_image = "quay.io/cloud-pak-deployer/cloud-pak-deployer" - cpd_admin_password = "Passw0rd" #pragma: allowlist secret - cpd_entitlement_key = "entitlementKey" - install_odf_cluster_addon = var.install_odf_cluster_addon - watsonx_ai_install = false + cluster_resource_group_id = module.resource_group.resource_group_id + cpd_admin_password = var.cpd_admin_password + cpd_entitlement_key = var.cpd_entitlement_key } diff --git a/examples/basic/variables.tf b/examples/basic/variables.tf index 1ae18a75..973d3bf2 100644 --- a/examples/basic/variables.tf +++ b/examples/basic/variables.tf @@ -31,12 +31,6 @@ variable "resource_tags" { default = [] } -variable "install_odf_cluster_addon" { - description = "Install the odf cluster addon" - type = bool - default = false -} - variable "existing_cluster_name" { description = "Existing cluster name" type = string @@ -44,7 +38,19 @@ variable "existing_cluster_name" { } variable "resource_group" { - description = "Existing resource group name" type = string + description = "The name of an existing resource group to provision resources in to. If not set a new resource group will be created using the prefix variable." default = null } + +variable "cpd_admin_password" { + description = "Password for the Cloud Pak for Data admin user." + sensitive = true + type = string +} + +variable "cpd_entitlement_key" { + description = "Cloud Pak for Data entitlement key for access to the IBM Entitled Registry. Can be fetched from https://myibm.ibm.com/products-services/containerlibrary." + sensitive = true + type = string +} diff --git a/ibm_catalog.json b/ibm_catalog.json index 7acaba6e..d11460a0 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1,7 +1,7 @@ { "products": [ { - "label": "Watsonx (Self-Managed) on Red Hat OpenShift", + "label": "watsonx self-managed on Red Hat OpenShift", "name": "deploy-arch-ibm-watsonx-self-managed", "product_kind": "solution", "tags": [ @@ -28,6 +28,7 @@ "long_description": "Solution that deploys Watsonx services (watsonx.ai, watsonx.data, Watson Assistant, Watson Discovery) on an existing Red Hat OpenShift cluster.", "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-watsonx-self-managed-ocp/blob/main/solutions/fully-configurable/README.md", "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-watsonx-self-managed-ocp/main/images/watsonx-self-managed-ocp.svg", + "support_details": "This product is in the community registry, as such support is handled through the originated repo. If you experience issues please open an issue in the following [issues repository](https://github.com/terraform-ibm-modules/terraform-ibm-watsonx-self-managed-ocp/issues). Please note this product is not supported via the IBM Cloud Support Center.", "features": [ { "title": "Flexible Cluster Deployment", @@ -52,23 +53,41 @@ "name": "fully-configurable", "working_directory": "solutions/fully-configurable", "iam_permissions": [ + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Viewer" + ], + "service_name": "Resource group only", + "notes": "Viewer access is required in the resource group you want to provision in." + }, { "service_name": "containers-kubernetes", "role_crns": [ "crn:v1:bluemix:public:iam::::serviceRole:Manager", "crn:v1:bluemix:public:iam::::role:Viewer" ] + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "codeengine", + "notes": "[Optional] Required if building image." + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "container-registry", + "notes": "[Optional] Required if building image." } ], "architecture": { "features": [ { - "title": "Cluster must meet minimum requirements to install any Watson services you wish to add.", - "description": "Yes" - }, - { - "title": "Deploys Watsonx services on an existing cluster.", - "description": "Yes" + "title": " ", + "description": "Configured to use IBM secure by default standards, but can be edited to fit your use case." } ], "diagrams": [ @@ -92,29 +111,27 @@ "required": true }, { - "key": "region", - "required": true - }, - { - "key": "existing_cluster_name", - "required": true + "key": "existing_cluster_id", + "display_name": "existing_cluster", + "required": true, + "custom_config": { + "type": "cluster_var", + "grouping": "deployment", + "original_grouping": "deployment" + } }, { - "key": "existing_resource_group_name", + "key": "existing_cluster_resource_group_name", "custom_config": { "type": "resource_group", "grouping": "deployment", "original_grouping": "deployment", "config_constraints": { - "identifier": "rg_id" + "identifier": "rg_name" } }, "required": true }, - { - "key": "install_odf_cluster_addon", - "required": true - }, { "key": "cpd_entitlement_key", "required": true @@ -139,6 +156,18 @@ "key": "watson_assistant_install", "required": true }, + { + "key": "cpd_accept_license" + }, + { + "key": "cpd_admin_password" + }, + { + "key": "cpd_version" + }, + { + "key": "cloud_pak_deployer_image" + }, { "key": "code_engine_project_name" }, @@ -146,28 +175,43 @@ "key": "code_engine_project_id" }, { - "key": "cloud_pak_deployer_image" + "key": "existing_resource_group_name", + "custom_config": { + "type": "resource_group", + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "identifier": "rg_name" + } + } }, { - "key": "cloud_pak_deployer_release" + "key": "container_registry_namespace" }, { - "key": "cloud_pak_deployer_secret" + "key": "region" }, { - "key": "odf_version" + "key": "use_global_container_registry_location" }, { - "key": "odf_config" + "key": "cloud_pak_deployer_release" }, { - "key": "cpd_accept_license" + "key": "cloud_pak_deployer_secret" }, { - "key": "cpd_admin_password" + "key": "install_odf_cluster_addon" }, { - "key": "cpd_version" + "key": "odf_version" + }, + { + "key": "odf_config" + }, + { + "key": "provider_visibility", + "hidden": true } ], "install_type": "fullstack" diff --git a/main.tf b/main.tf index 1246b1fd..e3a279df 100644 --- a/main.tf +++ b/main.tf @@ -1,29 +1,31 @@ -locals { - openshift_version = join(".", slice(split(".", data.ibm_container_vpc_cluster.cluster_info.kube_version), 0, 2)) # Only use major and minor — no patch -} - -# Retrieve the openshift cluster info -data "ibm_container_vpc_cluster" "cluster_info" { - name = var.cluster_name - resource_group_id = var.cluster_rg_id -} +############################################################################## +# Build the image in Code Engine if one is not passed and publish to ICR +############################################################################## module "build_cpd_image" { - count = var.cloud_pak_deployer_image == null ? 1 : 0 - source = "./modules/cpd-image-build" - prefix = var.prefix - ibmcloud_api_key = var.ibmcloud_api_key - region = var.region - code_engine_project_name = var.code_engine_project_name - code_engine_project_id = var.code_engine_project_id - resource_group = var.resource_group - cloud_pak_deployer_release = var.cloud_pak_deployer_release + count = var.cloud_pak_deployer_image == null ? 1 : 0 + source = "./modules/cpd-image-build" + ibmcloud_api_key = var.ibmcloud_api_key + region = var.region + code_engine_project_name = var.code_engine_project_name + code_engine_project_id = var.code_engine_project_id + resource_group_id = var.resource_group_id + use_global_container_registry_location = var.use_global_container_registry_location + cloud_pak_deployer_release = var.cloud_pak_deployer_release + container_registry_namespace = var.container_registry_namespace + add_random_suffix_icr_namespace = var.add_random_suffix_icr_namespace + add_random_suffix_code_engine_project = var.add_random_suffix_code_engine_project } +############################################################################## +# Install OCP ODF cluster addon +############################################################################## + resource "ibm_container_addons" "odf_cluster_addon" { count = var.install_odf_cluster_addon ? 1 : 0 cluster = var.cluster_name manage_all_addons = false + resource_group_id = var.cluster_resource_group_id addons { name = "openshift-data-foundation" version = var.odf_version @@ -31,6 +33,10 @@ resource "ibm_container_addons" "odf_cluster_addon" { } } +############################################################################## +# watsonx-ai +############################################################################## + module "watsonx_ai" { source = "./modules/watsonx-ai" depends_on = [ibm_container_addons.odf_cluster_addon] @@ -40,12 +46,20 @@ module "watsonx_ai" { watsonx_ai_models = var.watsonx_ai_models } +############################################################################## +# watsonx-data +############################################################################## + module "watsonx_data" { source = "./modules/watsonx-data" depends_on = [ibm_container_addons.odf_cluster_addon] watsonx_data_install = var.watsonx_data_install } +############################################################################## +# Cloud Pak deployer +############################################################################## + module "cloud_pak_deployer" { depends_on = [ module.watsonx_ai, @@ -79,6 +93,15 @@ module "cloud_pak_deployer" { cpd_entitlement_key = var.cpd_entitlement_key } +# Retrieve the openshift cluster info +data "ibm_container_vpc_cluster" "cluster_info" { + name = var.cluster_name + resource_group_id = var.cluster_resource_group_id +} +locals { + openshift_version = join(".", slice(split(".", data.ibm_container_vpc_cluster.cluster_info.kube_version), 0, 2)) # Only use major and minor — no patch +} + # Cloud Pak Deployer configuration file local variable(s) only module "config" { source = "./modules/cloud-pak-deployer/config" diff --git a/modules/cloud-pak-deployer/.secrets.baseline b/modules/cloud-pak-deployer/.secrets.baseline deleted file mode 100644 index d9d7acb7..00000000 --- a/modules/cloud-pak-deployer/.secrets.baseline +++ /dev/null @@ -1,85 +0,0 @@ -{ - "exclude": { - "files": "^.secrets.baseline$", - "lines": null - }, - "generated_at": "2024-12-20T20:40:41Z", - "plugins_used": [ - { - "name": "AWSKeyDetector" - }, - { - "name": "ArtifactoryDetector" - }, - { - "name": "AzureStorageKeyDetector" - }, - { - "base64_limit": 4.5, - "name": "Base64HighEntropyString" - }, - { - "name": "BasicAuthDetector" - }, - { - "name": "BoxDetector" - }, - { - "name": "CloudantDetector" - }, - { - "ghe_instance": "github.ibm.com", - "name": "GheDetector" - }, - { - "name": "GitHubTokenDetector" - }, - { - "hex_limit": 3, - "name": "HexHighEntropyString" - }, - { - "name": "IbmCloudIamDetector" - }, - { - "name": "IbmCosHmacDetector" - }, - { - "name": "JwtTokenDetector" - }, - { - "keyword_exclude": null, - "name": "KeywordDetector" - }, - { - "name": "MailchimpDetector" - }, - { - "name": "NpmDetector" - }, - { - "name": "PrivateKeyDetector" - }, - { - "name": "SlackDetector" - }, - { - "name": "SoftlayerDetector" - }, - { - "name": "SquareOAuthDetector" - }, - { - "name": "StripeDetector" - }, - { - "name": "TwilioKeyDetector" - } - ], - "results": {}, - "version": "0.13.1+ibm.62.dss", - "word_list": { - "file": null, - "hash": null - } -} diff --git a/modules/cloud-pak-deployer/version.tf b/modules/cloud-pak-deployer/version.tf index 01abebb5..eb3da515 100644 --- a/modules/cloud-pak-deployer/version.tf +++ b/modules/cloud-pak-deployer/version.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.2.0" + required_version = ">= 1.9.0" required_providers { helm = { source = "hashicorp/helm" diff --git a/modules/cpd-image-build/README.md b/modules/cpd-image-build/README.md new file mode 100644 index 00000000..9c3a8619 --- /dev/null +++ b/modules/cpd-image-build/README.md @@ -0,0 +1,70 @@ +# Cloud Pak Data (CPD) image build module + +A module to build and publish the Cloud Pak Data (CPD) image to container registry. + +### Usage + +```hcl +module "build_image" { + source = "terraform-ibm-modules/watsonx-self-managed-ocp/ibm//modules/cpd-image-build" + version = "X.Y.Z" # Replace "X.Y.Z" with a release version to lock into a specific release + ibmcloud_api_key = "XXXXXXXXXXXX" # replace with apikey value + region = "us-south + resource_group_id = "xxXXxxXXxXxXXXXxxXxxxXXXXxXXXXX" # replace with resource group ID + container_registry_namespace = "my-namespace" + code_engine_project_name = "my-project" +} +``` + + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.9.0 | +| [ibm](#requirement\_ibm) | >=1.79.1, <2.0.0 | +| [random](#requirement\_random) | >= 3.4.3, < 4.0.0 | +| [shell](#requirement\_shell) | >= 1.7.10, <2.0.0 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| [code\_engine](#module\_code\_engine) | terraform-ibm-modules/code-engine/ibm | 4.4.1 | +| [code\_engine\_build](#module\_code\_engine\_build) | terraform-ibm-modules/code-engine/ibm//modules/build | 4.4.1 | + +### Resources + +| Name | Type | +|------|------| +| [ibm_cr_namespace.cr_namespace](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/resources/cr_namespace) | resource | +| [random_string.random](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string) | resource | +| [shell_script.build_run](https://registry.terraform.io/providers/scottwinkler/shell/latest/docs/resources/script) | resource | +| [ibm_code_engine_project.code_engine_project](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/data-sources/code_engine_project) | data source | +| [ibm_resource_group.group](https://registry.terraform.io/providers/ibm-cloud/ibm/latest/docs/data-sources/resource_group) | data source | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [add\_random\_suffix\_code\_engine\_project](#input\_add\_random\_suffix\_code\_engine\_project) | Whether to add a randomly generated 4-character suffix to the newly created Code Engine project. Only applies if `code_engine_project_id` is `null`. | `bool` | `true` | no | +| [add\_random\_suffix\_icr\_namespace](#input\_add\_random\_suffix\_icr\_namespace) | Whether to add a randomly generated 4-character suffix to the newly created ICR namespace. | `bool` | `true` | no | +| [cloud\_pak\_deployer\_release](#input\_cloud\_pak\_deployer\_release) | The GIT release of Cloud Pak Deployer version to build from. View releases at: https://github.com/IBM/cloud-pak-deployer/releases. | `string` | `"v3.1.8"` | no | +| [code\_engine\_project\_id](#input\_code\_engine\_project\_id) | If you want to use an existing project, you can pass the Code Engine project ID. Alternatively use `code_engine_project_name` to create a new project. | `string` | `null` | no | +| [code\_engine\_project\_name](#input\_code\_engine\_project\_name) | The name of the Code Engine project to be created for the image build. Alternatively use `code_engine_project_id` to use existing project. If `add_random_suffix_code_engine_project` is set to true, a randomly generated 4-character suffix will be added to this value. | `string` | `"cpd"` | no | +| [container\_registry\_namespace](#input\_container\_registry\_namespace) | The name of the Container Registry namespace to create. If `add_random_suffix_icr_namespace` is set to true, a randomly generated 4-character suffix will be added to this value. | `string` | `"cpd"` | no | +| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources. | `string` | n/a | yes | +| [region](#input\_region) | Region where Code Engine and Container Registry resources will be provisioned. To use the 'Global' Container Registry location set `use_global_container_registry_location` to true. | `string` | `"us-south"` | no | +| [resource\_group\_id](#input\_resource\_group\_id) | The ID of the resource group to create resource in. If not set, Default resource group will be used. | `string` | `null` | no | +| [use\_global\_container\_registry\_location](#input\_use\_global\_container\_registry\_location) | Set to true to create the Container Registry namespace in the 'Global' location. If set to false, the namespace will be created in the region provided in the `region` input value. | `bool` | `false` | no | + +### Outputs + +| Name | Description | +|------|-------------| +| [code\_engine\_project\_id](#output\_code\_engine\_project\_id) | The ID of the code engine project that used | +| [code\_engine\_project\_name](#output\_code\_engine\_project\_name) | The name of the code engine project that was used | +| [container\_registry\_namespace](#output\_container\_registry\_namespace) | The name of the container registry namespace | +| [container\_registry\_output\_image](#output\_container\_registry\_output\_image) | The path to the cpd container that was built | +| [container\_registry\_server](#output\_container\_registry\_server) | The url of the container registry | + diff --git a/modules/cpd-image-build/main.tf b/modules/cpd-image-build/main.tf index bf7aaea4..405c5bb6 100644 --- a/modules/cpd-image-build/main.tf +++ b/modules/cpd-image-build/main.tf @@ -1,12 +1,17 @@ -locals { - resource_group_name = var.resource_group == null ? "${var.prefix}-cpd" : var.resource_group - - container_registry_namespace = var.container_registry_namespace != null ? var.container_registry_namespace : "${var.prefix}-cpd-${random_string.random.result}" - container_registry_server = lookup(local.registry_server_map, var.region, null) != null ? local.registry_server_map[var.region] : "private.icr.io" - container_registry_output_image = "${local.container_registry_server}/${local.container_registry_namespace}/deployer:${var.cloud_pak_deployer_release}" +############################################################################## +# Locals +############################################################################## - code_engine_project_name = var.code_engine_project_name != null ? var.code_engine_project_name : "${var.prefix}-cpd-${random_string.random.result}" +data "ibm_resource_group" "group" { + count = var.resource_group_id == null ? 1 : 0 + is_default = "true" +} +locals { + resource_group_id = var.resource_group_id == null ? data.ibm_resource_group.group[0].id : var.resource_group_id + container_registry_server = var.use_global_container_registry_location ? "private.icr.io" : lookup(local.registry_server_map, var.region, null) != null ? local.registry_server_map[var.region] : "private.icr.io" + container_registry_output_image = "${local.container_registry_server}/${var.container_registry_namespace}/deployer:${var.cloud_pak_deployer_release}" + container_registry_namespace_name = var.add_random_suffix_icr_namespace ? "${var.container_registry_namespace}-${random_string.random[0].result}" : var.container_registry_namespace registry_server_map = { au-syd = "private.au.icr.io" br-sao = "private.br.icr.io" @@ -17,52 +22,45 @@ locals { eu-gb = "private.uk.icr.io" us-south = "private.us.icr.io" } - - resource_group_id = var.code_engine_project_id != null ? data.ibm_code_engine_project.code_engine_project[0].resource_group_id : module.resource_group[0].resource_group_id + ce_project_name = var.code_engine_project_name != null ? var.add_random_suffix_code_engine_project ? "${var.code_engine_project_name}-${random_string.random[0].result}" : var.code_engine_project_name : data.ibm_code_engine_project.code_engine_project[0].name } ############################################################################## # Generate a random seed since some resources need unique names ############################################################################## + resource "random_string" "random" { - length = 8 + count = var.add_random_suffix_icr_namespace || var.add_random_suffix_code_engine_project ? 1 : 0 + length = 4 lower = true upper = false special = false } -data "ibm_code_engine_project" "code_engine_project" { - count = var.code_engine_project_id != null ? 1 : 0 - project_id = var.code_engine_project_id -} - -module "resource_group" { - count = var.code_engine_project_id == null ? 1 : 0 - source = "terraform-ibm-modules/resource-group/ibm" - version = "1.2.1" - - # if an existing resource group is not set (null) create a new one using prefix - resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null - existing_resource_group_name = var.resource_group -} - ############################################################################## -# Container registry resources +# Container registry namespace ############################################################################## + resource "ibm_cr_namespace" "cr_namespace" { - name = local.container_registry_namespace + name = local.container_registry_namespace_name resource_group_id = local.resource_group_id } ############################################################################## # Code engine resources ############################################################################## + +data "ibm_code_engine_project" "code_engine_project" { + count = var.code_engine_project_id != null ? 1 : 0 + project_id = var.code_engine_project_id +} + module "code_engine" { source = "terraform-ibm-modules/code-engine/ibm" version = "4.4.1" - project_name = var.code_engine_project_id == null ? local.code_engine_project_name : null + project_name = var.code_engine_project_id == null ? var.code_engine_project_name : null existing_project_id = var.code_engine_project_id - resource_group_id = local.resource_group_id + resource_group_id = var.code_engine_project_id != null ? data.ibm_code_engine_project.code_engine_project[0].resource_group_id : local.resource_group_id secrets = { "registry-secret" = { format = "registry" diff --git a/modules/cpd-image-build/outputs.tf b/modules/cpd-image-build/outputs.tf index afd18f60..6535b0aa 100644 --- a/modules/cpd-image-build/outputs.tf +++ b/modules/cpd-image-build/outputs.tf @@ -1,11 +1,6 @@ -output "resource_group" { - description = "The resource group that was used for the resources within" - value = local.resource_group_name -} - output "container_registry_namespace" { description = "The name of the container registry namespace" - value = local.container_registry_namespace + value = ibm_cr_namespace.cr_namespace.name } output "container_registry_server" { @@ -19,6 +14,11 @@ output "container_registry_output_image" { } output "code_engine_project_name" { - description = "The name of the code engine project that was created" - value = local.code_engine_project_name + description = "The name of the code engine project that was used" + value = local.ce_project_name +} + +output "code_engine_project_id" { + description = "The ID of the code engine project that used" + value = module.code_engine.project_id } diff --git a/modules/cpd-image-build/variables.tf b/modules/cpd-image-build/variables.tf index 4c0c2acc..3ea23988 100644 --- a/modules/cpd-image-build/variables.tf +++ b/modules/cpd-image-build/variables.tf @@ -4,46 +4,60 @@ variable "ibmcloud_api_key" { sensitive = true } -variable "prefix" { - description = "The value that you would like to prefix to the name of the resources provisioned by this module. Explicitly set to null if you do not wish to use a prefix. This value is ignored if using one of the optional variables for explicit control over naming." - type = string - default = null -} - variable "region" { - description = "Region where resources will be provisioned" + description = "Region where Code Engine and Container Registry resources will be provisioned. To use the 'Global' Container Registry location set `use_global_container_registry_location` to true." type = string + default = "us-south" } -variable "resource_group" { - description = "Resource groups to create or reference" +variable "resource_group_id" { type = string + description = "The ID of the resource group to create resource in. If not set, Default resource group will be used." + default = null +} - default = null +variable "use_global_container_registry_location" { + description = "Set to true to create the Container Registry namespace in the 'Global' location. If set to false, the namespace will be created in the region provided in the `region` input value." + type = bool + default = false } variable "container_registry_namespace" { - description = "The name of the container registry namespace" + description = "The name of the Container Registry namespace to create. If `add_random_suffix_icr_namespace` is set to true, a randomly generated 4-character suffix will be added to this value." type = string - - default = null + default = "cpd" } variable "code_engine_project_name" { - description = "The name of the code engine project to be created for the image build" + description = "The name of the Code Engine project to be created for the image build. Alternatively use `code_engine_project_id` to use existing project. If `add_random_suffix_code_engine_project` is set to true, a randomly generated 4-character suffix will be added to this value." type = string - - default = null + default = "cpd" + validation { + condition = var.code_engine_project_name == null ? var.code_engine_project_id != null : true + error_message = "A value must be passed for either 'code_engine_project_name' (to create new project) or 'code_engine_project_id' (to use existing project)." + } } variable "code_engine_project_id" { - description = "If you want to use an existing project, you can pass the code engine project id vs a new project being created." + description = "If you want to use an existing project, you can pass the Code Engine project ID. Alternatively use `code_engine_project_name` to create a new project." type = string default = null } variable "cloud_pak_deployer_release" { - description = "The release of cloud pak deployer to build the image off of" + description = "The GIT release of Cloud Pak Deployer version to build from. View releases at: https://github.com/IBM/cloud-pak-deployer/releases." type = string - default = "latest" + default = "v3.1.8" # TODO: manage this version with renovate - https://github.com/terraform-ibm-modules/terraform-ibm-watsonx-self-managed-ocp/issues/36 +} + +variable "add_random_suffix_icr_namespace" { + type = bool + description = "Whether to add a randomly generated 4-character suffix to the newly created ICR namespace." + default = true +} + +variable "add_random_suffix_code_engine_project" { + type = bool + description = "Whether to add a randomly generated 4-character suffix to the newly created Code Engine project. Only applies if `code_engine_project_id` is `null`." + default = true } diff --git a/modules/cpd-image-build/version.tf b/modules/cpd-image-build/version.tf index cbc24ff8..ea19eac4 100644 --- a/modules/cpd-image-build/version.tf +++ b/modules/cpd-image-build/version.tf @@ -11,7 +11,7 @@ terraform { } shell = { source = "scottwinkler/shell" - version = "1.7.10" + version = ">= 1.7.10, <2.0.0" } } } diff --git a/scripts/wait_for_cpd_pod.sh b/scripts/wait_for_cpd_pod.sh index 647e88b2..c47021e1 100755 --- a/scripts/wait_for_cpd_pod.sh +++ b/scripts/wait_for_cpd_pod.sh @@ -3,14 +3,16 @@ set -e NAMESPACE="cloud-pak-deployer" -POD_NAME=$(kubectl get pods -n $NAMESPACE -o jsonpath='{.items[0].metadata.name}') +POD_NAME=$(kubectl get pods -n "${NAMESPACE}" -o jsonpath='{.items[0].metadata.name}') STATUS="" while true; do - # shellcheck disable=SC2086 - STATUS=$(kubectl get pod $POD_NAME -n $NAMESPACE -o jsonpath='{.status.phase}') - echo "Pod status: $STATUS" - if [[ "$STATUS" == "Succeeded" || "$STATUS" == "Failed" ]]; then + STATUS=$(kubectl get pod "${POD_NAME}" -n "${NAMESPACE}" -o jsonpath='{.status.phase}') + echo "Pod status: ${STATUS}" + if [[ "${STATUS}" == "Succeeded" ]]; then break + elif [[ "${STATUS}" == "Failed" ]]; then + echo "Exiting due to 'Failed' status. Check pod logs for more info." + exit 1 fi - sleep 300 + sleep 60 done diff --git a/solutions/fully-configurable/DA-types.md b/solutions/fully-configurable/DA-types.md index 409c3dc6..82704707 100644 --- a/solutions/fully-configurable/DA-types.md +++ b/solutions/fully-configurable/DA-types.md @@ -4,22 +4,7 @@ The `cloud_pak_deployer_secret` variable is used to provide credentials for accessing a private Cloud Pak Deployer image registry. This is required if you are using a custom or private image that is not publicly accessible. If this variable is set to `null`, a default secret will be created automatically. -## Variable Definition - -```hcl -variable "cloud_pak_deployer_secret" { - description = "Secret for accessing the Cloud Pak Deployer image. If `null`, a default secret will be created # pragma: allowlist secret." - type = object({ - username = string - password = string - server = string - email = string - }) - default = null -} -``` - -## Usage +### Usage The value should be an object with the following fields: @@ -28,12 +13,12 @@ The value should be an object with the following fields: - `server`: The registry server URL (e.g., `quay.io`, `icr.io`, etc.). - `email`: The email address associated with the registry account. -### Example +### Example usage ```hcl -cloud_pak_deployer_secret = { +{ username = "my-registry-user" - password = "my-registry-password" # pragma: allowlist secret + password = "my-registry-password" server = "quay.io" email = "user@example.com" } @@ -46,21 +31,10 @@ If you are using IBM Cloud Container Registry (ICR), your `server` might look li - **Required**: When your `cloud_pak_deployer_image` is hosted in a private registry that requires authentication. - **Optional**: If using the default public image, you can leave this variable as `null`. -## References +### References - [IBM Cloud Pak Deployer Documentation](https://github.com/IBM/cloud-pak-deployer) - [IBM Cloud Container Registry Docs](https://cloud.ibm.com/docs/container-registry) - [Terraform Input Variables](https://developer.hashicorp.com/terraform/language/values/variables) -## Example usage - -```hcl -cloud_pak_deployer_secret = { - username = "myuser" - password = "mypassword" # pragma: allowlist secret - server = "us.icr.io" - email = "myuser@example.com" -} -``` - > **Note:** If you do not need a custom image or private registry, you can omit this variable or set it to `null`. diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md index 34090f33..c6e66f20 100644 --- a/solutions/fully-configurable/README.md +++ b/solutions/fully-configurable/README.md @@ -1,180 +1,3 @@ - # Watsonx (Self-Managed) on Red Hat OpenShift - -[-red)](https://terraform-ibm-modules.github.io/documentation/#/badge-status) -[](https://github.com/terraform-ibm-modules/terraform-ibm-watsonx-self-managed-ocp/releases/latest) -[](https://github.com/pre-commit/pre-commit) -[](https://renovatebot.com/) -[](https://github.com/semantic-release/semantic-release) - - - -Deploy Watsonx services on an existing Red Hat OpenShift cluster. - -You can: -- **Use an existing OpenShift cluster** by providing its name and resource group - -Cluster must meet the minimum requirements to deploy Cloud Pak for Data [Learn more](https://www.ibm.com/docs/en/cloud-paks/cp-data/5.1.x?topic=overview-cloud-pak-data). - -The following services are currently supported: -- watsonx.ai -- Watson Assistant -- Watson Discovery -- Watson Data - - - - - -## Overview -* [terraform-ibm-watsonx-self-managed-ocp](#terraform-ibm-watsonx-self-managed-ocp) -* [Contributing](#contributing) - - - - - - - - -## terraform-ibm-watsonx-self-managed-ocp - -### Usage - - - -```hcl -module "watsonx_self_managed_ocp" { - source = "terraform-ibm-modules/watsonx-self-managed-ocp/ibm" - ibmcloud_api_key = "xXXxxxxXXXxxxx" # pragma: allowlist secret - prefix = "cp4d" - region = "us-south" - existing_cluster_name = "cluster1" - existing_resource_group_name = "rg-cluster-1" - cpd_admin_password = "xXXxxxxXXXxxxx" # pragma: allowlist secret - cpd_entitlement_key = "xXXxxxxXXXxxxx" # pragma: allowlist secret -} -``` - -### Required access policies - - - -You need the following permissions to run this module: - -- Service - - **Resource group only** - - `Viewer` access on the specific resource group - - **Kubernetes** service - - `Viewer` platform access - - `Manager` service access - - **Code Engine service - - `Administrator` platform access - - `Manager` service access - - **Container Registry service - - `Administrator` platform access - - `Manager` service access - - - - -### Requirements - -| Name | Version | -|------|---------| -| [terraform](#requirement\_terraform) | >= 1.9.0 | -| [external](#requirement\_external) | >= 2.3.5 | -| [helm](#requirement\_helm) | >= 2.17.0, < 3.0.0 | -| [ibm](#requirement\_ibm) | 1.79.2 | -| [null](#requirement\_null) | >= 3.2.4, < 4.0.0 | -| [shell](#requirement\_shell) | 1.7.10 | - -### Modules - -| Name | Source | Version | -|------|--------|---------| -| [resource\_group](#module\_resource\_group) | terraform-ibm-modules/resource-group/ibm | 1.2.1 | -| [watsonx\_self\_managed\_ocp](#module\_watsonx\_self\_managed\_ocp) | ../.. | n/a | - -### Resources - -| Name | Type | -|------|------| -| [null_resource.wait_for_cloud_pak_deployer_complete](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | -| [external_external.schematics](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source | -| [ibm_container_cluster_config.cluster_config](https://registry.terraform.io/providers/ibm-cloud/ibm/1.79.2/docs/data-sources/container_cluster_config) | data source | -| [ibm_iam_auth_token.tokendata](https://registry.terraform.io/providers/ibm-cloud/ibm/1.79.2/docs/data-sources/iam_auth_token) | data source | - -### Inputs - -| Name | Description | Type | Default | Required | -|------|-------------|------|---------|:--------:| -| [cloud\_pak\_deployer\_image](#input\_cloud\_pak\_deployer\_image) | Cloud Pak Deployer image to use. If `null`, the image will be built using Code Engine. | `string` | `"quay.io/cloud-pak-deployer/cloud-pak-deployer"` | no | -| [cloud\_pak\_deployer\_release](#input\_cloud\_pak\_deployer\_release) | Release of Cloud Pak Deployer version to use. View releases at: https://github.com/IBM/cloud-pak-deployer/releases. | `string` | `"v3.1.8"` | no | -| [cloud\_pak\_deployer\_secret](#input\_cloud\_pak\_deployer\_secret) | Secret for accessing the Cloud Pak Deployer image. If `null`, a default secret will be created # pragma: allowlist secret. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-watsonx-self-managed-ocp/tree/main/solutions/fully-configurable/DA-types.md). |
"ibm-granite-13b-instruct-v2"
]
object({
username = string
password = string
server = string
email = string
}) | `null` | no |
-| [code\_engine\_project\_id](#input\_code\_engine\_project\_id) | If you want to use an existing project, you can pass the code engine project ID and the Cloud Pak Deployer build will be built within the existing project instead of creating a new one. | `string` | `null` | no |
-| [code\_engine\_project\_name](#input\_code\_engine\_project\_name) | If `cloud_pak_deployer_image` is `null`, it will build the image with code engine and store it within a private ICR registry. Provide a name if you want to set the name. If not defined, default will be `{prefix}-cpd-{random-suffix}`. | `string` | `null` | no |
-| [cpd\_accept\_license](#input\_cpd\_accept\_license) | When set to `true`, it is understood that the user has read the terms of the Cloud Pak license(s) and agrees to the terms outlined. | `bool` | `true` | no |
-| [cpd\_admin\_password](#input\_cpd\_admin\_password) | Password for the Cloud Pak for Data admin user. | `string` | `"passw0rd"` | no |
-| [cpd\_entitlement\_key](#input\_cpd\_entitlement\_key) | Cloud Pak for Data entitlement key for access to the IBM Entitled Registry. Can be fetched from https://myibm.ibm.com/products-services/containerlibrary. | `string` | n/a | yes |
-| [cpd\_version](#input\_cpd\_version) | Cloud Pak for Data version to install. Only version 5.x.x is supported, latest versions can be found [here](https://www.ibm.com/docs/en/cloud-paks/cp-data?topic=versions-cloud-pak-data). | `string` | `"5.0.3"` | no |
-| [existing\_cluster\_name](#input\_existing\_cluster\_name) | Name of an existing Red Hat OpenShift cluster to create and install watsonx onto. | `string` | n/a | yes |
-| [existing\_resource\_group\_name](#input\_existing\_resource\_group\_name) | Resource group id of the cluster | `string` | n/a | yes |
-| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources. | `string` | n/a | yes |
-| [install\_odf\_cluster\_addon](#input\_install\_odf\_cluster\_addon) | Install the ODF cluster addon. | `bool` | `true` | no |
-| [odf\_config](#input\_odf\_config) | Configuration for the ODF addon. Example add on options can be found [here](https://cloud.ibm.com/docs/openshift?topic=openshift-deploy-odf-classic&interface=cli#install-odf-cli-classic) | `map(string)` | {
"addSingleReplicaPool": "false",
"billingType": "essentials",
"clusterEncryption": "false",
"disableNoobaaLB": "false",
"enableNFS": "false",
"encryptionInTransit": "false",
"hpcsBaseUrl": "",
"hpcsEncryption": "false",
"hpcsInstanceId": "",
"hpcsSecretName": "",
"hpcsServiceName": "",
"hpcsTokenUrl": "",
"ignoreNoobaa": "true",
"numOfOsd": "1",
"ocsUpgrade": "false",
"odfDeploy": "true",
"osdDevicePaths": "",
"osdSize": "512Gi",
"osdStorageClassName": "ibmc-vpc-block-metro-10iops-tier",
"prepareForDisasterRecovery": "false",
"resourceProfile": "balanced",
"taintNodes": "false",
"useCephRBDAsDefaultStorageClass": "false",
"workerNodes": "all",
"workerPool": ""
} | no |
-| [odf\_version](#input\_odf\_version) | Version of ODF to install. | `string` | `"4.16.0"` | no |
-| [prefix](#input\_prefix) | A unique identifier for resources that is prepended to resources that are provisioned. Must begin with a lowercase letter and end with a lowercase letter or number. Must be 16 or fewer characters. | `string` | `"cp4d"` | no |
-| [region](#input\_region) | Region where resources will be created. To find your VPC region, use `ibmcloud is regions` command to find available regions. | `string` | `"us-south"` | no |
-| [watson\_assistant\_install](#input\_watson\_assistant\_install) | If watsonx.ai is being installed, also install watson assistant | `bool` | `false` | no |
-| [watson\_discovery\_install](#input\_watson\_discovery\_install) | If watsonx.ai is being installed, also install watson discovery | `bool` | `false` | no |
-| [watsonx\_ai\_install](#input\_watsonx\_ai\_install) | Determine whether the watsonx.ai cartridge for the deployer will be installed | `bool` | `false` | no |
-| [watsonx\_ai\_models](#input\_watsonx\_ai\_models) | List of watsonx.ai models to install. Information on the foundation models including pre-reqs can be found here - https://www.ibm.com/docs/en/cloud-paks/cp-data/5.0.x?topic=install-foundation-models. Use the ModelID as input | `list(string)` | [| no | -| [watsonx\_data\_install](#input\_watsonx\_data\_install) | Determine whether the watsonx.data cartridge for the deployer will be installed | `bool` | `false` | no | - -### Outputs - -| Name | Description | -|------|-------------| -| [cloud\_pak\_deployer\_image](#output\_cloud\_pak\_deployer\_image) | The Cloud Pak Deployer image used. | -| [cloud\_pak\_deployer\_secret](#output\_cloud\_pak\_deployer\_secret) | The secret used for accessing the Cloud Pak Deployer image. | -| [cluster\_name](#output\_cluster\_name) | The name of the OpenShift cluster. | -| [code\_engine\_project\_name](#output\_code\_engine\_project\_name) | The name of the code engine project that was created | - - - -## Contributing - -You can report issues and request features for this module in GitHub issues in the module repo. See [Report an issue or request a feature](https://github.com/terraform-ibm-modules/.github/blob/main/.github/SUPPORT.md). - -To set up your local development environment, see [Local development setup](https://terraform-ibm-modules.github.io/documentation/#/local-dev-setup) in the project documentation. +:exclamation: **Important:** This solution is not intended to be called by other modules because it contains a provider configuration and is not compatible with the `for_each`, `count`, and `depends_on` arguments. For more information, see [Providers Within Modules](https://developer.hashicorp.com/terraform/language/modules/develop/providers). diff --git a/solutions/fully-configurable/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template index 18b78fec..45bef1ef 100644 --- a/solutions/fully-configurable/catalogValidationValues.json.template +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -1,6 +1,5 @@ { "ibmcloud_api_key": $VALIDATION_APIKEY, "cpd_entitlement_key": $SOFTWARE_ENTITLEMENT_KEY, - "prefix": $PREFIX, - "region": "us-south" + "prefix": $PREFIX } diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 7b16d815..fb0ed23a 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -2,42 +2,75 @@ # Resource Group ############################################################################## +module "cluster_resource_group" { + source = "terraform-ibm-modules/resource-group/ibm" + version = "1.2.0" + existing_resource_group_name = var.existing_cluster_resource_group_name +} + module "resource_group" { source = "terraform-ibm-modules/resource-group/ibm" version = "1.2.1" existing_resource_group_name = var.existing_resource_group_name } - ######################################################################################################################## # Watsonx Self Managed OCP module ######################################################################################################################## +resource "random_password" "admin_password" { + count = var.cpd_admin_password == null ? 1 : 0 + length = 32 + special = true + override_special = "-_" + min_numeric = 1 +} + +locals { + # _- are invalid first characters + # if - replace first char with J + # elseif _ replace first char with K + # else use asis + generated_admin_password = (length(random_password.admin_password) > 0 ? (startswith(random_password.admin_password[0].result, "-") ? "J${substr(random_password.admin_password[0].result, 1, -1)}" : startswith(random_password.admin_password[0].result, "_") ? "K${substr(random_password.admin_password[0].result, 1, -1)}" : random_password.admin_password[0].result) : null) + # admin password to use + cpd_admin_password = var.cpd_admin_password == null ? local.generated_admin_password : var.cpd_admin_password + prefix = var.prefix != null ? trimspace(var.prefix) != "" ? "${var.prefix}-" : "" : "" +} + +data "ibm_container_vpc_cluster" "cluster" { + name = var.existing_cluster_id + resource_group_id = module.cluster_resource_group.resource_group_id +} + module "watsonx_self_managed_ocp" { - source = "../.." - prefix = var.prefix - ibmcloud_api_key = var.ibmcloud_api_key - region = var.region - resource_group = module.resource_group.resource_group_id - code_engine_project_name = var.code_engine_project_name - code_engine_project_id = var.code_engine_project_id - cloud_pak_deployer_image = var.cloud_pak_deployer_image - cloud_pak_deployer_release = var.cloud_pak_deployer_release - cloud_pak_deployer_secret = var.cloud_pak_deployer_secret - cluster_name = var.existing_cluster_name - cluster_rg_id = module.resource_group.resource_group_id - install_odf_cluster_addon = var.install_odf_cluster_addon - odf_version = var.odf_version - odf_config = var.odf_config - cpd_version = var.cpd_version - cpd_accept_license = var.cpd_accept_license - cpd_admin_password = var.cpd_admin_password - cpd_entitlement_key = var.cpd_entitlement_key - watsonx_ai_install = var.watsonx_ai_install - watsonx_ai_models = var.watsonx_ai_models - watsonx_data_install = var.watsonx_data_install - watson_discovery_install = var.watson_discovery_install - watson_assistant_install = var.watson_assistant_install + source = "../.." + ibmcloud_api_key = var.ibmcloud_api_key + region = var.region + resource_group_id = module.resource_group.resource_group_id + code_engine_project_name = "${local.prefix}${var.code_engine_project_name}" + code_engine_project_id = var.code_engine_project_id + cloud_pak_deployer_image = var.cloud_pak_deployer_image + cloud_pak_deployer_release = var.cloud_pak_deployer_release + cloud_pak_deployer_secret = var.cloud_pak_deployer_secret + cluster_name = data.ibm_container_vpc_cluster.cluster.name + cluster_resource_group_id = module.cluster_resource_group.resource_group_id + install_odf_cluster_addon = var.install_odf_cluster_addon + odf_version = var.odf_version + odf_config = var.odf_config + cpd_version = var.cpd_version + cpd_accept_license = var.cpd_accept_license + cpd_admin_password = local.cpd_admin_password + cpd_entitlement_key = var.cpd_entitlement_key + watsonx_ai_install = var.watsonx_ai_install + watsonx_ai_models = var.watsonx_ai_models + watsonx_data_install = var.watsonx_data_install + watson_discovery_install = var.watson_discovery_install + watson_assistant_install = var.watson_assistant_install + use_global_container_registry_location = var.use_global_container_registry_location + container_registry_namespace = "${local.prefix}${var.container_registry_namespace}" + # No need to support suffix in DA as it has prefix functionality + add_random_suffix_icr_namespace = false + add_random_suffix_code_engine_project = false } resource "null_resource" "wait_for_cloud_pak_deployer_complete" { diff --git a/solutions/fully-configurable/outputs.tf b/solutions/fully-configurable/outputs.tf index dadba504..fe554976 100644 --- a/solutions/fully-configurable/outputs.tf +++ b/solutions/fully-configurable/outputs.tf @@ -18,3 +18,9 @@ output "code_engine_project_name" { description = "The name of the code engine project that was created" value = module.watsonx_self_managed_ocp.code_engine_project_name } + +output "cpd_admin_password" { + description = "The Cloud Pak Data admin password" + sensitive = true + value = local.cpd_admin_password +} diff --git a/solutions/fully-configurable/providers.tf b/solutions/fully-configurable/providers.tf index 88c2a2a4..fa940f14 100644 --- a/solutions/fully-configurable/providers.tf +++ b/solutions/fully-configurable/providers.tf @@ -1,7 +1,7 @@ provider "ibm" { ibmcloud_api_key = var.ibmcloud_api_key - - region = var.region + region = var.region + visibility = var.provider_visibility } locals { @@ -23,7 +23,7 @@ locals { } data "ibm_container_cluster_config" "cluster_config" { - cluster_name_id = var.existing_cluster_name + cluster_name_id = var.existing_cluster_id config_dir = local.kube_config_dir } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 5904a5de..03ad05c8 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -1,48 +1,67 @@ +############################################################################################### +# Common inputs +############################################################################################### + variable "ibmcloud_api_key" { description = "The IBM Cloud API key to deploy resources." type = string sensitive = true } -variable "prefix" { - description = "A unique identifier for resources that is prepended to resources that are provisioned. Must begin with a lowercase letter and end with a lowercase letter or number. Must be 16 or fewer characters." +variable "provider_visibility" { + description = "Set the visibility value for the IBM terraform provider. Supported values are `public`, `private`, `public-and-private`. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/guides/custom-service-endpoints)." type = string - default = "cp4d" + default = "private" + validation { - error_message = "Prefix must begin with a letter and contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters." - condition = can(regex("^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$", var.prefix)) && length(var.prefix) <= 16 + condition = contains(["public", "private", "public-and-private"], var.provider_visibility) + error_message = "Invalid visibility option. Allowed values are 'public', 'private', or 'public-and-private'." } } -variable "region" { - description = "Region where resources will be created. To find your VPC region, use `ibmcloud is regions` command to find available regions." +variable "prefix" { type = string - nullable = false - default = "us-south" -} + nullable = true + description = "The prefix to be added to all resources created by this solution. To skip using a prefix, set this value to null or an empty string. The prefix must begin with a lowercase letter and may contain only lowercase letters, digits, and hyphens '-'. It should not exceed 16 characters, must not end with a hyphen('-'), and can not contain consecutive hyphens ('--'). Example: prod-wx-cp4d. [Learn more](https://terraform-ibm-modules.github.io/documentation/#/prefix.md)." -variable "code_engine_project_name" { - description = "If `cloud_pak_deployer_image` is `null`, it will build the image with code engine and store it within a private ICR registry. Provide a name if you want to set the name. If not defined, default will be `{prefix}-cpd-{random-suffix}`." - type = string - default = null + validation { + # - null and empty string is allowed + # - Must not contain consecutive hyphens (--): length(regexall("--", var.prefix)) == 0 + # - Starts with a lowercase letter: [a-z] + # - Contains only lowercase letters (a–z), digits (0–9), and hyphens (-) + # - Must not end with a hyphen (-): [a-z0-9] + condition = (var.prefix == null || var.prefix == "" ? true : + alltrue([ + can(regex("^[a-z][-a-z0-9]*[a-z0-9]$", var.prefix)), + length(regexall("--", var.prefix)) == 0 + ]) + ) + error_message = "Prefix must begin with a lowercase letter and may contain only lowercase letters, digits, and hyphens '-'. It must not end with a hyphen('-'), and cannot contain consecutive hyphens ('--')." + } + + validation { + # must not exceed 16 characters in length + condition = length(var.prefix) <= 16 + error_message = "Prefix must not exceed 16 characters." + } } -variable "code_engine_project_id" { - description = "If you want to use an existing project, you can pass the code engine project ID and the Cloud Pak Deployer build will be built within the existing project instead of creating a new one." +variable "cloud_pak_deployer_image" { + description = "Cloud Pak Deployer image to use. If `null`, the image will be built using Code Engine and publish to a private Container Registry namespace." type = string - default = null + default = "quay.io/cloud-pak-deployer/cloud-pak-deployer:v3.1.8@sha256:e9cde204359a3014a3cee6a43c1e945a7dcb31d5fa92439326d4e5ab2191b48f" } -variable "cloud_pak_deployer_image" { - description = "Cloud Pak Deployer image to use. If `null`, the image will be built using Code Engine." +variable "existing_cluster_id" { + description = "ID of an existing Red Hat OpenShift cluster to create and install watsonx onto." type = string - default = "quay.io/cloud-pak-deployer/cloud-pak-deployer" + nullable = false } -variable "cloud_pak_deployer_release" { - description = "Release of Cloud Pak Deployer version to use. View releases at: https://github.com/IBM/cloud-pak-deployer/releases." +variable "existing_cluster_resource_group_name" { + description = "The name of the resource group that the cluster provided in `cluster_name` exists in." type = string - default = "v3.1.8" + nullable = false } variable "cloud_pak_deployer_secret" { @@ -56,20 +75,73 @@ variable "cloud_pak_deployer_secret" { default = null } -variable "existing_cluster_name" { - description = "Name of an existing Red Hat OpenShift cluster to create and install watsonx onto." +variable "cpd_accept_license" { + description = "When set to 'true', it is understood that the user has read the terms of the Cloud Pak license(s) and agrees to the terms outlined." + type = bool + default = true +} + +variable "cpd_admin_password" { + description = "Password for the Cloud Pak for Data admin user. If no value passed, a random password is generated and can be access using the 'cpd_admin_password' output." + sensitive = true type = string + default = null } -variable "existing_resource_group_name" { - description = "Resource group id of the cluster" +variable "cpd_entitlement_key" { + description = "Cloud Pak for Data entitlement key for access to the IBM Entitled Registry. Can be fetched from https://myibm.ibm.com/products-services/containerlibrary." + sensitive = true type = string +} + +variable "cpd_version" { + description = "Cloud Pak for Data version to install. Only version 5.x.x is supported, latest versions can be found [here](https://www.ibm.com/docs/en/cloud-paks/cp-data?topic=versions-cloud-pak-data)." + type = string + default = "5.0.3" + validation { - error_message = "`existing_resource_group_name` cannot be null if `existing_cluster_name` is not null." - condition = var.existing_cluster_name == null || var.existing_resource_group_name != null + error_message = "Cloud pak for data major version 5 is supported." + condition = split(".", var.cpd_version)[0] == "5" } } +# Only used in the watsonx.ai offering flavour +variable "watsonx_ai_install" { + description = "Determine whether the watsonx.ai cartridge for the deployer will be installed" + type = bool + default = false +} + +# Only used in the watsonx.ai offering flavour +variable "watsonx_ai_models" { + description = "List of watsonx.ai models to install. Information on the foundation models including pre-reqs can be found here - https://www.ibm.com/docs/en/cloud-paks/cp-data/5.0.x?topic=install-foundation-models. Use the ModelID as input" + type = list(string) + default = ["ibm-granite-13b-instruct-v2"] +} + +# Only used in the watsonx.data offering flavour +variable "watsonx_data_install" { + description = "Determine whether the watsonx.data cartridge for the deployer will be installed" + type = bool + default = false +} + +variable "watson_discovery_install" { + description = "If watsonx.ai is being installed, also install watson discovery" + type = bool + default = false +} + +variable "watson_assistant_install" { + description = "If watsonx.ai is being installed, also install watson assistant" + type = bool + default = false +} + +############################################################################################### +# ODF inputs +############################################################################################### + variable "install_odf_cluster_addon" { description = "Install the ODF cluster addon." type = bool @@ -120,73 +192,52 @@ variable "odf_config" { } } -variable "cpd_accept_license" { - description = "When set to `true`, it is understood that the user has read the terms of the Cloud Pak license(s) and agrees to the terms outlined." - type = bool - default = true - nullable = false -} - -variable "cpd_admin_password" { - description = "Password for the Cloud Pak for Data admin user." - sensitive = true - type = string - nullable = false - default = "passw0rd" # pragma: allowlist secret -} +############################################################################################### +# Below inputs are only used if building image (aka setting "cloud_pak_deployer_image" to null) +############################################################################################### -variable "cpd_entitlement_key" { - description = "Cloud Pak for Data entitlement key for access to the IBM Entitled Registry. Can be fetched from https://myibm.ibm.com/products-services/containerlibrary." - sensitive = true +variable "existing_resource_group_name" { type = string - nullable = false + description = "The name of the resource group where Code Engine and Container Registry resources will be provisioned. Only applies if `cloud_pak_deployer_image` is `null`." + default = "Default" } -variable "cpd_version" { - description = "Cloud Pak for Data version to install. Only version 5.x.x is supported, latest versions can be found [here](https://www.ibm.com/docs/en/cloud-paks/cp-data?topic=versions-cloud-pak-data)." +variable "region" { + description = "Region where Code Engine and Container Registry resources will be provisioned. Only applies if `cloud_pak_deployer_image` is `null`. To use the 'Global' Container Registry location set `use_global_container_registry_location` to true." type = string - validation { - error_message = "Cloud pak for data major version 5 is supported." - condition = split(".", var.cpd_version)[0] == "5" - } - default = "5.0.3" - nullable = false + default = "us-south" } -# Only used in the watsonx.ai offering flavour -variable "watsonx_ai_install" { - description = "Determine whether the watsonx.ai cartridge for the deployer will be installed" +variable "use_global_container_registry_location" { + description = "Set to true to create the Container Registry namespace in the 'Global' location. If set to false, the namespace will be created in the region provided in the `region` input value. Only applies if `cloud_pak_deployer_image` is `null`." type = bool default = false - nullable = false } -# Only used in the watsonx.ai offering flavour -variable "watsonx_ai_models" { - description = "List of watsonx.ai models to install. Information on the foundation models including pre-reqs can be found here - https://www.ibm.com/docs/en/cloud-paks/cp-data/5.0.x?topic=install-foundation-models. Use the ModelID as input" - type = list(string) - default = ["ibm-granite-13b-instruct-v2"] - nullable = false +variable "container_registry_namespace" { + description = "The name of the Container Registry namespace to create. Only applies if `cloud_pak_deployer_image` is `null`. If a prefix input variable is specified, the prefix is added to the name in the `
"ibm-granite-13b-instruct-v2"
]