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.ACTIVEis 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_ipis 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
Physicalnetworks of which only one is routable -- so filteringdtcloud_networksby 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 withdtcloud_routersand look that name up indtcloud_networks. - A router costs a public address, plus a router from the router quota and address space on
the external network.
dtcloud_project_quotasshows 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_vmhas norebootargument. - A gateway removed outside Terraform comes back.
external_network_idreads 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.