Repository: bpg/terraform-provider-proxmox

Issue:
LXC flaky acceptance tests
**Describe the bug**
Tests in `resource_container_test.go` seem to be flaky and fail randomly. 

**To Reproduce**
Steps to reproduce the behavior:

```bash
./testacc TestAccResourceContainer
```

Output (may be different):
```
--- FAIL: TestAccResourceContainer (104.98s)
    --- FAIL: TestAccResourceContainer/create,_start_and_update_container (6.59s)
        resource_container_test.go:738: Step 1/3 error: Error running apply: exit status 1
            
            Error: error creating container: received an HTTP 500 response - Reason: unable to create CT 100236 - can't lock file '/run/lock/lxc/pve-config-100236.lock' - got timeout
            
              with proxmox_virtual_environment_container.test_container,
              on terraform_plugin_test.tf line 25, in resource "proxmox_virtual_environment_container" "test_container":
              25:                               resource "proxmox_virtual_environment_container" "test_container" {
            
    --- FAIL: TestAccResourceContainer/dns_block_with_null_values_on_create (87.48s)
        resource_container_test.go:738: Step 1/1 error: Error running apply: exit status 1
            
            Error: error waiting for container start: task "UPID:pve:000153A5:000B006B:690927F6:vzstart:103:root@pam:" failed to complete with exit code: can't lock file '/run/lock/lxc/pve-config-103.lock' - got timeout
            
              with proxmox_virtual_environment_container.test_container,
              on terraform_plugin_test.tf line 25, in resource "proxmox_virtual_environment_container" "test_container":
              25:                               resource "proxmox_virtual_environment_container" "test_container" {
            
    --- FAIL: TestAccResourceContainer/empty_dns_block_on_create (87.50s)
        resource_container_test.go:738: Step 1/1 error: Error running apply: exit status 1
            
            Error: error waiting for container start: task "UPID:pve:00015380:000B0002:690927F5:vzstart:102:root@pam:" failed to complete with exit code: can't lock file '/run/lock/lxc/pve-config-102.lock' - got timeout
            
              with proxmox_virtual_environment_container.test_container,
              on terraform_plugin_test.tf line 25, in resource "proxmox_virtual_environment_container" "test_container":
              25:                               resource "proxmox_virtual_environment_container" "test_container" {
            
FAIL
FAIL    github.com/bpg/terraform-provider-proxmox/fwprovider/test       220.790s
FAIL
```

**Expected behavior**
Tests are run successfully

**Additional context**
branch: main (227ceef9)

- Single or clustered Proxmox: single, installed in VirtualBox
- Proxmox version: 9.0.3
- Provider version (ideally it should be the latest version): commit 227ceef9
- Terraform/OpenTofu version: v1.13.4
- OS (where you run Terraform/OpenTofu from): linux_amd
- Debug logs (`TF_LOG=DEBUG terraform apply`):


Discussion:
@bpg: These types of errors (config lock) are often a symptom of slow I/O or other resource bottlenecks on the PVE host, and are more common on virtualized PVE instances.@shamilovstas: > These types of errors (config lock) are often a symptom of slow I/O or other resource bottlenecks on the PVE host, and are more common on virtualized PVE instances.

While what you said might be true, what I also noticed is that the test in `resource_container_test.go` had `resource.TestStep`s running in parallel. Since they all were using the same container, I suspect it might be source for at least some portion of the test's flakiness. 
In the draft PR mentioned above I tried to split the test into multiple independent tests that use their own containers. While there are still some flakiness, overall it seems the test started working better.
As for the remaining flakiness, I observe that it happens in `TestAccResourceContainer` and `TestAccResourceContainerHostname` and seems to be related to the situations when a container needs to be rebooted. From the proxmox log I noticed that sometimes `Shutdown` is called right after `Reboot`. If this happens, usually the `Shutdown` task gets stuck and causes timeout. When it doesn't happen, tests pass.@bpg: Thanks, good points! If test containers use the same IDs then for sure there is a good chance for conflicts. Unique ID autogeneration (when `vm_id` is omitted) is not super reliable in the proxmox / provider either.

Solution patch:
diff --git a/.all-contributorsrc b/.all-contributorsrc
index 5f1cfdca..b2e63f88 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -1528,6 +1528,15 @@
       "contributions": [
         "code"
       ]
+    },
+    {
+      "login": "alexhaydock",
+      "name": "Alex Haydock",
+      "avatar_url": "https://avatars.githubusercontent.com/u/13152214?v=4",
+      "profile": "https://github.com/alexhaydock",
+      "contributions": [
+        "doc"
+      ]
     }
   ],
   "contributorsPerLine": 7,
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 4cee34dc..97cb76be 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -215,6 +215,7 @@
     <tr>
       <td align="center" valign="top" width="14.28%"><a href="https://mlit.pro"><img src="https://avatars.githubusercontent.com/u/693906?v=4?s=100" width="100px;" alt="Maciej Lech"/><br /><sub><b>Maciej Lech</b></sub></a><br /><a href="https://github.com/bpg/terraform-provider-proxmox/commits?author=maciej-lech" title="Tests">⚠️</a> <a href="https://github.com/bpg/terraform-provider-proxmox/commits?author=maciej-lech" title="Code">💻</a></td>
       <td align="center" valign="top" width="14.28%"><a href="https://github.com/JustasUmbrasas"><img src="https://avatars.githubusercontent.com/u/70886320?v=4?s=100" width="100px;" alt="Justas Umbrasas"/><br /><sub><b>Justas Umbrasas</b></sub></a><br /><a href="https://github.com/bpg/terraform-provider-proxmox/commits?author=JustasUmbrasas" title="Code">💻</a></td>
+      <td align="center" valign="top" width="14.28%"><a href="https://github.com/alexhaydock"><img src="https://avatars.githubusercontent.com/u/13152214?v=4?s=100" width="100px;" alt="Alex Haydock"/><br /><sub><b>Alex Haydock</b></sub></a><br /><a href="https://github.com/bpg/terraform-provider-proxmox/commits?author=alexhaydock" title="Documentation">📖</a></td>
     </tr>
   </tbody>
   <tfoot>
diff --git a/docs/data-sources/virtual_environment_sdn_vnet.md b/docs/data-sources/virtual_environment_sdn_vnet.md
index 3497dd73..a1b2ffdf 100644
--- a/docs/data-sources/virtual_environment_sdn_vnet.md
+++ b/docs/data-sources/virtual_environment_sdn_vnet.md
@@ -11,7 +11,24 @@ description: |-
 
 Retrieves information about an existing SDN VNet.
 
-
+## Example Usage
+
+```terraform
+data "proxmox_virtual_environment_sdn_vnet" "example" {
+  id = "vnet1"
+}
+
+output "data_proxmox_virtual_environment_sdn_vnet" {
+  value = {
+    id            = data.proxmox_virtual_environment_sdn_vnet.example.id
+    zone          = data.proxmox_virtual_environment_sdn_vnet.example.zone
+    alias         = data.proxmox_virtual_environment_sdn_vnet.example.alias
+    isolate_ports = data.proxmox_virtual_environment_sdn_vnet.example.isolate_ports
+    tag           = data.proxmox_virtual_environment_sdn_vnet.example.tag
+    vlan_aware    = data.proxmox_virtual_environment_sdn_vnet.example.vlan_aware
+  }
+}
+```
 
 <!-- schema generated by tfplugindocs -->
 ## Schema
diff --git a/docs/data-sources/virtual_environment_sdn_vnets.md b/docs/data-sources/virtual_environment_sdn_vnets.md
new file mode 100644
index 00000000..01353bfd
--- /dev/null
+++ b/docs/data-sources/virtual_environment_sdn_vnets.md
@@ -0,0 +1,44 @@
+---
+layout: page
+title: proxmox_virtual_environment_sdn_vnets
+parent: Data Sources
+subcategory: Virtual Environment
+description: |-
+  Retrieves information about all SDN VNets in Proxmox. This data source lists all virtual networks configured in the Software-Defined Networking setup.
+---
+
+# Data Source: proxmox_virtual_environment_sdn_vnets
+
+Retrieves information about all SDN VNets in Proxmox. This data source lists all virtual networks configured in the Software-Defined Networking setup.
+
+## Example Usage
+
+```terraform
+# List all SDN VNets
+data "proxmox_virtual_environment_sdn_vnets" "all" {}
+
+output "data_proxmox_virtual_environment_sdn_vnets_all" {
+  value = {
+    vnets = data.proxmox_virtual_environment_sdn_vnets.all.vnets
+  }
+}
+```
+
+<!-- schema generated by tfplugindocs -->
+## Schema
+
+### Read-Only
+
+- `vnets` (List of Object) List of SDN VNets. (see [below for nested schema](#nestedatt--vnets))
+
+<a id="nestedatt--vnets"></a>
+### Nested Schema for `vnets`
+
+Read-Only:
+
+- `alias` (String)
+- `id` (String)
+- `isolate_ports` (Boolean)
+- `tag` (Number)
+- `vlan_aware` (Boolean)
+- `zone` (String)
diff --git a/docs/index.md b/docs/index.md
index dba630d4..1444e2fd 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -45,6 +45,14 @@ Use the navigation to the left to read about the available resources.
 | `PROXMOX_VE_SSH_USERNAME` | SSH username | No |
 | `PROXMOX_VE_SSH_PASSWORD` | SSH password | No |
 | `PROXMOX_VE_SSH_PRIVATE_KEY` | SSH private key | No |
+| `PROXMOX_VE_SSH_AGENT` | Use SSH agent for authentication | No |
+| `PROXMOX_VE_SSH_AUTH_SOCK` | SSH agent socket path | No |
+| `PROXMOX_VE_SSH_AGENT_FORWARDING` | Enable SSH agent forwarding | No |
+| `PROXMOX_VE_SSH_SOCKS5_SERVER` | SOCKS5 proxy server address | No |
+| `PROXMOX_VE_SSH_SOCKS5_USERNAME` | SOCKS5 proxy username | No |
+| `PROXMOX_VE_SSH_SOCKS5_PASSWORD` | SOCKS5 proxy password | No |
+| `PROXMOX_VE_MIN_TLS` | Minimum TLS version | No |
+| `PROXMOX_VE_OTP` | One-time password (deprecated) | No |
 | `PROXMOX_VE_TMPDIR` | Custom temporary directory | No |
 
 *One of these authentication methods is required
@@ -76,7 +84,7 @@ provider "proxmox" {
 ## Authentication
 
 The Proxmox provider offers a flexible means of providing credentials for authentication.
-Static credentials and pre-authenticated session-ticket can be provided to the `proxmox` block through one of the choices of arguments below, ordered by precedence:
+Static credentials and pre-authenticated session ticket can be provided to the `proxmox` block through one of the choices of arguments below, ordered by precedence:
 
 - `api_token`
 - `auth_ticket` and `csrf_prevention_token`
@@ -192,20 +200,20 @@ See the [Argument Reference](#argument-reference) section for the supported vari
 ### API Token Authentication
 
 API Token authentication can be used to authenticate with the Proxmox API without the need to provide a password.
-In combination with the `ssh` block and `ssh-agent` support, this allows for a fully password-less authentication.
+In combination with the `ssh` block and SSH agent support, this allows for a fully password-less authentication.
 
 You can create an API Token for a user via the Proxmox UI, or via the command line on the Proxmox host or cluster:
 
 - Create a user:
 
     ```sh
-    sudo pveum user add terraform@pve
+    pveum user add terraform@pve
     ```
 
 - Create a role for the user (you can skip this step if you want to use any of the existing roles):
 
     ```sh
-    sudo pveum role add Terraform -privs "Realm.AllocateUser, VM.PowerMgmt, VM.GuestAgent.Unrestricted, Sys.Console, Sys.Audit, Sys.AccessNetwork, VM.Config.Cloudinit, VM.Replicate, Pool.Allocate, SDN.Audit, Realm.Allocate, SDN.Use, Mapping.Modify, VM.Config.Memory, VM.GuestAgent.FileSystemMgmt, VM.Allocate, SDN.Allocate, VM.Console, VM.Clone, VM.Backup, Datastore.AllocateTemplate, VM.Snapshot, VM.Config.Network, Sys.Incoming, Sys.Modify, VM.Snapshot.Rollback, VM.Config.Disk, Datastore.Allocate, VM.Config.CPU, VM.Config.CDROM, Group.Allocate, Datastore.Audit, VM.Migrate, VM.GuestAgent.FileWrite, Mapping.Use, Datastore.AllocateSpace, Sys.Syslog, VM.Config.Options, Pool.Audit, User.Modify, VM.Config.HWType, VM.Audit, Sys.PowerMgmt, VM.GuestAgent.Audit, Mapping.Audit, VM.GuestAgent.FileRead, Permissions.Modify"
+    pveum role add Terraform -privs "Realm.AllocateUser, VM.PowerMgmt, VM.GuestAgent.Unrestricted, Sys.Console, Sys.Audit, Sys.AccessNetwork, VM.Config.Cloudinit, VM.Replicate, Pool.Allocate, SDN.Audit, Realm.Allocate, SDN.Use, Mapping.Modify, VM.Config.Memory, VM.GuestAgent.FileSystemMgmt, VM.Allocate, SDN.Allocate, VM.Console, VM.Clone, VM.Backup, Datastore.AllocateTemplate, VM.Snapshot, VM.Config.Network, Sys.Incoming, Sys.Modify, VM.Snapshot.Rollback, VM.Config.Disk, Datastore.Allocate, VM.Config.CPU, VM.Config.CDROM, Group.Allocate, Datastore.Audit, VM.Migrate, VM.GuestAgent.FileWrite, Mapping.Use, Datastore.AllocateSpace, Sys.Syslog, VM.Config.Options, Pool.Audit, User.Modify, VM.Config.HWType, VM.Audit, Sys.PowerMgmt, VM.GuestAgent.Audit, Mapping.Audit, VM.GuestAgent.FileRead, Permissions.Modify"
     ```
 
   ~> The list of available privileges has been changed in PVE 9.0, and the above list is only an example (and most likely too excessive for most use cases), please review it and adjust to your needs.
@@ -214,15 +222,17 @@ You can create an API Token for a user via the Proxmox UI, or via the command li
 - Assign the role to the previously created user:
 
     ```sh
-    sudo pveum aclmod / -user terraform@pve -role Terraform
+    pveum aclmod / -user terraform@pve -role Terraform
     ```
 
 - Create an API token for the user:
 
     ```sh
-    sudo pveum user token add terraform@pve provider --privsep=0
+    pveum user token add terraform@pve provider --privsep=0
     ```
 
+    -> Make sure you copy the token value, as it will not be displayed again.
+
 Refer to the upstream docs as needed for additional details concerning [PVE User Management](https://pve.proxmox.com/wiki/User_Management).
 
 Generating the token will output a table containing the token's ID and secret which are meant to be concatenated into a single string for use with either the `api_token` field of the `provider` block (fine for testing but should be avoided) or sourced from the `PROXMOX_VE_API_TOKEN` environment variable.
@@ -322,7 +332,7 @@ Please refer to the [Argument Reference](#argument-reference) section to view th
 ### SSH Agent
 
 The provider does not use OS-specific SSH configuration files, such as `~/.ssh/config`.
-Instead, it uses the SSH protocol directly, and supports the `SSH_AUTH_SOCK` environment variable (or `agent_socket` argument) to connect to the `ssh-agent`.
+Instead, it uses the SSH protocol directly, and supports the `SSH_AUTH_SOCK` environment variable (or `agent_socket` argument) to connect to the SSH agent.
 This allows the provider to use the SSH agent configured by the user, and to support multiple SSH agents running on the same machine.
 You can find more details on the SSH Agent [here](https://www.digitalocean.com/community/tutorials/ssh-essentials-working-with-ssh-servers-clients-and-keys#adding-your-ssh-keys-to-an-ssh-agent-to-avoid-typing-the-passphrase).
 The SSH agent authentication takes precedence over the `private_key` and `password` authentication.
@@ -436,7 +446,7 @@ In the example below, we create a user `terraform` and assign the `sudo` privile
 
   You should be able to connect to the target node and see the output containing `APIVER <number>` on the screen without being prompted for your password.
 
-Alternatively if `pam_ssh_agent_auth` is configured on the target node the SSH Config option `agent_forwarding` may be used to forward the SSH Agent that was used for the connection to the remote server. This can allow `sudo` without a password which validates public ssh key configured for `pam_ssh_agent_auth`.
+Alternatively if `pam_ssh_agent_auth` is configured on the target node the SSH Config option `agent_forwarding` may be used to forward the SSH agent that was used for the connection to the remote server. This can allow `sudo` without a password which validates public SSH key configured for `pam_ssh_agent_auth`.
 
 ### Node IP address used for SSH connection
 
diff --git a/docs/resources/virtual_environment_container.md b/docs/resources/virtual_environment_container.md
index 0255b9e1..13542a17 100644
--- a/docs/resources/virtual_environment_container.md
+++ b/docs/resources/virtual_environment_container.md
@@ -160,9 +160,9 @@ output "ubuntu_container_public_key" {
         - `ipv6` - (Optional) The IPv6 configuration.
             - `address` - (Optional) The IPv6 address in CIDR notation
               (e.g. fd1c::7334/64). Alternatively, set this
-              to `dhcp` for autodiscovery.
+              to `dhcp` for DHCPv6, or `auto` for SLAAC.
             - `gateway` - (Optional) The IPv6 gateway (must be omitted
-                when `dhcp` is used as the address).
+                when `dhcp` or `auto` are used as the address).
     - `user_account` - (Optional) The user account configuration.
         - `keys` - (Optional) The SSH keys for the root account.
         - `password` - (Optional) The password for the root account.
@@ -225,7 +225,8 @@ output "ubuntu_container_public_key" {
         - `opensuse` - openSUSE.
         - `ubuntu` - Ubuntu.
         - `unmanaged` - Unmanaged.
-- `pool_id` - (Optional) The identifier for a pool to assign the container to.
+- `pool_id` - (Optional, **Deprecated**) The identifier for a pool to assign the container to.
+  This field is deprecated and will be removed in a future release. To assign the container to a pool, use the `proxmox_virtual_environment_pool_membership` resource instead. 
 - `protection` - (Optional) Whether to set the protection flag of the container (defaults to `false`). This will prevent the container itself and its disk for remove/update operations.
 - `started` - (Optional) Whether to start the container (defaults to `true`).
 - `startup` - (Optional) Defines startup and shutdown behavior of the container.
diff --git a/docs/resources/virtual_environment_vm.md b/docs/resources/virtual_environment_vm.md
index a52777be..07cab635 100755
--- a/docs/resources/virtual_environment_vm.md
+++ b/docs/resources/virtual_environment_vm.md
@@ -390,9 +390,9 @@ output "ubuntu_vm_public_key" {
         - `ipv6` - (Optional) The IPv6 configuration.
             - `address` - (Optional) The IPv6 address in CIDR notation
                 (e.g. fd1c::7334/64). Alternatively, set this
-                to `dhcp` for autodiscovery.
+                to `dhcp` for DHCPv6, or `auto` for SLAAC.
             - `gateway` - (Optional) The IPv6 gateway (must be omitted
-                when `dhcp` is used as the address).
+                when `dhcp` or `auto` are used as the address).
     - `user_account` - (Optional) The user account configuration (conflicts
         with `user_data_file_id`).
         - `keys` - (Optional) The SSH keys.
@@ -503,7 +503,8 @@ output "ubuntu_vm_public_key" {
         - `win11` - Windows 11
         - `wvista` - Windows Vista.
         - `wxp` - Windows XP.
-- `pool_id` - (Optional) The identifier for a pool to assign the virtual machine to.
+- `pool_id` - (Optional, **Deprecated**) The identifier for a pool to assign the virtual machine to.
+  This field is deprecated and will be removed in a future release. To assign the VM to a pool, use the `proxmox_virtual_environment_pool_membership` resource instead.
 - `protection` - (Optional) Sets the protection flag of the VM. This will disable the remove VM and remove disk operations (defaults to `false`).
 - `reboot` - (Optional) Reboot the VM after initial creation (defaults to `false`).
 - `reboot_after_update` - (Optional) Reboot the VM after update if needed (defaults to `true`).
diff --git a/example/data_source_virtual_environment_sdn.tf b/example/data_source_virtual_environment_sdn.tf
index 42553d17..13852e48 100644
--- a/example/data_source_virtual_environment_sdn.tf
+++ b/example/data_source_virtual_environment_sdn.tf
@@ -23,6 +23,13 @@ data "proxmox_virtual_environment_sdn_vnet" "test_vnet_1" {
   id = proxmox_virtual_environment_sdn_vnet.test_vnet_1.id
 }
 
+data "proxmox_virtual_environment_sdn_vnets" "all" {
+  depends_on = [
+    proxmox_virtual_environment_sdn_vnet.test_vnet_1,
+    proxmox_virtual_environment_sdn_vnet.test_vnet_2,
+  ]
+}
+
 data "proxmox_virtual_environment_sdn_subnet" "test_subnet_dhcp" {
   depends_on = [proxmox_virtual_environment_sdn_subnet.test_subnet_dhcp]
   cidr = proxmox_virtual_environment_sdn_subnet.test_subnet_dhcp.cidr
@@ -45,6 +52,10 @@ output "proxmox_virtual_environment_sdn_vnet" {
   value = data.proxmox_virtual_environment_sdn_vnet.test_vnet_1
 }
 
+output "proxmox_virtual_environment_sdn_vnets" {
+  value = data.proxmox_virtual_environment_sdn_vnets.all
+}
+
 output "proxmox_virtual_environment_sdn_subnet" {
   value = data.proxmox_virtual_environment_sdn_subnet.test_subnet_dhcp
 }
diff --git a/example/resource_virtual_environment_container.tf b/example/resource_virtual_environment_container.tf
index 0e9f3e70..85893369 100644
--- a/example/resource_virtual_environment_container.tf
+++ b/example/resource_virtual_environment_container.tf
@@ -42,7 +42,7 @@ resource "proxmox_virtual_environment_container" "example_template" {
   node_name = data.proxmox_virtual_environment_nodes.example.names[0]
 
   operating_system {
-    template_file_id = proxmox_virtual_environment_download_file.release_20250701_ubuntu_24_10_lxc_img.id
+    template_file_id = proxmox_virtual_environment_download_file.ubuntu_24_04_lxc_img.id
     type             = "ubuntu"
   }
 
diff --git a/example/resource_virtual_environment_download_file.tf b/example/resource_virtual_environment_download_file.tf
index ae5ec760..2dc8a335 100644
--- a/example/resource_virtual_environment_download_file.tf
+++ b/example/resource_virtual_environment_download_file.tf
@@ -1,11 +1,11 @@
 ## Debian and ubuntu image download
 
-resource "proxmox_virtual_environment_download_file" "release_20250701_ubuntu_24_10_lxc_img" {
+resource "proxmox_virtual_environment_download_file" "ubuntu_24_04_lxc_img" {
   content_type        = "vztmpl"
   datastore_id        = "local"
   node_name           = data.proxmox_virtual_environment_nodes.example.names[0]
-  url                 = var.release_20250701_ubuntu_24_10_lxc_img_url
-  checksum            = var.release_20250701_ubuntu_24_10_lxc_img_checksum
+  url                 = var.ubuntu_24_04_lxc_img_url
+  checksum            = var.ubuntu_24_04_lxc_img_checksum
   checksum_algorithm  = "sha256"
   upload_timeout      = 4444
   overwrite_unmanaged = true
diff --git a/example/resource_virtual_environment_vm.tf b/example/resource_virtual_environment_vm.tf
index 9340f732..03938c35 100644
--- a/example/resource_virtual_environment_vm.tf
+++ b/example/resource_virtual_environment_vm.tf
@@ -17,6 +17,10 @@ resource "proxmox_virtual_environment_vm" "example_template" {
     # affinity = "0-1"
   }
 
+  memory {
+    dedicated = 2048
+  }
+
   smbios {
     manufacturer = "Terraform"
     product      = "Terraform Provider Proxmox"
@@ -133,7 +137,7 @@ resource "proxmox_virtual_environment_vm" "example" {
   machine = "q35"
 
   memory {
-    dedicated = 768
+    dedicated = 2048
     # hugepages = "2"
   }
 
diff --git a/example/variables.tf b/example/variables.tf
index 254f7933..231d27f8 100644
--- a/example/variables.tf
+++ b/example/variables.tf
@@ -52,14 +52,14 @@ variable "latest_debian_12_bookworm_qcow2_img_url" {
   default     = "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
 }
 
-variable "release_20250701_ubuntu_24_10_lxc_img_url" {
+variable "ubuntu_24_04_lxc_img_url" {
   description = "The URL for the Ubuntu 24.10 LXC image"
   type        = string
-  default     = "https://mirrors.servercentral.com/ubuntu-cloud-images/releases/24.10/release-20250701/ubuntu-24.10-server-cloudimg-amd64-root.tar.xz"
+  default     = "https://cloud-images.ubuntu.com/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64-root.tar.xz"
 }
 
-variable "release_20250701_ubuntu_24_10_lxc_img_checksum" {
+variable "ubuntu_24_04_lxc_img_checksum" {
   description = "The checksum for the Ubuntu 24.10 LXC image"
   type        = string
-  default     = "6caa4e90e4c2ae33d3fff0526c75cfc3d221e0c1ccd49d01229a44776af126d1"
+  default     = "bdc90f9c0908e45dc602208da8fbd9e38db6483a1483fc7042332f5cd4e9aa22"
 }
diff --git a/examples/data-sources/proxmox_virtual_environment_sdn_vnet/data-source.tf b/examples/data-sources/proxmox_virtual_environment_sdn_vnet/data-source.tf
new file mode 100644
index 00000000..724d9c38
--- /dev/null
+++ b/examples/data-sources/proxmox_virtual_environment_sdn_vnet/data-source.tf
@@ -0,0 +1,14 @@
+data "proxmox_virtual_environment_sdn_vnet" "example" {
+  id = "vnet1"
+}
+
+output "data_proxmox_virtual_environment_sdn_vnet" {
+  value = {
+    id            = data.proxmox_virtual_environment_sdn_vnet.example.id
+    zone          = data.proxmox_virtual_environment_sdn_vnet.example.zone
+    alias         = data.proxmox_virtual_environment_sdn_vnet.example.alias
+    isolate_ports = data.proxmox_virtual_environment_sdn_vnet.example.isolate_ports
+    tag           = data.proxmox_virtual_environment_sdn_vnet.example.tag
+    vlan_aware    = data.proxmox_virtual_environment_sdn_vnet.example.vlan_aware
+  }
+}
diff --git a/examples/data-sources/proxmox_virtual_environment_sdn_vnets/data-source.tf b/examples/data-sources/proxmox_virtual_environment_sdn_vnets/data-source.tf
new file mode 100644
index 00000000..94c8e364
--- /dev/null
+++ b/examples/data-sources/proxmox_virtual_environment_sdn_vnets/data-source.tf
@@ -0,0 +1,8 @@
+# List all SDN VNets
+data "proxmox_virtual_environment_sdn_vnets" "all" {}
+
+output "data_proxmox_virtual_environment_sdn_vnets_all" {
+  value = {
+    vnets = data.proxmox_virtual_environment_sdn_vnets.all.vnets
+  }
+}
diff --git a/fwprovider/cluster/sdn/vnet/datasource_vnets.go b/fwprovider/cluster/sdn/vnet/datasource_vnets.go
new file mode 100644
index 00000000..e93e0993
--- /dev/null
+++ b/fwprovider/cluster/sdn/vnet/datasource_vnets.go
@@ -0,0 +1,169 @@
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package vnet
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/hashicorp/terraform-plugin-framework/attr"
+	"github.com/hashicorp/terraform-plugin-framework/datasource"
+	"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+
+	"github.com/bpg/terraform-provider-proxmox/fwprovider/config"
+	"github.com/bpg/terraform-provider-proxmox/proxmox/cluster/sdn"
+	"github.com/bpg/terraform-provider-proxmox/proxmox/cluster/sdn/vnets"
+)
+
+// Ensure the implementation satisfies the required interfaces.
+var (
+	_ datasource.DataSource              = &vnetsDataSource{}
+	_ datasource.DataSourceWithConfigure = &vnetsDataSource{}
+)
+
+// vnetsDataSource is the data source implementation for SDN VNets.
+type vnetsDataSource struct {
+	client *vnets.Client
+}
+
+// vnetsDataSourceModel represents the data source model for listing VNets.
+type vnetsDataSourceModel struct {
+	VNets types.List `tfsdk:"vnets"`
+}
+
+// vnetDataModel represents individual VNet data in the list.
+type vnetDataModel struct {
+	ID           types.String `tfsdk:"id"`
+	Zone         types.String `tfsdk:"zone"`
+	Alias        types.String `tfsdk:"alias"`
+	IsolatePorts types.Bool   `tfsdk:"isolate_ports"`
+	Tag          types.Int64  `tfsdk:"tag"`
+	VlanAware    types.Bool   `tfsdk:"vlan_aware"`
+}
+
+// Configure adds the provider-configured client to the data source.
+func (d *vnetsDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
+	if req.ProviderData == nil {
+		return
+	}
+
+	cfg, ok := req.ProviderData.(config.DataSource)
+	if !ok {
+		resp.Diagnostics.AddError(
+			"Unexpected DataSource Configure Type",
+			fmt.Sprintf("Expected config.DataSource, got: %T", req.ProviderData),
+		)
+
+		return
+	}
+
+	d.client = &vnets.Client{Client: cfg.Client.Cluster()}
+}
+
+// Metadata returns the data source type name.
+func (d *vnetsDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
+	resp.TypeName = req.ProviderTypeName + "_sdn_vnets"
+}
+
+// Schema defines the schema for the data source.
+func (d *vnetsDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
+	resp.Schema = schema.Schema{
+		Description: "Retrieves information about all SDN VNets in Proxmox.",
+		MarkdownDescription: "Retrieves information about all SDN VNets in Proxmox. " +
+			"This data source lists all virtual networks configured in the Software-Defined Networking setup.",
+		Attributes: map[string]schema.Attribute{
+			"vnets": schema.ListAttribute{
+				Description: "List of SDN VNets.",
+				Computed:    true,
+				ElementType: types.ObjectType{
+					AttrTypes: map[string]attr.Type{
+						"id":            types.StringType,
+						"zone":          types.StringType,
+						"alias":         types.StringType,
+						"isolate_ports": types.BoolType,
+						"tag":           types.Int64Type,
+						"vlan_aware":    types.BoolType,
+					},
+				},
+			},
+		},
+	}
+}
+
+// Read fetches all SDN VNets from the Proxmox VE API.
+func (d *vnetsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
+	var data vnetsDataSourceModel
+	resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
+
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	vnetsList, err := d.client.GetVnetsWithParams(ctx, &sdn.QueryParams{})
+	if err != nil {
+		resp.Diagnostics.AddError(
+			"Unable to Read SDN VNets",
+			err.Error(),
+		)
+
+		return
+	}
+
+	// Convert VNets to list elements
+	vnetElements := make([]attr.Value, len(vnetsList))
+	for i, vnet := range vnetsList {
+		vnetData := vnetDataModel{
+			ID:           types.StringValue(vnet.ID),
+			Zone:         types.StringPointerValue(vnet.Zone),
+			Alias:        types.StringPointerValue(vnet.Alias),
+			IsolatePorts: types.BoolPointerValue(vnet.IsolatePorts.PointerBool()),
+			Tag:          types.Int64PointerValue(vnet.Tag),
+			VlanAware:    types.BoolPointerValue(vnet.VlanAware.PointerBool()),
+		}
+
+		objValue, objDiag := types.ObjectValueFrom(ctx, map[string]attr.Type{
+			"id":            types.StringType,
+			"zone":          types.StringType,
+			"alias":         types.StringType,
+			"isolate_ports": types.BoolType,
+			"tag":           types.Int64Type,
+			"vlan_aware":    types.BoolType,
+		}, vnetData)
+		resp.Diagnostics.Append(objDiag...)
+
+		if resp.Diagnostics.HasError() {
+			return
+		}
+
+		vnetElements[i] = objValue
+	}
+
+	listValue, listDiag := types.ListValue(types.ObjectType{
+		AttrTypes: map[string]attr.Type{
+			"id":            types.StringType,
+			"zone":          types.StringType,
+			"alias":         types.StringType,
+			"isolate_ports": types.BoolType,
+			"tag":           types.Int64Type,
+			"vlan_aware":    types.BoolType,
+		},
+	}, vnetElements)
+	resp.Diagnostics.Append(listDiag...)
+
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	data.VNets = listValue
+	resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+// NewVNetsDataSource returns a new data source for SDN VNets.
+func NewVNetsDataSource() datasource.DataSource {
+	return &vnetsDataSource{}
+}
diff --git a/fwprovider/provider.go b/fwprovider/provider.go
index eb453f06..828f9270 100644
--- a/fwprovider/provider.go
+++ b/fwprovider/provider.go
@@ -573,6 +573,7 @@ func (p *proxmoxProvider) DataSources(_ context.Context) []func() datasource.Dat
 		sdnzone.NewZonesDataSource,
 		sdnsubnet.NewDataSource,
 		sdnvnet.NewDataSource,
+		sdnvnet.NewVNetsDataSource,
 		vm.NewDataSource,
 	}
 }
diff --git a/main.go b/main.go
index 507539cf..ea74f7b8 100644
--- a/main.go
+++ b/main.go
@@ -49,6 +49,7 @@ import (
 //go:generate cp ./build/docs-gen/data-sources/virtual_environment_haresource.md ./docs/data-sources/
 //go:generate cp ./build/docs-gen/data-sources/virtual_environment_haresources.md ./docs/data-sources/
 //go:generate cp ./build/docs-gen/data-sources/virtual_environment_sdn_vnet.md ./docs/data-sources/
+//go:generate cp ./build/docs-gen/data-sources/virtual_environment_sdn_vnets.md ./docs/data-sources/
 //go:generate cp ./build/docs-gen/data-sources/virtual_environment_sdn_zones.md ./docs/data-sources/
 //go:generate cp ./build/docs-gen/data-sources/virtual_environment_sdn_zone_simple.md ./docs/data-sources/
 //go:generate cp ./build/docs-gen/data-sources/virtual_environment_sdn_subnet.md ./docs/data-sources/
diff --git a/proxmox/cluster/sdn/vnets/vnets_types.go b/proxmox/cluster/sdn/vnets/vnets_types.go
index 3fc58e37..84c668ef 100644
--- a/proxmox/cluster/sdn/vnets/vnets_types.go
+++ b/proxmox/cluster/sdn/vnets/vnets_types.go
@@ -28,7 +28,8 @@ type VNet struct {
 type VNetData struct {
 	VNet
 
-	Pending *VNet `json:"pending,omitempty" url:"pending,omitempty"`
+	ID      string `json:"vnet"              url:"vnet"`
+	Pending *VNet  `json:"pending,omitempty" url:"pending,omitempty"`
 }
 
 type VNetCreate struct {
diff --git a/proxmox/nodes/containers/containers.go b/proxmox/nodes/containers/containers.go
index d274be6d..ce846711 100644
--- a/proxmox/nodes/containers/containers.go
+++ b/proxmox/nodes/containers/containers.go
@@ -19,16 +19,39 @@ import (
 	"github.com/bpg/terraform-provider-proxmox/proxmox/api"
 )
 
+var errContainerAlreadyRunning = errors.New("container is already running")
+
 // CloneContainer clones a container.
 func (c *Client) CloneContainer(ctx context.Context, d *CloneRequestBody) error {
-	err := c.DoRequest(ctx, http.MethodPost, c.ExpandPath("/clone"), d, nil)
+	taskID, err := c.CloneContainerAsync(ctx, d)
 	if err != nil {
-		return fmt.Errorf("error cloning container: %w", err)
+		return err
+	}
+
+	err = c.Tasks().WaitForTask(ctx, *taskID)
+	if err != nil {
+		return fmt.Errorf("error waiting for container cloned: %w", err)
 	}
 
 	return nil
 }
 
+// CloneContainerAsync clones a container asynchronously.
+func (c *Client) CloneContainerAsync(ctx context.Context, d *CloneRequestBody) (*string, error) {
+	resBody := &CloneResponseBody{}
+
+	err := c.DoRequest(ctx, http.MethodPost, c.ExpandPath("/clone"), d, resBody)
+	if err != nil {
+		return nil, fmt.Errorf("error cloning container: %w", err)
+	}
+
+	if resBody.Data == nil {
+		return nil, api.ErrNoDataObjectInResponse
+	}
+
+	return resBody.Data, nil
+}
+
 // CreateContainer creates a container.
 func (c *Client) CreateContainer(ctx context.Context, d *CreateRequestBody) error {
 	taskID, err := c.CreateContainerAsync(ctx, d)
@@ -192,14 +215,35 @@ func (c *Client) WaitForContainerNetworkInterfaces(
 
 // RebootContainer reboots a container.
 func (c *Client) RebootContainer(ctx context.Context, d *RebootRequestBody) error {
-	err := c.DoRequest(ctx, http.MethodPost, c.ExpandPath("status/reboot"), d, nil)
+	taskID, err := c.RebootContainerAsync(ctx, d)
+	if err != nil {
+		return err
+	}
+
+	err = c.Tasks().WaitForTask(ctx, *taskID)
 	if err != nil {
-		return fmt.Errorf("error rebooting container: %w", err)
+		return fmt.Errorf("error waiting for container reboot: %w", err)
 	}
 
 	return nil
 }
 
+// RebootContainerAsync reboots a container asynchronously.
+func (c *Client) RebootContainerAsync(ctx context.Context, d *RebootRequestBody) (*string, error) {
+	resBody := &RebootResponseBody{}
+
+	err := c.DoRequest(ctx, http.MethodPost, c.ExpandPath("status/reboot"), d, resBody)
+	if err != nil {
+		return nil, fmt.Errorf("error rebooting container: %w", err)
+	}
+
+	if resBody.Data == nil {
+		return nil, api.ErrNoDataObjectInResponse
+	}
+
+	return resBody.Data, nil
+}
+
 // ShutdownContainer shuts down a container.
 func (c *Client) ShutdownContainer(ctx context.Context, d *ShutdownRequestBody) error {
 	taskID, err := c.ShutdownContainerAsync(ctx, d)
@@ -244,6 +288,10 @@ func (c *Client) StartContainer(ctx context.Context) error {
 
 	taskID, err := c.StartContainerAsync(ctx)
 	if err != nil {
+		if errors.Is(err, errContainerAlreadyRunning) {
+			return nil
+		}
+
 		return fmt.Errorf("error starting container: %w", err)
 	}
 
@@ -267,6 +315,10 @@ func (c *Client) StartContainerAsync(ctx context.Context) (*string, error) {
 
 	err := c.DoRequest(ctx, http.MethodPost, c.ExpandPath("status/start"), nil, resBody)
 	if err != nil {
+		if strings.Contains(err.Error(), "already running") {
+			return nil, errContainerAlreadyRunning
+		}
+
 		return nil, fmt.Errorf("error starting container: %w", err)
 	}
 
@@ -289,6 +341,7 @@ func (c *Client) StopContainer(ctx context.Context) error {
 
 // UpdateContainer updates a container.
 func (c *Client) UpdateContainer(ctx context.Context, d *UpdateRequestBody) error {
+	// note: put config does not return a task ID, so we cannot wait for it to complete
 	err := c.DoRequest(ctx, http.MethodPut, c.ExpandPath("config"), d, nil)
 	if err != nil {
 		return fmt.Errorf("error updating container: %w", err)
diff --git a/proxmox/nodes/containers/containers_types.go b/proxmox/nodes/containers/containers_types.go
index 036097b7..68c955d6 100644
--- a/proxmox/nodes/containers/containers_types.go
+++ b/proxmox/nodes/containers/containers_types.go
@@ -165,12 +165,16 @@ type CustomStartupBehavior struct {
 	Up    *int `json:"up,omitempty"    url:"up,omitempty"`
 }
 
-// CreateResponseBody contains the body from a container create response.
-type CreateResponseBody struct {
+type TaskSubmittedResponseBody struct {
 	Data *string `json:"data,omitempty"`
 }
 
-type ShutdownResponseBody = CreateResponseBody
+type (
+	CreateResponseBody   = TaskSubmittedResponseBody
+	CloneResponseBody    = TaskSubmittedResponseBody
+	RebootResponseBody   = TaskSubmittedResponseBody
+	ShutdownResponseBody = TaskSubmittedResponseBody
+)
 
 // GetResponseBody contains the body from a user get response.
 type GetResponseBody struct {
diff --git a/proxmox/types/nodes/apt/repositories/ceph_version_name.go b/proxmox/types/nodes/apt/repositories/ceph_version_name.go
index 68344413..7df4ea03 100644
--- a/proxmox/types/nodes/apt/repositories/ceph_version_name.go
+++ b/proxmox/types/nodes/apt/repositories/ceph_version_name.go
@@ -31,6 +31,9 @@ var (
 	// CephVersionNameReef is the name for the "Reef" Ceph major version.
 	CephVersionNameReef = CephVersionName{"reef"}
 
+	// CephVersionNameSquid is the name for the "Squid" Ceph major version.
+	CephVersionNameSquid = CephVersionName{"squid"}
+
 	// CephVersionNameUnknown is the name for an unknown Ceph major version.
 	CephVersionNameUnknown = CephVersionName{"unknown"}
 )
@@ -99,6 +102,8 @@ func ParseCephVersionName(input string) (CephVersionName, error) {
 		return CephVersionNameQuincy, nil
 	case CephVersionNameReef.String():
 		return CephVersionNameReef, nil
+	case CephVersionNameSquid.String():
+		return CephVersionNameSquid, nil
 	default:
 		return CephVersionName{}, ErrCephVersionNameIllegal(input)
 	}
diff --git a/proxmoxtf/resource/container/container.go b/proxmoxtf/resource/container/container.go
index acb0c790..4babdfed 100644
--- a/proxmoxtf/resource/container/container.go
+++ b/proxmoxtf/resource/container/container.go
@@ -891,6 +891,8 @@ func Container() *schema.Resource {
 				Optional:    true,
 				ForceNew:    true,
 				Default:     dvPoolID,
+				Deprecated: "This field is deprecated and will be removed in a future release. " +
+					"To assign the container to a pool, use `proxmox_virtual_environment_pool_membership` resource instead",
 			},
 			mkProtection: {
 				Type: schema.TypeBool,
@@ -1144,12 +1146,6 @@ func containerCreateClone(ctx context.Context, d *schema.ResourceData, m interfa
 
 	containerAPI := client.Node(nodeName).Container(vmID)
 
-	// Wait for the container to be created and its configuration lock to be released.
-	err = containerAPI.WaitForContainerConfigUnlock(ctx, true)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-
 	// Now that the virtual machine has been cloned, we need to perform some modifications.
 	updateBody := &containers.UpdateRequestBody{}
 
@@ -1959,12 +1955,6 @@ func containerCreateCustom(ctx context.Context, d *schema.ResourceData, m interf
 
 	d.SetId(strconv.Itoa(vmID))
 
-	// Wait for the container's lock to be released.
-	err = client.Node(nodeName).Container(vmID).WaitForContainerConfigUnlock(ctx, true)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-
 	return containerCreateStart(ctx, d, m)
 }
 
@@ -3399,6 +3389,12 @@ func containerUpdate(ctx context.Context, d *schema.ResourceData, m interface{})
 		return diag.FromErr(e)
 	}
 
+	// Wait for the container's lock to be released.
+	e = containerAPI.WaitForContainerConfigUnlock(ctx, true)
+	if e != nil {
+		return diag.FromErr(e)
+	}
+
 	// Determine if the state of the container needs to be changed.
 	started := d.Get(mkStarted).(bool)
 
diff --git a/proxmoxtf/resource/vm/vm.go b/proxmoxtf/resource/vm/vm.go
index 3b4c769c..2beaea6e 100644
--- a/proxmoxtf/resource/vm/vm.go
+++ b/proxmoxtf/resource/vm/vm.go
@@ -1261,6 +1261,8 @@ func VM() *schema.Resource {
 			Description: "The ID of the pool to assign the virtual machine to",
 			Optional:    true,
 			Default:     dvPoolID,
+			Deprecated: "This field is deprecated and will be removed in a future release. " +
+				"To assign the VM to a pool, use `proxmox_virtual_environment_pool_membership` resource instead.",
 		},
 		mkProtection: {
 			Type:        schema.TypeBool,



Test patch:
diff --git a/fwprovider/cluster/sdn/vnet/datasource_vnets_test.go b/fwprovider/cluster/sdn/vnet/datasource_vnets_test.go
new file mode 100644
index 00000000..6b676bd7
--- /dev/null
+++ b/fwprovider/cluster/sdn/vnet/datasource_vnets_test.go
@@ -0,0 +1,249 @@
+//go:build acceptance || all
+
+/*
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
+ */
+
+package vnet_test
+
+import (
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+
+	"github.com/bpg/terraform-provider-proxmox/fwprovider/test"
+)
+
+func TestAccDataSourceSDNVNets(t *testing.T) {
+	t.Parallel()
+
+	te := test.InitEnvironment(t)
+
+	tests := []struct {
+		name  string
+		steps []resource.TestStep
+	}{
+		{"create multiple VNets with all attributes and read with vnets datasource", []resource.TestStep{{
+			Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_sdn_zone_simple" "test" {
+					id    = "vnetstst"
+					nodes = ["{{.NodeName}}"]
+				}
+
+				resource "proxmox_virtual_environment_sdn_vnet" "test1" {
+					id            = "dsvnet1"
+					zone          = proxmox_virtual_environment_sdn_zone_simple.test.id
+					alias         = "Test VNet 1"
+					isolate_ports = true
+					vlan_aware    = false
+				}
+
+				resource "proxmox_virtual_environment_sdn_vnet" "test2" {
+					id            = "dsvnet2"
+					zone          = proxmox_virtual_environment_sdn_zone_simple.test.id
+					alias         = "Test VNet 2"
+					isolate_ports = false
+					vlan_aware    = true
+				}
+
+				resource "proxmox_virtual_environment_sdn_applier" "test_applier" {
+					depends_on = [
+						proxmox_virtual_environment_sdn_vnet.test1,
+						proxmox_virtual_environment_sdn_vnet.test2
+					]
+				}
+
+				data "proxmox_virtual_environment_sdn_vnets" "all" {
+					depends_on = [
+						proxmox_virtual_environment_sdn_applier.test_applier
+					]
+				}
+			`),
+			Check: resource.ComposeTestCheckFunc(
+				// Check that the vnets datasource returns multiple vnets
+				resource.TestCheckResourceAttrSet("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.#"),
+				// Verify that vnets contain expected attributes
+				resource.TestCheckTypeSetElemNestedAttrs("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.*", map[string]string{
+					"id":            "dsvnet1",
+					"zone":          "vnetstst",
+					"alias":         "Test VNet 1",
+					"isolate_ports": "true",
+					"vlan_aware":    "false",
+				}),
+				resource.TestCheckTypeSetElemNestedAttrs("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.*", map[string]string{
+					"id":            "dsvnet2",
+					"zone":          "vnetstst",
+					"alias":         "Test VNet 2",
+					"isolate_ports": "false",
+					"vlan_aware":    "true",
+				}),
+			),
+		}}},
+		{"create VNets with VLAN zone and tags", []resource.TestStep{{
+			Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_sdn_zone_vlan" "test_vlan" {
+					id     = "vnetvlan"
+					nodes  = ["{{.NodeName}}"]
+					bridge = "vmbr0"
+				}
+
+				resource "proxmox_virtual_environment_sdn_vnet" "vlan1" {
+					id         = "vlan1"
+					zone       = proxmox_virtual_environment_sdn_zone_vlan.test_vlan.id
+					alias      = "VLAN VNet 1"
+					tag        = 100
+					vlan_aware = true
+				}
+
+				resource "proxmox_virtual_environment_sdn_vnet" "vlan2" {
+					id         = "vlan2"
+					zone       = proxmox_virtual_environment_sdn_zone_vlan.test_vlan.id
+					alias      = "VLAN VNet 2"
+					tag        = 200
+					vlan_aware = false
+				}
+
+				resource "proxmox_virtual_environment_sdn_applier" "test_applier" {
+					depends_on = [
+						proxmox_virtual_environment_sdn_vnet.vlan1,
+						proxmox_virtual_environment_sdn_vnet.vlan2
+					]
+				}
+
+				data "proxmox_virtual_environment_sdn_vnets" "all" {
+					depends_on = [
+						proxmox_virtual_environment_sdn_applier.test_applier
+					]
+				}
+			`),
+			Check: resource.ComposeTestCheckFunc(
+				resource.TestCheckResourceAttrSet("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.#"),
+				resource.TestCheckTypeSetElemNestedAttrs("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.*", map[string]string{
+					"id":         "vlan1",
+					"zone":       "vnetvlan",
+					"alias":      "VLAN VNet 1",
+					"tag":        "100",
+					"vlan_aware": "true",
+				}),
+				resource.TestCheckTypeSetElemNestedAttrs("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.*", map[string]string{
+					"id":         "vlan2",
+					"zone":       "vnetvlan",
+					"alias":      "VLAN VNet 2",
+					"tag":        "200",
+					"vlan_aware": "false",
+				}),
+			),
+		}}},
+		{"create VNets with minimal attributes", []resource.TestStep{{
+			Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_sdn_zone_simple" "test_minimal" {
+					id    = "vnetmin"
+					nodes = ["{{.NodeName}}"]
+				}
+
+				resource "proxmox_virtual_environment_sdn_vnet" "minimal1" {
+					id   = "minvnet1"
+					zone = proxmox_virtual_environment_sdn_zone_simple.test_minimal.id
+				}
+
+				resource "proxmox_virtual_environment_sdn_vnet" "minimal2" {
+					id   = "minvnet2"
+					zone = proxmox_virtual_environment_sdn_zone_simple.test_minimal.id
+				}
+
+				resource "proxmox_virtual_environment_sdn_applier" "test_applier" {
+					depends_on = [
+						proxmox_virtual_environment_sdn_vnet.minimal1,
+						proxmox_virtual_environment_sdn_vnet.minimal2
+					]
+				}
+
+				data "proxmox_virtual_environment_sdn_vnets" "all" {
+					depends_on = [
+						proxmox_virtual_environment_sdn_applier.test_applier
+					]
+				}
+			`),
+			Check: resource.ComposeTestCheckFunc(
+				resource.TestCheckResourceAttrSet("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.#"),
+				resource.TestCheckTypeSetElemNestedAttrs("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.*", map[string]string{
+					"id":   "minvnet1",
+					"zone": "vnetmin",
+				}),
+				resource.TestCheckTypeSetElemNestedAttrs("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.*", map[string]string{
+					"id":   "minvnet2",
+					"zone": "vnetmin",
+				}),
+			),
+		}}},
+		{"read vnets datasource with mixed zone types", []resource.TestStep{{
+			Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_sdn_zone_simple" "simple" {
+					id    = "mixsimpl"
+					nodes = ["{{.NodeName}}"]
+				}
+
+				resource "proxmox_virtual_environment_sdn_zone_vlan" "vlan" {
+					id     = "mixvlan"
+					nodes  = ["{{.NodeName}}"]
+					bridge = "vmbr0"
+				}
+
+				resource "proxmox_virtual_environment_sdn_vnet" "simple_vnet" {
+					id         = "mixvnet1"
+					zone       = proxmox_virtual_environment_sdn_zone_simple.simple.id
+					alias      = "Simple Zone VNet"
+					vlan_aware = false
+				}
+
+				resource "proxmox_virtual_environment_sdn_vnet" "vlan_vnet" {
+					id         = "mixvnet2"
+					zone       = proxmox_virtual_environment_sdn_zone_vlan.vlan.id
+					alias      = "VLAN Zone VNet"
+					tag        = 300
+					vlan_aware = true
+				}
+
+				resource "proxmox_virtual_environment_sdn_applier" "test_applier" {
+					depends_on = [
+						proxmox_virtual_environment_sdn_vnet.simple_vnet,
+						proxmox_virtual_environment_sdn_vnet.vlan_vnet
+					]
+				}
+
+				data "proxmox_virtual_environment_sdn_vnets" "all" {
+					depends_on = [
+						proxmox_virtual_environment_sdn_applier.test_applier
+					]
+				}
+			`),
+			Check: resource.ComposeTestCheckFunc(
+				resource.TestCheckResourceAttrSet("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.#"),
+				resource.TestCheckTypeSetElemNestedAttrs("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.*", map[string]string{
+					"id":         "mixvnet1",
+					"zone":       "mixsimpl",
+					"alias":      "Simple Zone VNet",
+					"vlan_aware": "false",
+				}),
+				resource.TestCheckTypeSetElemNestedAttrs("data.proxmox_virtual_environment_sdn_vnets.all", "vnets.*", map[string]string{
+					"id":         "mixvnet2",
+					"zone":       "mixvlan",
+					"alias":      "VLAN Zone VNet",
+					"tag":        "300",
+					"vlan_aware": "true",
+				}),
+			),
+		}}},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			resource.ParallelTest(t, resource.TestCase{
+				ProtoV6ProviderFactories: te.AccProviders,
+				Steps:                    tt.steps,
+			})
+		})
+	}
+}
diff --git a/fwprovider/test/resource_container_test.go b/fwprovider/test/resource_container_test.go
index adf7d5dc..cebe8934 100644
--- a/fwprovider/test/resource_container_test.go
+++ b/fwprovider/test/resource_container_test.go
@@ -15,59 +15,46 @@ import (
 	"testing"
 	"time"
 
-	"github.com/brianvoe/gofakeit/v7"
+	"github.com/bpg/terraform-provider-proxmox/proxmox/helpers/ptr"
+	"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/storage"
+
 	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
 	"github.com/hashicorp/terraform-plugin-testing/terraform"
 	"github.com/stretchr/testify/require"
-
-	"github.com/bpg/terraform-provider-proxmox/proxmox/helpers/ptr"
-	"github.com/bpg/terraform-provider-proxmox/proxmox/nodes/storage"
 )
 
 const (
-	accTestContainerName = "proxmox_virtual_environment_container.test_container"
+	accTestContainerName      = "proxmox_virtual_environment_container.test_container"
+	alpineTemplateRelativeURL = "images/system/alpine-3.22-default_20250617_amd64.tar.xz"
 )
 
-func TestAccResourceContainer(t *testing.T) {
-	t.Parallel()
+func getTemplateURL(t *testing.T, templateServerURL string) string {
+	t.Helper()
+	return fmt.Sprintf("%s/%s", templateServerURL, alpineTemplateRelativeURL)
+}
 
+func TestAccResourceContainer(t *testing.T) {
 	te := InitEnvironment(t)
+	imageFileName := fmt.Sprintf("%d-alpine-3.22-default_20250617_amd64.tar.xz", time.Now().UnixMicro())
+	testAccDownloadContainerTemplate(t, te, imageFileName)
 
-	imageFileName := gofakeit.Word() + "-ubuntu-24.04-standard_24.04-2_amd64.tar.zst"
 	accTestContainerID := 100000 + rand.Intn(99999)
-	accTestContainerIDClone := 100000 + rand.Intn(99999)
 
 	te.AddTemplateVars(map[string]interface{}{
-		"ImageFileName":        imageFileName,
-		"TestContainerID":      accTestContainerID,
-		"TestContainerIDClone": accTestContainerIDClone,
-	})
-
-	err := te.NodeStorageClient().DownloadFileByURL(context.Background(), &storage.DownloadURLPostRequestBody{
-		Content:  ptr.Ptr("vztmpl"),
-		FileName: ptr.Ptr(imageFileName),
-		Node:     ptr.Ptr(te.NodeName),
-		Storage:  ptr.Ptr(te.DatastoreID),
-		URL:      ptr.Ptr(fmt.Sprintf("%s/images/system/ubuntu-24.04-standard_24.04-2_amd64.tar.zst", te.ContainerImagesServer)),
+		"ImageFileName":   imageFileName,
+		"TestContainerID": accTestContainerID,
+		"TimeoutDelete":   300,
 	})
-	require.NoError(t, err)
 
-	t.Cleanup(func() {
-		e := te.NodeStorageClient().DeleteDatastoreFile(context.Background(), fmt.Sprintf("vztmpl/%s", imageFileName))
-		require.NoError(t, e)
-	})
-
-	tests := []struct {
-		name string
-		step []resource.TestStep
-	}{
-		{"create, start and update container", []resource.TestStep{
+	resource.ParallelTest(t, resource.TestCase{
+		ProtoV6ProviderFactories: te.AccProviders,
+		Steps: []resource.TestStep{
 			{
 				Config: te.RenderConfig(`
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
 					vm_id     = {{.TestContainerID}}
-					timeout_delete = 10
+					timeout_delete = {{ .TimeoutDelete }}
 					unprivileged = true
 					disk {
 						datastore_id = "local-lvm"
@@ -99,7 +86,7 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 					operating_system {
 						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
+						type             = "alpine"
 					}
 				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -110,20 +97,17 @@ func TestAccResourceContainer(t *testing.T) {
 						"device_passthrough.0.mode": "0660",
 						"initialization.0.dns.#":    "0",
 					}),
+					//nolint:godox
 					// TODO: depends on DHCP, which may not work in some environments
 					// ResourceAttributesSet(accTestContainerName, []string{
 					// 	"ipv4.vmbr0",
 					// }),
 					func(*terraform.State) error {
-						ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-						defer cancel()
-
 						ct := te.NodeClient().Container(accTestContainerID)
-						err := ct.WaitForContainerStatus(ctx, "running")
-						require.NoError(te.t, err, "container did not start")
 
-						ctInfo, err := ct.GetContainer(ctx)
+						ctInfo, err := ct.GetContainer(t.Context())
 						require.NoError(te.t, err, "failed to get container")
+
 						dev0, ok := ctInfo.PassthroughDevices["dev0"]
 						require.True(te.t, ok, `"dev0" passthrough device not found`)
 						require.NotNil(te.t, dev0, `"dev0" passthrough device is <nil>`)
@@ -138,7 +122,7 @@ func TestAccResourceContainer(t *testing.T) {
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
 					vm_id     = {{.TestContainerID}}
-					timeout_delete = 10
+					timeout_delete = {{ .TimeoutDelete }}
 					unprivileged = true
 					disk {
 						datastore_id = "local-lvm"
@@ -172,7 +156,7 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 					operating_system {
 						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
+						type             = "alpine"
 					}
 				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -190,7 +174,7 @@ func TestAccResourceContainer(t *testing.T) {
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
 					vm_id     = {{.TestContainerID}}
-					timeout_delete = 10
+					timeout_delete = {{ .TimeoutDelete }}
 					unprivileged = true
 					disk {
 						datastore_id = "local-lvm"
@@ -224,7 +208,7 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 					operating_system {
 						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
+						type             = "alpine"
 					}
 				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -233,126 +217,32 @@ func TestAccResourceContainer(t *testing.T) {
 					}),
 				),
 			},
-		}},
-		{"update mount points", []resource.TestStep{
-			{
-				Config: te.RenderConfig(`
-				resource "proxmox_virtual_environment_container" "test_container" {
-				    node_name = "{{.NodeName}}"
-				  	started   = false
-				    disk {
-						datastore_id = "local-lvm"
-						size         = 4
-					}
-				    mount_point {
-						volume = "local-lvm"
-						size   = "4G"
-						path   = "mnt/local1"
-				    }
-				    initialization {
-				  		hostname = "test"
-						ip_config {
-						  	ipv4 {
-								address = "dhcp"
-						  	}
-						}
-				    }
-				    network_interface {
-				  	    name = "vmbr0"
-				    }
-				    operating_system {
-						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
-				    }
-				}`),
-				Check: ResourceAttributes("proxmox_virtual_environment_container.test_container", map[string]string{
-					"mount_point.#": "1",
-				}),
-			},
+		},
+	})
+}
+
+func TestAccResourceContainerClone(t *testing.T) {
+	te := InitEnvironment(t)
+	accTestContainerID := 100000 + rand.Intn(99999)
+	accTestContainerIDClone := 100000 + rand.Intn(99999)
+	imageFileName := fmt.Sprintf("%d-alpine-3.22-default_20250617_amd64.tar.xz", time.Now().UnixMicro())
+
+	testAccDownloadContainerTemplate(t, te, imageFileName)
+
+	te.AddTemplateVars(map[string]interface{}{
+		"ImageFileName":        imageFileName,
+		"TestContainerID":      accTestContainerID,
+		"TestContainerIDClone": accTestContainerIDClone,
+	})
+
+	resource.ParallelTest(t, resource.TestCase{
+		ProtoV6ProviderFactories: te.AccProviders,
+		Steps: []resource.TestStep{
 			{
 				Config: te.RenderConfig(`
-				resource "proxmox_virtual_environment_container" "test_container" {
-				    node_name = "{{.NodeName}}"
-				  	started   = false
-				    disk {
-						datastore_id = "local-lvm"
-						size         = 4
-					}
-				    mount_point {
-						volume = "local-lvm"
-						size   = "4G"
-						path   = "mnt/local1"
-				    }
-					// add a new mount point
-				    mount_point {
-						volume = "local-lvm"
-						size   = "4G"
-						path   = "mnt/local2"
-				    }
-				    initialization {
-				  		hostname = "test"
-						ip_config {
-						  	ipv4 {
-								address = "dhcp"
-						  	}
-						}
-				    }
-				    network_interface {
-				  	    name = "vmbr0"
-				    }
-				    operating_system {
-						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
-				    }
-				}`),
-				Check: ResourceAttributes("proxmox_virtual_environment_container.test_container", map[string]string{
-					"mount_point.#": "2",
-				}),
-			},
-		}},
-		{"ipv4 and ipv6", []resource.TestStep{{
-			Config: te.RenderConfig(`
-			resource "proxmox_virtual_environment_container" "test_container" {
-				node_name = "{{.NodeName}}"
-				started   = false
-				disk {
-					datastore_id = "local-lvm"
-					size         = 4
-				}
-				initialization {
-					hostname = "test"
-					ip_config {
-						ipv4 {
-							address = "10.0.0.100/24"
-							gateway = "10.0.0.1"
-						}
-					}
-					ip_config {
-						ipv6 {
-							address = "2001:db8::100/64"	
-							gateway = "2001:db8::1"
-						}
-					}
-				}
-				network_interface {
-					name = "vmbr0"
-					bridge = "vmbr0"
-				}
-				network_interface {
-					name = "vmbr1"
-					bridge = "vmbr1"
-				}
-
-				operating_system {
-					template_file_id = "local:vztmpl/{{.ImageFileName}}"
-					type             = "ubuntu"
-				}
-			}`),
-		}}},
-		{"clone container", []resource.TestStep{{
-			Config: te.RenderConfig(`
 			resource "proxmox_virtual_environment_container" "test_container" {
 				node_name = "{{.NodeName}}"
+				vm_id     = {{.TestContainerID}}
 				template  = true
 				disk {
 					datastore_id = "local-lvm"
@@ -379,7 +269,7 @@ func TestAccResourceContainer(t *testing.T) {
 				}
 				operating_system {
 					template_file_id = "local:vztmpl/{{.ImageFileName}}"
-					type             = "ubuntu"
+					type             = "alpine"
 				}
 			}
 			resource "proxmox_virtual_environment_container" "test_container_clone" {
@@ -398,125 +288,46 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 				}
 			}`, WithRootUser()),
-			Check: resource.ComposeTestCheckFunc(
-				func(*terraform.State) error {
-					ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-					defer cancel()
-
-					ct := te.NodeClient().Container(accTestContainerIDClone)
-					err := ct.WaitForContainerStatus(ctx, "running")
-					require.NoError(te.t, err, "container did not start")
-
-					ctInfo, err := ct.GetContainer(ctx)
-					require.NoError(te.t, err, "failed to get container")
-					dev0, ok := ctInfo.PassthroughDevices["dev0"]
-					require.True(te.t, ok, `"dev0" passthrough device not found`)
-					require.NotNil(te.t, dev0, `"dev0" passthrough device is <nil>`)
-					require.Equal(te.t, "/dev/zero", dev0.Path)
-
-					return nil
-				},
-			),
-		}}},
-		{"hostname update", []resource.TestStep{
-			{
-				Config: te.RenderConfig(`
-				resource "proxmox_virtual_environment_container" "test_container" {
-					node_name = "{{.NodeName}}"
-					vm_id     = {{.TestContainerID}}
-					timeout_delete = 10
-					unprivileged = true
-					disk {
-						datastore_id = "local-lvm"
-						size         = 4
-					}
-					initialization {
-						hostname = "test-hostname-1"
-						ip_config {
-							ipv4 {
-								address = "dhcp"
-							}
-						}
-					}
-					network_interface {
-						name = "vmbr0"
-					}
-					operating_system {
-						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
-					}
-				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
-					ResourceAttributes(accTestContainerName, map[string]string{
-						"initialization.0.hostname": "test-hostname-1",
-					}),
 					func(*terraform.State) error {
-						ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-						defer cancel()
+						ct := te.NodeClient().Container(accTestContainerIDClone)
 
-						ct := te.NodeClient().Container(accTestContainerID)
-						err := ct.WaitForContainerStatus(ctx, "running")
-						require.NoError(te.t, err, "container did not start")
+						ctInfo, err := ct.GetContainer(t.Context())
+						require.NoError(te.t, err, "failed to get container")
+
+						dev0, ok := ctInfo.PassthroughDevices["dev0"]
+						require.True(te.t, ok, `"dev0" passthrough device not found`)
+						require.NotNil(te.t, dev0, `"dev0" passthrough device is <nil>`)
+						require.Equal(te.t, "/dev/zero", dev0.Path)
 
 						return nil
 					},
 				),
 			},
-			{
-				Config: te.RenderConfig(`
-				resource "proxmox_virtual_environment_container" "test_container" {
-					node_name = "{{.NodeName}}"
-					vm_id     = {{.TestContainerID}}
-					timeout_delete = 10
-					unprivileged = true
-					disk {
-						datastore_id = "local-lvm"
-						size         = 4
-					}
-					initialization {
-						hostname = "test-hostname-2"
-						ip_config {
-							ipv4 {
-								address = "dhcp"
-							}
-						}
-					}
-					network_interface {
-						name = "vmbr0"
-					}
-					operating_system {
-						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
-					}
-				}`, WithRootUser()),
-				Check: resource.ComposeTestCheckFunc(
-					ResourceAttributes(accTestContainerName, map[string]string{
-						"initialization.0.hostname": "test-hostname-2",
-					}),
-					func(*terraform.State) error {
-						ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
-						defer cancel()
+		},
+	})
+}
 
-						ct := te.NodeClient().Container(accTestContainerID)
-						err := ct.WaitForContainerStatus(ctx, "running")
-						require.NoError(te.t, err, "container did not start after hostname change")
+func TestAccResourceContainerDnsBlock(t *testing.T) {
+	te := InitEnvironment(t)
+	accTestContainerID := 100000 + rand.Intn(99999)
 
-						// Verify the hostname was actually updated in the container config
-						ctInfo, err := ct.GetContainer(ctx)
-						require.NoError(te.t, err, "failed to get container")
-						require.NotNil(te.t, ctInfo.Hostname, "hostname should not be nil")
-						require.Equal(te.t, "test-hostname-2", *ctInfo.Hostname, "hostname should be updated")
+	imageFileName := fmt.Sprintf("%d-alpine-3.22-default_20250617_amd64.tar.xz", time.Now().UnixMicro())
+	testAccDownloadContainerTemplate(t, te, imageFileName)
 
-						return nil
-					},
-				),
-			},
-		}},
-		{"empty dns block on update", []resource.TestStep{
+	te.AddTemplateVars(map[string]interface{}{
+		"ImageFileName":   imageFileName,
+		"TestContainerID": accTestContainerID,
+	})
+
+	resource.ParallelTest(t, resource.TestCase{
+		ProtoV6ProviderFactories: te.AccProviders,
+		Steps: []resource.TestStep{
 			{
 				Config: te.RenderConfig(`
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
 					unprivileged = true
 					disk {
 						datastore_id = "local-lvm"
@@ -535,7 +346,7 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 					operating_system {
 						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
+						type             = "alpine"
 					}
 				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -549,6 +360,7 @@ func TestAccResourceContainer(t *testing.T) {
 				Config: te.RenderConfig(`
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
 					unprivileged = true
 					disk {
 						datastore_id = "local-lvm"
@@ -568,7 +380,7 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 					operating_system {
 						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
+						type             = "alpine"
 					}
 				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -578,12 +390,11 @@ func TestAccResourceContainer(t *testing.T) {
 					}),
 				),
 			},
-		}},
-		{"empty dns block on create", []resource.TestStep{
 			{
 				Config: te.RenderConfig(`
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
 					unprivileged = true
 					disk {
 						datastore_id = "local-lvm"
@@ -603,7 +414,7 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 					operating_system {
 						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
+						type             = "alpine"
 					}
 				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -613,12 +424,11 @@ func TestAccResourceContainer(t *testing.T) {
 					}),
 				),
 			},
-		}},
-		{"dns block with null values on create", []resource.TestStep{
 			{
 				Config: te.RenderConfig(`
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
 					unprivileged = true
 					disk {
 						datastore_id = "local-lvm"
@@ -642,7 +452,7 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 					operating_system {
 						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
+						type             = "alpine"
 					}
 				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -652,12 +462,11 @@ func TestAccResourceContainer(t *testing.T) {
 					}),
 				),
 			},
-		}},
-		{"dns block with null values on update", []resource.TestStep{
 			{
 				Config: te.RenderConfig(`
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
 					unprivileged = true
 					disk {
 					datastore_id = "local-lvm"
@@ -680,7 +489,7 @@ func TestAccResourceContainer(t *testing.T) {
 				}
 				operating_system {
 					template_file_id = "local:vztmpl/{{.ImageFileName}}"
-					type             = "ubuntu"
+					type             = "alpine"
 				}
 			}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -698,6 +507,7 @@ func TestAccResourceContainer(t *testing.T) {
 				Config: te.RenderConfig(`
 				resource "proxmox_virtual_environment_container" "test_container" {
 					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
 					unprivileged = true
 					disk {
 						datastore_id = "local-lvm"
@@ -720,7 +530,7 @@ func TestAccResourceContainer(t *testing.T) {
 					}
 					operating_system {
 						template_file_id = "local:vztmpl/{{.ImageFileName}}"
-						type             = "ubuntu"
+						type             = "alpine"
 					}
 				}`, WithRootUser()),
 				Check: resource.ComposeTestCheckFunc(
@@ -730,15 +540,302 @@ func TestAccResourceContainer(t *testing.T) {
 					}),
 				),
 			},
-		}},
-	}
-
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			resource.ParallelTest(t, resource.TestCase{
-				ProtoV6ProviderFactories: te.AccProviders,
-				Steps:                    tt.step,
-			})
-		})
-	}
+		},
+	})
+}
+
+func TestAccResourceContainerHostname(t *testing.T) {
+	te := InitEnvironment(t)
+	accTestContainerID := 100000 + rand.Intn(99999)
+	imageFileName := fmt.Sprintf("%d-alpine-3.22-default_20250617_amd64.tar.xz", time.Now().UnixMicro())
+
+	testAccDownloadContainerTemplate(t, te, imageFileName)
+
+	te.AddTemplateVars(map[string]interface{}{
+		"ImageFileName":   imageFileName,
+		"TestContainerID": accTestContainerID,
+	})
+
+	resource.ParallelTest(t, resource.TestCase{
+		ProtoV6ProviderFactories: te.AccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_container" "test_container" {
+					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
+					unprivileged = true
+					disk {
+						datastore_id = "local-lvm"
+						size         = 4
+					}
+					initialization {
+						hostname = "test-hostname-1"
+						ip_config {
+							ipv4 {
+								address = "dhcp"
+							}
+						}
+					}
+					network_interface {
+						name = "vmbr0"
+					}
+					operating_system {
+						template_file_id = "local:vztmpl/{{.ImageFileName}}"
+						type             = "alpine"
+					}
+				}`, WithRootUser()),
+				Check: resource.ComposeTestCheckFunc(
+					ResourceAttributes(accTestContainerName, map[string]string{
+						"initialization.0.hostname": "test-hostname-1",
+					}),
+				),
+			},
+			{
+				Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_container" "test_container" {
+					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
+					unprivileged = true
+					disk {
+						datastore_id = "local-lvm"
+						size         = 4
+					}
+					initialization {
+						hostname = "test-hostname-2"
+						ip_config {
+							ipv4 {
+								address = "dhcp"
+							}
+						}
+					}
+					network_interface {
+						name = "vmbr0"
+					}
+					operating_system {
+						template_file_id = "local:vztmpl/{{.ImageFileName}}"
+						type             = "alpine"
+					}
+				}`, WithRootUser()),
+				Check: resource.ComposeTestCheckFunc(
+					ResourceAttributes(accTestContainerName, map[string]string{
+						"initialization.0.hostname": "test-hostname-2",
+					}),
+					func(*terraform.State) error {
+						ct := te.NodeClient().Container(accTestContainerID)
+						// Verify the hostname was actually updated in the container config
+						ctInfo, err := ct.GetContainer(t.Context())
+						require.NoError(te.t, err, "failed to get container")
+						require.NotNil(te.t, ctInfo.Hostname, "hostname should not be nil")
+						require.Equal(te.t, "test-hostname-2", *ctInfo.Hostname, "hostname should be updated")
+
+						return nil
+					},
+				),
+			},
+		},
+	})
+}
+
+func TestAccResourceContainerMountPoint(t *testing.T) {
+	te := InitEnvironment(t)
+	accTestContainerID := 100000 + rand.Intn(99999)
+	imageFileName := fmt.Sprintf("%d-alpine-3.22-default_20250617_amd64.tar.xz", time.Now().UnixMicro())
+
+	testAccDownloadContainerTemplate(t, te, imageFileName)
+
+	te.AddTemplateVars(map[string]interface{}{
+		"ImageFileName":   imageFileName,
+		"TestContainerID": accTestContainerID,
+	})
+
+	resource.ParallelTest(t, resource.TestCase{
+		ProtoV6ProviderFactories: te.AccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_container" "test_container" {
+				    node_name = "{{.NodeName}}"
+					vm_id = {{ .TestContainerID }}
+				  	started   = false
+				    disk {
+						datastore_id = "local-lvm"
+						size         = 4
+					}
+				    mount_point {
+						volume = "local-lvm"
+						size   = "4G"
+						path   = "mnt/local1"
+				    }
+				    initialization {
+				  		hostname = "test"
+						ip_config {
+						  	ipv4 {
+								address = "dhcp"
+						  	}
+						}
+				    }
+				    network_interface {
+				  	    name = "vmbr0"
+				    }
+				    operating_system {
+						template_file_id = "local:vztmpl/{{.ImageFileName}}"
+						type             = "alpine"
+				    }
+				}`),
+				Check: ResourceAttributes("proxmox_virtual_environment_container.test_container", map[string]string{
+					"mount_point.#": "1",
+				}),
+			},
+			{
+				Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_container" "test_container" {
+				    node_name = "{{.NodeName}}"
+					vm_id = {{ .TestContainerID }}
+				  	started   = false
+				    disk {
+						datastore_id = "local-lvm"
+						size         = 4
+					}
+				    mount_point {
+						volume = "local-lvm"
+						size   = "4G"
+						path   = "mnt/local1"
+				    }
+					// add a new mount point
+				    mount_point {
+						volume = "local-lvm"
+						size   = "4G"
+						path   = "mnt/local2"
+				    }
+				    initialization {
+				  		hostname = "test"
+						ip_config {
+						  	ipv4 {
+								address = "dhcp"
+						  	}
+						}
+				    }
+				    network_interface {
+				  	    name = "vmbr0"
+				    }
+				    operating_system {
+						template_file_id = "local:vztmpl/{{.ImageFileName}}"
+						type             = "alpine"
+				    }
+				}`),
+				Check: ResourceAttributes("proxmox_virtual_environment_container.test_container", map[string]string{
+					"mount_point.#": "2",
+				}),
+			},
+		},
+	})
+}
+
+func TestAccResourceContainerIpv4Ipv6(t *testing.T) {
+	te := InitEnvironment(t)
+	accTestContainerID := 100000 + rand.Intn(99999)
+	imageFileName := fmt.Sprintf("%d-alpine-3.22-default_20250617_amd64.tar.xz", time.Now().UnixMicro())
+
+	testAccDownloadContainerTemplate(t, te, imageFileName)
+
+	te.AddTemplateVars(map[string]interface{}{
+		"ImageFileName":   imageFileName,
+		"TestContainerID": accTestContainerID,
+	})
+
+	resource.ParallelTest(t, resource.TestCase{
+		ProtoV6ProviderFactories: te.AccProviders,
+		Steps: []resource.TestStep{
+			{
+				Config: te.RenderConfig(`
+				resource "proxmox_virtual_environment_network_linux_bridge" "vmbr1" {
+					node_name = "{{ .NodeName }}"
+					name = "vmbr1"
+				}
+				
+				resource "proxmox_virtual_environment_container" "test_container" {
+					node_name = "{{.NodeName}}"
+					vm_id     = {{.TestContainerID}}
+					unprivileged = true
+					started   = false
+					disk {
+						datastore_id = "local-lvm"
+						size         = 4
+					}
+					initialization {
+						hostname = "test-hostname-1"
+						ip_config {
+							ipv4 {
+								address = "dhcp"
+							}
+						}
+					}
+					network_interface {
+						name = "vmbr0"
+					}
+					operating_system {
+						template_file_id = "local:vztmpl/{{.ImageFileName}}"
+						type             = "alpine"
+					}
+				}
+				`),
+			},
+			{
+				Config: te.RenderConfig(`
+			resource "proxmox_virtual_environment_network_linux_bridge" "vmbr1" {
+				node_name = "{{ .NodeName }}"
+				name = "vmbr1"
+			}
+			resource "proxmox_virtual_environment_container" "test_container" {
+				node_name = "{{.NodeName}}"
+				vm_id     = {{.TestContainerID}}
+				unprivileged = true
+				started   = false
+				disk {
+					datastore_id = "local-lvm"
+					size         = 4
+				}
+				initialization {
+					hostname = "test-hostname-1"
+					ip_config {
+						ipv4 {
+							address = "dhcp"
+						}
+					}
+				}
+				network_interface {
+					name = "vmbr0"
+					bridge = "vmbr0"
+				}
+				network_interface {
+					name = "vmbr1"
+					bridge = "vmbr1"
+				}
+
+				operating_system {
+					template_file_id = "local:vztmpl/{{.ImageFileName}}"
+					type             = "alpine"
+				}
+			}`),
+			},
+		},
+	})
+}
+
+func testAccDownloadContainerTemplate(t *testing.T, te *Environment, imageFileName string) {
+	t.Helper()
+	err := te.NodeStorageClient().DownloadFileByURL(context.Background(), &storage.DownloadURLPostRequestBody{
+		Content:  ptr.Ptr("vztmpl"),
+		FileName: ptr.Ptr(imageFileName),
+		Node:     ptr.Ptr(te.NodeName),
+		Storage:  ptr.Ptr(te.DatastoreID),
+		URL:      ptr.Ptr(getTemplateURL(t, te.ContainerImagesServer)),
+	})
+	require.NoError(t, err)
+
+	t.Cleanup(func() {
+		e := te.NodeStorageClient().DeleteDatastoreFile(context.Background(), fmt.Sprintf("vztmpl/%s", imageFileName))
+		require.NoError(t, e)
+	})
 }
diff --git a/fwprovider/test/resource_vm_disks_test.go b/fwprovider/test/resource_vm_disks_test.go
index 59e2d8de..e22be646 100644
--- a/fwprovider/test/resource_vm_disks_test.go
+++ b/fwprovider/test/resource_vm_disks_test.go
@@ -110,7 +110,7 @@ func TestAccResourceVMDisks(t *testing.T) {
 					content_type = "iso"
 					datastore_id = "local"
 					node_name    = "{{.NodeName}}"
-					url          = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img"
+					url          = "{{.CloudImagesServer}}/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img"
 					overwrite_unmanaged = true
 				}
 				resource "proxmox_virtual_environment_vm" "test_disk" {
@@ -148,7 +148,7 @@ func TestAccResourceVMDisks(t *testing.T) {
 					content_type = "import"
 					datastore_id = "local"
 					node_name    = "{{.NodeName}}"
-					url          = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img"
+					url          = "{{.CloudImagesServer}}/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img"
 					file_name    = "test-disk-image.img.raw"
 					overwrite_unmanaged = true
 				}
@@ -1113,7 +1113,7 @@ func TestAccResourceVMDisks(t *testing.T) {
 					content_type = "import"
 					datastore_id = "local"
 					node_name    = "{{.NodeName}}"
-					url          = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img"
+					url          = "{{.CloudImagesServer}}/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img"
 					file_name    = "test-bootdisk-bug-image.img.raw"
 					overwrite_unmanaged = true
 				}
@@ -1148,7 +1148,7 @@ func TestAccResourceVMDisks(t *testing.T) {
 					content_type = "import"
 					datastore_id = "local"
 					node_name    = "{{.NodeName}}"
-					url          = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img"
+					url          = "{{.CloudImagesServer}}/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img"
 					file_name    = "test-bootdisk-bug-image.img.raw"
 					overwrite_unmanaged = true
 				}
@@ -1188,7 +1188,7 @@ func TestAccResourceVMDisks(t *testing.T) {
 					content_type = "import"
 					datastore_id = "local"
 					node_name    = "{{.NodeName}}"
-					url          = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img"
+					url          = "{{.CloudImagesServer}}/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img"
 					file_name    = "test-boot-resize-image.img.raw"
 					overwrite_unmanaged = true
 				}
@@ -1216,7 +1216,7 @@ func TestAccResourceVMDisks(t *testing.T) {
 					content_type = "import"
 					datastore_id = "local"
 					node_name    = "{{.NodeName}}"
-					url          = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img"
+					url          = "{{.CloudImagesServer}}/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img"
 					file_name    = "test-boot-resize-image.img.raw"
 					overwrite_unmanaged = true
 				}
diff --git a/fwprovider/test/resource_vm_test.go b/fwprovider/test/resource_vm_test.go
index 210bda4b..9012fe50 100644
--- a/fwprovider/test/resource_vm_test.go
+++ b/fwprovider/test/resource_vm_test.go
@@ -526,7 +526,7 @@ func TestAccResourceVMInitialization(t *testing.T) {
 					content_type = "iso"
 					datastore_id = "local"
 					node_name = "{{.NodeName}}"
-					url = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img"
+					url = "{{.CloudImagesServer}}/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img"
 					overwrite_unmanaged = true
 				}`),
 		}}},
@@ -691,7 +691,7 @@ func TestAccResourceVMNetwork(t *testing.T) {
 					content_type = "iso"
 					datastore_id = "local"
 					node_name    = "{{.NodeName}}"
-					url = "{{.CloudImagesServer}}/jammy/current/jammy-server-cloudimg-amd64.img"
+					url = "{{.CloudImagesServer}}/minimal/releases/noble/release/ubuntu-24.04-minimal-cloudimg-amd64.img"
 					overwrite_unmanaged = true
 				}`),
 			Check: resource.ComposeTestCheckFunc(
diff --git a/fwprovider/types/nodes/apt/standard_repo_handle_test.go b/fwprovider/types/nodes/apt/standard_repo_handle_test.go
index d99ac347..39692724 100644
--- a/fwprovider/types/nodes/apt/standard_repo_handle_test.go
+++ b/fwprovider/types/nodes/apt/standard_repo_handle_test.go
@@ -44,7 +44,7 @@ func TestStandardRepoHandleValueFromTerraform(t *testing.T) {
 					val.ValueString() == "ceph-foo-enterprise"
 			},
 		},
-		"valid Ceph APT standard repository handle": {
+		`valid Ceph "enterprise" APT standard repository handle`: {
 			val: tftypes.NewValue(tftypes.String, "ceph-quincy-enterprise"),
 			expected: func(val StandardRepoHandleValue) bool {
 				return val.kind == apitypes.StandardRepoHandleKindEnterprise &&
@@ -55,15 +55,26 @@ func TestStandardRepoHandleValueFromTerraform(t *testing.T) {
 					val.ValueString() == "ceph-quincy-enterprise"
 			},
 		},
+		`valid Ceph "no subscription" APT standard repository handle`: {
+			val: tftypes.NewValue(tftypes.String, "ceph-reef-no-subscription"),
+			expected: func(val StandardRepoHandleValue) bool {
+				return val.kind == apitypes.StandardRepoHandleKindNoSubscription &&
+					val.CephVersionName() == apitypes.CephVersionNameReef &&
+					val.IsCephHandle() &&
+					val.IsSupportedFilePath(apitypes.StandardRepoFilePathCeph) &&
+					val.ComponentName() == "no-subscription" &&
+					val.ValueString() == "ceph-reef-no-subscription"
+			},
+		},
 		`valid Ceph "test" APT standard repository handle`: {
-			val: tftypes.NewValue(tftypes.String, "ceph-reef-test"),
+			val: tftypes.NewValue(tftypes.String, "ceph-squid-test"),
 			expected: func(val StandardRepoHandleValue) bool {
 				return val.kind == apitypes.StandardRepoHandleKindTest &&
-					val.CephVersionName() == apitypes.CephVersionNameReef &&
+					val.CephVersionName() == apitypes.CephVersionNameSquid &&
 					val.IsCephHandle() &&
 					val.IsSupportedFilePath(apitypes.StandardRepoFilePathCeph) &&
 					val.ComponentName() == "test" &&
-					val.ValueString() == "ceph-reef-test"
+					val.ValueString() == "ceph-squid-test"
 			},
 		},
 		"invalid APT repository handle": {
diff --git a/proxmox/types/nodes/apt/repositories/ceph_version_name_test.go b/proxmox/types/nodes/apt/repositories/ceph_version_name_test.go
new file mode 100644
index 00000000..68f6cf1b
--- /dev/null
+++ b/proxmox/types/nodes/apt/repositories/ceph_version_name_test.go
@@ -0,0 +1,182 @@
+/*
+	This Source Code Form is subject to the terms of the Mozilla Public
+	License, v. 2.0. If a copy of the MPL was not distributed with this
+	file, You can obtain one at https://mozilla.org/MPL/2.0/.
+*/
+
+package repositories
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestParseCephVersionName(t *testing.T) {
+	t.Parallel()
+
+	tests := map[string]struct {
+		input       string
+		expected    CephVersionName
+		expectError bool
+	}{
+		"quincy": {
+			input:    "quincy",
+			expected: CephVersionNameQuincy,
+		},
+		"reef": {
+			input:    "reef",
+			expected: CephVersionNameReef,
+		},
+		"squid": {
+			input:    "squid",
+			expected: CephVersionNameSquid,
+		},
+		"invalid": {
+			input:       "invalid",
+			expectError: true,
+		},
+		"empty": {
+			input:       "",
+			expectError: true,
+		},
+		"uppercase": {
+			input:       "QUINCY",
+			expectError: true,
+		},
+	}
+
+	for name, test := range tests {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			result, err := ParseCephVersionName(test.input)
+
+			if test.expectError {
+				require.Error(t, err)
+			} else {
+				require.NoError(t, err)
+				require.Equal(t, test.expected, result)
+			}
+		})
+	}
+}
+
+func TestCephVersionNameString(t *testing.T) {
+	t.Parallel()
+
+	tests := map[string]struct {
+		version  CephVersionName
+		expected string
+	}{
+		"quincy": {
+			version:  CephVersionNameQuincy,
+			expected: "quincy",
+		},
+		"reef": {
+			version:  CephVersionNameReef,
+			expected: "reef",
+		},
+		"squid": {
+			version:  CephVersionNameSquid,
+			expected: "squid",
+		},
+		"unknown": {
+			version:  CephVersionNameUnknown,
+			expected: "unknown",
+		},
+	}
+
+	for name, test := range tests {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			result := test.version.String()
+			require.Equal(t, test.expected, result)
+		})
+	}
+}
+
+func TestCephVersionNameMarshalJSON(t *testing.T) {
+	t.Parallel()
+
+	tests := map[string]struct {
+		version  CephVersionName
+		expected string
+	}{
+		"quincy": {
+			version:  CephVersionNameQuincy,
+			expected: `"quincy"`,
+		},
+		"reef": {
+			version:  CephVersionNameReef,
+			expected: `"reef"`,
+		},
+		"squid": {
+			version:  CephVersionNameSquid,
+			expected: `"squid"`,
+		},
+		"unknown": {
+			version:  CephVersionNameUnknown,
+			expected: `"unknown"`,
+		},
+	}
+
+	for name, test := range tests {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			result, err := json.Marshal(test.version)
+			require.NoError(t, err)
+			require.Equal(t, test.expected, string(result))
+		})
+	}
+}
+
+func TestCephVersionNameUnmarshalJSON(t *testing.T) {
+	t.Parallel()
+
+	tests := map[string]struct {
+		input       string
+		expected    CephVersionName
+		expectError bool
+	}{
+		"quincy": {
+			input:    `"quincy"`,
+			expected: CephVersionNameQuincy,
+		},
+		"reef": {
+			input:    `"reef"`,
+			expected: CephVersionNameReef,
+		},
+		"squid": {
+			input:    `"squid"`,
+			expected: CephVersionNameSquid,
+		},
+		"invalid": {
+			input:       `"invalid"`,
+			expectError: true,
+		},
+		"malformed json": {
+			input:       `quincy`,
+			expectError: true,
+		},
+	}
+
+	for name, test := range tests {
+		t.Run(name, func(t *testing.T) {
+			t.Parallel()
+
+			var result CephVersionName
+			err := json.Unmarshal([]byte(test.input), &result)
+
+			if test.expectError {
+				require.Error(t, err)
+			} else {
+				require.NoError(t, err)
+				require.Equal(t, test.expected, result)
+			}
+		})
+	}
+}