Creates and manages a single NIOS
networkviewobject — the top-level IPAM scope every network container, network, range, and IP allocation lives inside. Built for infoblox v2.x / WAPI v2.12.3.
- 🟦 Wraps exactly one resource —
infoblox_network_view.this(WAPInetworkview). - 🌳 A network view is the root of the IPAM hierarchy: it has no parent scope of its own, so this module takes no upstream
network_view/dns_viewreference. - 🏷️ Exposes the two universal NIOS fields: an optional
commentandext_attrs(extensible attributes) passed as a plainmap(string). - 🔗 Emits
network_view(the name) for downstream IPAM modules to consume, plus the canonicalid(WAPI object reference) for imports and ID-based wiring. - 🚫 No
ttl(not a DNS resource), no IP allocation (it is the container others allocate within), and notimeouts(the provider exposes none onnetworkview).
💡 Why it matters: every other
terraform-infoblox-*IPAM module — network containers, networks, ranges, fixed addresses, shared networks, IP allocations — must point at a network view. Stand this up first.
If these Terraform modules have been helpful to you or your organization, I'd appreciate your support in any of the following ways:
- ⭐ Star this repository to help others discover this Terraform module.
- 🤝 Connect with me on LinkedIn: linkedin.com/in/microsoftexpert
- ☕ Buy me a coffee: buymeacoffee.com/microsoftexpert
Whether it's a star, a professional connection, or a coffee, every gesture helps keep these modules actively maintained and continually improving. Thank you for being part of the community!
The root of the whole suite: this module consumes nothing (no parent scope) and emits network_view, which every IPAM module (plus terraform-infoblox-dns-view) consumes — see 🔌 Typical wiring below for the full output-by-output breakdown.
flowchart TD
NV["terraform-infoblox-network-view<br/>(this module — networkview)"]
DV["terraform-infoblox-dns-view<br/>(dns_view)"]
C4["terraform-infoblox-ipv4-network-container"]
C6["terraform-infoblox-ipv6-network-container"]
N4["terraform-infoblox-ipv4-network"]
N6["terraform-infoblox-ipv6-network"]
SN["terraform-infoblox-ipv4-shared-network"]
FA["terraform-infoblox-ipv4-fixed-address"]
IPA["terraform-infoblox-ip-allocation"]
NV -->|network_view| DV
NV -->|network_view| C4
NV -->|network_view| C6
NV -->|network_view| N4
NV -->|network_view| N6
NV -->|network_view| SN
NV -->|network_view| FA
NV -->|network_view| IPA
classDef me fill:#00B4D8,color:#fff,stroke:#0077A3,stroke-width:2px;
class NV me;
One resource — infoblox_network_view.this — a thin renderer over the WAPI networkview object. name is immutable (NIOS cannot rename a network view in place).
flowchart TD
IN["name (immutable)<br/>comment / ext_attrs"]
THIS["infoblox_network_view.this<br/>(WAPI networkview — root IPAM scope)"]
ID["id (WAPI _ref)"]
OUT["network_view (name for downstream IPAM/DNS modules)"]
IN --> THIS
THIS --> ID
THIS --> OUT
classDef me fill:#00B4D8,color:#fff,stroke:#0077A3,stroke-width:2px;
class THIS me;
terraform-infoblox-network-view/
├── providers.tf # required_providers only — NO provider {} block
├── variables.tf # name (immutable), comment, ext_attrs
├── main.tf # infoblox_network_view.this
├── outputs.tf # id, name, network_view, comment
├── README.md # this file
└── SCOPE.md # managed resource + NIOS permissions/prerequisites
module "network_view_prod" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
comment = "Production IPAM scope — managed by Terraform"
}Wire the emitted network_view straight into any downstream IPAM module:
module "container" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-ipv4-network-container?ref=v1.0.0"
network_view = module.network_view_prod.network_view # ← wired here
cidr = "10.20.0.0/16"
}Grid credentials (
INFOBLOX_SERVER/INFOBLOX_USERNAME/INFOBLOX_PASSWORD, plusSSLMODE/WAPI_VERSION) are configured at the root / pipeline level — never inside this module.
| Role / License | Required for | Notes |
|---|---|---|
| DHCP Admin or superuser (Grid) | Create / update / delete the networkview object |
A scoped admin group with read-write permission on network views is sufficient for the resource itself. |
| Cloud Network Automation license (or superuser ) | The four required Extensible Attributes (see Prerequisites) | The license auto-provisions the EAs; without it they must be created manually. |
| superuser | Auto-creation of the Terraform Internal ID EA |
Required the first time any terraform-infoblox-* module runs against a grid that does not already have this EA. |
⚠️ Superuser callout: TheTerraform Internal IDEA is auto-created by the provider only when the connecting account is superuser. Downstream modules such asterraform-infoblox-ip-allocation/infoblox_ip_associationalso require superuser. If your Terraform identity is a scoped admin (not superuser), have a grid administrator pre-create all four EAs (below) before the firstterraform apply, otherwise apply fails with a connection / WAPI error.
These four Extensible Attributes must exist in the NIOS grid before terraform apply. They are added automatically by the Cloud Network Automation license, or created manually / via cURL:
| # | Extensible Attribute | Type | Notes |
|---|---|---|---|
| 1 | Tenant ID |
String | Cloud tenancy identifier |
| 2 | CMP Type |
String | Cloud Management Platform type (e.g. Terraform) |
| 3 | Cloud API Owned |
List (True, False) |
Marks objects managed via the Cloud API |
| 4 | Terraform Internal ID |
String, read-only (CR flag) | Used for drift detection when a NIOS reference changes outside Terraform |
Create the Terraform Internal ID EA via WAPI (adjust grid host / WAPI version as needed):
curl -k -u "$INFOBLOX_USERNAME:$INFOBLOX_PASSWORD" \
-H "Content-Type: application/json" \
-X POST "https://${INFOBLOX_SERVER}/wapi/v2.12.3/extensibleattributedef" \
-d '{
"name": "Terraform Internal ID",
"type": "STRING",
"flags": "CR",
"comment": "Internal ID for Terraform drift detection"
}'- WAPI version:
v2.12.3(provider default; align withWAPI_VERSION). - The
CRflags mark the EA as Cloud-API created and Read-only so operators do not edit it by hand.
| This module output | Feeds into |
|---|---|
id |
terraform import and any ID-based cross-module wiring |
name |
Reporting / labels |
network_view |
terraform-infoblox-ipv4-network-container, terraform-infoblox-ipv4-network, terraform-infoblox-ip-allocation, terraform-infoblox-ipv4-shared-network, terraform-infoblox-dns-view |
comment |
Reporting |
This module sits at the head of the IPAM chain. It consumes nothing; everything IPAM-related consumes its network_view output.
WAPI reference string (id). The primary output id is the NIOS object reference, e.g.
networkview/ZG5zLm5ldHdvcmtfdmlldyQw:default/true. It is opaque, grid-specific, and is the canonical identifier for terraform import and any reference-by-ID wiring. The _ref is <wapi_type>/<base64-id>:<name>/<is_default>.
Immutable field (force-new). name is immutable — NIOS does not support renaming a network view. Changing name forces Terraform to destroy and recreate the view, which orphans every network container, network, range, and allocation that referenced it. Choose the name carefully before the first apply.
Case sensitivity — network view names are NOT lowercased. Unlike DNS FQDNs (which every terraform-infoblox-* DNS module validates as lowercase-only because NIOS case-folds them), network view names are not case-folded by NIOS and may contain spaces (e.g. the built-in "default"). This module therefore intentionally does not lowercase-validate name — it validates only non-emptiness and the 64-character limit.
ext_attrs JSON-encode pattern. Callers always pass a plain map(string). main.tf encodes it:
ext_attrs = length(var.ext_attrs) > 0 ? jsonencode(var.ext_attrs) : nullThe length(...) > 0 guard is required because the provider expects a JSON string, not a map. Encoding an empty map would render "{}", which the provider then sees as a set-but-empty attribute and reports as perpetual drift on every plan. Encoding to null when the map is empty omits the argument entirely, so unused EAs stay quiet.
TTL behavior — not applicable here. A network view is not a DNS resource, so it has no ttl argument and this module exposes none. (For the terraform-infoblox-* DNS record modules, the convention is: null/omitted → inherit from the parent zone, 0 → disable caching, and a negative value stored in state → the field is unset/inherited.)
Next-available IP — not applicable here. A network view holds no addresses itself; dynamic next_available_ip allocation lives in the network / allocation modules. Nothing to expose here.
Terraform Internal ID EA (drift detection). When present (and auto-created under a superuser identity), the provider stamps this EA onto managed objects so it can re-locate them if the NIOS _ref changes due to out-of-band manual edits — preventing spurious destroy/recreate churn. Pre-create it if your identity is not superuser.
Eventual consistency. NIOS is a distributed grid; a freshly created view is normally visible immediately, but allow brief propagation before dependent reads in tightly chained pipelines.
1 · Minimal — name only
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
}2 · With a comment
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
comment = "Production IPAM scope — managed by Terraform"
}3 · With extensible attributes (jsonencode pattern)
The caller passes a plain map(string); the module jsonencodes it internally.
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
ext_attrs = {
"Tenant ID" = "prod"
"CMP Type" = "Terraform"
"Cloud API Owned" = "True"
}
}4 · Empty ext_attrs is a no-op (no drift)
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "lab"
ext_attrs = {} # encoded as null → argument omitted, no "{}" drift
}5 · A name with a space (not lowercased by NIOS)
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "Corp DMZ" # spaces & mixed case are valid for network views
comment = "Perimeter scope"
}6 · Multiple views with for_each
locals {
views = {
prod = "Production IPAM scope"
nonprod = "Non-production IPAM scope"
dmz = "Perimeter / DMZ scope"
}
}
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
for_each = local.views
name = each.key
comment = each.value
}7 · Tenant-tagged view (full EA set)
module "nv_tenant" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "tenant-acme"
comment = "Dedicated IPAM scope for tenant ACME"
ext_attrs = {
"Tenant ID" = "acme"
"CMP Type" = "Terraform"
"Cloud API Owned" = "True"
}
}8 · Wire into an IPv4 network container
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
}
module "container" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-ipv4-network-container?ref=v1.0.0"
network_view = module.nv.network_view # ← wired from this module
cidr = "10.0.0.0/8"
comment = "Top-level supernet"
}9 · Wire into an IPv4 network
module "net" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-ipv4-network?ref=v1.0.0"
network_view = module.nv.network_view
cidr = "10.20.30.0/24"
comment = "App tier subnet"
}10 · network_view as the parent for a DNS view
infoblox_dns_view optionally scopes to a network view by name.
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
}
module "dns_view" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-dns-view?ref=v1.0.0"
name = "prod-internal"
network_view = module.nv.network_view # DNS view scoped to this network view
comment = "Internal DNS view for prod"
}11 · Consume the id output for an import
output "nv_ref" {
value = module.nv.id # e.g. networkview/ZG5z...:prod/false
}# Import an existing view into module state using its WAPI _ref:
terraform import 'module.nv.infoblox_network_view.this' \
'networkview/ZG5zLm5ldHdvcmtfdmlldyQw:prod/false'12 · Wire into an IPv4 shared network
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
}
module "shared_net" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-ipv4-shared-network?ref=v1.0.0"
name = "Shared Net - Floor 2"
network_view = module.nv.network_view # ← wired from this module
networks = ["10.10.1.0/24", "10.10.2.0/24"]
comment = "DHCP shared network spanning two member subnets"
}13 · Wire into an IPv4 fixed address
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
}
module "fixed_addr" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-ipv4-fixed-address?ref=v1.0.0"
network_view = module.nv.network_view # ← wired from this module
ipv4addr = "10.10.10.50"
match_client = "MAC_ADDRESS"
mac = "00:0c:24:2e:8f:2a"
comment = "Reserved address for a network printer"
}14 · Wire into an ip_allocation host record
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
}
module "host" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-ip-allocation?ref=v1.0.0"
fqdn = "host1" # host-label only (enable_dns = false)
network_view = module.nv.network_view # ← wired from this module
enable_dns = false
ipv4_cidr = "10.10.10.0/24" # next-available allocation
}15 · End-to-end composition (view → container → network)
module "nv" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-network-view?ref=v1.0.0"
name = "prod"
comment = "Production IPAM scope"
ext_attrs = {
"CMP Type" = "Terraform"
"Cloud API Owned" = "True"
}
}
module "container" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-ipv4-network-container?ref=v1.0.0"
network_view = module.nv.network_view
cidr = "10.0.0.0/8"
}
module "network" {
source = "git::https://github.com/microsoftexpert/terraform-infoblox-ipv4-network?ref=v1.0.0"
network_view = module.nv.network_view
cidr = "10.10.10.0/24"
comment = "Workload subnet"
}| Name | Type | Default | Required | Description |
|---|---|---|---|---|
name |
string |
— | ✅ | Network view name. Immutable (force-new). 1–64 chars, non-empty. Not lowercase-validated. |
comment |
string |
null |
— | Human-readable description. Mutable; null = unset. |
ext_attrs |
map(string) |
{} |
— | Extensible attributes. jsonencoded internally; empty map → omitted (no drift). |
| Output | Description | Typically consumed by |
|---|---|---|
id |
Primary. WAPI object reference (e.g. networkview/ZG5z...:prod/false). |
terraform import, ID-based wiring |
network_view |
The view name, shaped to match the network_view input of downstream IPAM modules. |
terraform-infoblox-ipv4-network-container, terraform-infoblox-ipv4-network, terraform-infoblox-ip-allocation, terraform-infoblox-ipv4-shared-network, terraform-infoblox-dns-view |
name |
The view name as stored in NIOS. | Reporting / labels |
comment |
The comment set on the view (null if none). |
Reporting |
- One resource, named
this— the standalone-module standard. - No
provider {}block — credentials live at root/pipeline level only. - No
tags, noresource_group_name, noobject_id— Azure conventions do not apply to NIOS;ext_attrsis the NIOS equivalent of tags. - Universal fields only —
comment+ext_attrs; nottl(not DNS), notimeouts(provider exposes none). idis the contract — the WAPI_refis the cross-module identifier.- Immutability surfaced in docs and validation —
nameis force-new and documented as such.
terraform init -backend=false
terraform validate
terraform fmt -check
terraform plan/applyrequire a live NIOS grid endpoint and the auth env vars (INFOBLOX_SERVER/INFOBLOX_USERNAME/INFOBLOX_PASSWORD).init -backend=false+validate+fmt -checkrun fully offline.
⚠️ Always pin the module source to a specific tag (?ref=v1.0.0), never a branch.
| Symptom | Likely cause | Fix |
|---|---|---|
Unknown extensible attribute "..." on apply |
An EA key in ext_attrs is not defined in the grid |
Define the EA in NIOS first (see Prerequisites), or remove the key. |
| Apply fails immediately with a connection / WAPI error | One of the four required EAs (esp. Terraform Internal ID) is missing |
Pre-create the EAs (cURL above) or run as superuser / with the Cloud Network Automation license. |
401 Unauthorized / auth failure |
INFOBLOX_USERNAME / INFOBLOX_PASSWORD / INFOBLOX_SERVER not set at root |
Export the env vars (or set them in the pipeline) before plan/apply. |
| Plan wants to destroy and recreate the view | name was changed (immutable / force-new) |
Revert the name, or accept the recreate knowing it orphans child objects. |
Every plan shows ext_attrs drift |
An empty "{}" was pushed (not using the length > 0 guard) |
This module already guards it; if seen, confirm you're on v1.0.0+. |
| Import fails with "object not found" | Wrong _ref format |
Use networkview/<base64>:<name>/<is_default>; copy the exact _ref from the grid or id output. |
| Duplicate-name error | A network view with that name already exists | Use a unique name, or terraform import the existing object instead. |
- Provider:
infobloxopen/infoblox—infoblox_network_viewresource & data source - Infoblox NIOS documentation
SCOPE.md(this module) — managed resource, permissions, prerequisites, gotchas- Downstream:
terraform-infoblox-ipv4-network-container,terraform-infoblox-ipv4-network,terraform-infoblox-ip-allocation,terraform-infoblox-dns-view
💙 "Infrastructure as Code should be standardized, consistent, and secure."