Skip to content

pipam Configuration

pipam uses viper for configuration. TOML, YAML, and JSON formats are supported. The config file is discovered automatically from $XDG_CONFIG_HOME/pipam/config.* or /etc/pipam/config.*, or specified with --config.

collect_interval = 30
[proxmox]
url = "https://proxmox.example.com:8006"
user = "automation-user"
realm = "pve"
token_id = "terraform"
token_uuid = "d515c8a0-..."
insecure = true
[dns]
provider = "powerdns"
zones = ["example.com."]
[dns.powerdns]
url = "http://pdns:8081"
api_key = "changeme"
[mapping."example.com"]
networks = [{ cidr = "10.0.0.0/16" }]
KeyTypeDefaultDescription
collect_intervalint30Seconds between collection cycles
full_reconcile_intervalint0Seconds between full reconciles (0 = disabled). Re-ensures all entries periodically
skip_cidrs[]stringCIDRs to exclude from collection (e.g. ["100.64.0.0/10"])
KeyTypeDescription
urlstringProxmox API URL
userstringAPI user (e.g. automation-user)
realmstringAuth realm (e.g. pve)
token_idstringAPI token ID
token_uuidstringAPI token UUID
token_uuid_filestringPath to file containing the token UUID
insecureboolSkip TLS verification
KeyTypeDescription
providerstringDNS provider (powerdns)
zones[]stringDNS zones to manage (trailing dot)
KeyTypeDescription
urlstringPowerDNS API URL
api_keystringPowerDNS API key
api_key_filestringPath to file containing the API key

Omit the entire section to disable IPAM sync.

KeyTypeDescription
providerstringIPAM provider (netbox)
KeyTypeDescription
urlstringNetBox API URL
tokenstringNetBox API token
token_filestringPath to file containing the token
clusterstringNetBox cluster name to assign VMs to

Omit or set node_id = 0 for single-node mode.

KeyTypeDefaultDescription
node_idint0Raft node ID (0 = single-node)
listen_addrstringAddress for raft HTTP transport
data_dirstringWAL and snapshot persistence dir
tick_intervalint100Raft tick interval in ms
peersmap[int]stringNode ID to URL mapping

Example:

[raft]
node_id = 1
listen_addr = ":7800"
data_dir = "/var/lib/pipam"
tick_interval = 100
[raft.peers]
1 = "http://node1:7800"
2 = "http://node2:7800"
3 = "http://node3:7800"

Mapping entries determine how VM/LXC IPs are resolved to FQDNs. The key is the DNS domain suffix. Multiple mapping sections can coexist; the IP is matched using longest-prefix-match when subnets overlap.

KeyTypeDefaultDescription
ipv6_inherit_ipv4_fqdnboolfalseIPv6 addresses with no direct match inherit the IPv4 FQDN
networksarrayList of network objects (see below)

Each network object:

KeyTypeDescription
cidrstringSubnet CIDR (e.g. 10.50.0.0/16)
service_recordstringShared FQDN for all hosts in this subnet (optional)

Service records create a shared DNS name pointing to all host IPs in a subnet:

[mapping."k8s.example.com"]
ipv6_inherit_ipv4_fqdn = true
networks = [
{ cidr = "10.10.10.0/28", service_record = "k8s.example.com" }
]

This creates both per-host records (master-01.k8s.example.com) and a shared record (k8s.example.com) pointing to all IPs.

flowchart TD
IP[VM IP Address] --> Match{Match against<br/>mapping networks}
Match -->|10.50.0.0/16| A["hostname.services.example.com"]
Match -->|10.10.10.0/28| B["hostname.k8s.example.com"]
Match -->|no match| Skip[Skip DNS]
B --> SVC{service_record<br/>configured?}
SVC -->|yes| Shared["+ k8s.example.com (shared A/AAAA)"]
SVC -->|no| Done[Done]
A --> IPv6{IPv6 with no<br/>direct match?}
IPv6 -->|ipv6_inherit_ipv4_fqdn| Inherit["Inherit FQDN from IPv4"]
IPv6 -->|disabled| Skip6[Skip IPv6 DNS]

Secrets support three sources (highest priority first):

  1. Environment variablePIPAM_PROXMOX_TOKEN_UUID, PIPAM_DNS_POWERDNS_API_KEY, PIPAM_IPAM_NETBOX_TOKEN
  2. Filetoken_uuid_file = "/run/secrets/proxmox_token_uuid"
  3. Inline — directly in the config file

All config keys can also be set via env vars with PIPAM_ prefix and _ separators (e.g. PIPAM_PROXMOX_URL, PIPAM_RAFT_NODE_ID, PIPAM_COLLECT_INTERVAL).