Terraform Provider¶
The official b'nerd Terraform provider lets you manage b'nerd Cloud resources as code — servers, DNS, Kubernetes clusters, object storage users, load balancers, networks, and more.
Registry: bnerd-cloud/bnerd Source: app/terraform/bnerd-cloud-provider
Installation¶
Add the provider to your terraform block and run terraform init:
Configuration¶
provider "bnerd" {
api_url = "https://api.bnerd.cloud" # or BNERD_API_URL
token = var.bnerd_token # or BNERD_TOKEN
org_id = var.org_id # or BNERD_ORG_ID (UUID)
project_id = var.project_id # or BNERD_PROJECT_ID (UUID)
}
All four attributes can be supplied via environment variables instead of HCL. org_id and project_id must be valid UUIDs when set.
| Attribute / Environment variable | Required | Description |
|---|---|---|
api_url / BNERD_API_URL | yes | Base URL of the hq API |
token / BNERD_TOKEN | yes | Bearer authentication token |
org_id / BNERD_ORG_ID | no | Default organization UUID |
project_id / BNERD_PROJECT_ID | no | Default project UUID |
The recommended approach is to keep credentials out of version control and supply them via environment variables or a secrets manager.
Resources¶
| Resource | Description |
|---|---|
bnerd_dns_zone | DNS zone (PowerDNS). Forces-new on name change. |
bnerd_dns_record | DNS record within a zone. |
bnerd_project | Cloud project under an organization. |
bnerd_rgw_user | RGW (S3-compatible) object storage user. |
bnerd_dns_zone¶
resource "bnerd_dns_zone" "primary" {
name = "example.com." # must end with a dot
kind = "Native"
nameservers = ["ns1.bnerd.net.", "ns2.bnerd.net."]
}
Changing name forces replacement. organization_id defaults to the provider's org_id.
bnerd_dns_record¶
resource "bnerd_dns_record" "www" {
zone_id = bnerd_dns_zone.primary.id
name = "www.example.com."
type = "A"
ttl = 300
records = ["203.0.113.10"]
}
bnerd_project¶
bnerd_rgw_user¶
resource "bnerd_rgw_user" "app" {
name = "my-app-storage"
project_id = bnerd_project.main.id
}
output "s3_access_key" { value = bnerd_rgw_user.app.access_key_id }
output "s3_secret_key" {
value = bnerd_rgw_user.app.secret_key
sensitive = true
}
RGW control-plane contract
quota and locked are computed/read-only — they are set by platform admins and cannot be changed via Terraform. The resource does not support in-place updates; changing name or project_id forces replacement. This matches the admin-only contract for the RGW control plane.
Data Sources¶
Data sources are read-only. All project-scoped sources accept an optional project_id that falls back to the provider default.
Compute¶
| Data source | Description |
|---|---|
bnerd_servers | List all compute servers |
bnerd_server | Fetch a single server by ID |
bnerd_images | List available images |
bnerd_flavors | List compute flavors |
bnerd_ssh_keypairs | List SSH keypairs |
Block Storage¶
| Data source | Description |
|---|---|
bnerd_volumes | List block volumes |
bnerd_volume | Fetch a single volume by ID |
Networking¶
| Data source | Description |
|---|---|
bnerd_networks | List networks |
bnerd_network | Fetch a single network by ID |
bnerd_subnets | List subnets |
bnerd_subnet | Fetch a single subnet by ID |
bnerd_routers | List routers |
bnerd_router | Fetch a single router by ID |
bnerd_ports | List ports |
bnerd_port | Fetch a single port by ID |
bnerd_floating_ips | List floating IPs |
bnerd_floating_ip | Fetch a single floating IP by ID |
Load Balancing¶
| Data source | Description |
|---|---|
bnerd_loadbalancers | List load balancers |
bnerd_loadbalancer | Fetch a single load balancer by ID |
bnerd_lb_listeners | List LB listeners (filterable by LB ID) |
bnerd_lb_pools | List LB pools (filterable by LB ID) |
bnerd_lb_pool_members | List members of a pool |
bnerd_lb_health_monitors | List health monitors (filterable by pool) |
Kubernetes¶
| Data source | Description |
|---|---|
bnerd_k8s_clusters | List Kubernetes clusters |
bnerd_k8s_cluster | Fetch a single K8s cluster by ID |
bnerd_k8s_cloudprofiles | List K8s cloud profiles (global) |
Object Storage (RGW)¶
| Data source | Description |
|---|---|
bnerd_rgw_users | List RGW users |
bnerd_rgw_user | Fetch a single RGW user by ID |
bnerd_rgw_buckets | List buckets of an RGW user |
bnerd_rgw_bucket | Fetch a single RGW bucket |
DNS¶
| Data source | Description |
|---|---|
bnerd_dns_zones | List DNS zones (organization-scoped) |
bnerd_dns_zone | Fetch a single DNS zone |
bnerd_dns_records | List records in a DNS zone |
Account¶
| Data source | Description |
|---|---|
bnerd_projects | List projects |
bnerd_organizations | List organizations |
Working Example¶
The following creates a project, an RGW user, a DNS zone, and a DNS record:
terraform {
required_providers {
bnerd = {
source = "bnerd-cloud/bnerd"
version = "~> 0.1"
}
}
}
provider "bnerd" {
# Credentials from environment variables:
# BNERD_API_URL, BNERD_TOKEN, BNERD_ORG_ID, BNERD_PROJECT_ID
}
resource "bnerd_project" "main" {
name = "my-project"
organization_id = var.org_id
}
resource "bnerd_rgw_user" "app" {
name = "my-app-storage"
project_id = bnerd_project.main.id
}
resource "bnerd_dns_zone" "primary" {
name = "example.com."
kind = "Native"
nameservers = ["ns1.bnerd.net.", "ns2.bnerd.net."]
}
resource "bnerd_dns_record" "www" {
zone_id = bnerd_dns_zone.primary.id
name = "www.example.com."
type = "A"
ttl = 300
records = ["203.0.113.10"]
}
output "s3_access_key" { value = bnerd_rgw_user.app.access_key_id }
output "s3_secret_key" {
value = bnerd_rgw_user.app.secret_key
sensitive = true
}
More examples are in the provider source repository under examples/.
See Also¶
- Terraform Modules — reusable modules including
ipsec-gateway - Provision Object Storage guide
- Infrastructure as Code guide