Manages a single VLAN (
f5os_vlan) on an F5OS platform — VELOS chassis partition or rSeries appliance — targeting theF5Networks/f5osprovider~> 1.10(verified against v1.12.0).
- 🏷️ Manages exactly one
f5os_vlanresource — a numeric VLAN ID (0-4095) and an optional name. - 🧱 Standalone module: single keystone resource named
this, no children, nofor_eachinside the module boundary. - 🌐 Applies identically to a VELOS chassis partition or an rSeries appliance — the
f5os_vlanschema carries no platform-specific argument. - 🔗 Feeds
vlan_idto sibling modules —terraform-f5os-tenant'svlanslist, and VLAN-tagging arguments onterraform-f5os-interface/terraform-f5os-lag. - 🚫 No secrets, no nested blocks, no universal tail (
tags/timeouts) — this is the smallest resource shape in the F5OS catalog.
💡 Why it matters: VLANs are a hard prerequisite for tenant networking and interface tagging across the whole F5OS catalog — get the VLAN ID and name right once, here, and every downstream module (tenant, interface, LAG) references it by ID instead of duplicating a literal.
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!
graph LR
VLAN["terraform-f5os-vlan"]:::this
IFACE["terraform-f5os-interface"]:::sibling
LAG["terraform-f5os-lag"]:::sibling
PARTITION["terraform-f5os-partition (VELOS only)"]:::sibling
TENANT["terraform-f5os-tenant"]:::sibling
PLATFORM["F5OS platform (VELOS chassis partition or rSeries appliance)"]:::target
VLAN -->|"vlan_id consumed by"| TENANT
VLAN -->|"vlan_id consumed by (VLAN tagging)"| IFACE
VLAN -->|"vlan_id consumed by (VLAN tagging)"| LAG
PARTITION -->|"hosts tenants that reference VLANs"| TENANT
VLAN -->|"created directly against"| PLATFORM
classDef this fill:#E4002B,color:#ffffff,stroke:#8f0016,stroke-width:1px;
classDef target fill:#1B2A4A,color:#ffffff,stroke:#0d1626,stroke-width:1px;
classDef sibling fill:#E8E8E8,color:#1a1a1a,stroke:#b5b5b5,stroke-width:1px;
terraform-f5os-vlan (red) sits in the networking domain alongside terraform-f5os-interface and
terraform-f5os-lag. It has no upstream dependency of its own — it is a leaf module that other
modules (terraform-f5os-tenant, and interface/LAG modules where their schema exposes a VLAN-tagging
argument) consume by referencing its vlan_id output. terraform-f5os-partition is shown only to
illustrate that a VELOS chassis partition hosting a tenant is a separate concern from the VLAN
itself — this module does not consume or require a partition.
graph LR
subgraph Inputs["Inputs"]
VAR["var.vlan { vlan_id, name }"]
end
RES["f5os_vlan.this"]:::this
subgraph Outputs["Outputs"]
OUT_ID["id"]
OUT_NAME["name"]
OUT_VLANID["vlan_id"]
end
VAR -->|"vlan_id, name"| RES
RES -->|"exposes"| OUT_ID
RES -->|"exposes"| OUT_NAME
RES -->|"exposes"| OUT_VLANID
classDef this fill:#E4002B,color:#ffffff,stroke:#8f0016,stroke-width:1px;
Resource inventory
| Resource | Terraform address | Cardinality |
|---|---|---|
f5os_vlan |
f5os_vlan.this |
Exactly 1 per module call |
| Item | Value |
|---|---|
| Terraform floor | >= 1.12.0 |
| Provider pin | F5Networks/f5os ~> 1.10 — verified against the live Terraform Registry listing; terraform init resolved v1.12.0 during authoring, which satisfies this constraint |
| Provider block | None in this module — the caller configures provider "f5os" {} once, in the root module, targeting a single already-authenticated VELOS chassis controller or rSeries appliance |
| Platform context | Both — VELOS chassis partition and rSeries appliance. f5os_vlan's schema carries no partition-specific or appliance-specific argument; behavior is identical on either target |
Schema notes that bite (verified against the live f5os_vlan Argument Reference):
nameis marked Optional in the schema, but the provider's own documentation states "This parameter is required when creating a resource." Terraform's type system cannot catch this — it is a schema/docs mismatch, not a structural error — so omittingnamewill passterraform validateand fail only atapplytime against a real chassis/appliance.vlan_idhas a documented valid range of0-4095, but the schema types it as a plainNumberwith no range constraint enforced by Terraform. Out-of-range values passvalidateand fail atapply.- The fetched Argument Reference does not surface an explicit
(Requires replacement)annotation onvlan_id, but since it is the VLAN's identifying value, treat changing it as likely to force recreation in practice — confirm against a realterraform planbefore assuming safe in-place update. - Import uses the bare numeric VLAN ID as the resource ID (
terraform import f5os_vlan.vlan-id-import 4), not a composite string.
Least-privilege role: operator, per the f5os_user resource's documented role set
(role — "Specifies primary role assigned to the user (e.g., admin, operator, user)"). VLAN
management privilege scoped to the target chassis partition (VELOS) or the appliance itself
(rSeries) is sufficient for routine VLAN create/read/update/delete; admin is not required. No
role name beyond operator / admin / user is asserted here — those are the only values the
provider's own documentation shows as examples. Confirm the live RBAC role catalog on the target
platform before granting access, since it may differ per F5OS release.
- F5OS provider
F5Networks/f5os~> 1.10; Terraform>= 1.12.0. - Applies to both platform contexts — no partition or appliance-specific prerequisite exists
for
f5os_vlanitself. - No image, chassis partition, or tenant needs to be staged before this module — a VLAN has no
dependency on any other F5OS object in this catalog. It is instead a common prerequisite
for
terraform-f5os-tenant'svlanslist and for VLAN-tagging arguments onterraform-f5os-interface/terraform-f5os-lag. - The single, already-authenticated
f5osprovider instance in scope must target the chassis partition or appliance where the VLAN should be visible.
terraform-f5os-vlan/
├── providers.tf # required_version, F5Networks/f5os ~> 1.10 — no provider {} block
├── variables.tf # var.vlan { vlan_id, name } — 1:1 mapped to the real f5os_vlan schema
├── main.tf # f5os_vlan.this — the module's single keystone resource
├── outputs.tf # id, name, vlan_id
├── SCOPE.md # lightweight standalone contract — RBAC, prerequisites, emits, gotchas
└── README.md # this file — worked example configurations live in 📚 Example Library below
No separate
examples/directory ships with this module — every worked configuration is captured inline in the 📚 Example Library below, using the module's real variable names.
# The caller configures the provider once, elsewhere in the root module:
# provider "f5os" {
# host = var.f5os_host
# username = var.f5os_username
# password = var.f5os_password
# }
module "vlan_100" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 100
name = "vlan100"
}
}Consumes
| Input | Type | Source module |
|---|---|---|
| — | — | None. This is a leaf module in the F5OS catalog; it has no upstream dependency on another terraform-f5os-* module's output. |
Emits
| Output | Description | Consumed by |
|---|---|---|
id |
Provider-internal synthetic identifier for the f5os_vlan resource |
Informational / import use — not typically referenced by sibling modules |
name |
The configured VLAN name, if set (null otherwise) |
Informational; no documented sibling-module argument currently references it |
vlan_id |
The numeric VLAN ID (0-4095) actually configured on the platform | terraform-f5os-tenant (vlans list entries); terraform-f5os-interface / terraform-f5os-lag (VLAN tagging arguments — verify exact argument name per sibling module) |
1 · Minimal VLAN
The smallest real call — both fields set, since name is required in practice.
module "vlan_minimal" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 10
name = "vlan10"
}
}💡 Always set
nameeven though the schema marks it Optional — see "Schema notes that bite."
2 · Naming convention compliance
name must start with a letter, allow only alphanumerics/periods/commas/hyphens/underscores, and
stay under 58 characters.
module "vlan_named" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 20
name = "corp-mgmt_vlan.20"
}
}ℹ️ This module does not enforce the naming pattern with a
validation {}block (it is not a closed enum); the provider itself rejects a malformed name atapplytime.
3 · Lower boundary VLAN ID (0)
module "vlan_zero" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 0
name = "vlan0"
}
}
⚠️ VLAN0is within the documented schema range but may carry special meaning on some F5OS platform releases (e.g. default/native VLAN semantics) — confirm against the target platform's own documentation before relying on it in production.
4 · Upper boundary VLAN ID (4095)
module "vlan_max" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 4095
name = "vlan4095"
}
}5 · Omitting name (failure mode, documented deliberately)
module "vlan_no_name" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 30
# name intentionally omitted
}
}
⚠️ This passesterraform validate(the type isoptional(string), matching the provider's own schema) but the provider's documentation statesnameis required when creating the resource — expect anapply-time failure against a real chassis/appliance. Setnameexplicitly instead.
6 · Multiple VLANs via root-module for_each
This module manages exactly one VLAN per call — fan-out across several VLANs is a root-module concern.
locals {
vlans = {
vlan_10 = { vlan_id = 10, name = "vlan10" }
vlan_20 = { vlan_id = 20, name = "vlan20" }
vlan_100 = { vlan_id = 100, name = "vlan100" }
}
}
module "vlans" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
for_each = local.vlans
vlan = each.value
}7 · Referencing vlan_id into a tenant's vlans list
module "vlan_tenant_data" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 50
name = "vlan50-tenant-data"
}
}
module "tenant_app01" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-tenant.git?ref=v1.0.0"
# Illustrative — consult terraform-f5os-tenant's own README for its full variable schema.
# vlans = [module.vlan_tenant_data.vlan_id]
}🔗 Reference
vlan_id, notid— F5OS cross-references VLANs by numeric ID, andterraform-f5os-tenant'svlansargument is a flatlist(number)of VLAN IDs.
8 · Referencing vlan_id into an interface's VLAN tagging
module "vlan_data" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 60
name = "vlan60-data"
}
}
module "interface_1_0" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-interface.git?ref=v1.0.0"
# Illustrative — consult terraform-f5os-interface's own README for its exact VLAN-tagging
# argument name before wiring module.vlan_data.vlan_id into it.
}9 · VELOS chassis partition target context
The module call itself is identical to the rSeries case — only the caller's provider "f5os" {}
block (outside this module) changes to point at the VELOS chassis controller partition's
management endpoint.
# provider "f5os" {
# host = var.velos_partition_mgmt_ip
# username = var.f5os_username
# password = var.f5os_password
# }
module "vlan_velos" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 70
name = "vlan70-velos"
}
}10 · rSeries appliance target context
# provider "f5os" {
# host = var.rseries_appliance_mgmt_ip
# username = var.f5os_username
# password = var.f5os_password
# }
module "vlan_rseries" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 80
name = "vlan80-rseries"
}
}💡
f5os_vlanbehaves identically on VELOS and rSeries — there is no platform-context branch inside this module.
11 · Externalizing input via terraform.tfvars
# vlan.auto.tfvars
vlan = {
vlan_id = 90
name = "vlan90-ext"
}# main.tf (caller)
module "vlan_from_tfvars" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = var.vlan
}12 · Computed VLAN name via a local value
locals {
vlan_id_value = 200
}
module "vlan_computed_name" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = local.vlan_id_value
name = "vlan${local.vlan_id_value}"
}
}ℹ️ Useful for a root module generating many VLANs from a numeric range without hand-typing each name.
13 · Importing an existing VLAN
module "vlan_existing" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 4
name = "vlan4"
}
}terraform import module.vlan_existing.f5os_vlan.this 4🔒 Per the provider's documented import syntax, the bare numeric VLAN ID is the import key — not a composite string.
🏗️ 14 · End-to-end composition
VLAN provisioned once, then referenced by both an interface and a tenant deployed into a VELOS chassis partition — illustrating the full cross-module contract this module participates in.
module "vlan_app_data" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-vlan.git?ref=v1.0.0"
vlan = {
vlan_id = 500
name = "vlan500-app-data"
}
}
module "partition_appA" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-partition.git?ref=v1.0.0"
# Illustrative — consult terraform-f5os-partition's own README for its full variable schema.
}
module "interface_1_1" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-interface.git?ref=v1.0.0"
# Illustrative — wires module.vlan_app_data.vlan_id into whichever VLAN-tagging
# argument terraform-f5os-interface's own schema exposes.
}
module "tenant_appA" {
source = "git::https://github.com/microsoftexpert/terraform-f5os-tenant.git?ref=v1.0.0"
# Illustrative — consult terraform-f5os-tenant's own README.
# vlans = [module.vlan_app_data.vlan_id]
# partition_name = module.partition_appA.name # VELOS only
}💡 Why it matters: this is the shape every real deployment takes — VLAN and chassis partition provisioned independently and in parallel, then referenced by ID/name from the interface and tenant modules that depend on them. Never hardcode a literal VLAN ID downstream; always pass
module.vlan_app_data.vlan_id.
| Name | Type | Required | Description |
|---|---|---|---|
vlan |
object({ vlan_id = number, name = optional(string) }) |
Yes | VLAN configuration, 1:1 mapped to the f5os_vlan provider schema. |
Full vlan object schema
variable "vlan" {
type = object({
vlan_id = number # Required. 0-4095.
name = optional(string) # Optional per schema; required in practice per provider docs.
# First char must be a letter; alphanumerics, periods, commas,
# hyphens, underscores allowed; max 58 characters.
})
}No default is invented for name beyond the provider's own null/unset behavior — passing it
unset mirrors the provider's schema exactly rather than papering over the docs/schema mismatch
noted in "Schema notes that bite."
| Output | Description | Sensitive |
|---|---|---|
id |
Provider-internal synthetic identifier for the f5os_vlan resource |
No |
name |
The configured VLAN name, if set (null otherwise) |
No |
vlan_id |
The numeric VLAN ID (0-4095) configured on the platform — the value sibling modules should reference | No |
- Single keystone resource, no
for_each.f5os_vlan's schema exposes no nested/child collection (justvlan_idandname), so this module has no genuine child to iterate over. Multiplicity (many VLANs) is a root-module concern — see Example 6. try(var.vlan.name, null)inmain.tf. Defensive around the one optional field this module's object wraps; functionally equivalent to referencingvar.vlan.namedirectly givenoptional(string)'s own null-default behavior, but kept explicit per house style for optional nested-field references.- No VELOS-vs-rSeries branching. Unlike
f5os_partition(VELOS-only) orf5os_tenant(platform-specificpartition_nameinput),f5os_vlanbehaves identically on both platform contexts — there is nothing in this module'smain.tfthat varies by target. - Ordering. A VLAN should exist before any sibling tenant/interface/LAG module references its
vlan_id— always pass this module'svlan_idoutput into the consuming module's input via an implicit Terraform reference, never a hardcoded literal. vlan_idtreated as effectively immutable in practice. The fetched schema does not surface an explicit(Requires replacement)annotation, but since it is the VLAN's identifying value, verify actual in-place-update behavior against a realterraform planbefore assuming it is safe to change post-creation.
| Concern | Secure default | Opt-out (caller must type extra) |
|---|---|---|
| VLAN identification | No default vlan_id — always an explicit, required input; matches the house-wide "no allow-all VLANs" rule |
N/A — hard rule, not a toggle |
| VLAN naming | This module does not fabricate a default name even though the schema marks it Optional — passing it unset mirrors the provider's own optionality rather than papering over the documented schema/docs mismatch |
Caller explicitly supplies name (recommended for every real deployment per the provider's own documentation) |
| Credentials / secrets | Not applicable — f5os_vlan carries no secret-shaped argument |
N/A |
cd C:\GitHubCode\newf5modules\f5os\terraform-f5os-vlan
terraform init -backend=false
terraform validate
terraform fmt -check
Remove-Item -Recurse -Force.terraform,.terraform.lock.hcl -ErrorAction SilentlyContinuePin every consumer to a specific release: ?ref=v1.0.0.
This is a plan-only proof gate — it never touches a real chassis or appliance.
| Check | Catches | Does not catch |
|---|---|---|
terraform validate |
Missing vlan_id, wrong type on either field, malformed HCL |
The name-required-in-practice mismatch; vlan_id out-of-range values; RBAC/permission failures |
terraform fmt -check |
Formatting drift from canonical style | Anything semantic |
terraform plan (human-run, against real infra) |
The above two gaps — a real F5OS structured error surfaces at plan/apply time | — |
$ terraform output
id = "100"
name = "vlan100"
vlan_id = 100
| Symptom | Cause | Fix |
|---|---|---|
apply fails with a name-required error despite validate passing |
name omitted — schema marks it Optional but the provider requires it in practice at creation |
Set vlan.name explicitly (see Example 5) |
apply fails with an out-of-range VLAN ID error |
vlan_id outside 0-4095 — not enforced by Terraform's type system |
Correct vlan_id to the documented range |
Permission denied / RBAC error at apply |
The authenticated user's role lacks VLAN-management privilege on the target chassis partition or appliance | Grant at least the operator role scoped to that partition/appliance |
init cannot resolve provider version |
~> 1.10 no longer matches the current Terraform Registry listing |
Re-verify the pin against the registry and update providers.tf |
Plan shows unexpected diff on name/vlan_id with no caller change |
A previous out-of-band change was made directly on the F5OS platform | Reconcile via terraform import or terraform plan -refresh-only before applying |
f5os_vlanresource reference — F5Networks/f5os provider docsf5os_userresource reference — source of the confirmed RBAC role examples (admin,operator,user)- Sibling modules:
terraform-f5os-interface,terraform-f5os-lag,terraform-f5os-tenant,terraform-f5os-partition - This module's
SCOPE.md
💙 "Infrastructure as Code should be standardized, consistent, and secure."