Skip to content

Commit a32c967

Browse files
jor2Jordan-Williams2
andauthored
feat: allow use of existing reserved ip for endpoints (#415) <br> - Provides a way to create a reserved ip independently from the VPE creation. <br> - New optional input variable reserved_ips can be used to supply existing IPs <br> - New submodule modules/reserved-ips which can be used to manage reserved IPs separate from VPE module
* feat: add reserved ip submodule * fix: disable dns-svc for time being --------- Co-authored-by: Jordan-Williams2 <[email protected]>
1 parent c528b11 commit a32c967

File tree

17 files changed

+581
-15
lines changed

17 files changed

+581
-15
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ This module creates and configures virtual private endpoint gateways (https://cl
1111
The module supports the following actions:
1212
- Create virtual private endpoint gateways
1313
- Create reserved IP addresses
14-
- Attach endpoint gateways to reserved IP addresses
14+
- Attach endpoint gateways to reserved IP addresses.
1515

1616
### Known provider issues
1717

@@ -21,9 +21,12 @@ An IBM Provider [issue](https://github.com/IBM-Cloud/terraform-provider-ibm/issu
2121
<!-- BEGIN OVERVIEW HOOK -->
2222
## Overview
2323
* [terraform-ibm-vpe-gateway](#terraform-ibm-vpe-gateway)
24+
* [Submodules](./modules)
25+
* [reserved-ips](./modules/reserved-ips)
2426
* [Examples](./examples)
2527
* [Advanced dedicated service VPE gateway](./examples/advanced)
2628
* [Basic multi-tenant VPE gateway](./examples/basic)
29+
* [Existing Reserved IPs example](./examples/reserved-ips)
2730
* [Contributing](#contributing)
2831
<!-- END OVERVIEW HOOK -->
2932

@@ -103,13 +106,14 @@ You need the following permissions to run this module.
103106

104107
### Modules
105108

106-
No modules.
109+
| Name | Source | Version |
110+
|------|--------|---------|
111+
| <a name="module_ip"></a> [ip](#module\_ip) | ./modules/reserved-ips | n/a |
107112

108113
### Resources
109114

110115
| Name | Type |
111116
|------|------|
112-
| [ibm_is_subnet_reserved_ip.ip](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_subnet_reserved_ip) | resource |
113117
| [ibm_is_virtual_endpoint_gateway.vpe](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_virtual_endpoint_gateway) | resource |
114118
| [ibm_is_virtual_endpoint_gateway_ip.endpoint_gateway_ip](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_virtual_endpoint_gateway_ip) | resource |
115119
| [ibm_is_virtual_endpoint_gateway.vpe](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/is_virtual_endpoint_gateway) | data source |
@@ -120,8 +124,9 @@ No modules.
120124
|------|-------------|------|---------|:--------:|
121125
| <a name="input_cloud_service_by_crn"></a> [cloud\_service\_by\_crn](#input\_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 `<prefix>-<vpc_name>-<service_name>`. The value that you specify for `vpc_name` must be known at Terraform plan time. | <pre>set(<br/> object({<br/> crn = string<br/> 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.<br/> 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.<br/> allow_dns_resolution_binding = optional(bool, true)<br/> })<br/> )</pre> | `[]` | no |
122126
| <a name="input_cloud_services"></a> [cloud\_services](#input\_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 `<prefix>-<vpc_name>-<service_name>`. The value that you specify for `vpc_name` must be known at Terraform plan time. | <pre>set(object({<br/> service_name = string<br/> 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.<br/> allow_dns_resolution_binding = optional(bool, false)<br/> }))</pre> | `[]` | no |
123-
| <a name="input_prefix"></a> [prefix](#input\_prefix) | The prefix that you would like to append to your resources | `string` | `"vpe"` | no |
127+
| <a name="input_prefix"></a> [prefix](#input\_prefix) | The prefix that you would like to append to your resources. Value is only used if no value is passed for the `vpe_name` option in the `cloud_services` input variable. | `string` | `"vpe"` | no |
124128
| <a name="input_region"></a> [region](#input\_region) | The region where VPC and services are deployed | `string` | `"us-south"` | no |
129+
| <a name="input_reserved_ips"></a> [reserved\_ips](#input\_reserved\_ips) | Map of existing reserved IP names and values. If you wish to create your reserved ips independently and not create new ones you can first run the `reserved-ips` submodule and then copy the output `reserved_ip_map` here. | <pre>object({<br/> name = optional(string) # reserved ip name<br/> })</pre> | `{}` | no |
125130
| <a name="input_resource_group_id"></a> [resource\_group\_id](#input\_resource\_group\_id) | ID of the resource group where endpoint gateways will be provisioned | `string` | `null` | no |
126131
| <a name="input_security_group_ids"></a> [security\_group\_ids](#input\_security\_group\_ids) | List of security group ids to attach to each endpoint gateway. | `list(string)` | `null` | no |
127132
| <a name="input_service_endpoints"></a> [service\_endpoints](#input\_service\_endpoints) | Service endpoints to use to create endpoint gateways. Can be `public`, or `private`. | `string` | `"private"` | no |

examples/advanced/main.tf

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ module "vpes" {
9191
{
9292
service_name = "cloud-object-storage"
9393
}
94-
9594
]
9695
cloud_service_by_crn = [
9796
{

examples/reserved-ips/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Existing Reserved IPs example
2+
3+
This example creates reserved ips in the example and passes those values to the main modules `reserved_ips` variable which will use those existing reserved ips instead of creating new values.
4+
5+
This example creates the following infrastructure:
6+
- A resource group, if one is not passed in.
7+
- A VPC, if one is not passed in.
8+
- The VPC is created with three subnets across the three availability zones of the region that is passed as input.
9+
- A security group in the VPC.
10+
- The security group is created with a single inbound rule that allows traffic from resources that are attached to the default VPC security group. This rule is added as an example.
11+
- The reserved IPs are created. These are later passed to the gateway as an example of how the reserved IPs module could be used.
12+
- Two virtual private endpoint (VPE) gateways. By default, one VPE to COS and another VPE to Key Protect are created. You can change the defaults by using the `service_endpoints` input.
13+
- Each of the two virtual private endpoint gateways are attached to the three VPC subnets.
14+
- The new security group is attached to the two VPE gateways.
15+
- Passes existing reserved ip values to be used instead of creating new ones.

examples/reserved-ips/main.tf

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
##############################################################################
2+
# Resource Group
3+
##############################################################################
4+
module "resource_group" {
5+
source = "terraform-ibm-modules/resource-group/ibm"
6+
version = "1.0.6"
7+
# if an existing resource group is not set (null) create a new one using prefix
8+
resource_group_name = var.resource_group == null ? "${var.prefix}-resource-group" : null
9+
existing_resource_group_name = var.resource_group
10+
}
11+
12+
##############################################################################
13+
# Create a VPC for this example using defaults from terraform-ibm-landing-zone-vpc
14+
# ( 3 subnets across the 3 AZs in the region )
15+
##############################################################################
16+
17+
module "vpc" {
18+
count = var.vpc_id != null ? 0 : 1
19+
source = "terraform-ibm-modules/landing-zone-vpc/ibm"
20+
version = "7.5.0"
21+
resource_group_id = module.resource_group.resource_group_id
22+
region = var.region
23+
prefix = var.prefix
24+
name = var.vpc_name
25+
tags = var.resource_tags
26+
}
27+
28+
##############################################################################
29+
# Demonstrate how to create a custom security group that is applied to the VPEs
30+
# This examples allow all workload associated with the default VPC security group
31+
# to interact with the VPEs
32+
##############################################################################
33+
34+
data "ibm_is_vpc" "vpc" {
35+
# Explicit depends as the vpc_name is known prior to VPC creation
36+
depends_on = [
37+
module.vpc
38+
]
39+
name = var.vpc_id != null ? var.vpc_id : module.vpc[0].vpc_name
40+
}
41+
42+
data "ibm_is_security_group" "default_sg" {
43+
name = data.ibm_is_vpc.vpc.default_security_group_name
44+
}
45+
46+
module "vpe_security_group" {
47+
source = "terraform-ibm-modules/security-group/ibm"
48+
version = "2.0.0"
49+
security_group_name = "${var.prefix}-vpe-sg"
50+
add_ibm_cloud_internal_rules = false # No need for the internal ibm cloud rules for SG associated with VPEs
51+
52+
security_group_rules = [{
53+
name = "allow-all-default-sg-inbound"
54+
direction = "inbound"
55+
remote = data.ibm_is_security_group.default_sg.id
56+
}]
57+
58+
resource_group = module.resource_group.resource_group_id
59+
vpc_id = var.vpc_id != null ? var.vpc_id : module.vpc[0].vpc_id
60+
}
61+
62+
##############################################################################
63+
# Create Reserved IPs in the VPC
64+
##############################################################################
65+
module "ips" {
66+
source = "../../modules/reserved-ips"
67+
region = var.region
68+
subnet_zone_list = var.vpc_id != null ? var.subnet_zone_list : module.vpc[0].subnet_zone_list
69+
reserved_ips = {}
70+
reserved_ip_cloud_services = [
71+
{
72+
service_name = "kms"
73+
},
74+
{
75+
service_name = "cloud-object-storage"
76+
}
77+
]
78+
}
79+
80+
##############################################################################
81+
# Create VPEs in the VPC
82+
##############################################################################
83+
module "vpes" {
84+
source = "../../"
85+
region = var.region
86+
prefix = var.prefix
87+
vpc_name = var.vpc_name
88+
vpc_id = var.vpc_id != null ? var.vpc_id : module.vpc[0].vpc_id
89+
subnet_zone_list = var.vpc_id != null ? var.subnet_zone_list : module.vpc[0].subnet_zone_list
90+
resource_group_id = module.resource_group.resource_group_id
91+
security_group_ids = var.security_group_ids != null ? var.security_group_ids : [module.vpe_security_group.security_group_id]
92+
service_endpoints = var.service_endpoints
93+
reserved_ips = module.ips.reserved_ip_map
94+
}
95+
96+
##############################################################################

examples/reserved-ips/outputs.tf

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
output "vpe_ips" {
2+
description = "The endpoint gateway reserved ips"
3+
value = module.vpes.vpe_ips
4+
}
5+
6+
output "crn" {
7+
description = "The CRN of the endpoint gateway"
8+
value = module.vpes.crn
9+
}
10+
11+
12+
output "reserved_ips" {
13+
description = "The map of reserved ips created in the example"
14+
value = module.ips.reserved_ip_map
15+
}
16+
17+
output "endpoint_ip_list" {
18+
description = "The endpoint ip list created in the example"
19+
value = module.ips.endpoint_ip_list
20+
}
21+
22+
output "subnet_zone_list" {
23+
description = "The subnet zone list created in the example"
24+
value = var.vpc_id != null ? var.subnet_zone_list : module.vpc[0].subnet_zone_list
25+
}

examples/reserved-ips/provider.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
provider "ibm" {
2+
ibmcloud_api_key = var.ibmcloud_api_key
3+
region = var.region
4+
}

examples/reserved-ips/variables.tf

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
variable "ibmcloud_api_key" {
2+
type = string
3+
description = "The IBM Cloud API Key"
4+
sensitive = true
5+
}
6+
7+
variable "region" {
8+
description = "The region where VPC and services are deployed"
9+
type = string
10+
default = "us-south"
11+
}
12+
13+
variable "prefix" {
14+
description = "The prefix that you would like to append to your resources"
15+
type = string
16+
default = "vpe"
17+
}
18+
19+
variable "resource_group" {
20+
type = string
21+
description = "An existing resource group name to use for this example, if unset a new resource group will be created"
22+
default = null
23+
}
24+
25+
##############################################################################
26+
# VPC Variables
27+
##############################################################################
28+
29+
variable "vpc_name" {
30+
description = "Name of the VPC where the Endpoint Gateways will be created. This value is used to dynamically generate VPE names. It is also used to create a VPC when the vpc_id input is set to null."
31+
type = string
32+
default = "vpc-instance"
33+
}
34+
35+
variable "vpc_id" {
36+
description = "ID of the VPC where the Endpoint Gateways will be created. Creates a VPC if set to null."
37+
type = string
38+
default = null
39+
}
40+
41+
##############################################################################
42+
43+
##############################################################################
44+
# VPE Variables
45+
##############################################################################
46+
47+
variable "subnet_zone_list" {
48+
description = "List of subnets in the VPC where gateways and reserved IPs will be provisioned. This value is intended to use the `subnet_zone_list` output from the ICSE VPC Subnet Module (https://github.com/Cloud-Schematics/vpc-subnet-module) or from templates using that module for subnet creation."
49+
type = list(
50+
object({
51+
name = string
52+
id = string
53+
zone = optional(string)
54+
cidr = optional(string)
55+
})
56+
)
57+
default = []
58+
}
59+
60+
variable "security_group_ids" {
61+
description = "List of security group ids to attach to each endpoint gateway."
62+
type = list(string)
63+
default = null
64+
}
65+
66+
variable "service_endpoints" {
67+
description = "Service endpoints to use to create endpoint gateways. Can be `public`, or `private`."
68+
type = string
69+
default = "private"
70+
71+
validation {
72+
error_message = "Service endpoints can only be `public` or `private`."
73+
condition = contains(["public", "private"], var.service_endpoints)
74+
}
75+
}
76+
77+
variable "resource_tags" {
78+
type = list(string)
79+
description = "Optional list of tags to be added to created resources"
80+
default = []
81+
}
82+
83+
##############################################################################

examples/reserved-ips/versions.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
##############################################################################
2+
# Terraform Providers
3+
##############################################################################
4+
5+
terraform {
6+
required_version = ">= 1.3.0"
7+
required_providers {
8+
ibm = {
9+
source = "IBM-Cloud/ibm"
10+
version = ">= 1.58.0"
11+
}
12+
}
13+
}
14+
15+
##############################################################################

main.tf

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,12 @@ locals {
6565
# Create Reserved IPs
6666
##############################################################################
6767

68-
resource "ibm_is_subnet_reserved_ip" "ip" {
69-
for_each = {
70-
# Create a map based on endpoint IP name
71-
for gateway_ip in local.endpoint_ip_list :
72-
(gateway_ip.ip_name) => gateway_ip
73-
}
74-
name = each.value.name
75-
subnet = each.value.subnet_id
68+
module "ip" {
69+
source = "./modules/reserved-ips"
70+
endpoint_ip_list = local.endpoint_ip_list
71+
reserved_ips = var.reserved_ips
72+
prefix = var.prefix
73+
vpc_name = var.vpc_name
7674
}
7775

7876
##############################################################################
@@ -113,7 +111,7 @@ resource "ibm_is_virtual_endpoint_gateway_ip" "endpoint_gateway_ip" {
113111
(gateway_ip.ip_name) => gateway_ip
114112
}
115113
gateway = local.vpe_map[each.value.gateway_name].id
116-
reserved_ip = ibm_is_subnet_reserved_ip.ip[each.key].reserved_ip
114+
reserved_ip = lookup(var.reserved_ips, each.value.name, module.ip.reserved_ip_map[each.value.name])
117115
}
118116

119117
##############################################################################

0 commit comments

Comments
 (0)