From d13a7c9b6eaf603fc7ecee38ddaaefc14ea61e73 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Sat, 15 Feb 2025 00:21:53 +0530 Subject: [PATCH 01/46] feat: initial commit --- solutions/simple/README.md | 11 + .../catalogValidationValues.json.template | 6 + solutions/simple/main.tf | 128 ++++++ solutions/simple/outputs.tf | 36 ++ solutions/simple/provider.tf | 9 + solutions/simple/variables.tf | 400 ++++++++++++++++++ solutions/simple/version.tf | 10 + 7 files changed, 600 insertions(+) create mode 100644 solutions/simple/README.md create mode 100644 solutions/simple/catalogValidationValues.json.template create mode 100644 solutions/simple/main.tf create mode 100644 solutions/simple/outputs.tf create mode 100644 solutions/simple/provider.tf create mode 100644 solutions/simple/variables.tf create mode 100644 solutions/simple/version.tf diff --git a/solutions/simple/README.md b/solutions/simple/README.md new file mode 100644 index 00000000..2e70f5f9 --- /dev/null +++ b/solutions/simple/README.md @@ -0,0 +1,11 @@ +# IBM VPC deployable architecture + +This deployable architecture supports provisioning the following resources: + +- A new resource group if one is not passed in. +- A VPC. + + +![vpc-deployable-architecture](../../reference-architecture/vpc-quickstart-da.svg) + +:exclamation: **Important:** This solution is not intended to be called by other modules because it contains a provider configuration and is not compatible with the `for_each`, `count`, and `depends_on` arguments. For more information, see [Providers Within Modules](https://developer.hashicorp.com/terraform/language/modules/develop/providers). diff --git a/solutions/simple/catalogValidationValues.json.template b/solutions/simple/catalogValidationValues.json.template new file mode 100644 index 00000000..2815de1b --- /dev/null +++ b/solutions/simple/catalogValidationValues.json.template @@ -0,0 +1,6 @@ +{ + "ibmcloud_api_key": $VALIDATION_APIKEY, + "region": "us-south", + "resource_tags": $TAGS, + "resource_group_name": $PREFIX +} diff --git a/solutions/simple/main.tf b/solutions/simple/main.tf new file mode 100644 index 00000000..2f93dd55 --- /dev/null +++ b/solutions/simple/main.tf @@ -0,0 +1,128 @@ +locals { + prefix = var.prefix != null ? (var.prefix != "" ? var.prefix : null) : null +} + +############################################################################## +# Resource Group +############################################################################## + +module "resource_group" { + source = "terraform-ibm-modules/resource-group/ibm" + version = "1.1.6" + resource_group_name = var.use_existing_resource_group == false ? try("${local.prefix}-${var.resource_group_name}", var.resource_group_name) : null + existing_resource_group_name = var.use_existing_resource_group == true ? var.resource_group_name : null +} + +############################################################################# +# COS Bucket for VPC flow logs +############################################################################# + +# parse COS details from the existing COS instance CRN +module "existing_cos_crn_parser" { + count = var.existing_cos_instance_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_cos_instance_crn +} + +locals { + bucket_name = try("${local.prefix}-${var.cos_bucket_name}", var.cos_bucket_name) + + bucket_config = [{ + access_tags = var.access_tags + bucket_name = local.bucket_name + kms_encryption_enabled = var.kms_encryption_enabled_bucket + kms_guid = var.kms_encryption_enabled_bucket ? module.existing_kms_crn_parser[0].service_instance : null + kms_key_crn = var.kms_encryption_enabled_bucket ? var.existing_kms_instance_crn : null + skip_iam_authorization_policy = var.skip_cos_kms_auth_policy + management_endpoint_type = var.management_endpoint_type_for_bucket + storage_class = var.cos_bucket_class + resource_instance_id = var.existing_cos_instance_crn + region_location = var.region + force_delete = true + }] +} + +module "cos_buckets" { + count = var.enable_vpc_flow_logs ? 1 : 0 + source = "terraform-ibm-modules/cos/ibm//modules/buckets" + version = "8.19.2" + bucket_configs = local.bucket_config +} + +####################################################################################################################### +# KMS Key +####################################################################################################################### + +# parse KMS details from the existing KMS instance CRN +module "existing_kms_crn_parser" { + count = var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_kms_instance_crn +} + +locals { + # fetch KMS region from existing_kms_instance_crn if KMS resources are required + kms_region = var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].region : null + + kms_key_ring_name = try("${var.prefix}-${var.kms_key_ring_name}", var.kms_key_ring_name) + kms_key_name = try("${var.prefix}-${var.kms_key_name}", var.kms_key_name) +} + +module "kms" { + count = (var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null) ? 1 : 0 # no need to create any KMS resources if not passing an existing KMS CRN + source = "terraform-ibm-modules/kms-all-inclusive/ibm" + version = "4.19.5" + create_key_protect_instance = false + region = local.kms_region + existing_kms_instance_crn = var.existing_kms_instance_crn + key_ring_endpoint_type = var.kms_endpoint_type + key_endpoint_type = var.kms_endpoint_type + keys = [ + { + key_ring_name = local.kms_key_ring_name + existing_key_ring = false + force_delete_key_ring = true + keys = [ + { + key_name = local.kms_key_name + standard_key = false + rotation_interval_month = 3 + dual_auth_delete_enabled = false + force_delete = true + } + ] + } + ] +} + +############################################################################# +# VPC +############################################################################# + +locals { + # //TO DO + # to create use_public_gateways object +} + +module "vpc" { + source = "../../" + resource_group_id = module.resource_group.resource_group_id + region = var.region + create_vpc = true + name = var.vpc_name + prefix = local.prefix + tags = var.resource_tags + access_tags = var.access_tags + subnets = var.subnets + default_network_acl_name = var.default_network_acl_name + default_security_group_name = var.default_security_group_name + default_routing_table_name = var.default_routing_table_name + network_acls = var.network_acls + # use_public_gateways = local.public_gateway_object + enable_vpc_flow_logs = var.enable_vpc_flow_logs + create_authorization_policy_vpc_to_cos = var.create_authorization_policy_vpc_to_cos + existing_cos_instance_guid = var.enable_vpc_flow_logs ? module.existing_cos_crn_parser[0].service_instance : null + existing_storage_bucket_name = var.enable_vpc_flow_logs ? module.cos_buckets[0].buckets[0].bucket_name : null +} diff --git a/solutions/simple/outputs.tf b/solutions/simple/outputs.tf new file mode 100644 index 00000000..e6b2071e --- /dev/null +++ b/solutions/simple/outputs.tf @@ -0,0 +1,36 @@ +############################################################################## +# VPC +############################################################################## + +output "vpc_name" { + description = "Name of VPC created" + value = module.vpc.vpc_name +} + +output "vpc_id" { + description = "ID of VPC created" + value = module.vpc.vpc_id +} + +output "vpc_crn" { + description = "CRN of VPC created" + value = module.vpc.vpc_crn +} + +############################################################################## +# Public Gateways +############################################################################## + +output "public_gateways" { + description = "Map of public gateways by zone" + value = module.vpc.public_gateways +} + +############################################################################## +# VPC flow logs +############################################################################## + +output "vpc_flow_logs" { + description = "Details of VPC flow logs collector" + value = module.vpc.vpc_flow_logs +} diff --git a/solutions/simple/provider.tf b/solutions/simple/provider.tf new file mode 100644 index 00000000..e669b7ba --- /dev/null +++ b/solutions/simple/provider.tf @@ -0,0 +1,9 @@ +######################################################################################################################## +# Provider config +######################################################################################################################## + +provider "ibm" { + ibmcloud_api_key = var.ibmcloud_api_key + region = var.region + visibility = var.provider_visibility +} diff --git a/solutions/simple/variables.tf b/solutions/simple/variables.tf new file mode 100644 index 00000000..da6e2037 --- /dev/null +++ b/solutions/simple/variables.tf @@ -0,0 +1,400 @@ +############################################################################## +# Input Variables +############################################################################## + +variable "ibmcloud_api_key" { + type = string + description = "The IBM Cloud API key to deploy resources." + sensitive = true +} + +variable "provider_visibility" { + description = "Set the visibility value for the IBM terraform provider. Supported values are `public`, `private`, `public-and-private`. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/guides/custom-service-endpoints)." + type = string + default = "public" + + validation { + condition = contains(["public", "private", "public-and-private"], var.provider_visibility) + error_message = "Invalid visibility option. Allowed values are 'public', 'private', or 'public-and-private'." + } +} + +variable "use_existing_resource_group" { + type = bool + description = "Whether to use an existing resource group." + default = true +} + +variable "resource_group_name" { + type = string + description = "The name of a new or an existing resource group to provision the watsonx.ai resources. If a prefix input variable is specified, the prefix is added to the name in the `-` format." + default = "Default" +} + +variable "prefix" { + type = string + description = "Prefix to add to all the resources created by this solution. To not use any prefix value, you can set this value to `null` or an empty string." + default = "dev" +} + +variable "vpc_name" { + default = "simple" + description = "Name of the VPC." + type = string +} + +variable "region" { + default = "us-south" + description = "Region to deploy the VPC." + type = string +} + +variable "resource_tags" { + description = "Optional list of tags for the resources created by this solution." + type = list(string) + default = [] +} + +variable "access_tags" { + type = list(string) + description = "A list of access tags to apply to the VPC resources created by the module. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial." + default = [] + + validation { + condition = alltrue([ + for tag in var.access_tags : can(regex("[\\w\\-_\\.]+:[\\w\\-_\\.]+", tag)) && length(tag) <= 128 + ]) + error_message = "Tags must match the regular expression \"[\\w\\-_\\.]+:[\\w\\-_\\.]+\". For more information, see https://cloud.ibm.com/docs/account?topic=account-tag&interface=ui#limits." + } +} + +############################################################################## +# Subnets +############################################################################## + +variable "subnets" { + description = "List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created" + type = object({ + zone-1 = list(object({ + name = string + cidr = string + public_gateway = optional(bool) + acl_name = string + no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + })) + zone-2 = optional(list(object({ + name = string + cidr = string + public_gateway = optional(bool) + acl_name = string + no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + }))) + zone-3 = optional(list(object({ + name = string + cidr = string + public_gateway = optional(bool) + acl_name = string + no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + }))) + }) + + default = { + zone-1 = [ + { + name = "subnet-a" + cidr = "10.10.10.0/24" + public_gateway = true + acl_name = "vpc-acl" + no_addr_prefix = false + } + ] + } +} + +############################################################################## +# Network ACLs +############################################################################## + +variable "network_acls" { + description = "The list of ACLs to create. Provide at least one rule for each ACL." + type = list( + object({ + name = string + add_ibm_cloud_internal_rules = optional(bool) + add_vpc_connectivity_rules = optional(bool) + prepend_ibm_rules = optional(bool) + rules = list( + object({ + name = string + action = string + destination = string + direction = string + source = string + tcp = optional( + object({ + port_max = optional(number) + port_min = optional(number) + source_port_max = optional(number) + source_port_min = optional(number) + }) + ) + udp = optional( + object({ + port_max = optional(number) + port_min = optional(number) + source_port_max = optional(number) + source_port_min = optional(number) + }) + ) + icmp = optional( + object({ + type = optional(number) + code = optional(number) + }) + ) + }) + ) + }) + ) + + default = [ + { + name = "vpc-acl" + add_ibm_cloud_internal_rules = true + add_vpc_connectivity_rules = true + prepend_ibm_rules = true + rules = [ + { + name = "allow-all-443-inbound" + action = "allow" + direction = "inbound" + tcp = { + port_min = 443 + port_max = 443 + source_port_min = 1024 + source_port_max = 65535 + } + destination = "0.0.0.0/0" + source = "0.0.0.0/0" + }, + { + name = "allow-all-80-inbound" + action = "allow" + direction = "inbound" + tcp = { + port_min = 80 + port_max = 80 + source_port_min = 1024 + source_port_max = 65535 + } + destination = "0.0.0.0/0" + source = "0.0.0.0/0" + }, + { + name = "allow-all-22-inbound" + action = "allow" + direction = "inbound" + tcp = { + port_min = 22 + port_max = 22 + source_port_min = 1024 + source_port_max = 65535 + } + destination = "0.0.0.0/0" + source = "0.0.0.0/0" + }, + { + name = "allow-all-443-outbound" + action = "allow" + direction = "outbound" + tcp = { + source_port_min = 443 + source_port_max = 443 + port_min = 1024 + port_max = 65535 + } + destination = "0.0.0.0/0" + source = "0.0.0.0/0" + }, + { + name = "allow-all-80-outbound" + action = "allow" + direction = "outbound" + tcp = { + source_port_min = 80 + source_port_max = 80 + port_min = 1024 + port_max = 65535 + } + destination = "0.0.0.0/0" + source = "0.0.0.0/0" + }, + { + name = "allow-all-22-outbound" + action = "allow" + direction = "outbound" + tcp = { + source_port_min = 22 + source_port_max = 22 + port_min = 1024 + port_max = 65535 + } + destination = "0.0.0.0/0" + source = "0.0.0.0/0" + } + ] + } + ] + + validation { + error_message = "ACL rule actions can only be `allow` or `deny`." + condition = length(distinct( + flatten([ + # Check through rules + for rule in flatten([var.network_acls[*].rules]) : + # Return false action is not valid + false if !contains(["allow", "deny"], rule.action) + ]) + )) == 0 + } + + validation { + error_message = "ACL rule direction can only be `inbound` or `outbound`." + condition = length(distinct( + flatten([ + # Check through rules + for rule in flatten([var.network_acls[*].rules]) : + # Return false if direction is not valid + false if !contains(["inbound", "outbound"], rule.direction) + ]) + )) == 0 + } + + validation { + error_message = "ACL rule names must match the regex pattern ^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$." + condition = length(distinct( + flatten([ + # Check through rules + for rule in flatten([var.network_acls[*].rules]) : + # Return false if direction is not valid + false if !can(regex("^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$", rule.name)) + ]) + )) == 0 + } + +} + + +############################################################################## +# VPC Flow Logs Variables +############################################################################## + +variable "enable_vpc_flow_logs" { + description = "Flag to enable vpc flow logs. If true, flow log collector will be created" + type = bool + default = false +} + +variable "create_authorization_policy_vpc_to_cos" { + description = "Create authorisation policy for VPC to access COS. Set as false if authorization policy exists already" + type = bool + default = true +} + +variable "existing_cos_instance_crn" { + description = "GUID of the COS instance to create Flow log collector" + type = string + default = null +} + +variable "cos_bucket_name" { + description = "Name of the COS bucket to collect VPC flow logs" + type = string + default = "cos-bucket" +} + +variable "kms_encryption_enabled_bucket" { + description = "Set to true if bucket needs to be KMS encryption enabled" + type = bool + default = false +} + +variable "skip_cos_kms_auth_policy" { + type = bool + description = "To skip creating auth policy that allows COS to access KMS key." + default = false +} + +variable "management_endpoint_type_for_bucket" { + description = "The type of endpoint for the IBM Terraform provider to use to manage Cloud Object Storage buckets (`public`, `private`, or `direct`). If you are using a private endpoint, make sure that you enable virtual routing and forwarding (VRF) in your account, and that the Terraform runtime can access the IBM Cloud Private network." + type = string + default = "public" + validation { + condition = contains(["public", "private", "direct"], var.management_endpoint_type_for_bucket) + error_message = "The specified `management_endpoint_type_for_bucket` is not valid. Specify a valid type of endpoint for the IBM Terraform provider to use to manage Cloud Object Storage buckets." + } +} + +variable "cos_bucket_class" { + type = string + default = "standard" + description = "The storage class of the newly provisioned Cloud Object Storage bucket. Specify one of the following values for the storage class: `standard`, `vault`, `cold`, `smart` (default), or `onerate_active`." + validation { + condition = contains(["standard", "vault", "cold", "smart", "onerate_active"], var.cos_bucket_class) + error_message = "Specify one of the following values for the `cos_bucket_class`: `standard`, `vault`, `cold`, `smart`, or `onerate_active`." + } +} + +############################################################################################################### +# KMS +############################################################################################################### + +variable "existing_kms_instance_crn" { + type = string + default = null + description = "The CRN of the existing key management service (KMS) that is used to create keys for encrypting the Cloud Object Storage bucket." +} + +variable "kms_endpoint_type" { + type = string + description = "The type of endpoint to use for communicating with the Key Protect instance. Possible values: `public`, `private`. Applies only if `existing_cos_kms_key_crn` is not specified." + default = "public" + validation { + condition = can(regex("public|private", var.kms_endpoint_type)) + error_message = "Valid values for the `kms_endpoint_type_value` are `public` or `private`." + } +} + +variable "kms_key_ring_name" { + type = string + default = "cos-key-ring" + description = "The name of the key ring to create for the Cloud Object Storage bucket key. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key ring is prefixed to the value in the `-value` format." +} + +variable "kms_key_name" { + type = string + default = "cos-key" + description = "The name of the key to create for the Cloud Object Storage bucket. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key is prefixed to the value in the `-value` format." +} + +############################################################################## +# Optional VPC Variables +############################################################################## + +variable "default_network_acl_name" { + description = "OPTIONAL - Name of the Default ACL. If null, a name will be automatically generated" + type = string + default = null +} + +variable "default_security_group_name" { + description = "OPTIONAL - Name of the Default Security Group. If null, a name will be automatically generated" + type = string + default = null +} + +variable "default_routing_table_name" { + description = "OPTIONAL - Name of the Default Routing Table. If null, a name will be automatically generated" + type = string + default = null +} diff --git a/solutions/simple/version.tf b/solutions/simple/version.tf new file mode 100644 index 00000000..c27e769e --- /dev/null +++ b/solutions/simple/version.tf @@ -0,0 +1,10 @@ +terraform { + required_version = ">= 1.3.0" + required_providers { + # Use "greater than or equal to" range in modules + ibm = { + source = "IBM-Cloud/ibm" + version = ">= 1.59.0, < 2.0.0" + } + } +} From 0635ef84b45a7fcbf80b5847c0dd0b61dfac3028 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 17 Feb 2025 08:49:44 +0530 Subject: [PATCH 02/46] update defalt value of resource group --- solutions/simple/variables.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/solutions/simple/variables.tf b/solutions/simple/variables.tf index da6e2037..a762c75c 100644 --- a/solutions/simple/variables.tf +++ b/solutions/simple/variables.tf @@ -28,7 +28,6 @@ variable "use_existing_resource_group" { variable "resource_group_name" { type = string description = "The name of a new or an existing resource group to provision the watsonx.ai resources. If a prefix input variable is specified, the prefix is added to the name in the `-` format." - default = "Default" } variable "prefix" { From af8271a121e90b63086aadf65a1eeb4094795a14 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 17 Feb 2025 09:37:14 +0530 Subject: [PATCH 03/46] update code --- solutions/simple/main.tf | 2 +- solutions/simple/variables.tf | 24 ++++++++++++------------ solutions/simple/version.tf | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/solutions/simple/main.tf b/solutions/simple/main.tf index 2f93dd55..a6873cd9 100644 --- a/solutions/simple/main.tf +++ b/solutions/simple/main.tf @@ -122,7 +122,7 @@ module "vpc" { network_acls = var.network_acls # use_public_gateways = local.public_gateway_object enable_vpc_flow_logs = var.enable_vpc_flow_logs - create_authorization_policy_vpc_to_cos = var.create_authorization_policy_vpc_to_cos + create_authorization_policy_vpc_to_cos = !var.skip_vpc_cos_authorization_policy existing_cos_instance_guid = var.enable_vpc_flow_logs ? module.existing_cos_crn_parser[0].service_instance : null existing_storage_bucket_name = var.enable_vpc_flow_logs ? module.cos_buckets[0].buckets[0].bucket_name : null } diff --git a/solutions/simple/variables.tf b/solutions/simple/variables.tf index a762c75c..c2d44cb2 100644 --- a/solutions/simple/variables.tf +++ b/solutions/simple/variables.tf @@ -22,12 +22,12 @@ variable "provider_visibility" { variable "use_existing_resource_group" { type = bool description = "Whether to use an existing resource group." - default = true + default = false } variable "resource_group_name" { type = string - description = "The name of a new or an existing resource group to provision the watsonx.ai resources. If a prefix input variable is specified, the prefix is added to the name in the `-` format." + description = "The name of a new or an existing resource group to provision the resources. If a prefix input variable is specified, the prefix is added to the name in the `-` format." } variable "prefix" { @@ -38,7 +38,7 @@ variable "prefix" { variable "vpc_name" { default = "simple" - description = "Name of the VPC." + description = "Name of the VPC. If a prefix input variable is specified, the prefix is added to the name in the `-` format." type = string } @@ -56,7 +56,7 @@ variable "resource_tags" { variable "access_tags" { type = list(string) - description = "A list of access tags to apply to the VPC resources created by the module. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial." + description = "A list of access tags to apply to the VPC resources created by this solution. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial." default = [] validation { @@ -285,42 +285,42 @@ variable "network_acls" { ############################################################################## -# VPC Flow Logs Variables +# VPC Flow Logs ############################################################################## variable "enable_vpc_flow_logs" { - description = "Flag to enable vpc flow logs. If true, flow log collector will be created" + description = "To enable vpc flow logs, set this to true." type = bool default = false } -variable "create_authorization_policy_vpc_to_cos" { - description = "Create authorisation policy for VPC to access COS. Set as false if authorization policy exists already" +variable "skip_vpc_cos_authorization_policy" { + description = "To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`." type = bool default = true } variable "existing_cos_instance_crn" { - description = "GUID of the COS instance to create Flow log collector" + description = "CRN of the existing COS instance. It is required to create the bucket used for flow logs." type = string default = null } variable "cos_bucket_name" { - description = "Name of the COS bucket to collect VPC flow logs" + description = "Name of the Cloud Object Storage bucket to be created collect VPC flow logs." type = string default = "cos-bucket" } variable "kms_encryption_enabled_bucket" { - description = "Set to true if bucket needs to be KMS encryption enabled" + description = "Set to true if Cloud Object Storage bucket needs to be KMS encryption enabled." type = bool default = false } variable "skip_cos_kms_auth_policy" { type = bool - description = "To skip creating auth policy that allows COS to access KMS key." + description = "To skip creating auth policy that allows Cloud Object Storage(COS) to access KMS key." default = false } diff --git a/solutions/simple/version.tf b/solutions/simple/version.tf index c27e769e..8146ac7d 100644 --- a/solutions/simple/version.tf +++ b/solutions/simple/version.tf @@ -1,5 +1,5 @@ terraform { - required_version = ">= 1.3.0" + required_version = ">= 1.9.0" required_providers { # Use "greater than or equal to" range in modules ibm = { From 41eaba05023cf48809b3ee068c312a598a5962e6 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Thu, 27 Feb 2025 23:47:47 +0530 Subject: [PATCH 04/46] update code --- .../{simple => fully-configurable}/README.md | 0 .../catalogValidationValues.json.template | 0 .../{simple => fully-configurable}/main.tf | 7 +- .../{simple => fully-configurable}/outputs.tf | 0 .../provider.tf | 0 .../variables.tf | 67 +++++++++++++++++-- .../{simple => fully-configurable}/version.tf | 4 +- 7 files changed, 71 insertions(+), 7 deletions(-) rename solutions/{simple => fully-configurable}/README.md (100%) rename solutions/{simple => fully-configurable}/catalogValidationValues.json.template (100%) rename solutions/{simple => fully-configurable}/main.tf (91%) rename solutions/{simple => fully-configurable}/outputs.tf (100%) rename solutions/{simple => fully-configurable}/provider.tf (100%) rename solutions/{simple => fully-configurable}/variables.tf (84%) rename solutions/{simple => fully-configurable}/version.tf (52%) diff --git a/solutions/simple/README.md b/solutions/fully-configurable/README.md similarity index 100% rename from solutions/simple/README.md rename to solutions/fully-configurable/README.md diff --git a/solutions/simple/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template similarity index 100% rename from solutions/simple/catalogValidationValues.json.template rename to solutions/fully-configurable/catalogValidationValues.json.template diff --git a/solutions/simple/main.tf b/solutions/fully-configurable/main.tf similarity index 91% rename from solutions/simple/main.tf rename to solutions/fully-configurable/main.tf index a6873cd9..35e413b2 100644 --- a/solutions/simple/main.tf +++ b/solutions/fully-configurable/main.tf @@ -68,10 +68,12 @@ locals { kms_key_ring_name = try("${var.prefix}-${var.kms_key_ring_name}", var.kms_key_ring_name) kms_key_name = try("${var.prefix}-${var.kms_key_name}", var.kms_key_name) + + create_kms_key = var.existing_kms_key_crn == null ? ((var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null) ? true : false) : false } module "kms" { - count = (var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null) ? 1 : 0 # no need to create any KMS resources if not passing an existing KMS CRN + count = local.create_kms_key ? 1 : 0 # no need to create any KMS resources if not passing an existing KMS CRN or existing KMS key CRN is provided source = "terraform-ibm-modules/kms-all-inclusive/ibm" version = "4.19.5" create_key_protect_instance = false @@ -120,7 +122,10 @@ module "vpc" { default_security_group_name = var.default_security_group_name default_routing_table_name = var.default_routing_table_name network_acls = var.network_acls + clean_default_sg_acl = var.clean_default_sg_acl # use_public_gateways = local.public_gateway_object + address_prefixes = var.address_prefixes + routes = var.routes enable_vpc_flow_logs = var.enable_vpc_flow_logs create_authorization_policy_vpc_to_cos = !var.skip_vpc_cos_authorization_policy existing_cos_instance_guid = var.enable_vpc_flow_logs ? module.existing_cos_crn_parser[0].service_instance : null diff --git a/solutions/simple/outputs.tf b/solutions/fully-configurable/outputs.tf similarity index 100% rename from solutions/simple/outputs.tf rename to solutions/fully-configurable/outputs.tf diff --git a/solutions/simple/provider.tf b/solutions/fully-configurable/provider.tf similarity index 100% rename from solutions/simple/provider.tf rename to solutions/fully-configurable/provider.tf diff --git a/solutions/simple/variables.tf b/solutions/fully-configurable/variables.tf similarity index 84% rename from solutions/simple/variables.tf rename to solutions/fully-configurable/variables.tf index c2d44cb2..b73dcd8e 100644 --- a/solutions/simple/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -49,7 +49,7 @@ variable "region" { } variable "resource_tags" { - description = "Optional list of tags for the resources created by this solution." + description = "List of tags for the resources created by this solution." type = list(string) default = [] } @@ -283,6 +283,59 @@ variable "network_acls" { } +variable "clean_default_sg_acl" { + description = "Remove all rules from the default VPC security group and VPC ACL (less permissive)" + type = bool + default = false +} + +variable "address_prefixes" { + description = "The IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes" + type = object({ + zone-1 = optional(list(string)) + zone-2 = optional(list(string)) + zone-3 = optional(list(string)) + }) + default = { + zone-1 = null + zone-2 = null + zone-3 = null + } + validation { + error_message = "Keys for `use_public_gateways` must be in the order `zone-1`, `zone-2`, `zone-3`." + condition = var.address_prefixes == null ? true : ( + (length(var.address_prefixes) == 1 && keys(var.address_prefixes)[0] == "zone-1") || + (length(var.address_prefixes) == 2 && keys(var.address_prefixes)[0] == "zone-1" && keys(var.address_prefixes)[1] == "zone-2") || + (length(var.address_prefixes) == 3 && keys(var.address_prefixes)[0] == "zone-1" && keys(var.address_prefixes)[1] == "zone-2") && keys(var.address_prefixes)[2] == "zone-3" + ) + } +} + +############################################################################## +# Add routes to VPC +############################################################################## + +variable "routes" { + description = "Allows you to specify the next hop for packets based on their destination address" + type = list( + object({ + name = string + route_direct_link_ingress = optional(bool) + route_transit_gateway_ingress = optional(bool) + route_vpc_zone_ingress = optional(bool) + routes = optional( + list( + object({ + action = optional(string) + zone = number + destination = string + next_hop = string + }) + )) + }) + ) + default = [] +} ############################################################################## # VPC Flow Logs @@ -348,6 +401,12 @@ variable "cos_bucket_class" { # KMS ############################################################################################################### +variable "existing_kms_key_crn" { + type = string + default = null + description = "The CRN of the existing root key of key management service (KMS) that is used to encrypt the Cloud Object Storage bucket." +} + variable "existing_kms_instance_crn" { type = string default = null @@ -381,19 +440,19 @@ variable "kms_key_name" { ############################################################################## variable "default_network_acl_name" { - description = "OPTIONAL - Name of the Default ACL. If null, a name will be automatically generated" + description = "Name of the Default ACL. If null, a name will be automatically generated" type = string default = null } variable "default_security_group_name" { - description = "OPTIONAL - Name of the Default Security Group. If null, a name will be automatically generated" + description = "Name of the Default Security Group. If null, a name will be automatically generated" type = string default = null } variable "default_routing_table_name" { - description = "OPTIONAL - Name of the Default Routing Table. If null, a name will be automatically generated" + description = "Name of the Default Routing Table. If null, a name will be automatically generated" type = string default = null } diff --git a/solutions/simple/version.tf b/solutions/fully-configurable/version.tf similarity index 52% rename from solutions/simple/version.tf rename to solutions/fully-configurable/version.tf index 8146ac7d..a6c8e06e 100644 --- a/solutions/simple/version.tf +++ b/solutions/fully-configurable/version.tf @@ -1,10 +1,10 @@ terraform { required_version = ">= 1.9.0" required_providers { - # Use "greater than or equal to" range in modules + # Lock DA into an exact provider version - renovate automation will keep it updated ibm = { source = "IBM-Cloud/ibm" - version = ">= 1.59.0, < 2.0.0" + version = "1.75.2" } } } From faf01ac37f4c5a8c19a312a94180efbc0609de31 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Fri, 28 Feb 2025 00:38:16 +0530 Subject: [PATCH 05/46] add validations --- solutions/fully-configurable/main.tf | 6 +++--- solutions/fully-configurable/variables.tf | 19 +++++++++++++++++-- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 35e413b2..619fe5c9 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -32,7 +32,7 @@ locals { access_tags = var.access_tags bucket_name = local.bucket_name kms_encryption_enabled = var.kms_encryption_enabled_bucket - kms_guid = var.kms_encryption_enabled_bucket ? module.existing_kms_crn_parser[0].service_instance : null + kms_guid = var.kms_encryption_enabled_bucket ? module.existing_kms_instance_crn_parser[0].service_instance : null kms_key_crn = var.kms_encryption_enabled_bucket ? var.existing_kms_instance_crn : null skip_iam_authorization_policy = var.skip_cos_kms_auth_policy management_endpoint_type = var.management_endpoint_type_for_bucket @@ -55,7 +55,7 @@ module "cos_buckets" { ####################################################################################################################### # parse KMS details from the existing KMS instance CRN -module "existing_kms_crn_parser" { +module "existing_kms_instance_crn_parser" { count = var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null ? 1 : 0 source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" version = "1.1.0" @@ -64,7 +64,7 @@ module "existing_kms_crn_parser" { locals { # fetch KMS region from existing_kms_instance_crn if KMS resources are required - kms_region = var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null ? module.existing_kms_crn_parser[0].region : null + kms_region = var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null ? module.existing_kms_instance_crn_parser[0].region : null kms_key_ring_name = try("${var.prefix}-${var.kms_key_ring_name}", var.kms_key_ring_name) kms_key_name = try("${var.prefix}-${var.kms_key_name}", var.kms_key_name) diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index b73dcd8e..e03a9c25 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -357,6 +357,11 @@ variable "existing_cos_instance_crn" { description = "CRN of the existing COS instance. It is required to create the bucket used for flow logs." type = string default = null + + validation { + condition = var.enable_vpc_flow_logs ? (var.existing_cos_instance_crn != null ? true : false) : true + error_message = "'existing_cos_instance_crn' is required if 'enable_vpc_flow_logs' is set to true." + } } variable "cos_bucket_name" { @@ -368,12 +373,22 @@ variable "cos_bucket_name" { variable "kms_encryption_enabled_bucket" { description = "Set to true if Cloud Object Storage bucket needs to be KMS encryption enabled." type = bool - default = false + default = true + + validation { + condition = !var.enable_vpc_flow_logs ? (var.kms_encryption_enabled_bucket ? false : true) : true + error_message = "'kms_encryption_enabled_bucket' should be false if 'enable_vpc_flow_logs' is set to false." + } + + validation { + condition = var.kms_encryption_enabled_bucket ? ((var.existing_kms_key_crn != null || var.existing_kms_instance_crn != null) ? true : false) : true + error_message = "Either 'existing_kms_key_crn' or 'existing_kms_instance_crn' is required if 'kms_encryption_enabled_bucket' is set to true." + } } variable "skip_cos_kms_auth_policy" { type = bool - description = "To skip creating auth policy that allows Cloud Object Storage(COS) to access KMS key." + description = "To skip creating an IAM authorization policy that allows Cloud Object Storage(COS) to access KMS key." default = false } From cc592f73a404070aed240496bf75a1d4b030c2af Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Tue, 4 Mar 2025 11:33:18 +0530 Subject: [PATCH 06/46] create public_gateway object and added validation --- .../catalogValidationValues.json.template | 2 +- solutions/fully-configurable/main.tf | 39 ++++++++++--------- solutions/fully-configurable/variables.tf | 19 +++++---- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/solutions/fully-configurable/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template index 2815de1b..47adc9b3 100644 --- a/solutions/fully-configurable/catalogValidationValues.json.template +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -2,5 +2,5 @@ "ibmcloud_api_key": $VALIDATION_APIKEY, "region": "us-south", "resource_tags": $TAGS, - "resource_group_name": $PREFIX + "existing_resource_group_name": $PREFIX } diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 619fe5c9..3d4164f8 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -9,8 +9,7 @@ locals { module "resource_group" { source = "terraform-ibm-modules/resource-group/ibm" version = "1.1.6" - resource_group_name = var.use_existing_resource_group == false ? try("${local.prefix}-${var.resource_group_name}", var.resource_group_name) : null - existing_resource_group_name = var.use_existing_resource_group == true ? var.resource_group_name : null + existing_resource_group_name = var.existing_resource_group_name } ############################################################################# @@ -104,26 +103,28 @@ module "kms" { ############################################################################# locals { - # //TO DO - # to create use_public_gateways object + # create 'use_public_gateways' object + public_gateway_object = { + for key, value in var.subnets : key => value != null ? length([for sub in value : sub.public_gateway if sub.public_gateway]) > 0 ? [for sub in value : sub.public_gateway if sub.public_gateway][0] : false : false + } } module "vpc" { - source = "../../" - resource_group_id = module.resource_group.resource_group_id - region = var.region - create_vpc = true - name = var.vpc_name - prefix = local.prefix - tags = var.resource_tags - access_tags = var.access_tags - subnets = var.subnets - default_network_acl_name = var.default_network_acl_name - default_security_group_name = var.default_security_group_name - default_routing_table_name = var.default_routing_table_name - network_acls = var.network_acls - clean_default_sg_acl = var.clean_default_sg_acl - # use_public_gateways = local.public_gateway_object + source = "../../" + resource_group_id = module.resource_group.resource_group_id + region = var.region + create_vpc = true + name = var.vpc_name + prefix = local.prefix + tags = var.resource_tags + access_tags = var.access_tags + subnets = var.subnets + default_network_acl_name = var.default_network_acl_name + default_security_group_name = var.default_security_group_name + default_routing_table_name = var.default_routing_table_name + network_acls = var.network_acls + clean_default_sg_acl = var.clean_default_sg_acl + use_public_gateways = local.public_gateway_object address_prefixes = var.address_prefixes routes = var.routes enable_vpc_flow_logs = var.enable_vpc_flow_logs diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index e03a9c25..48fda473 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -19,15 +19,9 @@ variable "provider_visibility" { } } -variable "use_existing_resource_group" { - type = bool - description = "Whether to use an existing resource group." - default = false -} - -variable "resource_group_name" { +variable "existing_resource_group_name" { type = string - description = "The name of a new or an existing resource group to provision the resources. If a prefix input variable is specified, the prefix is added to the name in the `-` format." + description = "The name of an existing resource group to provision the resources." } variable "prefix" { @@ -37,7 +31,7 @@ variable "prefix" { } variable "vpc_name" { - default = "simple" + default = "vpc" description = "Name of the VPC. If a prefix input variable is specified, the prefix is added to the name in the `-` format." type = string } @@ -108,6 +102,11 @@ variable "subnets" { } ] } + + validation { + condition = alltrue([for key, value in var.subnets : value != null ? length([for subnet in value : subnet.public_gateway if subnet.public_gateway]) > 1 ? false : true : true]) + error_message = "var.subnets has more than one public gateway in a zone. Only one public gateway can be attached to a zone for the virtual private cloud." + } } ############################################################################## @@ -373,7 +372,7 @@ variable "cos_bucket_name" { variable "kms_encryption_enabled_bucket" { description = "Set to true if Cloud Object Storage bucket needs to be KMS encryption enabled." type = bool - default = true + default = false validation { condition = !var.enable_vpc_flow_logs ? (var.kms_encryption_enabled_bucket ? false : true) : true From c083207eda7ca2376631d1868febfcc991cf18c1 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Thu, 6 Mar 2025 13:59:45 +0530 Subject: [PATCH 07/46] added vpn gateway feature --- README.md | 3 +++ main.tf | 24 +++++++++++++++++++++- solutions/fully-configurable/main.tf | 2 ++ solutions/fully-configurable/variables.tf | 22 +++++++++++++++++++- variables.tf | 25 +++++++++++++++++++++++ 5 files changed, 74 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c78ad649..fef27e42 100644 --- a/README.md +++ b/README.md @@ -169,6 +169,7 @@ To attach access management tags to resources in this module, you need the follo | [ibm_is_vpc_dns_resolution_binding.vpc_dns_resolution_binding_id](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_dns_resolution_binding) | resource | | [ibm_is_vpc_routing_table.route_table](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_routing_table) | resource | | [ibm_is_vpc_routing_table_route.routing_table_routes](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_routing_table_route) | resource | +| [ibm_is_vpn_gateway.gateway](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpn_gateway) | resource | | [ibm_resource_instance.dns_instance_hub](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance) | resource | | [time_sleep.wait_for_authorization_policy](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | | [time_sleep.wait_for_vpc_creation_data](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | @@ -203,6 +204,7 @@ To attach access management tags to resources in this module, you need the follo | [enable\_hub\_vpc\_crn](#input\_enable\_hub\_vpc\_crn) | Indicates whether Hub VPC CRN is passed. | `bool` | `false` | no | | [enable\_hub\_vpc\_id](#input\_enable\_hub\_vpc\_id) | Indicates whether Hub VPC ID is passed. | `bool` | `false` | no | | [enable\_vpc\_flow\_logs](#input\_enable\_vpc\_flow\_logs) | Flag to enable vpc flow logs. If true, flow log collector will be created | `bool` | `false` | no | +| [enable\_vpn\_gateways](#input\_enable\_vpn\_gateways) | Set to true to add VPN gateways. If true, VPN gateways will be created using the variable 'vpn\_gateways'. | `bool` | `false` | no | | [existing\_cos\_instance\_guid](#input\_existing\_cos\_instance\_guid) | GUID of the COS instance to create Flow log collector | `string` | `null` | no | | [existing\_dns\_instance\_id](#input\_existing\_dns\_instance\_id) | Id of an existing dns instance in which the custom resolver is created. Only relevant if enable\_hub is set to true. | `string` | `null` | no | | [existing\_storage\_bucket\_name](#input\_existing\_storage\_bucket\_name) | Name of the COS bucket to collect VPC flow logs | `string` | `null` | no | @@ -232,6 +234,7 @@ To attach access management tags to resources in this module, you need the follo | [use\_existing\_dns\_instance](#input\_use\_existing\_dns\_instance) | Whether to use an existing dns instance. If true, existing\_dns\_instance\_id must be set. | `bool` | `false` | no | | [use\_public\_gateways](#input\_use\_public\_gateways) | Create a public gateway in any of the three zones with `true`. |
object({
zone-1 = optional(bool)
zone-2 = optional(bool)
zone-3 = optional(bool)
})
|
{
"zone-1": true,
"zone-2": false,
"zone-3": false
}
| no | | [vpc\_flow\_logs\_name](#input\_vpc\_flow\_logs\_name) | The name to give the provisioned VPC flow logs. If not set, the module generates a name based on the `prefix` and `name` variables. | `string` | `null` | no | +| [vpn\_gateways](#input\_vpn\_gateways) | List of VPN gateways to create. |
list(
object({
name = string
vpc_name = string
subnet_name = string # Do not include prefix, use same name as in `var.subnets`
mode = optional(string)
resource_group = optional(string)
access_tags = optional(list(string), [])
})
)
| `[]` | no | ### Outputs diff --git a/main.tf b/main.tf index 6b7fab72..68789284 100644 --- a/main.tf +++ b/main.tf @@ -356,7 +356,7 @@ resource "ibm_is_flow_log" "flow_logs" { ############################################################################## # DNS ZONE -# ############################################################################## +############################################################################### resource "ibm_dns_zone" "dns_zone" { count = var.enable_hub && !var.skip_custom_resolver_hub_creation && alltrue([var.dns_zone_name != null, var.dns_zone_name != ""]) ? 1 : 0 @@ -406,6 +406,28 @@ resource "ibm_dns_resource_record" "dns_record" { locals { record_ids = [for record in ibm_dns_resource_record.dns_record : element(split("/", record.id), 2)] + + # Convert the vpn_gateway input from list to a map + vpn_gateway_map = !var.enable_vpn_gateways ? {} : { for gateway in var.vpn_gateways : gateway.name => gateway } + +} + +############################################################################## +# Create VPN Gateways +############################################################################## + +resource "ibm_is_vpn_gateway" "gateway" { + for_each = local.vpn_gateway_map + name = "${var.prefix}-${each.key}" + subnet = each.value.subnet_name + mode = each.value.mode + resource_group = each.value.resource_group == null ? var.resource_group_id : each.value.resource_group + tags = var.tags + access_tags = each.value.access_tags + + timeouts { + delete = "1h" + } } ############################################################################## diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 3d4164f8..1a4231fb 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -131,4 +131,6 @@ module "vpc" { create_authorization_policy_vpc_to_cos = !var.skip_vpc_cos_authorization_policy existing_cos_instance_guid = var.enable_vpc_flow_logs ? module.existing_cos_crn_parser[0].service_instance : null existing_storage_bucket_name = var.enable_vpc_flow_logs ? module.cos_buckets[0].buckets[0].bucket_name : null + enable_vpn_gateways = true + vpn_gateways = var.vpn_gateways } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 48fda473..ac4c804e 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -26,8 +26,8 @@ variable "existing_resource_group_name" { variable "prefix" { type = string + nullable = true description = "Prefix to add to all the resources created by this solution. To not use any prefix value, you can set this value to `null` or an empty string." - default = "dev" } variable "vpc_name" { @@ -470,3 +470,23 @@ variable "default_routing_table_name" { type = string default = null } + +############################################################################## +# VPN Gateways +############################################################################## + +variable "vpn_gateways" { + description = "List of VPN Gateways to create." + type = list( + object({ + name = string + vpc_name = string + subnet_name = string # Do not include prefix, use same name as in `var.subnets` + mode = optional(string) + resource_group = optional(string) + access_tags = optional(list(string), []) + }) + ) + + default = [] +} diff --git a/variables.tf b/variables.tf index 6428db7f..c68b4a3d 100644 --- a/variables.tf +++ b/variables.tf @@ -718,3 +718,28 @@ variable "dns_records" { error_message = "Invalid MX record configuration. For 'MX' records, value for 'preference' must be provided." } } + +############################################################################## +# VPN Gateways +############################################################################## + +variable "enable_vpn_gateways" { + type = bool + description = "Set to true to add VPN gateways. If true, VPN gateways will be created using the variable 'vpn_gateways'." + default = false +} + +variable "vpn_gateways" { + description = "List of VPN gateways to create." + type = list( + object({ + name = string + vpc_name = string + subnet_name = string # Do not include prefix, use same name as in `var.subnets` + mode = optional(string) + resource_group = optional(string) + access_tags = optional(list(string), []) + }) + ) + default = [] +} From e5cc87a6407a1039eb2816cb56b598512b339f83 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 10 Mar 2025 17:38:00 +0530 Subject: [PATCH 08/46] update outputs --- solutions/fully-configurable/outputs.tf | 33 +++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/solutions/fully-configurable/outputs.tf b/solutions/fully-configurable/outputs.tf index e6b2071e..cfca496d 100644 --- a/solutions/fully-configurable/outputs.tf +++ b/solutions/fully-configurable/outputs.tf @@ -34,3 +34,36 @@ output "vpc_flow_logs" { description = "Details of VPC flow logs collector" value = module.vpc.vpc_flow_logs } + +############################################################################## +# Network ACLs +############################################################################## + +output "network_acls" { + description = "List of shortnames and IDs of network ACLs" + value = module.vpc.network_acls +} + +############################################################################## +# Subnet Outputs +############################################################################## + +output "subnet_ids" { + description = "The IDs of the subnets" + value = module.vpc.subnet_ids +} + +output "subnet_detail_list" { + description = "A list of subnets containing names, CIDR blocks, and zones." + value = module.vpc.subnet_detail_list +} + +output "subnet_zone_list" { + description = "A list containing subnet IDs and subnet zones" + value = module.vpc.subnet_zone_list +} + +output "subnet_detail_map" { + description = "A map of subnets containing IDs, CIDR blocks, and zones" + value = module.vpc.subnet_detail_map +} From 3ffb85908e0e02f230186c3320d0297250f2fd7a Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Wed, 12 Mar 2025 13:22:27 +0530 Subject: [PATCH 09/46] updated code, variables and outputs --- solutions/fully-configurable/main.tf | 90 ++++++++++++++++++--- solutions/fully-configurable/variables.tf | 96 ++++++++++++++++------- 2 files changed, 148 insertions(+), 38 deletions(-) diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 1a4231fb..2b1d3004 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -1,5 +1,5 @@ locals { - prefix = var.prefix != null ? (var.prefix != "" ? var.prefix : null) : null + prefix = (var.prefix != null && trimspace(var.prefix) != "" ? var.prefix : "") } ############################################################################## @@ -25,20 +25,31 @@ module "existing_cos_crn_parser" { } locals { - bucket_name = try("${local.prefix}-${var.cos_bucket_name}", var.cos_bucket_name) + cos_instance_guid = var.existing_cos_instance_crn != null ? module.existing_cos_crn_parser[0].service_instance : null + bucket_name = "${local.prefix}${var.flow_logs_cos_bucket_name}" + kms_guid = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].service_instance : module.existing_kms_instance_crn_parser[0].service_instance) : null + kms_account_id = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].account_id : module.existing_kms_instance_crn_parser[0].account_id) : null + kms_service = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_instance_crn_parser[0].service_name : module.existing_kms_key_crn_parser[0].service_name) : null + cos_kms_key_crn = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? var.existing_flow_logs_bucket_kms_key_crn : module.kms[0].keys[format("%s.%s", local.kms_key_ring_name, local.kms_key_name)].crn) : null + create_cos_kms_iam_auth_policy = var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && !var.skip_cos_kms_iam_auth_policy bucket_config = [{ access_tags = var.access_tags bucket_name = local.bucket_name + add_bucket_name_suffix = var.add_bucket_name_suffix kms_encryption_enabled = var.kms_encryption_enabled_bucket - kms_guid = var.kms_encryption_enabled_bucket ? module.existing_kms_instance_crn_parser[0].service_instance : null - kms_key_crn = var.kms_encryption_enabled_bucket ? var.existing_kms_instance_crn : null - skip_iam_authorization_policy = var.skip_cos_kms_auth_policy + kms_guid = local.kms_guid + kms_key_crn = local.cos_kms_key_crn + skip_iam_authorization_policy = var.skip_cos_kms_iam_auth_policy management_endpoint_type = var.management_endpoint_type_for_bucket storage_class = var.cos_bucket_class resource_instance_id = var.existing_cos_instance_crn region_location = var.region - force_delete = true + force_delete = var.force_delete + archive_days = null + expire_days = null + retention_enabled = false + object_versioning_enabled = true }] } @@ -49,6 +60,45 @@ module "cos_buckets" { bucket_configs = local.bucket_config } +# Create IAM Authorization Policy to allow COS to access KMS for the encryption key +resource "ibm_iam_authorization_policy" "cos_kms_iam_auth_policy" { + count = local.create_cos_kms_iam_auth_policy ? 1 : 0 + source_service_name = "cloud-object-storage" + source_resource_instance_id = local.cos_instance_guid + roles = ["Reader"] + description = "Allow the COS instance ${local.cos_instance_guid} to read the ${local.kms_service} key ${local.cos_kms_key_crn} from the instance ${local.kms_guid}" + resource_attributes { + name = "serviceName" + operator = "stringEquals" + value = local.kms_service + } + resource_attributes { + name = "accountId" + operator = "stringEquals" + value = local.kms_account_id + } + resource_attributes { + name = "serviceInstance" + operator = "stringEquals" + value = local.kms_guid + } + resource_attributes { + name = "resourceType" + operator = "stringEquals" + value = "key" + } + resource_attributes { + name = "resource" + operator = "stringEquals" + value = local.cos_kms_key_crn + } + # Scope of policy now includes the key, so ensure to create new policy before + # destroying old one to prevent any disruption to every day services. + lifecycle { + create_before_destroy = true + } +} + ####################################################################################################################### # KMS Key ####################################################################################################################### @@ -61,14 +111,22 @@ module "existing_kms_instance_crn_parser" { crn = var.existing_kms_instance_crn } +# parse KMS details from the existing KMS instance CRN +module "existing_kms_key_crn_parser" { + count = var.kms_encryption_enabled_bucket && var.existing_flow_logs_bucket_kms_key_crn != null ? 1 : 0 + source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser" + version = "1.1.0" + crn = var.existing_flow_logs_bucket_kms_key_crn +} + locals { # fetch KMS region from existing_kms_instance_crn if KMS resources are required kms_region = var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null ? module.existing_kms_instance_crn_parser[0].region : null - kms_key_ring_name = try("${var.prefix}-${var.kms_key_ring_name}", var.kms_key_ring_name) - kms_key_name = try("${var.prefix}-${var.kms_key_name}", var.kms_key_name) + kms_key_ring_name = "${local.prefix}${var.flow_logs_cos_key_ring_name}" + kms_key_name = "${local.prefix}${var.flow_logs_cos_key_name}" - create_kms_key = var.existing_kms_key_crn == null ? ((var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null) ? true : false) : false + create_kms_key = (var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket) ? (var.existing_flow_logs_bucket_kms_key_crn == null ? (var.existing_kms_instance_crn != null ? true : false) : false) : false } module "kms" { @@ -128,9 +186,19 @@ module "vpc" { address_prefixes = var.address_prefixes routes = var.routes enable_vpc_flow_logs = var.enable_vpc_flow_logs - create_authorization_policy_vpc_to_cos = !var.skip_vpc_cos_authorization_policy - existing_cos_instance_guid = var.enable_vpc_flow_logs ? module.existing_cos_crn_parser[0].service_instance : null + create_authorization_policy_vpc_to_cos = !var.skip_vpc_cos_iam_auth_policy + existing_cos_instance_guid = var.enable_vpc_flow_logs ? local.cos_instance_guid : null existing_storage_bucket_name = var.enable_vpc_flow_logs ? module.cos_buckets[0].buckets[0].bucket_name : null enable_vpn_gateways = true vpn_gateways = var.vpn_gateways } + +############################################################################# +# VPE Gateway +############################################################################# + +# module "vpe_gateway" { +# source = "terraform-ibm-modules/vpe-gateway/ibm" +# version = "4.5.0" + +# } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index ac4c804e..c08f2a0e 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -11,7 +11,7 @@ variable "ibmcloud_api_key" { variable "provider_visibility" { description = "Set the visibility value for the IBM terraform provider. Supported values are `public`, `private`, `public-and-private`. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/guides/custom-service-endpoints)." type = string - default = "public" + default = "private" validation { condition = contains(["public", "private", "public-and-private"], var.provider_visibility) @@ -28,6 +28,16 @@ variable "prefix" { type = string nullable = true description = "Prefix to add to all the resources created by this solution. To not use any prefix value, you can set this value to `null` or an empty string." + + 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 "vpc_name" { @@ -341,19 +351,19 @@ variable "routes" { ############################################################################## variable "enable_vpc_flow_logs" { - description = "To enable vpc flow logs, set this to true." + description = "To enable VPC Flow logs, set this to true." type = bool default = false } -variable "skip_vpc_cos_authorization_policy" { - description = "To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`." +variable "skip_vpc_cos_iam_auth_policy" { + description = "To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`. Required only if `enable_vpc_flow_logs` is set to true." type = bool default = true } variable "existing_cos_instance_crn" { - description = "CRN of the existing COS instance. It is required to create the bucket used for flow logs." + description = "CRN of the existing COS instance. It is only required if `enable_vpc_flow_logs` is set to true and will be used to create the flow logs bucket." type = string default = null @@ -363,29 +373,29 @@ variable "existing_cos_instance_crn" { } } -variable "cos_bucket_name" { - description = "Name of the Cloud Object Storage bucket to be created collect VPC flow logs." +variable "flow_logs_cos_bucket_name" { + description = "Name of the Cloud Object Storage bucket to be created to collect VPC flow logs." type = string - default = "cos-bucket" + default = "flow-logs-bucket" } variable "kms_encryption_enabled_bucket" { - description = "Set to true if Cloud Object Storage bucket needs to be KMS encryption enabled." + description = "Set to true to encrypt the Cloud Object Storage Flow Logs bucket with a KMS key. If set to true, a value must be passed for existing_flow_logs_bucket_kms_key_crn (to use that key) or existing_kms_instance_crn (to create a new key). Value cannot be set to true if enable_vpc_flow_logs is set to false." type = bool default = false validation { condition = !var.enable_vpc_flow_logs ? (var.kms_encryption_enabled_bucket ? false : true) : true - error_message = "'kms_encryption_enabled_bucket' should be false if 'enable_vpc_flow_logs' is set to false." + error_message = "'kms_encryption_enabled_bucket' can not be true if 'enable_vpc_flow_logs' is set to false." } validation { - condition = var.kms_encryption_enabled_bucket ? ((var.existing_kms_key_crn != null || var.existing_kms_instance_crn != null) ? true : false) : true - error_message = "Either 'existing_kms_key_crn' or 'existing_kms_instance_crn' is required if 'kms_encryption_enabled_bucket' is set to true." + condition = var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket ? ((var.existing_flow_logs_bucket_kms_key_crn != null || var.existing_kms_instance_crn != null) ? true : false) : true + error_message = "Either 'existing_flow_logs_bucket_kms_key_crn' or 'existing_kms_instance_crn' is required if 'enable_vpc_flow_logs' and 'kms_encryption_enabled_bucket' are set to true." } } -variable "skip_cos_kms_auth_policy" { +variable "skip_cos_kms_iam_auth_policy" { type = bool description = "To skip creating an IAM authorization policy that allows Cloud Object Storage(COS) to access KMS key." default = false @@ -394,7 +404,7 @@ variable "skip_cos_kms_auth_policy" { variable "management_endpoint_type_for_bucket" { description = "The type of endpoint for the IBM Terraform provider to use to manage Cloud Object Storage buckets (`public`, `private`, or `direct`). If you are using a private endpoint, make sure that you enable virtual routing and forwarding (VRF) in your account, and that the Terraform runtime can access the IBM Cloud Private network." type = string - default = "public" + default = "direct" validation { condition = contains(["public", "private", "direct"], var.management_endpoint_type_for_bucket) error_message = "The specified `management_endpoint_type_for_bucket` is not valid. Specify a valid type of endpoint for the IBM Terraform provider to use to manage Cloud Object Storage buckets." @@ -411,42 +421,54 @@ variable "cos_bucket_class" { } } +variable "force_delete" { + type = bool + description = "Whether to delete all the objects in the flow logs Cloud Object Storage bucket before the bucket is deleted." + default = false +} + +variable "add_bucket_name_suffix" { + type = bool + description = "Add a randomly generated suffix that is 4 characters in length, to the name of the newly provisioned Cloud Object Storage bucket. Do not use this suffix if you are passing the existing Cloud Object Storage bucket. To manage the name of the Cloud Object Storage bucket manually, use the `flow_logs_cos_bucket_name` variables." + default = true +} + ############################################################################################################### # KMS ############################################################################################################### -variable "existing_kms_key_crn" { +variable "existing_flow_logs_bucket_kms_key_crn" { type = string default = null - description = "The CRN of the existing root key of key management service (KMS) that is used to encrypt the Cloud Object Storage bucket." + description = "The CRN of the existing root key of key management service (KMS) that is used to encrypt the flow logs Cloud Object Storage bucket." } variable "existing_kms_instance_crn" { type = string default = null - description = "The CRN of the existing key management service (KMS) that is used to create keys for encrypting the Cloud Object Storage bucket." + description = "The CRN of the existing key management service (KMS) that is used to create keys for encrypting the flow logs Cloud Object Storage bucket." } variable "kms_endpoint_type" { type = string - description = "The type of endpoint to use for communicating with the Key Protect instance. Possible values: `public`, `private`. Applies only if `existing_cos_kms_key_crn` is not specified." - default = "public" + description = "The type of endpoint to use for communicating with the KMS. Possible values: `public`, `private`. Applies only if `existing_flow_logs_bucket_kms_key_crn` is not specified." + default = "private" validation { condition = can(regex("public|private", var.kms_endpoint_type)) error_message = "Valid values for the `kms_endpoint_type_value` are `public` or `private`." } } -variable "kms_key_ring_name" { +variable "flow_logs_cos_key_ring_name" { type = string - default = "cos-key-ring" + default = "flow-logs-cos-key-ring" description = "The name of the key ring to create for the Cloud Object Storage bucket key. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key ring is prefixed to the value in the `-value` format." } -variable "kms_key_name" { +variable "flow_logs_cos_key_name" { type = string - default = "cos-key" - description = "The name of the key to create for the Cloud Object Storage bucket. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key is prefixed to the value in the `-value` format." + default = "flow-logs-cos-key" + description = "The name of the key to encrypt the flow logs Cloud Object Storage bucket. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key is prefixed to the value in the `-value` format." } ############################################################################## @@ -454,19 +476,19 @@ variable "kms_key_name" { ############################################################################## variable "default_network_acl_name" { - description = "Name of the Default ACL. If null, a name will be automatically generated" + description = "Name of the Default ACL. If null, a name will be automatically generated." type = string default = null } variable "default_security_group_name" { - description = "Name of the Default Security Group. If null, a name will be automatically generated" + description = "Name of the Default Security Group. If null, a name will be automatically generated." type = string default = null } variable "default_routing_table_name" { - description = "Name of the Default Routing Table. If null, a name will be automatically generated" + description = "Name of the Default Routing Table. If null, a name will be automatically generated." type = string default = null } @@ -490,3 +512,23 @@ variable "vpn_gateways" { default = [] } + +############################################################################## +# VPE Gateways +############################################################################## + +# variable "vpe_gateways" { +# description = "List of VPE Gateways to create." +# type = list( +# object({ +# name = string +# vpc_name = string +# subnet_name = string # Do not include prefix, use same name as in `var.subnets` +# mode = optional(string) +# resource_group = optional(string) +# access_tags = optional(list(string), []) +# }) +# ) + +# default = [] +# } From fa3e9dbddff71fc238c8495dd8912d7297974113 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Thu, 13 Mar 2025 12:18:32 +0530 Subject: [PATCH 10/46] update default ACLs and add VPE gateway support --- solutions/fully-configurable/main.tf | 19 ++++-- solutions/fully-configurable/variables.tf | 80 +++++++++++++++-------- 2 files changed, 66 insertions(+), 33 deletions(-) diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 2b1d3004..22f631c8 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -197,8 +197,17 @@ module "vpc" { # VPE Gateway ############################################################################# -# module "vpe_gateway" { -# source = "terraform-ibm-modules/vpe-gateway/ibm" -# version = "4.5.0" - -# } +module "vpe_gateway" { + source = "terraform-ibm-modules/vpe-gateway/ibm" + version = "4.5.0" + resource_group_id = module.resource_group.resource_group_id + region = var.region + prefix = local.prefix + security_group_ids = var.security_group_ids + vpc_name = module.vpc.vpc_name + vpc_id = module.vpc.vpc_id + subnet_zone_list = module.vpc.subnet_zone_list + cloud_services = var.cloud_services + cloud_service_by_crn = var.cloud_service_by_crn + service_endpoints = var.vpe_service_endpoints +} diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index c08f2a0e..c00b770a 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -179,8 +179,8 @@ variable "network_acls" { tcp = { port_min = 443 port_max = 443 - source_port_min = 1024 - source_port_max = 65535 + source_port_min = 443 + source_port_max = 443 } destination = "0.0.0.0/0" source = "0.0.0.0/0" @@ -192,8 +192,8 @@ variable "network_acls" { tcp = { port_min = 80 port_max = 80 - source_port_min = 1024 - source_port_max = 65535 + source_port_min = 80 + source_port_max = 80 } destination = "0.0.0.0/0" source = "0.0.0.0/0" @@ -205,8 +205,8 @@ variable "network_acls" { tcp = { port_min = 22 port_max = 22 - source_port_min = 1024 - source_port_max = 65535 + source_port_min = 22 + source_port_max = 22 } destination = "0.0.0.0/0" source = "0.0.0.0/0" @@ -218,8 +218,8 @@ variable "network_acls" { tcp = { source_port_min = 443 source_port_max = 443 - port_min = 1024 - port_max = 65535 + port_min = 443 + port_max = 443 } destination = "0.0.0.0/0" source = "0.0.0.0/0" @@ -231,8 +231,8 @@ variable "network_acls" { tcp = { source_port_min = 80 source_port_max = 80 - port_min = 1024 - port_max = 65535 + port_min = 80 + port_max = 80 } destination = "0.0.0.0/0" source = "0.0.0.0/0" @@ -244,8 +244,8 @@ variable "network_acls" { tcp = { source_port_min = 22 source_port_max = 22 - port_min = 1024 - port_max = 65535 + port_min = 22 + port_max = 22 } destination = "0.0.0.0/0" source = "0.0.0.0/0" @@ -295,7 +295,7 @@ variable "network_acls" { variable "clean_default_sg_acl" { description = "Remove all rules from the default VPC security group and VPC ACL (less permissive)" type = bool - default = false + default = true } variable "address_prefixes" { @@ -517,18 +517,42 @@ variable "vpn_gateways" { # VPE Gateways ############################################################################## -# variable "vpe_gateways" { -# description = "List of VPE Gateways to create." -# type = list( -# object({ -# name = string -# vpc_name = string -# subnet_name = string # Do not include prefix, use same name as in `var.subnets` -# mode = optional(string) -# resource_group = optional(string) -# access_tags = optional(list(string), []) -# }) -# ) - -# default = [] -# } +variable "cloud_services" { + description = "The list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names are created in the format `--`." + type = set(object({ + service_name = string + vpe_name = optional(string), # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name. + allow_dns_resolution_binding = optional(bool, false) + })) + default = [] +} + +variable "cloud_service_by_crn" { + description = "The list of cloud service CRNs used to create endpoint gateways. Use this list to identify services that are not supported by service name in the `cloud_services` variable. For a list of supported services, see [VPE-enabled services](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). If `service_name` is not specified, the CRN is used to find the name. If `vpe_name` is not specified in the list, VPE names are created in the format `--`." + type = set( + object({ + crn = string + vpe_name = optional(string) # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name. + service_name = optional(string) # Name of the service used to compute the name of the VPE. If not specified, the service name will be obtained from the crn. + allow_dns_resolution_binding = optional(bool, true) + }) + ) + default = [] +} + +variable "vpe_service_endpoints" { + description = "Service endpoints to use to create endpoint gateways. Can be `public`, or `private`." + type = string + default = "private" + + validation { + error_message = "Service endpoints can only be `public` or `private`." + condition = contains(["public", "private"], var.vpe_service_endpoints) + } +} + +variable "security_group_ids" { + description = "List of security group ids to attach to each endpoint gateway." + type = list(string) + default = [] +} From 35d41f874632b7811328cbb4d2b2f0528cff39e7 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Thu, 13 Mar 2025 12:49:39 +0530 Subject: [PATCH 11/46] add outputs --- README.md | 4 +++- main.tf | 11 +++++----- outputs.tf | 20 ++++++++++++++++++ solutions/fully-configurable/outputs.tf | 28 +++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index fef27e42..3137eb4a 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,7 @@ To attach access management tags to resources in this module, you need the follo | [ibm_is_vpc_dns_resolution_binding.vpc_dns_resolution_binding_id](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_dns_resolution_binding) | resource | | [ibm_is_vpc_routing_table.route_table](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_routing_table) | resource | | [ibm_is_vpc_routing_table_route.routing_table_routes](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_routing_table_route) | resource | -| [ibm_is_vpn_gateway.gateway](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpn_gateway) | resource | +| [ibm_is_vpn_gateway.vpn_gateway](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpn_gateway) | resource | | [ibm_resource_instance.dns_instance_hub](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_instance) | resource | | [time_sleep.wait_for_authorization_policy](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | | [time_sleep.wait_for_vpc_creation_data](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/sleep) | resource | @@ -261,6 +261,8 @@ To attach access management tags to resources in this module, you need the follo | [vpc\_flow\_logs](#output\_vpc\_flow\_logs) | Details of VPC flow logs collector | | [vpc\_id](#output\_vpc\_id) | ID of VPC created | | [vpc\_name](#output\_vpc\_name) | Name of VPC created | +| [vpn\_gateways\_data](#output\_vpn\_gateways\_data) | Details of VPN gateways data | +| [vpn\_gateways\_name](#output\_vpn\_gateways\_name) | List of names of VPN gateways. | ## Contributing diff --git a/main.tf b/main.tf index 68789284..cc9c3c65 100644 --- a/main.tf +++ b/main.tf @@ -406,17 +406,18 @@ resource "ibm_dns_resource_record" "dns_record" { locals { record_ids = [for record in ibm_dns_resource_record.dns_record : element(split("/", record.id), 2)] - - # Convert the vpn_gateway input from list to a map - vpn_gateway_map = !var.enable_vpn_gateways ? {} : { for gateway in var.vpn_gateways : gateway.name => gateway } - } ############################################################################## # Create VPN Gateways ############################################################################## -resource "ibm_is_vpn_gateway" "gateway" { +locals { + # Convert the vpn_gateway input from list to a map + vpn_gateway_map = !var.enable_vpn_gateways ? {} : { for gateway in var.vpn_gateways : gateway.name => gateway } +} + +resource "ibm_is_vpn_gateway" "vpn_gateway" { for_each = local.vpn_gateway_map name = "${var.prefix}-${each.key}" subnet = each.value.subnet_name diff --git a/outputs.tf b/outputs.tf index a99031fa..f4425ae5 100644 --- a/outputs.tf +++ b/outputs.tf @@ -197,3 +197,23 @@ output "dns_record_ids" { description = "List of all the domain resource records." value = length(ibm_dns_resource_record.dns_record) > 0 ? local.record_ids : null } + +############################################################################## +# VPN Gateways +############################################################################## + +output "vpn_gateways_name" { + description = "List of names of VPN gateways." + value = [ + for gateway in ibm_is_vpn_gateway.vpn_gateway : + gateway.name + ] +} + +output "vpn_gateways_data" { + description = "Details of VPN gateways data" + value = [ + for gateway in ibm_is_vpn_gateway.vpn_gateway : + gateway + ] +} diff --git a/solutions/fully-configurable/outputs.tf b/solutions/fully-configurable/outputs.tf index cfca496d..4eff04cf 100644 --- a/solutions/fully-configurable/outputs.tf +++ b/solutions/fully-configurable/outputs.tf @@ -67,3 +67,31 @@ output "subnet_detail_map" { description = "A map of subnets containing IDs, CIDR blocks, and zones" value = module.vpc.subnet_detail_map } + +############################################################################## +# VPN Gateways Outputs +############################################################################## + +output "vpn_gateways_name" { + description = "List of names of VPN gateways." + value = module.vpc.vpn_gateways_name +} + +output "vpn_gateways_data" { + description = "Details of VPN gateways data" + value = module.vpc.vpn_gateways_data +} + +############################################################################## +# VPE Outputs +############################################################################## + +output "vpe_ips" { + description = "The reserved IPs for endpoint gateways." + value = module.vpe_gateway.vpe_ips +} + +output "vpe_crn" { + description = "The CRN of the endpoint gateway" + value = module.vpe_gateway.crn +} From ab403956d86d85238fcad93e40a191bb6f5bdc66 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Thu, 13 Mar 2025 20:05:28 +0530 Subject: [PATCH 12/46] update code and default values --- solutions/fully-configurable/main.tf | 4 ++-- solutions/fully-configurable/variables.tf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 22f631c8..051433e0 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -29,7 +29,7 @@ locals { bucket_name = "${local.prefix}${var.flow_logs_cos_bucket_name}" kms_guid = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].service_instance : module.existing_kms_instance_crn_parser[0].service_instance) : null kms_account_id = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].account_id : module.existing_kms_instance_crn_parser[0].account_id) : null - kms_service = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_instance_crn_parser[0].service_name : module.existing_kms_key_crn_parser[0].service_name) : null + kms_service = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].service_name : module.existing_kms_instance_crn_parser[0].service_name) : null cos_kms_key_crn = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? var.existing_flow_logs_bucket_kms_key_crn : module.kms[0].keys[format("%s.%s", local.kms_key_ring_name, local.kms_key_name)].crn) : null create_cos_kms_iam_auth_policy = var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && !var.skip_cos_kms_iam_auth_policy @@ -188,7 +188,7 @@ module "vpc" { enable_vpc_flow_logs = var.enable_vpc_flow_logs create_authorization_policy_vpc_to_cos = !var.skip_vpc_cos_iam_auth_policy existing_cos_instance_guid = var.enable_vpc_flow_logs ? local.cos_instance_guid : null - existing_storage_bucket_name = var.enable_vpc_flow_logs ? module.cos_buckets[0].buckets[0].bucket_name : null + existing_storage_bucket_name = var.enable_vpc_flow_logs ? module.cos_buckets[0].buckets[local.bucket_name].bucket_name : null enable_vpn_gateways = true vpn_gateways = var.vpn_gateways } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index c00b770a..18d304b2 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -359,7 +359,7 @@ variable "enable_vpc_flow_logs" { variable "skip_vpc_cos_iam_auth_policy" { description = "To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`. Required only if `enable_vpc_flow_logs` is set to true." type = bool - default = true + default = false } variable "existing_cos_instance_crn" { @@ -424,7 +424,7 @@ variable "cos_bucket_class" { variable "force_delete" { type = bool description = "Whether to delete all the objects in the flow logs Cloud Object Storage bucket before the bucket is deleted." - default = false + default = true } variable "add_bucket_name_suffix" { From 42519bc95658232433a5eb2bd3e6721fd2ad4946 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 17 Mar 2025 14:00:22 +0530 Subject: [PATCH 13/46] add tests --- solutions/fully-configurable/main.tf | 4 +-- solutions/fully-configurable/variables.tf | 4 +-- tests/pr_test.go | 43 +++++++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 051433e0..ef3289cf 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -123,8 +123,8 @@ locals { # fetch KMS region from existing_kms_instance_crn if KMS resources are required kms_region = var.kms_encryption_enabled_bucket && var.existing_kms_instance_crn != null ? module.existing_kms_instance_crn_parser[0].region : null - kms_key_ring_name = "${local.prefix}${var.flow_logs_cos_key_ring_name}" - kms_key_name = "${local.prefix}${var.flow_logs_cos_key_name}" + kms_key_ring_name = "${local.prefix}${var.kms_key_ring_name}" + kms_key_name = "${local.prefix}${var.kms_key_name}" create_kms_key = (var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket) ? (var.existing_flow_logs_bucket_kms_key_crn == null ? (var.existing_kms_instance_crn != null ? true : false) : false) : false } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 18d304b2..001c8684 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -459,13 +459,13 @@ variable "kms_endpoint_type" { } } -variable "flow_logs_cos_key_ring_name" { +variable "kms_key_ring_name" { type = string default = "flow-logs-cos-key-ring" description = "The name of the key ring to create for the Cloud Object Storage bucket key. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key ring is prefixed to the value in the `-value` format." } -variable "flow_logs_cos_key_name" { +variable "kms_key_name" { type = string default = "flow-logs-cos-key" description = "The name of the key to encrypt the flow logs Cloud Object Storage bucket. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key is prefixed to the value in the `-value` format." diff --git a/tests/pr_test.go b/tests/pr_test.go index 242ddbdd..9c3343bb 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -26,6 +26,7 @@ const existingVPCExampleTerraformDir = "examples/existing_vpc" const specificZoneExampleTerraformDir = "examples/specific-zone-only" const noprefixExampleTerraformDir = "examples/no-prefix" const vpcWithDnsExampleTerraformDir = "examples/vpc-with-dns" +const fullyConfigFlavorDir = "solutions/fully-configurable" const resourceGroup = "geretain-test-resources" // Define a struct with fields that match the structure of the YAML data @@ -202,3 +203,45 @@ func TestRunVpcWithDnsExample(t *testing.T) { assert.Nil(t, err, "This should not have errored") assert.NotNil(t, output, "Expected some output") } + +// Test the fully-configurable DA with defaults (no flow logs) +func TestFullyConfigurable(t *testing.T) { + t.Parallel() + + // Verify ibmcloud_api_key variable is set + checkVariable := "TF_VAR_ibmcloud_api_key" + val, present := os.LookupEnv(checkVariable) + require.True(t, present, checkVariable+" environment variable not set") + require.NotEqual(t, "", val, checkVariable+" environment variable is empty") + + // Programmatically determine region to use based on availability + region, _ := testhelper.GetBestVpcRegion(val, "../common-dev-assets/common-go-assets/cloudinfo-region-vpc-gen2-prefs.yaml", "eu-de") + + options := testhelper.TestOptionsDefault(&testhelper.TestOptions{ + Testing: t, + TerraformDir: fullyConfigFlavorDir, + }) + + options.TerraformVars = map[string]interface{}{ + "provider_visibility": "public", + "existing_resource_group_name": resourceGroup, + "prefix": "fully-config", + "region": region, + } + output, err := options.RunTestConsistency() + assert.Nil(t, err, "This should not have errored") + assert.NotNil(t, output, "Expected some output") +} + +// Test the upgrade of fully-configurable DA with defaults +func TestRunUpgradeFullyConfigurable(t *testing.T) { + t.Parallel() + + options := setupOptions(t, "fully-config-upg", fullyConfigFlavorDir) + + output, err := options.RunTestUpgrade() + if !options.UpgradeTestSkipped { + assert.Nil(t, err, "This should not have errored") + assert.NotNil(t, output, "Expected some output") + } +} From bdf5d2f8246274bf65bcacce0042821fc885b83b Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 17 Mar 2025 15:59:32 +0530 Subject: [PATCH 14/46] add rules for cos bucket --- solutions/fully-configurable/main.tf | 20 ++++++-- solutions/fully-configurable/variables.tf | 59 +++++++++++++++++++++++ 2 files changed, 75 insertions(+), 4 deletions(-) diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index ef3289cf..4f9ef516 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -46,10 +46,22 @@ locals { resource_instance_id = var.existing_cos_instance_crn region_location = var.region force_delete = var.force_delete - archive_days = null - expire_days = null - retention_enabled = false - object_versioning_enabled = true + archive_rule = var.flow_logs_cos_bucket_archive_days != null ? { + enable = true + days = var.flow_logs_cos_bucket_archive_days + type = var.flow_logs_cos_bucket_archive_type + } : null + expire_rule = var.flow_logs_cos_bucket_expire_days != null ? { + enable = true + days = var.flow_logs_cos_bucket_expire_days + } : null + retention_rule = var.flow_logs_cos_bucket_enable_retention ? { + default = var.flow_logs_cos_bucket_default_retention_days + maximum = var.flow_logs_cos_bucket_maximum_retention_days + minimum = var.flow_logs_cos_bucket_minimum_retention_days + permanent = var.flow_logs_cos_bucket_enable_permanent_retention + } : null + object_versioning_enabled = var.flow_logs_cos_bucket_enable_object_versioning }] } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 001c8684..3864c4c9 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -433,6 +433,65 @@ variable "add_bucket_name_suffix" { default = true } +variable "flow_logs_cos_bucket_archive_days" { + description = "The number of days before the `archive_type` rule action takes effect for the flow logs cloud object storage bucket." + type = number + default = null +} + +variable "flow_logs_cos_bucket_archive_type" { + description = "The storage class or archive type you want the object to transition to in the flow logs cloud object storage bucket." + type = string + default = "Glacier" +} + +variable "flow_logs_cos_bucket_expire_days" { + description = "The number of days before the expire rule action takes effect for the flow logs cloud object storage bucket." + type = number + default = null +} + +variable "flow_logs_cos_bucket_enable_object_versioning" { + description = "Set it to true if object versioning is enabled so that multiple versions of an object are retained in the flow logs cloud object storage bucket. Cannot be used if `flow_logs_cos_bucket_enable_retention` is true." + type = bool + default = false + + validation { + condition = var.flow_logs_cos_bucket_enable_object_versioning ? (var.flow_logs_cos_bucket_enable_retention ? false : true) : true + error_message = "`flow_logs_cos_bucket_enable_object_versioning` cannot set true if `flow_logs_cos_bucket_enable_retention` is true." + } +} + +variable "flow_logs_cos_bucket_enable_retention" { + description = "Set to true to enable retention for the flow logs cloud object storage bucket." + type = bool + default = false +} + +variable "flow_logs_cos_bucket_default_retention_days" { + description = "The number of days that an object can remain unmodified in the flow logs cloud object storage bucket." + type = number + default = 90 +} + +variable "flow_logs_cos_bucket_maximum_retention_days" { + description = "The maximum number of days that an object can be kept unmodified in the flow logs cloud object storage." + type = number + default = 350 +} + +variable "flow_logs_cos_bucket_minimum_retention_days" { + description = "The minimum number of days that an object must be kept unmodified in the flow logs cloud object storage." + type = number + default = 90 +} + +variable "flow_logs_cos_bucket_enable_permanent_retention" { + description = "Whether permanent retention status is enabled for the flow logs cloud object storage bucket. [Learn more](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-immutable)." + type = bool + default = false +} + ############################################################################################################### # KMS ############################################################################################################### From eac159ba1ad2bcf607a5e3d008862d2344ead3e7 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 17 Mar 2025 18:48:36 +0530 Subject: [PATCH 15/46] update code --- README.md | 3 +- outputs.tf | 11 +++- .../catalogValidationValues.json.template | 3 +- solutions/fully-configurable/main.tf | 11 ++-- solutions/fully-configurable/outputs.tf | 9 +++ solutions/fully-configurable/variables.tf | 66 ++++++++++++++++++- 6 files changed, 93 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3137eb4a..4a851a33 100644 --- a/README.md +++ b/README.md @@ -252,6 +252,7 @@ To attach access management tags to resources in this module, you need the follo | [dns\_zone\_state](#output\_dns\_zone\_state) | The state of the DNS zone. | | [network\_acls](#output\_network\_acls) | List of shortnames and IDs of network ACLs | | [public\_gateways](#output\_public\_gateways) | Map of public gateways by zone | +| [security\_group\_details](#output\_security\_group\_details) | Details of security group. | | [subnet\_detail\_list](#output\_subnet\_detail\_list) | A list of subnets containing names, CIDR blocks, and zones. | | [subnet\_detail\_map](#output\_subnet\_detail\_map) | A map of subnets containing IDs, CIDR blocks, and zones | | [subnet\_ids](#output\_subnet\_ids) | The IDs of the subnets | @@ -261,7 +262,7 @@ To attach access management tags to resources in this module, you need the follo | [vpc\_flow\_logs](#output\_vpc\_flow\_logs) | Details of VPC flow logs collector | | [vpc\_id](#output\_vpc\_id) | ID of VPC created | | [vpc\_name](#output\_vpc\_name) | Name of VPC created | -| [vpn\_gateways\_data](#output\_vpn\_gateways\_data) | Details of VPN gateways data | +| [vpn\_gateways\_data](#output\_vpn\_gateways\_data) | Details of VPN gateways data. | | [vpn\_gateways\_name](#output\_vpn\_gateways\_name) | List of names of VPN gateways. | diff --git a/outputs.tf b/outputs.tf index f4425ae5..e679654b 100644 --- a/outputs.tf +++ b/outputs.tf @@ -211,9 +211,18 @@ output "vpn_gateways_name" { } output "vpn_gateways_data" { - description = "Details of VPN gateways data" + description = "Details of VPN gateways data." value = [ for gateway in ibm_is_vpn_gateway.vpn_gateway : gateway ] } + +############################################################################## +# Security Group Details +############################################################################## + +output "security_group_details" { + description = "Details of security group." + value = ibm_is_security_group_rule.default_vpc_rule +} diff --git a/solutions/fully-configurable/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template index 47adc9b3..01f86ae4 100644 --- a/solutions/fully-configurable/catalogValidationValues.json.template +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -2,5 +2,6 @@ "ibmcloud_api_key": $VALIDATION_APIKEY, "region": "us-south", "resource_tags": $TAGS, - "existing_resource_group_name": $PREFIX + "existing_resource_group_name": $PREFIX, + "prefix": $PREFIX } diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 4f9ef516..d0f0c1ae 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -46,22 +46,22 @@ locals { resource_instance_id = var.existing_cos_instance_crn region_location = var.region force_delete = var.force_delete - archive_rule = var.flow_logs_cos_bucket_archive_days != null ? { + archive_rule = var.flow_logs_cos_bucket_archive_days != null ? { enable = true days = var.flow_logs_cos_bucket_archive_days type = var.flow_logs_cos_bucket_archive_type } : null - expire_rule = var.flow_logs_cos_bucket_expire_days != null ? { + expire_rule = var.flow_logs_cos_bucket_expire_days != null ? { enable = true days = var.flow_logs_cos_bucket_expire_days } : null - retention_rule = var.flow_logs_cos_bucket_enable_retention ? { + retention_rule = var.flow_logs_cos_bucket_enable_retention ? { default = var.flow_logs_cos_bucket_default_retention_days maximum = var.flow_logs_cos_bucket_maximum_retention_days minimum = var.flow_logs_cos_bucket_minimum_retention_days permanent = var.flow_logs_cos_bucket_enable_permanent_retention } : null - object_versioning_enabled = var.flow_logs_cos_bucket_enable_object_versioning + object_versioning_enabled = var.flow_logs_cos_bucket_enable_object_versioning }] } @@ -193,7 +193,8 @@ module "vpc" { default_security_group_name = var.default_security_group_name default_routing_table_name = var.default_routing_table_name network_acls = var.network_acls - clean_default_sg_acl = var.clean_default_sg_acl + security_group_rules = var.security_group_rules + clean_default_sg_acl = var.clean_default_security_group_acl use_public_gateways = local.public_gateway_object address_prefixes = var.address_prefixes routes = var.routes diff --git a/solutions/fully-configurable/outputs.tf b/solutions/fully-configurable/outputs.tf index 4eff04cf..9ebd3d6c 100644 --- a/solutions/fully-configurable/outputs.tf +++ b/solutions/fully-configurable/outputs.tf @@ -95,3 +95,12 @@ output "vpe_crn" { description = "The CRN of the endpoint gateway" value = module.vpe_gateway.crn } + +############################################################################## +# Security Group Details +############################################################################## + +output "security_group_details" { + description = "Details of security group." + value = module.vpc.security_group_details +} diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 3864c4c9..767df493 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -292,12 +292,74 @@ variable "network_acls" { } -variable "clean_default_sg_acl" { +############################################################################## +# Default Security Group Rules +############################################################################## + +variable "security_group_rules" { + description = "A list of security group rules to be added to the default vpc security group (default empty)" + default = [] + type = list( + object({ + name = string + direction = string + remote = string + tcp = optional( + object({ + port_max = optional(number) + port_min = optional(number) + }) + ) + udp = optional( + object({ + port_max = optional(number) + port_min = optional(number) + }) + ) + icmp = optional( + object({ + type = optional(number) + code = optional(number) + }) + ) + }) + ) + + validation { + error_message = "Security group rule direction can only be `inbound` or `outbound`." + condition = (var.security_group_rules == null || length(var.security_group_rules) == 0) ? true : length(distinct( + flatten([ + # Check through rules + for rule in var.security_group_rules : + # Return false if direction is not valid + false if !contains(["inbound", "outbound"], rule.direction) + ]) + )) == 0 + } + + validation { + error_message = "Security group rule names must match the regex pattern ^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$." + condition = (var.security_group_rules == null || length(var.security_group_rules) == 0) ? true : length(distinct( + flatten([ + # Check through rules + for rule in var.security_group_rules : + # Return false if direction is not valid + false if !can(regex("^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$", rule.name)) + ]) + )) == 0 + } +} + +variable "clean_default_security_group_acl" { description = "Remove all rules from the default VPC security group and VPC ACL (less permissive)" type = bool default = true } +############################################################################## +# Address Prefixes +############################################################################## + variable "address_prefixes" { description = "The IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes" type = object({ @@ -613,5 +675,5 @@ variable "vpe_service_endpoints" { variable "security_group_ids" { description = "List of security group ids to attach to each endpoint gateway." type = list(string) - default = [] + default = null } From ca57c8980dc2de927f3b059c512fe4ce2606bbdf Mon Sep 17 00:00:00 2001 From: Khuzaima Shakeel <56439894+Khuzaima05@users.noreply.github.com> Date: Mon, 17 Mar 2025 19:53:47 +0530 Subject: [PATCH 16/46] added ibm_catalog.json and reference architecture diagram for VPC DA. (#924) * added ibm_catalog.json * updated ibm_catalog.json * updated tile * updated ibm catalog.json * updated ibm catalog.json * updated ibm catalog.json * updated ibm catalog.json * fix ibm_catalog * fix ibm_catalog * update ibm_catalog * update ibm_catalog * update ibm_catalog * update to ocp * update to vpc * update to vpc * update offering id * updated config * updated config * updated config * updated config * updated config * updated config * updated label * update cos dependency * updated kms dependency * updated kms dependency * added reference architecture * updated reference-architecture * test_name * updated json * updated catalog * updated catalog.json --------- Co-authored-by: Khuzaima-Shakeel --- .catalog-onboard-pipeline.yaml | 14 + ibm_catalog.json | 490 ++++++++++++++++++ images/vpc_icon.svg | 1 + .../deployable-architecture-vpc.svg | 4 + 4 files changed, 509 insertions(+) create mode 100644 .catalog-onboard-pipeline.yaml create mode 100644 ibm_catalog.json create mode 100644 images/vpc_icon.svg create mode 100644 reference-architecture/deployable-architecture-vpc.svg diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml new file mode 100644 index 00000000..019a251f --- /dev/null +++ b/.catalog-onboard-pipeline.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: v1 +offerings: + - name: deploy-arch-ibm-vpc + kind: solution + catalog_id: f64499c8-eb50-4985-bf91-29f9e605a433 + offering_id: ae881fc1-273f-472e-8437-99099a6a753b + include_git_submodules: true + variations: + - name: fully-configurable + mark_ready: true + install_type: fullstack + scc: + instance_id: 1c7d5f78-9262-44c3-b779-b28fe4d88c37 diff --git a/ibm_catalog.json b/ibm_catalog.json new file mode 100644 index 00000000..80b3e05d --- /dev/null +++ b/ibm_catalog.json @@ -0,0 +1,490 @@ +{ + "products": [ + { + "name": "deploy-arch-ibm-vpc", + "label": "[Add-ons Beta] Cloud automation for VPC", + "product_kind": "solution", + "tags": [ + "network_vpc", + "ibm_created", + "target_terraform", + "terraform", + "support_ibm", + "solution" + ], + "keywords": [ + "vpc", + "terraform", + "IaC", + "infrastructure as code", + "solution" + ], + "short_description": "Provisions a VPC network on IBM Cloud", + "long_description": "The VPC landing zone deployable architecture deploys a simple Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters.", + "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/README.md", + "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/images/vpc_icon.svg", + "provider_name": "IBM", + "features": [ + { + "title": "Create a VPC on IBM Cloud", + "description": "Create a VPC on IBM Cloud." + } + ], + "flavors": [ + { + "label": "Fully configurable", + "name": "fully-configurable", + "install_type": "fullstack", + "working_directory": "solutions/fully-configurable", + "architecture": { + "descriptions": "This architecture creates a VPC.", + "features": [ + { + "title": "Creates a VPC", + "description": "Creates a VPC" + } + ], + "diagrams": [ + { + "diagram": { + "caption": "VPC for IBM Cloud.", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/reference-architecture/deployable-architecture-vpc.svg", + "type": "image/svg+xml" + }, + "description": "This architecture creates a VPC." + } + ] + }, + "configuration": [ + { + "key": "ibmcloud_api_key" + }, + { + "key": "prefix", + "required": true, + "description": "The prefix to add to all resources that this solution creates. To not use any prefix value, you can enter the string `__NULL__`." + }, + { + "key": "region" + }, + { + "key": "existing_resource_group_name", + "required": true, + "custom_config": { + "type": "resource_group", + "grouping": "deployment", + "original_grouping": "deployment", + "config_constraints": { + "identifier": "rg_name" + } + } + }, + { + "key": "provider_visibility", + "options": [ + { + "displayname": "private", + "value": "private" + }, + { + "displayname": "public", + "value": "public" + }, + { + "displayname": "public-and-private", + "value": "public-and-private" + } + ] + }, + { + "key": "vpc_name" + }, + { + "key": "subnets" + }, + { + "key": "network_acls" + }, + { + "key": "clean_default_security_group_acl", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "address_prefixes" + }, + { + "key": "routes" + }, + { + "key": "default_network_acl_name" + }, + { + "key": "security_group_rules" + }, + { + "key": "default_security_group_name" + }, + { + "key": "default_routing_table_name" + }, + { + "key": "security_group_ids" + }, + { + "key": "vpe_service_endpoints", + "options": [ + { + "displayname": "Public", + "value": "public" + }, + { + "displayname": "Private", + "value": "private" + } + ] + }, + { + "key": "vpn_gateways" + }, + { + "key": "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": "enable_vpc_flow_logs", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "skip_vpc_cos_iam_auth_policy", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "existing_cos_instance_crn" + }, + { + "key": "flow_logs_cos_bucket_name" + }, + { + "key": "kms_encryption_enabled_bucket", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "skip_cos_kms_iam_auth_policy", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "management_endpoint_type_for_bucket", + "options": [ + { + "displayname": "Public", + "value": "public" + }, + { + "displayname": "Private", + "value": "private" + }, + { + "displayname": "Direct", + "value": "direct" + } + ] + }, + { + "key": "cos_bucket_class", + "options": [ + { + "displayname": "Standard", + "value": "standard" + }, + { + "displayname": "Vault", + "value": "vault" + }, + { + "displayname": "Cold", + "value": "cold" + }, + { + "displayname": "Smart", + "value": "smart" + }, + { + "displayname": "OneRate Active", + "value": "onerate_active" + } + ] + }, + { + "key": "force_delete", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "add_bucket_name_suffix", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "flow_logs_cos_bucket_archive_days" + }, + { + "key": "flow_logs_cos_bucket_archive_type" + }, + { + "key": "flow_logs_cos_bucket_expire_days" + }, + { + "key": "flow_logs_cos_bucket_enable_object_versioning", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "flow_logs_cos_bucket_enable_retention", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "flow_logs_cos_bucket_default_retention_days" + }, + { + "key": "flow_logs_cos_bucket_maximum_retention_days" + }, + { + "key": "flow_logs_cos_bucket_minimum_retention_days" + }, + { + "key": "flow_logs_cos_bucket_enable_permanent_retention", + "options": [ + { + "displayname": "True", + "value": "true" + }, + { + "displayname": "False", + "value": "false" + } + ] + }, + { + "key": "existing_flow_logs_bucket_kms_key_crn" + }, + { + "key": "existing_kms_instance_crn" + }, + { + "key": "kms_endpoint_type", + "options": [ + { + "displayname": "private", + "value": "private" + }, + { + "displayname": "public", + "value": "public" + } + ] + }, + { + "key": "kms_key_ring_name" + }, + { + "key": "kms_key_name" + }, + { + "key": "cloud_services" + }, + { + "key": "cloud_service_by_crn" + } + ], + "dependencies": [ + { + "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_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": "region", + "version_input": "region", + "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 + } + ] + } + ], + "dependency_version_2": true + } + ] + } + ] +} diff --git a/images/vpc_icon.svg b/images/vpc_icon.svg new file mode 100644 index 00000000..6f06ea97 --- /dev/null +++ b/images/vpc_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/reference-architecture/deployable-architecture-vpc.svg b/reference-architecture/deployable-architecture-vpc.svg new file mode 100644 index 00000000..4de4ed1c --- /dev/null +++ b/reference-architecture/deployable-architecture-vpc.svg @@ -0,0 +1,4 @@ + + + +
ACL
locked
IBM Cloud
Region
Resource Group
Existing KMS
Key Ring
Root Key
Flow logs Bucket
Cloud Object Storage Instance
VPC
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 1
VPN Gateway (Optional)
ACL
locked
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
\ No newline at end of file From b58a2d468c48e319be4f98f342aa4d9a758246a4 Mon Sep 17 00:00:00 2001 From: "aashiq.jacob@ibm.com" Date: Tue, 18 Mar 2025 09:25:06 +0530 Subject: [PATCH 17/46] add private path output --- solutions/fully-configurable/main.tf | 2 +- solutions/fully-configurable/outputs.tf | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index d0f0c1ae..e2c9f4c5 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -1,5 +1,5 @@ locals { - prefix = (var.prefix != null && trimspace(var.prefix) != "" ? var.prefix : "") + prefix = var.prefix != null ? trimspace(var.prefix) != "" ? var.prefix : "" : "" } ############################################################################## diff --git a/solutions/fully-configurable/outputs.tf b/solutions/fully-configurable/outputs.tf index 9ebd3d6c..0a8cfef0 100644 --- a/solutions/fully-configurable/outputs.tf +++ b/solutions/fully-configurable/outputs.tf @@ -53,6 +53,11 @@ output "subnet_ids" { value = module.vpc.subnet_ids } +output "private_path_subnet_id" { + description = "The IDs of the subnets" + value = length(module.vpc.subnet_ids) > 0 ? module.vpc.subnet_ids[0] : null +} + output "subnet_detail_list" { description = "A list of subnets containing names, CIDR blocks, and zones." value = module.vpc.subnet_detail_list From d3a99a04b3762f0ee9f6174b0a523206401bedf1 Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Tue, 18 Mar 2025 12:40:17 +0530 Subject: [PATCH 18/46] update ibm_catalog --- ibm_catalog.json | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 80b3e05d..de1a8a05 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -22,7 +22,7 @@ "short_description": "Provisions a VPC network on IBM Cloud", "long_description": "The VPC landing zone deployable architecture deploys a simple Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters.", "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/README.md", - "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/images/vpc_icon.svg", + "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/vpc-da-12217/images/vpc_icon.svg", "provider_name": "IBM", "features": [ { @@ -48,13 +48,41 @@ { "diagram": { "caption": "VPC for IBM Cloud.", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/reference-architecture/deployable-architecture-vpc.svg", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/vpc-da-12217/reference-architecture/deployable-architecture-vpc.svg", "type": "image/svg+xml" }, "description": "This architecture creates a VPC." } ] }, + "iam_permissions": [ + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Administrator" + ], + "service_name": "iam-identity" + }, + { + "role_crns": [ + "crn:v1:bluemix:public:iam::::role:Administrator" + ], + "service_name": "is.vpc" + }, + { + "service_name": "cloud-object-storage", + "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" + ] + } + ], "configuration": [ { "key": "ibmcloud_api_key" @@ -447,6 +475,10 @@ "dependency_input": "use_existing_resource_group", "value": true, "reference_version": true + }, + { + "version_input":"kms_encryption_enabled_bucket", + "value":true } ] }, @@ -478,6 +510,10 @@ "dependency_input": "use_existing_resource_group", "value": true, "reference_version": true + }, + { + "version_input":"enable_vpc_flow_logs", + "value":true } ] } From eb53ebd7089ad4b3653ca6255bb307b327ab66db Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Tue, 18 Mar 2025 16:52:50 +0530 Subject: [PATCH 19/46] update code and SKIP UPGRADE TEST --- ibm_catalog.json | 72 +++++++++++++++++++++-- solutions/fully-configurable/variables.tf | 4 +- 2 files changed, 70 insertions(+), 6 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index de1a8a05..15f35193 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -20,14 +20,46 @@ "solution" ], "short_description": "Provisions a VPC network on IBM Cloud", - "long_description": "The VPC landing zone deployable architecture deploys a simple Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters.", + "long_description": "The VPC deployable architecture deploys a Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters.", "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/README.md", "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/vpc-da-12217/images/vpc_icon.svg", "provider_name": "IBM", "features": [ { - "title": "Create a VPC on IBM Cloud", + "title": "VPC on IBM Cloud", "description": "Create a VPC on IBM Cloud." + }, + { + "title": "Public gateways", + "description": "Create and configure public gateways." + }, + { + "title": "Subnets", + "description": "Creates subnets for VPC." + }, + { + "title": "Network ACLs", + "description": "Create network ACLs." + }, + { + "title": "VPN gateways", + "description": "Create and configure VPN gateways." + }, + { + "title": "VPE gateways", + "description": "Create and configure VPE gateways." + }, + { + "title": "Security groups", + "description": "Create and configure security group rules." + }, + { + "title": "VPC flow logs", + "description": "VPC flow logs can be enabled." + }, + { + "title": "Address Prefixes", + "description": "Creates address prefixes." } ], "flavors": [ @@ -40,8 +72,40 @@ "descriptions": "This architecture creates a VPC.", "features": [ { - "title": "Creates a VPC", - "description": "Creates a VPC" + "title": "VPC on IBM Cloud", + "description": "Create a VPC on IBM Cloud." + }, + { + "title": "Public gateways", + "description": "Create and configure public gateways." + }, + { + "title": "Subnets", + "description": "Creates subnets for VPC." + }, + { + "title": "Network ACLs", + "description": "Create network ACLs." + }, + { + "title": "VPN gateways", + "description": "Create and configure VPN gateways." + }, + { + "title": "VPE gateways", + "description": "Create and configure VPE gateways." + }, + { + "title": "Security groups", + "description": "Create and configure security group rules." + }, + { + "title": "VPC flow logs", + "description": "VPC flow logs can be enabled." + }, + { + "title": "Address Prefixes", + "description": "Creates address prefixes." } ], "diagrams": [ diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 767df493..eaa9281b 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -498,7 +498,7 @@ variable "add_bucket_name_suffix" { variable "flow_logs_cos_bucket_archive_days" { description = "The number of days before the `archive_type` rule action takes effect for the flow logs cloud object storage bucket." type = number - default = null + default = 20 } variable "flow_logs_cos_bucket_archive_type" { @@ -510,7 +510,7 @@ variable "flow_logs_cos_bucket_archive_type" { variable "flow_logs_cos_bucket_expire_days" { description = "The number of days before the expire rule action takes effect for the flow logs cloud object storage bucket." type = number - default = null + default = 365 } variable "flow_logs_cos_bucket_enable_object_versioning" { From 3fec4e095dd1f87bda8e45827938179a2dbef31d Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Wed, 19 Mar 2025 13:49:42 +0530 Subject: [PATCH 20/46] update code to support prefix as empty string and address review comments --- ibm_catalog.json | 27 ++++++----------------- solutions/fully-configurable/main.tf | 12 +++++----- solutions/fully-configurable/variables.tf | 14 ++++-------- solutions/fully-configurable/version.tf | 2 +- 4 files changed, 18 insertions(+), 37 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 15f35193..59f543fe 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -232,7 +232,7 @@ "key": "security_group_ids" }, { - "key": "vpe_service_endpoints", + "key": "vpe_gateway_service_endpoints", "options": [ { "displayname": "Public", @@ -244,6 +244,12 @@ } ] }, + { + "key": "vpe_gateway_cloud_services" + }, + { + "key": "vpe_gateway_cloud_service_by_crn" + }, { "key": "vpn_gateways" }, @@ -369,19 +375,6 @@ } ] }, - { - "key": "force_delete", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] - }, { "key": "add_bucket_name_suffix", "options": [ @@ -476,12 +469,6 @@ }, { "key": "kms_key_name" - }, - { - "key": "cloud_services" - }, - { - "key": "cloud_service_by_crn" } ], "dependencies": [ diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index e2c9f4c5..fb8d761b 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -1,5 +1,5 @@ locals { - prefix = var.prefix != null ? trimspace(var.prefix) != "" ? var.prefix : "" : "" + prefix = var.prefix != null ? (trimspace(var.prefix) != "" ? "${var.prefix}-" : "") : "" } ############################################################################## @@ -45,7 +45,7 @@ locals { storage_class = var.cos_bucket_class resource_instance_id = var.existing_cos_instance_crn region_location = var.region - force_delete = var.force_delete + force_delete = true archive_rule = var.flow_logs_cos_bucket_archive_days != null ? { enable = true days = var.flow_logs_cos_bucket_archive_days @@ -185,7 +185,7 @@ module "vpc" { region = var.region create_vpc = true name = var.vpc_name - prefix = local.prefix + prefix = local.prefix != "" ? trimspace(var.prefix) : null tags = var.resource_tags access_tags = var.access_tags subnets = var.subnets @@ -220,7 +220,7 @@ module "vpe_gateway" { vpc_name = module.vpc.vpc_name vpc_id = module.vpc.vpc_id subnet_zone_list = module.vpc.subnet_zone_list - cloud_services = var.cloud_services - cloud_service_by_crn = var.cloud_service_by_crn - service_endpoints = var.vpe_service_endpoints + cloud_services = var.vpe_gateway_cloud_services + cloud_service_by_crn = var.vpe_gateway_cloud_service_by_crn + service_endpoints = var.vpe_gateway_service_endpoints } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index eaa9281b..972c0e82 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -483,12 +483,6 @@ variable "cos_bucket_class" { } } -variable "force_delete" { - type = bool - description = "Whether to delete all the objects in the flow logs Cloud Object Storage bucket before the bucket is deleted." - default = true -} - variable "add_bucket_name_suffix" { type = bool description = "Add a randomly generated suffix that is 4 characters in length, to the name of the newly provisioned Cloud Object Storage bucket. Do not use this suffix if you are passing the existing Cloud Object Storage bucket. To manage the name of the Cloud Object Storage bucket manually, use the `flow_logs_cos_bucket_name` variables." @@ -638,7 +632,7 @@ variable "vpn_gateways" { # VPE Gateways ############################################################################## -variable "cloud_services" { +variable "vpe_gateway_cloud_services" { description = "The list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names are created in the format `--`." type = set(object({ service_name = string @@ -648,7 +642,7 @@ variable "cloud_services" { default = [] } -variable "cloud_service_by_crn" { +variable "vpe_gateway_cloud_service_by_crn" { description = "The list of cloud service CRNs used to create endpoint gateways. Use this list to identify services that are not supported by service name in the `cloud_services` variable. For a list of supported services, see [VPE-enabled services](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). If `service_name` is not specified, the CRN is used to find the name. If `vpe_name` is not specified in the list, VPE names are created in the format `--`." type = set( object({ @@ -661,14 +655,14 @@ variable "cloud_service_by_crn" { default = [] } -variable "vpe_service_endpoints" { +variable "vpe_gateway_service_endpoints" { description = "Service endpoints to use to create endpoint gateways. Can be `public`, or `private`." type = string default = "private" validation { error_message = "Service endpoints can only be `public` or `private`." - condition = contains(["public", "private"], var.vpe_service_endpoints) + condition = contains(["public", "private"], var.vpe_gateway_service_endpoints) } } diff --git a/solutions/fully-configurable/version.tf b/solutions/fully-configurable/version.tf index a6c8e06e..f1c29e5a 100644 --- a/solutions/fully-configurable/version.tf +++ b/solutions/fully-configurable/version.tf @@ -4,7 +4,7 @@ terraform { # Lock DA into an exact provider version - renovate automation will keep it updated ibm = { source = "IBM-Cloud/ibm" - version = "1.75.2" + version = "1.76.1" } } } From 00cb77642d003a6d9f27ad438c8434e5e8a5f2ae Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Wed, 19 Mar 2025 20:42:26 +0530 Subject: [PATCH 21/46] add subnet_tags and schematics test --- README.md | 2 +- solutions/fully-configurable/variables.tf | 3 + tests/pr_test.go | 73 +++++++++++++++++++---- variables.tf | 3 + 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 4a851a33..509255db 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,7 @@ To attach access management tags to resources in this module, you need the follo | [security\_group\_rules](#input\_security\_group\_rules) | A list of security group rules to be added to the default vpc security group (default empty) |
list(
object({
name = string
direction = string
remote = string
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
| `[]` | no | | [skip\_custom\_resolver\_hub\_creation](#input\_skip\_custom\_resolver\_hub\_creation) | Indicates whether to skip the configuration of a custom resolver in the hub VPC. Only relevant if enable\_hub is set to true. | `bool` | `false` | no | | [skip\_spoke\_auth\_policy](#input\_skip\_spoke\_auth\_policy) | Set to true to skip the creation of an authorization policy between the DNS resolution spoke and hub, only enable this if a policy already exists between these two VPCs. See https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-dns-sharing-s2s-auth&interface=ui for more details. | `bool` | `false` | no | -| [subnets](#input\_subnets) | List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created |
object({
zone-1 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
}))
zone-2 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
})))
zone-3 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
})))
})
|
{
"zone-1": [
{
"acl_name": "vpc-acl",
"cidr": "10.10.10.0/24",
"name": "subnet-a",
"no_addr_prefix": false,
"public_gateway": true
}
],
"zone-2": [
{
"acl_name": "vpc-acl",
"cidr": "10.20.10.0/24",
"name": "subnet-b",
"no_addr_prefix": false,
"public_gateway": true
}
],
"zone-3": [
{
"acl_name": "vpc-acl",
"cidr": "10.30.10.0/24",
"name": "subnet-c",
"no_addr_prefix": false,
"public_gateway": false
}
]
}
| no | +| [subnets](#input\_subnets) | List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created |
object({
zone-1 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
}))
zone-2 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
zone-3 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
})
|
{
"zone-1": [
{
"acl_name": "vpc-acl",
"cidr": "10.10.10.0/24",
"name": "subnet-a",
"no_addr_prefix": false,
"public_gateway": true
}
],
"zone-2": [
{
"acl_name": "vpc-acl",
"cidr": "10.20.10.0/24",
"name": "subnet-b",
"no_addr_prefix": false,
"public_gateway": true
}
],
"zone-3": [
{
"acl_name": "vpc-acl",
"cidr": "10.30.10.0/24",
"name": "subnet-c",
"no_addr_prefix": false,
"public_gateway": false
}
]
}
| no | | [tags](#input\_tags) | List of Tags for the resource created | `list(string)` | `null` | no | | [update\_delegated\_resolver](#input\_update\_delegated\_resolver) | If set to true, and if the vpc is configured to be a spoke for DNS resolution (enable\_hub\_vpc\_crn or enable\_hub\_vpc\_id set), then the spoke VPC resolver will be updated to a delegated resolver. | `bool` | `false` | no | | [use\_existing\_dns\_instance](#input\_use\_existing\_dns\_instance) | Whether to use an existing dns instance. If true, existing\_dns\_instance\_id must be set. | `bool` | `false` | no | diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 972c0e82..c690e77a 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -84,6 +84,7 @@ variable "subnets" { public_gateway = optional(bool) acl_name = string no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + subnet_tags = optional(list(string), []) })) zone-2 = optional(list(object({ name = string @@ -91,6 +92,7 @@ variable "subnets" { public_gateway = optional(bool) acl_name = string no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + subnet_tags = optional(list(string), []) }))) zone-3 = optional(list(object({ name = string @@ -98,6 +100,7 @@ variable "subnets" { public_gateway = optional(bool) acl_name = string no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + subnet_tags = optional(list(string), []) }))) }) diff --git a/tests/pr_test.go b/tests/pr_test.go index 6e5780d1..256017f0 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -16,6 +16,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/common" "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testhelper" + "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testschematic" ) const basicExampleTerraformDir = "examples/basic" @@ -216,31 +217,77 @@ func TestFullyConfigurable(t *testing.T) { // Programmatically determine region to use based on availability region, _ := testhelper.GetBestVpcRegion(val, "../common-dev-assets/common-go-assets/cloudinfo-region-vpc-gen2-prefs.yaml", "eu-de") - options := testhelper.TestOptionsDefault(&testhelper.TestOptions{ - Testing: t, - TerraformDir: fullyConfigFlavorDir, + prefix := "vpc-da" + + options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ + Testing: t, + Region: region, + Prefix: prefix, + TarIncludePatterns: []string{ + "*.tf", + "dynamic_values/*.tf", + "dynamic_values/config_modules/*/*.tf", + fullyConfigFlavorDir + "/*.tf", + }, + TemplateFolder: fullyConfigFlavorDir, + Tags: []string{"vpc-da-test"}, + DeleteWorkspaceOnFail: false, + WaitJobCompleteMinutes: 60, }) - options.TerraformVars = map[string]interface{}{ - "provider_visibility": "public", - "existing_resource_group_name": resourceGroup, - "prefix": "fully-config", - "region": region, + options.TerraformVars = []testschematic.TestSchematicTerraformVar{ + {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, + {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, + {Name: "region", Value: options.Region, DataType: "string"}, + {Name: "resource_tags", Value: options.Tags, DataType: "list(string)"}, + {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, + {Name: "prefix", Value: options.Prefix, DataType: "string"}, } - output, err := options.RunTestConsistency() + + err := options.RunSchematicTest() assert.Nil(t, err, "This should not have errored") - assert.NotNil(t, output, "Expected some output") } // Test the upgrade of fully-configurable DA with defaults func TestRunUpgradeFullyConfigurable(t *testing.T) { t.Parallel() - options := setupOptions(t, "fully-config-upg", fullyConfigFlavorDir) + // Verify ibmcloud_api_key variable is set + checkVariable := "TF_VAR_ibmcloud_api_key" + val, present := os.LookupEnv(checkVariable) + require.True(t, present, checkVariable+" environment variable not set") + require.NotEqual(t, "", val, checkVariable+" environment variable is empty") - output, err := options.RunTestUpgrade() + // Programmatically determine region to use based on availability + region, _ := testhelper.GetBestVpcRegion(val, "../common-dev-assets/common-go-assets/cloudinfo-region-vpc-gen2-prefs.yaml", "eu-de") + + prefix := "vpc-da" + + options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ + Testing: t, + Region: region, + Prefix: prefix, + TarIncludePatterns: []string{ + "*.tf", + fullyConfigFlavorDir + "/*.tf", + }, + TemplateFolder: fullyConfigFlavorDir, + Tags: []string{"vpc-da-test"}, + DeleteWorkspaceOnFail: false, + WaitJobCompleteMinutes: 60, + }) + + options.TerraformVars = []testschematic.TestSchematicTerraformVar{ + {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, + {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, + {Name: "region", Value: options.Region, DataType: "string"}, + {Name: "resource_tags", Value: options.Tags, DataType: "list(string)"}, + {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, + {Name: "prefix", Value: options.Prefix, DataType: "string"}, + } + + err := options.RunSchematicUpgradeTest() if !options.UpgradeTestSkipped { assert.Nil(t, err, "This should not have errored") - assert.NotNil(t, output, "Expected some output") } } diff --git a/variables.tf b/variables.tf index c68b4a3d..bb0e05d8 100644 --- a/variables.tf +++ b/variables.tf @@ -319,6 +319,7 @@ variable "subnets" { public_gateway = optional(bool) acl_name = string no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + subnet_tags = optional(list(string), []) })) zone-2 = optional(list(object({ name = string @@ -326,6 +327,7 @@ variable "subnets" { public_gateway = optional(bool) acl_name = string no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + subnet_tags = optional(list(string), []) }))) zone-3 = optional(list(object({ name = string @@ -333,6 +335,7 @@ variable "subnets" { public_gateway = optional(bool) acl_name = string no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true + subnet_tags = optional(list(string), []) }))) }) From 13aca54f7921d5c928533099c97ffd4e7a2bea4a Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Wed, 19 Mar 2025 20:54:55 +0530 Subject: [PATCH 22/46] update vpn_gateway code --- README.md | 1 - main.tf | 2 +- solutions/fully-configurable/main.tf | 1 - variables.tf | 7 +------ 4 files changed, 2 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 509255db..675c26aa 100644 --- a/README.md +++ b/README.md @@ -204,7 +204,6 @@ To attach access management tags to resources in this module, you need the follo | [enable\_hub\_vpc\_crn](#input\_enable\_hub\_vpc\_crn) | Indicates whether Hub VPC CRN is passed. | `bool` | `false` | no | | [enable\_hub\_vpc\_id](#input\_enable\_hub\_vpc\_id) | Indicates whether Hub VPC ID is passed. | `bool` | `false` | no | | [enable\_vpc\_flow\_logs](#input\_enable\_vpc\_flow\_logs) | Flag to enable vpc flow logs. If true, flow log collector will be created | `bool` | `false` | no | -| [enable\_vpn\_gateways](#input\_enable\_vpn\_gateways) | Set to true to add VPN gateways. If true, VPN gateways will be created using the variable 'vpn\_gateways'. | `bool` | `false` | no | | [existing\_cos\_instance\_guid](#input\_existing\_cos\_instance\_guid) | GUID of the COS instance to create Flow log collector | `string` | `null` | no | | [existing\_dns\_instance\_id](#input\_existing\_dns\_instance\_id) | Id of an existing dns instance in which the custom resolver is created. Only relevant if enable\_hub is set to true. | `string` | `null` | no | | [existing\_storage\_bucket\_name](#input\_existing\_storage\_bucket\_name) | Name of the COS bucket to collect VPC flow logs | `string` | `null` | no | diff --git a/main.tf b/main.tf index cc9c3c65..03561689 100644 --- a/main.tf +++ b/main.tf @@ -414,7 +414,7 @@ locals { locals { # Convert the vpn_gateway input from list to a map - vpn_gateway_map = !var.enable_vpn_gateways ? {} : { for gateway in var.vpn_gateways : gateway.name => gateway } + vpn_gateway_map = { for gateway in var.vpn_gateways : gateway.name => gateway } } resource "ibm_is_vpn_gateway" "vpn_gateway" { diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index fb8d761b..1cfafa3e 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -202,7 +202,6 @@ module "vpc" { create_authorization_policy_vpc_to_cos = !var.skip_vpc_cos_iam_auth_policy existing_cos_instance_guid = var.enable_vpc_flow_logs ? local.cos_instance_guid : null existing_storage_bucket_name = var.enable_vpc_flow_logs ? module.cos_buckets[0].buckets[local.bucket_name].bucket_name : null - enable_vpn_gateways = true vpn_gateways = var.vpn_gateways } diff --git a/variables.tf b/variables.tf index bb0e05d8..716d97db 100644 --- a/variables.tf +++ b/variables.tf @@ -726,14 +726,9 @@ variable "dns_records" { # VPN Gateways ############################################################################## -variable "enable_vpn_gateways" { - type = bool - description = "Set to true to add VPN gateways. If true, VPN gateways will be created using the variable 'vpn_gateways'." - default = false -} - variable "vpn_gateways" { description = "List of VPN gateways to create." + nullable = false type = list( object({ name = string From 3998e0c704582a5a09c3fb156013d2dd4fdd0cc9 Mon Sep 17 00:00:00 2001 From: Aatreyee Mukherjee <83368265+aatreyee2506@users.noreply.github.com> Date: Wed, 19 Mar 2025 21:05:39 +0530 Subject: [PATCH 23/46] DA_doc (#933) Co-authored-by: Aatreyee Mukherjee --- solutions/fully-configurable/DA_docs.md | 136 ++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 solutions/fully-configurable/DA_docs.md diff --git a/solutions/fully-configurable/DA_docs.md b/solutions/fully-configurable/DA_docs.md new file mode 100644 index 00000000..709d7dfe --- /dev/null +++ b/solutions/fully-configurable/DA_docs.md @@ -0,0 +1,136 @@ +# Configuring complex inputs for VPC in IBM Cloud projects +Several optional input variables in the IBM Cloud [VPC deployable architecture](https://cloud.ibm.com/catalog#deployable_architecture) use complex object types. You can specify these inputs when you configure your deployable architecture. + +- [Subnets](#options-with-subnets) (`subnets`) +- [Network Acls](#options-with-network-acls) (`network_acls`) +- [Address Prefixes](#options-with-address-prefixes) (`address_prefixes`) +- [Routes](#options-with-routes) (`routes`) +- [Vpn Gateways](#options-with-vpn-gateways) (`vpn_gateways`) +- [Cloud Services](#options-with-cloud-services) (`cloud_services`) +- [Cloud Service by crn](#options-with-cloud-service-by-crn) (`cloud_service_by_crn`) + +## Options with subnets + +This variable configuration allows you to specify the subnets for the VPC. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total IPv4 addresses. Public gateways will be enabled only in zones where a gateway has been created. + +### Example for subnets + +```hcl +subnets = { + zone-1 = [ + { + name = "subnet-a" + cidr = "10.10.10.0/24" + public_gateway = true + acl_name = "vpc-acl" + no_addr_prefix = false + } + ] +} +``` + +## Options with network_acls + +This variable configuration allows you to specify the list of ACLs to create. Each ACL must have at least one rule defined. + +### Example for network-acls + +```hcl +network_acls = { + default = [ + { + name = "vpc-acl" + add_ibm_cloud_internal_rules = true + add_vpc_connectivity_rules = true + prepend_ibm_rules = true + rules = [ + { + name = "allow-all-443-inbound" + action = "allow" + direction = "inbound" + tcp = { + port_min = 443 + port_max = 443 + source_port_min = 443 + source_port_max = 443 + } + destination = "0.0.0.0/0" + source = "0.0.0.0/0" + } + ] + } + ] +} +``` + +## Options with address_prefixes + +This variable configuration allows you to specify the list of ACLs to create. Each ACL must have at least one rule defined. + +### Example for address-prefixes + +```hcl +address_prefixes = { + default = { + zone-1 = null + zone-2 = null + zone-3 = null + } +} +``` + +## Options with routes + +This variable configuration allows you to specify the next hop for packets based on their destination address. + +### Example for routes + +```hcl +routes = { + name = "test-route" + routes = [ + { + zone = 1 + destination = "10.2.14.1/32" + next_hop = "1.1.1.1" + } + ] +} +``` + +## Options with vpn_gateways + +This variable configuration allows you to specify the list of VPN Gateways to create. + +### Example for vpn_gateways + +```hcl +vpn_gateways = { + + +} +``` + +## Options with cloud_services + +This variable configuration allows you to specify the list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names will be generated in the format `--`. + +### Example for cloud_services + +```hcl +cloud_services = { + +} +``` + +## Options with cloud_services + +This variable defines cloud service CRNs for endpoint gateways, used when `cloud_services` lacks support. If `service_name` is absent, the CRN sets the name. Missing `vpe_name` results in names like `--`. + +### Example for cloud_service-by-crn + +```hcl +cloud_service_by_crn = { + +} +``` \ No newline at end of file From d5fcd0d9835440648a13420ef0f4c9cebb17a356 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Thu, 20 Mar 2025 16:53:43 +0530 Subject: [PATCH 24/46] add DA-docs --- solutions/fully-configurable/DA_docs.md | 269 +++++++++++++++++++----- 1 file changed, 214 insertions(+), 55 deletions(-) diff --git a/solutions/fully-configurable/DA_docs.md b/solutions/fully-configurable/DA_docs.md index 709d7dfe..eeabfc87 100644 --- a/solutions/fully-configurable/DA_docs.md +++ b/solutions/fully-configurable/DA_docs.md @@ -1,43 +1,98 @@ -# Configuring complex inputs for VPC in IBM Cloud projects -Several optional input variables in the IBM Cloud [VPC deployable architecture](https://cloud.ibm.com/catalog#deployable_architecture) use complex object types. You can specify these inputs when you configure your deployable architecture. +# Configuring complex inputs for VPC -- [Subnets](#options-with-subnets) (`subnets`) -- [Network Acls](#options-with-network-acls) (`network_acls`) -- [Address Prefixes](#options-with-address-prefixes) (`address_prefixes`) -- [Routes](#options-with-routes) (`routes`) -- [Vpn Gateways](#options-with-vpn-gateways) (`vpn_gateways`) -- [Cloud Services](#options-with-cloud-services) (`cloud_services`) -- [Cloud Service by crn](#options-with-cloud-service-by-crn) (`cloud_service_by_crn`) +Several input variables in the **Cloud automation of VPC** [deployable architecture](https://cloud.ibm.com/catalog#deployable_architecture) use complex object types. You can specify these inputs when you configure your deployable architecture. -## Options with subnets +- [Subnets](#subnets) (`subnets`) +- [Network ACLs](#network-acls) (`network_acls`) +- [Security Group Rules](#security-group-rules)(`security_group_rules`) +- [Address Prefixes](#address-prefixes) (`address_prefixes`) +- [Routes](#routes) (`routes`) +- [VPN Gateways](#vpn-gateways) (`vpn_gateways`) +- [VPE Gateways Cloud Services](#cloud-services) (`vpe_gateway_cloud_services`) +- [VPE Gateways Cloud Service by CRN](#cloud-service-by-crn) (`vpe_gateway_cloud_service_by_crn`) + +## Subnets This variable configuration allows you to specify the subnets for the VPC. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total IPv4 addresses. Public gateways will be enabled only in zones where a gateway has been created. -### Example for subnets +- Variable name: `subnets`. +- Type: A object containing three zones. Each zone is a list of object. +- Default value: Subnet for `zone-1`. + +### Options for subnets + +For each zone, you can define the follwoing: + + - `name` (required): The name of subnet + - `cidr` (required): The cidr to define for the subnet + - `public_gateway` (optional): (bool) Set to true if need to create public gateway for the zone + - `acl_name` (required): The name of ACL created + - `no_addr_prefix` (optional): (bool) Default is `false`, it does not add address prefix for subnet + - `subnet_tags` (optional): (list) To specify tags for subnet specifically + +### Example ```hcl -subnets = { + subnets = { zone-1 = [ { name = "subnet-a" cidr = "10.10.10.0/24" public_gateway = true - acl_name = "vpc-acl" + acl_name = "vpc-acl-a" no_addr_prefix = false + subnet_tags = ["public"] } ] -} + zone-2 = [ + { + name = "subnet-b" + cidr = "10.10.20.0/24" + public_gateway = true + acl_name = "vpc-acl-b" + no_addr_prefix = false + } + ] + } ``` -## Options with network_acls +## Network ACLs This variable configuration allows you to specify the list of ACLs to create. Each ACL must have at least one rule defined. -### Example for network-acls +- Variable name: `network_acls`. +- Type: A list of object. + +### Options for Network ACLs + + - `name` (required): The name of network ACL. + - `add_ibm_cloud_internal_rules` (optional): (bool) Set to true to include pre-defined rules defined [here](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/network_acls.tf#L50). + - `add_vpc_connectivity_rules` (optional): (bool) Set to true to include pre-defined VPC connectivity rules defined [here](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/network_acls.tf#L102). + - `prepend_ibm_rules` (optional): (bool) Set to true to prepend pre-defined rules defined [here](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/network_acls.tf#L132). + - `rules` (required): (list of objects) + - `name`: Name of the rule. + - `action`: Allowed values are `allow` or `deny`. + - `direction`: Allowed values are `inbound` or `outbound`. + - `destination`: Destination address. + - `source`: Source address. + - `tcp` (optional): + - `port_min` + - `port_max` + - `source_port_min` + - `source_port_max` + - `udp` (optional): + - `port_min` + - `port_max` + - `source_port_min` + - `source_port_max` + - `icmp` (optional): + - `type` + - `code` + +### Example ```hcl -network_acls = { - default = [ + network_acls = [ { name = "vpc-acl" add_ibm_cloud_internal_rules = true @@ -60,77 +115,181 @@ network_acls = { ] } ] -} ``` -## Options with address_prefixes +## Security Group Rules -This variable configuration allows you to specify the list of ACLs to create. Each ACL must have at least one rule defined. +This variable configuration allows you to specify the list of security group rules to be added to the default VPC security group. You can create a different type of protocol rules." + +- Variable name: `security_group_rules`. +- Type: A list of object. +- Default value: An empty list (`[]`). + +### Options for Security Group Rules -### Example for address-prefixes +- `name` (required): The name of the security group rule. +- `direction` (required): The direction of the traffic. Allowed values are `inbound` or `outbound`. +- `remote` (optional): Security group ID or an IP address or a CIDR block. +- `tcp` (optional): + - `port_min` + - `port_max` +- `udp` (optional): + - `port_min` + - `port_max` +- `icmp` (optional): + - `type` + - `code` + + +### Example + +```hcl + security_group_rules = [ + { + name = "security-group-rule-1" + direction = "inbound" + remote = "127.0.0.1" + tcp = { + port_min = 8080 + port_max = 8080 + } + } + ] +``` + +## Address Prefixes + +This variable allows you to specify the IP range for the VPC for a certain location. + +- Variable name: `address_prefixes`. +- Type: A object including three zones. Each zone can have a list of address prefixes. +- Default value: `null` for each zone. + +### Options for Address Prefixes + +- `zone-1` (optional): (list) Address prefixes for zone-1. +- `zone-2` (optional): (list) Address prefixes for zone-2. +- `zone-3` (optional): (list) Address prefixes for zone-3. + +### Example ```hcl address_prefixes = { - default = { - zone-1 = null + zone-1 = ["10.10.10.0/18"] zone-2 = null zone-3 = null - } } ``` -## Options with routes +## Routes + +This variable allows you to add the custom routing tables and then add routes. + +- Variable name: `routes`. +- Type: A list of object. +- Default value: An empty list `[]`. -This variable configuration allows you to specify the next hop for packets based on their destination address. +### Options for Routes -### Example for routes +- `name` (required): The name of the route. +- `route_direct_link_ingress` (optional): (bool) Required if the routing table will be used to route traffic that originates from Direct Link to the VPC. +- `route_transit_gateway_ingress` (optional): (bool) Required if the routing table will be used to route traffic that originates from the internet. +- `route_vpc_zone_ingress` (optional): (bool) Required if the routing table will be used to route traffic that originates from Transit Gateway to the VPC. +- `routes` (optional): (list) + - `action`: The action to perform with a packet. Allowed values are `delegate`, `delegate_vpc`, `deliver`, `drop`. + - `zone`: Number of the zone. + - `destination`: The destination of the route. + - `next_hop`: The next hop of the route. For action other than deliver, you must specify `0.0.0.0`. + +### Example ```hcl -routes = { - name = "test-route" - routes = [ - { - zone = 1 - destination = "10.2.14.1/32" - next_hop = "1.1.1.1" - } - ] -} + routes = { + name = "route-1" + route_direct_link_ingress = false + route_transit_gateway_ingress = false + route_vpc_zone_ingress = true + routes = [ + { + zone = 1 + destination = "10.10.10.0/24" + next_hop = "10.10.0.4" + action = "deliver" + } + ] + } ``` -## Options with vpn_gateways +## VPN Gateways + +This variable allows you to specify the list of VPN Gateways to create. + +- Variable name: `vpn_gateways`. +- Type: A list of object. +- Default value: An empty list `[]`. + +### Options for VPN Gateways -This variable configuration allows you to specify the list of VPN Gateways to create. +- `name` (required): Name of the VPN gateway. +- `vpc_name` (required): Name of the VPC. +- `subnet_name` (required): Name of the subnet to attach a VPN gateway. +- `mode` (optional): Mode in VPN gateway. Allowed values are `route` and `policy`. +- `resource_group` (optional): The resource group where the VPN gateway to be created. +- `access_tags` (optional): (list) A list of tags to add to your VPN gateway. -### Example for vpn_gateways +### Example ```hcl vpn_gateways = { - - + name = "vpn-gateway-1" + subnet_name = "subnet-a" + mode = "route" } ``` -## Options with cloud_services +## VPE Gateway Cloud Services + +This variable configuration allows you to specify the list of cloud services used to create endpoint gateways. + +- Variable name: `vpe_gateway_cloud_services`. +- Type: A list of object. +- Default value: An empty list `[]`. -This variable configuration allows you to specify the list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names will be generated in the format `--`. +### Options for VPE Gateway Cloud Services -### Example for cloud_services +- `service_name` (required): The name of the Cloud service. +- `vpe_name` (optional): The name of the VPE gateway. If it is not specified, VPE name will be automatically generated in the format `--`. +- `allow_dns_resolution_binding` (optional): (bool) Set to `true` to allow this endpoint gateway to participate in DNS resolution bindings with a VPC. + +### Example ```hcl -cloud_services = { - -} + vpe_gateway_cloud_services = { + service_name = "cloud-object-storage" + vpe_name = "vpe1" + } ``` -## Options with cloud_services +## VPE Gateway Cloud Service by CRN + +This variable defines cloud service CRNs required to create endpoint gateways. This list is used to identify services that are not supported by service name in the `cloud_services` variable. For a list of supported services, see [VPE-enabled services](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). -This variable defines cloud service CRNs for endpoint gateways, used when `cloud_services` lacks support. If `service_name` is absent, the CRN sets the name. Missing `vpe_name` results in names like `--`. +- Variable name: `vpe_gateway_cloud_service_by_crn`. +- Type: A list of object. +- Default value: An empty list `[]`. -### Example for cloud_service-by-crn +### Options for VPE Gateway Cloud Services by CRN + +- `crn` (required): The CRN of the Cloud service. +- `vpe_name` (optional): The name of the VPE gateway. If it is not specified, VPE name will be automatically generated in the format `--`. +- `service_name` (optional): The name of the service. Required to compute the name of VPE. If not specified, the service name will be obtained from the crn. +- `allow_dns_resolution_binding` (optional): (bool) Set to `true` to allow this endpoint gateway to participate in DNS resolution bindings with a VPC. + +### Example ```hcl -cloud_service_by_crn = { - -} + cloud_service_by_crn = { + crn = "crn:v1:bluemix:public:cloud-object-storage:global:::endpoint:s3.direct.mil01.cloud-object-storage.appdomain.cloud" + vpe_name = "vpe2" + } ``` \ No newline at end of file From 4e3b12e0a57d561b96ec4c177129a117ca85cb27 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Thu, 20 Mar 2025 16:58:47 +0530 Subject: [PATCH 25/46] update filename --- solutions/fully-configurable/{DA_docs.md => DA-types.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename solutions/fully-configurable/{DA_docs.md => DA-types.md} (100%) diff --git a/solutions/fully-configurable/DA_docs.md b/solutions/fully-configurable/DA-types.md similarity index 100% rename from solutions/fully-configurable/DA_docs.md rename to solutions/fully-configurable/DA-types.md From d19bef03a165e1526f4675ac7fc03f45af4c6b06 Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Fri, 21 Mar 2025 15:21:52 +0530 Subject: [PATCH 26/46] update reference architecture --- .../deployable-architecture-vpc.svg | 2 +- solutions/fully-configurable/DA-types.md | 54 +++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/reference-architecture/deployable-architecture-vpc.svg b/reference-architecture/deployable-architecture-vpc.svg index 4de4ed1c..c2371c88 100644 --- a/reference-architecture/deployable-architecture-vpc.svg +++ b/reference-architecture/deployable-architecture-vpc.svg @@ -1,4 +1,4 @@ -
ACL
locked
IBM Cloud
Region
Resource Group
Existing KMS
Key Ring
Root Key
Flow logs Bucket
Cloud Object Storage Instance
VPC
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 1
VPN Gateway (Optional)
ACL
locked
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
\ No newline at end of file +
ACL
locked
IBM Cloud
Region
Existing Resource Group
Flow logs Bucket
Existing COS Instance
Existing KMS instance
VPC
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 1
VPN Gateway (Optional)
ACL
locked
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
\ No newline at end of file diff --git a/solutions/fully-configurable/DA-types.md b/solutions/fully-configurable/DA-types.md index eeabfc87..a040bffa 100644 --- a/solutions/fully-configurable/DA-types.md +++ b/solutions/fully-configurable/DA-types.md @@ -1,4 +1,4 @@ -# Configuring complex inputs for VPC +# Configuring complex inputs for VPC Several input variables in the **Cloud automation of VPC** [deployable architecture](https://cloud.ibm.com/catalog#deployable_architecture) use complex object types. You can specify these inputs when you configure your deployable architecture. @@ -25,9 +25,9 @@ For each zone, you can define the follwoing: - `name` (required): The name of subnet - `cidr` (required): The cidr to define for the subnet - - `public_gateway` (optional): (bool) Set to true if need to create public gateway for the zone + - `public_gateway` (optional): (bool) Set to true if need to create public gateway for the zone - `acl_name` (required): The name of ACL created - - `no_addr_prefix` (optional): (bool) Default is `false`, it does not add address prefix for subnet + - `no_addr_prefix` (optional): (bool) Default is `false`, it does not add address prefix for subnet - `subnet_tags` (optional): (list) To specify tags for subnet specifically ### Example @@ -75,18 +75,18 @@ This variable configuration allows you to specify the list of ACLs to create. Ea - `direction`: Allowed values are `inbound` or `outbound`. - `destination`: Destination address. - `source`: Source address. - - `tcp` (optional): - - `port_min` - - `port_max` - - `source_port_min` - - `source_port_max` - - `udp` (optional): - - `port_min` - - `port_max` - - `source_port_min` - - `source_port_max` - - `icmp` (optional): - - `type` + - `tcp` (optional): + - `port_min` + - `port_max` + - `source_port_min` + - `source_port_max` + - `udp` (optional): + - `port_min` + - `port_max` + - `source_port_min` + - `source_port_max` + - `icmp` (optional): + - `type` - `code` ### Example @@ -130,14 +130,14 @@ This variable configuration allows you to specify the list of security group rul - `name` (required): The name of the security group rule. - `direction` (required): The direction of the traffic. Allowed values are `inbound` or `outbound`. - `remote` (optional): Security group ID or an IP address or a CIDR block. -- `tcp` (optional): - - `port_min` - - `port_max` -- `udp` (optional): - - `port_min` - - `port_max` -- `icmp` (optional): - - `type` +- `tcp` (optional): + - `port_min` + - `port_max` +- `udp` (optional): + - `port_min` + - `port_max` +- `icmp` (optional): + - `type` - `code` @@ -193,7 +193,7 @@ This variable allows you to add the custom routing tables and then add routes. - `name` (required): The name of the route. - `route_direct_link_ingress` (optional): (bool) Required if the routing table will be used to route traffic that originates from Direct Link to the VPC. -- `route_transit_gateway_ingress` (optional): (bool) Required if the routing table will be used to route traffic that originates from the internet. +- `route_transit_gateway_ingress` (optional): (bool) Required if the routing table will be used to route traffic that originates from the internet. - `route_vpc_zone_ingress` (optional): (bool) Required if the routing table will be used to route traffic that originates from Transit Gateway to the VPC. - `routes` (optional): (list) - `action`: The action to perform with a packet. Allowed values are `delegate`, `delegate_vpc`, `deliver`, `drop`. @@ -237,13 +237,13 @@ This variable allows you to specify the list of VPN Gateways to create. - `resource_group` (optional): The resource group where the VPN gateway to be created. - `access_tags` (optional): (list) A list of tags to add to your VPN gateway. -### Example +### Example ```hcl vpn_gateways = { name = "vpn-gateway-1" subnet_name = "subnet-a" - mode = "route" + mode = "route" } ``` @@ -292,4 +292,4 @@ This variable defines cloud service CRNs required to create endpoint gateways. T crn = "crn:v1:bluemix:public:cloud-object-storage:global:::endpoint:s3.direct.mil01.cloud-object-storage.appdomain.cloud" vpe_name = "vpe2" } -``` \ No newline at end of file +``` From 638c6e005dff8867eb501ba88a074cb2d90f2ab3 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Sat, 22 Mar 2025 01:43:44 +0530 Subject: [PATCH 27/46] update vpn gateway inputs and name of vpc --- README.md | 5 +-- ibm_catalog.json | 5 ++- main.tf | 6 ++-- solutions/fully-configurable/DA-types.md | 24 +++++++-------- solutions/fully-configurable/main.tf | 3 +- solutions/fully-configurable/variables.tf | 37 ++++++++++++++--------- variables.tf | 3 +- 7 files changed, 48 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 675c26aa..08294c22 100644 --- a/README.md +++ b/README.md @@ -224,7 +224,7 @@ To attach access management tags to resources in this module, you need the follo | [resource\_group\_id](#input\_resource\_group\_id) | The resource group ID where the VPC to be created | `string` | n/a | yes | | [routes](#input\_routes) | OPTIONAL - Allows you to specify the next hop for packets based on their destination address |
list(
object({
name = string
route_direct_link_ingress = optional(bool)
route_transit_gateway_ingress = optional(bool)
route_vpc_zone_ingress = optional(bool)
routes = optional(
list(
object({
action = optional(string)
zone = number
destination = string
next_hop = string
})
))
})
)
| `[]` | no | | [routing\_table\_name](#input\_routing\_table\_name) | The name to give the provisioned routing tables. If not set, the module generates a name based on the `prefix` and `name` variables. | `string` | `null` | no | -| [security\_group\_rules](#input\_security\_group\_rules) | A list of security group rules to be added to the default vpc security group (default empty) |
list(
object({
name = string
direction = string
remote = string
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
| `[]` | no | +| [security\_group\_rules](#input\_security\_group\_rules) | A list of security group rules to be added to the default vpc security group (default empty) |
list(
object({
name = string
direction = string
remote = optional(string)
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
| `[]` | no | | [skip\_custom\_resolver\_hub\_creation](#input\_skip\_custom\_resolver\_hub\_creation) | Indicates whether to skip the configuration of a custom resolver in the hub VPC. Only relevant if enable\_hub is set to true. | `bool` | `false` | no | | [skip\_spoke\_auth\_policy](#input\_skip\_spoke\_auth\_policy) | Set to true to skip the creation of an authorization policy between the DNS resolution spoke and hub, only enable this if a policy already exists between these two VPCs. See https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-dns-sharing-s2s-auth&interface=ui for more details. | `bool` | `false` | no | | [subnets](#input\_subnets) | List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created |
object({
zone-1 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
}))
zone-2 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
zone-3 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
})
|
{
"zone-1": [
{
"acl_name": "vpc-acl",
"cidr": "10.10.10.0/24",
"name": "subnet-a",
"no_addr_prefix": false,
"public_gateway": true
}
],
"zone-2": [
{
"acl_name": "vpc-acl",
"cidr": "10.20.10.0/24",
"name": "subnet-b",
"no_addr_prefix": false,
"public_gateway": true
}
],
"zone-3": [
{
"acl_name": "vpc-acl",
"cidr": "10.30.10.0/24",
"name": "subnet-c",
"no_addr_prefix": false,
"public_gateway": false
}
]
}
| no | @@ -233,7 +233,7 @@ To attach access management tags to resources in this module, you need the follo | [use\_existing\_dns\_instance](#input\_use\_existing\_dns\_instance) | Whether to use an existing dns instance. If true, existing\_dns\_instance\_id must be set. | `bool` | `false` | no | | [use\_public\_gateways](#input\_use\_public\_gateways) | Create a public gateway in any of the three zones with `true`. |
object({
zone-1 = optional(bool)
zone-2 = optional(bool)
zone-3 = optional(bool)
})
|
{
"zone-1": true,
"zone-2": false,
"zone-3": false
}
| no | | [vpc\_flow\_logs\_name](#input\_vpc\_flow\_logs\_name) | The name to give the provisioned VPC flow logs. If not set, the module generates a name based on the `prefix` and `name` variables. | `string` | `null` | no | -| [vpn\_gateways](#input\_vpn\_gateways) | List of VPN gateways to create. |
list(
object({
name = string
vpc_name = string
subnet_name = string # Do not include prefix, use same name as in `var.subnets`
mode = optional(string)
resource_group = optional(string)
access_tags = optional(list(string), [])
})
)
| `[]` | no | +| [vpn\_gateways](#input\_vpn\_gateways) | List of VPN gateways to create. |
list(
object({
name = string
subnet_name = string # Do not include prefix, use same name as in `var.subnets`
mode = optional(string)
resource_group = optional(string)
access_tags = optional(list(string), [])
})
)
| `[]` | no | ### Outputs @@ -256,6 +256,7 @@ To attach access management tags to resources in this module, you need the follo | [subnet\_detail\_map](#output\_subnet\_detail\_map) | A map of subnets containing IDs, CIDR blocks, and zones | | [subnet\_ids](#output\_subnet\_ids) | The IDs of the subnets | | [subnet\_zone\_list](#output\_subnet\_zone\_list) | A list containing subnet IDs and subnet zones | +| [test](#output\_test) | test | | [vpc\_crn](#output\_vpc\_crn) | CRN of VPC created | | [vpc\_data](#output\_vpc\_data) | Data of the VPC used in this module, created or existing. | | [vpc\_flow\_logs](#output\_vpc\_flow\_logs) | Details of VPC flow logs collector | diff --git a/ibm_catalog.json b/ibm_catalog.json index 59f543fe..0af8d96c 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -229,7 +229,7 @@ "key": "default_routing_table_name" }, { - "key": "security_group_ids" + "key": "vpe_gateway_security_group_ids" }, { "key": "vpe_gateway_service_endpoints", @@ -250,6 +250,9 @@ { "key": "vpe_gateway_cloud_service_by_crn" }, + { + "key": "vpe_gateway_reserved_ips" + }, { "key": "vpn_gateways" }, diff --git a/main.tf b/main.tf index 03561689..03d6b25b 100644 --- a/main.tf +++ b/main.tf @@ -69,7 +69,7 @@ resource "time_sleep" "wait_for_vpc_creation_data" { resource "ibm_is_vpc" "vpc" { count = var.create_vpc == true ? 1 : 0 - name = var.prefix != null ? "${var.prefix}-${var.name}-vpc" : var.name + name = var.prefix != null ? "${var.prefix}-${var.name}" : var.name resource_group = var.resource_group_id # address prefix is set to auto only if no address prefixes NOR any subnet is passed as input address_prefix_management = (length([for prefix in values(coalesce(var.address_prefixes, {})) : prefix if prefix != null]) != 0) || (length([for subnet in values(coalesce(var.subnets, {})) : subnet if subnet != null]) != 0) ? "manual" : null @@ -419,8 +419,8 @@ locals { resource "ibm_is_vpn_gateway" "vpn_gateway" { for_each = local.vpn_gateway_map - name = "${var.prefix}-${each.key}" - subnet = each.value.subnet_name + name = var.prefix != null ? "${var.prefix}-${each.key}" : each.key + subnet = local.subnets["${local.vpc_name}-${each.value.subnet_name}"].id mode = each.value.mode resource_group = each.value.resource_group == null ? var.resource_group_id : each.value.resource_group tags = var.tags diff --git a/solutions/fully-configurable/DA-types.md b/solutions/fully-configurable/DA-types.md index a040bffa..24c6995d 100644 --- a/solutions/fully-configurable/DA-types.md +++ b/solutions/fully-configurable/DA-types.md @@ -10,6 +10,7 @@ Several input variables in the **Cloud automation of VPC** [deployable architect - [VPN Gateways](#vpn-gateways) (`vpn_gateways`) - [VPE Gateways Cloud Services](#cloud-services) (`vpe_gateway_cloud_services`) - [VPE Gateways Cloud Service by CRN](#cloud-service-by-crn) (`vpe_gateway_cloud_service_by_crn`) +- [VPE Gateways Reserved IPs](#reserved-ips) (`vpe_gateway_reserved_ips`) ## Subnets @@ -33,7 +34,7 @@ For each zone, you can define the follwoing: ### Example ```hcl - subnets = { + { zone-1 = [ { name = "subnet-a" @@ -92,7 +93,7 @@ This variable configuration allows you to specify the list of ACLs to create. Ea ### Example ```hcl - network_acls = [ + [ { name = "vpc-acl" add_ibm_cloud_internal_rules = true @@ -144,7 +145,7 @@ This variable configuration allows you to specify the list of security group rul ### Example ```hcl - security_group_rules = [ + [ { name = "security-group-rule-1" direction = "inbound" @@ -174,11 +175,11 @@ This variable allows you to specify the IP range for the VPC for a certain locat ### Example ```hcl -address_prefixes = { + { zone-1 = ["10.10.10.0/18"] zone-2 = null zone-3 = null -} + } ``` ## Routes @@ -204,7 +205,7 @@ This variable allows you to add the custom routing tables and then add routes. ### Example ```hcl - routes = { + { name = "route-1" route_direct_link_ingress = false route_transit_gateway_ingress = false @@ -231,7 +232,6 @@ This variable allows you to specify the list of VPN Gateways to create. ### Options for VPN Gateways - `name` (required): Name of the VPN gateway. -- `vpc_name` (required): Name of the VPC. - `subnet_name` (required): Name of the subnet to attach a VPN gateway. - `mode` (optional): Mode in VPN gateway. Allowed values are `route` and `policy`. - `resource_group` (optional): The resource group where the VPN gateway to be created. @@ -240,10 +240,10 @@ This variable allows you to specify the list of VPN Gateways to create. ### Example ```hcl -vpn_gateways = { + { name = "vpn-gateway-1" subnet_name = "subnet-a" - mode = "route" + mode = "route" } ``` @@ -264,7 +264,7 @@ This variable configuration allows you to specify the list of cloud services use ### Example ```hcl - vpe_gateway_cloud_services = { + { service_name = "cloud-object-storage" vpe_name = "vpe1" } @@ -288,8 +288,8 @@ This variable defines cloud service CRNs required to create endpoint gateways. T ### Example ```hcl - cloud_service_by_crn = { + { crn = "crn:v1:bluemix:public:cloud-object-storage:global:::endpoint:s3.direct.mil01.cloud-object-storage.appdomain.cloud" vpe_name = "vpe2" } -``` +``` \ No newline at end of file diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 1cfafa3e..8a250a50 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -215,11 +215,12 @@ module "vpe_gateway" { resource_group_id = module.resource_group.resource_group_id region = var.region prefix = local.prefix - security_group_ids = var.security_group_ids + security_group_ids = var.vpe_gateway_security_group_ids vpc_name = module.vpc.vpc_name vpc_id = module.vpc.vpc_id subnet_zone_list = module.vpc.subnet_zone_list cloud_services = var.vpe_gateway_cloud_services cloud_service_by_crn = var.vpe_gateway_cloud_service_by_crn service_endpoints = var.vpe_gateway_service_endpoints + reserved_ips = var.vpe_gateway_reserved_ips } diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index c690e77a..5399f6f0 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -22,6 +22,7 @@ variable "provider_visibility" { variable "existing_resource_group_name" { type = string description = "The name of an existing resource group to provision the resources." + default = "Default" } variable "prefix" { @@ -76,7 +77,7 @@ variable "access_tags" { ############################################################################## variable "subnets" { - description = "List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created" + description = "List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#subnets-)." type = object({ zone-1 = list(object({ name = string @@ -127,7 +128,7 @@ variable "subnets" { ############################################################################## variable "network_acls" { - description = "The list of ACLs to create. Provide at least one rule for each ACL." + description = "The list of ACLs to create. Provide at least one rule for each ACL. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#network-acls-)." type = list( object({ name = string @@ -300,13 +301,13 @@ variable "network_acls" { ############################################################################## variable "security_group_rules" { - description = "A list of security group rules to be added to the default vpc security group (default empty)" + description = "A list of security group rules to be added to the default vpc security group (default empty). [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#security-group-rules-)." default = [] type = list( object({ name = string direction = string - remote = string + remote = optional(string) tcp = optional( object({ port_max = optional(number) @@ -364,7 +365,7 @@ variable "clean_default_security_group_acl" { ############################################################################## variable "address_prefixes" { - description = "The IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes" + description = "The IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#address-prefixes-)." type = object({ zone-1 = optional(list(string)) zone-2 = optional(list(string)) @@ -390,7 +391,7 @@ variable "address_prefixes" { ############################################################################## variable "routes" { - description = "Allows you to specify the next hop for packets based on their destination address" + description = "Allows you to specify the next hop for packets based on their destination address. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#routes-)." type = list( object({ name = string @@ -558,13 +559,13 @@ variable "flow_logs_cos_bucket_enable_permanent_retention" { variable "existing_flow_logs_bucket_kms_key_crn" { type = string default = null - description = "The CRN of the existing root key of key management service (KMS) that is used to encrypt the flow logs Cloud Object Storage bucket." + description = "The CRN of the existing root key of key management service (KMS) that is used to encrypt the flow logs Cloud Object Storage bucket. If no value is set for this variable, specify a value for the `existing_kms_instance_crn` variable to create a key ring and key." } variable "existing_kms_instance_crn" { type = string default = null - description = "The CRN of the existing key management service (KMS) that is used to create keys for encrypting the flow logs Cloud Object Storage bucket." + description = "The CRN of the existing key management service (KMS) that is used to create keys for encrypting the flow logs Cloud Object Storage bucket. Used to create a new KMS key unless an existing key is passed using the `existing_flow_logs_bucket_kms_key_crn` input." } variable "kms_endpoint_type" { @@ -616,11 +617,11 @@ variable "default_routing_table_name" { ############################################################################## variable "vpn_gateways" { - description = "List of VPN Gateways to create." + description = "List of VPN Gateways to create. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpn-gateways-)." + nullable = false type = list( object({ name = string - vpc_name = string subnet_name = string # Do not include prefix, use same name as in `var.subnets` mode = optional(string) resource_group = optional(string) @@ -636,7 +637,7 @@ variable "vpn_gateways" { ############################################################################## variable "vpe_gateway_cloud_services" { - description = "The list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names are created in the format `--`." + description = "The list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names are created in the format `--`. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpe-gateway-cloud-services-)." type = set(object({ service_name = string vpe_name = optional(string), # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name. @@ -646,7 +647,7 @@ variable "vpe_gateway_cloud_services" { } variable "vpe_gateway_cloud_service_by_crn" { - description = "The list of cloud service CRNs used to create endpoint gateways. Use this list to identify services that are not supported by service name in the `cloud_services` variable. For a list of supported services, see [VPE-enabled services](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). If `service_name` is not specified, the CRN is used to find the name. If `vpe_name` is not specified in the list, VPE names are created in the format `--`." + description = "The list of cloud service CRNs used to create endpoint gateways. Use this list to identify services that are not supported by service name in the `cloud_services` variable. For a list of supported services, see [VPE-enabled services](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). If `service_name` is not specified, the CRN is used to find the name. If `vpe_name` is not specified in the list, VPE names are created in the format `--`. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpe-gateway-cloud-service-by-crn-)." type = set( object({ crn = string @@ -669,8 +670,16 @@ variable "vpe_gateway_service_endpoints" { } } -variable "security_group_ids" { +variable "vpe_gateway_security_group_ids" { description = "List of security group ids to attach to each endpoint gateway." type = list(string) - default = null + default = null # Let this default value be null instead of []. Known issue - https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4546 +} + +variable "vpe_gateway_reserved_ips" { + description = "Map of existing reserved IP names and values. Leave this value as default if you want to create new reserved ips, this value is used when a user passes their existing reserved ips created here and not attempt to recreate those." + type = object({ + name = optional(string) # reserved ip name + }) + default = {} } diff --git a/variables.tf b/variables.tf index 716d97db..f0508036 100644 --- a/variables.tf +++ b/variables.tf @@ -409,7 +409,7 @@ variable "security_group_rules" { object({ name = string direction = string - remote = string + remote = optional(string) tcp = optional( object({ port_max = optional(number) @@ -732,7 +732,6 @@ variable "vpn_gateways" { type = list( object({ name = string - vpc_name = string subnet_name = string # Do not include prefix, use same name as in `var.subnets` mode = optional(string) resource_group = optional(string) From cde65bb595209764b5ada721838b02ec2f964cdb Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Sat, 22 Mar 2025 02:08:59 +0530 Subject: [PATCH 28/46] update code --- solutions/fully-configurable/DA-types.md | 24 +++++++++++++++++-- .../catalogValidationValues.json.template | 8 +++++-- solutions/fully-configurable/main.tf | 3 +++ solutions/fully-configurable/variables.tf | 4 ++-- tests/pr_test.go | 4 +++- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/solutions/fully-configurable/DA-types.md b/solutions/fully-configurable/DA-types.md index 24c6995d..915a0809 100644 --- a/solutions/fully-configurable/DA-types.md +++ b/solutions/fully-configurable/DA-types.md @@ -243,7 +243,7 @@ This variable allows you to specify the list of VPN Gateways to create. { name = "vpn-gateway-1" subnet_name = "subnet-a" - mode = "route" + mode = "route" } ``` @@ -292,4 +292,24 @@ This variable defines cloud service CRNs required to create endpoint gateways. T crn = "crn:v1:bluemix:public:cloud-object-storage:global:::endpoint:s3.direct.mil01.cloud-object-storage.appdomain.cloud" vpe_name = "vpe2" } -``` \ No newline at end of file +``` + +## VPE Gateways Reserved IPs + +This variable defines a map of existing reserved IP names and values to attach with the endpoint gateways. This value is used when a user uses the existing reserved ips instead of creating new." + +- Variable name: `vpe_gateway_reserved_ips`. +- Type: A object. +- Default value: An empty object `{}`. + +### Options for VPE Gateway Cloud Services by CRN + +- `name` (optional): The name of the reserved IP with its value. + +### Example + +```hcl + { + name = "10.10.10.4" + } +``` diff --git a/solutions/fully-configurable/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template index 01f86ae4..92c260d6 100644 --- a/solutions/fully-configurable/catalogValidationValues.json.template +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -2,6 +2,10 @@ "ibmcloud_api_key": $VALIDATION_APIKEY, "region": "us-south", "resource_tags": $TAGS, - "existing_resource_group_name": $PREFIX, - "prefix": $PREFIX + "existing_resource_group_name": "geretain-test-resources", + "prefix": $PREFIX, + "enable_vpc_flow_logs": true, + "kms_encryption_enabled_bucket": true, + "existing_kms_instance_crn": $HPCS_US_SOUTH_CRN, + "existing_cos_instance_crn": $COS_INSTANCE_CRN } diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 8a250a50..5d265d94 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -33,6 +33,7 @@ locals { cos_kms_key_crn = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? var.existing_flow_logs_bucket_kms_key_crn : module.kms[0].keys[format("%s.%s", local.kms_key_ring_name, local.kms_key_name)].crn) : null create_cos_kms_iam_auth_policy = var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && !var.skip_cos_kms_iam_auth_policy + # configuration for the flow logs bucket bucket_config = [{ access_tags = var.access_tags bucket_name = local.bucket_name @@ -65,6 +66,7 @@ locals { }] } +# Create COS bucket using the defined bucket configuration module "cos_buckets" { count = var.enable_vpc_flow_logs ? 1 : 0 source = "terraform-ibm-modules/cos/ibm//modules/buckets" @@ -179,6 +181,7 @@ locals { } } +# Create VPC module "vpc" { source = "../../" resource_group_id = module.resource_group.resource_group_id diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 5399f6f0..86e7548c 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -673,11 +673,11 @@ variable "vpe_gateway_service_endpoints" { variable "vpe_gateway_security_group_ids" { description = "List of security group ids to attach to each endpoint gateway." type = list(string) - default = null # Let this default value be null instead of []. Known issue - https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4546 + default = null # Let this default value be null instead of []. Provider issue - https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4546 } variable "vpe_gateway_reserved_ips" { - description = "Map of existing reserved IP names and values. Leave this value as default if you want to create new reserved ips, this value is used when a user passes their existing reserved ips created here and not attempt to recreate those." + description = "Map of existing reserved IP names and values. Leave this value as default if you want to create new reserved ips, this value is used when a user passes their existing reserved ips created here and not attempt to recreate those. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#reserved-ips-)." type = object({ name = optional(string) # reserved ip name }) diff --git a/tests/pr_test.go b/tests/pr_test.go index 256017f0..9ac8e0de 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -261,7 +261,7 @@ func TestRunUpgradeFullyConfigurable(t *testing.T) { // Programmatically determine region to use based on availability region, _ := testhelper.GetBestVpcRegion(val, "../common-dev-assets/common-go-assets/cloudinfo-region-vpc-gen2-prefs.yaml", "eu-de") - prefix := "vpc-da" + prefix := "vpc-upg" options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{ Testing: t, @@ -269,6 +269,8 @@ func TestRunUpgradeFullyConfigurable(t *testing.T) { Prefix: prefix, TarIncludePatterns: []string{ "*.tf", + "dynamic_values/*.tf", + "dynamic_values/config_modules/*/*.tf", fullyConfigFlavorDir + "/*.tf", }, TemplateFolder: fullyConfigFlavorDir, From 2fab799d5b2710781672e81d352d270d81f1e1b8 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Sat, 22 Mar 2025 02:22:19 +0530 Subject: [PATCH 29/46] DA readme --- solutions/fully-configurable/README.md | 130 ++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 5 deletions(-) diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md index 2e70f5f9..7df8c60f 100644 --- a/solutions/fully-configurable/README.md +++ b/solutions/fully-configurable/README.md @@ -1,11 +1,131 @@ -# IBM VPC deployable architecture +# Cloud automation for VPC (Fully configurable) -This deployable architecture supports provisioning the following resources: +### Prerequisites -- A new resource group if one is not passed in. -- A VPC. +- An existing resource group +- An existing COS istance if VPC flow logs is enabled +- An existing KMS instance (or key) if encryption of the COS bucket is required +### Configuration -![vpc-deployable-architecture](../../reference-architecture/vpc-quickstart-da.svg) +This solution supports provisioning and configuring the following infrastructure: + +- A VPC +- A Cloud Object Storage bucket which is required to store flow logs +- KMS key-ring and key if existing key is not passed in +- Configures the following for the created VPC: + - subnets + - network ACLs + - security group rules + - address prefixes + - customized routing table and routes + - public gateway + - VPN gateway + - VPE gateway + - flow logs + + +![vpc-deployable-architecture](../../reference-architecture/deployable-architecture-vpc.svg) :exclamation: **Important:** This solution is not intended to be called by other modules because it contains a provider configuration and is not compatible with the `for_each`, `count`, and `depends_on` arguments. For more information, see [Providers Within Modules](https://developer.hashicorp.com/terraform/language/modules/develop/providers). + + + +### Requirements + +| Name | Version | +|------|---------| +| [terraform](#requirement\_terraform) | >= 1.9.0 | +| [ibm](#requirement\_ibm) | 1.76.1 | + +### Modules + +| Name | Source | Version | +|------|--------|---------| +| [cos\_buckets](#module\_cos\_buckets) | terraform-ibm-modules/cos/ibm//modules/buckets | 8.19.2 | +| [existing\_cos\_crn\_parser](#module\_existing\_cos\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [existing\_kms\_instance\_crn\_parser](#module\_existing\_kms\_instance\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [existing\_kms\_key\_crn\_parser](#module\_existing\_kms\_key\_crn\_parser) | terraform-ibm-modules/common-utilities/ibm//modules/crn-parser | 1.1.0 | +| [kms](#module\_kms) | terraform-ibm-modules/kms-all-inclusive/ibm | 4.19.5 | +| [resource\_group](#module\_resource\_group) | terraform-ibm-modules/resource-group/ibm | 1.1.6 | +| [vpc](#module\_vpc) | ../../ | n/a | +| [vpe\_gateway](#module\_vpe\_gateway) | terraform-ibm-modules/vpe-gateway/ibm | 4.5.0 | + +### Resources + +| Name | Type | +|------|------| +| [ibm_iam_authorization_policy.cos_kms_iam_auth_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.76.1/docs/resources/iam_authorization_policy) | resource | + +### Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [access\_tags](#input\_access\_tags) | A list of access tags to apply to the VPC resources created by this solution. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial. | `list(string)` | `[]` | no | +| [add\_bucket\_name\_suffix](#input\_add\_bucket\_name\_suffix) | Add a randomly generated suffix that is 4 characters in length, to the name of the newly provisioned Cloud Object Storage bucket. Do not use this suffix if you are passing the existing Cloud Object Storage bucket. To manage the name of the Cloud Object Storage bucket manually, use the `flow_logs_cos_bucket_name` variables. | `bool` | `true` | no | +| [address\_prefixes](#input\_address\_prefixes) | The IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#address-prefixes-). |
object({
zone-1 = optional(list(string))
zone-2 = optional(list(string))
zone-3 = optional(list(string))
})
|
{
"zone-1": null,
"zone-2": null,
"zone-3": null
}
| no | +| [clean\_default\_security\_group\_acl](#input\_clean\_default\_security\_group\_acl) | Remove all rules from the default VPC security group and VPC ACL (less permissive) | `bool` | `true` | no | +| [cos\_bucket\_class](#input\_cos\_bucket\_class) | The storage class of the newly provisioned Cloud Object Storage bucket. Specify one of the following values for the storage class: `standard`, `vault`, `cold`, `smart` (default), or `onerate_active`. | `string` | `"standard"` | no | +| [default\_network\_acl\_name](#input\_default\_network\_acl\_name) | Name of the Default ACL. If null, a name will be automatically generated. | `string` | `null` | no | +| [default\_routing\_table\_name](#input\_default\_routing\_table\_name) | Name of the Default Routing Table. If null, a name will be automatically generated. | `string` | `null` | no | +| [default\_security\_group\_name](#input\_default\_security\_group\_name) | Name of the Default Security Group. If null, a name will be automatically generated. | `string` | `null` | no | +| [enable\_vpc\_flow\_logs](#input\_enable\_vpc\_flow\_logs) | To enable VPC Flow logs, set this to true. | `bool` | `false` | no | +| [existing\_cos\_instance\_crn](#input\_existing\_cos\_instance\_crn) | CRN of the existing COS instance. It is only required if `enable_vpc_flow_logs` is set to true and will be used to create the flow logs bucket. | `string` | `null` | no | +| [existing\_flow\_logs\_bucket\_kms\_key\_crn](#input\_existing\_flow\_logs\_bucket\_kms\_key\_crn) | The CRN of the existing root key of key management service (KMS) that is used to encrypt the flow logs Cloud Object Storage bucket. If no value is set for this variable, specify a value for the `existing_kms_instance_crn` variable to create a key ring and key. | `string` | `null` | no | +| [existing\_kms\_instance\_crn](#input\_existing\_kms\_instance\_crn) | The CRN of the existing key management service (KMS) that is used to create keys for encrypting the flow logs Cloud Object Storage bucket. Used to create a new KMS key unless an existing key is passed using the `existing_flow_logs_bucket_kms_key_crn` input. | `string` | `null` | no | +| [existing\_resource\_group\_name](#input\_existing\_resource\_group\_name) | The name of an existing resource group to provision the resources. | `string` | `"Default"` | no | +| [flow\_logs\_cos\_bucket\_archive\_days](#input\_flow\_logs\_cos\_bucket\_archive\_days) | The number of days before the `archive_type` rule action takes effect for the flow logs cloud object storage bucket. | `number` | `20` | no | +| [flow\_logs\_cos\_bucket\_archive\_type](#input\_flow\_logs\_cos\_bucket\_archive\_type) | The storage class or archive type you want the object to transition to in the flow logs cloud object storage bucket. | `string` | `"Glacier"` | no | +| [flow\_logs\_cos\_bucket\_default\_retention\_days](#input\_flow\_logs\_cos\_bucket\_default\_retention\_days) | The number of days that an object can remain unmodified in the flow logs cloud object storage bucket. | `number` | `90` | no | +| [flow\_logs\_cos\_bucket\_enable\_object\_versioning](#input\_flow\_logs\_cos\_bucket\_enable\_object\_versioning) | Set it to true if object versioning is enabled so that multiple versions of an object are retained in the flow logs cloud object storage bucket. Cannot be used if `flow_logs_cos_bucket_enable_retention` is true. | `bool` | `false` | no | +| [flow\_logs\_cos\_bucket\_enable\_permanent\_retention](#input\_flow\_logs\_cos\_bucket\_enable\_permanent\_retention) | Whether permanent retention status is enabled for the flow logs cloud object storage bucket. [Learn more](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-immutable). | `bool` | `false` | no | +| [flow\_logs\_cos\_bucket\_enable\_retention](#input\_flow\_logs\_cos\_bucket\_enable\_retention) | Set to true to enable retention for the flow logs cloud object storage bucket. | `bool` | `false` | no | +| [flow\_logs\_cos\_bucket\_expire\_days](#input\_flow\_logs\_cos\_bucket\_expire\_days) | The number of days before the expire rule action takes effect for the flow logs cloud object storage bucket. | `number` | `365` | no | +| [flow\_logs\_cos\_bucket\_maximum\_retention\_days](#input\_flow\_logs\_cos\_bucket\_maximum\_retention\_days) | The maximum number of days that an object can be kept unmodified in the flow logs cloud object storage. | `number` | `350` | no | +| [flow\_logs\_cos\_bucket\_minimum\_retention\_days](#input\_flow\_logs\_cos\_bucket\_minimum\_retention\_days) | The minimum number of days that an object must be kept unmodified in the flow logs cloud object storage. | `number` | `90` | no | +| [flow\_logs\_cos\_bucket\_name](#input\_flow\_logs\_cos\_bucket\_name) | Name of the Cloud Object Storage bucket to be created to collect VPC flow logs. | `string` | `"flow-logs-bucket"` | no | +| [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources. | `string` | n/a | yes | +| [kms\_encryption\_enabled\_bucket](#input\_kms\_encryption\_enabled\_bucket) | Set to true to encrypt the Cloud Object Storage Flow Logs bucket with a KMS key. If set to true, a value must be passed for existing\_flow\_logs\_bucket\_kms\_key\_crn (to use that key) or existing\_kms\_instance\_crn (to create a new key). Value cannot be set to true if enable\_vpc\_flow\_logs is set to false. | `bool` | `false` | no | +| [kms\_endpoint\_type](#input\_kms\_endpoint\_type) | The type of endpoint to use for communicating with the KMS. Possible values: `public`, `private`. Applies only if `existing_flow_logs_bucket_kms_key_crn` is not specified. | `string` | `"private"` | no | +| [kms\_key\_name](#input\_kms\_key\_name) | The name of the key to encrypt the flow logs Cloud Object Storage bucket. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key is prefixed to the value in the `-value` format. | `string` | `"flow-logs-cos-key"` | no | +| [kms\_key\_ring\_name](#input\_kms\_key\_ring\_name) | The name of the key ring to create for the Cloud Object Storage bucket key. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key ring is prefixed to the value in the `-value` format. | `string` | `"flow-logs-cos-key-ring"` | no | +| [management\_endpoint\_type\_for\_bucket](#input\_management\_endpoint\_type\_for\_bucket) | The type of endpoint for the IBM Terraform provider to use to manage Cloud Object Storage buckets (`public`, `private`, or `direct`). If you are using a private endpoint, make sure that you enable virtual routing and forwarding (VRF) in your account, and that the Terraform runtime can access the IBM Cloud Private network. | `string` | `"direct"` | no | +| [network\_acls](#input\_network\_acls) | The list of ACLs to create. Provide at least one rule for each ACL. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#network-acls-). |
list(
object({
name = string
add_ibm_cloud_internal_rules = optional(bool)
add_vpc_connectivity_rules = optional(bool)
prepend_ibm_rules = optional(bool)
rules = list(
object({
name = string
action = string
destination = string
direction = string
source = string
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
source_port_max = optional(number)
source_port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
source_port_max = optional(number)
source_port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
})
)
|
[
{
"add_ibm_cloud_internal_rules": true,
"add_vpc_connectivity_rules": true,
"name": "vpc-acl",
"prepend_ibm_rules": true,
"rules": [
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "inbound",
"name": "allow-all-443-inbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 443,
"port_min": 443,
"source_port_max": 443,
"source_port_min": 443
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "inbound",
"name": "allow-all-80-inbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 80,
"port_min": 80,
"source_port_max": 80,
"source_port_min": 80
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "inbound",
"name": "allow-all-22-inbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 22,
"port_min": 22,
"source_port_max": 22,
"source_port_min": 22
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "outbound",
"name": "allow-all-443-outbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 443,
"port_min": 443,
"source_port_max": 443,
"source_port_min": 443
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "outbound",
"name": "allow-all-80-outbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 80,
"port_min": 80,
"source_port_max": 80,
"source_port_min": 80
}
},
{
"action": "allow",
"destination": "0.0.0.0/0",
"direction": "outbound",
"name": "allow-all-22-outbound",
"source": "0.0.0.0/0",
"tcp": {
"port_max": 22,
"port_min": 22,
"source_port_max": 22,
"source_port_min": 22
}
}
]
}
]
| no | +| [prefix](#input\_prefix) | Prefix to add to all the resources created by this solution. To not use any prefix value, you can set this value to `null` or an empty string. | `string` | n/a | yes | +| [provider\_visibility](#input\_provider\_visibility) | Set the visibility value for the IBM terraform provider. Supported values are `public`, `private`, `public-and-private`. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/guides/custom-service-endpoints). | `string` | `"private"` | no | +| [region](#input\_region) | Region to deploy the VPC. | `string` | `"us-south"` | no | +| [resource\_tags](#input\_resource\_tags) | List of tags for the resources created by this solution. | `list(string)` | `[]` | no | +| [routes](#input\_routes) | Allows you to specify the next hop for packets based on their destination address. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#routes-). |
list(
object({
name = string
route_direct_link_ingress = optional(bool)
route_transit_gateway_ingress = optional(bool)
route_vpc_zone_ingress = optional(bool)
routes = optional(
list(
object({
action = optional(string)
zone = number
destination = string
next_hop = string
})
))
})
)
| `[]` | no | +| [security\_group\_rules](#input\_security\_group\_rules) | A list of security group rules to be added to the default vpc security group (default empty). [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#security-group-rules-). |
list(
object({
name = string
direction = string
remote = optional(string)
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
| `[]` | no | +| [skip\_cos\_kms\_iam\_auth\_policy](#input\_skip\_cos\_kms\_iam\_auth\_policy) | To skip creating an IAM authorization policy that allows Cloud Object Storage(COS) to access KMS key. | `bool` | `false` | no | +| [skip\_vpc\_cos\_iam\_auth\_policy](#input\_skip\_vpc\_cos\_iam\_auth\_policy) | To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`. Required only if `enable_vpc_flow_logs` is set to true. | `bool` | `false` | no | +| [subnets](#input\_subnets) | List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#subnets-). |
object({
zone-1 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
}))
zone-2 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
zone-3 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
})
|
{
"zone-1": [
{
"acl_name": "vpc-acl",
"cidr": "10.10.10.0/24",
"name": "subnet-a",
"no_addr_prefix": false,
"public_gateway": true
}
]
}
| no | +| [vpc\_name](#input\_vpc\_name) | Name of the VPC. If a prefix input variable is specified, the prefix is added to the name in the `-` format. | `string` | `"vpc"` | no | +| [vpe\_gateway\_cloud\_service\_by\_crn](#input\_vpe\_gateway\_cloud\_service\_by\_crn) | The list of cloud service CRNs used to create endpoint gateways. Use this list to identify services that are not supported by service name in the `cloud_services` variable. For a list of supported services, see [VPE-enabled services](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). If `service_name` is not specified, the CRN is used to find the name. If `vpe_name` is not specified in the list, VPE names are created in the format `--`. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpe-gateway-cloud-service-by-crn-). |
set(
object({
crn = string
vpe_name = optional(string) # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name.
service_name = optional(string) # Name of the service used to compute the name of the VPE. If not specified, the service name will be obtained from the crn.
allow_dns_resolution_binding = optional(bool, true)
})
)
| `[]` | no | +| [vpe\_gateway\_cloud\_services](#input\_vpe\_gateway\_cloud\_services) | The list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names are created in the format `--`. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpe-gateway-cloud-services-). |
set(object({
service_name = string
vpe_name = optional(string), # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name.
allow_dns_resolution_binding = optional(bool, false)
}))
| `[]` | no | +| [vpe\_gateway\_reserved\_ips](#input\_vpe\_gateway\_reserved\_ips) | Map of existing reserved IP names and values. Leave this value as default if you want to create new reserved ips, this value is used when a user passes their existing reserved ips created here and not attempt to recreate those. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#reserved-ips-). |
object({
name = optional(string) # reserved ip name
})
| `{}` | no | +| [vpe\_gateway\_security\_group\_ids](#input\_vpe\_gateway\_security\_group\_ids) | List of security group ids to attach to each endpoint gateway. | `list(string)` | `null` | no | +| [vpe\_gateway\_service\_endpoints](#input\_vpe\_gateway\_service\_endpoints) | Service endpoints to use to create endpoint gateways. Can be `public`, or `private`. | `string` | `"private"` | no | +| [vpn\_gateways](#input\_vpn\_gateways) | List of VPN Gateways to create. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpn-gateways-). |
list(
object({
name = string
subnet_name = string # Do not include prefix, use same name as in `var.subnets`
mode = optional(string)
resource_group = optional(string)
access_tags = optional(list(string), [])
})
)
| `[]` | no | + +### Outputs + +| Name | Description | +|------|-------------| +| [network\_acls](#output\_network\_acls) | List of shortnames and IDs of network ACLs | +| [private\_path\_subnet\_id](#output\_private\_path\_subnet\_id) | The IDs of the subnets | +| [public\_gateways](#output\_public\_gateways) | Map of public gateways by zone | +| [security\_group\_details](#output\_security\_group\_details) | Details of security group. | +| [subnet\_detail\_list](#output\_subnet\_detail\_list) | A list of subnets containing names, CIDR blocks, and zones. | +| [subnet\_detail\_map](#output\_subnet\_detail\_map) | A map of subnets containing IDs, CIDR blocks, and zones | +| [subnet\_ids](#output\_subnet\_ids) | The IDs of the subnets | +| [subnet\_zone\_list](#output\_subnet\_zone\_list) | A list containing subnet IDs and subnet zones | +| [vpc\_crn](#output\_vpc\_crn) | CRN of VPC created | +| [vpc\_flow\_logs](#output\_vpc\_flow\_logs) | Details of VPC flow logs collector | +| [vpc\_id](#output\_vpc\_id) | ID of VPC created | +| [vpc\_name](#output\_vpc\_name) | Name of VPC created | +| [vpe\_crn](#output\_vpe\_crn) | The CRN of the endpoint gateway | +| [vpe\_ips](#output\_vpe\_ips) | The reserved IPs for endpoint gateways. | +| [vpn\_gateways\_data](#output\_vpn\_gateways\_data) | Details of VPN gateways data | +| [vpn\_gateways\_name](#output\_vpn\_gateways\_name) | List of names of VPN gateways. | + From a0d11a2ff0d55e2fa52a26663d8f21b59d7d495b Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Sat, 22 Mar 2025 14:08:28 +0530 Subject: [PATCH 30/46] fix readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 08294c22..d0987f26 100644 --- a/README.md +++ b/README.md @@ -256,7 +256,6 @@ To attach access management tags to resources in this module, you need the follo | [subnet\_detail\_map](#output\_subnet\_detail\_map) | A map of subnets containing IDs, CIDR blocks, and zones | | [subnet\_ids](#output\_subnet\_ids) | The IDs of the subnets | | [subnet\_zone\_list](#output\_subnet\_zone\_list) | A list containing subnet IDs and subnet zones | -| [test](#output\_test) | test | | [vpc\_crn](#output\_vpc\_crn) | CRN of VPC created | | [vpc\_data](#output\_vpc\_data) | Data of the VPC used in this module, created or existing. | | [vpc\_flow\_logs](#output\_vpc\_flow\_logs) | Details of VPC flow logs collector | From 76120b62ecaf381ad81b27d1fff61540d3054c01 Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Mon, 24 Mar 2025 11:37:00 +0530 Subject: [PATCH 31/46] updated rf arch --- reference-architecture/deployable-architecture-vpc.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference-architecture/deployable-architecture-vpc.svg b/reference-architecture/deployable-architecture-vpc.svg index c2371c88..4de4ed1c 100644 --- a/reference-architecture/deployable-architecture-vpc.svg +++ b/reference-architecture/deployable-architecture-vpc.svg @@ -1,4 +1,4 @@ -
ACL
locked
IBM Cloud
Region
Existing Resource Group
Flow logs Bucket
Existing COS Instance
Existing KMS instance
VPC
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 1
VPN Gateway (Optional)
ACL
locked
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
\ No newline at end of file +
ACL
locked
IBM Cloud
Region
Resource Group
Existing KMS
Key Ring
Root Key
Flow logs Bucket
Cloud Object Storage Instance
VPC
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 1
VPN Gateway (Optional)
ACL
locked
Subnet
Public Gateway (Optional)Virtual Private Endpoints(Optional)
Zone 2
VPN Gateway (Optional)
\ No newline at end of file From 1603610663af9e3a2c4d0554b0fac0e92f5217ef Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 24 Mar 2025 12:33:24 +0530 Subject: [PATCH 32/46] update boolean variables --- solutions/fully-configurable/main.tf | 5 ++--- solutions/fully-configurable/variables.tf | 9 +++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 5d265d94..97d5be6b 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -154,9 +154,8 @@ module "kms" { key_endpoint_type = var.kms_endpoint_type keys = [ { - key_ring_name = local.kms_key_ring_name - existing_key_ring = false - force_delete_key_ring = true + key_ring_name = local.kms_key_ring_name + existing_key_ring = false keys = [ { key_name = local.kms_key_name diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 86e7548c..09fe26c6 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -357,6 +357,7 @@ variable "security_group_rules" { variable "clean_default_security_group_acl" { description = "Remove all rules from the default VPC security group and VPC ACL (less permissive)" type = bool + nullable = false default = true } @@ -419,12 +420,14 @@ variable "routes" { variable "enable_vpc_flow_logs" { description = "To enable VPC Flow logs, set this to true." type = bool + nullable = false default = false } variable "skip_vpc_cos_iam_auth_policy" { description = "To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`. Required only if `enable_vpc_flow_logs` is set to true." type = bool + nullable = false default = false } @@ -448,6 +451,7 @@ variable "flow_logs_cos_bucket_name" { variable "kms_encryption_enabled_bucket" { description = "Set to true to encrypt the Cloud Object Storage Flow Logs bucket with a KMS key. If set to true, a value must be passed for existing_flow_logs_bucket_kms_key_crn (to use that key) or existing_kms_instance_crn (to create a new key). Value cannot be set to true if enable_vpc_flow_logs is set to false." type = bool + nullable = false default = false validation { @@ -463,6 +467,7 @@ variable "kms_encryption_enabled_bucket" { variable "skip_cos_kms_iam_auth_policy" { type = bool + nullable = false description = "To skip creating an IAM authorization policy that allows Cloud Object Storage(COS) to access KMS key." default = false } @@ -489,6 +494,7 @@ variable "cos_bucket_class" { variable "add_bucket_name_suffix" { type = bool + nullable = false description = "Add a randomly generated suffix that is 4 characters in length, to the name of the newly provisioned Cloud Object Storage bucket. Do not use this suffix if you are passing the existing Cloud Object Storage bucket. To manage the name of the Cloud Object Storage bucket manually, use the `flow_logs_cos_bucket_name` variables." default = true } @@ -514,6 +520,7 @@ variable "flow_logs_cos_bucket_expire_days" { variable "flow_logs_cos_bucket_enable_object_versioning" { description = "Set it to true if object versioning is enabled so that multiple versions of an object are retained in the flow logs cloud object storage bucket. Cannot be used if `flow_logs_cos_bucket_enable_retention` is true." type = bool + nullable = false default = false validation { @@ -525,6 +532,7 @@ variable "flow_logs_cos_bucket_enable_object_versioning" { variable "flow_logs_cos_bucket_enable_retention" { description = "Set to true to enable retention for the flow logs cloud object storage bucket." type = bool + nullable = false default = false } @@ -549,6 +557,7 @@ variable "flow_logs_cos_bucket_minimum_retention_days" { variable "flow_logs_cos_bucket_enable_permanent_retention" { description = "Whether permanent retention status is enabled for the flow logs cloud object storage bucket. [Learn more](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-immutable)." type = bool + nullable = false default = false } From ef0498aaa5477c798ea4437088a8d688a63bf30c Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 24 Mar 2025 13:21:11 +0530 Subject: [PATCH 33/46] catalog changes --- ibm_catalog.json | 119 +++++++++++++++---------- solutions/fully-configurable/README.md | 6 +- 2 files changed, 77 insertions(+), 48 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 0af8d96c..09c1fc9d 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -21,17 +21,13 @@ ], "short_description": "Provisions a VPC network on IBM Cloud", "long_description": "The VPC deployable architecture deploys a Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters.", - "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/README.md", - "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/vpc-da-12217/images/vpc_icon.svg", + "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/README.md", + "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/images/vpc_icon.svg", "provider_name": "IBM", "features": [ { "title": "VPC on IBM Cloud", - "description": "Create a VPC on IBM Cloud." - }, - { - "title": "Public gateways", - "description": "Create and configure public gateways." + "description": "Create a VPC network on IBM Cloud." }, { "title": "Subnets", @@ -41,6 +37,10 @@ "title": "Network ACLs", "description": "Create network ACLs." }, + { + "title": "Public gateways", + "description": "Create and configure public gateways." + }, { "title": "VPN gateways", "description": "Create and configure VPN gateways." @@ -60,6 +60,10 @@ { "title": "Address Prefixes", "description": "Creates address prefixes." + }, + { + "title": "Routing Table and routes", + "description": "Creates routing table and customized routes." } ], "flavors": [ @@ -72,47 +76,71 @@ "descriptions": "This architecture creates a VPC.", "features": [ { - "title": "VPC on IBM Cloud", - "description": "Create a VPC on IBM Cloud." + "title": "Create VPC", + "description": "Yes" + }, + { + "title": "Use existing VPC instance", + "description": "No" }, { - "title": "Public gateways", - "description": "Create and configure public gateways." + "title": "New resource group creation", + "description": "No" }, { - "title": "Subnets", - "description": "Creates subnets for VPC." + "title": "Create public gateways", + "description": "Yes" }, { - "title": "Network ACLs", - "description": "Create network ACLs." + "title": "Create subnets", + "description": "Yes" }, { - "title": "VPN gateways", - "description": "Create and configure VPN gateways." + "title": "Create network ACLs", + "description": "Yes" }, { - "title": "VPE gateways", - "description": "Create and configure VPE gateways." + "title": "Create VPN gateways", + "description": "Yes" }, { - "title": "Security groups", - "description": "Create and configure security group rules." + "title": "Create VPE gateways", + "description": "Yes" }, { - "title": "VPC flow logs", - "description": "VPC flow logs can be enabled." + "title": "Create security groups rules", + "description": "Yes" }, { - "title": "Address Prefixes", - "description": "Creates address prefixes." + "title": "Configure VPC flow logs", + "description": "Yes" + }, + { + "title": "Create COS instance", + "description": "No" + }, + { + "title": "Enforced KMS encryption", + "description": "No" + }, + { + "title": "Use existing KMS key", + "description": "Yes" + }, + { + "title": "KMS key ring and key creation", + "description": "Yes" + }, + { + "title": "Create custom routes", + "description": "Yes" } ], "diagrams": [ { "diagram": { "caption": "VPC for IBM Cloud.", - "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/vpc-da-12217/reference-architecture/deployable-architecture-vpc.svg", + "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/reference-architecture/deployable-architecture-vpc.svg", "type": "image/svg+xml" }, "description": "This architecture creates a VPC." @@ -189,7 +217,8 @@ ] }, { - "key": "vpc_name" + "key": "vpc_name", + "required": true }, { "key": "subnets" @@ -197,6 +226,15 @@ { "key": "network_acls" }, + { + "key": "address_prefixes" + }, + { + "key": "routes" + }, + { + "key": "security_group_rules" + }, { "key": "clean_default_security_group_acl", "options": [ @@ -210,24 +248,6 @@ } ] }, - { - "key": "address_prefixes" - }, - { - "key": "routes" - }, - { - "key": "default_network_acl_name" - }, - { - "key": "security_group_rules" - }, - { - "key": "default_security_group_name" - }, - { - "key": "default_routing_table_name" - }, { "key": "vpe_gateway_security_group_ids" }, @@ -256,6 +276,15 @@ { "key": "vpn_gateways" }, + { + "key": "default_network_acl_name" + }, + { + "key": "default_security_group_name" + }, + { + "key": "default_routing_table_name" + }, { "key": "resource_tags", "custom_config": { diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md index 7df8c60f..a15ac08d 100644 --- a/solutions/fully-configurable/README.md +++ b/solutions/fully-configurable/README.md @@ -2,9 +2,9 @@ ### Prerequisites -- An existing resource group -- An existing COS istance if VPC flow logs is enabled -- An existing KMS instance (or key) if encryption of the COS bucket is required +- An existing resource group. +- An existing COS istance if VPC flow logs is enabled. +- An existing KMS instance (or key) if encryption of the flow logs COS bucket is required. ### Configuration From f3dae55be54ed746da263c19295caa6623679081 Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Mon, 24 Mar 2025 14:10:19 +0530 Subject: [PATCH 34/46] updated catalog --- ibm_catalog.json | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 09c1fc9d..8e6de2d1 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -27,15 +27,15 @@ "features": [ { "title": "VPC on IBM Cloud", - "description": "Create a VPC network on IBM Cloud." + "description": "Creates and configures a VPC network on IBM Cloud." }, { "title": "Subnets", - "description": "Creates subnets for VPC." + "description": "Creates and configures subnets for VPC." }, { "title": "Network ACLs", - "description": "Create network ACLs." + "description": "Creates and configures network ACLs." }, { "title": "Public gateways", @@ -59,11 +59,19 @@ }, { "title": "Address Prefixes", - "description": "Creates address prefixes." + "description": "Creates and configures address prefixes." }, { "title": "Routing Table and routes", - "description": "Creates routing table and customized routes." + "description": "Creates and configures routing table and customized routes." + }, + { + "title": "Object Storage bucket for VPC flow logs", + "description": "Creates and configures an Object Storage bucket required for VPC flow logs." + }, + { + "title": "KMS encryption", + "description": "Supports creating a new key, or using an existing one to encrypt the COS flow log bucket." } ], "flavors": [ @@ -149,15 +157,11 @@ }, "iam_permissions": [ { - "role_crns": [ - "crn:v1:bluemix:public:iam::::role:Administrator" - ], + "role_crns": ["crn:v1:bluemix:public:iam::::role:Administrator"], "service_name": "iam-identity" }, { - "role_crns": [ - "crn:v1:bluemix:public:iam::::role:Administrator" - ], + "role_crns": ["crn:v1:bluemix:public:iam::::role:Administrator"], "service_name": "is.vpc" }, { @@ -185,7 +189,16 @@ "description": "The prefix to add to all resources that this solution creates. To not use any prefix value, you can enter the string `__NULL__`." }, { - "key": "region" + "key": "region", + "required": true, + "custom_config": { + "config_constraints": { + "generationType": "2" + }, + "grouping": "deployment", + "original_grouping": "deployment", + "type": "vpc_region" + } }, { "key": "existing_resource_group_name", @@ -560,8 +573,8 @@ "reference_version": true }, { - "version_input":"kms_encryption_enabled_bucket", - "value":true + "version_input": "kms_encryption_enabled_bucket", + "value": true } ] }, @@ -595,8 +608,8 @@ "reference_version": true }, { - "version_input":"enable_vpc_flow_logs", - "value":true + "version_input": "enable_vpc_flow_logs", + "value": true } ] } From 7ccf77300a0ed74969b9df9b537befd17c1dcf90 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 24 Mar 2025 14:14:21 +0530 Subject: [PATCH 35/46] update default values for cos bucket --- solutions/fully-configurable/README.md | 4 ++-- solutions/fully-configurable/variables.tf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md index a15ac08d..104d99cd 100644 --- a/solutions/fully-configurable/README.md +++ b/solutions/fully-configurable/README.md @@ -74,13 +74,13 @@ This solution supports provisioning and configuring the following infrastructure | [existing\_flow\_logs\_bucket\_kms\_key\_crn](#input\_existing\_flow\_logs\_bucket\_kms\_key\_crn) | The CRN of the existing root key of key management service (KMS) that is used to encrypt the flow logs Cloud Object Storage bucket. If no value is set for this variable, specify a value for the `existing_kms_instance_crn` variable to create a key ring and key. | `string` | `null` | no | | [existing\_kms\_instance\_crn](#input\_existing\_kms\_instance\_crn) | The CRN of the existing key management service (KMS) that is used to create keys for encrypting the flow logs Cloud Object Storage bucket. Used to create a new KMS key unless an existing key is passed using the `existing_flow_logs_bucket_kms_key_crn` input. | `string` | `null` | no | | [existing\_resource\_group\_name](#input\_existing\_resource\_group\_name) | The name of an existing resource group to provision the resources. | `string` | `"Default"` | no | -| [flow\_logs\_cos\_bucket\_archive\_days](#input\_flow\_logs\_cos\_bucket\_archive\_days) | The number of days before the `archive_type` rule action takes effect for the flow logs cloud object storage bucket. | `number` | `20` | no | +| [flow\_logs\_cos\_bucket\_archive\_days](#input\_flow\_logs\_cos\_bucket\_archive\_days) | The number of days before the `archive_type` rule action takes effect for the flow logs cloud object storage bucket. | `number` | `90` | no | | [flow\_logs\_cos\_bucket\_archive\_type](#input\_flow\_logs\_cos\_bucket\_archive\_type) | The storage class or archive type you want the object to transition to in the flow logs cloud object storage bucket. | `string` | `"Glacier"` | no | | [flow\_logs\_cos\_bucket\_default\_retention\_days](#input\_flow\_logs\_cos\_bucket\_default\_retention\_days) | The number of days that an object can remain unmodified in the flow logs cloud object storage bucket. | `number` | `90` | no | | [flow\_logs\_cos\_bucket\_enable\_object\_versioning](#input\_flow\_logs\_cos\_bucket\_enable\_object\_versioning) | Set it to true if object versioning is enabled so that multiple versions of an object are retained in the flow logs cloud object storage bucket. Cannot be used if `flow_logs_cos_bucket_enable_retention` is true. | `bool` | `false` | no | | [flow\_logs\_cos\_bucket\_enable\_permanent\_retention](#input\_flow\_logs\_cos\_bucket\_enable\_permanent\_retention) | Whether permanent retention status is enabled for the flow logs cloud object storage bucket. [Learn more](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-immutable). | `bool` | `false` | no | | [flow\_logs\_cos\_bucket\_enable\_retention](#input\_flow\_logs\_cos\_bucket\_enable\_retention) | Set to true to enable retention for the flow logs cloud object storage bucket. | `bool` | `false` | no | -| [flow\_logs\_cos\_bucket\_expire\_days](#input\_flow\_logs\_cos\_bucket\_expire\_days) | The number of days before the expire rule action takes effect for the flow logs cloud object storage bucket. | `number` | `365` | no | +| [flow\_logs\_cos\_bucket\_expire\_days](#input\_flow\_logs\_cos\_bucket\_expire\_days) | The number of days before the expire rule action takes effect for the flow logs cloud object storage bucket. | `number` | `366` | no | | [flow\_logs\_cos\_bucket\_maximum\_retention\_days](#input\_flow\_logs\_cos\_bucket\_maximum\_retention\_days) | The maximum number of days that an object can be kept unmodified in the flow logs cloud object storage. | `number` | `350` | no | | [flow\_logs\_cos\_bucket\_minimum\_retention\_days](#input\_flow\_logs\_cos\_bucket\_minimum\_retention\_days) | The minimum number of days that an object must be kept unmodified in the flow logs cloud object storage. | `number` | `90` | no | | [flow\_logs\_cos\_bucket\_name](#input\_flow\_logs\_cos\_bucket\_name) | Name of the Cloud Object Storage bucket to be created to collect VPC flow logs. | `string` | `"flow-logs-bucket"` | no | diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 09fe26c6..64c45c52 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -502,7 +502,7 @@ variable "add_bucket_name_suffix" { variable "flow_logs_cos_bucket_archive_days" { description = "The number of days before the `archive_type` rule action takes effect for the flow logs cloud object storage bucket." type = number - default = 20 + default = 90 } variable "flow_logs_cos_bucket_archive_type" { @@ -514,7 +514,7 @@ variable "flow_logs_cos_bucket_archive_type" { variable "flow_logs_cos_bucket_expire_days" { description = "The number of days before the expire rule action takes effect for the flow logs cloud object storage bucket." type = number - default = 365 + default = 366 } variable "flow_logs_cos_bucket_enable_object_versioning" { From de7dd4398f475003d6944c8603b76fbe9051fd0b Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Mon, 24 Mar 2025 14:47:00 +0530 Subject: [PATCH 36/46] catalog varaible sequence changes --- ibm_catalog.json | 74 ++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 8e6de2d1..5ed8fb1c 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -261,6 +261,15 @@ } ] }, + { + "key": "vpn_gateways" + }, + { + "key": "vpe_gateway_cloud_services" + }, + { + "key": "vpe_gateway_cloud_service_by_crn" + }, { "key": "vpe_gateway_security_group_ids" }, @@ -277,18 +286,9 @@ } ] }, - { - "key": "vpe_gateway_cloud_services" - }, - { - "key": "vpe_gateway_cloud_service_by_crn" - }, { "key": "vpe_gateway_reserved_ips" }, - { - "key": "vpn_gateways" - }, { "key": "default_network_acl_name" }, @@ -333,6 +333,9 @@ } ] }, + { + "key": "existing_cos_instance_crn" + }, { "key": "skip_vpc_cos_iam_auth_policy", "options": [ @@ -346,9 +349,6 @@ } ] }, - { - "key": "existing_cos_instance_crn" - }, { "key": "flow_logs_cos_bucket_name" }, @@ -365,6 +365,12 @@ } ] }, + { + "key": "existing_flow_logs_bucket_kms_key_crn" + }, + { + "key": "existing_kms_instance_crn" + }, { "key": "skip_cos_kms_iam_auth_policy", "options": [ @@ -378,6 +384,25 @@ } ] }, + { + "key": "kms_endpoint_type", + "options": [ + { + "displayname": "private", + "value": "private" + }, + { + "displayname": "public", + "value": "public" + } + ] + }, + { + "key": "kms_key_ring_name" + }, + { + "key": "kms_key_name" + }, { "key": "management_endpoint_type_for_bucket", "options": [ @@ -489,31 +514,6 @@ "value": "false" } ] - }, - { - "key": "existing_flow_logs_bucket_kms_key_crn" - }, - { - "key": "existing_kms_instance_crn" - }, - { - "key": "kms_endpoint_type", - "options": [ - { - "displayname": "private", - "value": "private" - }, - { - "displayname": "public", - "value": "public" - } - ] - }, - { - "key": "kms_key_ring_name" - }, - { - "key": "kms_key_name" } ], "dependencies": [ From 8a158072ea548399c2c4570046fce87651df325b Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Tue, 25 Mar 2025 01:27:17 +0530 Subject: [PATCH 37/46] updated tags variable --- ibm_catalog.json | 6 ++---- solutions/fully-configurable/README.md | 4 ++-- .../catalogValidationValues.json.template | 2 +- solutions/fully-configurable/main.tf | 6 +++--- solutions/fully-configurable/variables.tf | 15 ++++----------- tests/pr_test.go | 8 ++++---- 6 files changed, 16 insertions(+), 25 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 5ed8fb1c..475ff84c 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -299,9 +299,8 @@ "key": "default_routing_table_name" }, { - "key": "resource_tags", + "key": "vpc_instance_resource_tags", "custom_config": { - "type": "array", "grouping": "deployment", "original_grouping": "deployment", "config_constraints": { @@ -310,9 +309,8 @@ } }, { - "key": "access_tags", + "key": "vpc_instance_access_tags", "custom_config": { - "type": "array", "grouping": "deployment", "original_grouping": "deployment", "config_constraints": { diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md index 104d99cd..67c398f5 100644 --- a/solutions/fully-configurable/README.md +++ b/solutions/fully-configurable/README.md @@ -61,7 +61,6 @@ This solution supports provisioning and configuring the following infrastructure | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [access\_tags](#input\_access\_tags) | A list of access tags to apply to the VPC resources created by this solution. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial. | `list(string)` | `[]` | no | | [add\_bucket\_name\_suffix](#input\_add\_bucket\_name\_suffix) | Add a randomly generated suffix that is 4 characters in length, to the name of the newly provisioned Cloud Object Storage bucket. Do not use this suffix if you are passing the existing Cloud Object Storage bucket. To manage the name of the Cloud Object Storage bucket manually, use the `flow_logs_cos_bucket_name` variables. | `bool` | `true` | no | | [address\_prefixes](#input\_address\_prefixes) | The IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#address-prefixes-). |
object({
zone-1 = optional(list(string))
zone-2 = optional(list(string))
zone-3 = optional(list(string))
})
|
{
"zone-1": null,
"zone-2": null,
"zone-3": null
}
| no | | [clean\_default\_security\_group\_acl](#input\_clean\_default\_security\_group\_acl) | Remove all rules from the default VPC security group and VPC ACL (less permissive) | `bool` | `true` | no | @@ -94,12 +93,13 @@ This solution supports provisioning and configuring the following infrastructure | [prefix](#input\_prefix) | Prefix to add to all the resources created by this solution. To not use any prefix value, you can set this value to `null` or an empty string. | `string` | n/a | yes | | [provider\_visibility](#input\_provider\_visibility) | Set the visibility value for the IBM terraform provider. Supported values are `public`, `private`, `public-and-private`. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/guides/custom-service-endpoints). | `string` | `"private"` | no | | [region](#input\_region) | Region to deploy the VPC. | `string` | `"us-south"` | no | -| [resource\_tags](#input\_resource\_tags) | List of tags for the resources created by this solution. | `list(string)` | `[]` | no | | [routes](#input\_routes) | Allows you to specify the next hop for packets based on their destination address. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#routes-). |
list(
object({
name = string
route_direct_link_ingress = optional(bool)
route_transit_gateway_ingress = optional(bool)
route_vpc_zone_ingress = optional(bool)
routes = optional(
list(
object({
action = optional(string)
zone = number
destination = string
next_hop = string
})
))
})
)
| `[]` | no | | [security\_group\_rules](#input\_security\_group\_rules) | A list of security group rules to be added to the default vpc security group (default empty). [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#security-group-rules-). |
list(
object({
name = string
direction = string
remote = optional(string)
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
| `[]` | no | | [skip\_cos\_kms\_iam\_auth\_policy](#input\_skip\_cos\_kms\_iam\_auth\_policy) | To skip creating an IAM authorization policy that allows Cloud Object Storage(COS) to access KMS key. | `bool` | `false` | no | | [skip\_vpc\_cos\_iam\_auth\_policy](#input\_skip\_vpc\_cos\_iam\_auth\_policy) | To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`. Required only if `enable_vpc_flow_logs` is set to true. | `bool` | `false` | no | | [subnets](#input\_subnets) | List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#subnets-). |
object({
zone-1 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
}))
zone-2 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
zone-3 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
})
|
{
"zone-1": [
{
"acl_name": "vpc-acl",
"cidr": "10.10.10.0/24",
"name": "subnet-a",
"no_addr_prefix": false,
"public_gateway": true
}
]
}
| no | +| [vpc\_instance\_access\_tags](#input\_vpc\_instance\_access\_tags) | The list of access tags to add to the VPC instance. | `list(string)` | `[]` | no | +| [vpc\_instance\_resource\_tags](#input\_vpc\_instance\_resource\_tags) | The list of tags to add to the VPC instance. | `list(string)` | `[]` | no | | [vpc\_name](#input\_vpc\_name) | Name of the VPC. If a prefix input variable is specified, the prefix is added to the name in the `-` format. | `string` | `"vpc"` | no | | [vpe\_gateway\_cloud\_service\_by\_crn](#input\_vpe\_gateway\_cloud\_service\_by\_crn) | The list of cloud service CRNs used to create endpoint gateways. Use this list to identify services that are not supported by service name in the `cloud_services` variable. For a list of supported services, see [VPE-enabled services](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). If `service_name` is not specified, the CRN is used to find the name. If `vpe_name` is not specified in the list, VPE names are created in the format `--`. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpe-gateway-cloud-service-by-crn-). |
set(
object({
crn = string
vpe_name = optional(string) # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name.
service_name = optional(string) # Name of the service used to compute the name of the VPE. If not specified, the service name will be obtained from the crn.
allow_dns_resolution_binding = optional(bool, true)
})
)
| `[]` | no | | [vpe\_gateway\_cloud\_services](#input\_vpe\_gateway\_cloud\_services) | The list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names are created in the format `--`. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpe-gateway-cloud-services-). |
set(object({
service_name = string
vpe_name = optional(string), # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name.
allow_dns_resolution_binding = optional(bool, false)
}))
| `[]` | no | diff --git a/solutions/fully-configurable/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template index 92c260d6..9e2a787c 100644 --- a/solutions/fully-configurable/catalogValidationValues.json.template +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -1,7 +1,7 @@ { "ibmcloud_api_key": $VALIDATION_APIKEY, "region": "us-south", - "resource_tags": $TAGS, + "vpc_instance_resource_tags": $TAGS, "existing_resource_group_name": "geretain-test-resources", "prefix": $PREFIX, "enable_vpc_flow_logs": true, diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 97d5be6b..99fcebea 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -35,7 +35,7 @@ locals { # configuration for the flow logs bucket bucket_config = [{ - access_tags = var.access_tags + access_tags = var.vpc_instance_access_tags bucket_name = local.bucket_name add_bucket_name_suffix = var.add_bucket_name_suffix kms_encryption_enabled = var.kms_encryption_enabled_bucket @@ -188,8 +188,8 @@ module "vpc" { create_vpc = true name = var.vpc_name prefix = local.prefix != "" ? trimspace(var.prefix) : null - tags = var.resource_tags - access_tags = var.access_tags + tags = var.vpc_instance_resource_tags + access_tags = var.vpc_instance_access_tags subnets = var.subnets default_network_acl_name = var.default_network_acl_name default_security_group_name = var.default_security_group_name diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index 64c45c52..d933acbf 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -53,23 +53,16 @@ variable "region" { type = string } -variable "resource_tags" { - description = "List of tags for the resources created by this solution." +variable "vpc_instance_resource_tags" { type = list(string) + description = "The list of tags to add to the VPC instance." default = [] } -variable "access_tags" { +variable "vpc_instance_access_tags" { type = list(string) - description = "A list of access tags to apply to the VPC resources created by this solution. For more information, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial." + description = "The list of access tags to add to the VPC instance." default = [] - - validation { - condition = alltrue([ - for tag in var.access_tags : can(regex("[\\w\\-_\\.]+:[\\w\\-_\\.]+", tag)) && length(tag) <= 128 - ]) - error_message = "Tags must match the regular expression \"[\\w\\-_\\.]+:[\\w\\-_\\.]+\". For more information, see https://cloud.ibm.com/docs/account?topic=account-tag&interface=ui#limits." - } } ############################################################################## diff --git a/tests/pr_test.go b/tests/pr_test.go index 9ac8e0de..90432ffd 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -239,8 +239,8 @@ func TestFullyConfigurable(t *testing.T) { {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, {Name: "region", Value: options.Region, DataType: "string"}, - {Name: "resource_tags", Value: options.Tags, DataType: "list(string)"}, - {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, + {Name: "vpc_instance_resource_tags", Value: options.Tags, DataType: "list(string)"}, + {Name: "vpc_instance_access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, {Name: "prefix", Value: options.Prefix, DataType: "string"}, } @@ -283,8 +283,8 @@ func TestRunUpgradeFullyConfigurable(t *testing.T) { {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, {Name: "region", Value: options.Region, DataType: "string"}, - {Name: "resource_tags", Value: options.Tags, DataType: "list(string)"}, - {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, + {Name: "vpc_instance_resource_tags", Value: options.Tags, DataType: "list(string)"}, + {Name: "vpc_instance_access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, {Name: "prefix", Value: options.Prefix, DataType: "string"}, } From b28175287c980625cf85ae8a1395b4fb7096f5d3 Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Tue, 25 Mar 2025 01:53:25 +0530 Subject: [PATCH 38/46] updated boolean variables in catalog --- ibm_catalog.json | 108 ++++------------------------------------------- 1 file changed, 9 insertions(+), 99 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 475ff84c..7f111de8 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -249,17 +249,7 @@ "key": "security_group_rules" }, { - "key": "clean_default_security_group_acl", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "clean_default_security_group_acl" }, { "key": "vpn_gateways" @@ -319,49 +309,19 @@ } }, { - "key": "enable_vpc_flow_logs", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "enable_vpc_flow_logs" }, { "key": "existing_cos_instance_crn" }, { - "key": "skip_vpc_cos_iam_auth_policy", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "skip_vpc_cos_iam_auth_policy" }, { "key": "flow_logs_cos_bucket_name" }, { - "key": "kms_encryption_enabled_bucket", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "kms_encryption_enabled_bucket" }, { "key": "existing_flow_logs_bucket_kms_key_crn" @@ -370,17 +330,7 @@ "key": "existing_kms_instance_crn" }, { - "key": "skip_cos_kms_iam_auth_policy", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "skip_cos_kms_iam_auth_policy" }, { "key": "kms_endpoint_type", @@ -444,17 +394,7 @@ ] }, { - "key": "add_bucket_name_suffix", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "add_bucket_name_suffix" }, { "key": "flow_logs_cos_bucket_archive_days" @@ -466,30 +406,10 @@ "key": "flow_logs_cos_bucket_expire_days" }, { - "key": "flow_logs_cos_bucket_enable_object_versioning", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "flow_logs_cos_bucket_enable_object_versioning" }, { - "key": "flow_logs_cos_bucket_enable_retention", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "flow_logs_cos_bucket_enable_retention" }, { "key": "flow_logs_cos_bucket_default_retention_days" @@ -501,17 +421,7 @@ "key": "flow_logs_cos_bucket_minimum_retention_days" }, { - "key": "flow_logs_cos_bucket_enable_permanent_retention", - "options": [ - { - "displayname": "True", - "value": "true" - }, - { - "displayname": "False", - "value": "false" - } - ] + "key": "flow_logs_cos_bucket_enable_permanent_retention" } ], "dependencies": [ From 7577fea3ca7057bfafd0c0d334e175d541c81007 Mon Sep 17 00:00:00 2001 From: Shikha Maheshwari Date: Tue, 25 Mar 2025 13:30:47 +0530 Subject: [PATCH 39/46] cross-account kms key support --- ibm_catalog.json | 3 ++ solutions/fully-configurable/DA-types.md | 2 +- solutions/fully-configurable/README.md | 5 ++- solutions/fully-configurable/main.tf | 43 ++++++++++++++++------- solutions/fully-configurable/provider.tf | 7 ++++ solutions/fully-configurable/variables.tf | 7 ++++ solutions/fully-configurable/version.tf | 4 +++ 7 files changed, 56 insertions(+), 15 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 7f111de8..49254a74 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -351,6 +351,9 @@ { "key": "kms_key_name" }, + { + "key": "ibmcloud_kms_api_key" + }, { "key": "management_endpoint_type_for_bucket", "options": [ diff --git a/solutions/fully-configurable/DA-types.md b/solutions/fully-configurable/DA-types.md index 915a0809..9d658fc1 100644 --- a/solutions/fully-configurable/DA-types.md +++ b/solutions/fully-configurable/DA-types.md @@ -310,6 +310,6 @@ This variable defines a map of existing reserved IP names and values to attach w ```hcl { - name = "10.10.10.4" + name = "vpe-reserved-ip" } ``` diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md index 67c398f5..53ac0d3f 100644 --- a/solutions/fully-configurable/README.md +++ b/solutions/fully-configurable/README.md @@ -37,6 +37,7 @@ This solution supports provisioning and configuring the following infrastructure |------|---------| | [terraform](#requirement\_terraform) | >= 1.9.0 | | [ibm](#requirement\_ibm) | 1.76.1 | +| [time](#requirement\_time) | 0.13.0 | ### Modules @@ -55,7 +56,8 @@ This solution supports provisioning and configuring the following infrastructure | Name | Type | |------|------| -| [ibm_iam_authorization_policy.cos_kms_iam_auth_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.76.1/docs/resources/iam_authorization_policy) | resource | +| [ibm_iam_authorization_policy.cos_kms_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/1.76.1/docs/resources/iam_authorization_policy) | resource | +| [time_sleep.wait_for_cross_account_authorization_policy](https://registry.terraform.io/providers/hashicorp/time/0.13.0/docs/resources/sleep) | resource | ### Inputs @@ -84,6 +86,7 @@ This solution supports provisioning and configuring the following infrastructure | [flow\_logs\_cos\_bucket\_minimum\_retention\_days](#input\_flow\_logs\_cos\_bucket\_minimum\_retention\_days) | The minimum number of days that an object must be kept unmodified in the flow logs cloud object storage. | `number` | `90` | no | | [flow\_logs\_cos\_bucket\_name](#input\_flow\_logs\_cos\_bucket\_name) | Name of the Cloud Object Storage bucket to be created to collect VPC flow logs. | `string` | `"flow-logs-bucket"` | no | | [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources. | `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. If not specified, the 'ibmcloud\_api\_key' variable is used. Specify this key if the instance in `existing_kms_instance_crn` is in an account that's different from the Cloud Object Storage instance. Leave this input empty if the same account owns both instances. | `string` | `null` | no | | [kms\_encryption\_enabled\_bucket](#input\_kms\_encryption\_enabled\_bucket) | Set to true to encrypt the Cloud Object Storage Flow Logs bucket with a KMS key. If set to true, a value must be passed for existing\_flow\_logs\_bucket\_kms\_key\_crn (to use that key) or existing\_kms\_instance\_crn (to create a new key). Value cannot be set to true if enable\_vpc\_flow\_logs is set to false. | `bool` | `false` | no | | [kms\_endpoint\_type](#input\_kms\_endpoint\_type) | The type of endpoint to use for communicating with the KMS. Possible values: `public`, `private`. Applies only if `existing_flow_logs_bucket_kms_key_crn` is not specified. | `string` | `"private"` | no | | [kms\_key\_name](#input\_kms\_key\_name) | The name of the key to encrypt the flow logs Cloud Object Storage bucket. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key is prefixed to the value in the `-value` format. | `string` | `"flow-logs-cos-key"` | no | diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index 99fcebea..d6b11ca2 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -25,13 +25,15 @@ module "existing_cos_crn_parser" { } locals { - cos_instance_guid = var.existing_cos_instance_crn != null ? module.existing_cos_crn_parser[0].service_instance : null - bucket_name = "${local.prefix}${var.flow_logs_cos_bucket_name}" - kms_guid = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].service_instance : module.existing_kms_instance_crn_parser[0].service_instance) : null - kms_account_id = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].account_id : module.existing_kms_instance_crn_parser[0].account_id) : null - kms_service = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].service_name : module.existing_kms_instance_crn_parser[0].service_name) : null - cos_kms_key_crn = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? var.existing_flow_logs_bucket_kms_key_crn : module.kms[0].keys[format("%s.%s", local.kms_key_ring_name, local.kms_key_name)].crn) : null - create_cos_kms_iam_auth_policy = var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && !var.skip_cos_kms_iam_auth_policy + cos_instance_guid = var.existing_cos_instance_crn != null ? module.existing_cos_crn_parser[0].service_instance : null + cos_account_id = var.existing_cos_instance_crn != null ? module.existing_cos_crn_parser[0].account_id : null + bucket_name = "${local.prefix}${var.flow_logs_cos_bucket_name}" + kms_guid = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].service_instance : module.existing_kms_instance_crn_parser[0].service_instance) : null + kms_account_id = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].account_id : module.existing_kms_instance_crn_parser[0].account_id) : null + kms_service_name = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? module.existing_kms_key_crn_parser[0].service_name : module.existing_kms_instance_crn_parser[0].service_name) : null + cos_kms_key_crn = var.kms_encryption_enabled_bucket ? (length(module.existing_kms_key_crn_parser) > 0 ? var.existing_flow_logs_bucket_kms_key_crn : module.kms[0].keys[format("%s.%s", local.kms_key_ring_name, local.kms_key_name)].crn) : null + create_cos_kms_iam_auth_policy = var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket && !var.skip_cos_kms_iam_auth_policy + create_cross_account_cos_kms_auth_policy = (local.create_cos_kms_iam_auth_policy && var.ibmcloud_kms_api_key == null) ? false : (local.cos_account_id != local.kms_account_id) # configuration for the flow logs bucket bucket_config = [{ @@ -41,7 +43,7 @@ locals { kms_encryption_enabled = var.kms_encryption_enabled_bucket kms_guid = local.kms_guid kms_key_crn = local.cos_kms_key_crn - skip_iam_authorization_policy = var.skip_cos_kms_iam_auth_policy + skip_iam_authorization_policy = local.create_cross_account_cos_kms_auth_policy || var.skip_cos_kms_iam_auth_policy management_endpoint_type = var.management_endpoint_type_for_bucket storage_class = var.cos_bucket_class resource_instance_id = var.existing_cos_instance_crn @@ -69,22 +71,25 @@ locals { # Create COS bucket using the defined bucket configuration module "cos_buckets" { count = var.enable_vpc_flow_logs ? 1 : 0 + depends_on = [time_sleep.wait_for_cross_account_authorization_policy[0]] source = "terraform-ibm-modules/cos/ibm//modules/buckets" version = "8.19.2" bucket_configs = local.bucket_config } -# Create IAM Authorization Policy to allow COS to access KMS for the encryption key -resource "ibm_iam_authorization_policy" "cos_kms_iam_auth_policy" { - count = local.create_cos_kms_iam_auth_policy ? 1 : 0 +# Create IAM Authorization Policy to allow COS to access KMS for the encryption key, if cross account KMS is passed in +resource "ibm_iam_authorization_policy" "cos_kms_policy" { + count = local.create_cross_account_cos_kms_auth_policy ? 1 : 0 + provider = ibm.kms + source_service_account = local.cos_account_id source_service_name = "cloud-object-storage" source_resource_instance_id = local.cos_instance_guid roles = ["Reader"] - description = "Allow the COS instance ${local.cos_instance_guid} to read the ${local.kms_service} key ${local.cos_kms_key_crn} from the instance ${local.kms_guid}" + description = "Allow the COS instance ${local.cos_instance_guid} to read the ${local.kms_service_name} key ${local.cos_kms_key_crn} from the instance ${local.kms_guid}" resource_attributes { name = "serviceName" operator = "stringEquals" - value = local.kms_service + value = local.kms_service_name } resource_attributes { name = "accountId" @@ -113,6 +118,14 @@ resource "ibm_iam_authorization_policy" "cos_kms_iam_auth_policy" { } } +# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478 +resource "time_sleep" "wait_for_cross_account_authorization_policy" { + depends_on = [ibm_iam_authorization_policy.cos_kms_policy] + count = local.create_cross_account_cos_kms_auth_policy ? 1 : 0 + + create_duration = "30s" +} + ####################################################################################################################### # KMS Key ####################################################################################################################### @@ -143,7 +156,11 @@ locals { create_kms_key = (var.enable_vpc_flow_logs && var.kms_encryption_enabled_bucket) ? (var.existing_flow_logs_bucket_kms_key_crn == null ? (var.existing_kms_instance_crn != null ? true : false) : false) : false } +# KMS root key for flow logs COS bucket module "kms" { + providers = { + ibm = ibm.kms + } count = local.create_kms_key ? 1 : 0 # no need to create any KMS resources if not passing an existing KMS CRN or existing KMS key CRN is provided source = "terraform-ibm-modules/kms-all-inclusive/ibm" version = "4.19.5" diff --git a/solutions/fully-configurable/provider.tf b/solutions/fully-configurable/provider.tf index e669b7ba..b97eb3ca 100644 --- a/solutions/fully-configurable/provider.tf +++ b/solutions/fully-configurable/provider.tf @@ -7,3 +7,10 @@ provider "ibm" { region = var.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.kms_region + visibility = var.provider_visibility +} diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index d933acbf..e3b661a6 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -592,6 +592,13 @@ variable "kms_key_name" { description = "The name of the key to encrypt the flow logs Cloud Object Storage bucket. If an existing key is used, this variable is not required. If the prefix input variable is passed, the name of the key is prefixed to the value in the `-value` 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. If not specified, the 'ibmcloud_api_key' variable is used. Specify this key if the instance in `existing_kms_instance_crn` is in an account that's different from the Cloud Object Storage instance. Leave this input empty if the same account owns both instances." + sensitive = true + default = null +} + ############################################################################## # Optional VPC Variables ############################################################################## diff --git a/solutions/fully-configurable/version.tf b/solutions/fully-configurable/version.tf index f1c29e5a..6015f671 100644 --- a/solutions/fully-configurable/version.tf +++ b/solutions/fully-configurable/version.tf @@ -6,5 +6,9 @@ terraform { source = "IBM-Cloud/ibm" version = "1.76.1" } + time = { + source = "hashicorp/time" + version = "0.13.0" + } } } From 324a8199901ca7331baa9c82f7b33ad6701c0007 Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Tue, 25 Mar 2025 13:54:32 +0530 Subject: [PATCH 40/46] updated tags --- ibm_catalog.json | 4 ++-- solutions/fully-configurable/README.md | 4 ++-- .../catalogValidationValues.json.template | 2 +- solutions/fully-configurable/main.tf | 6 +++--- solutions/fully-configurable/variables.tf | 4 ++-- tests/pr_test.go | 8 ++++---- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 49254a74..a402d8cd 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -289,7 +289,7 @@ "key": "default_routing_table_name" }, { - "key": "vpc_instance_resource_tags", + "key": "resource_tags", "custom_config": { "grouping": "deployment", "original_grouping": "deployment", @@ -299,7 +299,7 @@ } }, { - "key": "vpc_instance_access_tags", + "key": "access_tags", "custom_config": { "grouping": "deployment", "original_grouping": "deployment", diff --git a/solutions/fully-configurable/README.md b/solutions/fully-configurable/README.md index 53ac0d3f..4b925bf1 100644 --- a/solutions/fully-configurable/README.md +++ b/solutions/fully-configurable/README.md @@ -63,6 +63,7 @@ This solution supports provisioning and configuring the following infrastructure | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| [access\_tags](#input\_access\_tags) | The list of access tags to add to the VPC instance. | `list(string)` | `[]` | no | | [add\_bucket\_name\_suffix](#input\_add\_bucket\_name\_suffix) | Add a randomly generated suffix that is 4 characters in length, to the name of the newly provisioned Cloud Object Storage bucket. Do not use this suffix if you are passing the existing Cloud Object Storage bucket. To manage the name of the Cloud Object Storage bucket manually, use the `flow_logs_cos_bucket_name` variables. | `bool` | `true` | no | | [address\_prefixes](#input\_address\_prefixes) | The IP range that will be defined for the VPC for a certain location. Use only with manual address prefixes. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#address-prefixes-). |
object({
zone-1 = optional(list(string))
zone-2 = optional(list(string))
zone-3 = optional(list(string))
})
|
{
"zone-1": null,
"zone-2": null,
"zone-3": null
}
| no | | [clean\_default\_security\_group\_acl](#input\_clean\_default\_security\_group\_acl) | Remove all rules from the default VPC security group and VPC ACL (less permissive) | `bool` | `true` | no | @@ -96,13 +97,12 @@ This solution supports provisioning and configuring the following infrastructure | [prefix](#input\_prefix) | Prefix to add to all the resources created by this solution. To not use any prefix value, you can set this value to `null` or an empty string. | `string` | n/a | yes | | [provider\_visibility](#input\_provider\_visibility) | Set the visibility value for the IBM terraform provider. Supported values are `public`, `private`, `public-and-private`. [Learn more](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/guides/custom-service-endpoints). | `string` | `"private"` | no | | [region](#input\_region) | Region to deploy the VPC. | `string` | `"us-south"` | no | +| [resource\_tags](#input\_resource\_tags) | The list of tags to add to the VPC instance. | `list(string)` | `[]` | no | | [routes](#input\_routes) | Allows you to specify the next hop for packets based on their destination address. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#routes-). |
list(
object({
name = string
route_direct_link_ingress = optional(bool)
route_transit_gateway_ingress = optional(bool)
route_vpc_zone_ingress = optional(bool)
routes = optional(
list(
object({
action = optional(string)
zone = number
destination = string
next_hop = string
})
))
})
)
| `[]` | no | | [security\_group\_rules](#input\_security\_group\_rules) | A list of security group rules to be added to the default vpc security group (default empty). [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#security-group-rules-). |
list(
object({
name = string
direction = string
remote = optional(string)
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
| `[]` | no | | [skip\_cos\_kms\_iam\_auth\_policy](#input\_skip\_cos\_kms\_iam\_auth\_policy) | To skip creating an IAM authorization policy that allows Cloud Object Storage(COS) to access KMS key. | `bool` | `false` | no | | [skip\_vpc\_cos\_iam\_auth\_policy](#input\_skip\_vpc\_cos\_iam\_auth\_policy) | To skip creating an IAM authorization policy that allows the VPC to access the Cloud Object Storage, set this variable to `true`. Required only if `enable_vpc_flow_logs` is set to true. | `bool` | `false` | no | | [subnets](#input\_subnets) | List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#subnets-). |
object({
zone-1 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
}))
zone-2 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
zone-3 = optional(list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
no_addr_prefix = optional(bool, false) # do not automatically add address prefix for subnet, overrides other conditions if set to true
subnet_tags = optional(list(string), [])
})))
})
|
{
"zone-1": [
{
"acl_name": "vpc-acl",
"cidr": "10.10.10.0/24",
"name": "subnet-a",
"no_addr_prefix": false,
"public_gateway": true
}
]
}
| no | -| [vpc\_instance\_access\_tags](#input\_vpc\_instance\_access\_tags) | The list of access tags to add to the VPC instance. | `list(string)` | `[]` | no | -| [vpc\_instance\_resource\_tags](#input\_vpc\_instance\_resource\_tags) | The list of tags to add to the VPC instance. | `list(string)` | `[]` | no | | [vpc\_name](#input\_vpc\_name) | Name of the VPC. If a prefix input variable is specified, the prefix is added to the name in the `-` format. | `string` | `"vpc"` | no | | [vpe\_gateway\_cloud\_service\_by\_crn](#input\_vpe\_gateway\_cloud\_service\_by\_crn) | The list of cloud service CRNs used to create endpoint gateways. Use this list to identify services that are not supported by service name in the `cloud_services` variable. For a list of supported services, see [VPE-enabled services](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). If `service_name` is not specified, the CRN is used to find the name. If `vpe_name` is not specified in the list, VPE names are created in the format `--`. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpe-gateway-cloud-service-by-crn-). |
set(
object({
crn = string
vpe_name = optional(string) # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name.
service_name = optional(string) # Name of the service used to compute the name of the VPE. If not specified, the service name will be obtained from the crn.
allow_dns_resolution_binding = optional(bool, true)
})
)
| `[]` | no | | [vpe\_gateway\_cloud\_services](#input\_vpe\_gateway\_cloud\_services) | The list of cloud services used to create endpoint gateways. If `vpe_name` is not specified in the list, VPE names are created in the format `--`. [Learn more](https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/DA-types.md#vpe-gateway-cloud-services-). |
set(object({
service_name = string
vpe_name = optional(string), # Full control on the VPE name. If not specified, the VPE name will be computed based on prefix, vpc name and service name.
allow_dns_resolution_binding = optional(bool, false)
}))
| `[]` | no | diff --git a/solutions/fully-configurable/catalogValidationValues.json.template b/solutions/fully-configurable/catalogValidationValues.json.template index 9e2a787c..92c260d6 100644 --- a/solutions/fully-configurable/catalogValidationValues.json.template +++ b/solutions/fully-configurable/catalogValidationValues.json.template @@ -1,7 +1,7 @@ { "ibmcloud_api_key": $VALIDATION_APIKEY, "region": "us-south", - "vpc_instance_resource_tags": $TAGS, + "resource_tags": $TAGS, "existing_resource_group_name": "geretain-test-resources", "prefix": $PREFIX, "enable_vpc_flow_logs": true, diff --git a/solutions/fully-configurable/main.tf b/solutions/fully-configurable/main.tf index d6b11ca2..1bd22a76 100644 --- a/solutions/fully-configurable/main.tf +++ b/solutions/fully-configurable/main.tf @@ -37,7 +37,7 @@ locals { # configuration for the flow logs bucket bucket_config = [{ - access_tags = var.vpc_instance_access_tags + access_tags = var.access_tags bucket_name = local.bucket_name add_bucket_name_suffix = var.add_bucket_name_suffix kms_encryption_enabled = var.kms_encryption_enabled_bucket @@ -205,8 +205,8 @@ module "vpc" { create_vpc = true name = var.vpc_name prefix = local.prefix != "" ? trimspace(var.prefix) : null - tags = var.vpc_instance_resource_tags - access_tags = var.vpc_instance_access_tags + tags = var.resource_tags + access_tags = var.access_tags subnets = var.subnets default_network_acl_name = var.default_network_acl_name default_security_group_name = var.default_security_group_name diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index e3b661a6..c79e1823 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -53,13 +53,13 @@ variable "region" { type = string } -variable "vpc_instance_resource_tags" { +variable "resource_tags" { type = list(string) description = "The list of tags to add to the VPC instance." default = [] } -variable "vpc_instance_access_tags" { +variable "access_tags" { type = list(string) description = "The list of access tags to add to the VPC instance." default = [] diff --git a/tests/pr_test.go b/tests/pr_test.go index 90432ffd..9ac8e0de 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -239,8 +239,8 @@ func TestFullyConfigurable(t *testing.T) { {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, {Name: "region", Value: options.Region, DataType: "string"}, - {Name: "vpc_instance_resource_tags", Value: options.Tags, DataType: "list(string)"}, - {Name: "vpc_instance_access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, + {Name: "resource_tags", Value: options.Tags, DataType: "list(string)"}, + {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, {Name: "prefix", Value: options.Prefix, DataType: "string"}, } @@ -283,8 +283,8 @@ func TestRunUpgradeFullyConfigurable(t *testing.T) { {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true}, {Name: "existing_resource_group_name", Value: resourceGroup, DataType: "string"}, {Name: "region", Value: options.Region, DataType: "string"}, - {Name: "vpc_instance_resource_tags", Value: options.Tags, DataType: "list(string)"}, - {Name: "vpc_instance_access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, + {Name: "resource_tags", Value: options.Tags, DataType: "list(string)"}, + {Name: "access_tags", Value: permanentResources["accessTags"], DataType: "list(string)"}, {Name: "prefix", Value: options.Prefix, DataType: "string"}, } From 577a22390b552beb1c75e2c0c91a5f4605144991 Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Tue, 25 Mar 2025 17:45:31 +0530 Subject: [PATCH 41/46] resolve catalog review comments --- .catalog-onboard-pipeline.yaml | 3 ++- ibm_catalog.json | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index 019a251f..f67c38ef 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -4,7 +4,7 @@ offerings: - name: deploy-arch-ibm-vpc kind: solution catalog_id: f64499c8-eb50-4985-bf91-29f9e605a433 - offering_id: ae881fc1-273f-472e-8437-99099a6a753b + offering_id: 2af61763-f8ef-4527-a815-b92166f29bc8 include_git_submodules: true variations: - name: fully-configurable @@ -12,3 +12,4 @@ offerings: install_type: fullstack scc: instance_id: 1c7d5f78-9262-44c3-b779-b28fe4d88c37 + region: us-south diff --git a/ibm_catalog.json b/ibm_catalog.json index a402d8cd..686de37e 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -19,8 +19,8 @@ "infrastructure as code", "solution" ], - "short_description": "Provisions a VPC network on IBM Cloud", - "long_description": "The VPC deployable architecture deploys a Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters.", + "short_description": "Automates VPC deployment on IBM Cloud, offering full configurability and flexibility for diverse workloads.", + "long_description": "The VPC deployable architecture deploys a Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters.This is an experimental tile and not suitable for production workloads. Stay here if you want to try an experimental version with the Optional and swappable components capability.", "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/README.md", "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/images/vpc_icon.svg", "provider_name": "IBM", @@ -81,7 +81,7 @@ "install_type": "fullstack", "working_directory": "solutions/fully-configurable", "architecture": { - "descriptions": "This architecture creates a VPC.", + "descriptions": "This architecture supports provisioning and configuring fully configurable Virtual Private Cloud.", "features": [ { "title": "Create VPC", @@ -147,11 +147,11 @@ "diagrams": [ { "diagram": { - "caption": "VPC for IBM Cloud.", + "caption": "Architecture for provisioning and configuring fully configurable Virtual Private Cloud..", "url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/reference-architecture/deployable-architecture-vpc.svg", "type": "image/svg+xml" }, - "description": "This architecture creates a VPC." + "description": "This architecture supports provisioning and configuring fully configurable Virtual Private Cloud." } ] }, From 3742a09a753ff8ce9e63364b58b97faf8b3ccbe2 Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Tue, 25 Mar 2025 18:40:38 +0530 Subject: [PATCH 42/46] resolve review comments --- ibm_catalog.json | 12 +++++++++++- solutions/fully-configurable/variables.tf | 4 ++++ tests/pr_test.go | 4 ++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 686de37e..5dcee653 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -403,7 +403,17 @@ "key": "flow_logs_cos_bucket_archive_days" }, { - "key": "flow_logs_cos_bucket_archive_type" + "key": "flow_logs_cos_bucket_archive_type", + "options": [ + { + "displayname": "Glacier", + "value": "Glacier" + }, + { + "displayname": "Accelerated", + "value": "Accelerated" + } + ] }, { "key": "flow_logs_cos_bucket_expire_days" diff --git a/solutions/fully-configurable/variables.tf b/solutions/fully-configurable/variables.tf index c79e1823..bef9415d 100644 --- a/solutions/fully-configurable/variables.tf +++ b/solutions/fully-configurable/variables.tf @@ -502,6 +502,10 @@ variable "flow_logs_cos_bucket_archive_type" { description = "The storage class or archive type you want the object to transition to in the flow logs cloud object storage bucket." type = string default = "Glacier" + validation { + condition = contains(["Glacier", "Accelerated"], var.flow_logs_cos_bucket_archive_type) + error_message = "The specified flow_logs_cos_bucket_archive_type is not a valid selection!" + } } variable "flow_logs_cos_bucket_expire_days" { diff --git a/tests/pr_test.go b/tests/pr_test.go index 9ac8e0de..b935b54e 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -232,7 +232,7 @@ func TestFullyConfigurable(t *testing.T) { TemplateFolder: fullyConfigFlavorDir, Tags: []string{"vpc-da-test"}, DeleteWorkspaceOnFail: false, - WaitJobCompleteMinutes: 60, + WaitJobCompleteMinutes: 120, }) options.TerraformVars = []testschematic.TestSchematicTerraformVar{ @@ -276,7 +276,7 @@ func TestRunUpgradeFullyConfigurable(t *testing.T) { TemplateFolder: fullyConfigFlavorDir, Tags: []string{"vpc-da-test"}, DeleteWorkspaceOnFail: false, - WaitJobCompleteMinutes: 60, + WaitJobCompleteMinutes: 120, }) options.TerraformVars = []testschematic.TestSchematicTerraformVar{ From 3bde6bee20841913d3c17575c00748f756a94b1e Mon Sep 17 00:00:00 2001 From: Khuzaima-Shakeel Date: Tue, 25 Mar 2025 20:43:28 +0530 Subject: [PATCH 43/46] updated long description --- ibm_catalog.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index 5dcee653..b794e720 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -20,7 +20,7 @@ "solution" ], "short_description": "Automates VPC deployment on IBM Cloud, offering full configurability and flexibility for diverse workloads.", - "long_description": "The VPC deployable architecture deploys a Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters.This is an experimental tile and not suitable for production workloads. Stay here if you want to try an experimental version with the Optional and swappable components capability.", + "long_description": "The VPC deployable architecture deploys a Virtual Private Cloud (VPC) infrastructure without any compute resources, such as Virtual Server Instances (VSI) or Red Hat OpenShift clusters. This is an experimental tile and not suitable for production workloads. Stay here if you want to try an experimental version with the [Optional and swappable components](https://cloud.ibm.com/docs/secure-enterprise?topic=secure-enterprise-choose-plan-process#optional-swappable) capability.", "offering_docs_url": "https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/blob/main/solutions/fully-configurable/README.md", "offering_icon_url": "https://raw.githubusercontent.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc/main/images/vpc_icon.svg", "provider_name": "IBM", From cb581ba7019aad20837f98cc54ed8fd7e4313b56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Conall=20=C3=93=20Cofaigh?= Date: Wed, 26 Mar 2025 14:54:09 +0000 Subject: [PATCH 44/46] Update .releaserc --- .releaserc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.releaserc b/.releaserc index 708916f7..4160e575 100644 --- a/.releaserc +++ b/.releaserc @@ -10,6 +10,9 @@ }], ["@semantic-release/exec", { "successCmd": "echo \"SEMVER_VERSION=${nextRelease.version}\" >> $GITHUB_ENV" + }], + ["@semantic-release/exec",{ + "publishCmd": "./ci/trigger-catalog-onboarding-pipeline.sh --version=v${nextRelease.version}" }] ] } From 23c9d303a292fa9cc6536d68072a3bc93891cc6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Conall=20=C3=93=20Cofaigh?= Date: Wed, 26 Mar 2025 15:00:09 +0000 Subject: [PATCH 45/46] Update .catalog-onboard-pipeline.yaml --- .catalog-onboard-pipeline.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.catalog-onboard-pipeline.yaml b/.catalog-onboard-pipeline.yaml index f67c38ef..66e3a232 100644 --- a/.catalog-onboard-pipeline.yaml +++ b/.catalog-onboard-pipeline.yaml @@ -13,3 +13,4 @@ offerings: scc: instance_id: 1c7d5f78-9262-44c3-b779-b28fe4d88c37 region: us-south + scope_resource_group_var_name: existing_resource_group_name From 521e61ffc662d9cf68be618f03b5cfbe66d5eb93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Conall=20=C3=93=20Cofaigh?= Date: Wed, 26 Mar 2025 15:06:17 +0000 Subject: [PATCH 46/46] Update ibm_catalog.json --- ibm_catalog.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ibm_catalog.json b/ibm_catalog.json index b794e720..2bde293a 100644 --- a/ibm_catalog.json +++ b/ibm_catalog.json @@ -5,12 +5,13 @@ "label": "[Add-ons Beta] Cloud automation for VPC", "product_kind": "solution", "tags": [ + "network", "network_vpc", "ibm_created", "target_terraform", "terraform", - "support_ibm", - "solution" + "solution", + "ibm_beta" ], "keywords": [ "vpc",