Skip to content

Commit

Permalink
fix: create VPE when crn name is unknown at plan time
Browse files Browse the repository at this point in the history
* fix: create VPE when crn name is unknown at plan time
* fix: handle ip reservation and binding for instance vpe
  • Loading branch information
vburckhardt committed May 29, 2023
1 parent d31065e commit 5a80541
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 26 deletions.
36 changes: 29 additions & 7 deletions examples/default/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,25 @@ module "vpe_security_group" {
vpc_id = var.vpc_id != null ? var.vpc_id : module.vpc[0].vpc_id
}


##############################################################################
# Create a PostgreSQL instance to demonstrate how to create an instance VPE
##############################################################################

module "postgresql_db" {
source = "git::https://github.com/terraform-ibm-modules/terraform-ibm-icd-postgresql?ref=v3.1.0"
resource_group_id = module.resource_group.resource_group_id
name = "${var.prefix}-vpe-pg"
region = var.region
}

locals {
cloud_service_by_crn = concat([{
name = "postgresql" # name of the vpe
crn = module.postgresql_db.crn }
], var.cloud_service_by_crn)
}

##############################################################################
# Create VPEs in the VPC
##############################################################################
Expand All @@ -69,16 +88,19 @@ module "vpes" {
resource_group_id = module.resource_group.resource_group_id
security_group_ids = var.security_group_ids != null ? var.security_group_ids : [module.vpe_security_group.security_group_id]
cloud_services = var.cloud_services
cloud_service_by_crn = var.cloud_service_by_crn
cloud_service_by_crn = local.cloud_service_by_crn
service_endpoints = var.service_endpoints
# Wait 30secs after security group is destroyed before destroying VPE to workaround timing issue which can produce “Target not found” error on destroy
depends_on = [time_sleep.wait_30_seconds]
# See comments below (resource "time_sleep" "sleep_time") for explaination on why this is needed.
depends_on = [time_sleep.sleep_time]
}

resource "time_sleep" "wait_30_seconds" {
depends_on = [data.ibm_is_security_group.default_sg]

destroy_duration = "30s"
## This sleep serve two purposes:
# 1. Give some extra time after postgresql db creation, and before creating the VPE targetting it. This works around the error "Service does not support VPE extensions."
# 2. Give time on deletion between the VPE destruction and the destruction of the SG that is attached to the VPE. This works around the error "Target not found"
resource "time_sleep" "sleep_time" {
depends_on = [module.vpe_security_group.security_group_id, module.postgresql_db]
create_duration = "120s"
destroy_duration = "120s"
}


Expand Down
4 changes: 4 additions & 0 deletions examples/default/moved.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
moved {
from = time_sleep.wait_30_seconds
to = time_sleep.sleep_time
}
33 changes: 21 additions & 12 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,30 @@ locals {
endpoint_ip_list = flatten([
# Create object for each subnet
for subnet in var.subnet_zone_list :
[
concat([
for service in var.cloud_services :
{
ip_name = "${subnet.name}-${service}-gateway-${replace(subnet.zone, "/${var.region}-/", "")}-ip"
subnet_id = subnet.id
gateway_name = "${var.vpc_name}-${service}"
gateway_name = "${var.prefix}-${var.vpc_name}-${service}"
}
]
],
[
for service in var.cloud_service_by_crn :
{
ip_name = "${subnet.name}-${service.name}-gateway-${replace(subnet.zone, "/${var.region}-/", "")}-ip"
subnet_id = subnet.id
gateway_name = "${var.prefix}-${var.vpc_name}-${service.name}"
}
])
])

# Convert the virtual_endpoint_gateway output from list to a map
vpe_map = {
for gateway in ibm_is_virtual_endpoint_gateway.vpe :
(gateway.name) => gateway
}

# Map of Services to endpoints
service_to_endpoint_map = {
kms = "crn:v1:bluemix:public:kms:${var.region}:::endpoint:${var.service_endpoints}.${var.region}.kms.cloud.ibm.com"
Expand Down Expand Up @@ -68,18 +82,13 @@ resource "ibm_is_subnet_reserved_ip" "ip" {
##############################################################################

resource "ibm_is_virtual_endpoint_gateway" "vpe" {
for_each = {
# Create map based on gateway name if enabled
for gateway in local.gateway_list :
(gateway.name) => gateway
}

name = "${var.prefix}-${each.key}"
count = length(local.gateway_list)
name = "${var.prefix}-${local.gateway_list[count.index].name}"
vpc = var.vpc_id
resource_group = var.resource_group_id
security_groups = var.security_group_ids
target {
crn = each.value.service == null ? each.value.crn : local.service_to_endpoint_map[each.value.service]
crn = local.gateway_list[count.index].service == null ? local.gateway_list[count.index].crn : local.service_to_endpoint_map[local.gateway_list[count.index].service]
resource_type = "provider_cloud_service"
}
}
Expand All @@ -96,7 +105,7 @@ resource "ibm_is_virtual_endpoint_gateway_ip" "endpoint_gateway_ip" {
for gateway_ip in local.endpoint_ip_list :
(gateway_ip.ip_name) => gateway_ip
}
gateway = ibm_is_virtual_endpoint_gateway.vpe[each.value.gateway_name].id
gateway = local.vpe_map[each.value.gateway_name].id
reserved_ip = ibm_is_subnet_reserved_ip.ip[each.key].reserved_ip
}

Expand Down
6 changes: 3 additions & 3 deletions module-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
},
"pos": {
"filename": "main.tf",
"line": 55
"line": 69
}
},
"ibm_is_virtual_endpoint_gateway.vpe": {
Expand All @@ -168,7 +168,7 @@
},
"pos": {
"filename": "main.tf",
"line": 70
"line": 84
}
},
"ibm_is_virtual_endpoint_gateway_ip.endpoint_gateway_ip": {
Expand All @@ -180,7 +180,7 @@
},
"pos": {
"filename": "main.tf",
"line": 93
"line": 102
}
}
},
Expand Down
9 changes: 9 additions & 0 deletions moved.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
moved {
from = ibm_is_virtual_endpoint_gateway.vpe["vpc-instance-cloud-object-storage"]
to = ibm_is_virtual_endpoint_gateway.vpe[1]
}

moved {
from = ibm_is_virtual_endpoint_gateway.vpe["vpc-instance-kms"]
to = ibm_is_virtual_endpoint_gateway.vpe[0]
}
12 changes: 8 additions & 4 deletions tests/pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ const defaultExampleTerraformDir = "examples/default"

func setupOptions(t *testing.T, prefix string, dir string) *testhelper.TestOptions {
options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{
Testing: t,
TerraformDir: dir,
Prefix: prefix,
Testing: t,
TerraformDir: dir,
Prefix: prefix,
IgnoreUpdates: testhelper.Exemptions{ // Ignore for consistency check
List: []string{
"time_sleep.sleep_time",
},
},
ResourceGroup: resourceGroup,
})
return options
Expand All @@ -32,7 +37,6 @@ func TestRunDefaultExample(t *testing.T) {
}

func TestRunUpgradeExample(t *testing.T) {
t.Skip()
t.Parallel()

options := setupOptions(t, "vpe-upgrade", defaultExampleTerraformDir)
Expand Down

0 comments on commit 5a80541

Please sign in to comment.