Terraform provider for managing Yamaha RTX series routers - enterprise-grade network routers widely used in Japan.
- Terraform >= 1.11 (required for WriteOnly attribute support)
- Go >= 1.22 (for building from source)
- Yamaha RTX router with SSH access enabled
Important: This provider requires Terraform 1.11 or later. The WriteOnly attribute feature used for sensitive fields (passwords, pre-shared keys) is not available in earlier versions.
Starting with version 0.7, this provider has been migrated from Terraform SDK v2 to the Terraform Plugin Framework:
- WriteOnly Attributes: Sensitive fields (
password,admin_password,private_key,private_key_passphrase,pre_shared_keyin resources) now use WriteOnly attributes. These values are sent to the provider but never stored in Terraform state, improving security. - No Breaking Changes: Resource schemas remain unchanged. Existing configurations will continue to work.
- State File: After upgrading, sensitive values will no longer appear in state files. This is expected behavior.
terraform {
required_providers {
rtx = {
source = "shin1ohno/rtx"
version = "~> 0.10"
}
}
}Then run terraform init.
- Download the appropriate archive for your platform from GitHub Releases
- Extract and install to your Terraform plugins directory:
# Linux/macOS
mkdir -p ~/.terraform.d/plugins/registry.terraform.io/shin1ohno/rtx/0.10.2/linux_amd64
unzip terraform-provider-rtx_0.10.2_linux_amd64.zip -d ~/.terraform.d/plugins/registry.terraform.io/shin1ohno/rtx/0.10.2/linux_amd64- Configure Terraform to use the local provider:
terraform {
required_providers {
rtx = {
source = "shin1ohno/rtx"
version = "0.10.2"
}
}
}git clone https://github.com/shin1ohno/terraform-provider-rtx.git
cd terraform-provider-rtx
make installBefore using this provider, you must configure SSH host key verification. Choose one of these options:
Option 1: Add router's host key to known_hosts (Recommended)
ssh-keyscan -t rsa 192.168.1.1 >> ~/.ssh/known_hostsOption 2: Skip host key verification (Testing only)
provider "rtx" {
# ... other settings ...
skip_host_key_check = true
}terraform {
required_providers {
rtx = {
source = "shin1ohno/rtx"
version = "~> 0.10"
}
}
}
provider "rtx" {
host = "192.168.1.1"
username = "admin"
password = var.rtx_password
}
# Configure a VLAN
resource "rtx_vlan" "guest" {
vlan_id = 10
interface = "lan1"
name = "Guest Network"
ip_address = "192.168.10.1"
ip_mask = "255.255.255.0"
}| Category | Resources |
|---|---|
| Interfaces | interface, bridge, vlan, pp_interface, ipv6_interface, ipv6_prefix |
| Connectivity | pppoe, static_route, bgp, ospf |
| VPN | tunnel, ipsec_tunnel, ipsec_transport, l2tp, l2tp_service, pptp |
| NAT | nat_masquerade, nat_static |
| Security | access_list_ip, access_list_ip_apply, access_list_ipv6, access_list_ipv6_apply, access_list_ip_dynamic, access_list_ipv6_dynamic, access_list_mac, access_list_mac_apply, access_list_extended, access_list_extended_ipv6 |
| DHCP & DNS | dhcp_scope, dhcp_binding, dns_server, ddns, netvolante_dns |
| QoS | class_map, policy_map, service_policy, shape |
| Services | sshd, sshd_authorized_keys, sshd_host_key, sftpd, httpd, snmp_server, syslog |
| Administration | admin, admin_user, system, kron_schedule, kron_policy |
| Example | Description |
|---|---|
| bridge | Layer 2 bridge configuration |
| vlan | 802.1Q VLAN setup |
| pppoe | PPPoE connection for ISP |
| ipv6_interface | IPv6 with SLAAC and DHCPv6 |
| tunnel | Unified tunnel (IPsec, L2TPv3, L2TPv2) |
| ipsec_tunnel | Site-to-site IPsec VPN |
| ipsec_transport | IPsec transport mode for L2TP |
| l2tp | L2TP/L2TPv3 VPN tunnels |
| nat_masquerade | NAT/PAT configuration |
| nat_static | Static NAT (1:1 mapping) |
| access_list_ip | IP access list filtering |
| access_list_ipv6 | IPv6 access list filtering |
| access_list_mac | MAC access list filtering |
| static_route | Static routing |
| dhcp | DHCP server setup |
| dns_server | DNS server and forwarding |
| ddns | Dynamic DNS configuration |
| snmp | SNMP server monitoring |
| syslog | Syslog configuration |
| qos | QoS with class/policy maps |
| bgp | BGP routing |
| ospf | OSPF routing |
| schedule | Scheduled tasks (kron) |
| admin | Administrative settings |
| import | Comprehensive import example |
provider "rtx" {
host = "192.168.1.1" # Router IP or hostname
username = "admin" # SSH username
password = var.rtx_password # SSH password (sensitive)
port = 22 # SSH port (default: 22)
timeout = 30 # Connection timeout in seconds
# Optional: Use SFTP for faster config reading
use_sftp = true
# Optional: SSH session pooling for better performance
ssh_session_pool {
enabled = true
max_sessions = 2
idle_timeout = "5m"
}
}| Variable | Description |
|---|---|
RTX_HOST |
Router hostname or IP |
RTX_USERNAME |
SSH username |
RTX_PASSWORD |
SSH password |
RTX_ADMIN_PASSWORD |
Admin password for config changes |
RTX_USE_SFTP |
Enable SFTP-based config reading |
RTX_SFTP_CONFIG_PATH |
SFTP path to config file (auto-detected if empty) |
RTX_SSH_HOST_KEY |
SSH host public key (base64 encoded) |
RTX_KNOWN_HOSTS_FILE |
Path to known_hosts file (default: ~/.ssh/known_hosts) |
RTX_SKIP_HOST_KEY_CHECK |
Skip SSH host key verification (insecure) |
RTX_MAX_PARALLELISM |
Max concurrent operations (default: 4) |
Provider configuration takes precedence over environment variables:
provider "rtx" {
host = "192.168.1.1" # This value is used, even if RTX_HOST is set
}If a value is not set in the provider block, the environment variable is used as the default.
Local development - Use environment variables to avoid committing credentials:
export RTX_HOST="192.168.1.1"
export RTX_USERNAME="admin"
export RTX_PASSWORD="secret"
terraform planCI/CD - Set environment variables in your pipeline:
# GitHub Actions example
env:
RTX_HOST: ${{ secrets.RTX_HOST }}
RTX_USERNAME: ${{ secrets.RTX_USERNAME }}
RTX_PASSWORD: ${{ secrets.RTX_PASSWORD }}Multiple routers - Use provider configuration with variables:
variable "routers" {
type = map(object({
host = string
username = string
password = string
}))
}
provider "rtx" {
alias = "router1"
host = var.routers["router1"].host
username = var.routers["router1"].username
password = var.routers["router1"].password
}Resources provide computed attributes for referencing in other resources:
# Interface resources
resource "rtx_interface" "lan1" {
name = "lan1"
}
resource "rtx_pppoe" "wan" {
pp_number = 1
bind_interface = rtx_interface.lan2.interface_name # "lan2"
# ...
}
resource "rtx_l2tp" "tunnel1" {
tunnel_id = 1
# ...
}
resource "rtx_bridge" "internal" {
name = "bridge1"
members = [
rtx_interface.lan1.interface_name, # "lan1"
rtx_l2tp.tunnel1.tunnel_interface # "tunnel1"
]
}
# Use computed pp_interface for NAT
resource "rtx_nat_masquerade" "main" {
descriptor_id = 1
outer_address = rtx_pppoe.wan.pp_interface # "pp1"
inner_network = "192.168.1.0-192.168.1.255"
}| Resource | Attribute | Example |
|---|---|---|
rtx_interface |
interface_name |
"lan1" |
rtx_bridge |
interface_name |
"bridge1" |
rtx_vlan |
vlan_interface |
"lan1/1" |
rtx_pppoe |
pp_interface |
"pp1" |
rtx_pp_interface |
pp_interface |
"pp1" |
rtx_l2tp |
tunnel_interface |
"tunnel1" |
rtx_ipsec_tunnel |
tunnel_interface |
"tunnel1" |
# Import a VLAN
terraform import rtx_vlan.guest lan1/10
# Import a PPPoE connection
terraform import rtx_pppoe.wan 1
# Import an IPsec tunnel
terraform import rtx_ipsec_tunnel.vpn 1
# Import a bridge
terraform import rtx_bridge.internal bridge1This provider is designed for Yamaha RTX series routers including:
- vRX (virtual router)
- RTX5000
- RTX3510
- RTX3500
- RTX1300
- RTX1220
- RTX1210
- RTX840
- RTX830
# Build
make build
# Run tests
make test
# Run acceptance tests (requires RTX router)
TF_ACC=1 make testacc
# Generate documentation
make docs
# Lint
make lintMIT License - see LICENSE for details.
[Contribution guidelines here]