Skip to main content

dtcloud_router (Resource)

Manages a virtual router: what gives private networks a way out to the internet, and a way to reach each other.

A router always has an external gateway. The platform has no endpoint that creates one without, so external_network_id is required rather than optional, and every router consumes one public address from the project's quota.

Two things that belong to a router are not arguments here, because each has a lifecycle of its own: the private networks attached to it (dtcloud_router_interface) and its static routes (dtcloud_router_static_route).

Example Usage​

# The external network has to be given by id, and nothing on the platform flags
# which network that is -- ask whoever operates the region, or read the name off
# an existing router with dtcloud_routers and look it up in dtcloud_networks.
variable "external_network_id" {
type = string
}

resource "dtcloud_router" "main" {
name = "edge"
external_network_id = var.external_network_id
enable_snat = true
}

resource "dtcloud_network" "app" {
name = "app"
ipam_enabled = true
cidr = "10.0.10.0/24"
}

# Give the app network a way out.
resource "dtcloud_router_interface" "app" {
router_id = dtcloud_router.main.id
network_id = dtcloud_network.app.id
}

Schema​

Required​

  • external_network_id (String) ID of the external network the router reaches the outside through. Every router has one. Can be changed in place.
  • name (String) Name of the router. Can be changed in place.

Optional​

  • enable_snat (Boolean) Whether the gateway masquerades traffic from the private networks behind it. Can be changed in place.
  • timeouts (Block, Optional) (see below for nested schema)

Read-Only​

  • admin_state_up (Boolean) Whether the router is administratively enabled.
  • created_at (String) When the router was created, as the platform reports it.
  • description (String) Description held by the platform. There is no way to set one through this API, so it is reported but not managed.
  • external_fixed_ip (List of Object) Addresses the external network allocated to the gateway. The create endpoint always asks for IPv4 and never accepts a specific address, so these are read-only. (see below for nested schema)
  • id (String) The ID of this resource.
  • project_id (String) ID of the project the router belongs to.
  • status (String) Status reported by the platform. ACTIVE is the resting state.
  • updated_at (String) When the router last changed.

Nested Schema for timeouts​

Optional:

  • create (String)
  • delete (String)
  • update (String)

Nested Schema for external_fixed_ip​

Read-Only:

  • ip_address (String)
  • subnet_id (String)

Behaviour worth knowing​

  • The gateway's address is assigned, not requested. external_fixed_ip is read-only: create asks the external network for an address and takes what it is given. For a fixed, known public address in front of a service, use a floating IP rather than the router gateway.
  • Nothing identifies the external network. The network list carries no flag for it, and a region can hold several Physical networks of which only one is routable -- so filtering dtcloud_networks by type and taking the first is a guess that will eventually be wrong. Ask whoever operates the region, or read the name off an existing router with dtcloud_routers and look that name up in dtcloud_networks.
  • A router costs a public address, plus a router from the router quota and address space on the external network. dtcloud_project_quotas shows what is left.
  • A rename and a gateway change are two requests. The platform takes them through different bodies, so changing both in one apply sends two calls. Nothing about it shows in the plan.
  • Restarting is not exposed. The platform's restart action answers before doing any work, does it twenty seconds later in the background, and reports neither success nor failure -- there is no handle a resource could hold. It is an event rather than a state, the same reason dtcloud_vm has no reboot argument.
  • A gateway removed outside Terraform comes back. external_network_id reads empty and the next plan proposes putting it back, which is exactly the difference a plan should show.

Timeouts​

create, update and delete each default to 10 minutes. Create does not return until the platform reports ACTIVE, and destroy not until the router has stopped resolving -- so a dependent resource is never handed a router that cannot yet carry traffic, and a destroy does not leave the public address it held still charged.

Import​

terraform import dtcloud_router.main 3f2a1c9e-77b4-4a01-9d3e-2b6c81f4e5a7

Everything round-trips. name, external_network_id and enable_snat are all reported, so an import followed by a plan is empty.

Attached interfaces and static routes are not imported with the router: import each as its own resource, or read them without managing them through dtcloud_router_interfaces and dtcloud_router_static_routes.