opentelekomcloud / terraform-provider-opentelekomcloud

Terraform OpenTelekomCloud provider
https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest
Mozilla Public License 2.0
84 stars 76 forks source link

Adding route to existing route table using terraform provider #2562

Open simfeiOTC opened 2 weeks ago

simfeiOTC commented 2 weeks ago

My question is: how can I add routes to the existing routing table?

My scenario is: 1) I create a VPC with subnets and routing tables in a module A 2) I create VPN connection in a module B

Now I need to add a route to the subnet created in module A to the VPN gateway created in module B.

How can I do this?

resource "opentelekomcloud_vpc_route_table_v1" "rtb" { vpc_id = local.vpc.id name = local.private-route-table.name route { destination = "10.0.0.0/8" type = "vpn" nexthop = module.otc-vpn-site-to-site.otc-tunnel.id } }

my old routes are removed.

To prevent this I need to somehow merge old routes with new ones. But...

- There is no route table data source. So there is no way to get the existing routes for a specific route table.
- In documentation (https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest/docs/resources/vpc_route_table_v1) the `route` block is described as  
> (Optional, List) Specifies the route object list. The route object is documented below.
however the declaration is a block, so when I do:

resource "opentelekomcloud_vpc_route_table_v1" "rtb" { route = [] }

that should work if route is the list - I get an error:

Error: Unsupported argument

on main.tf line 16, in resource "opentelekomcloud_vpc_route_table_v1" "rtb": 16: route = []

An argument named "route" is not expected here. Did you mean to define a block of type "route"?



As usual I googled, read the docs, but... I didn't manage to find how to do such a simple action as just in general updating routes in the existing route table. 

And I know for sure that this is very standard action, for example:
- I can create individual route object inside route table in AWS CloudFormation (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-route.html, https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/route)
- I can create individual routes using GCP (https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_route) and even though I can't get all the routes - I can import the individual one w/o affecting any other.
- Azure has route table data source (https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/data-sources/route_table)
anton-sidelnikov commented 2 weeks ago

in case of import you must keep all routes in hcl, because on apply terraform will update resource and remove all not presented routes:

import {
  to = opentelekomcloud_vpc_route_table_v1.rtb
  id = local.private-route-table.id
}

resource "opentelekomcloud_vpc_route_table_v1" "rtb" {
  vpc_id = local.vpc.id
  name = local.private-route-table.name

  route {
    old-route
  }

  route {
    destination = "10.0.0.0/8"
    type        = "vpn"
    nexthop     = module.otc-vpn-site-to-site.otc-tunnel.id
  }
}

We have a lack of api options for individual routes opentelekomcloud_vpc_route_v2, only peering type supported, so but I can add one more data-source for obtaining all routes from vpc

apankratov commented 1 week ago

I was the originator of the issue via support. Multiple blocks don't work. You will get internal server error.

Route table resource definition.

resource "opentelekomcloud_vpc_route_table_v1" "private" {
  name        = "rtb-${local.name}-private"
  vpc_id      = opentelekomcloud_vpc_v1.vpc.id
  description = "Route table for private subnets"
  subnets = [
    for key, subnet in opentelekomcloud_vpc_subnet_v1.subnets :
    subnet.network_id if subnet.tags.type == "private"
  ]

  route {
    destination = "0.0.0.0/0"
    type        = "nat"
    nexthop     = opentelekomcloud_nat_gateway_v2.natgw.id
    description = "Route outbound traffic to NAT Gateway"
  }
  route {
    description = "vpn route"
    destination = "10.252.0.0/16"
    nexthop     = "<vpn service uuid>"
    type        = "vpn"
  }
}

Error:

│ Error: error updating OpenTelekomCloud VPC route table: Internal Server Error
│
│   with module.otc-vpc.opentelekomcloud_vpc_route_table_v1.private,
│   on .terraform/modules/otc-vpc/main.tf line 83, in resource "opentelekomcloud_vpc_route_table_v1" "private":
│   83: resource "opentelekomcloud_vpc_route_table_v1" "private" {

The problem is that all routing operations is a little bit of a mess. For example according to API documentation - route table update receives object with routes property that includes RouteTableRouteAction object.

However in provider the singular property route is checked for update.

And it's not quite clear who to trust because, for example, API docs is not quite a reliable source of truth. For example, for querying route tables - routetable field does not include, well, routes. Though they are returned and data structs are correctly defined inside SDK.

apankratov commented 1 week ago

Also what is the desired way to comment on the pull requests I am not the creator of? Should I just comment inline inside the PR?

The point is that, for example, in the PR you've created you force-set region that is:

artem-lifshits commented 1 week ago

Hello @apankratov please provide the output after terraform apply with TF_LOG= TRACE option.

apankratov commented 1 week ago

@artem-lifshits here you go:

https://gist.github.com/apankratov/b76373376870200f063621b440e5ff11

anton-sidelnikov commented 1 week ago

I was the originator of the issue via support. Multiple blocks don't work. You will get internal server error.

Route table resource definition.

resource "opentelekomcloud_vpc_route_table_v1" "private" {
  name        = "rtb-${local.name}-private"
  vpc_id      = opentelekomcloud_vpc_v1.vpc.id
  description = "Route table for private subnets"
  subnets = [
    for key, subnet in opentelekomcloud_vpc_subnet_v1.subnets :
    subnet.network_id if subnet.tags.type == "private"
  ]

  route {
    destination = "0.0.0.0/0"
    type        = "nat"
    nexthop     = opentelekomcloud_nat_gateway_v2.natgw.id
    description = "Route outbound traffic to NAT Gateway"
  }
  route {
    description = "vpn route"
    destination = "10.252.0.0/16"
    nexthop     = "<vpn service uuid>"
    type        = "vpn"
  }
}

Error:

│ Error: error updating OpenTelekomCloud VPC route table: Internal Server Error
│
│   with module.otc-vpc.opentelekomcloud_vpc_route_table_v1.private,
│   on .terraform/modules/otc-vpc/main.tf line 83, in resource "opentelekomcloud_vpc_route_table_v1" "private":
│   83: resource "opentelekomcloud_vpc_route_table_v1" "private" {

The problem is that all routing operations is a little bit of a mess. For example according to API documentation - route table update receives object with routes property that includes RouteTableRouteAction object.

However in provider the singular property route is checked for update.

And it's not quite clear who to trust because, for example, API docs is not quite a reliable source of truth. For example, for querying route tables - routetable field does not include, well, routes. Though they are returned and data structs are correctly defined inside SDK.

Hi @apankratov, we need some time for investigation i assume that this problem only related to vpn or nat type, and this is not a terraform issue. And yes you're right the route documentation are rough, we create resource not relying to documentation but only on api itself, and maybe api has some bugs.

About region attribute in data-source this only sets from your cloud config, not affects anything.

apankratov commented 1 week ago

@anton-sidelnikov thanks for the effort.

In a meanwhile I've submitted PR draft that adds data source for route tables collection. The rationale is to be able to get route tables outside of the module in which the route tables were created.

I would be appreciated if you take a look at it as well.