From 6a74708d41bd98635a2f4d105d74de6fb487c775 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Thu, 5 Oct 2023 23:23:14 +0530 Subject: [PATCH 01/12] feat: exposed composed string for psql connection and updated complete example to include db connection --- common-dev-assets | 2 +- examples/complete/main.tf | 178 +++++++++++++++++++++++++++++++++++--- main.tf | 1 + module-metadata.json | 2 +- 4 files changed, 167 insertions(+), 16 deletions(-) diff --git a/common-dev-assets b/common-dev-assets index 1d683d90..43517250 160000 --- a/common-dev-assets +++ b/common-dev-assets @@ -1 +1 @@ -Subproject commit 1d683d90a0649e7894786a7209a4177a1d42e3fd +Subproject commit 43517250b2bdc95d60ad57a52d5d0d83238ca3f2 diff --git a/examples/complete/main.tf b/examples/complete/main.tf index e0d13a38..90727b21 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -1,3 +1,12 @@ +locals { + # reserved IP that will be assigned to VSI deployed in subnet-a + vsi-reserved-ip = "10.10.10.10" + + # https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-connecting-psql + composed = replace(module.postgresql_db.service_credentials_object.credentials["postgressql_viewer"]["composed"], "sslmode=verify-full", "sslmode=require") +} + + ############################################################################## # Resource Group ############################################################################## @@ -45,21 +54,78 @@ module "vpc" { prefix = var.prefix name = "vpc" tags = var.resource_tags + network_acls = [ + { + name = "vpc-acl" + add_ibm_cloud_internal_rules = true + add_vpc_connectivity_rules = true + prepend_ibm_rules = true + rules = [ + # Allow all traffic from and to VSI in subnet-a + { + name = "allow-all-inbound" + action = "allow" + direction = "inbound" + destination = "${local.vsi-reserved-ip}/32" + source = "0.0.0.0/0" + }, + { + name = "allow-all-outbound" + action = "allow" + direction = "outbound" + destination = "0.0.0.0/0" + source = "${local.vsi-reserved-ip}/32" + } + ] + } + ] } + ############################################################################## # Security group ############################################################################## -resource "ibm_is_security_group" "sg1" { - name = "${var.prefix}-sg1" - vpc = module.vpc.vpc_id -} - -# wait 30 secs after security group is destroyed before destroying VPE to workaround race condition -resource "time_sleep" "wait_30_seconds" { - depends_on = [ibm_is_security_group.sg1] - destroy_duration = "30s" +module "create_sgr_rule_vsi" { + source = "terraform-ibm-modules/security-group/ibm" + version = "v2.0.0" + add_ibm_cloud_internal_rules = false + security_group_name = "${var.prefix}-sg-vsi" + resource_group = module.resource_group.resource_group_id + vpc_id = module.vpc.vpc_id + security_group_rules = [{ + name = "allow-ssh-inbound" + direction = "inbound" + remote = "0.0.0.0/0" + tcp = { + port_min = 22 + port_max = 22 + } + }, { + name = "allow-http-inbound" + direction = "inbound" + remote = "0.0.0.0/0" + tcp = { + port_min = 80 + port_max = 80 + } + }, { + name = "allow-https-inbound" + direction = "inbound" + remote = "0.0.0.0/0" + tcp = { + port_min = 443 + port_max = 443 + } + }, { + name = "allow-ping-inbound" + direction = "inbound" + remote = "0.0.0.0/0" + icmp = { + type = 8 + } + }] + target_ids = [ibm_is_instance.vsi.primary_network_interface[0].id] } ############################################################################## @@ -139,12 +205,96 @@ module "vpe" { crn = module.postgresql_db.crn }, ] - vpc_id = module.vpc.vpc_id - subnet_zone_list = module.vpc.subnet_zone_list - resource_group_id = module.resource_group.resource_group_id - security_group_ids = [ibm_is_security_group.sg1.id] + vpc_id = module.vpc.vpc_id + subnet_zone_list = module.vpc.subnet_zone_list + resource_group_id = module.resource_group.resource_group_id depends_on = [ time_sleep.wait_120_seconds, - time_sleep.wait_30_seconds ] } + + +############################################################################## +# Floating IP +############################################################################## + +resource "ibm_is_floating_ip" "vsi_fip" { + name = "${var.prefix}-fip" + target = ibm_is_instance.vsi.primary_network_interface[0].id + access_tags = var.access_tags +} + +############################################################################## +# SSH Key +############################################################################## + +resource "tls_private_key" "tls_key" { + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "ibm_is_ssh_key" "ssh_key" { + name = "${var.prefix}-ssh-key" + public_key = tls_private_key.tls_key.public_key_openssh +} + +############################################################################## +# VSI +############################################################################## + +resource "ibm_is_instance" "vsi" { + name = "${var.prefix}-vsi" + image = "r006-fedc50ed-8ea3-4a66-9559-c482c4e6ed88" + profile = "cx2-2x4" + resource_group = module.resource_group.resource_group_id + vpc = module.vpc.vpc_id + zone = "${var.region}-1" + keys = [ibm_is_ssh_key.ssh_key.id] + + lifecycle { + ignore_changes = [ + image + ] + } + + primary_network_interface { + subnet = module.vpc.subnet_ids[0] + name = "${var.prefix}-eth" + primary_ip { + address = local.vsi-reserved-ip + auto_delete = true + } + } + + # User can configure timeouts + timeouts { + create = "15m" + update = "15m" + delete = "15m" + } +} + +resource "null_resource" "db_connection" { + depends_on = [module.postgresql_db, ibm_is_instance.vsi, module.create_sgr_rule_vsi] + + provisioner "remote-exec" { + + inline = [ + "sudo apt-get update -y", + "sudo apt-get install postgresql-client -y", + + "${local.composed} -c 'CREATE TABLE test (id serial PRIMARY KEY, marks serial);'", + "${local.composed} -c 'INSERT INTO test (id, marks) VALUES (11, 100);'", + "${local.composed} -c 'INSERT INTO test (id, marks) VALUES (12, 200);'", + "${local.composed} -c 'INSERT INTO test (id, marks) VALUES (13, 300);'", + "${local.composed} -c 'INSERT INTO test (id, marks) VALUES (14, 400);'", + "${local.composed} -c 'SELECT * FROM test;'", + ] + connection { + type = "ssh" + host = ibm_is_floating_ip.vsi_fip.address + user = "root" + private_key = tls_private_key.tls_key.private_key_pem + } + } +} diff --git a/main.tf b/main.tf index 0ce302db..f2aac80d 100644 --- a/main.tf +++ b/main.tf @@ -211,6 +211,7 @@ locals { service_credential["name"] => { username = service_credential.credentials["connection.postgres.authentication.username"] password = service_credential.credentials["connection.postgres.authentication.password"] + composed = service_credential.credentials["connection.cli.composed.0"] } } } : null diff --git a/module-metadata.json b/module-metadata.json index 968c1d56..a8c54f9c 100644 --- a/module-metadata.json +++ b/module-metadata.json @@ -571,7 +571,7 @@ }, "pos": { "filename": "main.tf", - "line": 219 + "line": 220 } } }, From 97d9f6aec65d900b3bea261fc9b36fe889896984 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Thu, 5 Oct 2023 23:55:45 +0530 Subject: [PATCH 02/12] chore: updated comments --- examples/complete/main.tf | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 90727b21..b1cae133 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -1,6 +1,6 @@ locals { - # reserved IP that will be assigned to VSI deployed in subnet-a - vsi-reserved-ip = "10.10.10.10" + # reserved IP that will be assigned to VSI + vsi_reserved_ip = "10.10.10.10" # https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-connecting-psql composed = replace(module.postgresql_db.service_credentials_object.credentials["postgressql_viewer"]["composed"], "sslmode=verify-full", "sslmode=require") @@ -61,12 +61,12 @@ module "vpc" { add_vpc_connectivity_rules = true prepend_ibm_rules = true rules = [ - # Allow all traffic from and to VSI in subnet-a + # Allow all traffic from and to VSI { name = "allow-all-inbound" action = "allow" direction = "inbound" - destination = "${local.vsi-reserved-ip}/32" + destination = "${local.vsi_reserved_ip}/32" source = "0.0.0.0/0" }, { @@ -74,7 +74,7 @@ module "vpc" { action = "allow" direction = "outbound" destination = "0.0.0.0/0" - source = "${local.vsi-reserved-ip}/32" + source = "${local.vsi_reserved_ip}/32" } ] } @@ -117,7 +117,7 @@ module "create_sgr_rule_vsi" { port_min = 443 port_max = 443 } - }, { + }, { name = "allow-ping-inbound" direction = "inbound" remote = "0.0.0.0/0" @@ -261,12 +261,11 @@ resource "ibm_is_instance" "vsi" { subnet = module.vpc.subnet_ids[0] name = "${var.prefix}-eth" primary_ip { - address = local.vsi-reserved-ip + address = local.vsi_reserved_ip auto_delete = true } } - # User can configure timeouts timeouts { create = "15m" update = "15m" From e60772734d3ea06ad22469a882eff319ab653e04 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Fri, 6 Oct 2023 10:05:13 +0530 Subject: [PATCH 03/12] fix: extracted composed string from service_credentials_json --- examples/complete/main.tf | 18 +++++++++++------- main.tf | 1 - 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/examples/complete/main.tf b/examples/complete/main.tf index b1cae133..a5a04ef5 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -2,8 +2,12 @@ locals { # reserved IP that will be assigned to VSI vsi_reserved_ip = "10.10.10.10" + # Change this local variable accordingly if default value of `service_credential_names` is changed in complete example + service_credential_name = "postgressql_viewer" + service_credential = jsondecode(module.postgresql_db.service_credentials_json[local.service_credential_name]) # https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-connecting-psql - composed = replace(module.postgresql_db.service_credentials_object.credentials["postgressql_viewer"]["composed"], "sslmode=verify-full", "sslmode=require") + composed_string = replace(local.service_credential.connection.cli.composed[0], "sslmode=verify-full", "sslmode=require") + } @@ -282,12 +286,12 @@ resource "null_resource" "db_connection" { "sudo apt-get update -y", "sudo apt-get install postgresql-client -y", - "${local.composed} -c 'CREATE TABLE test (id serial PRIMARY KEY, marks serial);'", - "${local.composed} -c 'INSERT INTO test (id, marks) VALUES (11, 100);'", - "${local.composed} -c 'INSERT INTO test (id, marks) VALUES (12, 200);'", - "${local.composed} -c 'INSERT INTO test (id, marks) VALUES (13, 300);'", - "${local.composed} -c 'INSERT INTO test (id, marks) VALUES (14, 400);'", - "${local.composed} -c 'SELECT * FROM test;'", + "${local.composed_string} -c 'CREATE TABLE test (id serial PRIMARY KEY, marks serial);'", + "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (11, 100);'", + "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (12, 200);'", + "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (13, 300);'", + "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (14, 400);'", + "${local.composed_string} -c 'SELECT * FROM test;'", ] connection { type = "ssh" diff --git a/main.tf b/main.tf index f2aac80d..0ce302db 100644 --- a/main.tf +++ b/main.tf @@ -211,7 +211,6 @@ locals { service_credential["name"] => { username = service_credential.credentials["connection.postgres.authentication.username"] password = service_credential.credentials["connection.postgres.authentication.password"] - composed = service_credential.credentials["connection.cli.composed.0"] } } } : null From 1a56cda5181a63c2a4b06df37c6f88af18987676 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Fri, 6 Oct 2023 10:31:22 +0530 Subject: [PATCH 04/12] fix: updated terraform-ibm-key-protect-all-inclusive version in complete example --- examples/complete/main.tf | 2 +- module-metadata.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/complete/main.tf b/examples/complete/main.tf index a5a04ef5..7f7387e0 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -29,7 +29,7 @@ module "resource_group" { module "key_protect_all_inclusive" { source = "terraform-ibm-modules/key-protect-all-inclusive/ibm" - version = "4.2.0" + version = "4.3.0" resource_group_id = module.resource_group.resource_group_id # Note: Database instance and Key Protect must be created in the same region when using BYOK # See https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok diff --git a/module-metadata.json b/module-metadata.json index a8c54f9c..968c1d56 100644 --- a/module-metadata.json +++ b/module-metadata.json @@ -571,7 +571,7 @@ }, "pos": { "filename": "main.tf", - "line": 220 + "line": 219 } } }, From 2a993c43b3690d05b846c0ee7913facbe94beb13 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Fri, 6 Oct 2023 11:01:12 +0530 Subject: [PATCH 05/12] fix: pre-commit failures --- examples/complete/version.tf | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/examples/complete/version.tf b/examples/complete/version.tf index 4e35bb57..3de75f43 100644 --- a/examples/complete/version.tf +++ b/examples/complete/version.tf @@ -10,5 +10,14 @@ terraform { source = "hashicorp/time" version = ">= 0.8.0" } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } } } From 13fdcbda2abece794a518e438d64efad70ad9770 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Fri, 6 Oct 2023 12:13:26 +0530 Subject: [PATCH 06/12] SKIP UPGRADE TEST From 5d5b9c22d7855b5dacb709f0596c3a097bd30a6e Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Fri, 6 Oct 2023 14:39:16 +0530 Subject: [PATCH 07/12] docs: updated complete example readme --- common-dev-assets | 2 +- examples/complete/README.md | 2 ++ examples/complete/main.tf | 25 +++++++++++++++++++++---- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/common-dev-assets b/common-dev-assets index 43517250..1d683d90 160000 --- a/common-dev-assets +++ b/common-dev-assets @@ -1 +1 @@ -Subproject commit 43517250b2bdc95d60ad57a52d5d0d83238ca3f2 +Subproject commit 1d683d90a0649e7894786a7209a4177a1d42e3fd diff --git a/examples/complete/README.md b/examples/complete/README.md index 69f0801e..20536151 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -10,3 +10,5 @@ An end-to-end example that does the following: - Create a Virtual Private Cloud (VPC). - Create Context Based Restriction (CBR) to only allow Postgresql to be accessible from the VPC. - Create a security group and a VPE for the PostgreSQL instance. +- Create a new VSI instance, floating IP and SSH key pair +- Create a security group for VSI instance diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 7f7387e0..01b77782 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -90,11 +90,26 @@ module "vpc" { # Security group ############################################################################## +module "create_sgr_rule_pg" { + source = "terraform-ibm-modules/security-group/ibm" + version = "v2.0.0" + add_ibm_cloud_internal_rules = false + security_group_name = "${var.prefix}-security-group-pg" + resource_group = module.resource_group.resource_group_id + vpc_id = module.vpc.vpc_id +} + +# wait 30 secs after security group is destroyed before destroying VPE to workaround race condition +resource "time_sleep" "wait_30_seconds" { + depends_on = [module.create_sgr_rule_pg] + destroy_duration = "30s" +} + module "create_sgr_rule_vsi" { source = "terraform-ibm-modules/security-group/ibm" version = "v2.0.0" add_ibm_cloud_internal_rules = false - security_group_name = "${var.prefix}-sg-vsi" + security_group_name = "${var.prefix}-security-group-vsi" resource_group = module.resource_group.resource_group_id vpc_id = module.vpc.vpc_id security_group_rules = [{ @@ -209,11 +224,13 @@ module "vpe" { crn = module.postgresql_db.crn }, ] - vpc_id = module.vpc.vpc_id - subnet_zone_list = module.vpc.subnet_zone_list - resource_group_id = module.resource_group.resource_group_id + vpc_id = module.vpc.vpc_id + subnet_zone_list = module.vpc.subnet_zone_list + resource_group_id = module.resource_group.resource_group_id + security_group_ids = module.create_sgr_rule_pg.security_group_id depends_on = [ time_sleep.wait_120_seconds, + time_sleep.wait_30_seconds ] } From b75a73738ce0b75936914c628968f820b35f150e Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Fri, 6 Oct 2023 15:51:13 +0530 Subject: [PATCH 08/12] fix: bug with security groups id in vpe creation --- examples/complete/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 01b77782..f66efb20 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -227,7 +227,7 @@ module "vpe" { vpc_id = module.vpc.vpc_id subnet_zone_list = module.vpc.subnet_zone_list resource_group_id = module.resource_group.resource_group_id - security_group_ids = module.create_sgr_rule_pg.security_group_id + security_group_ids = [module.create_sgr_rule_pg.security_group_id] depends_on = [ time_sleep.wait_120_seconds, time_sleep.wait_30_seconds From 9ae98b41b4e7f3f4c138470141119fae76786f05 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Wed, 11 Oct 2023 14:03:11 +0530 Subject: [PATCH 09/12] fix: added depends on vpe in null_resource --- examples/complete/main.tf | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/examples/complete/main.tf b/examples/complete/main.tf index f66efb20..b709fe06 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -97,12 +97,7 @@ module "create_sgr_rule_pg" { security_group_name = "${var.prefix}-security-group-pg" resource_group = module.resource_group.resource_group_id vpc_id = module.vpc.vpc_id -} - -# wait 30 secs after security group is destroyed before destroying VPE to workaround race condition -resource "time_sleep" "wait_30_seconds" { - depends_on = [module.create_sgr_rule_pg] - destroy_duration = "30s" + target_ids = [for crn in module.vpe.crn : element(split(":", crn), length(split(":", crn)) - 1)] } module "create_sgr_rule_vsi" { @@ -224,13 +219,11 @@ module "vpe" { crn = module.postgresql_db.crn }, ] - vpc_id = module.vpc.vpc_id - subnet_zone_list = module.vpc.subnet_zone_list - resource_group_id = module.resource_group.resource_group_id - security_group_ids = [module.create_sgr_rule_pg.security_group_id] + vpc_id = module.vpc.vpc_id + subnet_zone_list = module.vpc.subnet_zone_list + resource_group_id = module.resource_group.resource_group_id depends_on = [ time_sleep.wait_120_seconds, - time_sleep.wait_30_seconds ] } @@ -295,7 +288,7 @@ resource "ibm_is_instance" "vsi" { } resource "null_resource" "db_connection" { - depends_on = [module.postgresql_db, ibm_is_instance.vsi, module.create_sgr_rule_vsi] + depends_on = [ibm_is_instance.vsi, module.create_sgr_rule_vsi, module.vpe] provisioner "remote-exec" { From a54f879102df828c078cbb1729e4f3231287ccd2 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Thu, 12 Oct 2023 23:09:05 +0530 Subject: [PATCH 10/12] fix: added on_failure attribute in remote-exec --- examples/complete/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/complete/main.tf b/examples/complete/main.tf index b709fe06..1624bfab 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -291,7 +291,6 @@ resource "null_resource" "db_connection" { depends_on = [ibm_is_instance.vsi, module.create_sgr_rule_vsi, module.vpe] provisioner "remote-exec" { - inline = [ "sudo apt-get update -y", "sudo apt-get install postgresql-client -y", @@ -309,5 +308,6 @@ resource "null_resource" "db_connection" { user = "root" private_key = tls_private_key.tls_key.private_key_pem } + on_failure = fail } } From d6a5858019a4bc4f4904149e3cfd1c422cf8362b Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Tue, 24 Oct 2023 20:29:32 +0530 Subject: [PATCH 11/12] test: added db-connectivity test --- common-dev-assets | 2 +- examples/complete/README.md | 2 - examples/complete/main.tf | 179 ++------------------------------- examples/complete/outputs.tf | 15 +++ examples/complete/variables.tf | 53 ++++++++++ examples/complete/version.tf | 9 -- tests/go.mod | 2 +- tests/go.sum | 4 +- tests/pr_test.go | 72 +++++++++++++ tests/resources/main.tf | 132 ++++++++++++++++++++++++ tests/resources/provider.tf | 4 + tests/resources/variables.tf | 54 ++++++++++ tests/resources/version.tf | 23 +++++ 13 files changed, 364 insertions(+), 187 deletions(-) create mode 100644 tests/resources/main.tf create mode 100644 tests/resources/provider.tf create mode 100644 tests/resources/variables.tf create mode 100644 tests/resources/version.tf diff --git a/common-dev-assets b/common-dev-assets index cce592fb..edde38e2 160000 --- a/common-dev-assets +++ b/common-dev-assets @@ -1 +1 @@ -Subproject commit cce592fb1b6b73168725534b8aef045c944328a9 +Subproject commit edde38e2b86b2e04ca724f12c9d52083f32100c9 diff --git a/examples/complete/README.md b/examples/complete/README.md index 20536151..69f0801e 100644 --- a/examples/complete/README.md +++ b/examples/complete/README.md @@ -10,5 +10,3 @@ An end-to-end example that does the following: - Create a Virtual Private Cloud (VPC). - Create Context Based Restriction (CBR) to only allow Postgresql to be accessible from the VPC. - Create a security group and a VPE for the PostgreSQL instance. -- Create a new VSI instance, floating IP and SSH key pair -- Create a security group for VSI instance diff --git a/examples/complete/main.tf b/examples/complete/main.tf index 1624bfab..1622c3fd 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -1,23 +1,10 @@ -locals { - # reserved IP that will be assigned to VSI - vsi_reserved_ip = "10.10.10.10" - - # Change this local variable accordingly if default value of `service_credential_names` is changed in complete example - service_credential_name = "postgressql_viewer" - service_credential = jsondecode(module.postgresql_db.service_credentials_json[local.service_credential_name]) - # https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-connecting-psql - composed_string = replace(local.service_credential.connection.cli.composed[0], "sslmode=verify-full", "sslmode=require") - -} - - ############################################################################## # Resource Group ############################################################################## module "resource_group" { source = "terraform-ibm-modules/resource-group/ibm" - version = "1.0.6" + version = "1.1.0" # 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 @@ -29,7 +16,7 @@ module "resource_group" { module "key_protect_all_inclusive" { source = "terraform-ibm-modules/key-protect-all-inclusive/ibm" - version = "4.3.0" + version = "4.4.0" resource_group_id = module.resource_group.resource_group_id # Note: Database instance and Key Protect must be created in the same region when using BYOK # See https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok @@ -52,40 +39,15 @@ data "ibm_iam_account_settings" "iam_account_settings" { module "vpc" { source = "terraform-ibm-modules/landing-zone-vpc/ibm" - version = "7.3.1" + version = "7.7.0" resource_group_id = module.resource_group.resource_group_id region = var.region prefix = var.prefix name = "vpc" tags = var.resource_tags - network_acls = [ - { - name = "vpc-acl" - add_ibm_cloud_internal_rules = true - add_vpc_connectivity_rules = true - prepend_ibm_rules = true - rules = [ - # Allow all traffic from and to VSI - { - name = "allow-all-inbound" - action = "allow" - direction = "inbound" - destination = "${local.vsi_reserved_ip}/32" - source = "0.0.0.0/0" - }, - { - name = "allow-all-outbound" - action = "allow" - direction = "outbound" - destination = "0.0.0.0/0" - source = "${local.vsi_reserved_ip}/32" - } - ] - } - ] + network_acls = var.vpc_network_acls } - ############################################################################## # Security group ############################################################################## @@ -100,55 +62,13 @@ module "create_sgr_rule_pg" { target_ids = [for crn in module.vpe.crn : element(split(":", crn), length(split(":", crn)) - 1)] } -module "create_sgr_rule_vsi" { - source = "terraform-ibm-modules/security-group/ibm" - version = "v2.0.0" - add_ibm_cloud_internal_rules = false - security_group_name = "${var.prefix}-security-group-vsi" - resource_group = module.resource_group.resource_group_id - vpc_id = module.vpc.vpc_id - security_group_rules = [{ - name = "allow-ssh-inbound" - direction = "inbound" - remote = "0.0.0.0/0" - tcp = { - port_min = 22 - port_max = 22 - } - }, { - name = "allow-http-inbound" - direction = "inbound" - remote = "0.0.0.0/0" - tcp = { - port_min = 80 - port_max = 80 - } - }, { - name = "allow-https-inbound" - direction = "inbound" - remote = "0.0.0.0/0" - tcp = { - port_min = 443 - port_max = 443 - } - }, { - name = "allow-ping-inbound" - direction = "inbound" - remote = "0.0.0.0/0" - icmp = { - type = 8 - } - }] - target_ids = [ibm_is_instance.vsi.primary_network_interface[0].id] -} - ############################################################################## # Create CBR Zone ############################################################################## module "cbr_zone" { source = "terraform-ibm-modules/cbr/ibm//modules/cbr-zone-module" - version = "1.12.0" + version = "1.15.0" name = "${var.prefix}-VPC-network-zone" zone_description = "CBR Network zone representing VPC" account_id = data.ibm_iam_account_settings.iam_account_settings.account_id @@ -211,7 +131,7 @@ resource "time_sleep" "wait_120_seconds" { module "vpe" { source = "terraform-ibm-modules/vpe-module/ibm" - version = "2.4.0" + version = "3.1.0" prefix = "vpe-to-pg" cloud_service_by_crn = [ { @@ -223,91 +143,6 @@ module "vpe" { subnet_zone_list = module.vpc.subnet_zone_list resource_group_id = module.resource_group.resource_group_id depends_on = [ - time_sleep.wait_120_seconds, + time_sleep.wait_120_seconds ] } - - -############################################################################## -# Floating IP -############################################################################## - -resource "ibm_is_floating_ip" "vsi_fip" { - name = "${var.prefix}-fip" - target = ibm_is_instance.vsi.primary_network_interface[0].id - access_tags = var.access_tags -} - -############################################################################## -# SSH Key -############################################################################## - -resource "tls_private_key" "tls_key" { - algorithm = "RSA" - rsa_bits = 4096 -} - -resource "ibm_is_ssh_key" "ssh_key" { - name = "${var.prefix}-ssh-key" - public_key = tls_private_key.tls_key.public_key_openssh -} - -############################################################################## -# VSI -############################################################################## - -resource "ibm_is_instance" "vsi" { - name = "${var.prefix}-vsi" - image = "r006-fedc50ed-8ea3-4a66-9559-c482c4e6ed88" - profile = "cx2-2x4" - resource_group = module.resource_group.resource_group_id - vpc = module.vpc.vpc_id - zone = "${var.region}-1" - keys = [ibm_is_ssh_key.ssh_key.id] - - lifecycle { - ignore_changes = [ - image - ] - } - - primary_network_interface { - subnet = module.vpc.subnet_ids[0] - name = "${var.prefix}-eth" - primary_ip { - address = local.vsi_reserved_ip - auto_delete = true - } - } - - timeouts { - create = "15m" - update = "15m" - delete = "15m" - } -} - -resource "null_resource" "db_connection" { - depends_on = [ibm_is_instance.vsi, module.create_sgr_rule_vsi, module.vpe] - - provisioner "remote-exec" { - inline = [ - "sudo apt-get update -y", - "sudo apt-get install postgresql-client -y", - - "${local.composed_string} -c 'CREATE TABLE test (id serial PRIMARY KEY, marks serial);'", - "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (11, 100);'", - "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (12, 200);'", - "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (13, 300);'", - "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (14, 400);'", - "${local.composed_string} -c 'SELECT * FROM test;'", - ] - connection { - type = "ssh" - host = ibm_is_floating_ip.vsi_fip.address - user = "root" - private_key = tls_private_key.tls_key.private_key_pem - } - on_failure = fail - } -} diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf index 3383a7e2..3f168731 100644 --- a/examples/complete/outputs.tf +++ b/examples/complete/outputs.tf @@ -42,3 +42,18 @@ output "port" { description = "Postgresql instance port" value = module.postgresql_db.port } + +output "vpc_id" { + description = "ID of VPC created" + value = module.vpc.vpc_id +} + +output "subnet_ids" { + description = "list of subnet IDs" + value = module.vpc.subnet_ids +} + +output "resource_group_id" { + description = "ID of resource_group created" + value = module.resource_group.resource_group_id +} diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index fb342eef..1ce28122 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -69,3 +69,56 @@ variable "service_credential_names" { "postgressql_editor" : "Editor", } } + + +variable "vpc_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 = [] + } + ] +} diff --git a/examples/complete/version.tf b/examples/complete/version.tf index e358bfee..08d83b61 100644 --- a/examples/complete/version.tf +++ b/examples/complete/version.tf @@ -10,14 +10,5 @@ terraform { source = "hashicorp/time" version = ">= 0.8.0" } - null = { - source = "hashicorp/null" - version = ">= 3.2.1" - } - - tls = { - source = "hashicorp/tls" - version = ">= 4.0.4" - } } } diff --git a/tests/go.mod b/tests/go.mod index fce40cc8..552f2def 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -7,7 +7,7 @@ toolchain go1.21.3 require ( github.com/gruntwork-io/terratest v0.46.0 github.com/stretchr/testify v1.8.4 - github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper v1.23.4 + github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper v1.23.8 ) require ( diff --git a/tests/go.sum b/tests/go.sum index 547d2f87..96a5baf5 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -662,8 +662,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper v1.23.4 h1:J0EIpvOVD9VJ6ejZh2fQqMqcTxrakfPXeGSBfXBBmUY= -github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper v1.23.4/go.mod h1:6cuESZXW/sD6eXs5PUoZ48IEpYjE95NhStmPYU1P6BI= +github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper v1.23.8 h1:37Mpl51G6x5BG8Myh4ko8snsAfHmMDUWQuH3MXv/ckE= +github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper v1.23.8/go.mod h1:0SiqR1jWVkpgRnsbS+qKgF/VoQaA2Pt6x4jVAGtJZLc= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tmccombs/hcl2json v0.5.0 h1:cT2sXStOzKL06c8ZTf9vh+0N8GKGzV7+9RUaY5/iUP8= diff --git a/tests/pr_test.go b/tests/pr_test.go index afe94270..c2002189 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -39,6 +39,7 @@ func TestMain(m *testing.M) { func TestRunFSCloudExample(t *testing.T) { t.Parallel() + t.Skip() options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ Testing: t, @@ -72,8 +73,79 @@ func TestRunFSCloudExample(t *testing.T) { options.TestTearDown() } +func TestRunDBConnectivity(t *testing.T) { + t.Parallel() + + prefix := "postgres-db-connectivity" + options_postgres := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ + Testing: t, + TerraformDir: "examples/complete", + Prefix: prefix, + Region: "us-south", + ResourceGroup: resourceGroup, + TerraformVars: map[string]interface{}{ + "vpc_network_acls": `[{ + name = "vpc-acl" + add_ibm_cloud_internal_rules = true + add_vpc_connectivity_rules = true + prepend_ibm_rules = true + rules = [ + { + name = "allow-all-inbound" + action = "allow" + direction = "inbound" + destination = "10.10.10.64/32" + source = "0.0.0.0/0" + }, + { + name = "allow-all-outbound" + action = "allow" + direction = "outbound" + destination = "0.0.0.0/0" + source = "10.10.10.64/32" + } + ] + }]`, + }, + }) + options_postgres.SkipTestTearDown = true + output_postgres, err_postgres := options_postgres.RunTestConsistency() + assert.Nil(t, err_postgres, "This should not have errored") + assert.NotNil(t, output_postgres, "Expected some output") + + outputs := terraform.OutputAll(options_postgres.Testing, options_postgres.TerraformOptions) + + var serviceCredential string + for _, data := range outputs["service_credentials_json"].(map[string]interface{}) { + serviceCredential = data.(string) + break + } + assert.NotNil(t, serviceCredential, "Unable to access service credentials") + + options_vsi := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{ + Testing: t, + TerraformDir: "tests/resources", + Prefix: prefix, + Region: "us-south", + TerraformVars: map[string]interface{}{ + "resource_group_id": outputs["resource_group_id"], + "service_credential": serviceCredential, + "vpc_id": outputs["vpc_id"], + "subnet_ids": outputs["subnet_ids"], + "vsi_reserved_ip": "10.10.10.64", + }, + }) + output_vsi, err_vsi := options_vsi.RunTestConsistency() + + assert.Nil(t, err_vsi, "This should not have errored") + assert.NotNil(t, output_vsi, "Expected some output") + options_postgres.TestTearDown() + +} + func TestRunUpgradeCompleteExample(t *testing.T) { t.Parallel() + t.Skip() // Generate a 10 char long random string for the admin_pass randomBytes := make([]byte, 10) diff --git a/tests/resources/main.tf b/tests/resources/main.tf new file mode 100644 index 00000000..5cb982f3 --- /dev/null +++ b/tests/resources/main.tf @@ -0,0 +1,132 @@ + +module "create_sgr_rule_vsi" { + source = "terraform-ibm-modules/security-group/ibm" + version = "v2.0.0" + add_ibm_cloud_internal_rules = false + security_group_name = "${var.prefix}-security-group-vsi" + resource_group = var.resource_group_id + vpc_id = var.vpc_id + security_group_rules = [{ + name = "allow-ssh-inbound" + direction = "inbound" + remote = "0.0.0.0/0" + tcp = { + port_min = 22 + port_max = 22 + } + }, { + name = "allow-http-inbound" + direction = "inbound" + remote = "0.0.0.0/0" + tcp = { + port_min = 80 + port_max = 80 + } + }, { + name = "allow-https-inbound" + direction = "inbound" + remote = "0.0.0.0/0" + tcp = { + port_min = 443 + port_max = 443 + } + }, { + name = "allow-ping-inbound" + direction = "inbound" + remote = "0.0.0.0/0" + icmp = { + type = 8 + } + }] + target_ids = [ibm_is_instance.vsi.primary_network_interface[0].id] +} + + +############################################################################## +# Floating IP +############################################################################## + +resource "ibm_is_floating_ip" "vsi_fip" { + name = "${var.prefix}-fip" + target = ibm_is_instance.vsi.primary_network_interface[0].id +} + +############################################################################## +# SSH Key +############################################################################## + +resource "tls_private_key" "tls_key" { + algorithm = "RSA" + rsa_bits = 4096 +} + +resource "ibm_is_ssh_key" "ssh_key" { + name = "${var.prefix}-ssh-key" + public_key = tls_private_key.tls_key.public_key_openssh +} + +############################################################################## +# VSI +############################################################################## + +resource "ibm_is_instance" "vsi" { + name = "${var.prefix}-vsi" + image = "r006-fedc50ed-8ea3-4a66-9559-c482c4e6ed88" + profile = "cx2-2x4" + resource_group = var.resource_group_id + vpc = var.vpc_id + zone = "${var.region}-1" + keys = [ibm_is_ssh_key.ssh_key.id] + + lifecycle { + ignore_changes = [ + image + ] + } + + primary_network_interface { + subnet = var.subnet_ids[0] + name = "${var.prefix}-eth" + primary_ip { + address = var.vsi_reserved_ip + auto_delete = true + } + } + + timeouts { + create = "15m" + update = "15m" + delete = "15m" + } +} +locals { + composed_string = replace(jsondecode(var.service_credential).connection.cli.composed[0], "sslmode=verify-full", "sslmode=require") +} + +resource "null_resource" "db_connection" { + depends_on = [ + ibm_is_instance.vsi, + module.create_sgr_rule_vsi, +] + + provisioner "remote-exec" { + inline = [ + "sudo apt-get update -y", + "sudo apt-get install postgresql-client -y", + + "${local.composed_string} -c 'CREATE TABLE test (id serial PRIMARY KEY, marks serial);'", + "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (101, 100);'", + "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (102, 200);'", + "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (103, 300);'", + "${local.composed_string} -c 'INSERT INTO test (id, marks) VALUES (104, 400);'", + "${local.composed_string} -c 'SELECT * FROM test;'", + ] + connection { + type = "ssh" + host = ibm_is_floating_ip.vsi_fip.address + user = "root" + private_key = tls_private_key.tls_key.private_key_pem + } + on_failure = fail + } +} \ No newline at end of file diff --git a/tests/resources/provider.tf b/tests/resources/provider.tf new file mode 100644 index 00000000..df45ef50 --- /dev/null +++ b/tests/resources/provider.tf @@ -0,0 +1,4 @@ +provider "ibm" { + ibmcloud_api_key = var.ibmcloud_api_key + region = var.region +} diff --git a/tests/resources/variables.tf b/tests/resources/variables.tf new file mode 100644 index 00000000..a92cb4ee --- /dev/null +++ b/tests/resources/variables.tf @@ -0,0 +1,54 @@ +variable "ibmcloud_api_key" { + type = string + description = "The IBM Cloud API Key" + sensitive = true +} + +variable "region" { + type = string + description = "Region to provision all resources created by this example." + default = "us-south" +} + +variable "prefix" { + type = string + description = "Prefix to append to all resources created by this example" + default = "postgres" +} + +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 "resource_tags" { + type = list(string) + description = "Optional list of tags to be added to created resources" + default = [] +} + +variable "service_credential" { + type = string + description = "Database service credential" +} + +variable "resource_group_id" { + type = string + description = "Id of existing resource_group" +} + +variable "vpc_id" { + type = string + description = "Id of existing vpc" +} + +variable "subnet_ids" { + type = list(string) + description = "List of subnet ids" +} + +variable "vsi_reserved_ip"{ + type = string + description = "Reserved IP for vsi" +} + diff --git a/tests/resources/version.tf b/tests/resources/version.tf new file mode 100644 index 00000000..0260a803 --- /dev/null +++ b/tests/resources/version.tf @@ -0,0 +1,23 @@ +terraform { + required_version = ">= 1.3.0, <1.6.0" + required_providers { + # Use latest version of provider in non-basic examples to verify latest version works with module + ibm = { + source = "IBM-Cloud/ibm" + version = ">= 1.56.1" + } + time = { + source = "hashicorp/time" + version = ">= 0.8.0" + } + null = { + source = "hashicorp/null" + version = ">= 3.2.1" + } + + tls = { + source = "hashicorp/tls" + version = ">= 4.0.4" + } + } +} \ No newline at end of file From 6697d046346c49774c52eff7b6c154533a47eb48 Mon Sep 17 00:00:00 2001 From: Mohammad Soaib Date: Tue, 21 Nov 2023 19:15:25 +0530 Subject: [PATCH 12/12] test: used RunTest method in TestRunDBConnectivity for complete example --- tests/pr_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/pr_test.go b/tests/pr_test.go index 8877f1f9..aac658c2 100644 --- a/tests/pr_test.go +++ b/tests/pr_test.go @@ -108,7 +108,7 @@ func TestRunDBConnectivity(t *testing.T) { }, }) options_postgres.SkipTestTearDown = true - output_postgres, err_postgres := options_postgres.RunTestConsistency() + output_postgres, err_postgres := options_postgres.RunTest() assert.Nil(t, err_postgres, "This should not have errored") assert.NotNil(t, output_postgres, "Expected some output") @@ -135,13 +135,13 @@ func TestRunDBConnectivity(t *testing.T) { }, }) output_vsi, err_vsi := options_vsi.RunTestConsistency() - + options_postgres.TestTearDown() assert.Nil(t, err_vsi, "This should not have errored") assert.NotNil(t, output_vsi, "Expected some output") - options_postgres.TestTearDown() } + func TestRunUpgradeCompleteExample(t *testing.T) { t.Parallel()