diff --git a/README.md b/README.md index 65e5d28e..37a48bc0 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,8 @@ You need the following permissions to run this module. | [ibm_is_vpc.vpc](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc) | resource | | [ibm_is_vpc_address_prefix.address_prefixes](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_address_prefix) | resource | | [ibm_is_vpc_address_prefix.subnet_prefix](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_address_prefix) | resource | -| [ibm_is_vpc_route.route](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_route) | resource | +| [ibm_is_vpc_routing_table.route_table](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_routing_table) | resource | +| [ibm_is_vpc_routing_table_route.routing_table_routes](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_vpc_routing_table_route) | resource | ## Inputs @@ -169,7 +170,7 @@ You need the following permissions to run this module. | [prefix](#input\_prefix) | The prefix that you would like to append to your resources | `string` | n/a | yes | | [region](#input\_region) | The region to which to deploy the VPC | `string` | n/a | yes | | [resource\_group\_id](#input\_resource\_group\_id) | The resource group ID where the VPC to be created | `string` | n/a | yes | -| [routes](#input\_routes) | OPTIONAL - Allows you to specify the next hop for packets based on their destination address |
list(
object({
name = string
zone = number
destination = string
next_hop = string
})
)
| `[]` | no | +| [routes](#input\_routes) | OPTIONAL - Allows you to specify the next hop for packets based on their destination address |
list(
object({
name = string
route_direct_link_ingress = optional(bool)
route_transit_gateway_ingress = optional(bool)
route_vpc_zone_ingress = optional(bool)
routes = optional(
list(
object({
action = optional(string)
zone = number
destination = string
next_hop = string
})
))
})
)
| `[]` | no | | [security\_group\_rules](#input\_security\_group\_rules) | A list of security group rules to be added to the default vpc security group |
list(
object({
name = string
direction = string
remote = string
tcp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
udp = optional(
object({
port_max = optional(number)
port_min = optional(number)
})
)
icmp = optional(
object({
type = optional(number)
code = optional(number)
})
)
})
)
|
[
{
"direction": "inbound",
"name": "default-sgr",
"remote": "10.0.0.0/8"
}
]
| no | | [subnets](#input\_subnets) | List of subnets for the vpc. For each item in each array, a subnet will be created. Items can be either CIDR blocks or total ipv4 addressess. Public gateways will be enabled only in zones where a gateway has been created |
object({
zone-1 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
}))
zone-2 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
}))
zone-3 = list(object({
name = string
cidr = string
public_gateway = optional(bool)
acl_name = string
}))
})
|
{
"zone-1": [
{
"acl_name": "vpc-acl",
"cidr": "10.10.10.0/24",
"name": "subnet-a",
"public_gateway": true
}
],
"zone-2": [
{
"acl_name": "vpc-acl",
"cidr": "10.20.10.0/24",
"name": "subnet-b",
"public_gateway": true
}
],
"zone-3": [
{
"acl_name": "vpc-acl",
"cidr": "10.30.10.0/24",
"name": "subnet-c",
"public_gateway": false
}
]
}
| no | | [tags](#input\_tags) | List of Tags for the resource created | `list(string)` | `null` | no | diff --git a/dynamic_values.tf b/dynamic_values.tf index 5e54f6e0..0bb35990 100644 --- a/dynamic_values.tf +++ b/dynamic_values.tf @@ -34,10 +34,14 @@ module "unit_tests" { } routes = [ { - name = "test-route" - zone = 1 - destination = "test" - next_hop = "test" + name = "test-route" + routes = [ + { + zone = 1 + destination = "10.2.14.1/32" + next_hop = "1.1.1.1" + } + ] } ] use_public_gateways = { diff --git a/dynamic_values.unit_tests.tf b/dynamic_values.unit_tests.tf index 734dbd7c..7022564a 100644 --- a/dynamic_values.unit_tests.tf +++ b/dynamic_values.unit_tests.tf @@ -23,7 +23,7 @@ locals { # tflint-ignore: terraform_unused_declarations assert_route_key_exists = lookup(module.unit_tests.routes, "test-route") # tflint-ignore: terraform_unused_declarations - assert_route_has_correct_next_hop = regex("test", module.unit_tests.routes["test-route"].next_hop) + assert_route_has_route_table = lookup(module.unit_tests.routing_table_route_map, "ut-test-route-route-1") } ############################################################################## diff --git a/dynamic_values/outputs.tf b/dynamic_values/outputs.tf index 3e709785..1c6f9d5f 100644 --- a/dynamic_values/outputs.tf +++ b/dynamic_values/outputs.tf @@ -79,3 +79,17 @@ output "subnet_map" { } ############################################################################## + +############################################################################## +# Routing table +############################################################################## + +output "routing_table_map" { + description = "Routing table as map" + value = module.routes.value +} + +output "routing_table_route_map" { + description = "Routing table routes as map" + value = local.routing_table_route_map +} diff --git a/dynamic_values/routes.tf b/dynamic_values/routes.tf new file mode 100644 index 00000000..2621295d --- /dev/null +++ b/dynamic_values/routes.tf @@ -0,0 +1,19 @@ +module "routes" { + source = "./config_modules/list_to_map" + list = var.routes +} + +locals { + routing_table_route_list = flatten( + [for route_table in module.routes.value : [ + for rt in(lookup(route_table, "routes", null) == null ? [] : route_table.routes) : + merge(rt, { route_table = route_table.name, route_index = index(route_table.routes, rt) + 1 }) + ] + ] + ) + + routing_table_route_map = { + for route in local.routing_table_route_list : + ("${var.prefix}-${route.route_table}-route-${route.route_index}") => route + } +} diff --git a/dynamic_values/variables.tf b/dynamic_values/variables.tf index d2e16423..41444023 100644 --- a/dynamic_values/variables.tf +++ b/dynamic_values/variables.tf @@ -37,10 +37,19 @@ variable "routes" { description = "direct reference to routes variable" type = list( object({ - name = string - zone = number - destination = string - next_hop = string + name = string + route_direct_link_ingress = optional(bool) + route_transit_gateway_ingress = optional(bool) + route_vpc_zone_ingress = optional(bool) + routes = optional( + list( + object({ + action = optional(string) + zone = number + destination = string + next_hop = string + }) + )) }) ) } diff --git a/main.tf b/main.tf index 6c2a50ae..81690732 100644 --- a/main.tf +++ b/main.tf @@ -40,24 +40,27 @@ resource "ibm_is_vpc_address_prefix" "address_prefixes" { ############################################################################## -# ibm_is_vpc_route: Create vpc route resource +# Create vpc route resource ############################################################################## -locals { - routes_map = { - # Convert routes from list to map - for route in var.routes : - (route.name) => route - } +resource "ibm_is_vpc_routing_table" "route_table" { + for_each = module.dynamic_values.routing_table_map + name = "${var.prefix}-${var.name}-route-${each.value.name}" + vpc = ibm_is_vpc.vpc.id + route_direct_link_ingress = each.value.route_direct_link_ingress + route_transit_gateway_ingress = each.value.route_transit_gateway_ingress + route_vpc_zone_ingress = each.value.route_vpc_zone_ingress } -resource "ibm_is_vpc_route" "route" { - for_each = local.routes_map - name = "${var.prefix}-${var.name}-route-${each.value.name}" - vpc = ibm_is_vpc.vpc.id - zone = each.value.zone - destination = each.value.destination - next_hop = each.value.next_hop +resource "ibm_is_vpc_routing_table_route" "routing_table_routes" { + for_each = module.dynamic_values.routing_table_route_map + vpc = ibm_is_vpc.vpc.id + routing_table = ibm_is_vpc_routing_table.route_table[each.value.route_table].routing_table + zone = "${var.region}-${each.value.zone}" + name = each.key + destination = each.value.destination + action = each.value.action + next_hop = each.value.next_hop } ############################################################################## diff --git a/module-metadata.json b/module-metadata.json index 1d5e6909..58893ad9 100644 --- a/module-metadata.json +++ b/module-metadata.json @@ -135,7 +135,7 @@ }, "routes": { "name": "routes", - "type": "list(\n object({\n name = string\n zone = number\n destination = string\n next_hop = string\n })\n )", + "type": "list(\n object({\n name = string\n route_direct_link_ingress = optional(bool)\n route_transit_gateway_ingress = optional(bool)\n route_vpc_zone_ingress = optional(bool)\n routes = optional(\n list(\n object({\n action = optional(string)\n zone = number\n destination = string\n next_hop = string\n })\n ))\n })\n )", "description": "OPTIONAL - Allows you to specify the next hop for packets based on their destination address", "default": [], "pos": { @@ -336,7 +336,7 @@ }, "pos": { "filename": "main.tf", - "line": 78 + "line": 81 } }, "ibm_is_security_group_rule.default_vpc_rule": { @@ -413,10 +413,10 @@ "line": 16 } }, - "ibm_is_vpc_route.route": { + "ibm_is_vpc_routing_table.route_table": { "mode": "managed", - "type": "ibm_is_vpc_route", - "name": "route", + "type": "ibm_is_vpc_routing_table", + "name": "route_table", "attributes": { "name": "prefix" }, @@ -425,7 +425,22 @@ }, "pos": { "filename": "main.tf", - "line": 54 + "line": 46 + } + }, + "ibm_is_vpc_routing_table_route.routing_table_routes": { + "mode": "managed", + "type": "ibm_is_vpc_routing_table_route", + "name": "routing_table_routes", + "attributes": { + "zone": "region" + }, + "provider": { + "name": "ibm" + }, + "pos": { + "filename": "main.tf", + "line": 55 } } }, diff --git a/variables.tf b/variables.tf index 114285f8..c586c9de 100644 --- a/variables.tf +++ b/variables.tf @@ -399,10 +399,19 @@ variable "routes" { description = "OPTIONAL - Allows you to specify the next hop for packets based on their destination address" type = list( object({ - name = string - zone = number - destination = string - next_hop = string + name = string + route_direct_link_ingress = optional(bool) + route_transit_gateway_ingress = optional(bool) + route_vpc_zone_ingress = optional(bool) + routes = optional( + list( + object({ + action = optional(string) + zone = number + destination = string + next_hop = string + }) + )) }) ) default = []