diff --git a/terraform/data_sources.tf b/terraform/data_sources.tf index 713a2668..1c98e3ab 100644 --- a/terraform/data_sources.tf +++ b/terraform/data_sources.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. data "oci_identity_regions" "home_region" { @@ -209,3 +209,9 @@ data "oci_core_instances" "provisioned_instances" { } } +data "oci_certificates_management_certificate_authority" "root_certificate_authority" { + count = var.configure_secure_mode && var.root_ca_id != "" ? 1 : 0 + #Required + certificate_authority_id = var.root_ca_id +} + diff --git a/terraform/locals.tf b/terraform/locals.tf index d7502c13..6169eba4 100644 --- a/terraform/locals.tf +++ b/terraform/locals.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. locals { @@ -93,7 +93,7 @@ locals { deploy_sample_app = (var.deploy_sample_app && var.wls_edition != "SE") admin_ip_address = local.assign_weblogic_public_ip ? module.compute.instance_public_ips[0] : module.compute.instance_private_ips[0] - admin_console_app_url = format("https://%s:%s/console", local.admin_ip_address, var.wls_extern_ssl_admin_port) + admin_console_app_url = format("https://%s:%s/console", local.admin_ip_address, local.wls_extern_ssl_admin_port) sample_app_protocol = local.add_load_balancer ? "https" : "http" sample_app_url_lb_ip = local.deploy_sample_app && local.add_load_balancer ? format("%s://%s/sample-app", local.sample_app_protocol, local.lb_ip) : "" sample_app_url_wls_ip = local.deploy_sample_app ? format("https://%s:%s/sample-app", local.admin_ip_address, var.wls_ms_extern_ssl_port) : "" @@ -184,4 +184,16 @@ locals { is_rms_private_endpoint_required = var.is_rms_private_endpoint_required && var.wls_existing_vcn_id != "" && var.wls_subnet_id != "" && !local.assign_weblogic_public_ip ? true : false add_new_rms_private_endpoint = local.is_rms_private_endpoint_required && var.add_rms_private_endpoint == "Create New Resource Manager Endpoint" ? true : false add_existing_rms_private_endpoint = local.is_rms_private_endpoint_required && var.add_rms_private_endpoint == "Use Existing Resource Manager Endpoint" ? true : false + + # Secured Production Mode + preserve_boot_properties = var.configure_secure_mode ? var.preserve_boot_properties : true + wls_admin_port = var.configure_secure_mode ? var.administration_port : var.wls_admin_port + keystore_password_id = var.configure_secure_mode ? var.keystore_password_id : "" + root_ca_id = var.configure_secure_mode ? var.root_ca_id : "" + cert_compartment_id = var.cert_compartment_id == "" ? local.network_compartment_id : var.cert_compartment_id + wls_domain_configuration = var.configure_secure_mode ? "Secured Production Mode" : "Production Mode" + wls_extern_ssl_admin_port = var.configure_secure_mode ? var.administration_port : var.wls_extern_ssl_admin_port + wls_admin_user = var.configure_secure_mode ? var.wls_primary_admin_user : var.wls_admin_user + wls_secondary_admin_password_id = var.configure_secure_mode ? var.wls_secondary_admin_password_id : "" + root_ca_compartment_id = var.configure_secure_mode && var.root_ca_id != "" ? data.oci_certificates_management_certificate_authority.root_certificate_authority[0].compartment_id : "" } diff --git a/terraform/main.tf b/terraform/main.tf index e6c1efff..12460dc7 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023,2024, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. ### Removing network validation script from provisioning flow temporarily. @@ -63,9 +63,12 @@ module "network-vcn-config" { wls_extern_ssl_admin_port = var.wls_extern_ssl_admin_port wls_extern_admin_port = var.wls_extern_admin_port wls_expose_admin_port = var.wls_expose_admin_port + wls_admin_ssl_port = var.wls_admin_ssl_port wls_admin_port_source_cidr = var.wls_admin_port_source_cidr - wls_ms_content_port = local.add_load_balancer ? (var.is_idcs_selected ? var.idcs_cloudgate_port : var.wls_ms_extern_port) : var.wls_ms_extern_ssl_port + wls_ms_content_port = local.add_load_balancer ? (var.is_idcs_selected ? var.idcs_cloudgate_port : (var.configure_secure_mode ? var.wls_ms_extern_ssl_port : var.wls_ms_extern_port)) : var.wls_ms_extern_ssl_port assign_backend_public_ip = local.assign_weblogic_public_ip + configure_secure_mode = var.configure_secure_mode + administration_port = var.administration_port wls_subnet_cidr = local.wls_subnet_cidr wls_ms_source_cidrs = local.add_load_balancer ? [local.lb_subnet_1_subnet_cidr] : ["0.0.0.0/0"] @@ -239,6 +242,12 @@ module "policies" { fss_compartment_id = var.fss_compartment_id == "" ? var.compartment_ocid : var.fss_compartment_id mount_target_compartment_id = var.mount_target_compartment_id == "" ? var.compartment_ocid : var.mount_target_compartment_id is_rms_private_endpoint_required = local.is_rms_private_endpoint_required + instance_image_id = var.instance_image_id + configure_secure_mode = var.configure_secure_mode + keystore_password_id = local.keystore_password_id + cert_compartment_id = local.cert_compartment_id + root_ca_compartment_id = local.root_ca_compartment_id + wls_secondary_admin_password_id = local.wls_secondary_admin_password_id } module "bastion" { @@ -464,6 +473,14 @@ module "validators" { provisioned_node_count = length(data.oci_core_instances.provisioned_instances.instances.*.display_name) use_marketplace_image = var.use_marketplace_image wls_edition = var.wls_edition + + # Secured Production Mode + configure_secure_mode = var.configure_secure_mode + keystore_password_id = local.keystore_password_id + root_ca_id = local.root_ca_id + wls_secondary_admin_password_id = local.wls_secondary_admin_password_id + administration_port = var.administration_port + ms_administration_port = var.ms_administration_port } module "fss" { @@ -591,7 +608,7 @@ module "compute" { tf_script_version = var.tf_script_version use_regional_subnet = local.use_regional_subnet wls_14c_jdk_version = var.wls_14c_jdk_version - wls_admin_user = var.wls_admin_user + wls_admin_user = local.wls_admin_user wls_admin_password_id = var.wls_admin_password_id wls_admin_server_name = format("%s_adminserver", local.service_name_prefix) wls_ms_server_name = format("%s_server_", local.service_name_prefix) @@ -604,13 +621,25 @@ module "compute" { wls_machine_name = format("%s_machine_", local.service_name_prefix) wls_extern_admin_port = var.wls_extern_admin_port wls_extern_ssl_admin_port = var.wls_extern_ssl_admin_port - wls_admin_port = var.wls_admin_port + wls_admin_port = local.wls_admin_port wls_admin_ssl_port = var.wls_admin_ssl_port wls_domain_name = format("%s_domain", local.service_name_prefix) wls_server_startup_args = var.wls_server_startup_args wls_existing_vcn_id = var.wls_existing_vcn_id create_policies = var.create_policies + # Secured Production Mode + configure_secure_mode = var.configure_secure_mode + preserve_boot_properties = local.preserve_boot_properties + administration_port = var.administration_port + ms_administration_port = var.ms_administration_port + keystore_password_id = local.keystore_password_id + root_ca_id = local.root_ca_id + cert_compartment_id = local.cert_compartment_id + thread_pool_limit = var.thread_pool_limit + wls_secondary_admin_user = var.wls_secondary_admin_user + wls_secondary_admin_password_id = local.wls_secondary_admin_password_id + #The following two are for adding a dependency on the peering module wls_vcn_peering_dns_resolver_id = element(flatten(concat(module.vcn-peering[*].wls_vcn_dns_resolver_id, [""])), 0) wls_vcn_peering_route_table_attachment_id = local.assign_weblogic_public_ip ? element(flatten(concat(module.vcn-peering[*].wls_vcn_public_route_table_attachment_id, [""])), 0) : element(flatten(concat(module.vcn-peering[*].wls_vcn_private_route_table_attachment_id, [""])), 0) @@ -709,8 +738,11 @@ module "load-balancer-backends" { lb_backendset_name = local.lb_backendset_name num_vm_instances = var.wls_node_count instance_private_ips = module.compute.instance_private_ips - backend_port = var.is_idcs_selected ? var.idcs_cloudgate_port : var.wls_ms_extern_port + backend_port = var.is_idcs_selected ? var.idcs_cloudgate_port : (var.configure_secure_mode ? var.wls_ms_extern_ssl_port : var.wls_ms_extern_port) health_check_url = var.is_idcs_selected ? "/cloudgate" : "/" + + configure_secure_mode = var.configure_secure_mode + root_ca_id = local.root_ca_id } module "observability-logging" { diff --git a/terraform/modules/compute/wls_compute/variables.tf b/terraform/modules/compute/wls_compute/variables.tf index de2b0bed..bd517247 100644 --- a/terraform/modules/compute/wls_compute/variables.tf +++ b/terraform/modules/compute/wls_compute/variables.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023,2024, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. variable "tenancy_id" { @@ -293,3 +293,56 @@ variable "is_ucm_image" { type = bool description = "The metadata info to send it to instance to determine if its ucm image based instance or not" } + +# All the variables under this comment belong to Secured Production Mode +variable "configure_secure_mode" { + type = bool + description = "Set to true to configure a secure WebLogic domain" +} + +variable "preserve_boot_properties" { + type = bool + description = "Set to true to preserve the boot.properties file for administration server and managed servers" +} + +variable "administration_port" { + type = number + description = "The domain-wide administration port to configure a secure WebLogic domain" +} + +variable "ms_administration_port" { + type = number + description = "The administration port for managed servers to configure a secure WebLogic domain" +} + +variable "keystore_dir" { + type = string + description = "The directory where the pkcs12 keystores will be created in the compute instance when secured production mode is enabled." + default = "/u01/data/keystores" +} + +variable "keystore_password_id" { + type = string + description = "The OCID of the vault secret with the password for creating the keystore" +} + +variable "root_ca_id" { + type = string + description = "The OCID of the existing root certificate authority to issue the certificates" +} + +variable "cert_compartment_id" { + type = string + description = "The OCID of the compartment where the certificate will be created. Leave it blank to use the network compartment for the certificate" +} + +variable "thread_pool_limit" { + type = number + description = "Shared Capacity For Work Managers" +} + +variable "certificate_id" { + type = string + description = "The OCID of the SSL certificate to configure a secure WebLogic domain" + default = "" +} \ No newline at end of file diff --git a/terraform/modules/compute/wls_compute/wls_compute.tf b/terraform/modules/compute/wls_compute/wls_compute.tf index 19b3029d..4a0ec1c5 100644 --- a/terraform/modules/compute/wls_compute/wls_compute.tf +++ b/terraform/modules/compute/wls_compute/wls_compute.tf @@ -54,7 +54,6 @@ module "wls-instances" { wls_ms_server_name = var.wls_ms_server_name wls_admin_server_name = var.wls_admin_server_name wls_cluster_name = var.wls_cluster_name - wls_cluster_mc_port = var.wls_cluster_mc_port wls_machine_name = var.wls_machine_name wls_server_startup_args = var.wls_server_startup_args total_vm_count = var.num_vm_instances @@ -69,6 +68,20 @@ module "wls-instances" { is_bastion_instance_required = var.is_bastion_instance_required create_policies = var.create_policies + # Secured Production Mode + configure_secure_mode = var.configure_secure_mode + preserve_boot_properties = var.preserve_boot_properties + administration_port = var.administration_port + ms_administration_port = var.ms_administration_port + keystore_dir = var.keystore_dir + keystore_password_id = var.keystore_password_id + root_ca_id = var.root_ca_id + cert_compartment_id = var.cert_compartment_id + certificate_id = var.certificate_id + thread_pool_limit = var.thread_pool_limit + wls_secondary_admin_user = var.wls_secondary_admin_user + wls_secondary_admin_password_ocid = var.wls_secondary_admin_password_id + user_data = data.template_cloudinit_config.config.rendered mode = var.mode wls_version = var.wls_version diff --git a/terraform/modules/compute/wls_compute/wls_variables.tf b/terraform/modules/compute/wls_compute/wls_variables.tf index 4fab7166..777a77ea 100644 --- a/terraform/modules/compute/wls_compute/wls_variables.tf +++ b/terraform/modules/compute/wls_compute/wls_variables.tf @@ -13,7 +13,8 @@ variable "wls_edition" { variable "wls_admin_user" { type = string - description = "The name of the admin user that will be added to the WebLogic domain" + description = "Name of WebLogic administration user" + default = "weblogic" validation { condition = replace(var.wls_admin_user, "/^[a-zA-Z][a-zA-Z0-9_-]{7,127}/", "0") == "0" error_message = "WLSC-ERROR: The value for wls_admin_user should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters." @@ -137,16 +138,6 @@ variable "wls_ms_ssl_port" { } } -variable "wls_cluster_mc_port" { - type = number - description = "The managed server port on which to send heartbeats and other internal cluster traffic" - default = 5555 - validation { - condition = var.wls_cluster_mc_port > 0 - error_message = "WLSC-ERROR: The value for wls_cluster_mc_port should be greater than 0." - } -} - variable "wls_nm_port" { type = number description = "The listen port number for the node manager process on all compute instances" @@ -170,8 +161,8 @@ variable "provisioning_timeout_mins" { variable "wls_admin_server_wait_timeout_mins" { type = number - description = "Teh timeout in minutes for the administration server to enroll to node manager" - default = 30 + description = "The timeout in minutes for the administration server to enroll to node manager" + default = 10 } variable "wls_version" { @@ -228,3 +219,29 @@ variable "wls_version_to_rcu_component_list_map" { "12.2.1.4" = "MDS,WLS,STB,IAU_APPEND,IAU_VIEWER,UCSUMS,IAU,OPSS" } } + +# All variables under this comment belong to secured production mode +variable "wls_primary_admin_user" { + type = string + description = "Name of primary WebLogic administration user" + default = "wls_user" + validation { + condition = replace(var.wls_primary_admin_user, "/^[a-zA-Z][a-zA-Z0-9_-]{7,127}/", "0") == "0" && !contains(["system", "admin", "administrator", "weblogic"], var.wls_primary_admin_user) + error_message = "WLSC-ERROR: The value for wls_primary_admin_user should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters, and should not be system, admin, administrator, or weblogic." + } +} + +variable "wls_secondary_admin_user" { + type = string + description = "Name of secondary WebLogic administration user" + default = "wls_user_1" + validation { + condition = replace(var.wls_secondary_admin_user, "/^[a-zA-Z][a-zA-Z0-9_-]{7,127}/", "0") == "0" && !contains(["system", "admin", "administrator", "weblogic"], var.wls_secondary_admin_user) + error_message = "WLSC-ERROR: The value for wls_secondary_admin_user should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters, and should not be system, admin, administrator, or weblogic." + } +} + +variable "wls_secondary_admin_password_id" { + type = string + description = "The OCID of the vault secret with the password for secondary WebLogic administration user" +} \ No newline at end of file diff --git a/terraform/modules/lb/backends/lb_backends.tf b/terraform/modules/lb/backends/lb_backends.tf index 939ae35d..8ebb1139 100644 --- a/terraform/modules/lb/backends/lb_backends.tf +++ b/terraform/modules/lb/backends/lb_backends.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. locals { @@ -9,7 +9,7 @@ locals { resource "oci_load_balancer_backend_set" "wls_lb_backendset" { # If using existing load balancer, use per-created backend set of existing lb - count = var.use_existing_lb ? 0 : 1 + count = var.configure_secure_mode ? 0 : var.use_existing_lb ? 0 : 1 name = var.lb_backendset_name load_balancer_id = var.load_balancer_id @@ -27,11 +27,41 @@ resource "oci_load_balancer_backend_set" "wls_lb_backendset" { lb_cookie_session_persistence_configuration {} } +resource "oci_load_balancer_backend_set" "wls_lb_backendset_secure_mode" { + # If using existing load balancer in secured production mode, use per-created backend set of existing lb + count = var.use_existing_lb ? 0 : var.configure_secure_mode ? 1 : 0 + + name = var.lb_backendset_name + load_balancer_id = var.load_balancer_id + policy = var.lb_policy + + health_checker { + port = var.backend_port + protocol = var.lb_protocol + response_body_regex = ".*" + url_path = local.health_check_url_path + return_code = var.return_code + } + + ssl_configuration { + trusted_certificate_authority_ids = [var.root_ca_id] + verify_depth = 1 + verify_peer_certificate = true + } + + # Set the session persistence to lb-session-persistence with all default values. + lb_cookie_session_persistence_configuration {} + + lifecycle { + ignore_changes = [ssl_configuration] + } +} + resource "oci_load_balancer_listener" "wls_lb_listener_https" { count = local.use_https_listener_count load_balancer_id = var.load_balancer_id name = "${var.resource_name_prefix}_https" - default_backend_set_name = var.use_existing_lb ? var.lb_backendset_name : oci_load_balancer_backend_set.wls_lb_backendset[count.index].name + default_backend_set_name = var.use_existing_lb ? var.lb_backendset_name : var.configure_secure_mode ? oci_load_balancer_backend_set.wls_lb_backendset_secure_mode[count.index].name : oci_load_balancer_backend_set.wls_lb_backendset[count.index].name port = var.lb_https_lstr_port protocol = var.lb_protocol rule_set_names = [oci_load_balancer_rule_set.SSL_headers[count.index].name] @@ -51,10 +81,10 @@ resource "oci_load_balancer_listener" "wls_lb_listener_https" { } resource "oci_load_balancer_backend" "wls_lb_backend" { - count = var.use_existing_lb || (length(oci_load_balancer_backend_set.wls_lb_backendset) > 0) ? var.num_vm_instances : 0 + count = var.use_existing_lb || (length(oci_load_balancer_backend_set.wls_lb_backendset) > 0) || (length(oci_load_balancer_backend_set.wls_lb_backendset_secure_mode) > 0) ? var.num_vm_instances : 0 load_balancer_id = var.load_balancer_id - backendset_name = var.use_existing_lb ? var.lb_backendset_name : oci_load_balancer_backend_set.wls_lb_backendset[0].name + backendset_name = var.use_existing_lb ? var.lb_backendset_name : var.configure_secure_mode ? oci_load_balancer_backend_set.wls_lb_backendset_secure_mode[0].name : oci_load_balancer_backend_set.wls_lb_backendset[0].name ip_address = var.instance_private_ips[count.index] port = var.backend_port backup = false diff --git a/terraform/modules/lb/backends/variables.tf b/terraform/modules/lb/backends/variables.tf index 4366d59b..9037155e 100644 --- a/terraform/modules/lb/backends/variables.tf +++ b/terraform/modules/lb/backends/variables.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. variable "instance_private_ips" { @@ -78,3 +78,14 @@ variable "resource_name_prefix" { type = string description = "Prefix used by the WebLogic for OCI instance of which this compute is part" } + +# All the variables under this comment belong to Secured Production Mode +variable "configure_secure_mode" { + type = bool + description = "Set to true to configure a secure WebLogic domain" +} + +variable "root_ca_id" { + type = string + description = "The OCID of the existing root certificate authority to issue the certificates" +} diff --git a/terraform/modules/network-validator/scripts/network_validation.sh b/terraform/modules/network-validator/scripts/network_validation.sh index 29aca75e..7a0ee496 100644 --- a/terraform/modules/network-validator/scripts/network_validation.sh +++ b/terraform/modules/network-validator/scripts/network_validation.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. # # ############################################################################ @@ -24,6 +24,7 @@ WLS_LB_PORT=7003 LB_PORT=443 ADMIN_HTTP_PORT=7001 ADMIN_HTTPS_PORT=7002 +IDCS_PORT= WLS_SUBNET_OCID="" BASTION_SUBNET_OCID="" BASTION_HOST_IP="" @@ -38,6 +39,7 @@ FSS_NSG_OCID="" LPG_OCID="" ALL_IPS="0.0.0.0/0" LB_SOURCE_CIDR="" +SECURE_MODE="false" NETWORK_VALIDATION_MSG="Fix the network validation script errors and re-run the script in the cloud shell" debug=false @@ -611,6 +613,7 @@ while [[ $1 = -?* ]]; do -w|--wlssubnet) shift; WLS_SUBNET_OCID=${1} ;; -p|--http_port) shift; ADMIN_HTTP_PORT=${1} ;; -s|--https_port) shift; ADMIN_HTTPS_PORT=${1} ;; + -c|--idcs_port) shift; IDCS_PORT=${1} ;; -d|--ocidbid) shift; OCIDB_OCID=${1} ;; -P|--ocidbport) shift; DB_PORT=${1} ;; -t|--atpdbid) shift; ATPDB_OCID=${1} ;; @@ -627,6 +630,7 @@ while [[ $1 = -?* ]]; do -o|--lbnsg) shift; LB_NSG_OCID=${1} ;; -e|--fssnsg) shift; FSS_NSG_OCID=${1} ;; -n|--bastionnsg) shift; BASTION_NSG_OCID=${1} ;; + -z|--securemode) shift; SECURE_MODE=${1} ;; --debug) debug=true;; --endopts) shift; break ;; *) "invalid option: '$1'." ; usage >&2; exit 1 ;; @@ -658,6 +662,30 @@ if ${debug}; then set -x ; fi # This way you can catch the error in case mysqldump fails in `mysqldump |gzip`, for example. set -o pipefail +# Setting the WLS LB port when IDCS is enabled +if [[ -n ${IDCS_PORT} ]] +then + WLS_LB_PORT=${IDCS_PORT} +fi + +# Convert to lowercase for case insensitive check +secure_mode=$(echo "$SECURE_MODE" | tr '[:upper:]' '[:lower:]') + +# Change the default value of ports for secured production mode +if [ "$secure_mode" = "true" ]; then + if [ "${WLS_LB_PORT}" -eq 7003 ] + then + WLS_LB_PORT=7004 + fi + + if [ "${ADMIN_HTTPS_PORT}" -eq 7002 ] + then + ADMIN_HTTPS_PORT=9002 + fi + + T3_PORT=9072 +fi + ### Validate all required params are present ### # Required for validating existing subnets @@ -802,6 +830,21 @@ then then echo "WARNING: Exposing the WebLogic administrator port [${ADMIN_HTTPS_PORT}] in the subnet [{$WLS_SUBNET_OCID}] to the internet [${ALL_IPS}] allows any user to access the WebLogic console, which is not a recommended practice. Ensure that only a specific CIDR range can access the WebLogic console. ${NETWORK_VALIDATION_MSG}" fi + + # Check if Administration Port is open for access by WLS subnet CIDR for secure mode + if [ "$secure_mode" = "true" ]; then + res=$(validate_subnet_port_access ${WLS_SUBNET_OCID} ${ADMIN_HTTPS_PORT} ${wls_subnet_cidr_block}) + if [[ $res == *"WARNING"* ]] + then + for warning in "${res[@]}"; do + echo "$warning" + done + elif [[ $res -ne 0 ]] + then + echo "ERROR: Port ${ADMIN_HTTPS_PORT} is not open for access by WLS Subnet CIDR [$wls_subnet_cidr_block] in WLS Subnet [$WLS_SUBNET_OCID]. ${NETWORK_VALIDATION_MSG}" + validation_return_code=2 + fi + fi fi ### Validation - Only when WLS Subnet OCID, Admin Server NSG & Managed Server NSG are provided ### @@ -859,6 +902,21 @@ then then echo "WARNING: Exposing the WebLogic administrator port [${ADMIN_HTTPS_PORT}] in the Admin Server NSG [{$ADMIN_SRV_NSG_OCID}] to the internet [${ALL_IPS}] allows any user to access the WebLogic console, which is not a recommended practice. Ensure that only a specific CIDR range can access the WebLogic console. ${NETWORK_VALIDATION_MSG}" fi + + # Check if Administration Port is open for access by WLS subnet CIDR in Managed Server NSG for secure mode + if [ "$secure_mode" = "true" ]; then + res=$(check_tcp_port_open_in_seclist_or_nsg $MANAGED_SRV_NSG_OCID ${ADMIN_HTTPS_PORT} "$wls_subnet_cidr_block" "nsg") + if [[ $res == *"WARNING"* ]] + then + for warning in "${res[@]}"; do + echo "$warning" + done + elif [[ $res -ne 0 ]] + then + echo "ERROR: Port ${ADMIN_HTTPS_PORT} is not open for access by WLS Subnet CIDR [$wls_subnet_cidr_block] in Managed Server NSG [$MANAGED_SRV_NSG_OCID]. ${NETWORK_VALIDATION_MSG}" + validation_return_code=2 + fi + fi fi ### Validation - Only when OCI DB OCID is provided ### @@ -1019,6 +1077,39 @@ then fi fi fi + + # In secured production mode, Check if bastion Host IP CIDR or Bastion Subnet CIDR has access to Administration Port on WLS subnet or Admin Server NSG + if [ "$secure_mode" = "true" ]; then + if [[ -z ${ADMIN_SRV_NSG_OCID} && -z ${MANAGED_SRV_NSG_OCID} ]] + then + res=$(validate_subnet_port_access ${WLS_SUBNET_OCID} ${ADMIN_HTTPS_PORT} ${bastion_cidr_block}) + if [[ $res == *"WARNING"* ]] + then + for warning in "${res[@]}"; do + echo "$warning" + done + elif [[ $res -ne 0 ]] + then + echo "ERROR: Port ${ADMIN_HTTPS_PORT} is not open for access by [$bastion_cidr_block] in WLS Subnet [$WLS_SUBNET_OCID]. ${NETWORK_VALIDATION_MSG}" + validation_return_code=2 + fi + fi + + if [[ -n ${ADMIN_SRV_NSG_OCID} && -n ${MANAGED_SRV_NSG_OCID} ]] + then + res=$(check_tcp_port_open_in_seclist_or_nsg $ADMIN_SRV_NSG_OCID ${ADMIN_HTTPS_PORT} ${bastion_cidr_block} "nsg") + if [[ $res == *"WARNING"* ]] + then + for warning in "${res[@]}"; do + echo "$warning" + done + elif [[ $res -ne 0 ]] + then + echo "ERROR: Port ${ADMIN_HTTPS_PORT} is not open for access by [$bastion_cidr_block] in Admin Server NSG [$ADMIN_SRV_NSG_OCID]. ${NETWORK_VALIDATION_MSG}" + validation_return_code=2 + fi + fi + fi fi fi diff --git a/terraform/modules/network/vcn-config/locals.tf b/terraform/modules/network/vcn-config/locals.tf index 72e19d7b..0c9e837e 100644 --- a/terraform/modules/network/vcn-config/locals.tf +++ b/terraform/modules/network/vcn-config/locals.tf @@ -1,8 +1,9 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. locals { port_for_ingress_lb_security_rule = 443 wls_admin_port_source_cidrs = var.wls_expose_admin_port ? [var.wls_admin_port_source_cidr] : [] nat_gw_exists = length(var.existing_nat_gateway_ids) == 0 ? false : true + ssl_admin_port = var.configure_secure_mode ? var.administration_port : var.wls_extern_ssl_admin_port } diff --git a/terraform/modules/network/vcn-config/nsg_security_rule.tf b/terraform/modules/network/vcn-config/nsg_security_rule.tf index 5d9c44f1..cadaeb9c 100644 --- a/terraform/modules/network/vcn-config/nsg_security_rule.tf +++ b/terraform/modules/network/vcn-config/nsg_security_rule.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. resource "oci_core_network_security_group_security_rule" "bastion_ingress_security_rule" { @@ -61,7 +61,18 @@ resource "oci_core_network_security_group_security_rule" "wls_ingress_security_r } resource "oci_core_network_security_group_security_rule" "wls_ingress_internal_security_rule" { + count = var.configure_secure_mode ? 0 : 1 + network_security_group_id = element(var.nsg_ids["managed_nsg_id"], 0) + direction = "INGRESS" + protocol = "6" + + source = var.wls_subnet_cidr + source_type = "CIDR_BLOCK" + stateless = false +} +resource "oci_core_network_security_group_security_rule" "wls_ingress_internal_security_rule_secure_mode" { + count = var.configure_secure_mode ? 1 : 0 network_security_group_id = element(var.nsg_ids["managed_nsg_id"], 0) direction = "INGRESS" protocol = "6" @@ -69,6 +80,31 @@ resource "oci_core_network_security_group_security_rule" "wls_ingress_internal_s source = var.wls_subnet_cidr source_type = "CIDR_BLOCK" stateless = false + + tcp_options { + destination_port_range { + min = var.administration_port + max = var.administration_port + } + } +} + +resource "oci_core_network_security_group_security_rule" "wls_ingress_internal_ssl_security_rule_secure_mode" { + count = var.configure_secure_mode ? 1 : 0 + network_security_group_id = element(var.nsg_ids["managed_nsg_id"], 0) + direction = "INGRESS" + protocol = "6" + + source = var.wls_subnet_cidr + source_type = "CIDR_BLOCK" + stateless = false + + tcp_options { + destination_port_range { + min = var.wls_admin_ssl_port + max = var.wls_admin_ssl_port + } + } } resource "oci_core_network_security_group_security_rule" "wls_ingress_app_ms_security_rule" { @@ -155,8 +191,8 @@ resource "oci_core_network_security_group_security_rule" "wls_admin_bastion_ingr tcp_options { destination_port_range { - max = var.wls_extern_ssl_admin_port - min = var.wls_extern_ssl_admin_port + max = local.ssl_admin_port + min = local.ssl_admin_port } } } @@ -173,8 +209,8 @@ resource "oci_core_network_security_group_security_rule" "wls_admin_existing_bas tcp_options { destination_port_range { - max = var.wls_extern_ssl_admin_port - min = var.wls_extern_ssl_admin_port + max = local.ssl_admin_port + min = local.ssl_admin_port } } } diff --git a/terraform/modules/network/vcn-config/variables.tf b/terraform/modules/network/vcn-config/variables.tf index 8fd4290a..68abaca4 100644 --- a/terraform/modules/network/vcn-config/variables.tf +++ b/terraform/modules/network/vcn-config/variables.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. variable "compartment_id" { @@ -206,3 +206,17 @@ variable "add_existing_mount_target" { default = false } +variable "configure_secure_mode" { + type = bool + description = "Set to true to configure a secure WebLogic domain" +} + +variable "administration_port" { + type = number + description = "The domain-wide administration port to configure a secure WebLogic domain" +} + +variable "wls_admin_ssl_port" { + type = number + description = "The administration server port for T3s protocol" +} \ No newline at end of file diff --git a/terraform/modules/policies/locals.tf b/terraform/modules/policies/locals.tf index d21ca739..bcb12c85 100644 --- a/terraform/modules/policies/locals.tf +++ b/terraform/modules/policies/locals.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. locals { @@ -79,6 +79,7 @@ locals { autoscaling_statement26 = var.use_autoscaling ? length(oci_identity_dynamic_group.wlsc_functions_principal_group) > 0 ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_functions_principal_group[0].name} to manage policies in tenancy" : "" : "" autoscaling_statement27 = var.use_autoscaling ? length(oci_identity_dynamic_group.wlsc_functions_principal_group) > 0 ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_functions_principal_group[0].name} to use tag-namespaces in tenancy" : "" : "" autoscaling_statement28 = var.use_autoscaling && var.network_compartment_id != var.compartment_id && var.is_rms_private_endpoint_required ? length(oci_identity_dynamic_group.wlsc_functions_principal_group) > 0 ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_functions_principal_group[0].name} to manage orm-family in compartment id ${var.network_compartment_id}" : "" : "" + autoscaling_statement29 = (var.use_autoscaling && var.instance_image_id != "") ? length(oci_identity_dynamic_group.wlsc_functions_principal_group) > 0 ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_functions_principal_group[0].name} to {INSTANCE_IMAGE_READ} in tenancy where target.image.id='${var.instance_image_id}'" : "" : "" autoscaling_atp_policy_statement = (var.atp_db.is_atp && var.use_autoscaling) ? length(oci_identity_dynamic_group.wlsc_functions_principal_group) > 0 ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_functions_principal_group[0].name} to inspect autonomous-transaction-processing-family in compartment id ${var.atp_db.compartment_id}" : "" : "" autoscaling_db_policy_statement = (local.is_oci_db && var.use_autoscaling) ? length(oci_identity_dynamic_group.wlsc_functions_principal_group) > 0 ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_functions_principal_group[0].name} to inspect database-family in compartment id ${var.oci_db.compartment_id}" : "" : "" autoscaling_fss_mount_target_policy_statement = (var.add_fss && var.use_autoscaling) ? length(oci_identity_dynamic_group.wlsc_functions_principal_group) > 0 ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_functions_principal_group[0].name} to manage mount-targets in compartment id ${var.mount_target_compartment_id}" : "" : "" @@ -99,7 +100,7 @@ locals { local.autoscaling_statement18, local.autoscaling_statement19, local.autoscaling_statement20, local.autoscaling_statement21, local.autoscaling_statement22, local.autoscaling_statement23, local.autoscaling_statement24, local.autoscaling_statement25, local.autoscaling_statement26, - local.autoscaling_statement27, local.autoscaling_statement28, + local.autoscaling_statement27, local.autoscaling_statement28, local.autoscaling_statement29, local.autoscaling_logging_policy_1, local.autoscaling_logging_policy_2, local.autoscaling_logging_policy_3, local.autoscaling_atp_policy_statement, local.autoscaling_db_policy_statement, @@ -108,8 +109,20 @@ locals { local.autoscaling_fss_export_sets_policy_statement ]) + #Policies for creating wildcard certificate to configure SSL in secured production mode + secure_mode_statement1 = var.configure_secure_mode ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_instance_principal_group.name} to use certificate-authority-delegates in compartment id ${var.cert_compartment_id}" : "" + secure_mode_statement2 = var.configure_secure_mode ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_instance_principal_group.name} to manage leaf-certificates in compartment id ${var.cert_compartment_id}" : "" + secure_mode_statement3 = var.configure_secure_mode ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_instance_principal_group.name} to read leaf-certificate-bundles in compartment id ${var.cert_compartment_id} where target.leaf-certificate.bundle-type = 'CERTIFICATE_CONTENT_PUBLIC_ONLY'" : "" + secure_mode_statement4 = var.configure_secure_mode ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_instance_principal_group.name} to read certificate-authorities in compartment id ${var.root_ca_compartment_id}" : "" + secure_mode_statement5 = (var.configure_secure_mode && var.use_autoscaling) ? length(oci_identity_dynamic_group.wlsc_functions_principal_group) > 0 ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_functions_principal_group[0].name} to read certificate-authorities in compartment id ${var.root_ca_compartment_id}" : "" : "" + + #Policy for reading keystore password secret + secure_mode_secrets_policy_statement1 = (var.configure_secure_mode && var.keystore_password_id != "" && var.wls_secondary_admin_password_id != "" && var.keystore_password_id != var.wls_admin_password_id && var.keystore_password_id != var.wls_secondary_admin_password_id) ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_instance_principal_group.name} to read secret-bundles in tenancy where target.secret.id = '${var.keystore_password_id}'" : "" + secure_mode_secrets_policy_statement2 = (var.configure_secure_mode && var.wls_secondary_admin_password_id != "" && var.wls_admin_password_id != var.wls_secondary_admin_password_id) ? "Allow dynamic-group ${oci_identity_dynamic_group.wlsc_instance_principal_group.name} to read secret-bundles in tenancy where target.secret.id = '${var.wls_secondary_admin_password_id}'" : "" + secure_mode_statement = compact([local.secure_mode_statement1, local.secure_mode_statement2, local.secure_mode_statement3, local.secure_mode_statement4, local.secure_mode_statement5, local.secure_mode_secrets_policy_statement1, local.secure_mode_secrets_policy_statement2]) + #TODO: When other categories with more statements are added here, concat them with service_statements - policy_statements = concat(local.service_statements, local.cloning_policy_statement, local.autoscaling_statements) + policy_statements = concat(local.service_statements, local.cloning_policy_statement, local.autoscaling_statements, local.secure_mode_statement) reserved_ips_info = var.compartment_id == "" ? [{ id = var.resource_name_prefix }] : [] diff --git a/terraform/modules/policies/variables.tf b/terraform/modules/policies/variables.tf index cb332fc6..68311c2f 100644 --- a/terraform/modules/policies/variables.tf +++ b/terraform/modules/policies/variables.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. variable "tenancy_id" { @@ -192,3 +192,34 @@ variable "is_rms_private_endpoint_required" { type = bool description = "Set resource manager private endpoint" } + +variable "instance_image_id" { + type = string + description = "The OCID of the compute image used to create the WebLogic compute instances" + default = "" +} + +variable "configure_secure_mode" { + type = bool + description = "Set to true to configure a secure WebLogic domain" +} + +variable "keystore_password_id" { + type = string + description = "The OCID of the vault secret with the password for creating the keystore" +} + +variable "cert_compartment_id" { + type = string + description = "The OCID of the compartment where the certificate will be created. Leave it blank to use the network compartment for the certificate" +} + +variable "root_ca_compartment_id" { + type = string + description = "The OCID of the compartment where the root certificate authority exists" +} + +variable "wls_secondary_admin_password_id" { + type = string + description = "The OCID of the vault secret with the password for secondary WebLogic administration user" +} diff --git a/terraform/modules/validators/validators.tf b/terraform/modules/validators/validators.tf index d28d0c4d..e2c0e72a 100644 --- a/terraform/modules/validators/validators.tf +++ b/terraform/modules/validators/validators.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. locals { @@ -60,4 +60,27 @@ locals { invalid_script_version = var.mode == "PROD" && var.tf_script_version == "" script_version_msg = "WLSC-ERROR: The value for tf script version cannot be empty. Please provide valid script version that matches with version on the image." validate_script_version = local.invalid_script_version ? local.validators_msg_map[local.script_version_msg] : null + + # Validations related to Secured Production Mode + missing_keystore_password_id = var.configure_secure_mode && var.keystore_password_id == "" + keystore_password_id_required_msg = "WLSC-ERROR: The value for keystore_password_id is required when enabling secured production mode." + validate_missing_keystore_password_id = local.missing_keystore_password_id ? local.validators_msg_map[local.keystore_password_id_required_msg] : null + + missing_root_ca_id = var.configure_secure_mode && var.root_ca_id == "" + root_ca_id_required_msg = "WLSC-ERROR: The value for root_ca_id is required when enabling secured production mode." + validate_missing_root_ca_id = local.missing_root_ca_id ? local.validators_msg_map[local.root_ca_id_required_msg] : null + + missing_wls_secondary_admin_password_id = var.configure_secure_mode && var.wls_secondary_admin_password_id == "" + missing_wls_secondary_admin_password_id_required_msg = "WLSC-ERROR: The value for wls_secondary_admin_password_id is required when enabling secured production mode" + invalid_wls_secondary_admin_password_id = var.configure_secure_mode && length(regexall("^ocid1.vaultsecret.", var.wls_secondary_admin_password_id)) <= 0 + invalid_wls_secondary_admin_password_id_required_msg = "WLSC-ERROR: The value for wls_secondary_admin_password_id should start with \"ocid1.vaultsecret.\"" + validate_wls_secondary_admin_password_id = local.missing_wls_secondary_admin_password_id ? local.validators_msg_map[local.missing_wls_secondary_admin_password_id_required_msg] : (local.invalid_wls_secondary_admin_password_id ? local.validators_msg_map[local.invalid_wls_secondary_admin_password_id_required_msg] : null) + + invalid_administration_ports = var.configure_secure_mode && var.administration_port == var.ms_administration_port + invalid_administration_ports_msg = "WLSC-ERROR: The value for administration_port=[${var.administration_port}] and ms_administration_port=[${var.ms_administration_port}] cannot be same." + validate_administration_ports = local.invalid_administration_ports ? local.validators_msg_map[local.invalid_administration_ports_msg] : null + + invalid_jrf_12c_secure_mode = var.configure_secure_mode && (var.is_oci_db || var.is_atp_db || trimspace(var.oci_db_connection_string) != "") + invalid_jrf_12c_secure_mode_msg = "WLSC-ERROR: JRF domain is not supported for FMW 12c version in secured production mode." + validate_jrf_12c_secure_mode = local.invalid_jrf_12c_secure_mode ? local.validators_msg_map[local.invalid_jrf_12c_secure_mode_msg] : "" } diff --git a/terraform/modules/validators/variables.tf b/terraform/modules/validators/variables.tf index db7c260a..91cd2497 100644 --- a/terraform/modules/validators/variables.tf +++ b/terraform/modules/validators/variables.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, 2024 Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. variable "compartment_id" { @@ -533,3 +533,34 @@ variable "tf_script_version" { type = string description = "The version of the provisioning scripts located in the OCI image used to create the WebLogic compute instances" } + +# All variables under this comment belong to secured production mode +variable "configure_secure_mode" { + type = bool + description = "Set to true to configure a secure WebLogic domain" +} + +variable "keystore_password_id" { + type = string + description = "The OCID of the vault secret with the password for creating the keystore" +} + +variable "root_ca_id" { + type = string + description = "The OCID of the existing root certificate authority to issue the certificates" +} + +variable "wls_secondary_admin_password_id" { + type = string + description = "The OCID of the vault secret with the password for secondary WebLogic administration user" +} + +variable "administration_port" { + type = number + description = "The domain-wide administration port to configure a secure WebLogic domain" +} + +variable "ms_administration_port" { + type = number + description = "The administration port for managed servers to configure a secure WebLogic domain" +} \ No newline at end of file diff --git a/terraform/outputs.tf b/terraform/outputs.tf index 48908a34..0d9071b5 100644 --- a/terraform/outputs.tf +++ b/terraform/outputs.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. output "virtual_cloud_network_id" { @@ -58,6 +58,10 @@ output "weblogic_version" { ) } +output "webLogic_server_domain_configuration" { + value = local.wls_domain_configuration +} + output "weblogic_server_administration_console" { value = local.admin_console_app_url } diff --git a/terraform/schema.yaml b/terraform/schema.yaml index 697c4e47..2944e121 100644 --- a/terraform/schema.yaml +++ b/terraform/schema.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. title: Oracle WebLogic Server for Oracle Cloud Infrastructure @@ -20,6 +20,7 @@ groupings: - ${use_apm_service} - ${use_autoscaling} - ${add_fss} + - ${configure_secure_mode} - title: "Virtual Cloud Networking" variables: @@ -36,8 +37,15 @@ groupings: - title: "WebLogic Domain Configuration" variables: - ${wls_admin_user} + - ${wls_primary_admin_user} - ${wls_admin_secret_compartment_id} - ${wls_admin_password_id} + - ${wls_secondary_admin_user} + - ${wls_secondary_admin_password_id} + - ${keystore_password_id} + - ${root_ca_id} + - ${cert_compartment_id} + - ${preserve_boot_properties} - ${add_JRF} #Start of JRF fields - ${db_strategy} @@ -68,11 +76,13 @@ groupings: #End of JRF fields - ${deploy_sample_app} - ${wls_server_startup_args} + - ${thread_pool_limit} - ${configure_wls_ports} + - ${administration_port} + - ${ms_administration_port} - ${wls_nm_port} - ${wls_extern_admin_port} - ${wls_extern_ssl_admin_port} - - ${wls_cluster_mc_port} - ${wls_ms_extern_port} - ${wls_ms_extern_ssl_port} - ${allow_manual_domain_extension} @@ -470,11 +480,16 @@ variables: required: true wls_admin_user: - visible: ${orm_create_mode} + visible: + and: + - ${orm_create_mode} + - not: + - ${configure_secure_mode} type: string title: "WebLogic Server Admin User Name" - description: "The name of the administrator in the WebLogic Server domain" + description: "The name of the administrator in the WebLogic Server domain. The value should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters." pattern: "^[a-zA-Z][a-zA-Z0-9_-]{7,127}$" + default: "weblogic" minLength: 8 maxLength: 128 required: true @@ -520,6 +535,8 @@ variables: and: - ${orm_create_mode} - ${configure_wls_ports} + - not: + - ${configure_secure_mode} type: integer default: 7001 minimum: 1024 @@ -534,6 +551,8 @@ variables: and: - ${orm_create_mode} - ${configure_wls_ports} + - not: + - ${configure_secure_mode} type: integer default: 7002 minimum: 1024 @@ -543,25 +562,13 @@ variables: description: "The administration server SSL port on which to access the administration console" required: true - wls_cluster_mc_port: - visible: - and: - - ${orm_create_mode} - - ${configure_wls_ports} - type: integer - default: 5555 - minimum: 1024 - maximum: 65535 - multipleOf: 1 - title: "WebLogic Cluster Port" - description: "The managed server port on which to send heartbeats and other internal cluster traffic (not applicable for Standard Edition)" - required: true - wls_ms_extern_port: visible: and: - ${orm_create_mode} - ${configure_wls_ports} + - not: + - ${configure_secure_mode} type: integer default: 7003 minimum: 1024 @@ -772,6 +779,144 @@ variables: title: "Existing Network Security Groups" description: "Use existing Network Security Groups (NSG) for existing subnets" + # Secured Production Mode variables + configure_secure_mode: + visible: ${orm_create_mode} + type: boolean + required: true + default: false + title: "Enable Secured Production Mode" + description: "Configure a secure domain" + + preserve_boot_properties: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: boolean + required: true + default: false + title: "Preserve the boot.properties file for administration server and managed servers" + description: "Preserve the boot.properties file for administration server and managed servers. NOTE: Leaving this unchecked (false) will result in node manager being unable to revive servers if they are killed." + + administration_port: + visible: + and: + - ${orm_create_mode} + - ${configure_wls_ports} + - ${configure_secure_mode} + type: integer + default: 9002 + minimum: 1024 + maximum: 65535 + multipleOf: 1 + title: "WebLogic Server domain-wide Administration Port" + description: "The domain-wide administration port to configure a secure WebLogic domain" + required: true + + ms_administration_port: + visible: + and: + - ${orm_create_mode} + - ${configure_wls_ports} + - ${configure_secure_mode} + type: integer + default: 9004 + minimum: 1024 + maximum: 65535 + multipleOf: 1 + title: "Administration Port for Managed Servers" + description: "The administration port for managed servers to configure a secure WebLogic domain" + required: true + + keystore_password_id: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: "oci:kms:secret:id" + minLength: 1 + maxLength: 1024 + required: true + title: "Validated Secret for Keystore password" + description: "The secret that contains the keystore password. To create secrets, see Create Secrets for Passwords." + dependsOn: + compartmentId: ${wls_admin_secret_compartment_id} + + root_ca_id: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: string + pattern: ^ocid1.certificateauthority.*$ + required: true + title: "Existing Root Certificate Authority ID" + description: "The OCID of the existing root certificate authority to issue the certificates" + + cert_compartment_id: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + - ${create_policies} + type: oci:identity:compartment:id + required: false + title: "Certificate Compartment" + description: "The compartment where you want to create the certificate" + default: ${network_compartment_id} + + thread_pool_limit: + visible: + and: + - ${orm_create_mode} + - and: + - ${configure_secure_mode} + type: string + default: 65536 + title: "Throttle the thread pool" + description: "Shared Capacity For Work Managers" + required: true + + wls_primary_admin_user: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: string + title: "WebLogic Server Admin User Name" + description: "The name of the primary administrator in the WebLogic Server domain. The value should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters, and should not be system, admin, administrator, or weblogic." + pattern: "^(?!weblogic$|administrator$)[a-zA-Z][a-zA-Z0-9_-]{7,127}$" + default: "wls_user" + minLength: 8 + maxLength: 128 + required: true + + wls_secondary_admin_user: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: string + title: "WebLogic Server Admin User Name" + description: "The name of the secondary administrator in the WebLogic Server domain. The value should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters, and should not be system, admin, administrator, or weblogic." + pattern: "^(?!weblogic$|administrator$)[a-zA-Z][a-zA-Z0-9_-]{7,127}$" + default: "wls_user_1" + minLength: 8 + maxLength: 128 + required: true + + wls_secondary_admin_password_id: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: "oci:kms:secret:id" + title: "Validated Secret for WebLogic Server Admin Password" + description: "The secret that contains the administration password of the secondary administrator in the WebLogic Server domain. Use a WebLogic Administrator password that starts with a letter, is between 8 and 30 characters long, contains at least one number, and, optionally, any number of the special characters ($ # _). For example, Ach1z0#d. To create secrets, see Create Secrets for Passwords." + required: true + dependsOn: + compartmentId: ${wls_admin_secret_compartment_id} # WLS Network Configuration wls_vcn_name: @@ -1508,7 +1653,11 @@ variables: default: true add_JRF: - visible: ${orm_create_mode} + visible: + and: + - ${orm_create_mode} + - not: + - ${configure_secure_mode} type: boolean default: false title: "Provision with JRF" diff --git a/terraform/schema_14110.yaml b/terraform/schema_14110.yaml index 38d64823..39573878 100644 --- a/terraform/schema_14110.yaml +++ b/terraform/schema_14110.yaml @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. title: Oracle WebLogic Server for Oracle Cloud Infrastructure @@ -20,6 +20,7 @@ groupings: - ${use_apm_service} - ${use_autoscaling} - ${add_fss} + - ${configure_secure_mode} - title: "Virtual Cloud Networking" variables: @@ -36,16 +37,25 @@ groupings: - title: "WebLogic Domain Configuration" variables: - ${wls_admin_user} + - ${wls_primary_admin_user} - ${wls_admin_secret_compartment_id} - ${wls_admin_password_id} + - ${wls_secondary_admin_user} + - ${wls_secondary_admin_password_id} + - ${keystore_password_id} + - ${root_ca_id} + - ${cert_compartment_id} + - ${preserve_boot_properties} - ${wls_14c_jdk_version} - ${deploy_sample_app} - ${wls_server_startup_args} + - ${thread_pool_limit} - ${configure_wls_ports} + - ${administration_port} + - ${ms_administration_port} - ${wls_nm_port} - ${wls_extern_admin_port} - ${wls_extern_ssl_admin_port} - - ${wls_cluster_mc_port} - ${wls_ms_extern_port} - ${wls_ms_extern_ssl_port} - ${allow_manual_domain_extension} @@ -468,11 +478,16 @@ variables: required: true wls_admin_user: - visible: ${orm_create_mode} + visible: + and: + - ${orm_create_mode} + - not: + - ${configure_secure_mode} type: string title: "WebLogic Server Admin User Name" - description: "The name of the administrator in the WebLogic Server domain" + description: "The name of the administrator in the WebLogic Server domain. The value should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters." pattern: "^[a-zA-Z][a-zA-Z0-9_-]{7,127}$" + default: "weblogic" minLength: 8 maxLength: 128 required: true @@ -529,6 +544,8 @@ variables: and: - ${orm_create_mode} - ${configure_wls_ports} + - not: + - ${configure_secure_mode} type: integer default: 7001 minimum: 1024 @@ -543,6 +560,8 @@ variables: and: - ${orm_create_mode} - ${configure_wls_ports} + - not: + - ${configure_secure_mode} type: integer default: 7002 minimum: 1024 @@ -552,25 +571,13 @@ variables: description: "The administration server SSL port on which to access the administration console" required: true - wls_cluster_mc_port: - visible: - and: - - ${orm_create_mode} - - ${configure_wls_ports} - type: integer - default: 5555 - minimum: 1024 - maximum: 65535 - multipleOf: 1 - title: "WebLogic Cluster Port" - description: "The managed server port on which to send heartbeats and other internal cluster traffic (not applicable for Standard Edition)" - required: true - wls_ms_extern_port: visible: and: - ${orm_create_mode} - ${configure_wls_ports} + - not: + - ${configure_secure_mode} type: integer default: 7003 minimum: 1024 @@ -781,6 +788,144 @@ variables: title: "Existing Network Security Groups" description: "Use existing Network Security Groups (NSG) for existing subnets" + # Secured Production Mode variables + configure_secure_mode: + visible: ${orm_create_mode} + type: boolean + required: true + default: false + title: "Enable Secured Production Mode" + description: "Configure a secure domain" + + preserve_boot_properties: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: boolean + required: true + default: false + title: "Preserve the boot.properties file for administration server and managed servers" + description: "Preserve the boot.properties file for administration server and managed servers. NOTE: Leaving this unchecked (false) will result in node manager being unable to revive servers if they are killed." + + administration_port: + visible: + and: + - ${orm_create_mode} + - ${configure_wls_ports} + - ${configure_secure_mode} + type: integer + default: 9002 + minimum: 1024 + maximum: 65535 + multipleOf: 1 + title: "WebLogic Server domain-wide Administration Port" + description: "The domain-wide administration port to configure a secure WebLogic domain" + required: true + + ms_administration_port: + visible: + and: + - ${orm_create_mode} + - ${configure_wls_ports} + - ${configure_secure_mode} + type: integer + default: 9004 + minimum: 1024 + maximum: 65535 + multipleOf: 1 + title: "Administration Port for Managed Servers" + description: "The administration port for managed servers to configure a secure WebLogic domain" + required: true + + keystore_password_id: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: "oci:kms:secret:id" + minLength: 1 + maxLength: 1024 + required: true + title: "Validated Secret for Keystore password" + description: "The secret that contains the keystore password. To create secrets, see Create Secrets for Passwords." + dependsOn: + compartmentId: ${wls_admin_secret_compartment_id} + + root_ca_id: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: string + pattern: ^ocid1.certificateauthority.*$ + required: true + title: "Existing Root Certificate Authority ID" + description: "The OCID of the existing root certificate authority to issue the certificates" + + cert_compartment_id: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + - ${create_policies} + type: oci:identity:compartment:id + required: false + title: "Certificate Compartment" + description: "The compartment where you want to create the certificate" + default: ${network_compartment_id} + + thread_pool_limit: + visible: + and: + - ${orm_create_mode} + - and: + - ${configure_secure_mode} + type: string + default: 65536 + title: "Throttle the thread pool" + description: "Shared Capacity For Work Managers" + required: true + + wls_primary_admin_user: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: string + title: "WebLogic Server Admin User Name" + description: "The name of the primary administrator in the WebLogic Server domain. The value should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters, and should not be system, admin, administrator, or weblogic." + pattern: "^(?!weblogic$|administrator$)[a-zA-Z][a-zA-Z0-9_-]{7,127}$" + default: "wls_user" + minLength: 8 + maxLength: 128 + required: true + + wls_secondary_admin_user: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: string + title: "WebLogic Server Admin User Name" + description: "The name of the secondary administrator in the WebLogic Server domain. The value should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters, and should not be system, admin, administrator, or weblogic." + pattern: "^(?!weblogic$|administrator$)[a-zA-Z][a-zA-Z0-9_-]{7,127}$" + default: "wls_user_1" + minLength: 8 + maxLength: 128 + required: true + + wls_secondary_admin_password_id: + visible: + and: + - ${orm_create_mode} + - ${configure_secure_mode} + type: "oci:kms:secret:id" + title: "Validated Secret for WebLogic Server Admin Password" + description: "The secret that contains the administration password of the secondary administrator in the WebLogic Server domain. Use a WebLogic Administrator password that starts with a letter, is between 8 and 30 characters long, contains at least one number, and, optionally, any number of the special characters ($ # _). For example, Ach1z0#d. To create secrets, see Create Secrets for Passwords." + required: true + dependsOn: + compartmentId: ${wls_admin_secret_compartment_id} # WLS Network Configuration wls_vcn_name: diff --git a/terraform/weblogic_variables.tf b/terraform/weblogic_variables.tf index 44bd303a..95a60e9a 100644 --- a/terraform/weblogic_variables.tf +++ b/terraform/weblogic_variables.tf @@ -1,4 +1,4 @@ -# Copyright (c) 2023, Oracle and/or its affiliates. +# Copyright (c) 2023, 2024, Oracle and/or its affiliates. # Licensed under the Universal Permissive License v1.0 as shown at https://oss.oracle.com/licenses/upl. variable "wls_version" { @@ -106,6 +106,7 @@ variable "wls_admin_ssl_port" { error_message = "WLSC-ERROR: The value for wls_admin_ssl_port should be greater than 0." } } + variable "wls_expose_admin_port" { type = bool description = "[WARNING] Selecting this option will expose the console to the internet if the default 0.0.0.0/0 CIDR is used. You should change the CIDR range below to allow access to a trusted IP range." @@ -165,16 +166,6 @@ variable "wls_extern_admin_port" { } } -variable "wls_cluster_mc_port" { - type = number - description = "The managed server port on which to send heartbeats and other internal cluster traffic" - default = 5555 - validation { - condition = var.wls_cluster_mc_port > 0 - error_message = "WLSC-ERROR: The value for wls_cluster_mc_port should be greater than 0." - } -} - variable "wls_nm_port" { type = number description = "The listen port number for the node manager process on all compute instances" @@ -197,3 +188,77 @@ variable "deploy_sample_app" { default = true } +# All the variables under this comment belong to Secured Production Mode +variable "configure_secure_mode" { + type = bool + description = "Set to true to configure a secure WebLogic domain" + default = false +} + +variable "preserve_boot_properties" { + type = bool + description = "Set to true to preserve the boot.properties file for administration server and managed servers" + default = "false" +} + +variable "keystore_password_id" { + type = string + description = "The OCID of the vault secret with the password for creating the keystore" + default = "" +} + +variable "root_ca_id" { + type = string + description = "The OCID of the existing root certificate authority to issue the certificates" + default = "" +} + +variable "cert_compartment_id" { + type = string + description = "The OCID of the compartment where the certificate will be created. Leave it blank to use the network compartment for the certificate" + default = "" +} + +variable "administration_port" { + type = number + description = "The domain-wide administration port to configure a secure WebLogic domain" + default = 9002 +} + +variable "ms_administration_port" { + type = number + description = "The administration port for managed servers to configure a secure WebLogic domain" + default = 9004 +} + +variable "thread_pool_limit" { + type = number + description = "Shared Capacity For Work Managers" + default = 65536 +} + +variable "wls_primary_admin_user" { + type = string + description = "Name of primary WebLogic administration user" + default = "wls_user" + validation { + condition = replace(var.wls_primary_admin_user, "/^[a-zA-Z][a-zA-Z0-9_-]{7,127}/", "0") == "0" && !contains(["system", "admin", "administrator", "weblogic"], var.wls_primary_admin_user) + error_message = "WLSC-ERROR: The value for wls_primary_admin_user should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters, and should not be system, admin, administrator, or weblogic." + } +} + +variable "wls_secondary_admin_user" { + type = string + description = "Name of secondary WebLogic administration user" + default = "wls_user_1" + validation { + condition = replace(var.wls_secondary_admin_user, "/^[a-zA-Z][a-zA-Z0-9_-]{7,127}/", "0") == "0" && !contains(["system", "admin", "administrator", "weblogic"], var.wls_secondary_admin_user) + error_message = "WLSC-ERROR: The value for wls_secondary_admin_user should be between 8 and 128 characters long and alphanumeric, and can contain underscore (_) and hyphen(-) special characters, and should not be system, admin, administrator, or weblogic." + } +} + +variable "wls_secondary_admin_password_id" { + type = string + description = "The OCID of the vault secret with the password for secondary WebLogic administration user" + default = "" +} \ No newline at end of file