From 2ee0f7c599bb83a8dbcf4fed6e27b536624f687e Mon Sep 17 00:00:00 2001 From: rajatagarwal-ibm <108140212+rajatagarwal-ibm@users.noreply.github.com> Date: Wed, 27 Sep 2023 20:04:41 +0100 Subject: [PATCH] feat: Updated the naming of VSIs provisioned by this module. If upgrading from a previous version be aware that your VSI will be renamed non-disruptively. For example a VSI named `my-vsi-1` will now be renamed to `my-vsi-001` (#536) --- README.md | 3 +- examples/basic/main.tf | 25 +++---- examples/complete/README.md | 10 +++ examples/complete/main.tf | 125 +++++++++++++++++++++++++++++++++ examples/complete/outputs.tf | 9 +++ examples/complete/provider.tf | 4 ++ examples/complete/variables.tf | 47 +++++++++++++ examples/complete/version.tf | 13 ++++ examples/fscloud/main.tf | 23 +++--- examples/fscloud/variables.tf | 2 +- load_balancer.tf | 1 + main.tf | 9 ++- module-metadata.json | 32 ++++----- profiles/fscloud/README.md | 2 +- profiles/fscloud/variables.tf | 113 ++--------------------------- tests/other_test.go | 13 +--- tests/pr_test.go | 35 +++++++-- variables.tf | 7 ++ 18 files changed, 302 insertions(+), 171 deletions(-) create mode 100644 examples/complete/README.md create mode 100644 examples/complete/main.tf create mode 100644 examples/complete/outputs.tf create mode 100644 examples/complete/provider.tf create mode 100644 examples/complete/variables.tf create mode 100644 examples/complete/version.tf diff --git a/README.md b/README.md index 1adf6507..1b8dedb5 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,7 @@ You need the following permissions to run this module. ## Examples - [ End to end basic example](examples/basic) +- [ Complete Example using a placement group, attaching a load balancer, and adding additional data volumes](examples/complete) - [ Financial Services Cloud profile example](examples/fscloud) @@ -155,7 +156,7 @@ No modules. | [existing\_kms\_instance\_guid](#input\_existing\_kms\_instance\_guid) | The GUID of the Hyper Protect Crypto Services instance in which the key specified in var.boot\_volume\_encryption\_key is coming from. | `string` | `null` | no | | [image\_id](#input\_image\_id) | Image ID used for VSI. Run 'ibmcloud is images' to find available images in a region | `string` | n/a | yes | | [kms\_encryption\_enabled](#input\_kms\_encryption\_enabled) | Set this to true to control the encryption keys used to encrypt the data that for the block storage volumes for VPC. If set to false, the data is encrypted by using randomly generated keys. For more info on encrypting block storage volumes, see https://cloud.ibm.com/docs/vpc?topic=vpc-creating-instances-byok | `bool` | `false` | no | -| [load\_balancers](#input\_load\_balancers) | Load balancers to add to VSI |
list(| `[]` | no | +| [load\_balancers](#input\_load\_balancers) | Load balancers to add to VSI |
object({
name = string
type = string
listener_port = number
listener_protocol = string
connection_limit = number
algorithm = string
protocol = string
health_delay = number
health_retries = number
health_timeout = number
health_type = string
pool_member_port = string
security_group = optional(
object({
name = string
rules = list(
object({
name = string
direction = string
source = string
tcp = optional(
object({
port_max = number
port_min = number
})
)
udp = optional(
object({
port_max = number
port_min = number
})
)
icmp = optional(
object({
type = number
code = number
})
)
})
)
})
)
})
)
list(| `[]` | no | | [machine\_type](#input\_machine\_type) | VSI machine type. Run 'ibmcloud is instance-profiles' to get a list of regional profiles | `string` | n/a | yes | | [placement\_group\_id](#input\_placement\_group\_id) | Unique Identifier of the Placement Group for restricting the placement of the instance, default behaviour is placement on any host | `string` | `null` | no | | [prefix](#input\_prefix) | The IBM Cloud platform API key needed to deploy IAM enabled resources | `string` | n/a | yes | diff --git a/examples/basic/main.tf b/examples/basic/main.tf index 5bf14e7e..ae6c146e 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -3,24 +3,19 @@ ############################################################################## locals { - resource_group_id = var.resource_group != null ? data.ibm_resource_group.existing_resource_group[0].id : ibm_resource_group.resource_group[0].id - ssh_key_id = var.ssh_key != null ? data.ibm_is_ssh_key.existing_ssh_key[0].id : resource.ibm_is_ssh_key.ssh_key[0].id + ssh_key_id = var.ssh_key != null ? data.ibm_is_ssh_key.existing_ssh_key[0].id : resource.ibm_is_ssh_key.ssh_key[0].id } ############################################################################## # Resource Group -# (if var.resource_group is null, create a new RG using var.prefix) ############################################################################## -resource "ibm_resource_group" "resource_group" { - count = var.resource_group != null ? 0 : 1 - name = "${var.prefix}-rg" - quota_id = null -} - -data "ibm_resource_group" "existing_resource_group" { - count = var.resource_group != null ? 1 : 0 - name = var.resource_group +module "resource_group" { + source = "terraform-ibm-modules/resource-group/ibm" + version = "1.0.6" + # if an existing resource group is not set (null) create a new one using prefix + resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null + existing_resource_group_name = var.resource_group } ############################################################################## @@ -51,7 +46,7 @@ data "ibm_is_ssh_key" "existing_ssh_key" { module "slz_vpc" { source = "terraform-ibm-modules/landing-zone-vpc/ibm" version = "7.5.0" - resource_group_id = local.resource_group_id + resource_group_id = module.resource_group.resource_group_id region = var.region prefix = var.prefix tags = var.resource_tags @@ -64,7 +59,7 @@ module "slz_vpc" { resource "ibm_is_placement_group" "placement_group" { name = "${var.prefix}-host-spread" - resource_group = local.resource_group_id + resource_group = module.resource_group.resource_group_id strategy = "host_spread" tags = var.resource_tags } @@ -75,7 +70,7 @@ resource "ibm_is_placement_group" "placement_group" { module "slz_vsi" { source = "../../" - resource_group_id = local.resource_group_id + resource_group_id = module.resource_group.resource_group_id image_id = var.image_id create_security_group = var.create_security_group security_group = var.security_group diff --git a/examples/complete/README.md b/examples/complete/README.md new file mode 100644 index 00000000..b23fc8d3 --- /dev/null +++ b/examples/complete/README.md @@ -0,0 +1,10 @@ +# Complete Example using a placement group, attaching a load balancer, and adding additional data volumes + +It will provision the following: + +- A new resource group if one is not passed in. +- A new public SSH key if one is not passed in. +- A new VPC with 3 subnets. +- A new placement group. +- A VSI in each subnet placed in the placement group. +- A new Application Load Balancer to balance traffic between all virtual servers that are created by this example. diff --git a/examples/complete/main.tf b/examples/complete/main.tf new file mode 100644 index 00000000..79047e4f --- /dev/null +++ b/examples/complete/main.tf @@ -0,0 +1,125 @@ +############################################################################## +# Locals +############################################################################## + +locals { + ssh_key_id = var.ssh_key != null ? data.ibm_is_ssh_key.existing_ssh_key[0].id : resource.ibm_is_ssh_key.ssh_key[0].id +} + +############################################################################## +# Resource Group +############################################################################## + +module "resource_group" { + source = "terraform-ibm-modules/resource-group/ibm" + version = "1.0.6" + # if an existing resource group is not set (null) create a new one using prefix + resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null + existing_resource_group_name = var.resource_group +} + +############################################################################## +# Key Protect All Inclusive +############################################################################## + +module "key_protect_all_inclusive" { + source = "terraform-ibm-modules/key-protect-all-inclusive/ibm" + version = "4.2.0" + resource_group_id = module.resource_group.resource_group_id + region = var.region + key_protect_instance_name = "${var.prefix}-kp" + resource_tags = var.resource_tags + key_map = { "slz-vsi" = ["${var.prefix}-vsi"] } +} + +############################################################################## +# Create new SSH key +############################################################################## + +resource "tls_private_key" "tls_key" { + count = var.ssh_key != null ? 0 : 1 + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "ibm_is_ssh_key" "ssh_key" { + count = var.ssh_key != null ? 0 : 1 + name = "${var.prefix}-ssh-key" + public_key = resource.tls_private_key.tls_key[0].public_key_openssh +} + +data "ibm_is_ssh_key" "existing_ssh_key" { + count = var.ssh_key != null ? 1 : 0 + name = var.ssh_key +} + +############################################################################# +# Provision VPC +############################################################################# + +module "slz_vpc" { + source = "terraform-ibm-modules/landing-zone-vpc/ibm" + version = "7.5.0" + resource_group_id = module.resource_group.resource_group_id + region = var.region + prefix = var.prefix + tags = var.resource_tags + name = "${var.prefix}-vpc" +} + +############################################################################# +# Placement group +############################################################################# + +resource "ibm_is_placement_group" "placement_group" { + name = "${var.prefix}-host-spread" + resource_group = module.resource_group.resource_group_id + strategy = "host_spread" + tags = var.resource_tags +} + +############################################################################# +# Provision VSI +############################################################################# + +module "slz_vsi" { + source = "../../" + resource_group_id = module.resource_group.resource_group_id + image_id = var.image_id + create_security_group = false + tags = var.resource_tags + access_tags = var.access_tags + subnets = module.slz_vpc.subnet_zone_list + vpc_id = module.slz_vpc.vpc_id + prefix = var.prefix + placement_group_id = ibm_is_placement_group.placement_group.id + machine_type = "cx2-2x4" + user_data = null + boot_volume_encryption_key = module.key_protect_all_inclusive.keys["slz-vsi.${var.prefix}-vsi"].crn + kms_encryption_enabled = true + existing_kms_instance_guid = module.key_protect_all_inclusive.key_protect_guid + vsi_per_subnet = 1 + ssh_key_ids = [local.ssh_key_id] + # Add 1 additional data volume to each VSI + block_storage_volumes = [ + { + name = var.prefix + profile = "10iops-tier" + }] + load_balancers = [ + { + name = "${var.prefix}-lb" + type = "public" + listener_port = 9080 + listener_protocol = "http" + connection_limit = 100 + algorithm = "round_robin" + protocol = "http" + health_delay = 60 + health_retries = 5 + health_timeout = 30 + health_type = "http" + pool_member_port = 8080 + } + ] +} diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf new file mode 100644 index 00000000..b18b60a3 --- /dev/null +++ b/examples/complete/outputs.tf @@ -0,0 +1,9 @@ +output "slz_vpc" { + value = module.slz_vpc + description = "VPC module values" +} + +output "slz_vsi" { + value = module.slz_vsi + description = "VSI module values" +} diff --git a/examples/complete/provider.tf b/examples/complete/provider.tf new file mode 100644 index 00000000..df45ef50 --- /dev/null +++ b/examples/complete/provider.tf @@ -0,0 +1,4 @@ +provider "ibm" { + ibmcloud_api_key = var.ibmcloud_api_key + region = var.region +} diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf new file mode 100644 index 00000000..64b6458f --- /dev/null +++ b/examples/complete/variables.tf @@ -0,0 +1,47 @@ +variable "ibmcloud_api_key" { + description = "APIkey that's associated with the account to provision resources to" + type = string + sensitive = true +} + +variable "resource_group" { + type = string + description = "An existing resource group name to use for this example, if unset a new resource group will be created" + default = null +} + +variable "region" { + description = "The region to which to deploy all resources in this example" + type = string + default = "us-south" +} + +variable "prefix" { + description = "The prefix that you would like to append to your resources" + type = string + default = "slz-vsi-com" +} + +variable "resource_tags" { + description = "List of Tags for the resource created" + type = list(string) + default = null +} + +variable "access_tags" { + type = list(string) + description = "A list of access tags to apply to the VSI resources created by the module." + default = [] +} + +variable "image_id" { + description = "Image ID used for VSI. Run 'ibmcloud is images' to find available images. Be aware that region is important for the image since the id's are different in each region." + type = string + default = "r006-1366d3e6-bf5b-49a0-b69a-8efd93cc225f" +} + +variable "ssh_key" { + type = string + description = "An existing ssh key name to use for this example, if unset a new ssh key will be created" + default = null +} diff --git a/examples/complete/version.tf b/examples/complete/version.tf new file mode 100644 index 00000000..ad1abc9d --- /dev/null +++ b/examples/complete/version.tf @@ -0,0 +1,13 @@ +terraform { + required_version = ">= 1.3.0" + required_providers { + ibm = { + source = "IBM-Cloud/ibm" + version = ">= 1.54.0" + } + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + } +} diff --git a/examples/fscloud/main.tf b/examples/fscloud/main.tf index cf0590db..4d751229 100644 --- a/examples/fscloud/main.tf +++ b/examples/fscloud/main.tf @@ -3,24 +3,19 @@ ############################################################################## locals { - resource_group_id = var.resource_group != null ? data.ibm_resource_group.existing_resource_group[0].id : ibm_resource_group.resource_group[0].id - ssh_key_id = var.ssh_key != null ? data.ibm_is_ssh_key.existing_ssh_key[0].id : ibm_is_ssh_key.ssh_key[0].id + ssh_key_id = var.ssh_key != null ? data.ibm_is_ssh_key.existing_ssh_key[0].id : ibm_is_ssh_key.ssh_key[0].id } ############################################################################## # Resource Group -# (if var.resource_group is null, create a new RG using var.prefix) ############################################################################## -resource "ibm_resource_group" "resource_group" { - count = var.resource_group != null ? 0 : 1 - name = "${var.prefix}-rg" - quota_id = null -} - -data "ibm_resource_group" "existing_resource_group" { - count = var.resource_group != null ? 1 : 0 - name = var.resource_group +module "resource_group" { + source = "terraform-ibm-modules/resource-group/ibm" + version = "1.0.6" + # if an existing resource group is not set (null) create a new one using prefix + resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null + existing_resource_group_name = var.resource_group } ############################################################################## @@ -50,7 +45,7 @@ data "ibm_is_ssh_key" "existing_ssh_key" { module "slz_vpc" { source = "terraform-ibm-modules/landing-zone-vpc/ibm" version = "7.5.0" - resource_group_id = local.resource_group_id + resource_group_id = module.resource_group.resource_group_id region = var.region prefix = var.prefix tags = var.resource_tags @@ -63,7 +58,7 @@ module "slz_vpc" { module "slz_vsi" { source = "../../profiles/fscloud" - resource_group_id = local.resource_group_id + resource_group_id = module.resource_group.resource_group_id image_id = var.image_id create_security_group = var.create_security_group security_group = var.security_group diff --git a/examples/fscloud/variables.tf b/examples/fscloud/variables.tf index 68d4c71e..f34d55f1 100644 --- a/examples/fscloud/variables.tf +++ b/examples/fscloud/variables.tf @@ -19,7 +19,7 @@ variable "region" { variable "prefix" { description = "The prefix that you would like to append to your resources" type = string - default = "rajat-fs-vsi" + default = "slz-fs-vsi" } variable "resource_tags" { diff --git a/load_balancer.tf b/load_balancer.tf index 8c3fafad..20f74220 100644 --- a/load_balancer.tf +++ b/load_balancer.tf @@ -14,6 +14,7 @@ resource "ibm_is_lb" "lb" { name = "${var.prefix}-${each.value.name}-lb" subnets = var.subnets[*].id type = each.value.type + profile = each.value.profile security_groups = each.value.security_group == null ? null : [ibm_is_security_group.security_group[each.value.security_group.name].id] resource_group = var.resource_group_id tags = var.tags diff --git a/main.tf b/main.tf index 28e83380..416ea3c1 100644 --- a/main.tf +++ b/main.tf @@ -6,6 +6,13 @@ locals { validate_kms_vars = var.kms_encryption_enabled && var.boot_volume_encryption_key == null ? tobool("When setting var.kms_encryption_enabled to true, a value must be passed for var.boot_volume_encryption_key") : true # tflint-ignore: terraform_unused_declarations validate_auth_policy = var.kms_encryption_enabled && var.skip_iam_authorization_policy == false && var.existing_kms_instance_guid == null ? tobool("When var.skip_iam_authorization_policy is set to false, and var.kms_encryption_enabled to true, a value must be passed for var.existing_kms_instance_guid in order to create the auth policy.") : true + + # Determine what KMS service is being used for database encryption + kms_service = var.boot_volume_encryption_key != null ? ( + can(regex(".*kms.*", var.boot_volume_encryption_key)) ? "kms" : ( + can(regex(".*hs-crypto.*", var.boot_volume_encryption_key)) ? "hs-crypto" : null + ) + ) : null } ############################################################################## @@ -87,7 +94,7 @@ locals { resource "ibm_iam_authorization_policy" "block_storage_policy" { count = var.kms_encryption_enabled == false || var.skip_iam_authorization_policy ? 0 : 1 source_service_name = "server-protect" - target_service_name = "hs-crypto" + target_service_name = local.kms_service target_resource_instance_id = var.existing_kms_instance_guid roles = ["Reader"] description = "Allow block storage volumes to be encrypted by Key Management instance." diff --git a/module-metadata.json b/module-metadata.json index cfdec91c..8f1d4641 100644 --- a/module-metadata.json +++ b/module-metadata.json @@ -122,7 +122,7 @@ }, "load_balancers": { "name": "load_balancers", - "type": "list(\n object({\n name = string\n type = string\n listener_port = number\n listener_protocol = string\n connection_limit = number\n algorithm = string\n protocol = string\n health_delay = number\n health_retries = number\n health_timeout = number\n health_type = string\n pool_member_port = string\n security_group = optional(\n object({\n name = string\n rules = list(\n object({\n name = string\n direction = string\n source = string\n tcp = optional(\n object({\n port_max = number\n port_min = number\n })\n )\n udp = optional(\n object({\n port_max = number\n port_min = number\n })\n )\n icmp = optional(\n object({\n type = number\n code = number\n })\n )\n })\n )\n })\n )\n })\n )", + "type": "list(\n object({\n name = string\n type = string\n listener_port = number\n listener_protocol = string\n connection_limit = number\n algorithm = string\n protocol = string\n health_delay = number\n health_retries = number\n health_timeout = number\n health_type = string\n pool_member_port = string\n profile = optional(string)\n dns = optional(\n object({\n instance_crn = string\n zone_id = string\n })\n )\n security_group = optional(\n object({\n name = string\n rules = list(\n object({\n name = string\n direction = string\n source = string\n tcp = optional(\n object({\n port_max = number\n port_min = number\n })\n )\n udp = optional(\n object({\n port_max = number\n port_min = number\n })\n )\n icmp = optional(\n object({\n type = number\n code = number\n })\n )\n })\n )\n })\n )\n })\n )", "description": "Load balancers to add to VSI", "default": [], "pos": { @@ -199,7 +199,7 @@ "default": false, "pos": { "filename": "variables.tf", - "line": 398 + "line": 405 } }, "secondary_floating_ips": { @@ -212,7 +212,7 @@ ], "pos": { "filename": "variables.tf", - "line": 387 + "line": 394 } }, "secondary_security_groups": { @@ -222,7 +222,7 @@ "default": [], "pos": { "filename": "variables.tf", - "line": 366 + "line": 373 } }, "secondary_subnets": { @@ -232,7 +232,7 @@ "default": [], "pos": { "filename": "variables.tf", - "line": 347 + "line": 354 } }, "secondary_use_vsi_security_group": { @@ -242,7 +242,7 @@ "default": false, "pos": { "filename": "variables.tf", - "line": 360 + "line": 367 } }, "security_group": { @@ -451,7 +451,7 @@ }, "pos": { "filename": "main.tf", - "line": 87 + "line": 94 } }, "ibm_is_floating_ip.secondary_fip": { @@ -468,7 +468,7 @@ }, "pos": { "filename": "main.tf", - "line": 164 + "line": 171 } }, "ibm_is_floating_ip.vsi_fip": { @@ -485,7 +485,7 @@ }, "pos": { "filename": "main.tf", - "line": 156 + "line": 163 } }, "ibm_is_instance.vsi": { @@ -509,7 +509,7 @@ }, "pos": { "filename": "main.tf", - "line": 96 + "line": 103 } }, "ibm_is_lb.lb": { @@ -540,7 +540,7 @@ }, "pos": { "filename": "load_balancer.tf", - "line": 81 + "line": 82 } }, "ibm_is_lb_pool.pool": { @@ -555,7 +555,7 @@ }, "pos": { "filename": "load_balancer.tf", - "line": 30 + "line": 31 } }, "ibm_is_lb_pool_member.pool_members": { @@ -567,7 +567,7 @@ }, "pos": { "filename": "load_balancer.tf", - "line": 65 + "line": 66 } }, "ibm_is_security_group.security_group": { @@ -625,7 +625,7 @@ }, "pos": { "filename": "main.tf", - "line": 55 + "line": 62 } } }, @@ -639,7 +639,7 @@ }, "pos": { "filename": "main.tf", - "line": 71 + "line": 78 } }, "data.ibm_is_vpcs.vpcs": { @@ -654,7 +654,7 @@ }, "pos": { "filename": "main.tf", - "line": 65 + "line": 72 } } }, diff --git a/profiles/fscloud/README.md b/profiles/fscloud/README.md index 3a1768ef..c221dadb 100644 --- a/profiles/fscloud/README.md +++ b/profiles/fscloud/README.md @@ -33,7 +33,7 @@ No resources. | [enable\_floating\_ip](#input\_enable\_floating\_ip) | Create a floating IP for each virtual server created | `bool` | `false` | no | | [existing\_kms\_instance\_guid](#input\_existing\_kms\_instance\_guid) | The GUID of the Hyper Protect Crypto Services or Key Protect instance in which the key specified in var.kms\_key\_crn and var.backup\_encryption\_key\_crn is coming from. Required only if var.skip\_iam\_authorization\_policy is set to false. | `string` | `null` | no | | [image\_id](#input\_image\_id) | Image ID used for VSI. Run 'ibmcloud is images' to find available images in a region | `string` | n/a | yes | -| [load\_balancers](#input\_load\_balancers) | Load balancers to add to VSI |
object({
name = string
type = string
listener_port = number
listener_protocol = string
connection_limit = number
algorithm = string
protocol = string
health_delay = number
health_retries = number
health_timeout = number
health_type = string
pool_member_port = string
profile = optional(string)
dns = optional(
object({
instance_crn = string
zone_id = string
})
)
security_group = optional(
object({
name = string
rules = list(
object({
name = string
direction = string
source = string
tcp = optional(
object({
port_max = number
port_min = number
})
)
udp = optional(
object({
port_max = number
port_min = number
})
)
icmp = optional(
object({
type = number
code = number
})
)
})
)
})
)
})
)
list(| `[]` | no | +| [load\_balancers](#input\_load\_balancers) | Load balancers to add to VSI |
object({
name = string
type = string
listener_port = number
listener_protocol = string
connection_limit = number
algorithm = string
protocol = string
health_delay = number
health_retries = number
health_timeout = number
health_type = string
pool_member_port = string
security_group = optional(
object({
name = string
rules = list(
object({
name = string
direction = string
source = string
tcp = optional(
object({
port_max = number
port_min = number
})
)
udp = optional(
object({
port_max = number
port_min = number
})
)
icmp = optional(
object({
type = number
code = number
})
)
})
)
})
)
})
)
list(| `[]` | no | | [machine\_type](#input\_machine\_type) | VSI machine type. Run 'ibmcloud is instance-profiles' to get a list of regional profiles | `string` | n/a | yes | | [prefix](#input\_prefix) | The prefix that you would like to append to your resources | `string` | n/a | yes | | [resource\_group\_id](#input\_resource\_group\_id) | ID of resource group to create VSI and block storage volumes. If you wish to create the block storage volumes in a different resource group, you can optionally set that directly in the 'block\_storage\_volumes' variable. | `string` | n/a | yes | diff --git a/profiles/fscloud/variables.tf b/profiles/fscloud/variables.tf index 050309ca..9f2aff65 100644 --- a/profiles/fscloud/variables.tf +++ b/profiles/fscloud/variables.tf @@ -10,11 +10,6 @@ variable "resource_group_id" { variable "prefix" { description = "The prefix that you would like to append to your resources" type = string - - validation { - error_message = "Prefix must begin and end with a letter and contain only letters, numbers, and - characters." - condition = can(regex("^([A-z]|[a-z][-a-z0-9]*[a-z0-9])$", var.prefix)) - } } variable "tags" { @@ -131,44 +126,12 @@ variable "security_group" { }) ) }) - - validation { - error_message = "Each security group rule must have a unique name." - condition = ( - var.security_group == null - ? true - : length(distinct(var.security_group.rules[*].name)) == length(var.security_group.rules[*].name) - ) - } - - validation { - error_message = "Security group rule direction can only be `inbound` or `outbound`." - condition = var.security_group == null ? true : length( - distinct( - flatten([ - for rule in var.security_group.rules : - false if !contains(["inbound", "outbound"], rule.direction) - ]) - ) - ) == 0 - } - } variable "security_group_ids" { description = "IDs of additional security groups to be added to VSI deployment primary interface. A VSI interface can have a maximum of 5 security groups." type = list(string) default = [] - - validation { - error_message = "Security group IDs must be unique." - condition = length(var.security_group_ids) == length(distinct(var.security_group_ids)) - } - - validation { - error_message = "No more than 5 security groups can be added to a VSI deployment." - condition = length(var.security_group_ids) <= 5 - } } variable "block_storage_volumes" { @@ -183,11 +146,6 @@ variable "block_storage_volumes" { }) ) default = [] - - validation { - error_message = "Each block storage volume must have a unique name." - condition = length(distinct(var.block_storage_volumes[*].name)) == length(var.block_storage_volumes) - } } variable "load_balancers" { @@ -206,6 +164,13 @@ variable "load_balancers" { health_timeout = number health_type = string pool_member_port = string + profile = optional(string) + dns = optional( + object({ + instance_crn = string + zone_id = string + }) + ) security_group = optional( object({ name = string @@ -239,63 +204,6 @@ variable "load_balancers" { }) ) default = [] - - validation { - error_message = "Load balancer names must match the regex pattern ^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$." - condition = length(distinct( - flatten([ - # Check through rules - for load_balancer in var.load_balancers : - # Return false if direction is not valid - false if !can(regex("^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$", load_balancer.name)) - ]) - )) == 0 - } - - validation { - error_message = "Load Balancer Pool algorithm can only be `round_robin`, `weighted_round_robin`, or `least_connections`." - condition = length( - flatten([ - for load_balancer in var.load_balancers : - true if !contains(["round_robin", "weighted_round_robin", "least_connections"], load_balancer.algorithm) - ]) - ) == 0 - } - - validation { - error_message = "Load Balancer Pool Protocol can only be `http`, `https`, or `tcp`." - condition = length( - flatten([ - for load_balancer in var.load_balancers : - true if !contains(["http", "https", "tcp"], load_balancer.protocol) - ]) - ) == 0 - } - - validation { - error_message = "Pool health delay must be greater than the timeout." - condition = length( - flatten([ - for load_balancer in var.load_balancers : - true if load_balancer.health_delay < load_balancer.health_timeout - ]) - ) == 0 - } - - validation { - error_message = "Load Balancer Pool Health Check Type can only be `http`, `https`, or `tcp`." - condition = length( - flatten([ - for load_balancer in var.load_balancers : - true if !contains(["http", "https", "tcp"], load_balancer.health_type) - ]) - ) == 0 - } - - validation { - error_message = "Each load balancer must have a unique name." - condition = length(distinct(var.load_balancers[*].name)) == length(var.load_balancers[*].name) - } } variable "existing_kms_instance_guid" { @@ -314,13 +222,6 @@ variable "access_tags" { type = list(string) description = "A list of access tags to apply to the VSI 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." - } } ############################################################################## diff --git a/tests/other_test.go b/tests/other_test.go index eb069312..4007ba9c 100644 --- a/tests/other_test.go +++ b/tests/other_test.go @@ -4,23 +4,12 @@ package test import ( "github.com/stretchr/testify/assert" "testing" - - "github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testhelper" ) func TestRunBasicExample(t *testing.T) { t.Parallel() - options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ - Testing: t, - TerraformDir: basicExampleTerraformDir, - Prefix: "slz-vsi-basic", - ResourceGroup: resourceGroup, - Region: region, - TerraformVars: map[string]interface{}{ - "access_tags": permanentResources["accessTags"], - }, - }) + options := setupOptions(t, basicExampleTerraformDir, "slz-vsi-basic") output, err := options.RunTestConsistency() assert.Nil(t, err, "This should not have errored") diff --git a/tests/pr_test.go b/tests/pr_test.go index 43385489..b49dbd6b 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -11,6 +11,7 @@ import ( ) const basicExampleTerraformDir = "examples/basic" +const completeExampleTerraformDir = "examples/complete" const fsCloudExampleTerraformDir = "examples/fscloud" const resourceGroup = "geretain-test-resources" @@ -50,12 +51,38 @@ func setupFSCloudOptions(t *testing.T, prefix string) *testhelper.TestOptions { return options } -func TestRunUpgradeFSCloudExample(t *testing.T) { - // t.Parallel() +func setupOptions(t *testing.T, dir string, prefix string) *testhelper.TestOptions { + options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ + Testing: t, + TerraformDir: dir, + Prefix: prefix, + ResourceGroup: resourceGroup, + Region: region, + TerraformVars: map[string]interface{}{ + "access_tags": permanentResources["accessTags"], + }, + }) + + return options +} + +func TestRunCompleteExample(t *testing.T) { + t.Parallel() + + options := setupOptions(t, completeExampleTerraformDir, "slz-vsi-com") + + output, err := options.RunTestConsistency() + assert.Nil(t, err, "This should not have errored") + assert.NotNil(t, output, "Expected some output") +} - options := setupFSCloudOptions(t, "slz-vsi-upg") +func TestRunCompleteUpgradeExample(t *testing.T) { + t.Parallel() + + options := setupOptions(t, completeExampleTerraformDir, "slz-vsi-com-upg") output, err := options.RunTestUpgrade() + if !options.UpgradeTestSkipped { assert.Nil(t, err, "This should not have errored") assert.NotNil(t, output, "Expected some output") @@ -63,7 +90,7 @@ func TestRunUpgradeFSCloudExample(t *testing.T) { } func TestRunFSCloudExample(t *testing.T) { - // t.Parallel() + t.Parallel() options := setupFSCloudOptions(t, "slz-vsi-fscloud") diff --git a/variables.tf b/variables.tf index bf1fef09..3f72eaed 100644 --- a/variables.tf +++ b/variables.tf @@ -245,6 +245,13 @@ variable "load_balancers" { health_timeout = number health_type = string pool_member_port = string + profile = optional(string) + dns = optional( + object({ + instance_crn = string + zone_id = string + }) + ) security_group = optional( object({ name = string
object({
name = string
type = string
listener_port = number
listener_protocol = string
connection_limit = number
algorithm = string
protocol = string
health_delay = number
health_retries = number
health_timeout = number
health_type = string
pool_member_port = string
profile = optional(string)
dns = optional(
object({
instance_crn = string
zone_id = string
})
)
security_group = optional(
object({
name = string
rules = list(
object({
name = string
direction = string
source = string
tcp = optional(
object({
port_max = number
port_min = number
})
)
udp = optional(
object({
port_max = number
port_min = number
})
)
icmp = optional(
object({
type = number
code = number
})
)
})
)
})
)
})
)