Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# VPC Private-path External Connectivity

[![Incubating (Not yet consumable)](https://img.shields.io/badge/status-Incubating%20(Not%20yet%20consumable)-red)](https://terraform-ibm-modules.github.io/documentation/#/badge-status)
[![Graduated (Supported)](https://img.shields.io/badge/Status-Graduated%20(Supported)-brightgreen)](https://terraform-ibm-modules.github.io/documentation/#/badge-status)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it actually Graduated? It has CISO approval? Or is it just Stable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CISO approved - so graduated

[![latest release](https://img.shields.io/github/v/release/terraform-ibm-modules/sample-deployable-architectures?logo=GitHub&sort=semver)](https://github.com/terraform-ibm-modules/sample-deployable-architectures/releases/latest)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
[![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com/)
Expand Down
374 changes: 313 additions & 61 deletions ibm_catalog.json

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"region": "us-south",
"prefix": $PREFIX,
"private_path_name": $PREFIX,
"private_path_service_endpoints": ["vpc-pps.dev.internal"]
"private_path_service_endpoints": ["vpc-pps.dev.internal"],
"existing_secrets_manager_instance_crn": $SM_CRN
}
79 changes: 73 additions & 6 deletions solutions/fully-configurable/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,90 @@ module "resource_group" {
existing_resource_group_name = var.existing_resource_group_name
}

########################################################################################################################
# Secrets Manager resources
########################################################################################################################
locals {
secrets_manager_cert_crn = var.application_loadbalancer_listener_certificate_crn != null ? var.application_loadbalancer_listener_certificate_crn : module.secrets_manager_private_certificate[0].secret_crn
secrets_manager_secret_group_id = var.application_loadbalancer_listener_certificate_crn != null ? null : var.existing_secrets_manager_secret_group_id != null ? var.existing_secrets_manager_secret_group_id : module.secrets_manager_secret_group[0].secret_group_id
}
module "existing_sm_crn_parser" {
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.2.0"
crn = var.existing_secrets_manager_instance_crn
}

module "application_loadbalancer_listener_certificate_crn_parser" {
count = var.application_loadbalancer_listener_certificate_crn != null ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.2.0"
crn = var.application_loadbalancer_listener_certificate_crn
}

# Create a secret group to place the certificate if provisioning a new certificate
module "secrets_manager_secret_group" {
count = var.application_loadbalancer_listener_certificate_crn == null && var.existing_secrets_manager_secret_group_id == null ? 1 : 0
source = "terraform-ibm-modules/secrets-manager-secret-group/ibm"
version = "1.3.15"
region = module.existing_sm_crn_parser.region
secrets_manager_guid = module.existing_sm_crn_parser.service_instance
secret_group_name = (var.prefix != null && var.prefix != "") ? "${var.prefix}-cert-secret-group" : "cert-secret-group"
secret_group_description = "secret group used for private certificates"
providers = {
ibm = ibm.ibm-sm
}
}

# Create private certificate to use for VPN server
module "secrets_manager_private_certificate" {
count = var.application_loadbalancer_listener_certificate_crn == null ? 1 : 0
source = "terraform-ibm-modules/secrets-manager-private-cert/ibm"
version = "1.7.0"
cert_name = (var.prefix != null && var.prefix != "") ? "${var.prefix}-cts-vpn-private-cert" : "cts-vpn-private-cert"
cert_description = "private certificate for client to site VPN connection"
cert_template = var.private_cert_engine_config_template_name
cert_secrets_group_id = local.secrets_manager_secret_group_id
cert_common_name = var.private_cert_engine_config_root_ca_common_name
secrets_manager_guid = module.existing_sm_crn_parser.service_instance
secrets_manager_region = module.existing_sm_crn_parser.region
providers = {
ibm = ibm.ibm-sm
}
}

########################################################################################################################
# Application Load balancer resources
########################################################################################################################

module "existing_vpc_crn_parser" {
count = var.existing_vpc_crn != null ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.2.0"
crn = var.existing_vpc_crn
}

locals {
prefix = var.prefix != null ? trimspace(var.prefix) != "" ? "${var.prefix}-" : "" : ""
network_loadbalancer_name = "${local.prefix}${var.network_loadbalancer_name}"
private_path_name = "${local.prefix}${var.private_path_name}"
subnet_id = var.existing_subnet_id != null ? var.existing_subnet_id : data.ibm_is_vpc.vpc[0].subnets[0].id
existing_vpc_id = var.existing_vpc_crn != null ? module.existing_vpc_crn_parser[0].resource : null
}

data "ibm_is_vpc" "vpc" {
count = var.existing_vpc_id != null && var.existing_subnet_id == null ? 1 : 0
identifier = var.existing_vpc_id
count = var.existing_vpc_crn != null && var.existing_subnet_id == null ? 1 : 0
identifier = local.existing_vpc_id
}

resource "ibm_is_lb" "alb" {
name = "${local.prefix}-alb"
name = "${local.prefix}alb"
resource_group = module.resource_group.resource_group_id
subnets = [local.subnet_id]
type = var.application_loadbalancer_type
}

resource "ibm_is_lb_pool" "alb_backend_pool" {
name = "${local.prefix}-alb-pool"
name = "${local.prefix}alb-pool"
lb = ibm_is_lb.alb.id
algorithm = var.application_loadbalancer_pool_algorithm
protocol = var.application_loadbalancer_pool_protocol
Expand All @@ -51,13 +114,17 @@ resource "ibm_is_lb_listener" "alb_frontend_listener" {
port = var.application_loadbalancer_listener_port
protocol = var.application_loadbalancer_listener_protocol
idle_connection_timeout = var.application_loadbalancer_listener_idle_timeout
certificate_instance = var.application_loadbalancer_listener_certificate_instance
certificate_instance = local.secrets_manager_cert_crn
default_pool = ibm_is_lb_pool.alb_backend_pool.pool_id
}

########################################################################################################################
# Private path resources
########################################################################################################################

module "private_path" {
source = "terraform-ibm-modules/vpc-private-path/ibm"
version = "1.3.2"
version = "1.5.0"
resource_group_id = module.resource_group.resource_group_id
subnet_id = local.subnet_id
tags = var.private_path_tags
Expand Down
5 changes: 5 additions & 0 deletions solutions/fully-configurable/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ output "alb_listener_id" {
value = ibm_is_lb_listener.alb_frontend_listener.id
}

output "alb_listener_certificate_secret_id" {
description = "ID of the client to site vpn server certificate secret stored in Secrets Manager"
value = var.application_loadbalancer_listener_certificate_crn == null ? module.secrets_manager_private_certificate[0].secret_id : module.application_loadbalancer_listener_certificate_crn_parser[0].service_instance
}

## Private Path
output "nlb_crn" {
description = "The CRN for this load balancer."
Expand Down
8 changes: 8 additions & 0 deletions solutions/fully-configurable/provider.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@ provider "ibm" {
visibility = var.provider_visibility
private_endpoint_type = (var.provider_visibility == "private" && var.region == "ca-mon") ? "vpe" : null
}

provider "ibm" {
ibmcloud_api_key = var.ibmcloud_api_key
region = module.existing_sm_crn_parser.region
alias = "ibm-sm"
visibility = var.provider_visibility
private_endpoint_type = (var.provider_visibility == "private" && var.region == "ca-mon") ? "vpe" : null
}
102 changes: 81 additions & 21 deletions solutions/fully-configurable/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@ variable "private_path_access_tags" {
# VPC Variables
##############################################################################

variable "existing_vpc_id" {
description = "The ID of an existing VPC. If the user provides only the `existing_vpc_id`, the Private Path service will be provisioned in the first subnet."
variable "existing_vpc_crn" {
type = string
description = "CRN of the existing VPC in which the VPN infrastructure will be created. If the user provides only the `existing_vpc_crn`, the Private Path service will be provisioned in the first subnet."
default = null
validation {
condition = var.existing_vpc_id == null && var.existing_subnet_id == null ? false : true
error_message = "A value for either `existing_vpc_id` or `existing_subnet_id` should be passed."
condition = var.existing_vpc_crn == null && var.existing_subnet_id == null ? false : true
error_message = "A value for either `existing_vpc_crn` or `existing_subnet_id` should be passed."
}
}

Expand All @@ -104,18 +104,27 @@ variable "application_loadbalancer_type" {
type = string
default = "private"
description = "The type of the application load balancer. Supported values are `private`, `public`."
validation {
condition = contains(["private", "public"], var.application_loadbalancer_type)
error_message = "Invalid type of application load balancer. Allowed values are 'private', 'public'."
}
}

variable "application_loadbalancer_pool_algorithm" {
type = string
description = "The load-balancing algorithm for Private Path network load balancer pool members. Supported values are `round_robin` or `weighted_round_robin`."
default = "round_robin"

validation {
condition = contains(["round_robin", "weighted_round_robin"], var.application_loadbalancer_pool_algorithm)
error_message = "Invalid load-balancing algorithm. Allowed values are 'round_robin', 'weighted_round_robin'."
}
}

variable "application_loadbalancer_pool_member_port" {
type = number
description = "The port where traffic is sent to the instance."
default = 80
default = 443
}

variable "application_loadbalancer_pool_health_delay" {
Expand All @@ -138,45 +147,88 @@ variable "application_loadbalancer_pool_health_timeout" {

variable "application_loadbalancer_pool_health_type" {
type = string
description = "The protocol used to send health check messages to instances in the pool. Supported values are `tcp` or `http`."
default = "http"
description = "The protocol used to send health check messages to instances in the pool. Supported values are `tcp`, `https`."
default = "https"
validation {
condition = contains(["tcp", "https"], var.application_loadbalancer_pool_health_type)
error_message = "Invalid protocol for health check. Allowed values are 'tcp', 'https'."
}
}

variable "application_loadbalancer_pool_protocol" {
type = string
description = "The protocol used to send traffic to instances in the pool. Supported values are `tcp`, `http`, `https` or `udp`."
default = "http"
description = "The protocol used to send traffic to instances in the pool. Supported values are `tcp`, `https` or `udp`."
default = "https"
validation {
condition = contains(["tcp", "https", "udp"], var.application_loadbalancer_pool_protocol)
error_message = "Invalid protocol for loadbalancer pool. Allowed values are 'tcp', 'https' or 'udp'."
}
}

variable "application_loadbalancer_listener_port" {
type = number
description = "The listener port for the Private Path network load balancer."
default = 80
default = 443
}

variable "application_loadbalancer_listener_protocol" {
type = string
description = "The protocol used to send traffic to instances in the pool. Supported values are `tcp`, `http`, `https` or `udp`."
default = "http"
description = "The listener protocol used by instances in the application loadbalancer pool. Supported values are `tcp`, `https` or `udp`."
default = "https"
validation {
condition = contains(["tcp", "https", "udp"], var.application_loadbalancer_listener_protocol)
error_message = "Invalid listener protocol for application loadbalancer. Allowed values are 'tcp', 'https' or 'udp'."
}
}

variable "application_loadbalancer_listener_idle_timeout" {
type = number
description = "The protocol used to send traffic to instances in the pool. Supported values are `tcp`, `http`, `https` or `udp`."
description = "The idle connection timeout of the listener in seconds."
default = 50
}

variable "application_loadbalancer_listener_certificate_instance" {
variable "application_loadbalancer_listener_certificate_crn" {
type = string
description = "The CRN of the certificate in your secret manager, it is applicable(mandatory) only to https protocol."
description = "The CRN of existing secrets manager private certificate to use to create application loadbalancer listener. If the value is null, then new private certificate is created. [Learn more](https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-certificates&interface=ui)"
default = null

validation {
condition = var.application_loadbalancer_listener_protocol == "https" ? var.application_loadbalancer_listener_certificate_instance != null ? true : false : true
error_message = "A value must be set for `application_loadbalancer_listener_certificate_instance` when `application_loadbalancer_listener_protocol` is set to `https`."
condition = var.application_loadbalancer_listener_certificate_crn == null ? var.private_cert_engine_config_template_name != null && var.private_cert_engine_config_root_ca_common_name != null : true
error_message = "Set 'private_cert_engine_config_root_ca_common_name' and 'private_cert_engine_config_template_name' input variables if a 'application_loadbalancer_listener_certificate_crn' input variable is not set"
}

validation {
condition = var.application_loadbalancer_listener_certificate_crn != null ? var.private_cert_engine_config_template_name == null && var.private_cert_engine_config_root_ca_common_name == null : true
error_message = "'private_cert_engine_config_root_ca_common_name' and 'private_cert_engine_config_template_name' input variables can not be set if a 'application_loadbalancer_listener_certificate_crn' input variable is already set"
}
}

##############################################################################
# Secrets Manager resources
##############################################################################

variable "existing_secrets_manager_instance_crn" {
type = string
description = "The CRN of existing secrets manager where the certificate to use for the ALB listener is stored or where the new private certificate will be created. [Learn more](https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-getting-started)"
}

variable "existing_secrets_manager_secret_group_id" {
type = string
description = "The ID of existing secrets manager secret group used for new created certificate. If the value is null, then new secrets manager secret group is created. [Learn more](https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-secret-groups&interface=ui)"
default = null
}

variable "private_cert_engine_config_root_ca_common_name" {
type = string
description = "A fully qualified domain name or host domain name for the certificate to be created. Required if `application_loadbalancer_listener_certificate_crn` input variable is `null`. [Learn more](https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-private-certificates&interface=ui)"
default = null
}

variable "private_cert_engine_config_template_name" {
type = string
description = "The name of the Certificate Template to create for a private certificate secret engine. When `application_loadbalancer_listener_certificate_crn` input variable is `null`, then it has to be the existing template name that exists in the private cert engine. [Learn more](https://cloud.ibm.com/docs/secrets-manager?topic=secrets-manager-private-certificates&interface=ui)"
default = null
}

##############################################################################
# NLB Variables
Expand All @@ -191,7 +243,7 @@ variable "network_loadbalancer_name" {
variable "network_loadbalancer_listener_port" {
type = number
description = "The listener port for the Private Path network load balancer."
default = 80
default = 443
}

variable "network_loadbalancer_listener_accept_proxy_protocol" {
Expand Down Expand Up @@ -226,8 +278,12 @@ variable "network_loadbalancer_pool_health_timeout" {

variable "network_loadbalancer_pool_health_type" {
type = string
description = "The protocol used to send health check messages to instances in the pool. Supported values are `tcp` or `http`."
description = "The protocol used to send health check messages to instances in the pool. Supported values are `tcp` or `https`."
default = "tcp"
validation {
condition = contains(["tcp", "https"], var.network_loadbalancer_pool_health_type)
error_message = "Invalid network loadbalancer health type. Allowed values are 'tcp', 'https'."
}
}

variable "network_loadbalancer_pool_health_monitor_url" {
Expand All @@ -239,13 +295,13 @@ variable "network_loadbalancer_pool_health_monitor_url" {
variable "network_loadbalancer_pool_health_monitor_port" {
type = number
description = "The port on which the load balancer sends health check requests. By default, health checks are sent on the same port where traffic is sent to the instance."
default = 80
default = 443
}

variable "network_loadbalancer_pool_member_port" {
type = number
description = "The port where traffic is sent to the instance."
default = 80
default = 443
}

##############################################################################
Expand All @@ -256,6 +312,10 @@ variable "private_path_default_access_policy" {
type = string
description = "The policy to use for bindings from accounts without an explicit account policy. The default policy is set to Review all requests. Supported options are `permit`, `deny`, or `review`."
default = "review"
validation {
condition = contains(["review", "permit", "deny"], var.private_path_default_access_policy)
error_message = "Invalid network loadbalancer health type. Allowed values are 'review', 'permit' or 'deny'."
}
}

variable "private_path_service_endpoints" {
Expand Down
Loading