5.1 KiB
5.1 KiB
TowerOps Terraform Provider Design
Overview
A Terraform provider for managing TowerOps resources (Sites and Devices) via the existing REST API.
Scope
- Resources: Sites, Devices
- Authentication: API token in provider config
- Import: Supported for existing resources
- Endpoint: Fixed production URL
Provider Configuration
terraform {
required_providers {
towerops = {
source = "towerops/towerops"
}
}
}
provider "towerops" {
token = var.towerops_api_token # Required, scopes all operations to one org
}
The token determines which organization's resources are accessible via the existing API token authentication.
Project Structure
towerops-tf-provider/
├── main.go # Entry point
├── go.mod / go.sum
├── internal/
│ └── provider/
│ ├── provider.go # Provider schema + config
│ ├── client.go # HTTP client for TowerOps API
│ ├── site_resource.go
│ ├── device_resource.go
├── examples/
│ └── main.tf # Usage example
└── docs/ # Generated documentation
Uses the Terraform Plugin Framework (modern approach).
Resource Schemas
towerops_site
resource "towerops_site" "main" {
name = "Main Office"
location = "New York, NY" # Optional
snmp_community = "public" # Optional
}
output "site_id" {
value = towerops_site.main.id
}
Attributes:
name(Required, string) - Site name, 2-200 charslocation(Optional, string) - Physical location descriptionsnmp_community(Optional, string) - Default SNMP community for devices
Computed:
id(string) - UUID assigned by TowerOpsinserted_at(string) - Creation timestamp
towerops_device
resource "towerops_device" "router" {
site_id = towerops_site.main.id
name = "Core Router"
ip_address = "192.168.1.1"
monitoring_enabled = true # Optional, default true
snmp_enabled = true # Optional, default true
snmp_version = "2c" # Optional, default "2c"
snmp_port = 161 # Optional, default 161
}
Attributes:
site_id(Required, string) - UUID of parent sitename(Required, string) - Device nameip_address(Required, string) - Device IP addressdescription(Optional, string) - Device descriptionmonitoring_enabled(Optional, bool) - Enable monitoring, default truesnmp_enabled(Optional, bool) - Enable SNMP polling, default truesnmp_version(Optional, string) - SNMP version (1, 2c, 3), default "2c"snmp_port(Optional, int) - SNMP port, default 161
Computed:
id(string) - UUID assigned by TowerOpsinserted_at(string) - Creation timestamp
HTTP Client
type Client struct {
BaseURL string
Token string
HTTPClient *http.Client
}
// Site operations
func (c *Client) CreateSite(site Site) (*Site, error)
func (c *Client) GetSite(id string) (*Site, error)
func (c *Client) UpdateSite(id string, site Site) (*Site, error)
func (c *Client) DeleteSite(id string) error
// Device operations
func (c *Client) CreateDevice(device Device) (*Device, error)
func (c *Client) GetDevice(id string) (*Device, error)
func (c *Client) UpdateDevice(id string, device Device) (*Device, error)
func (c *Client) DeleteDevice(id string) error
API Mapping
| Terraform Operation | HTTP Method | Endpoint |
|---|---|---|
| Create | POST | /api/v1/sites or /api/v1/devices |
| Read | GET | /api/v1/sites/:id or /api/v1/devices/:id |
| Update | PATCH | /api/v1/sites/:id or /api/v1/devices/:id |
| Delete | DELETE | /api/v1/sites/:id or /api/v1/devices/:id |
| Import | GET | Same as Read |
Import Support
# Import existing site by UUID
terraform import towerops_site.main 550e8400-e29b-41d4-a716-446655440000
# Import existing device by UUID
terraform import towerops_device.router 7c9e6679-7425-40de-944b-e07fc1f90ae7
Import uses the same GetSite/GetDevice client methods as Read.
Testing Strategy
- Unit tests - Mock HTTP responses, test schema validation
- Acceptance tests - Run against real TowerOps instance (skipped in CI without credentials)
func TestAccSiteResource(t *testing.T) {
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
Config: `resource "towerops_site" "test" { name = "Test Site" }`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("towerops_site.test", "name", "Test Site"),
resource.TestCheckResourceAttrSet("towerops_site.test", "id"),
),
},
},
})
}
Implementation Order
- Project scaffolding (go.mod, main.go)
- HTTP client with Site CRUD
- Site resource implementation
- HTTP client Device CRUD
- Device resource implementation
- Import support for both resources
- Acceptance tests
- Documentation and examples