diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index 1e421ee2..f1fbee85 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -1,20 +1,17 @@ --- apiVersion: v1 offerings: - - name: terraform-ibm-base-ocp-vpc - kind: module - catalog_id: 7df1e4ca-d54c-4fd0-82ce-3d13247308cd - offering_id: 8531b562-91d5-4974-a195-5dff72ef2a5d - examples: - - name: basic - mark_ready: true - - name: advanced - mark_ready: true - - name: fscloud - mark_ready: true - - name: multiple_mzr_clusters - mark_ready: true - - name: add_rules_to_sg - mark_ready: true - - name: cross_kms_support + - name: deploy-arch-ibm-ocp-vpc + kind: solution + catalog_id: f64499c8-eb50-4985-bf91-29f9e605a433 + offering_id: 1728a4fd-f561-4cf9-82ef-2b1eeb5da1a8 + variations: + - name: fully-configurable mark_ready: true + install_type: fullstack + pre_validation: "tests/scripts/pre-validation-deploy-cos-instance-and-vpc.sh" + post_validation: "tests/scripts/post-validation-destroy-cos-instance-and-vpc.sh" + scc: + instance_id: 1c7d5f78-9262-44c3-b779-b28fe4d88c37 + region: us-south + scope_resource_group_var_name: existing_resource_group_name diff --git a/.releaserc b/.releaserc index 708916f7..f7db2979 100644 --- a/.releaserc +++ b/.releaserc @@ -1,15 +1,29 @@ { "tagFormat": "v${version}", - "branches": ["main"], + "branches": [ + "main" + ], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/github", - ["@semantic-release/git", { - "assets": "false" - }], - ["@semantic-release/exec", { - "successCmd": "echo \"SEMVER_VERSION=${nextRelease.version}\" >> $GITHUB_ENV" - }] + [ + "@semantic-release/git", + { + "assets": "false" + } + ], + [ + "@semantic-release/exec", + { + "successCmd": "echo \"SEMVER_VERSION=${nextRelease.version}\" >> $GITHUB_ENV" + } + ], + [ + "@semantic-release/exec", + { + "publishCmd": "./ci/trigger-catalog-onboarding-pipeline.sh --version=v${nextRelease.version}" + } + ] ] } diff --git a/.secrets.baseline b/.secrets.baseline index afecdab1..30a7b446 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2024-07-12T12:56:42Z", + "generated_at": "2025-04-01T10:27:06Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -77,12 +77,12 @@ } ], "results": { - "ibm_catalog.json": [ + "tests/pr_test.go": [ { - "hashed_secret": "a03815a5700107eb9f0d1a9608d2fcbdc48b7f5d", + "hashed_secret": "8196b86ede820e665b2b8af9c648f4996be99838", "is_secret": false, "is_verified": false, - "line_number": 20, + "line_number": 60, "type": "Secret Keyword", "verified_result": null } diff --git a/README.md b/README.md index c1312300..2d7df42f 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ module "ocp_base" { The user must export the endpoint as an environment variable in order to use custom cloud service endpoints with this module. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/guides/custom-service-endpoints#getting-started-with-custom-service-endpoints). -**Important** The only supported method for customizing cloud service endpoints is to export the enviroment variables endpoint; be sure to export the value for `IBMCLOUD_IAM_API_ENDPOINT`, `IBMCLOUD_CS_API_ENDPOINT` and `IBMCLOUD_IS_NG_API_ENDPOINT`. For example, +**Important** The only supported method for customizing cloud service endpoints is to export the environment variables endpoint; be sure to export the value for `IBMCLOUD_IAM_API_ENDPOINT`, `IBMCLOUD_CS_API_ENDPOINT` and `IBMCLOUD_IS_NG_API_ENDPOINT`. For example, ``` export IBMCLOUD_IAM_API_ENDPOINT="" export IBMCLOUD_CS_API_ENDPOINT="" @@ -283,18 +283,18 @@ Optionally, you need the following permissions to attach Access Management tags | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | [access\_tags](#input\_access\_tags) | A list of access tags to apply to the resources created by the module, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial for more details | `list(string)` | `[]` | no | -| [additional\_lb\_security\_group\_ids](#input\_additional\_lb\_security\_group\_ids) | Additional security groups to add to the load balancers associated with the cluster. Ensure that the number\_of\_lbs is set to the number of LBs associated with the cluster. This comes in addition to the IBM maintained security group. | `list(string)` | `[]` | no | +| [additional\_lb\_security\_group\_ids](#input\_additional\_lb\_security\_group\_ids) | Additional security groups to add to the load balancers associated with the cluster. Ensure that the `number_of_lbs` is set to the number of LBs associated with the cluster. This comes in addition to the IBM maintained security group. | `list(string)` | `[]` | no | | [additional\_vpe\_security\_group\_ids](#input\_additional\_vpe\_security\_group\_ids) | Additional security groups to add to all existing load balancers. This comes in addition to the IBM maintained security group. |
object({
master = optional(list(string), [])
registry = optional(list(string), [])
api = optional(list(string), [])
})
| `{}` | no | | [addons](#input\_addons) | Map of OCP cluster add-on versions to install (NOTE: The 'vpc-block-csi-driver' add-on is installed by default for VPC clusters and 'ibm-storage-operator' is installed by default in OCP 4.15 and later, however you can explicitly specify it here if you wish to choose a later version than the default one). For full list of all supported add-ons and versions, see https://cloud.ibm.com/docs/containers?topic=containers-supported-cluster-addon-versions |
object({
debug-tool = optional(string)
image-key-synchronizer = optional(string)
openshift-data-foundation = optional(string)
vpc-file-csi-driver = optional(string)
static-route = optional(string)
cluster-autoscaler = optional(string)
vpc-block-csi-driver = optional(string)
ibm-storage-operator = optional(string)
openshift-ai = optional(string)
})
| `{}` | no | | [allow\_default\_worker\_pool\_replacement](#input\_allow\_default\_worker\_pool\_replacement) | (Advanced users) Set to true to allow the module to recreate a default worker pool. If you wish to make any change to the default worker pool which requires the re-creation of the default pool follow these [steps](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc?tab=readme-ov-file#important-considerations-for-terraform-and-default-worker-pool). | `bool` | `false` | no | -| [attach\_ibm\_managed\_security\_group](#input\_attach\_ibm\_managed\_security\_group) | Specify whether to attach the IBM-defined default security group (whose name is kube-) to all worker nodes. Only applicable if custom\_security\_group\_ids is set. | `bool` | `true` | no | +| [attach\_ibm\_managed\_security\_group](#input\_attach\_ibm\_managed\_security\_group) | Specify whether to attach the IBM-defined default security group (whose name is kube-) to all worker nodes. Only applicable if `custom_security_group_ids` is set. | `bool` | `true` | no | | [cbr\_rules](#input\_cbr\_rules) | The list of context-based restriction rules to create. |
list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
tags = optional(list(object({
name = string
value = string
})), [])
operations = optional(list(object({
api_types = list(object({
api_type_id = string
}))
})))
}))
| `[]` | no | | [cluster\_config\_endpoint\_type](#input\_cluster\_config\_endpoint\_type) | Specify which type of endpoint to use for for cluster config access: 'default', 'private', 'vpe', 'link'. 'default' value will use the default endpoint of the cluster. | `string` | `"default"` | no | | [cluster\_name](#input\_cluster\_name) | The name that will be assigned to the provisioned cluster | `string` | n/a | yes | | [cluster\_ready\_when](#input\_cluster\_ready\_when) | The cluster is ready when one of the following: MasterNodeReady (not recommended), OneWorkerNodeReady, Normal, IngressReady | `string` | `"IngressReady"` | no | | [cos\_name](#input\_cos\_name) | Name of the COS instance to provision for OpenShift internal registry storage. New instance only provisioned if 'enable\_registry\_storage' is true and 'use\_existing\_cos' is false. Default: '\_cos' | `string` | `null` | no | -| [custom\_security\_group\_ids](#input\_custom\_security\_group\_ids) | Security groups to add to all worker nodes. This comes in addition to the IBM maintained security group if attach\_ibm\_managed\_security\_group is set to true. If this variable is set, the default VPC security group is NOT assigned to the worker nodes. | `list(string)` | `null` | no | -| [disable\_outbound\_traffic\_protection](#input\_disable\_outbound\_traffic\_protection) | Whether to allow public outbound access from the cluster workers. This is only applicable for `ocp_version` 4.15 | `bool` | `false` | no | +| [custom\_security\_group\_ids](#input\_custom\_security\_group\_ids) | Security groups to add to all worker nodes. This comes in addition to the IBM maintained security group if `attach_ibm_managed_security_group` is set to true. If this variable is set, the default VPC security group is NOT assigned to the worker nodes. | `list(string)` | `null` | no | +| [disable\_outbound\_traffic\_protection](#input\_disable\_outbound\_traffic\_protection) | Whether to allow public outbound access from the cluster workers. This is only applicable for OCP 4.15 and later. | `bool` | `false` | no | | [disable\_public\_endpoint](#input\_disable\_public\_endpoint) | Whether access to the public service endpoint is disabled when the cluster is created. Does not affect existing clusters. You can't disable a public endpoint on an existing cluster, so you can't convert a public cluster to a private cluster. To change a public endpoint to private, create another cluster with this input set to `true`. | `bool` | `false` | no | | [enable\_ocp\_console](#input\_enable\_ocp\_console) | Flag to specify whether to enable or disable the OpenShift console. If set to `null` the module will not modify the setting currently set on the cluster. Bare in mind when setting this to `true` or `false` on a cluster with private only endpoint enabled, the runtime must be able to access the private endpoint. | `bool` | `null` | no | | [enable\_registry\_storage](#input\_enable\_registry\_storage) | Set to `true` to enable IBM Cloud Object Storage for the Red Hat OpenShift internal image registry. Set to `false` only for new cluster deployments in an account that is allowlisted for this feature. | `bool` | `true` | no | @@ -303,7 +303,7 @@ Optionally, you need the following permissions to attach Access Management tags | [ignore\_worker\_pool\_size\_changes](#input\_ignore\_worker\_pool\_size\_changes) | Enable if using worker autoscaling. Stops Terraform managing worker count | `bool` | `false` | no | | [kms\_config](#input\_kms\_config) | Use to attach a KMS instance to the cluster. If account\_id is not provided, defaults to the account in use. |
object({
crk_id = string
instance_id = string
private_endpoint = optional(bool, true) # defaults to true
account_id = optional(string) # To attach KMS instance from another account
wait_for_apply = optional(bool, true) # defaults to true so terraform will wait until the KMS is applied to the master, ready and deployed
})
| `null` | no | | [manage\_all\_addons](#input\_manage\_all\_addons) | Instructs Terraform to manage all cluster addons, even if addons were installed outside of the module. If set to 'true' this module will destroy any addons that were installed by other sources. | `bool` | `false` | no | -| [number\_of\_lbs](#input\_number\_of\_lbs) | The number of LBs to associated the additional\_lb\_security\_group\_names security group with. | `number` | `1` | no | +| [number\_of\_lbs](#input\_number\_of\_lbs) | The number of LBs to associated the `additional_lb_security_group_names` security group with. | `number` | `1` | no | | [ocp\_entitlement](#input\_ocp\_entitlement) | Value that is applied to the entitlements for OCP cluster provisioning | `string` | `null` | no | | [ocp\_version](#input\_ocp\_version) | The version of the OpenShift cluster that should be provisioned (format 4.x). If no value is specified, the current default version is used. You can also specify `default`. This input is used only during initial cluster provisioning and is ignored for updates. To prevent possible destructive changes, update the cluster version outside of Terraform. | `string` | `null` | no | | [pod\_subnet\_cidr](#input\_pod\_subnet\_cidr) | Specify a custom subnet CIDR to provide private IP addresses for pods. The subnet must have a CIDR of at least `/23` or larger. Default value is `172.30.0.0/16` when the variable is set to `null`. | `string` | `null` | no | diff --git a/examples/advanced/main.tf b/examples/advanced/main.tf index d1b45ffd..39341f6b 100644 --- a/examples/advanced/main.tf +++ b/examples/advanced/main.tf @@ -66,7 +66,7 @@ resource "ibm_is_public_gateway" "gateway" { } ######################################################################################################################## -# Subnets accross 3 zones +# Subnets across 3 zones # Public gateway attached to all the zones ######################################################################################################################## diff --git a/examples/multiple_mzr_clusters/main.tf b/examples/multiple_mzr_clusters/main.tf index ade6b5e4..56b391e4 100644 --- a/examples/multiple_mzr_clusters/main.tf +++ b/examples/multiple_mzr_clusters/main.tf @@ -34,7 +34,7 @@ resource "ibm_is_public_gateway" "gateway" { } ######################################################################################################################## -# Subnets accross the 2 zones +# Subnets across the 2 zones ######################################################################################################################## resource "ibm_is_subnet" "subnet_cluster_1" { diff --git a/ibm_catalog.json b/ibm_catalog.json index f5552d3b..72616972 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -1,156 +1,553 @@ { - "products": [ + "products": [ + { + "name": "deploy-arch-ibm-ocp-vpc", + "label": "[Add-ons Beta] Cloud automation for Red Hat OpenShift Container Platform on VPC", + "product_kind": "solution", + "tags": [ + "containers", + "target_terraform", + "terraform", + "solution", + "ibm_created", + "ibm_beta" + ], + "keywords": [ + "terraform", + "ocp", + "cluster", + "red_hat_openshift" + ], + "short_description": "Automates Red Hat OpenShift VPC cluster deployment on IBM Cloud, offering full configurability and flexibility for diverse workloads.", + "long_description": "This deployable architecture deploys a Red Hat OpenShift cluster on IBM Cloud. This is an experimental tile and not suitable for production workloads. Stay here if you want to try an experimental version with the [Optional and swappable components](https://cloud.ibm.com/docs/secure-enterprise?topic=secure-enterprise-choose-plan-process#optional-swappable) capability.", + "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/README.md", + "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/main/images/ocp_icon.svg", + "provider_name": "IBM", + "features": [ { - "name": "terraform-ibm-base-ocp-vpc", - "label": "Red Hat OpenShift VPC cluster on IBM Cloud module", - "product_kind": "module", - "tags": [ - "dev_ops", - "target_terraform", - "terraform", - "module", - "ibm_created" - ], - "keywords": [ - "terraform", - "ocp", - "cluster" - ], - "short_description": "Provisions a Red Hat OpenShift VPC cluster on IBM Cloud", - "long_description": "Use this module to provision an [IBM Cloud Red Hat OpenShift cluster](https:\/\/cloud.ibm.com\/docs\/openshift?topic=openshift-getting-started) on VPC Gen2. The module either creates the required Cloud Object Storage instance or uses an existing instance. The module also supports optionally passing a key management configuration for secret encryption and boot volume encryption.\r\n\r\n### Before you begin\r\n\r\n- Make sure that you have a recent version of the [IBM Cloud CLI](https:\/\/cloud.ibm.com\/docs\/cli?topic=cli-getting-started)\r\n- Make sure that you have a recent version of the [IBM Cloud Kubernetes service CLI](https:\/\/cloud.ibm.com\/docs\/containers?topic=containers-kubernetes-service-cli)\r\n\r\n### Usage\r\n```hcl\r\nmodule \"ocp_base\" {\r\n # Replace \"X.X.X\" with a release version to lock into a specific release\r\n source = \"https:\/\/cm.globalcatalog.cloud.ibm.com\/api\/v1-beta\/offering\/source?archive=tgz&kind=terraform&name=terraform-ibm-base-ocp-vpc&version=X.X.X\"\r\n ibmcloud_api_key = \"XXXXXXXXXXXXXXXXXXX\"\r\n cluster_name = \"example-cluster-name\"\r\n resource_group_id = \"xxXXxxXXxXxXXXXxxXxxxXXXXxXXXXX\"\r\n region = \"us-south\"\r\n force_delete_storage = true\r\n vpc_id = \"79cxxxx-xxxx-xxxx-xxxx-xxxxxXX8667\"\r\n # obtain the below values from the targeted VPC and adjust to the number of zones, subnets, subnet name, cidr_block, id, zone\r\n vpc_subnets = {\r\n zone-1 = [\r\n {\r\n cidr_block = \"192.168.32.0\/22\"\r\n id = \"0717-afc29fbb-0dbe-493a-a5b9-f3c5899cb8b9\"\r\n zone = \"us-south-1\"\r\n },\r\n {\r\n cidr_block = \"192.168.36.0\/22\"\r\n id = \"0727-d65c1eda-9e38-4200-8452-cb8ff5bb3140\"\r\n zone = \"us-south-2\"\r\n },\r\n {\r\n cidr_block = \"192.168.40.0\/22\"\r\n id = \"0737-9a823cd3-16bf-4ba4-a429-9e1fc7db74b8\"\r\n zone = \"us-south-3\"\r\n }\r\n ]\r\n zone-2 = [\r\n {\r\n cidr_block = \"192.168.0.0\/22\"\r\n id = \"0717-846b9490-34ae-4a6c-8288-28112dca1ba3\"\r\n zone = \"us-south-1\"\r\n },\r\n {\r\n cidr_block = \"192.168.4.0\/22\"\r\n id = \"0727-ef8db7f6-ffa5-4d8b-a317-4631741a45ee\"\r\n zone = \"us-south-2\"\r\n },\r\n {\r\n cidr_block = \"192.168.8.0\/22\"\r\n id = \"0737-c9a6d871-d95b-4914-abf5-82c22f4161d1\"\r\n zone = \"us-south-3\"\r\n }\r\n ]\r\n zone-3 = [\r\n {\r\n cidr_block = \"192.168.16.0\/22\"\r\n id = \"0717-d46e227c-89d4-4b02-9008-d03907a275b6\"\r\n zone = \"us-south-1\"\r\n },\r\n {\r\n cidr_block = \"192.168.20.0\/22\"\r\n id = \"0727-93b1edcb-966c-4517-a7af-6ac63cd93adf\"\r\n zone = \"us-south-2\"\r\n },\r\n {\r\n cidr_block = \"192.168.24.0\/22\"\r\n id = \"0737-807ec4f1-4d84-484e-b2f4-62dd5e431065\"\r\n zone = \"us-south-3\"\r\n }\r\n ]\r\n }\r\n}\r\n```", - "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/README.md", - "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/documentation/main/icons/RH_OpenShift.svg", - "provider_name": "IBM", + "title": "OCP on IBM Cloud", + "description": "Create and configures a Red Hat OpenShift VPC cluster on IBM Cloud." + }, + { + "title": "Object Storage bucket for OpenShift internal registry storage.", + "description": "Creates and configures an Object Storage bucket required for OpenShift internal registry storage." + }, + { + "title": "KMS encryption", + "description": "Supports creating a new key, or using an existing one to encrypt the COS bucket." + } + ], + "flavors": [ + { + "label": "Fully configurable", + "name": "fully-configurable", + "install_type": "fullstack", + "working_directory": "solutions/fully-configurable", + "iam_permissions": [ + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Administrator" + ], + "service_name": "iam-identity" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "hs-crypto" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "kms" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Editor" + ], + "service_name": "cloud-object-storage" + }, + { + "service_name": "containers-kubernetes", + "role_crns": [ + "crn:v1:bluemix:public:iam::::serviceRole:Manager", + "crn:v1:bluemix:public:iam::::role:Editor" + ] + } + ], + "architecture": { + "descriptions": "This architecture creates a fully-configurable OCP VPC cluster.", "features": [ + { + "title": "Creates a Red Hat OpenShift VPC cluster.", + "description": "Creates a Red Hat OpenShift VPC cluster." + } + ], + "diagrams": [ + { + "diagram": { + "caption": "Red Hat OpenShift VPC cluster for IBM Cloud.", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/qs/reference-architecture/deployable-architecture-ocp-cluster-qs.svg", + "type": "image/svg+xml" + }, + "description": "This architecture creates a fully-configurable Red Hat OpenShift VPC cluster." + } + ] + }, + "configuration": [ + { + "key": "ibmcloud_api_key" + }, + { + "key": "prefix", + "required": true, + "description": "The prefix to add to all resources that this solution creates. To not use any prefix value, you can enter the string `__NULL__`." + }, + { + "key": "existing_resource_group_name", + "required": true, + "custom_config": { + "type": "resource_group", + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "identifier": "rg_name" + } + } + }, + { + "key": "existing_vpc_crn", + "required": true + }, + { + "key": "existing_cos_instance_crn", + "required": true + }, + { + "key": "cluster_name", + "required": true + }, + { + "key": "ocp_version", + "required": true, + "options": [ { - "title": "Create a Red Hat OpenShift VPC cluster on IBM Cloud", - "description": "Create a Red Hat OpenShift VPC cluster on IBM Cloud." + "displayname": "4.14", + "value": "4.14" }, { - "title": "Autoscaling", - "description": "Configure worker autoscaling." + "displayname": "4.15", + "value": "4.15" }, { - "title": "Optionally create a Cloud Object Storage instance", - "description": "Optionally create a Cloud Object Storage instance which is required by OCP VPC clusters. Also supports using existing instance." + "displayname": "4.16", + "value": "4.16" }, { - "title": "Attach access tags", - "description": "Attach access tags to the cluster resources." + "displayname": "4.17", + "value": "4.17" + } + ] + }, + { + "key": "default_worker_pool_machine_type", + "required": true + }, + { + "key": "default_worker_pool_workers_per_zone", + "required": true + }, + { + "key": "default_worker_pool_operating_system", + "required": true + }, + { + "key": "provider_visibility", + "options": [ + { + "displayname": "private", + "value": "private" }, { - "title": "Enable cluster managed add-ons", - "description": "Enable any of the supported [managed cluster addons](https://cloud.ibm.com/docs/containers?topic=containers-managed-addons)." + "displayname": "public", + "value": "public" }, { - "title": "Encrypt data with key management services", - "description": "Supports key management encryption (BYOK and KYOK) for boot volumes and cluster data." + "displayname": "public-and-private", + "value": "public-and-private" } - ], - "flavors": [ - { - "label": "Basic", - "name": "basic", - "working_directory": "examples/basic", - "architecture": { - "diagrams": [ - { - "diagram": { - "caption": "Basic example", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/documentation/main/icons/ModuleExampleDiagram.svg", - "type": "image/svg+xml" - }, - "description": "A simple example that shows how to provision a basic single zone OCP VPC cluster." - } - ] - } - }, - { - "label": "Advanced", - "name": "advanced", - "working_directory": "examples/advanced", - "architecture": { - "diagrams": [ - { - "diagram": { - "caption": "Advanced example", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/documentation/main/icons/ModuleExampleDiagram.svg", - "type": "image/svg+xml" - }, - "description": "An advanced example which shows how to create a multi-zone KMS encrypted OCP VPC cluster with custom worker node taints." - } - ] - } - }, - { - "label": "Financial Services compliant", - "name": "fscloud", - "working_directory": "examples/fscloud", - "architecture": { - "diagrams": [ - { - "diagram": { - "caption": "Financial Services compliant example", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/documentation/main/icons/ModuleExampleDiagram.svg", - "type": "image/svg+xml" - }, - "description": "This example uses the Profile for IBM Cloud Framework for Financial Services to provision an instance of the base OCP VPC module in a compliant manner." - } - ] - } - }, - { - "label": "2 MZR clusters in same VPC", - "name": "multiple_mzr_clusters", - "working_directory": "examples/multiple_mzr_clusters", - "architecture": { - "diagrams": [ - { - "diagram": { - "caption": "2 MZR clusters in same VPC example", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/documentation/main/icons/ModuleExampleDiagram.svg", - "type": "image/svg+xml" - }, - "description": "This is an example of creating 2 MZR clusters in same VPC, and deploying the observability agents in the clusters." - } - ] - } - }, - { - "label": "Cluster security group rules", - "name": "add_rules_to_sg", - "working_directory": "examples/add_rules_to_sg", - "architecture": { - "diagrams": [ - { - "diagram": { - "caption": "Cluster security group rules example", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/documentation/main/icons/ModuleExampleDiagram.svg", - "type": "image/svg+xml" - }, - "description": "This example will add security rules to the `kube-` and `kube-` security groups." - } - ] - } - }, - { - "label": "Cross account KMS encryption", - "name": "cross_kms_support", - "working_directory": "examples/cross_kms_support", - "architecture": { - "diagrams": [ - { - "diagram": { - "caption": "Cross account KMS encryption example", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/documentation/main/icons/ModuleExampleDiagram.svg", - "type": "image/svg+xml" - }, - "description": "A single zone OCP VPC cluster configured with KMS encryption for cluster data and worker block storage using a KMS encryption key from another account." - } - ] - } + ] + }, + { + "key": "cluster_resource_tags", + "custom_config": { + "type": "array", + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "type": "string" } - ] + } + }, + { + "key": "access_tags", + "custom_config": { + "type": "array", + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "type": "string" + } + } + }, + { + "key": "ocp_entitlement" + }, + { + "key": "cluster_ready_when", + "options": [ + { + "displayname": "Normal", + "value": "Normal" + }, + { + "displayname": "IngressReady", + "value": "IngressReady" + }, + { + "displayname": "OneWorkerNodeReady", + "value": "OneWorkerNodeReady" + }, + { + "displayname": "MasterNodeReady", + "value": "MasterNodeReady" + } + ] + }, + { + "key": "enable_ocp_console" + }, + { + "key": "addons" + }, + { + "key": "manage_all_addons" + }, + { + "key": "additional_worker_pools" + }, + { + "key": "worker_pools_taints" + }, + { + "key": "ignore_worker_pool_size_changes" + }, + { + "key": "allow_default_worker_pool_replacement" + }, + { + "key": "default_worker_pool_labels" + }, + { + "key": "default_worker_pool_secondary_storage" + }, + { + "key": "enable_autoscaling_for_default_pool" + }, + { + "key": "default_pool_minimum_number_of_nodes" + }, + { + "key": "default_pool_maximum_number_of_nodes" + }, + { + "key": "additional_security_group_ids" + }, + { + "key": "existing_subnet_ids" + }, + { + "key": "use_private_endpoint" + }, + { + "key": "disable_public_endpoint" + }, + { + "key": "cluster_config_endpoint_type", + "options": [ + { + "displayname": "default", + "value": "default" + }, + { + "displayname": "private", + "value": "private" + }, + { + "displayname": "vpe", + "value": "vpe" + }, + { + "displayname": "link", + "value": "link" + } + ] + }, + { + "key": "disable_outbound_traffic_protection" + }, + { + "key": "verify_worker_network_readiness" + }, + { + "key": "pod_subnet_cidr" + }, + { + "key": "service_subnet_cidr" + }, + { + "key": "custom_security_group_ids" + }, + { + "key": "attach_ibm_managed_security_group" + }, + { + "key": "additional_lb_security_group_ids" + }, + { + "key": "number_of_lbs" + }, + { + "key": "additional_vpe_security_group_ids" + }, + { + "key": "ibmcloud_kms_api_key" + }, + { + "key": "kms_encryption_enabled_cluster" + }, + { + "key": "existing_kms_instance_crn" + }, + { + "key": "existing_cluster_kms_key_crn" + }, + { + "key": "kms_endpoint_type" + }, + { + "key": "cluster_key_name" + }, + { + "key": "cluster_key_ring_name" + }, + { + "key": "kms_encryption_enabled_boot_volume" + }, + { + "key": "existing_boot_volume_kms_key_crn" + }, + { + "key": "boot_volume_key_name" + }, + { + "key": "boot_volume_key_ring_name" + }, + { + "key": "cbr_rules" + } + ], + "dependencies": [ + { + "name": "deploy-arch-ibm-vpc", + "id": "2af61763-f8ef-4527-a815-b92166f29bc8-global", + "version": "^v7.21.0", + "flavors": [ + "fully-configurable" + ], + "catalog_id": "7a4d68b4-cf8b-40cd-a3d1-f49aff526eb3", + "optional": true, + "on_by_default": true, + "ignore_auto_referencing": [ + "*" + ], + "input_mapping": [ + { + "dependency_input": "prefix", + "version_input": "prefix", + "reference_version": true + }, + { + "dependency_input": "existing_resource_group_name", + "version_input": "existing_resource_group_name", + "reference_version": true + }, + { + "dependency_output": "vpc_crn", + "version_input": "existing_vpc_crn" + } + ] + }, + { + "name": "deploy-arch-ibm-account-infra-base", + "catalog_id": "7a4d68b4-cf8b-40cd-a3d1-f49aff526eb3", + "flavors": [ + "standard" + ], + "id": "63641cec-6093-4b4f-b7b0-98d2f4185cd6-global", + "ignore_auto_referencing": [ + "*" + ], + "input_mapping": [ + { + "dependency_output": "workload_resource_group_name", + "version_input": "existing_resource_group_name" + }, + { + "dependency_input": "prefix", + "version_input": "prefix", + "reference_version": true + } + ], + "optional": true, + "on_by_default": true, + "version": "^v1.18.0" + }, + { + "name": "testing-deploy-arch-ibm-kms", + "id": "85fdbd7a-8c77-4abd-b716-653a31f3aba9-global", + "version": "^v1.2.1", + "flavors": [ + "standard" + ], + "catalog_id": "7a4d68b4-cf8b-40cd-a3d1-f49aff526eb3", + "optional": true, + "on_by_default": true, + "ignore_auto_referencing": [ + "*" + ], + "input_mapping": [ + { + "dependency_input": "kms_encryption_enabled_cluster", + "value": true, + "reference_version": true + }, + { + "dependency_output": "kms_instance_crn", + "version_input": "existing_kms_instance_crn" + }, + { + "dependency_input": "resource_group_name", + "version_input": "existing_resource_group_name", + "reference_version": true + }, + { + "dependency_input": "prefix", + "version_input": "prefix", + "reference_version": true + }, + { + "dependency_input": "use_existing_resource_group", + "value": true, + "reference_version": true + } + ] + }, + { + "name": "deploy-arch-ibm-cos", + "id": "68921490-2778-4930-ac6d-bae7be6cd958-global", + "version": "^v8.20.1", + "flavors": [ + "instance" + ], + "catalog_id": "7a4d68b4-cf8b-40cd-a3d1-f49aff526eb3", + "optional": true, + "on_by_default": true, + "ignore_auto_referencing": [ + "*" + ], + "input_mapping": [ + { + "dependency_output": "cos_instance_id", + "version_input": "existing_cos_instance_crn" + }, + { + "dependency_input": "prefix", + "version_input": "prefix", + "reference_version": true + }, + { + "dependency_input": "resource_group_name", + "version_input": "existing_resource_group_name", + "reference_version": true + }, + { + "dependency_input": "use_existing_resource_group", + "value": true, + "reference_version": true + } + ] + }, + { + "name": "testing-deploy-arch-ibm-observability", + "id": "daf2cf91-2384-4205-b7f4-621299a4896d-global", + "version": "^1.3.0", + "flavors": [ + "standard" + ], + "catalog_id": "7a4d68b4-cf8b-40cd-a3d1-f49aff526eb3", + "optional": true, + "on_by_default": true, + "ignore_auto_referencing": [ + "*" + ], + "input_mapping": [ + { + "dependency_input": "prefix", + "version_input": "prefix", + "reference_version": true + } + ] + }, + { + "name": "testing-deploy-arch-ibm-secrets-manager", + "id": "5f149ae6-d781-460a-977d-c8c4171ad0fa-global", + "version": "^1.2.2", + "flavors": [ + "standard" + ], + "catalog_id": "7a4d68b4-cf8b-40cd-a3d1-f49aff526eb3", + "optional": true, + "on_by_default": true, + "ignore_auto_referencing": [ + "*" + ], + "input_mapping": [ + { + "dependency_input": "prefix", + "version_input": "prefix", + "reference_version": true + }, + { + "dependency_input": "resource_group_name", + "version_input": "existing_resource_group_name", + "reference_version": true + }, + { + "dependency_input": "use_existing_resource_group", + "value": true, + "reference_version": true + } + ] + } + ], + "dependency_version_2": true } - ] + ] + } + ] } diff --git a/images/ocp_icon.svg b/images/ocp_icon.svg new file mode 100644 index 00000000..1bfb4b5d --- /dev/null +++ b/images/ocp_icon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/modules/fscloud/variables.tf b/modules/fscloud/variables.tf index 26d5d4a9..a183d5c3 100644 --- a/modules/fscloud/variables.tf +++ b/modules/fscloud/variables.tf @@ -122,6 +122,7 @@ variable "force_delete_storage" { description = "Flag indicating whether or not to delete attached storage when destroying the cluster - Default: false" default = false } + variable "existing_cos_id" { type = string description = "The COS id of an already existing COS instance" @@ -216,7 +217,7 @@ variable "number_of_lbs" { nullable = false validation { condition = var.number_of_lbs >= 1 - error_message = "Please set the number_of_lbs to a minumum of." + error_message = "Please set the number_of_lbs to a minimum of 1." } } diff --git a/reference-architecture/deployable-architecture-ocp-cluster-qs.svg b/reference-architecture/deployable-architecture-ocp-cluster-qs.svg new file mode 100644 index 00000000..5c0905f2 --- /dev/null +++ b/reference-architecture/deployable-architecture-ocp-cluster-qs.svg @@ -0,0 +1,4 @@ + + + +
IBM Cloud
IBM Cloud
Region
Region
Existing VPC
Existing VPC
Existing Zones
Existing Zones
Existing Subnet
Existing Subnet
OCP Cluster
OCP Cluster
OCP WorkerOCP Worker
Text is not SVG - cannot display
diff --git a/solutions/fully-configurable/DA_docs.md b/solutions/fully-configurable/DA_docs.md new file mode 100644 index 00000000..17581f65 --- /dev/null +++ b/solutions/fully-configurable/DA_docs.md @@ -0,0 +1,227 @@ +# Configuring complex inputs for OCP in IBM Cloud projects + +Several optional input variables in the Red Hat Openshift Cluster [Deployable Architecture](https://cloud.ibm.com/catalog#deployable_architecture) use complex object types. You can specify these inputs when you configure your Deployable Architectures (DA). + +- [Add-ons](#options-with-addons) (`addons`) +- [Manage All Add-ons](#manage-all-add-ons) (`manage_all_addons`) +- [Additional Worker Pools](#options-with-additional-worker-pools) (`additional_worker_pools`) +- [Worker Pool Taints](#options-with-worker-pools-taints) (`worker_pools_taints`) +- [Additional VPE Security IDs](#options-with-additional-vpe-security-group-ids) (`additional_vpe_security_group_ids`) +- [Context Based Restrictions](#options-with-cbr) (`cbr_rules`) + +## Options with Add-ons + +This variable configuration allows you to specify which Red Hat OpenShift add-ons to install on your cluster and the version of each add-on to use. + +- Variable name: `addons` +- Type: An object representing Red Hat OpenShift cluster add-ons. +- Default value: An empty object (`{}`). + +### Supported Add-ons + +- `debug-tool` (optional): The Debug Tool add-on helps diagnose and troubleshoot cluster issues by running tests and gathering information, accessible through the Red Hat OpenShift console. + +- `image-key-synchronizer` (optional): The Image Key Synchronizer add-on enables the deployment of containers using encrypted images by synchronizing image keys, ensuring only authorized users can access and run them. + +- `openshift-data-foundation` (optional): The Red Hat OpenShift Data Foundation (ODF) add-on manages persistent storage for containerized applications with a highly available storage solution. + +- `vpc-file-csi-driver` (optional): The Virtual Private Cloud File Container Storage Interface Driver add-on enables the creation of persistent volume claims for fast, flexible, network-attached, Network File System-based file storage for Virtual Private Cloud. + +- `static-route` (optional): The Static Route add-on allows worker nodes to re-route response packets through a virtual private network or gateway to an Internet Protocol (IP) address in an on-premises data center. + +- `cluster-autoscaler` (optional): The Cluster Autoscaler add-on automatically scales worker pools based on the resource demands of scheduled workloads. + +- `vpc-block-csi-driver` (optional): The Virtual Private Cloud (VPC) Block Container Storage Interface (CSI) Driver add-on enables snapshotting of storage volumes, allowing users to restore data from specific points in time without duplicating the volume. + +- `ibm-storage-operator` (optional): The IBM Storage Operator add-on streamlines the management of storage configuration maps and resources in your cluster. + +- `openshift-ai` (optional): The Red Hat OpenShift AI add-on enables quick deployment of Red Hat OpenShift AI on a Red Hat OpenShift Cluster in IBM Cloud. + +Please refer to [this](https://cloud.ibm.com/docs/containers?topic=containers-supported-cluster-addon-versions) page for information on supported add-ons and their versions. + +### Example for addons configuration + +```hcl +{ + cluster-autoscaler = "1.0.4" + openshift-data-foundation = "4.12.0" + vpc-file-csi-driver = "1.1.0" +} +``` + +## Manage All Add-ons + +The variable `manage_all_addons` determines whether Terraform manages all add-ons in your cluster. This is crucial when working with add-ons. + +- If set to `true`, Terraform will manage all add-ons. This includes updating and removing older versions if you specify a new version in the addons block. + +- If set to `false`, Terraform will only manage the add-ons listed in the addons map, leaving any others unchanged. + +## Options with additional_worker_pools + +This variable defines the worker node pools for your OCP cluster, with each pool having its own configuration settings. + +- Variable name: `additional_worker_pools`. +- Type: A list of objects. Each object represents a worker_pool configuration. +- Default value: An empty list (`[]`). + +### Options for additional_worker_pools + +- `vpc_subnets` (optional): (List) A list of object which specify which all subnets the worker pool should deploy its nodes. + - `id` (required): A unique identifier for the VPC subnet. + - `zone` (required): The zone where the subnet is located. + - `cidr_block` (required): This defines the IP address range for the subnet in CIDR notation. +- `pool_name` (required): The name of the worker pool. +- `machine_type` (required): The machine type for worker nodes. +- `workers_per_zone` (required): Number of worker nodes in each zone of the cluster. +- `operating_system` (required): The operating system installed on the worker nodes. +- `labels` (optional): A set of key-value labels assigned to the worker pool for identification. +- `minSize` (optional): The minimum number of worker nodes allowed in the pool. +- `maxSize` (optional): The maximum number of worker nodes allowed in the pool. +- `secondary_storage` (optional): The secondary storage attached to the worker nodes. Secondary storage is immutable and can't be changed after provisioning. +- `enableAutoscaling` (optional): Set `true` to enable automatic scaling of worker based on workload demand. +- `additional_security_group_ids` (optional): A list of security group IDs that are attached to the worker nodes for additional network security controls. + +### Example for additional_worker_pools configuration + +```hcl +[ + { + pool_name = "logging" + machine_type = "bx2.4x16" + workers_per_zone = 1 + secondary_storage = "300gb.5iops-tier" + operating_system = "REDHAT_9_64" + }, + { + vpc_subnets = [ + { + id = "0717-a4b3c2d1-e5f6-g7h8-i9j0-k1l2m3n4o5p6" # pragma: allowlist secret + zone = "us-south-1" + cidr_block = " "10.10.10.0/24" + }, + { + id = "0717-b4c3d2e1-f5g6-h7i8-j9k0-l1m2n3o4p5q6" # pragma: allowlist secret + zone = "us-south-2" + cidr_block = "10.20.10.0/24" + } + ] + pool_name = "zone-3" + machine_type = "bx2.4x16" + workers_per_zone = 1 + operating_system = "REDHAT_9_64" + } +] +``` + +## Options with worker_pool_taints + +This variable allows you to configure taints for your worker pools in your OCP cluster. + +- Variable name: `worker_pools_taints`. +- Type: An map of list of object. +- Default value: `null`. + +### Options for worker_pool_taints + +- `all` (optional): This applies to all worker pools. Since it's empty (`[]`), no taints are applied globally. +- `default` (optional): Represents the default worker pool. It is also empty, meaning no taints are applied by default. +- `zone-1`(optional): Represents the taint applied to the zone-1 worker pool. + - `key`(optional): The key of the taint that the pod will tolerate. It must match a taint key on a node. + - `value`(optional): This is the value associated with the taint. The pod will tolerate only taints with the same key and value. + - `effect`(optional): Defines what happens to pods that do not tolerate the taint: NoExecute → If a pod does not have this toleration, it will be evicted from the node. This is useful for ensuring only specific workloads run on a node. + +### Example for worker_pool_taints configuration + +```hcl +{ + all = [] + default = [] + zone-1 = [{ + key = "dedicated" + value = "zone-1" + effect = "NoExecute" + }] + zone-2 = [{ + key = "dedicated" + value = "zone-2" + effect = "NoExecute" + }] +} +``` + +## Options with additional_vpe_security_group_ids + +This variable allows you to add extra security groups to the Virtual Private Endpoints (VPEs) that are created with your OCP cluster. + +- Variable name: `additional_vpe_security_group_ids`. +- Type: An object representing a security group. +- Default value: An empty object (`{}`). + +### Options for additional_vpe_security_group_ids + +- `master` (optional): The security group ID for the master node VPE, ensuring secure communication for cluster management. +- `registry` (optional): Security group ID for the container registry VPE, enabling secure access to image repositories. +- `api` (optional): Security group ID for the API VPE, controlling access to API endpoints for the VPC. + +### Example for additional_vpe_security_group_ids configuration + +```hcl +{ + master = ["r042-5fbe77a5-a8a5-4828-8395-5e51124b8a2f"] + registry = ["r042-4bcdbe33-8434-4d74-95ac-fbebaafc62db"] + api = ["r042-e36d58d8-cc9b-4cb6-99a7-d6544f79e584"] +} +``` + +## Options with cbr_rules + +This variable allows you to provide a rule for the target service to enforce access restrictions for the service based on the context of access requests. Contexts are criteria that include the network location of access requests, the endpoint type from where the request is sent, etc. + +- Variable name: `cbr_rules`. +- Type: A list of objects. Allows only one object representing a rule for the target service + - `description` (required): The description of the rule to create. + - `account_id` (required): The IBM Cloud Account ID + - `rule_contexts` (required): (List) The contexts the rule applies to + - `attributes` (optional): (List) Individual context attributes + - `name` (required): The attribute name. + - `value`(required): The attribute value. + + - `enforcement_mode` (required): The rule enforcement mode can have the following values: + - `enabled` - The restrictions are enforced and reported. This is the default. + - `disabled` - The restrictions are disabled. Nothing is enforced or reported. + - `report` - The restrictions are evaluated and reported, but not enforced. + - `operations` (optional): The operations this rule applies to + - `api_types`(required): (List) The API types this rule applies to. + - `api_type_id`(required):The API type ID +- Default value: An empty list (`[]`). + +### Example for cbr_rules + +```hcl +cbr_rules = [ + { + description = "Event Notifications can be accessed from xyz" + account_id = "defc0df06b644a9cabc6e44f55b3880s." + rule_contexts= [{ + attributes = [ + { + name : "endpointType", + value : "private" + }, + { + name = "networkZoneId" + value = "93a51a1debe2674193217209601dde6f" # pragma: allowlist secret + } + ] + } + ] + enforcement_mode = "enabled" + operations = [{ + api_types = [{ + api_type_id = "crn:v1:bluemix:public:context-based-restrictions::::api-type:" + }] + }] + } +] +``` diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md new file mode 100644 index 00000000..677f8ad1 --- /dev/null +++ b/solutions/fully-configurable/README.md @@ -0,0 +1,123 @@ +# Fully-configurable OCP VPC cluster + +This architecture creates a fully-configurable OCP VPC cluster. Also the outbound traffic is allowed, which is required for accessing the Operator Hub. + +The following resources are provisioned by this example: + +- OCP VPC cluster. +- Cluster keys if an existing KMS instance is passed. + + +![ocp-cluster](../../reference-architecture/deployable-architecture-ocp-cluster-qs.svg) + + + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >=1.9.0 | +| [ibm](#requirement\_ibm) | 1.76.2 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| [existing\_boot\_volume\_kms\_key\_crn\_parser](#module\_existing\_boot\_volume\_kms\_key\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [existing\_cluster\_kms\_key\_crn\_parser](#module\_existing\_cluster\_kms\_key\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [existing\_kms\_crn\_parser](#module\_existing\_kms\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [existing\_vpc\_crn\_parser](#module\_existing\_vpc\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [kms](#module\_kms) | terraform-ibm-modules/kms-all-inclusive/ibm | 4.21.2 | +| [ocp\_base](#module\_ocp\_base) | ../.. | n/a | +| [resource\_group](#module\_resource\_group) | terraform-ibm-modules/resource-group/ibm | 1.1.6 | + +### Resources + +| Name | Type | +|------|------| +| [ibm_is_subnet.subnets](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.76.2/docs/data-sources/is_subnet) | data source | +| [ibm_is_subnets.vpc_subnets](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.76.2/docs/data-sources/is_subnets) | data source | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [access\_tags](#input\_access\_tags) | A list of access tags to apply to the resources created by the module. | `list(string)` | `[]` | no | +| [additional\_lb\_security\_group\_ids](#input\_additional\_lb\_security\_group\_ids) | Additional security groups to add to the load balancers associated with the cluster. Ensure that the `number_of_lbs` is set to the number of LBs associated with the cluster. This comes in addition to the IBM maintained security group. | `list(string)` | `[]` | no | +| [additional\_security\_group\_ids](#input\_additional\_security\_group\_ids) | A list of security group IDs that are attached to the worker nodes for additional network security controls. | `list(string)` | `[]` | no | +| [additional\_vpe\_security\_group\_ids](#input\_additional\_vpe\_security\_group\_ids) | Additional security groups to add to all existing load balancers. This comes in addition to the IBM maintained security group. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-additional-vpe-security-group-ids) |
object({
master = optional(list(string), [])
registry = optional(list(string), [])
api = optional(list(string), [])
})
| `{}` | no | +| [additional\_worker\_pools](#input\_additional\_worker\_pools) | List of additional worker pools. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-worker-pools) |
list(object({
vpc_subnets = optional(list(object({
id = string
zone = string
cidr_block = string
})), [])
pool_name = string
machine_type = string
workers_per_zone = number
operating_system = string
labels = optional(map(string))
minSize = optional(number)
secondary_storage = optional(string)
maxSize = optional(number)
enableAutoscaling = optional(bool)
additional_security_group_ids = optional(list(string))
}))
| `[]` | no | +| [addons](#input\_addons) | Map of OCP cluster add-on versions to install (NOTE: The 'vpc-block-csi-driver' add-on is installed by default for VPC clusters and 'ibm-storage-operator' is installed by default in OCP 4.15 and later, however you can explicitly specify it here if you wish to choose a later version than the default one). For full list of all supported add-ons and versions, see https://cloud.ibm.com/docs/containers?topic=containers-supported-cluster-addon-versions. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-addons) |
object({
debug-tool = optional(string)
image-key-synchronizer = optional(string)
openshift-data-foundation = optional(string)
vpc-file-csi-driver = optional(string)
static-route = optional(string)
cluster-autoscaler = optional(string)
vpc-block-csi-driver = optional(string)
ibm-storage-operator = optional(string)
openshift-ai = optional(string)
})
| `{}` | no | +| [allow\_default\_worker\_pool\_replacement](#input\_allow\_default\_worker\_pool\_replacement) | Set to true to allow the module to recreate a default worker pool. Only use in the case where you are getting an error indicating that the default worker pool cannot be replaced on apply. Once the default worker pool is handled separately, if you wish to make any change to the default worker pool which requires the re-creation of the default pool set this variable to true. | `bool` | `false` | no | +| [attach\_ibm\_managed\_security\_group](#input\_attach\_ibm\_managed\_security\_group) | Specify whether to attach the IBM-defined default security group (whose name is kube-) to all worker nodes. Only applicable if `custom_security_group_ids` is set. | `bool` | `true` | no | +| [boot\_volume\_key\_name](#input\_boot\_volume\_key\_name) | The name for the key created for the block storage volumes. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format. | `string` | `"boot-volume-key"` | no | +| [boot\_volume\_key\_ring\_name](#input\_boot\_volume\_key\_ring\_name) | The name for the key ring created for the block storage volumes key. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format. | `string` | `"boot-volume-key-ring"` | no | +| [cbr\_rules](#input\_cbr\_rules) | The list of context-based restriction rules to create. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-cbr) |
list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
tags = optional(list(object({
name = string
value = string
})), [])
operations = optional(list(object({
api_types = list(object({
api_type_id = string
}))
})))
}))
| `[]` | no | +| [cluster\_config\_endpoint\_type](#input\_cluster\_config\_endpoint\_type) | Specify which type of endpoint to use for for cluster config access: 'default', 'private', 'vpe', 'link'. 'default' value will use the default endpoint of the cluster. | `string` | `"default"` | no | +| [cluster\_key\_name](#input\_cluster\_key\_name) | The name of the key to be created for the cluster's Object Storage bucket encryption. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format. | `string` | `"cluster-key"` | no | +| [cluster\_key\_ring\_name](#input\_cluster\_key\_ring\_name) | The name of the key ring to be created for the cluster's Object Storage bucket encryption key. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format. | `string` | `"cluster-key-ring"` | no | +| [cluster\_name](#input\_cluster\_name) | The name of the new IBM Cloud OpenShift Cluster. If a `prefix` input variable is specified, it is added to this name in the `-value` format. | `string` | `"openshift"` | no | +| [cluster\_ready\_when](#input\_cluster\_ready\_when) | The cluster is ready when one of the following: MasterNodeReady (not recommended), OneWorkerNodeReady, Normal, IngressReady. | `string` | `"IngressReady"` | no | +| [cluster\_resource\_tags](#input\_cluster\_resource\_tags) | Metadata labels describing this cluster deployment, i.e. test. | `list(string)` | `[]` | no | +| [custom\_security\_group\_ids](#input\_custom\_security\_group\_ids) | Security groups to add to all worker nodes. This comes in addition to the IBM maintained security group if `attach_ibm_managed_security_group` is set to true. If this variable is set, the default VPC security group is NOT assigned to the worker nodes. | `list(string)` | `null` | no | +| [default\_pool\_maximum\_number\_of\_nodes](#input\_default\_pool\_maximum\_number\_of\_nodes) | The maximum number of worker nodes allowed in the pool, preventing the pool from exceeding three workers. | `number` | `3` | no | +| [default\_pool\_minimum\_number\_of\_nodes](#input\_default\_pool\_minimum\_number\_of\_nodes) | The minimum number of worker nodes allowed in the pool, ensuring at least one worker is always running. | `number` | `1` | no | +| [default\_worker\_pool\_labels](#input\_default\_worker\_pool\_labels) | A set of key-value labels assigned to the worker pool for identification. For Example: { env = "prod", team = "devops" } | `map(string)` | `{}` | no | +| [default\_worker\_pool\_machine\_type](#input\_default\_worker\_pool\_machine\_type) | The machine type for worker nodes.[Learn more](https://cloud.ibm.com/docs/openshift?topic=openshift-vpc-flavors) | `string` | `"bx2.8x32"` | no | +| [default\_worker\_pool\_operating\_system](#input\_default\_worker\_pool\_operating\_system) | The operating system installed on the worker nodes. [Learn more](https://cloud.ibm.com/docs/openshift?topic=openshift-vpc-flavors) | `string` | `"RHEL_9_64"` | no | +| [default\_worker\_pool\_secondary\_storage](#input\_default\_worker\_pool\_secondary\_storage) | The secondary storage attached to the worker nodes. Secondary storage is immutable and can't be changed after provisioning. | `string` | `null` | no | +| [default\_worker\_pool\_workers\_per\_zone](#input\_default\_worker\_pool\_workers\_per\_zone) | Number of worker nodes in each zone of the cluster. | `number` | `2` | no | +| [disable\_outbound\_traffic\_protection](#input\_disable\_outbound\_traffic\_protection) | Whether to allow public outbound access from the cluster workers. This is only applicable for OCP 4.15 and later. | `bool` | `false` | no | +| [disable\_public\_endpoint](#input\_disable\_public\_endpoint) | Whether access to the public service endpoint is disabled when the cluster is created. Does not affect existing clusters. You can't disable a public endpoint on an existing cluster, so you can't convert a public cluster to a private cluster. To change a public endpoint to private, create another cluster with this input set to `true`. | `bool` | `true` | no | +| [enable\_autoscaling\_for\_default\_pool](#input\_enable\_autoscaling\_for\_default\_pool) | Set `true` to enable automatic scaling of worker based on workload demand. | `bool` | `false` | no | +| [enable\_ocp\_console](#input\_enable\_ocp\_console) | Flag to specify whether to enable or disable the OpenShift console. If set to `null` the module will not modify the setting currently set on the cluster. Bare in mind when setting this to `true` or `false` on a cluster with private only endpoint enabled, the runtime must be able to access the private endpoint. | `bool` | `null` | no | +| [existing\_boot\_volume\_kms\_key\_crn](#input\_existing\_boot\_volume\_kms\_key\_crn) | The CRN of an existing KMS key to use to encrypt the the block storage volumes for VPC. If no value is set for this variable, specify a value for either the `existing_kms_instance_crn` variable to create a key ring and key. | `string` | `null` | no | +| [existing\_cluster\_kms\_key\_crn](#input\_existing\_cluster\_kms\_key\_crn) | The CRN of an existing KMS key to use for encrypting the Object Storage of the Cluster. If no value is set for this variable, please specify a value for `existing_kms_instance_crn` variable to create a key ring and key. | `string` | `null` | no | +| [existing\_cos\_instance\_crn](#input\_existing\_cos\_instance\_crn) | The CRN of an already existing Object Storage instance to use for OpenShift internal registry storage. | `string` | n/a | yes | +| [existing\_kms\_instance\_crn](#input\_existing\_kms\_instance\_crn) | The CRN of an existing KMS instance (Hyper Protect Crypto Services or Key Protect). If the KMS instance is in different account you must also provide a value for `ibmcloud_kms_api_key`. | `string` | `null` | no | +| [existing\_resource\_group\_name](#input\_existing\_resource\_group\_name) | The name of an existing resource group to provision the cluster. | `string` | `"Default"` | no | +| [existing\_subnet\_ids](#input\_existing\_subnet\_ids) | The list of IDs of existing subnets where the default worker pool nodes of the cluster will be provisioned. | `list(string)` | `[]` | no | +| [existing\_vpc\_crn](#input\_existing\_vpc\_crn) | The CRN of an existing VPC. If the user provides only the `existing_vpc_crn` the default worker pool will be provisioned across all the subnets in the VPC. | `string` | n/a | yes | +| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud api key. | `string` | n/a | yes | +| [ibmcloud\_kms\_api\_key](#input\_ibmcloud\_kms\_api\_key) | The IBM Cloud API key that can create a root key and key ring in the key management service (KMS) instance for the cluster. If not specified, the 'ibmcloud\_api\_key' variable is used. Specify this key if the KMS instance in `existing_kms_instance_crn` is in an account that is different from the cluster's account. Leave this input empty if both the cluster and the KMS instance are in the same account. | `string` | `null` | no | +| [ignore\_worker\_pool\_size\_changes](#input\_ignore\_worker\_pool\_size\_changes) | Enable if using worker autoscaling. Stops Terraform managing worker count. | `bool` | `false` | no | +| [kms\_encryption\_enabled\_boot\_volume](#input\_kms\_encryption\_enabled\_boot\_volume) | Set this to true to control the encryption keys used to encrypt the data that for the block storage volumes for VPC. If set to false, the data is encrypted by using randomly generated keys. For more info on encrypting block storage volumes, see https://cloud.ibm.com/docs/vpc?topic=vpc-creating-instances-byok | `bool` | `false` | no | +| [kms\_encryption\_enabled\_cluster](#input\_kms\_encryption\_enabled\_cluster) | Set to true to enable KMS encryption for the cluster's Object Storage bucket. When set to true, a value must be passed for either `existing_cluster_kms_key_crn` or `existing_kms_instance_crn`. | `bool` | `false` | no | +| [kms\_endpoint\_type](#input\_kms\_endpoint\_type) | The endpoint for communicating with the KMS instance. Possible values: `public`, `private`. Applies only if `kms_encryption_enabled_cluster` is true | `string` | `"private"` | no | +| [manage\_all\_addons](#input\_manage\_all\_addons) | Instructs deployable architecture to manage all cluster addons, even if addons were installed outside of the module. If set to 'true' this DA will destroy any addons that were installed by other sources. | `bool` | `false` | no | +| [number\_of\_lbs](#input\_number\_of\_lbs) | The number of LBs to associated the `additional_lb_security_group_names` security group with. | `number` | `1` | no | +| [ocp\_entitlement](#input\_ocp\_entitlement) | Value that is applied to the entitlements for OCP cluster provisioning. | `string` | `null` | no | +| [ocp\_version](#input\_ocp\_version) | Version of the OCP cluster to provision. | `string` | `"4.17"` | no | +| [pod\_subnet\_cidr](#input\_pod\_subnet\_cidr) | Specify a custom subnet CIDR to provide private IP addresses for pods. The subnet must have a CIDR of at least `/23` or larger. Default value is `172.30.0.0/16` when the variable is set to `null`. | `string` | `null` | no | +| [prefix](#input\_prefix) | The prefix to add to all resources that this solution creates (e.g `prod`, `test`, `dev`). To not use any prefix value, you can set this value to `null` or an empty string. | `string` | n/a | yes | +| [provider\_visibility](#input\_provider\_visibility) | 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). | `string` | `"private"` | no | +| [service\_subnet\_cidr](#input\_service\_subnet\_cidr) | Specify a custom subnet CIDR to provide private IP addresses for services. The subnet must be at least `/24` or larger. Default value is `172.21.0.0/16` when the variable is set to `null`. | `string` | `null` | no | +| [use\_private\_endpoint](#input\_use\_private\_endpoint) | Set this to true to force all api calls to use the IBM Cloud private endpoints. | `bool` | `true` | no | +| [verify\_worker\_network\_readiness](#input\_verify\_worker\_network\_readiness) | By setting this to true, a script will run kubectl commands to verify that all worker nodes can communicate successfully with the master. If the runtime does not have access to the kube cluster to run kubectl commands, this should be set to false. | `bool` | `true` | no | +| [worker\_pools\_taints](#input\_worker\_pools\_taints) | Optional, Map of lists containing node taints by node-pool name. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-worker-pools-taints) | `map(list(object({ key = string, value = string, effect = string })))` | `null` | no | + +### Outputs + +| Name | Description | +|------|-------------| +| [api\_vpe](#output\_api\_vpe) | Details of the API Virtual Private Endpoint (VPE), if it exists. For more info about schema, see https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/is_virtual_endpoint_gateway | +| [cluster\_crn](#output\_cluster\_crn) | The Cloud Resource Name (CRN) of the provisioned OpenShift cluster. | +| [cluster\_id](#output\_cluster\_id) | The unique identifier assigned to the provisioned OpenShift cluster. | +| [cluster\_name](#output\_cluster\_name) | The name of the provisioned OpenShift cluster. | +| [cos\_crn](#output\_cos\_crn) | The Cloud Resource Name (CRN) of the Object Storage instance associated with the cluster. | +| [ingress\_hostname](#output\_ingress\_hostname) | The hostname assigned to the Cluster's Ingress subdomain for external access. | +| [kms\_config](#output\_kms\_config) | Configuration details for Key Management Service (KMS) used for encryption in the cluster. | +| [master\_status](#output\_master\_status) | The current status of the Kubernetes master node in the cluster. | +| [master\_url](#output\_master\_url) | The API endpoint URL for the Kubernetes master node of the cluster. | +| [master\_vpe](#output\_master\_vpe) | Details of the master, or default Virtual Private Endpoint (VPE). For more info about schema, see https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/is_virtual_endpoint_gateway | +| [ocp\_version](#output\_ocp\_version) | The version of OpenShift running on the provisioned cluster. | +| [operating\_system](#output\_operating\_system) | The operating system used by the worker nodes in the default worker pool. | +| [private\_service\_endpoint\_url](#output\_private\_service\_endpoint\_url) | The Private service endpoint URL for accessing the cluster over a private network. | +| [public\_service\_endpoint\_url](#output\_public\_service\_endpoint\_url) | The public service endpoint URL for accessing the cluster over the internet. | +| [region](#output\_region) | The IBM Cloud region where the cluster is deployed. | +| [registry\_vpe](#output\_registry\_vpe) | Details of the registry Virtual Private Endpoint (VPE), if it exists. For more info about schema, see https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/is_virtual_endpoint_gateway | +| [resource\_group\_id](#output\_resource\_group\_id) | The ID of the resource group where the cluster is deployed. | +| [vpc\_id](#output\_vpc\_id) | The ID of the Virtual Private Cloud (VPC) in which the cluster is deployed. | +| [vpe\_url](#output\_vpe\_url) | The Virtual Private Endpoint (VPE) URL used for private network access to the cluster. | +| [workerpools](#output\_workerpools) | A list of worker pools associated with the provisioned cluster | + diff --git a/solutions/fully-configurable/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template new file mode 100644 index 00000000..eddc88b7 --- /dev/null +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -0,0 +1,6 @@ +{ + "cluster_resource_tags": $TAGS, + "kms_encryption_enabled_cluster": true, + "existing_kms_instance_crn": $HPCS_US_SOUTH_CRN, + "existing_cos_instance_crn": $COS_INSTANCE_CRN +} diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf new file mode 100644 index 00000000..7affa5a8 --- /dev/null +++ b/solutions/fully-configurable/main.tf @@ -0,0 +1,224 @@ +####################################################################################################################### +# Resource Group +####################################################################################################################### +module "resource_group" { + source = "terraform-ibm-modules/resource-group/ibm" + version = "1.1.6" + existing_resource_group_name = var.existing_resource_group_name +} + +####################################################################################################################### +# KMS Key +####################################################################################################################### + +module "existing_kms_crn_parser" { + count = var.existing_kms_instance_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_kms_instance_crn +} + +module "existing_cluster_kms_key_crn_parser" { + count = var.existing_cluster_kms_key_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_cluster_kms_key_crn +} + +module "existing_boot_volume_kms_key_crn_parser" { + count = var.existing_boot_volume_kms_key_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_boot_volume_kms_key_crn +} + +locals { + prefix = var.prefix != null ? trimspace(var.prefix) != "" ? "${var.prefix}-" : "" : "" + cluster_name = "${local.prefix}${var.cluster_name}" + cluster_kms_region = var.existing_kms_instance_crn != null && var.kms_encryption_enabled_cluster ? module.existing_kms_crn_parser[0].region : var.existing_cluster_kms_key_crn != null ? module.existing_cluster_kms_key_crn_parser[0].region : null + cluster_existing_kms_guid = var.existing_kms_instance_crn != null && var.kms_encryption_enabled_cluster ? module.existing_kms_crn_parser[0].service_instance : var.existing_cluster_kms_key_crn != null ? module.existing_cluster_kms_key_crn_parser[0].service_instance : null + cluster_kms_account_id = var.existing_kms_instance_crn != null && var.kms_encryption_enabled_cluster ? module.existing_kms_crn_parser[0].account_id : var.existing_cluster_kms_key_crn != null ? module.existing_cluster_kms_key_crn_parser[0].account_id : null + cluster_kms_key_id = var.existing_kms_instance_crn != null && var.kms_encryption_enabled_cluster ? module.kms[0].keys[format("%s.%s", local.cluster_key_ring_name, local.cluster_key_name)].key_id : var.existing_cluster_kms_key_crn != null ? module.existing_cluster_kms_key_crn_parser[0].resource : null + cluster_key_ring_name = "${local.prefix}${var.cluster_key_ring_name}" + cluster_key_name = "${local.prefix}${var.cluster_key_name}" + + boot_volume_key_ring_name = "${local.prefix}${var.boot_volume_key_ring_name}" + boot_volume_key_name = "${local.prefix}${var.boot_volume_key_name}" + boot_volume_existing_kms_guid = var.existing_kms_instance_crn != null && var.kms_encryption_enabled_boot_volume ? module.existing_kms_crn_parser[0].service_instance : var.existing_boot_volume_kms_key_crn != null ? module.existing_boot_volume_kms_key_crn_parser[0].service_instance : null + boot_volume_kms_account_id = var.existing_kms_instance_crn != null && var.kms_encryption_enabled_boot_volume ? module.existing_kms_crn_parser[0].account_id : var.existing_boot_volume_kms_key_crn != null ? module.existing_boot_volume_kms_key_crn_parser[0].account_id : null + boot_volume_kms_key_id = var.existing_kms_instance_crn != null && var.kms_encryption_enabled_boot_volume ? module.kms[0].keys[format("%s.%s", local.boot_volume_key_ring_name, local.boot_volume_key_name)].key_id : var.existing_boot_volume_kms_key_crn != null ? module.existing_boot_volume_kms_key_crn_parser[0].resource : null + + kms_config = var.kms_encryption_enabled_cluster ? { + crk_id = local.cluster_kms_key_id + instance_id = local.cluster_existing_kms_guid + private_endpoint = var.kms_endpoint_type == "private" ? true : false + account_id = local.cluster_kms_account_id + } : null +} + +locals { + keys = [ + var.kms_encryption_enabled_cluster ? { + key_ring_name = local.cluster_key_ring_name + existing_key_ring = false + keys = [ + { + key_name = local.cluster_key_name + standard_key = false + rotation_interval_month = 3 + dual_auth_delete_enabled = false + force_delete = true + } + ] + } : null, + var.kms_encryption_enabled_boot_volume ? { + key_ring_name = local.boot_volume_key_ring_name + existing_key_ring = false + keys = [ + { + key_name = local.boot_volume_key_name + standard_key = false + rotation_interval_month = 3 + dual_auth_delete_enabled = false + force_delete = true + } + ] + } : null + ] +} + + +# KMS root key for cluster or boot volume +module "kms" { + providers = { + ibm = ibm.kms + } + count = (var.kms_encryption_enabled_boot_volume || var.kms_encryption_enabled_cluster) && var.existing_cluster_kms_key_crn == null ? 1 : 0 + source = "terraform-ibm-modules/kms-all-inclusive/ibm" + version = "4.21.2" + create_key_protect_instance = false + region = local.cluster_kms_region + existing_kms_instance_crn = var.existing_kms_instance_crn + key_ring_endpoint_type = var.kms_endpoint_type + key_endpoint_type = var.kms_endpoint_type + keys = [for key in local.keys : key if key != null] +} + +######################################################################################################################## +# OCP VPC cluster +######################################################################################################################## +module "existing_vpc_crn_parser" { + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_vpc_crn +} + +locals { + vpc_region = module.existing_vpc_crn_parser.region + existing_vpc_id = module.existing_vpc_crn_parser.resource +} + +data "ibm_is_subnets" "vpc_subnets" { + vpc = local.existing_vpc_id +} + +data "ibm_is_subnet" "subnets" { + count = length(var.existing_subnet_ids) > 0 ? length(var.existing_subnet_ids) : 0 + identifier = var.existing_subnet_ids[count.index] +} + +locals { + vpc_subnets = { + # The default behavior is to deploy the worker pool across all subnets within the VPC. + "default" = length(var.existing_subnet_ids) > 0 ? [ + for i in range(length(var.existing_subnet_ids)) : + { + id = data.ibm_is_subnet.subnets[i].id + zone = data.ibm_is_subnet.subnets[i].zone + cidr_block = data.ibm_is_subnet.subnets[i].ipv4_cidr_block + } + ] : [ + for subnet in data.ibm_is_subnets.vpc_subnets.subnets : + { + id = subnet.id + zone = subnet.zone + cidr_block = subnet.ipv4_cidr_block + } + ] + } + + worker_pools = concat([ + { + subnet_prefix = "default" + pool_name = "default" + machine_type = var.default_worker_pool_machine_type + workers_per_zone = var.default_worker_pool_workers_per_zone + resource_group_id = module.resource_group.resource_group_id + operating_system = var.default_worker_pool_operating_system + labels = var.default_worker_pool_labels + minSize = var.default_pool_minimum_number_of_nodes + secondary_storage = var.default_worker_pool_secondary_storage + maxSize = var.default_pool_maximum_number_of_nodes + enableAutoscaling = var.enable_autoscaling_for_default_pool + boot_volume_encryption_kms_config = { + crk = local.boot_volume_kms_key_id + kms_instance_id = local.boot_volume_existing_kms_guid + kms_account_id = local.boot_volume_kms_account_id + } + additional_security_group_ids = var.additional_security_group_ids + } + ], [for pool in var.additional_worker_pools : pool if length(pool.vpc_subnets) > 0], + [for pool in var.additional_worker_pools : { + pool_name = pool.pool_name + machine_type = pool.machine_type + workers_per_zone = pool.workers_per_zone + resource_group_id = pool.resource_group_id + operating_system = pool.operating_system + labels = pool.labels + minSize = pool.minSize + secondary_storage = pool.secondary_storage + maxSize = pool.maxSize + enableAutoscaling = pool.enableAutoscaling + boot_volume_encryption_kms_config = pool.boot_volume_encryption_kms_config + additional_security_group_ids = pool.additional_security_group_ids + subnet_prefix = "default" + } if length(pool.vpc_subnets) == 0]) +} + +module "ocp_base" { + source = "../.." + resource_group_id = module.resource_group.resource_group_id + region = local.vpc_region + tags = var.cluster_resource_tags + cluster_name = local.cluster_name + force_delete_storage = true + use_existing_cos = true + existing_cos_id = var.existing_cos_instance_crn + vpc_id = local.existing_vpc_id + vpc_subnets = local.vpc_subnets + ocp_version = var.ocp_version + worker_pools = local.worker_pools + access_tags = var.access_tags + ocp_entitlement = var.ocp_entitlement + additional_lb_security_group_ids = var.additional_lb_security_group_ids + additional_vpe_security_group_ids = var.additional_vpe_security_group_ids + addons = var.addons + allow_default_worker_pool_replacement = var.allow_default_worker_pool_replacement + attach_ibm_managed_security_group = var.attach_ibm_managed_security_group + cluster_config_endpoint_type = var.cluster_config_endpoint_type + cbr_rules = var.cbr_rules + cluster_ready_when = var.cluster_ready_when + custom_security_group_ids = var.custom_security_group_ids + disable_outbound_traffic_protection = var.disable_outbound_traffic_protection + disable_public_endpoint = var.disable_public_endpoint + enable_ocp_console = var.enable_ocp_console + ignore_worker_pool_size_changes = var.ignore_worker_pool_size_changes + kms_config = local.kms_config + manage_all_addons = var.manage_all_addons + number_of_lbs = var.number_of_lbs + pod_subnet_cidr = var.pod_subnet_cidr + service_subnet_cidr = var.service_subnet_cidr + use_private_endpoint = var.use_private_endpoint + verify_worker_network_readiness = var.verify_worker_network_readiness + worker_pools_taints = var.worker_pools_taints +} diff --git a/solutions/fully-configurable/outputs.tf b/solutions/fully-configurable/outputs.tf new file mode 100644 index 00000000..f38aaa93 --- /dev/null +++ b/solutions/fully-configurable/outputs.tf @@ -0,0 +1,103 @@ +######################################################################################################################## +# Outputs +######################################################################################################################## + +output "cluster_name" { + value = module.ocp_base.cluster_name + description = "The name of the provisioned OpenShift cluster." +} + +output "cluster_id" { + value = module.ocp_base.cluster_id + description = "The unique identifier assigned to the provisioned OpenShift cluster." +} + +output "cluster_crn" { + description = "The Cloud Resource Name (CRN) of the provisioned OpenShift cluster." + value = module.ocp_base.cluster_crn +} + +output "workerpools" { + description = "A list of worker pools associated with the provisioned cluster" + value = module.ocp_base.workerpools +} + +output "ocp_version" { + description = "The version of OpenShift running on the provisioned cluster." + value = module.ocp_base.ocp_version +} + +output "cos_crn" { + description = "The Cloud Resource Name (CRN) of the Object Storage instance associated with the cluster." + value = module.ocp_base.cos_crn +} + +output "vpc_id" { + description = "The ID of the Virtual Private Cloud (VPC) in which the cluster is deployed." + value = module.ocp_base.vpc_id +} + +output "region" { + description = "The IBM Cloud region where the cluster is deployed." + value = module.ocp_base.region +} + +output "resource_group_id" { + description = "The ID of the resource group where the cluster is deployed." + value = module.ocp_base.resource_group_id +} + +output "ingress_hostname" { + description = "The hostname assigned to the Cluster's Ingress subdomain for external access." + value = module.ocp_base.ingress_hostname +} + +output "private_service_endpoint_url" { + description = "The Private service endpoint URL for accessing the cluster over a private network." + value = module.ocp_base.private_service_endpoint_url +} + +output "public_service_endpoint_url" { + description = "The public service endpoint URL for accessing the cluster over the internet." + value = module.ocp_base.public_service_endpoint_url +} + +output "master_url" { + description = "The API endpoint URL for the Kubernetes master node of the cluster." + value = module.ocp_base.master_url +} + +output "vpe_url" { + description = "The Virtual Private Endpoint (VPE) URL used for private network access to the cluster." + value = module.ocp_base.vpe_url +} + +output "kms_config" { + description = "Configuration details for Key Management Service (KMS) used for encryption in the cluster." + value = module.ocp_base.kms_config +} + +output "operating_system" { + description = "The operating system used by the worker nodes in the default worker pool." + value = module.ocp_base.operating_system +} + +output "master_status" { + description = "The current status of the Kubernetes master node in the cluster." + value = module.ocp_base.master_status +} + +output "master_vpe" { + description = "Details of the master, or default Virtual Private Endpoint (VPE). For more info about schema, see https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/is_virtual_endpoint_gateway" + value = module.ocp_base.master_vpe +} + +output "api_vpe" { + description = "Details of the API Virtual Private Endpoint (VPE), if it exists. For more info about schema, see https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/is_virtual_endpoint_gateway" + value = module.ocp_base.api_vpe +} + +output "registry_vpe" { + description = "Details of the registry Virtual Private Endpoint (VPE), if it exists. For more info about schema, see https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/is_virtual_endpoint_gateway" + value = module.ocp_base.registry_vpe +} diff --git a/solutions/fully-configurable/provider.tf b/solutions/fully-configurable/provider.tf new file mode 100644 index 00000000..0c6f84d7 --- /dev/null +++ b/solutions/fully-configurable/provider.tf @@ -0,0 +1,16 @@ +######################################################################################################################## +# Provider config +######################################################################################################################## + +provider "ibm" { + ibmcloud_api_key = var.ibmcloud_api_key + region = local.vpc_region + visibility = var.provider_visibility +} + +provider "ibm" { + alias = "kms" + ibmcloud_api_key = var.ibmcloud_kms_api_key != null ? var.ibmcloud_kms_api_key : var.ibmcloud_api_key + region = local.cluster_kms_region + visibility = var.provider_visibility +} diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf new file mode 100644 index 00000000..d90ee7e8 --- /dev/null +++ b/solutions/fully-configurable/variables.tf @@ -0,0 +1,478 @@ +######################################################################################################################## +# Input variables +######################################################################################################################## + +############################################################## +# General Configuration +############################################################## +variable "ibmcloud_api_key" { + type = string + description = "The IBM Cloud api key." + sensitive = true +} + +variable "prefix" { + type = string + description = "The prefix to add to all resources that this solution creates (e.g `prod`, `test`, `dev`). To not use any prefix value, you can set this value to `null` or an empty string." + nullable = true + validation { + condition = (var.prefix == null ? true : + alltrue([ + can(regex("^[a-z]{0,1}[-a-z0-9]{0,14}[a-z0-9]{0,1}$", var.prefix)), + length(regexall("^.*--.*", var.prefix)) == 0 + ]) + ) + error_message = "Prefix must begin with a lowercase letter, contain only lowercase letters, numbers, and - characters. Prefixes must end with a lowercase letter or number and be 16 or fewer characters." + } +} + +variable "existing_resource_group_name" { + type = string + description = "The name of an existing resource group to provision the cluster." + default = "Default" +} + +variable "cluster_resource_tags" { + type = list(string) + description = "Metadata labels describing this cluster deployment, i.e. test." + default = [] +} + +variable "access_tags" { + type = list(string) + description = "A list of access tags to apply to the resources created by the module." + default = [] +} + +############################################################## +# Cluster Related +############################################################## + +variable "cluster_name" { + type = string + description = "The name of the new IBM Cloud OpenShift Cluster. If a `prefix` input variable is specified, it is added to this name in the `-value` format." + default = "openshift" +} + +variable "ocp_version" { + type = string + description = "Version of the OCP cluster to provision." + default = "4.17" +} + +variable "ocp_entitlement" { + type = string + description = "Value that is applied to the entitlements for OCP cluster provisioning." + default = null +} + +variable "cluster_ready_when" { + type = string + description = "The cluster is ready when one of the following: MasterNodeReady (not recommended), OneWorkerNodeReady, Normal, IngressReady." + default = "IngressReady" +} + +variable "enable_ocp_console" { + description = "Flag to specify whether to enable or disable the OpenShift console. If set to `null` the module will not modify the setting currently set on the cluster. Bare in mind when setting this to `true` or `false` on a cluster with private only endpoint enabled, the runtime must be able to access the private endpoint." + type = bool + default = null + nullable = true +} + +variable "addons" { + type = object({ + debug-tool = optional(string) + image-key-synchronizer = optional(string) + openshift-data-foundation = optional(string) + vpc-file-csi-driver = optional(string) + static-route = optional(string) + cluster-autoscaler = optional(string) + vpc-block-csi-driver = optional(string) + ibm-storage-operator = optional(string) + openshift-ai = optional(string) + }) + description = "Map of OCP cluster add-on versions to install (NOTE: The 'vpc-block-csi-driver' add-on is installed by default for VPC clusters and 'ibm-storage-operator' is installed by default in OCP 4.15 and later, however you can explicitly specify it here if you wish to choose a later version than the default one). For full list of all supported add-ons and versions, see https://cloud.ibm.com/docs/containers?topic=containers-supported-cluster-addon-versions. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-addons)" + nullable = false + default = {} +} + +variable "manage_all_addons" { + type = bool + default = false + nullable = false + description = "Instructs deployable architecture to manage all cluster addons, even if addons were installed outside of the module. If set to 'true' this DA will destroy any addons that were installed by other sources." +} + +variable "worker_pools_taints" { + type = map(list(object({ key = string, value = string, effect = string }))) + description = "Optional, Map of lists containing node taints by node-pool name. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-worker-pools-taints)" + default = null +} + +variable "ignore_worker_pool_size_changes" { + type = bool + description = "Enable if using worker autoscaling. Stops Terraform managing worker count." + default = false +} + +variable "allow_default_worker_pool_replacement" { + type = bool + description = "Set to true to allow the module to recreate a default worker pool. Only use in the case where you are getting an error indicating that the default worker pool cannot be replaced on apply. Once the default worker pool is handled separately, if you wish to make any change to the default worker pool which requires the re-creation of the default pool set this variable to true." + default = false + nullable = false +} + +variable "default_worker_pool_machine_type" { + type = string + description = "The machine type for worker nodes.[Learn more](https://cloud.ibm.com/docs/openshift?topic=openshift-vpc-flavors)" + default = "bx2.8x32" +} + +variable "default_worker_pool_workers_per_zone" { + type = number + description = "Number of worker nodes in each zone of the cluster." + default = 2 +} + +variable "default_worker_pool_operating_system" { + type = string + description = "The operating system installed on the worker nodes. [Learn more](https://cloud.ibm.com/docs/openshift?topic=openshift-vpc-flavors)" + default = "RHEL_9_64" +} + +variable "default_worker_pool_labels" { + type = map(string) + description = "A set of key-value labels assigned to the worker pool for identification. For Example: { env = \"prod\", team = \"devops\" }" + default = {} +} + +variable "default_worker_pool_secondary_storage" { + type = string + description = "The secondary storage attached to the worker nodes. Secondary storage is immutable and can't be changed after provisioning." + default = null + nullable = true +} + +variable "enable_autoscaling_for_default_pool" { + type = bool + description = "Set `true` to enable automatic scaling of worker based on workload demand." + default = false +} + +variable "default_pool_minimum_number_of_nodes" { + type = number + description = "The minimum number of worker nodes allowed in the pool, ensuring at least one worker is always running." + default = 1 +} + +variable "default_pool_maximum_number_of_nodes" { + type = number + description = "The maximum number of worker nodes allowed in the pool, preventing the pool from exceeding three workers." + default = 3 +} + +variable "additional_security_group_ids" { + type = list(string) + description = "A list of security group IDs that are attached to the worker nodes for additional network security controls." + default = [] +} + +variable "additional_worker_pools" { + type = list(object({ + vpc_subnets = optional(list(object({ + id = string + zone = string + cidr_block = string + })), []) + pool_name = string + machine_type = string + workers_per_zone = number + operating_system = string + labels = optional(map(string)) + minSize = optional(number) + secondary_storage = optional(string) + maxSize = optional(number) + enableAutoscaling = optional(bool) + additional_security_group_ids = optional(list(string)) + })) + description = "List of additional worker pools. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-worker-pools)" + default = [] +} + +############################################################## +# COS Related +############################################################## + +variable "existing_cos_instance_crn" { + type = string + description = "The CRN of an already existing Object Storage instance to use for OpenShift internal registry storage." +} + +############################################################## +# Network Related +############################################################## + +variable "existing_vpc_crn" { + type = string + description = "The CRN of an existing VPC. If the user provides only the `existing_vpc_crn` the default worker pool will be provisioned across all the subnets in the VPC." +} + +variable "existing_subnet_ids" { + type = list(string) + description = "The list of IDs of existing subnets where the default worker pool nodes of the cluster will be provisioned." + default = [] +} + +variable "use_private_endpoint" { + type = bool + description = "Set this to true to force all api calls to use the IBM Cloud private endpoints." + default = true +} + +variable "disable_public_endpoint" { + type = bool + description = "Whether access to the public service endpoint is disabled when the cluster is created. Does not affect existing clusters. You can't disable a public endpoint on an existing cluster, so you can't convert a public cluster to a private cluster. To change a public endpoint to private, create another cluster with this input set to `true`." + default = true +} + +variable "cluster_config_endpoint_type" { + description = "Specify which type of endpoint to use for for cluster config access: 'default', 'private', 'vpe', 'link'. 'default' value will use the default endpoint of the cluster." + type = string + default = "default" + nullable = false +} + +variable "disable_outbound_traffic_protection" { + type = bool + description = "Whether to allow public outbound access from the cluster workers. This is only applicable for OCP 4.15 and later." + default = false +} + +variable "verify_worker_network_readiness" { + type = bool + description = "By setting this to true, a script will run kubectl commands to verify that all worker nodes can communicate successfully with the master. If the runtime does not have access to the kube cluster to run kubectl commands, this should be set to false." + default = true +} + +variable "pod_subnet_cidr" { + type = string + description = "Specify a custom subnet CIDR to provide private IP addresses for pods. The subnet must have a CIDR of at least `/23` or larger. Default value is `172.30.0.0/16` when the variable is set to `null`." + default = null +} + +variable "service_subnet_cidr" { + type = string + description = "Specify a custom subnet CIDR to provide private IP addresses for services. The subnet must be at least `/24` or larger. Default value is `172.21.0.0/16` when the variable is set to `null`." + default = null +} + +variable "custom_security_group_ids" { + description = "Security groups to add to all worker nodes. This comes in addition to the IBM maintained security group if `attach_ibm_managed_security_group` is set to true. If this variable is set, the default VPC security group is NOT assigned to the worker nodes." + type = list(string) + default = null +} + +variable "attach_ibm_managed_security_group" { + description = "Specify whether to attach the IBM-defined default security group (whose name is kube-) to all worker nodes. Only applicable if `custom_security_group_ids` is set." + type = bool + default = true +} + +variable "additional_lb_security_group_ids" { + description = "Additional security groups to add to the load balancers associated with the cluster. Ensure that the `number_of_lbs` is set to the number of LBs associated with the cluster. This comes in addition to the IBM maintained security group." + type = list(string) + default = [] + nullable = false +} + +variable "number_of_lbs" { + description = "The number of LBs to associated the `additional_lb_security_group_names` security group with." + type = number + default = 1 + nullable = false +} + +variable "additional_vpe_security_group_ids" { + description = "Additional security groups to add to all existing load balancers. This comes in addition to the IBM maintained security group. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-additional-vpe-security-group-ids)" + type = object({ + master = optional(list(string), []) + registry = optional(list(string), []) + api = optional(list(string), []) + }) + default = {} +} + +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 = "private" + validation { + condition = contains(["public", "private", "public-and-private"], var.provider_visibility) + error_message = "Invalid visibility option. Allowed values are `public`, `private`, or `public-and-private`." + } +} + +############################################################## +# KMS Related +############################################################## +variable "kms_encryption_enabled_cluster" { + description = "Set to true to enable KMS encryption for the cluster's Object Storage bucket. When set to true, a value must be passed for either `existing_cluster_kms_key_crn` or `existing_kms_instance_crn`." + type = bool + default = false + nullable = false + + validation { + condition = var.existing_kms_instance_crn != null ? var.kms_encryption_enabled_cluster : true + error_message = "If passing a value for 'existing_kms_instance_crn', you should set 'kms_encryption_enabled_cluster' to true." + } + + validation { + condition = var.existing_cluster_kms_key_crn != null ? var.kms_encryption_enabled_cluster : true + error_message = "If passing a value for 'existing_cluster_kms_key_crn', you should set 'kms_encryption_enabled_cluster' to true." + } + + validation { + condition = var.kms_encryption_enabled_cluster ? ((var.existing_cluster_kms_key_crn != null || var.existing_kms_instance_crn != null) ? true : false) : true + error_message = "Either 'existing_cluster_kms_key_crn' or 'existing_kms_instance_crn' is required if 'kms_encryption_enabled_cluster' is set to true." + } +} + +variable "existing_kms_instance_crn" { + type = string + default = null + description = "The CRN of an existing KMS instance (Hyper Protect Crypto Services or Key Protect). If the KMS instance is in different account you must also provide a value for `ibmcloud_kms_api_key`." + + validation { + condition = anytrue([ + can(regex("^crn:(.*:){3}(kms|hs-crypto):(.*:){2}[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}::$", var.existing_kms_instance_crn)), + var.existing_kms_instance_crn == null, + ]) + error_message = "The provided KMS instance CRN in the input 'existing_kms_instance_crn' in not valid." + } +} + +variable "existing_cluster_kms_key_crn" { + type = string + default = null + description = "The CRN of an existing KMS key to use for encrypting the Object Storage of the Cluster. If no value is set for this variable, please specify a value for `existing_kms_instance_crn` variable to create a key ring and key." + + validation { + condition = anytrue([ + can(regex("^crn:(.*:){3}(kms|hs-crypto):(.*:){2}[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}:key:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", var.existing_cluster_kms_key_crn)), + var.existing_cluster_kms_key_crn == null, + ]) + error_message = "The provided KMS key CRN in the input 'existing_cluster_kms_key_crn' in not valid." + } + + validation { + condition = var.existing_cluster_kms_key_crn != null ? var.existing_kms_instance_crn == null : true + error_message = "A value should not be passed for 'existing_kms_instance_crn' when passing an existing key value using the 'existing_cluster_kms_key_crn' input." + } + +} + +variable "kms_endpoint_type" { + type = string + description = "The endpoint for communicating with the KMS instance. Possible values: `public`, `private`. Applies only if `kms_encryption_enabled_cluster` is true" + default = "private" + nullable = false + validation { + condition = can(regex("public|private", var.kms_endpoint_type)) + error_message = "The kms_endpoint_type value must be 'public' or 'private'." + } +} + +variable "cluster_key_ring_name" { + type = string + default = "cluster-key-ring" + description = "The name of the key ring to be created for the cluster's Object Storage bucket encryption key. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format." +} + +variable "cluster_key_name" { + type = string + default = "cluster-key" + description = "The name of the key to be created for the cluster's Object Storage bucket encryption. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format." +} + +variable "ibmcloud_kms_api_key" { + type = string + description = "The IBM Cloud API key that can create a root key and key ring in the key management service (KMS) instance for the cluster. If not specified, the 'ibmcloud_api_key' variable is used. Specify this key if the KMS instance in `existing_kms_instance_crn` is in an account that is different from the cluster's account. Leave this input empty if both the cluster and the KMS instance are in the same account." + sensitive = true + default = null +} + +variable "kms_encryption_enabled_boot_volume" { + type = bool + description = "Set this to true to control the encryption keys used to encrypt the data that for the block storage volumes for VPC. If set to false, the data is encrypted by using randomly generated keys. For more info on encrypting block storage volumes, see https://cloud.ibm.com/docs/vpc?topic=vpc-creating-instances-byok" + default = false + nullable = false + + validation { + condition = var.existing_kms_instance_crn != null ? var.kms_encryption_enabled_boot_volume || var.kms_encryption_enabled_cluster : true + error_message = "If passing a value for 'existing_kms_instance_crn', you should set 'kms_encryption_enabled_boot_volume' to true." + } + + validation { + condition = var.existing_boot_volume_kms_key_crn != null ? var.kms_encryption_enabled_boot_volume : true + error_message = "If passing a value for 'existing_boot_volume_kms_key_crn', you should set 'kms_encryption_enabled_boot_volume' to true." + } + + validation { + condition = var.kms_encryption_enabled_boot_volume ? ((var.existing_boot_volume_kms_key_crn != null || var.existing_kms_instance_crn != null) ? true : false) : true + error_message = "Either 'existing_boot_volume_kms_key_crn' or 'existing_kms_instance_crn' is required if 'kms_encryption_enabled_boot_volume' is set to true." + } +} + +variable "existing_boot_volume_kms_key_crn" { + type = string + default = null + description = "The CRN of an existing KMS key to use to encrypt the the block storage volumes for VPC. If no value is set for this variable, specify a value for either the `existing_kms_instance_crn` variable to create a key ring and key." + + validation { + condition = anytrue([ + can(regex("^crn:(.*:){3}(kms|hs-crypto):(.*:){2}[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}:key:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$", var.existing_boot_volume_kms_key_crn)), + var.existing_boot_volume_kms_key_crn == null, + ]) + error_message = "The provided KMS key CRN in the input 'existing_boot_volume_kms_key_crn' in not valid." + } +} + +variable "boot_volume_key_ring_name" { + type = string + default = "boot-volume-key-ring" + description = "The name for the key ring created for the block storage volumes key. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format." +} + +variable "boot_volume_key_name" { + type = string + default = "boot-volume-key" + description = "The name for the key created for the block storage volumes. Applies only if not specifying an existing key. If a prefix input variable is specified, the prefix is added to the name in the `-` format." +} + +############################################################## +# CBR Related +############################################################## + +variable "cbr_rules" { + type = list(object({ + description = string + account_id = string + rule_contexts = list(object({ + attributes = optional(list(object({ + name = string + value = string + }))) })) + enforcement_mode = string + tags = optional(list(object({ + name = string + value = string + })), []) + operations = optional(list(object({ + api_types = list(object({ + api_type_id = string + })) + }))) + })) + description = "The list of context-based restriction rules to create. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-base-ocp-vpc/blob/main/solutions/fully-configurable/DA_docs.md#options-with-cbr)" + default = [] +} diff --git a/solutions/fully-configurable/version.tf b/solutions/fully-configurable/version.tf new file mode 100644 index 00000000..d36e4d9a --- /dev/null +++ b/solutions/fully-configurable/version.tf @@ -0,0 +1,11 @@ +terraform { + required_version = ">=1.9.0" + + # Lock DA into an exact provider version - renovate automation will keep it updated + required_providers { + ibm = { + source = "IBM-Cloud/ibm" + version = "1.76.2" + } + } +} diff --git a/tests/existing-resources/README.md b/tests/existing-resources/README.md new file mode 100644 index 00000000..4bb3621d --- /dev/null +++ b/tests/existing-resources/README.md @@ -0,0 +1 @@ +The terraform code in this directory is used by the existing resource test in tests/pr_test.go diff --git a/tests/existing-resources/main.tf b/tests/existing-resources/main.tf new file mode 100644 index 00000000..2d71acf5 --- /dev/null +++ b/tests/existing-resources/main.tf @@ -0,0 +1,49 @@ +############################################################################# +# Provision Resource Group +############################################################################# +module "resource_group" { + source = "terraform-ibm-modules/resource-group/ibm" + version = "1.1.6" + resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null + existing_resource_group_name = var.resource_group +} + +############################################################################# +# Provision VPC +############################################################################# + +module "vpc" { + source = "terraform-ibm-modules/landing-zone-vpc/ibm" + version = "7.19.1" + resource_group_id = module.resource_group.resource_group_id + region = var.region + name = "vpc" + prefix = var.prefix + tags = var.resource_tags + subnets = { + zone-1 = [ + { + name = "subnet-a" + cidr = "10.10.10.0/24" + public_gateway = true + acl_name = "vpc-acl" + } + ] + } +} + +############################################################################# +# Provision COS +############################################################################# + +module "cos" { + source = "terraform-ibm-modules/cos/ibm" + version = "8.16.5" + resource_group_id = module.resource_group.resource_group_id + region = var.region + cos_instance_name = "${var.prefix}-cos" + cos_tags = var.resource_tags + bucket_name = "${var.prefix}-bucket" + retention_enabled = false + kms_encryption_enabled = false +} diff --git a/tests/existing-resources/outputs.tf b/tests/existing-resources/outputs.tf new file mode 100644 index 00000000..96c4e21d --- /dev/null +++ b/tests/existing-resources/outputs.tf @@ -0,0 +1,33 @@ +######################################################################################################################## +# Outputs +######################################################################################################################## + +output "resource_group_id" { + description = "The id of the resource group where resources are created" + value = module.resource_group.resource_group_id +} + +output "resource_group_name" { + description = "The name of the resource group where resources are created" + value = module.resource_group.resource_group_name +} + +output "vpc_id" { + value = module.vpc.vpc_id + description = "VPC id" +} + +output "vpc_crn" { + value = module.vpc.vpc_crn + description = "VPC crn" +} + +output "cos_crn" { + description = "COS CRN" + value = module.cos.cos_instance_crn +} + +output "cos_instance_id" { + description = "The ID of the Cloud Object Storage instance" + value = module.cos.cos_instance_id +} diff --git a/tests/existing-resources/provider.tf b/tests/existing-resources/provider.tf new file mode 100644 index 00000000..df45ef50 --- /dev/null +++ b/tests/existing-resources/provider.tf @@ -0,0 +1,4 @@ +provider "ibm" { + ibmcloud_api_key = var.ibmcloud_api_key + region = var.region +} diff --git a/tests/existing-resources/variables.tf b/tests/existing-resources/variables.tf new file mode 100644 index 00000000..4b457584 --- /dev/null +++ b/tests/existing-resources/variables.tf @@ -0,0 +1,32 @@ +############################################################################## +# Input variables +############################################################################## + +variable "ibmcloud_api_key" { + type = string + description = "The IBM Cloud API Key" + sensitive = true +} + +variable "region" { + type = string + description = "Region to provision all resources created by this example" + default = "us-south" +} + +variable "prefix" { + type = string + description = "Prefix to append to all resources created by this example" +} + +variable "resource_group" { + 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 "resource_tags" { + type = list(string) + description = "Optional list of tags to be added to created resources" + default = [] +} diff --git a/tests/existing-resources/version.tf b/tests/existing-resources/version.tf new file mode 100644 index 00000000..97b20938 --- /dev/null +++ b/tests/existing-resources/version.tf @@ -0,0 +1,9 @@ +terraform { + required_version = ">= 1.3.0" + required_providers { + ibm = { + source = "ibm-cloud/ibm" + version = ">= 1.64.1" + } + } +} diff --git a/tests/other_test.go b/tests/other_test.go index 7521f0ed..368529eb 100644 --- a/tests/other_test.go +++ b/tests/other_test.go @@ -4,10 +4,60 @@ package test import ( "testing" + "github.com/gruntwork-io/terratest/modules/terraform" "github.com/stretchr/testify/assert" "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testhelper" + "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testschematic" ) +const resourceGroup = "geretain-test-base-ocp-vpc" +const advancedExampleDir = "examples/advanced" +const basicExampleDir = "examples/basic" +const fscloudExampleDir = "examples/fscloud" +const crossKmsSupportExampleDir = "examples/cross_kms_support" +const customsgExampleDir = "examples/custom_sg" + +// Ensure there is one test per supported OCP version +const ocpVersion2 = "4.16" // used by TestCustomSGExample and TestRunCustomsgExample +const ocpVersion3 = "4.15" // used by TestRunAdvancedExample and TestCrossKmsSupportExample +const ocpVersion4 = "4.14" // used by TestRunAddRulesToSGExample and TestRunBasicExample + +func setupOptions(t *testing.T, prefix string, terraformDir string, ocpVersion string) *testhelper.TestOptions { + options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ + Testing: t, + TerraformDir: terraformDir, + Prefix: prefix, + ResourceGroup: resourceGroup, + CloudInfoService: sharedInfoSvc, + TerraformVars: map[string]interface{}{ + "ocp_version": ocpVersion, + "access_tags": permanentResources["accessTags"], + "ocp_entitlement": "cloud_pak", + }, + }) + + return options +} + +func getClusterIngress(options *testhelper.TestOptions) error { + + // Get output of the last apply + outputs, outputErr := terraform.OutputAllE(options.Testing, options.TerraformOptions) + if !assert.NoError(options.Testing, outputErr, "error getting last terraform apply outputs: %s", outputErr) { + return nil + } + + // Validate that the "cluster_name" key is present in the outputs + expectedOutputs := []string{"cluster_name"} + _, ValidationErr := testhelper.ValidateTerraformOutputs(outputs, expectedOutputs...) + + // Proceed with the cluster ingress health check if "cluster_name" is valid + if assert.NoErrorf(options.Testing, ValidationErr, "Some outputs not found or nil: %s", ValidationErr) { + options.CheckClusterIngressHealthyDefaultTimeout(outputs["cluster_name"].(string)) + } + return nil +} + func TestRunBasicExample(t *testing.T) { t.Parallel() @@ -135,3 +185,57 @@ func TestCrossKmsSupportExample(t *testing.T) { assert.NotNil(t, output, "Expected some output") } + +func TestRunAdvancedExample(t *testing.T) { + t.Parallel() + + options := setupOptions(t, "base-ocp-adv", advancedExampleDir, ocpVersion3) + options.PostApplyHook = getClusterIngress + + output, err := options.RunTestConsistency() + + assert.Nil(t, err, "This should not have errored") + assert.NotNil(t, output, "Expected some output") +} + +func TestFSCloudInSchematic(t *testing.T) { + t.Parallel() + + options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ + Testing: t, + Prefix: "base-ocp-fscloud", + TarIncludePatterns: []string{ + "*.tf", + "scripts/*.sh", + "examples/fscloud/*.tf", + "modules/*/*.tf", + "kubeconfig/README.md", + }, + ResourceGroup: resourceGroup, + TemplateFolder: fscloudExampleDir, + Tags: []string{"test-schematic"}, + DeleteWorkspaceOnFail: false, + WaitJobCompleteMinutes: 240, + }) + + // If "jp-osa" was the best region selected, default to us-south instead. + // "jp-osa" is currently not allowing hs-crypto be used for encrypting in that region. + if options.Region == "jp-osa" { + options.Region = "us-south" + } + + options.TerraformVars = []testschematic.TestSchematicTerraformVar{ + {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, + {Name: "region", Value: options.Region, DataType: "string"}, + {Name: "prefix", Value: options.Prefix, DataType: "string"}, + {Name: "resource_group", Value: options.ResourceGroup, DataType: "string"}, + {Name: "hpcs_instance_guid", Value: permanentResources["hpcs_south"], DataType: "string"}, + {Name: "hpcs_key_crn_cluster", Value: permanentResources["hpcs_south_root_key_crn"], DataType: "string"}, + {Name: "hpcs_key_crn_worker_pool", Value: permanentResources["hpcs_south_root_key_crn"], DataType: "string"}, + {Name: "ocp_version", Value: ocpVersion1, DataType: "string"}, + {Name: "ocp_entitlement", Value: "cloud_pak", DataType: "string"}, + } + + err := options.RunSchematicTest() + assert.Nil(t, err, "This should not have errored") +} diff --git a/tests/pr_test.go b/tests/pr_test.go index 427ebdbd..d973f000 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -2,38 +2,36 @@ package test import ( + "fmt" "log" "os" + "strings" "testing" + "github.com/gruntwork-io/terratest/modules/files" + "github.com/gruntwork-io/terratest/modules/logger" + "github.com/gruntwork-io/terratest/modules/random" "github.com/gruntwork-io/terratest/modules/terraform" - "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testschematic" - "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/common" + "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testschematic" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/cloudinfo" "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testhelper" ) -const resourceGroup = "geretain-test-base-ocp-vpc" -const advancedExampleDir = "examples/advanced" -const basicExampleDir = "examples/basic" -const fscloudExampleDir = "examples/fscloud" -const crossKmsSupportExampleDir = "examples/cross_kms_support" -const customsgExampleDir = "examples/custom_sg" +const fullyConfigurableTerraformDir = "solutions/fully-configurable" // Define a struct with fields that match the structure of the YAML data const yamlLocation = "../common-dev-assets/common-go-assets/common-permanent-resources.yaml" // Ensure there is one test per supported OCP version -const ocpVersion1 = "4.17" // used by TestRunUpgradeAdvancedExample , TestFSCloudInSchematic and TestRunMultiClusterExample -const ocpVersion2 = "4.16" // used by TestCustomSGExample and TestRunCustomsgExample -const ocpVersion3 = "4.15" // used by TestRunAdvancedExample and TestCrossKmsSupportExample -const ocpVersion4 = "4.14" // used by TestRunAddRulesToSGExample and TestRunBasicExample +const ocpVersion1 = "4.17" // used by TestRunFullyConfigurable, TestRunUpgradeFullyConfigurable, TestFSCloudInSchematic and TestRunMultiClusterExample -var sharedInfoSvc *cloudinfo.CloudInfoService -var permanentResources map[string]interface{} +var ( + sharedInfoSvc *cloudinfo.CloudInfoService + permanentResources map[string]interface{} +) // TestMain will be run before any parallel tests, used to set up a shared InfoService object to track region usage // for multiple tests @@ -49,104 +47,108 @@ func TestMain(m *testing.M) { os.Exit(m.Run()) } -func setupOptions(t *testing.T, prefix string, terraformDir string, ocpVersion string) *testhelper.TestOptions { - options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ - Testing: t, - TerraformDir: terraformDir, - Prefix: prefix, - ResourceGroup: resourceGroup, - CloudInfoService: sharedInfoSvc, - TerraformVars: map[string]interface{}{ - "ocp_version": ocpVersion, - "access_tags": permanentResources["accessTags"], - "ocp_entitlement": "cloud_pak", - }, - }) - - return options +func validateEnvVariable(t *testing.T, varName string) string { + val, present := os.LookupEnv(varName) + require.True(t, present, "%s environment variable not set", varName) + require.NotEqual(t, "", val, "%s environment variable is empty", varName) + return val } -func TestRunAdvancedExample(t *testing.T) { - t.Parallel() - - options := setupOptions(t, "base-ocp-adv", advancedExampleDir, ocpVersion3) - options.PostApplyHook = getClusterIngress +func setupTerraform(t *testing.T, prefix, realTerraformDir string) *terraform.Options { + tempTerraformDir, err := files.CopyTerraformFolderToTemp(realTerraformDir, prefix) + require.NoError(t, err, "Failed to create temporary Terraform folder") + apiKey := validateEnvVariable(t, "TF_VAR_ibmcloud_api_key") + region, err := testhelper.GetBestVpcRegion(apiKey, "../common-dev-assets/common-go-assets/cloudinfo-region-vpc-gen2-prefs.yaml", "eu-de") + require.NoError(t, err, "Failed to get best VPC region") + + existingTerraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{ + TerraformDir: tempTerraformDir, + Vars: map[string]interface{}{ + "prefix": prefix, + "region": region, + }, + // Set Upgrade to true to ensure latest version of providers and modules are used by terratest. + // This is the same as setting the -upgrade=true flag with terraform. + Upgrade: true, + }) - output, err := options.RunTestConsistency() + terraform.WorkspaceSelectOrNew(t, existingTerraformOptions, prefix) + _, err = terraform.InitAndApplyE(t, existingTerraformOptions) + require.NoError(t, err, "Init and Apply of temp existing resource failed") - assert.Nil(t, err, "This should not have errored") - assert.NotNil(t, output, "Expected some output") + return existingTerraformOptions } -func getClusterIngress(options *testhelper.TestOptions) error { - - // Get output of the last apply - outputs, outputErr := terraform.OutputAllE(options.Testing, options.TerraformOptions) - if !assert.NoError(options.Testing, outputErr, "error getting last terraform apply outputs: %s", outputErr) { - return nil - } - - // Validate that the "cluster_name" key is present in the outputs - expectedOutputs := []string{"cluster_name"} - _, ValidationErr := testhelper.ValidateTerraformOutputs(outputs, expectedOutputs...) - - // Proceed with the cluster ingress health check if "cluster_name" is valid - if assert.NoErrorf(options.Testing, ValidationErr, "Some outputs not found or nil: %s", ValidationErr) { - options.CheckClusterIngressHealthyDefaultTimeout(outputs["cluster_name"].(string)) +func cleanupTerraform(t *testing.T, options *terraform.Options, prefix string) { + if t.Failed() && strings.ToLower(os.Getenv("DO_NOT_DESTROY_ON_FAILURE")) == "true" { + fmt.Println("Terratest failed. Debug the test and delete resources manually.") + return } - return nil + logger.Log(t, "START: Destroy (existing resources)") + terraform.Destroy(t, options) + terraform.WorkspaceDelete(t, options, prefix) + logger.Log(t, "END: Destroy (existing resources)") } -func TestRunUpgradeAdvancedExample(t *testing.T) { +func TestRunFullyConfigurableInSchematics(t *testing.T) { t.Parallel() - options := setupOptions(t, "base-ocp-upg", advancedExampleDir, ocpVersion2) + // Provision resources first + prefix := fmt.Sprintf("ocp-fc-%s", strings.ToLower(random.UniqueId())) + existingTerraformOptions := setupTerraform(t, prefix, "./existing-resources") + + options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ + Testing: t, + Prefix: "ocp-fc", + TarIncludePatterns: []string{"*.tf", fullyConfigurableTerraformDir + "/*.*", "scripts/*.sh", "kubeconfig/README.md"}, + TemplateFolder: fullyConfigurableTerraformDir, + Tags: []string{"test-schematic"}, + DeleteWorkspaceOnFail: false, + }) - output, err := options.RunTestUpgrade() - if !options.UpgradeTestSkipped { - assert.Nil(t, err, "This should not have errored") - assert.NotNil(t, output, "Expected some output") + options.TerraformVars = []testschematic.TestSchematicTerraformVar{ + {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, + {Name: "prefix", Value: options.Prefix, DataType: "string"}, + {Name: "cluster_name", Value: "cluster", DataType: "string"}, + {Name: "ocp_version", Value: ocpVersion1, DataType: "string"}, + {Name: "ocp_entitlement", Value: "cloud_pak", DataType: "string"}, + {Name: "existing_resource_group_name", Value: terraform.Output(t, existingTerraformOptions, "resource_group_name"), DataType: "string"}, + {Name: "existing_cos_instance_crn", Value: terraform.Output(t, existingTerraformOptions, "cos_instance_id"), DataType: "string"}, + {Name: "existing_vpc_crn", Value: terraform.Output(t, existingTerraformOptions, "vpc_crn"), DataType: "string"}, + {Name: "kms_encryption_enabled_cluster", Value: "true", DataType: "bool"}, + {Name: "existing_kms_instance_crn", Value: permanentResources["hpcs_south_crn"], DataType: "string"}, } + require.NoError(t, options.RunSchematicTest(), "This should not have errored") + cleanupTerraform(t, existingTerraformOptions, prefix) } -func TestFSCloudInSchematic(t *testing.T) { +// Upgrade Test does not require KMS encryption +func TestRunUpgradeFullyConfigurable(t *testing.T) { t.Parallel() + // Provision existing resources first + prefix := fmt.Sprintf("ocp-existing-%s", strings.ToLower(random.UniqueId())) + existingTerraformOptions := setupTerraform(t, prefix, "./existing-resources") + options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ - Testing: t, - Prefix: "base-ocp-fscloud", - TarIncludePatterns: []string{ - "*.tf", - "scripts/*.sh", - "examples/fscloud/*.tf", - "modules/*/*.tf", - "kubeconfig/README.md", - }, - ResourceGroup: resourceGroup, - TemplateFolder: fscloudExampleDir, - Tags: []string{"test-schematic"}, - DeleteWorkspaceOnFail: false, - WaitJobCompleteMinutes: 240, + Testing: t, + Prefix: "ocp-fc-upg", + TarIncludePatterns: []string{"*.tf", "scripts/*.sh", "kubeconfig/README.md", fullyConfigurableTerraformDir + "/*.*"}, + TemplateFolder: fullyConfigurableTerraformDir, + Tags: []string{"test-schematic"}, + DeleteWorkspaceOnFail: false, }) - // If "jp-osa" was the best region selected, default to us-south instead. - // "jp-osa" is currently not allowing hs-crypto be used for encrypting in that region. - if options.Region == "jp-osa" { - options.Region = "us-south" - } - options.TerraformVars = []testschematic.TestSchematicTerraformVar{ {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, - {Name: "region", Value: options.Region, DataType: "string"}, {Name: "prefix", Value: options.Prefix, DataType: "string"}, - {Name: "resource_group", Value: options.ResourceGroup, DataType: "string"}, - {Name: "hpcs_instance_guid", Value: permanentResources["hpcs_south"], DataType: "string"}, - {Name: "hpcs_key_crn_cluster", Value: permanentResources["hpcs_south_root_key_crn"], DataType: "string"}, - {Name: "hpcs_key_crn_worker_pool", Value: permanentResources["hpcs_south_root_key_crn"], DataType: "string"}, + {Name: "cluster_name", Value: "cluster", DataType: "string"}, {Name: "ocp_version", Value: ocpVersion1, DataType: "string"}, - {Name: "ocp_entitlement", Value: "cloud_pak", DataType: "string"}, + {Name: "existing_resource_group_name", Value: terraform.Output(t, existingTerraformOptions, "resource_group_name"), DataType: "string"}, + {Name: "existing_cos_instance_crn", Value: terraform.Output(t, existingTerraformOptions, "cos_instance_id"), DataType: "string"}, + {Name: "existing_vpc_crn", Value: terraform.Output(t, existingTerraformOptions, "vpc_crn"), DataType: "string"}, } - err := options.RunSchematicTest() - assert.Nil(t, err, "This should not have errored") + require.NoError(t, options.RunSchematicUpgradeTest(), "This should not have errored") + cleanupTerraform(t, existingTerraformOptions, prefix) } diff --git a/tests/scripts/post-validation-destroy-cos-instance-and-vpc.sh b/tests/scripts/post-validation-destroy-cos-instance-and-vpc.sh new file mode 100755 index 00000000..6ff0d189 --- /dev/null +++ b/tests/scripts/post-validation-destroy-cos-instance-and-vpc.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +############################################################################################################# +# This script is used by the catalog pipeline to destroy the COS instance and VPC, which were provisioned # +# as prerequisites for the fully configurable OCP VPC cluster that is published to the catalog. # +############################################################################################################# + +set -e + +TERRAFORM_SOURCE_DIR="tests/existing-resources" +TF_VARS_FILE="terraform.tfvars" + +( + cd "${TERRAFORM_SOURCE_DIR}" + echo "Destroying pre-requisite COS instance and VPC..." + terraform destroy -input=false -auto-approve -var-file="${TF_VARS_FILE}" || exit 1 + + echo "Post-validation completed successfully." +) diff --git a/tests/scripts/pre-validation-deploy-cos-instance-and-vpc.sh b/tests/scripts/pre-validation-deploy-cos-instance-and-vpc.sh new file mode 100755 index 00000000..e7b4d316 --- /dev/null +++ b/tests/scripts/pre-validation-deploy-cos-instance-and-vpc.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +############################################################################################################ +## This script is used by the catalog pipeline to deploy the VPC instance +## which are the prerequisites for the fully-configurable OCP VPC Cluster. +############################################################################################################ + +set -e + +DA_DIR="solutions/fully-configurable" +TERRAFORM_SOURCE_DIR="tests/existing-resources" +JSON_FILE="${DA_DIR}/catalogValidationValues.json" +TF_VARS_FILE="terraform.tfvars" + +( + cwd=$(pwd) + cd ${TERRAFORM_SOURCE_DIR} + echo "Provisioning pre-requisite VPC instance .." + terraform init || exit 1 + + # $VALIDATION_APIKEY is available in the catalog runtime + { + echo "ibmcloud_api_key=\"${VALIDATION_APIKEY}\"" + echo "prefix=\"ocp-$(openssl rand -hex 2)\"" + } >> ${TF_VARS_FILE} + terraform apply -input=false -auto-approve -var-file=${TF_VARS_FILE} || exit 1 + + existing_resource_group_name="existing_resource_group_name" + existing_resource_group_value=$(terraform output -state=terraform.tfstate -raw resource_group_name) + existing_vpc_crn_name="existing_vpc_crn" + existing_vpc_crn_value=$(terraform output -state=terraform.tfstate -raw vpc_crn) + + echo "Appending '${existing_resource_group_name}' and '${existing_vpc_crn_name}' input variable values to ${JSON_FILE}.." + + cd "${cwd}" + jq -r --arg existing_resource_group_name "${existing_resource_group_name}" \ + --arg existing_resource_group_value "${existing_resource_group_value}" \ + --arg existing_vpc_crn_name "${existing_vpc_crn_name}" \ + --arg existing_vpc_crn_value "${existing_vpc_crn_value}" \ + '. + {($existing_resource_group_name): $existing_resource_group_value,($existing_vpc_crn_name): $existing_vpc_crn_value}' "${JSON_FILE}" > tmpfile && mv tmpfile "${JSON_FILE}" || exit 1 + + echo "Pre-validation completed successfully." +) diff --git a/variables.tf b/variables.tf index 3b1ebfbe..6078a42a 100644 --- a/variables.tf +++ b/variables.tf @@ -125,13 +125,13 @@ variable "worker_pools_taints" { } variable "attach_ibm_managed_security_group" { - description = "Specify whether to attach the IBM-defined default security group (whose name is kube-) to all worker nodes. Only applicable if custom_security_group_ids is set." + description = "Specify whether to attach the IBM-defined default security group (whose name is kube-) to all worker nodes. Only applicable if `custom_security_group_ids` is set." type = bool default = true } variable "custom_security_group_ids" { - description = "Security groups to add to all worker nodes. This comes in addition to the IBM maintained security group if attach_ibm_managed_security_group is set to true. If this variable is set, the default VPC security group is NOT assigned to the worker nodes." + description = "Security groups to add to all worker nodes. This comes in addition to the IBM maintained security group if `attach_ibm_managed_security_group` is set to true. If this variable is set, the default VPC security group is NOT assigned to the worker nodes." type = list(string) default = null validation { @@ -141,7 +141,7 @@ variable "custom_security_group_ids" { } variable "additional_lb_security_group_ids" { - description = "Additional security groups to add to the load balancers associated with the cluster. Ensure that the number_of_lbs is set to the number of LBs associated with the cluster. This comes in addition to the IBM maintained security group." + description = "Additional security groups to add to the load balancers associated with the cluster. Ensure that the `number_of_lbs` is set to the number of LBs associated with the cluster. This comes in addition to the IBM maintained security group." type = list(string) default = [] nullable = false @@ -152,13 +152,13 @@ variable "additional_lb_security_group_ids" { } variable "number_of_lbs" { - description = "The number of LBs to associated the additional_lb_security_group_names security group with." + description = "The number of LBs to associated the `additional_lb_security_group_names` security group with." type = number default = 1 nullable = false validation { condition = var.number_of_lbs >= 1 - error_message = "Please set the number_of_lbs to a minumum of." + error_message = "Please set the number_of_lbs to a minimum of 1." } } @@ -280,7 +280,7 @@ variable "access_tags" { variable "disable_outbound_traffic_protection" { type = bool - description = "Whether to allow public outbound access from the cluster workers. This is only applicable for `ocp_version` 4.15" + description = "Whether to allow public outbound access from the cluster workers. This is only applicable for OCP 4.15 and later." default = false }