Skip to content

Commit

Permalink
feat: add reserved ip submodule
Browse files Browse the repository at this point in the history
  • Loading branch information
Jordan-Williams2 authored and Jordan-Williams2 committed Jan 19, 2024
1 parent b7ea2ba commit cffb03d
Show file tree
Hide file tree
Showing 18 changed files with 625 additions and 18 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ This module creates and configures virtual private endpoint gateways (https://cl
The module supports the following actions:
- Create virtual private endpoint gateways
- Create reserved IP addresses
- Attach endpoint gateways to reserved IP addresses
- Attach endpoint gateways to reserved IP addresses.

### Known provider issues

Expand All @@ -21,9 +21,12 @@ An IBM Provider [issue](https://github.com/IBM-Cloud/terraform-provider-ibm/issu
<!-- BEGIN OVERVIEW HOOK -->
## Overview
* [terraform-ibm-vpe-gateway](#terraform-ibm-vpe-gateway)
* [Submodules](./modules)
* [reserved-ips](./modules/reserved-ips)
* [Examples](./examples)
* [End-to-end example](./examples/default)
* [Every multi-tenant VPE](./examples/every-mt-vpe)
* [Existing Reserved IPs example](./examples/reserved-ips)
* [Contributing](#contributing)
<!-- END OVERVIEW HOOK -->

Expand Down Expand Up @@ -99,13 +102,14 @@ You need the following permissions to run this module.

### Modules

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

### Resources

| Name | Type |
|------|------|
| [ibm_is_subnet_reserved_ip.ip](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_subnet_reserved_ip) | resource |
| [ibm_is_virtual_endpoint_gateway.vpe](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_virtual_endpoint_gateway) | resource |
| [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 |
| [ibm_is_virtual_endpoint_gateway.vpe](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/is_virtual_endpoint_gateway) | data source |
Expand All @@ -116,14 +120,15 @@ No modules.
|------|-------------|------|---------|:--------:|
| <a name="input_cloud_service_by_crn"></a> [cloud\_service\_by\_crn](#input\_cloud\_service\_by\_crn) | List of cloud service CRNs. The keys are the CRN. The values (all optional) give some level of control on the created VPEs. Each CRN will have a unique endpoint gateways created. For a list of supported services, see the docs [here](https://cloud.ibm.com/docs/vpc?topic=vpc-vpe-supported-services). | <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 |
| <a name="input_cloud_services"></a> [cloud\_services](#input\_cloud\_services) | List of cloud services to create an endpoint gateway. The keys are the service names, the values (all optional) give some level of control on the created VPEs. | <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 |
| <a name="input_prefix"></a> [prefix](#input\_prefix) | The prefix that you would like to append to your resources | `string` | `"vpe"` | no |
| <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 |
| <a name="input_region"></a> [region](#input\_region) | The region where VPC and services are deployed | `string` | `"us-south"` | no |
| <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) # endpoint gateway IP ID<br> })</pre> | `{}` | no |
| <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 |
| <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 |
| <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 |
| <a name="input_subnet_zone_list"></a> [subnet\_zone\_list](#input\_subnet\_zone\_list) | 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 Landing Zone VPC Subnet Module (https://github.com/terraform-ibm-modules/terraform-ibm-landing-zone-vpc) or from templates using that module for subnet creation. | <pre>list(<br> object({<br> name = string<br> id = string<br> zone = optional(string)<br> cidr = optional(string)<br> })<br> )</pre> | `[]` | no |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | ID of the VPC where the Endpoint Gateways will be created | `string` | `null` | no |
| <a name="input_vpc_name"></a> [vpc\_name](#input\_vpc\_name) | Name of the VPC where the Endpoint Gateways will be created. This value is used to dynamically generate VPE names. | `string` | `"vpc"` | no |
| <a name="input_vpc_name"></a> [vpc\_name](#input\_vpc\_name) | Name of the VPC where the Endpoint Gateways will be created. This value is used to dynamically generate VPE names. Value is only used if no value is passed for the `vpe_name` option in the `cloud_services` input variable. | `string` | `"vpc"` | no |

### Outputs

Expand Down
2 changes: 1 addition & 1 deletion common-dev-assets
1 change: 0 additions & 1 deletion examples/default/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ module "vpes" {
{
service_name = "cloud-object-storage"
}

]
cloud_service_by_crn = [
{
Expand Down
15 changes: 15 additions & 0 deletions examples/reserved-ips/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Existing Reserved IPs example

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.

This example creates the following infrastructure:
- A resource group, if one is not passed in.
- A VPC, if one is not passed in.
- The VPC is created with three subnets across the three availability zones of the region that is passed as input.
- A security group in the VPC.
- 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.
- The reserved IPs are created. These are later passed to the gateway as an example of how the reserved IPs module could be used.
- 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.
- Each of the two virtual private endpoint gateways are attached to the three VPC subnets.
- The new security group is attached to the two VPE gateways.
- Passes existing reserved ip values to be used instead of creating new ones.
96 changes: 96 additions & 0 deletions examples/reserved-ips/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
##############################################################################
# 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
}

##############################################################################
# Create a VPC for this example using defaults from terraform-ibm-landing-zone-vpc
# ( 3 subnets across the 3 AZs in the region )
##############################################################################

module "vpc" {
count = var.vpc_id != null ? 0 : 1
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
name = var.vpc_name
tags = var.resource_tags
}

##############################################################################
# Demonstrate how to create a custom security group that is applied to the VPEs
# This examples allow all workload associated with the default VPC security group
# to interact with the VPEs
##############################################################################

data "ibm_is_vpc" "vpc" {
# Explicit depends as the vpc_name is known prior to VPC creation
depends_on = [
module.vpc
]
name = var.vpc_id != null ? var.vpc_id : module.vpc[0].vpc_name
}

data "ibm_is_security_group" "default_sg" {
name = data.ibm_is_vpc.vpc.default_security_group_name
}

module "vpe_security_group" {
source = "terraform-ibm-modules/security-group/ibm"
version = "2.0.0"
security_group_name = "${var.prefix}-vpe-sg"
add_ibm_cloud_internal_rules = false # No need for the internal ibm cloud rules for SG associated with VPEs

security_group_rules = [{
name = "allow-all-default-sg-inbound"
direction = "inbound"
remote = data.ibm_is_security_group.default_sg.id
}]

resource_group = module.resource_group.resource_group_id
vpc_id = var.vpc_id != null ? var.vpc_id : module.vpc[0].vpc_id
}

##############################################################################
# Create Reserved IPs in the VPC
##############################################################################
module "ips" {
source = "../../modules/reserved-ips"
region = var.region
subnet_zone_list = var.vpc_id != null ? var.subnet_zone_list : module.vpc[0].subnet_zone_list
reserved_ips = {}
reserved_ip_cloud_services = [
{
service_name = "kms"
},
{
service_name = "cloud-object-storage"
}
]
}

##############################################################################
# Create VPEs in the VPC
##############################################################################
module "vpes" {
source = "../../"
region = var.region
prefix = var.prefix
vpc_name = var.vpc_name
vpc_id = var.vpc_id != null ? var.vpc_id : module.vpc[0].vpc_id
subnet_zone_list = var.vpc_id != null ? var.subnet_zone_list : module.vpc[0].subnet_zone_list
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]
service_endpoints = var.service_endpoints
reserved_ips = module.ips.reserved_ip_map
}

##############################################################################
25 changes: 25 additions & 0 deletions examples/reserved-ips/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
output "vpe_ips" {
description = "The endpoint gateway reserved ips"
value = module.vpes.vpe_ips
}

output "crn" {
description = "The CRN of the endpoint gateway"
value = module.vpes.crn
}


output "reserved_ips" {
description = "The map of reserved ips created in the example"
value = module.ips.reserved_ip_map
}

output "endpoint_ip_list" {
description = "The endpoint ip list created in the example"
value = module.ips.endpoint_ip_list
}

output "subnet_zone_list" {
description = "The subnet zone list created in the example"
value = var.vpc_id != null ? var.subnet_zone_list : module.vpc[0].subnet_zone_list
}
4 changes: 4 additions & 0 deletions examples/reserved-ips/provider.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
provider "ibm" {
ibmcloud_api_key = var.ibmcloud_api_key
region = var.region
}
83 changes: 83 additions & 0 deletions examples/reserved-ips/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
variable "ibmcloud_api_key" {
type = string
description = "The IBM Cloud API Key"
sensitive = true
}

variable "region" {
description = "The region where VPC and services are deployed"
type = string
default = "us-south"
}

variable "prefix" {
description = "The prefix that you would like to append to your resources"
type = string
default = "vpe"
}

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
}

##############################################################################
# VPC Variables
##############################################################################

variable "vpc_name" {
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."
type = string
default = "vpc-instance"
}

variable "vpc_id" {
description = "ID of the VPC where the Endpoint Gateways will be created. Creates a VPC if set to null."
type = string
default = null
}

##############################################################################

##############################################################################
# VPE Variables
##############################################################################

variable "subnet_zone_list" {
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."
type = list(
object({
name = string
id = string
zone = optional(string)
cidr = optional(string)
})
)
default = []
}

variable "security_group_ids" {
description = "List of security group ids to attach to each endpoint gateway."
type = list(string)
default = null
}

variable "service_endpoints" {
description = "Service endpoints to use to create endpoint gateways. Can be `public`, or `private`."
type = string
default = "private"

validation {
error_message = "Service endpoints can only be `public` or `private`."
condition = contains(["public", "private"], var.service_endpoints)
}
}

variable "resource_tags" {
type = list(string)
description = "Optional list of tags to be added to created resources"
default = []
}

##############################################################################
15 changes: 15 additions & 0 deletions examples/reserved-ips/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
##############################################################################
# Terraform Providers
##############################################################################

terraform {
required_version = ">= 1.3.0"
required_providers {
ibm = {
source = "IBM-Cloud/ibm"
version = ">= 1.58.0"
}
}
}

##############################################################################
16 changes: 7 additions & 9 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,12 @@ locals {
# Create Reserved IPs
##############################################################################

resource "ibm_is_subnet_reserved_ip" "ip" {
for_each = {
# Create a map based on endpoint IP name
for gateway_ip in local.endpoint_ip_list :
(gateway_ip.ip_name) => gateway_ip
}
name = each.value.name
subnet = each.value.subnet_id
module "ip" {
source = "./modules/reserved-ips"
endpoint_ip_list = local.endpoint_ip_list
reserved_ips = var.reserved_ips
prefix = var.prefix
vpc_name = var.vpc_name
}

##############################################################################
Expand Down Expand Up @@ -113,7 +111,7 @@ resource "ibm_is_virtual_endpoint_gateway_ip" "endpoint_gateway_ip" {
(gateway_ip.ip_name) => gateway_ip
}
gateway = local.vpe_map[each.value.gateway_name].id
reserved_ip = ibm_is_subnet_reserved_ip.ip[each.key].reserved_ip
reserved_ip = lookup(var.reserved_ips, each.value.name, module.ip.reserved_ip_map[each.value.name])
}

##############################################################################
Expand Down
Loading

0 comments on commit cffb03d

Please sign in to comment.