diff --git a/.secrets.baseline b/.secrets.baseline index 30a7b446..f917958d 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "go.sum|^.secrets.baseline$", "lines": null }, - "generated_at": "2025-04-01T10:27:06Z", + "generated_at": "2025-04-08T08:01:21Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -82,7 +82,7 @@ "hashed_secret": "8196b86ede820e665b2b8af9c648f4996be99838", "is_secret": false, "is_verified": false, - "line_number": 60, + "line_number": 61, "type": "Secret Keyword", "verified_result": null } diff --git a/ibm_catalog.json b/ibm_catalog.json index b0173005..50b3d86a 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -546,6 +546,458 @@ } ], "dependency_version_2": true + }, + { + "label": "Security enforced", + "name": "security-enforced", + "install_type": "fullstack", + "working_directory": "solutions/security-enforced", + "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/main/reference-architecture/deployable-architecture-ocp-cluster.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 + }, + { + "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": [ + { + "displayname": "4.14", + "value": "4.14" + }, + { + "displayname": "4.15", + "value": "4.15" + }, + { + "displayname": "4.16", + "value": "4.16" + }, + { + "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": "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": "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": "existing_kms_instance_crn" + }, + { + "key": "existing_cluster_kms_key_crn" + }, + { + "key": "cluster_key_name" + }, + { + "key": "cluster_key_ring_name" + }, + { + "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/solutions/security-enforced/README.md b/solutions/security-enforced/README.md new file mode 100644 index 00000000..2b06086a --- /dev/null +++ b/solutions/security-enforced/README.md @@ -0,0 +1,106 @@ +# 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.svg) + + + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >=1.9.0 | +| [ibm](#requirement\_ibm) | 1.76.2 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| [base\_ocp\_vpc](#module\_base\_ocp\_vpc) | ../fully-configurable | n/a | + +### Resources + +No resources. + +### 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\_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 | +| [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 | +| [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 | +| [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 | +| [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/security-enforced/catalogValidationValues.json.template b/solutions/security-enforced/catalogValidationValues.json.template new file mode 100644 index 00000000..7e2f7bba --- /dev/null +++ b/solutions/security-enforced/catalogValidationValues.json.template @@ -0,0 +1,6 @@ +{ + "cluster_resource_tags": $TAGS, + "existing_kms_instance_crn": $HPCS_US_SOUTH_CRN, + "existing_cos_instance_crn": $COS_INSTANCE_CRN, + "prefix": $PREFIX +} diff --git a/solutions/security-enforced/main.tf b/solutions/security-enforced/main.tf new file mode 100644 index 00000000..f40ccbe2 --- /dev/null +++ b/solutions/security-enforced/main.tf @@ -0,0 +1,56 @@ +module "base_ocp_vpc" { + source = "../fully-configurable" + ibmcloud_api_key = var.ibmcloud_api_key + existing_resource_group_name = var.existing_resource_group_name + prefix = var.prefix + provider_visibility = "private" + cluster_resource_tags = var.cluster_resource_tags + access_tags = var.access_tags + cluster_name = var.cluster_name + ocp_version = var.ocp_version + ocp_entitlement = var.ocp_entitlement + cluster_ready_when = var.cluster_ready_when + enable_ocp_console = var.enable_ocp_console + addons = var.addons + manage_all_addons = var.manage_all_addons + worker_pools_taints = var.worker_pools_taints + ignore_worker_pool_size_changes = var.ignore_worker_pool_size_changes + allow_default_worker_pool_replacement = var.allow_default_worker_pool_replacement + default_worker_pool_machine_type = var.default_worker_pool_machine_type + default_worker_pool_workers_per_zone = var.default_worker_pool_workers_per_zone + default_worker_pool_operating_system = var.default_worker_pool_operating_system + default_worker_pool_labels = var.default_worker_pool_labels + default_worker_pool_secondary_storage = var.default_worker_pool_secondary_storage + enable_autoscaling_for_default_pool = var.enable_autoscaling_for_default_pool + default_pool_minimum_number_of_nodes = var.default_pool_minimum_number_of_nodes + default_pool_maximum_number_of_nodes = var.default_pool_maximum_number_of_nodes + additional_security_group_ids = var.additional_security_group_ids + additional_worker_pools = var.additional_worker_pools + existing_cos_instance_crn = var.existing_cos_instance_crn + existing_vpc_crn = var.existing_vpc_crn + existing_subnet_ids = var.existing_subnet_ids + use_private_endpoint = true + disable_public_endpoint = true + cluster_config_endpoint_type = "private" + disable_outbound_traffic_protection = false + verify_worker_network_readiness = var.verify_worker_network_readiness + pod_subnet_cidr = var.pod_subnet_cidr + service_subnet_cidr = var.service_subnet_cidr + custom_security_group_ids = var.custom_security_group_ids + attach_ibm_managed_security_group = var.attach_ibm_managed_security_group + additional_lb_security_group_ids = var.additional_lb_security_group_ids + number_of_lbs = var.number_of_lbs + additional_vpe_security_group_ids = var.additional_vpe_security_group_ids + kms_encryption_enabled_cluster = true + existing_kms_instance_crn = var.existing_kms_instance_crn + existing_cluster_kms_key_crn = var.existing_cluster_kms_key_crn + kms_endpoint_type = "private" + cluster_key_ring_name = var.cluster_key_ring_name + cluster_key_name = var.cluster_key_name + ibmcloud_kms_api_key = var.ibmcloud_kms_api_key + kms_encryption_enabled_boot_volume = true + existing_boot_volume_kms_key_crn = var.existing_boot_volume_kms_key_crn + boot_volume_key_ring_name = var.boot_volume_key_ring_name + boot_volume_key_name = var.boot_volume_key_name + cbr_rules = var.cbr_rules +} diff --git a/solutions/security-enforced/outputs.tf b/solutions/security-enforced/outputs.tf new file mode 100644 index 00000000..ba254280 --- /dev/null +++ b/solutions/security-enforced/outputs.tf @@ -0,0 +1,103 @@ +######################################################################################################################## +# Outputs +######################################################################################################################## + +output "cluster_name" { + value = module.base_ocp_vpc.cluster_name + description = "The name of the provisioned OpenShift cluster." +} + +output "cluster_id" { + value = module.base_ocp_vpc.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.base_ocp_vpc.cluster_crn +} + +output "workerpools" { + description = "A list of worker pools associated with the provisioned cluster" + value = module.base_ocp_vpc.workerpools +} + +output "ocp_version" { + description = "The version of OpenShift running on the provisioned cluster." + value = module.base_ocp_vpc.ocp_version +} + +output "cos_crn" { + description = "The Cloud Resource Name (CRN) of the Object Storage instance associated with the cluster." + value = module.base_ocp_vpc.cos_crn +} + +output "vpc_id" { + description = "The ID of the Virtual Private Cloud (VPC) in which the cluster is deployed." + value = module.base_ocp_vpc.vpc_id +} + +output "region" { + description = "The IBM Cloud region where the cluster is deployed." + value = module.base_ocp_vpc.region +} + +output "resource_group_id" { + description = "The ID of the resource group where the cluster is deployed." + value = module.base_ocp_vpc.resource_group_id +} + +output "ingress_hostname" { + description = "The hostname assigned to the Cluster's Ingress subdomain for external access." + value = module.base_ocp_vpc.ingress_hostname +} + +output "private_service_endpoint_url" { + description = "The Private service endpoint URL for accessing the cluster over a private network." + value = module.base_ocp_vpc.private_service_endpoint_url +} + +output "public_service_endpoint_url" { + description = "The public service endpoint URL for accessing the cluster over the internet." + value = module.base_ocp_vpc.public_service_endpoint_url +} + +output "master_url" { + description = "The API endpoint URL for the Kubernetes master node of the cluster." + value = module.base_ocp_vpc.master_url +} + +output "vpe_url" { + description = "The Virtual Private Endpoint (VPE) URL used for private network access to the cluster." + value = module.base_ocp_vpc.vpe_url +} + +output "kms_config" { + description = "Configuration details for Key Management Service (KMS) used for encryption in the cluster." + value = module.base_ocp_vpc.kms_config +} + +output "operating_system" { + description = "The operating system used by the worker nodes in the default worker pool." + value = module.base_ocp_vpc.operating_system +} + +output "master_status" { + description = "The current status of the Kubernetes master node in the cluster." + value = module.base_ocp_vpc.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.base_ocp_vpc.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.base_ocp_vpc.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.base_ocp_vpc.registry_vpe +} diff --git a/solutions/security-enforced/provider.tf b/solutions/security-enforced/provider.tf new file mode 100644 index 00000000..0c6f84d7 --- /dev/null +++ b/solutions/security-enforced/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/security-enforced/variables.tf b/solutions/security-enforced/variables.tf new file mode 100644 index 00000000..efe3707d --- /dev/null +++ b/solutions/security-enforced/variables.tf @@ -0,0 +1,407 @@ +######################################################################################################################## +# 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 "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 = {} +} + +############################################################## +# KMS Related +############################################################## + +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." + } + + validation { + condition = var.existing_cluster_kms_key_crn != null || var.existing_kms_instance_crn != null + error_message = "A value must be passed for either 'existing_cluster_kms_key_crn' or 'existing_kms_instance_crn'" + } + +} + + +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 "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." + } + + validation { + condition = var.existing_boot_volume_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_boot_volume_kms_key_crn' input." + } + + validation { + condition = var.existing_boot_volume_kms_key_crn != null || var.existing_kms_instance_crn != null + error_message = "A value must be passed for either 'existing_boot_volume_kms_key_crn' or 'existing_kms_instance_crn'" + } +} + +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/security-enforced/version.tf b/solutions/security-enforced/version.tf new file mode 100644 index 00000000..d36e4d9a --- /dev/null +++ b/solutions/security-enforced/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/pr_test.go b/tests/pr_test.go index d973f000..4eee5591 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -21,6 +21,7 @@ import ( ) const fullyConfigurableTerraformDir = "solutions/fully-configurable" +const securityEnforcedTerraformDir = "solutions/security-enforced" // 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" @@ -122,6 +123,37 @@ func TestRunFullyConfigurableInSchematics(t *testing.T) { cleanupTerraform(t, existingTerraformOptions, prefix) } +func TestRunSecurityEnforcedInSchematics(t *testing.T) { + t.Parallel() + + // Provision resources first + prefix := fmt.Sprintf("ocp-se-%s", strings.ToLower(random.UniqueId())) + existingTerraformOptions := setupTerraform(t, prefix, "./existing-resources") + + options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ + Testing: t, + Prefix: "ocp-se", + TarIncludePatterns: []string{"*.tf", securityEnforcedTerraformDir + "/*.*", "scripts/*.sh", "kubeconfig/README.md"}, + TemplateFolder: securityEnforcedTerraformDir, + Tags: []string{"test-schematic"}, + DeleteWorkspaceOnFail: false, + }) + + 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: "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) +} + // Upgrade Test does not require KMS encryption func TestRunUpgradeFullyConfigurable(t *testing.T) { t.Parallel() @@ -152,3 +184,34 @@ func TestRunUpgradeFullyConfigurable(t *testing.T) { require.NoError(t, options.RunSchematicUpgradeTest(), "This should not have errored") cleanupTerraform(t, existingTerraformOptions, prefix) } + +func TestRunUpgradeSecurityEnforced(t *testing.T) { + t.Parallel() + + // Provision existing resources first + prefix := fmt.Sprintf("ocp-se-upg-%s", strings.ToLower(random.UniqueId())) + existingTerraformOptions := setupTerraform(t, prefix, "./existing-resources") + + options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ + Testing: t, + Prefix: "ocp-se-upg", + TarIncludePatterns: []string{"*.tf", "scripts/*.sh", "kubeconfig/README.md", securityEnforcedTerraformDir + "/*.*"}, + TemplateFolder: securityEnforcedTerraformDir, + Tags: []string{"test-schematic"}, + DeleteWorkspaceOnFail: false, + }) + + 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: "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: "existing_kms_instance_crn", Value: permanentResources["hpcs_south_crn"], DataType: "string"}, + } + + require.NoError(t, options.RunSchematicUpgradeTest(), "This should not have errored") + cleanupTerraform(t, existingTerraformOptions, prefix) +}