Skip to content

Add VLAN ID support to vsphere_network data source#2675

Closed
akli-ime wants to merge 6 commits intovmware:mainfrom
akli-ime:patch-2
Closed

Add VLAN ID support to vsphere_network data source#2675
akli-ime wants to merge 6 commits intovmware:mainfrom
akli-ime:patch-2

Conversation

@akli-ime
Copy link
Contributor

@akli-ime akli-ime commented Feb 8, 2026

This PR adds support for filtering networks by VLAN ID in the vsphere_network data source.

Currently, the data source only allows lookup by name. With this change, users can look up Distributed Virtual Port Groups based on their VLAN ID.

Changes

  • Added a new optional schema field vlan_id (TypeInt).
  • Introduced helper distributedPortGroupStructure and function expandDistributedPortGroupVlan.
  • Updated dataSourceVSphereNetworkRead to handle VLAN-based network lookup.
  • Updated documentation to include the new vlan_id argument.

Tests

  • Tests have not been added

Example Usage

data "vsphere_network" "filter_vlan_by_id {
  vlan_id       = 101
  datacenter_id = "datacenter-123"
} 

@akli-ime akli-ime requested a review from a team as a code owner February 8, 2026 22:07
@github-actions github-actions bot added documentation Documentation provider Provider needs-review Needs Review size/m Relative Sizing: Medium labels Feb 8, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new lookup mode to the vsphere_network data source so users can discover a Distributed Virtual Port Group by VLAN ID instead of (only) by name.

Changes:

  • Makes name optional and introduces vlan_id with ExactlyOneOf enforcement.
  • Implements VLAN-based DVPG lookup by scanning networks and inspecting DVPG default port config VLAN settings.
  • Updates vsphere_network data source docs to describe the new vlan_id argument.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
vsphere/data_source_vsphere_network.go Adds vlan_id schema + new VLAN-based lookup logic in dataSourceVSphereNetworkRead.
docs/data-sources/network.md Documents vlan_id and updates name to optional with mutual exclusivity.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions github-actions bot added the documentation Documentation label Feb 9, 2026
@akli-ime akli-ime requested a review from tenthirtyam February 9, 2026 08:46
Copy link
Contributor

@spacegospod spacegospod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name attribute should remain mandatory IMO.

I have my doubts about the general idea of filtering by VLAN ID becaue it is not a unique identifier. On the contrary - VLANs are intended to be shared across multiple portgroups.

This implementation also does not handle VLAN trunks and standard portgroups. It will only work for distributed portgroups with a single VLAN ID.

Comment on lines +189 to +192
dvpg, ok := n.(*object.DistributedVirtualPortgroup)
if !ok {
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Standard networks can be assigned with a VLAN ID too

Copy link
Contributor Author

@akli-ime akli-ime Feb 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole point of this PR is to allow lookup by VLAN ID without requiring a name. Names may not always be known or consistent — for example, a portgroup might have one name in vSphere and a completely different one in Infoblox (IP address management, IPAM). Using only the VLAN ID provides a single identifier that can be used to bind resources across both technologies, so making the name mandatory would defeat the purpose. This provides an alternative for identifying distributed portgroups by VLAN.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, ExactlyOneOf will mean that name is still necessary as long as vlan_id is not set.

I'm assuming that your infrastructure has a one-to-one mapping of distributed portgroups and VLAN IDs.
This is not how it works in vSphere though. Every managed resource has a single unique identifier and that is its ID.
Names can be treated as unique too because the VIM API enforces this rule and we use it for our datasources.
Trying to identify a network by its VLAN ID will begin to fail as soon as a second portgroup is assigned to the same VLAN.

Let me give some examples how network names are unique

  1. Standard networks

Every host has a "VM Network" created by default. All of these actually point to the same managed object.
Even if you create a new standard network on several hosts using the same name, these networks would be backed by a single managed object.

  1. Opaque networks

These are externally created by NSX. The name is unique in both systems and is synchronized between NSX-T and vCenter.

  1. Distributed portgroups

Every distributed portgroup is a managed object and is stored in the same network folder as its distributed switch.
To the VIM API a VDS and a distributed portgroup are equal entities (the UI renders them as nested but that's only visual)

vCenter does not allow more than 1 distributed portgroup to exist under the same name even across different datacenters. What it does allow is an arbitrary number of distributed portgroups to be assigned to the same VLAN

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From our perspective, it is important to give users the flexibility to decide how they want to identify and select their target resources when using the data source.

At the moment, the provider already offers mechanisms to help narrow down the selection, including support for wildcard (*) name patterns. When multiple networks match, a clear error message is returned to prompt the user to refine their criteria.

Here is a concrete example I just tested with Terraform, using a wildcard name pattern:

data "vsphere_network" "network" {
  name          = "V3*"
  datacenter_id = data.vsphere_datacenter.datacenter.id
}

Returned error:

Error: multiple networks found with the name 'V3*'. Please specify a filter to narrow down the results

This approach helps avoid ambiguity and encourages users to be explicit about their intent, which is especially important in environments where multiple networks may share similar characteristics.

In this context, leaving the responsibility of precise resource identification to the user provides greater flexibility and aligns well with the variety of infrastructure designs found in real-world deployments.

@akli-ime
Copy link
Contributor Author

This implementation is directly inspired by the semantics of the official vsphere_host_port_group resource, where vlan_id = 4095 explicitly represents trunk mode. The same convention was deliberately reused here to stay fully aligned with existing Terraform vsphere provider behavior, as well as with the current resource schema and data source filtering logic.

The main objective of this pull request is therefore to align the existing implementation across resource and data source, rather than introducing new or custom semantics. This ensures consistency and predictability for users already familiar with vSphere networking in Terraform:

0 → no tagging
1–4094 → single VLAN
4095 → trunk mode

Regarding trunk mode, I fully agree that filtering based on VLAN ID is not meaningful, since trunk portgroups do not represent a single VLAN. However, users who need to identify or filter trunk portgroups can still reliably do so using the name attribute, even though it is now optional. In practice, name-based filtering remains the recommended and deterministic approach for trunk portgroups, while VLAN-based filtering is intended for single-VLAN use cases only.

So in practice:

-VLAN ID filtering is designed for single-VLAN portgroups.
-Trunk mode is supported for configuration consistency and provider alignment.
-Filtering trunk portgroups should rely on the portgroup name, which remains fully supported.

Overall, this PR mainly aligns the existing behavior with the Terraform vsphere provider model and the current data source filter, without changing the fundamental networking semantics.

@spacegospod
Copy link
Contributor

Please open an issue in the backlog and include any relevant information from this PR (e.g. why this is a valid scenario for your setup).

I am not denying that supporting a 1-1 mapping between VLANs and portgroups works for your environment but I would like to gather more input from the community. I'm not willing to maintain this workflow unless it's a widely adopted practice.

@akli-ime
Copy link
Contributor Author

I’m opening an issue to gather community feedback on optionally supporting a strict 1-to-1 VLAN ↔ Portgroup mapping for d/vsphere_network: #2677

@tenthirtyam tenthirtyam removed the needs-review Needs Review label Mar 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-response Awaiting Response documentation Documentation enhancement Enhancement provider Provider size/m Relative Sizing: Medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants