diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml
index 3db9705a..e644517a 100644
--- a/.github/workflows/linters.yml
+++ b/.github/workflows/linters.yml
@@ -17,9 +17,9 @@ jobs:
       - name: Check out code
         uses: actions/checkout@v4
       - name: golangci-lint
-        uses: golangci/golangci-lint-action@v5
+        uses: golangci/golangci-lint-action@v6
         with:
-          version: 'v1.57.1'
+          version: v1.59.1
           args: -c .golangci.yml -v
 
   markdown-lint:
diff --git a/.golangci.yml b/.golangci.yml
index 08d126ad..73509739 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,44 +1,39 @@
 run:
   timeout: 5m
+
 linters:
   enable-all: true
   disable:
-    - maligned # deprecated 1.38
-    - interfacer # deprecated 1.38
-    - scopelint # deprecated 1.39
-    - golint # deprecated 1.41
-    - exhaustivestruct # deprecated 1.46
-    - ifshort # deprecated 1.48
-    - deadcode # deprecated 1.49
-    - structcheck # deprecated 1.49
-    - varcheck # deprecated 1.49
-    - funlen
+    # deprecated
+    - execinquery # deprecated 1.58.0
+    - gomnd # deprecated 1.58.0
+    # unwanted
+    - cyclop
+    - depguard
     - dupl
-    - wsl
-    - gomnd
-    - goerr113 
-    - nestif
+    - err113
     - exhaustruct
-    - paralleltest
-    - cyclop
     - forcetypeassert
+    - funlen
     - gomoddirectives
-    - varnamelen
-    - nonamedreturns
-    - maintidx
-    - execinquery
-    - nosnakecase
-    - musttag
-    - depguard
     - gosec
     - inamedparam
     - ireturn
+    - maintidx
+    - mnd
+    - musttag
+    - nestif
+    - nonamedreturns
+    - paralleltest
+    - varnamelen
+    - wsl
+
 linters-settings:
   gci:
     custom-order: true
     sections:
       - standard
-      - prefix(github.com/jeremmfr/terraform-provider-junos/)
+      - localModule
       - default
   gocognit:
     # minimal code complexity to report, 30 by default
@@ -52,8 +47,6 @@ linters-settings:
     # minimal code complexity to report, 30 by default
     min-complexity: 100
   gofumpt:
-    module-path: github.com/jeremmfr/terraform-provider-junos
-    # Choose whether to use the extra rules.
     extra-rules: true
   govet:
     enable-all: true
@@ -91,6 +84,7 @@ linters-settings:
       - name: import-alias-naming
       - name: import-shadowing
       - name: unhandled-error
+
 issues:
   exclude-rules:
     - text: "github.com/jeremmfr/terraform-provider-junos/internal"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 22a38b9c..92f82e5b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,43 @@
 <!-- markdownlint-disable-file MD013 MD041 -->
 # changelog
 
+## v2.8.0 (2024-06-27)
+
+ENHANCEMENTS:
+
+* **resource/junos_bridge_domain**:  add `static_remote_vtep_list` argument inside `vxlan` block argument (Fix [#672](https://github.com/jeremmfr/terraform-provider-junos/issues/672))
+* **resource/junos_interface_logical**: add `encapsulation` argument (Fix [#674](https://github.com/jeremmfr/terraform-provider-junos/issues/674))
+* **data-source/junos_interface_logical**: add `encapsulation` attribute like resource
+* **resource/junos_routing_instance**:  add `remote_vtep_list` and `remote_vtep_v6_list` arguments (Fix [#673](https://github.com/jeremmfr/terraform-provider-junos/issues/673))
+* **data-source/junos_routing_instance**: add `remote_vtep_list` and `remote_vtep_v6_list` attributes like resource
+* **resource/junos_rstp**: resource now use new [terraform-plugin-framework](https://github.com/hashicorp/terraform-plugin-framework)  
+  some of config errors are now sent during Plan instead of during Apply  
+  optional boolean attributes doesn't accept value *false*
+* **resource/junos_rstp_interface**: resource now use new [terraform-plugin-framework](https://github.com/hashicorp/terraform-plugin-framework)  
+  some of config errors are now sent during Plan instead of during Apply  
+  optional boolean attributes doesn't accept value *false*
+* **resource/junos_security_log_stream**:
+  * resource now use new [terraform-plugin-framework](https://github.com/hashicorp/terraform-plugin-framework)  
+  some of config errors are now sent during Plan instead of during Apply  
+  optional boolean attributes doesn't accept value *false*  
+  optional string attributes doesn't accept *empty* value  
+  the resource schema has been upgraded to have one-blocks in single mode instead of list
+  * add `transport` block argument (Fix [#675](https://github.com/jeremmfr/terraform-provider-junos/issues/675))
+* **resource/junos_switch_options**:  add `remote_vtep_list` and `remote_vtep_v6_list` arguments
+* **resource/junos_vlan**:  add `static_remote_vtep_list` argument inside `vxlan` block argument
+* **resource/junos_vstp**: resource now use new [terraform-plugin-framework](https://github.com/hashicorp/terraform-plugin-framework)  
+  some of config errors are now sent during Plan instead of during Apply  
+  optional boolean attributes doesn't accept value *false*
+* **resource/junos_vstp_interface**: resource now use new [terraform-plugin-framework](https://github.com/hashicorp/terraform-plugin-framework)  
+  some of config errors are now sent during Plan instead of during Apply  
+  optional boolean attributes doesn't accept value *false*
+* **resource/junos_vstp_vlan**: resource now use new [terraform-plugin-framework](https://github.com/hashicorp/terraform-plugin-framework)  
+  some of config errors are now sent during Plan instead of during Apply  
+  optional boolean attributes doesn't accept value *false*
+* **resource/junos_vstp_vlan_group**: resource now use new [terraform-plugin-framework](https://github.com/hashicorp/terraform-plugin-framework)  
+  some of config errors are now sent during Plan instead of during Apply  
+  optional boolean attributes doesn't accept value *false*
+
 ## v2.7.0 (2024-05-03)
 
 FEATURES:
diff --git a/docs/data-sources/interface_logical.md b/docs/data-sources/interface_logical.md
index d3e0c478..457556f2 100644
--- a/docs/data-sources/interface_logical.md
+++ b/docs/data-sources/interface_logical.md
@@ -44,6 +44,8 @@ The following attributes are exported:
   Description for interface.
 - **disable** (Boolean)  
   Interface disabled.
+- **encapsulation** (String)  
+  Logical link-layer encapsulation.
 - **family_inet** (Block)  
   Family inet enabled and possible configuration.
   - **address** (Block List)  
diff --git a/docs/data-sources/routing_instance.md b/docs/data-sources/routing_instance.md
index 168eef66..9b5fe954 100644
--- a/docs/data-sources/routing_instance.md
+++ b/docs/data-sources/routing_instance.md
@@ -40,6 +40,10 @@ The following attributes are exported:
   Import policy for instance RIBs.
 - **interface** (Set of String)  
   List of interfaces in routing instance.
+- **remote_vtep_list** (Set of String)  
+  Static remote VXLAN tunnel endpoints.
+- **remote_vtep_v6_list** (Set of String)  
+  Static ipv6 remote VXLAN tunnel endpoints.
 - **route_distinguisher** (String)  
   Route distinguisher for this instance.
 - **router_id** (String)  
diff --git a/docs/resources/bridge_domain.md b/docs/resources/bridge_domain.md
index 722a32dc..8a983661 100644
--- a/docs/resources/bridge_domain.md
+++ b/docs/resources/bridge_domain.md
@@ -55,6 +55,8 @@ The following arguments are supported:
   Declare vxlan options.
   - **vni** (Required, Number)  
     VXLAN identifier (0..16777214).
+  - **vni_extend_evpn** (Optional, Boolean)  
+    Extend VNI to EVPN.
   - **decapsulate_accept_inner_vlan** (Optional, Boolean)  
     Accept VXLAN packets with inner VLAN.
   - **encapsulate_inner_vlan** (Optional, Boolean)  
@@ -65,10 +67,10 @@ The following arguments are supported:
     CIDR for Multicast group registered for VXLAN segment.
   - **ovsdb_managed** (Optional, Boolean)  
     Bridge-domain is managed remotely via VXLAN OVSDB Controller.
+  - **static_remote_vtep_list** (Optional, Set of String)  
+    Configure bridge domain specific static remote VXLAN tunnel endpoints.
   - **unreachable_vtep_aging_timer** (Optional, Number)  
     Unreachable VXLAN tunnel endpoint removal timer (300..1800 seconds).
-  - **vni_extend_evpn** (Optional, Boolean)  
-    Extend VNI to EVPN.
 
 ## Attribute Reference
 
diff --git a/docs/resources/interface_logical.md b/docs/resources/interface_logical.md
index fc22e2ba..d8099e21 100644
--- a/docs/resources/interface_logical.md
+++ b/docs/resources/interface_logical.md
@@ -35,6 +35,8 @@ The following arguments are supported:
   Description for interface.
 - **disable** (Optional, Boolean)  
   Disable this logical interface.
+- **encapsulation** (Optional, String)  
+  Logical link-layer encapsulation.
 - **family_inet** (Optional, Block)  
   Enable family inet and add configurations if specified.
   - **address** (Optional, Block List)  
diff --git a/docs/resources/routing_instance.md b/docs/resources/routing_instance.md
index 90cd3f34..a87861ee 100644
--- a/docs/resources/routing_instance.md
+++ b/docs/resources/routing_instance.md
@@ -40,6 +40,10 @@ The following arguments are supported:
   Export policy for instance RIBs.
 - **instance_import** (Optional, List of String)  
   Import policy for instance RIBs.
+- **remote_vtep_list** (Optional, Set of String)  
+  Configure static remote VXLAN tunnel endpoints.
+- **remote_vtep_v6_list** (Optional, Set of String)  
+  Configure static ipv6 remote VXLAN tunnel endpoints.
 - **route_distinguisher** (Optional, String)  
   Route distinguisher for this instance.
 - **router_id** (Optional, String)  
diff --git a/docs/resources/rstp.md b/docs/resources/rstp.md
index 2673d9c9..0621c127 100644
--- a/docs/resources/rstp.md
+++ b/docs/resources/rstp.md
@@ -30,7 +30,7 @@ The following arguments are supported:
 - **backup_bridge_priority** (Optional, String)  
   Priority of the bridge (in increments of 4k - 4k,8k,..60k).
 - **bpdu_block_on_edge** (Optional, Boolean)  
-  Block BPDU on all interfaces configured as edge (BPDU Protect)
+  Block BPDU on all interfaces configured as edge (BPDU Protect).
 - **bpdu_destination_mac_address_provider_bridge_group** (Optional, Boolean)  
   Destination MAC address in the spanning tree BPDUs is 802.1ad provider bridge group address.
 - **bridge_priority** (Optional, String)  
@@ -40,7 +40,7 @@ The following arguments are supported:
 - **extended_system_id** (Optional, Number)  
   Extended system identifier (0..4095).
 - **force_version_stp** (Optional, Boolean)  
-  Force protocol version stp.
+  Force protocol version STP.
 - **forward_delay** (Optional, Number)  
   Time spent in listening or learning state (4..30 seconds).
 - **hello_time** (Optional, Number)  
diff --git a/docs/resources/security_log_stream.md b/docs/resources/security_log_stream.md
index 0e0cfaa9..1835aa57 100644
--- a/docs/resources/security_log_stream.md
+++ b/docs/resources/security_log_stream.md
@@ -61,6 +61,15 @@ The following arguments are supported:
   Rate-limit for security logs.
 - **severity** (Optional, String)  
   Severity threshold for security logs.
+- **transport** (Optional, Block)  
+  Set security log transport settings.
+  - **protocol** (Optional, String)  
+    Set security log transport protocol for the device.  
+    Need to be `tcp`, `tls` or `udp`.
+  - **tcp_connections** (Optional, Number)  
+    Set tcp connection number per-stream (1..5).
+  - **tls_profile** (Optional, String)  
+    TLS profile.
 
 ## Attribute Reference
 
diff --git a/docs/resources/switch_options.md b/docs/resources/switch_options.md
index cb19dd99..f1954dbe 100644
--- a/docs/resources/switch_options.md
+++ b/docs/resources/switch_options.md
@@ -25,6 +25,10 @@ The following arguments are supported:
 
 - **clean_on_destroy** (Optional, Boolean)  
   Clean supported lines when destroy this resource.
+- **remote_vtep_list** (Optional, Set of String)  
+  Configure static remote VXLAN tunnel endpoints.
+- **remote_vtep_v6_list** (Optional, Set of String)  
+  Configure static ipv6 remote VXLAN tunnel endpoints.
 - **service_id** (Optional, Number)  
   Service ID required if multi-chassis AE is part of a bridge-domain (1..65535).
 - **vtep_source_interface** (Optional, String)  
diff --git a/docs/resources/vlan.md b/docs/resources/vlan.md
index 4a64771c..8a7047c8 100644
--- a/docs/resources/vlan.md
+++ b/docs/resources/vlan.md
@@ -60,6 +60,8 @@ The following arguments are supported:
   Declare vxlan configuration.
   - **vni** (Required, Number)  
     VXLAN identifier (0..16777214).
+  - **vni_extend_evpn** (Optional, Boolean)  
+    Extend VNI to EVPN.
   - **encapsulate_inner_vlan** (Optional, Boolean)  
     Retain inner VLAN in the packet.
   - **ingress_node_replication** (Optional, Boolean)  
@@ -68,10 +70,10 @@ The following arguments are supported:
     Multicast group registered for VXLAN segment.
   - **ovsdb_managed** (Optional, Boolean)  
     Bridge-domain is managed remotely via VXLAN OVSDB Controller.
+  - **static_remote_vtep_list** (Optional, Set of String)  
+    Configure vlan specific static remote VXLAN tunnel endpoints.
   - **translation_vni** (Optional, Number)  
     Translated VXLAN identifier (1..16777214).
-  - **vni_extend_evpn** (Optional, Boolean)  
-    Extend VNI to EVPN.
   - **unreachable_vtep_aging_timer** (Optional, Number)  
     Unreachable VXLAN tunnel endpoint removal timer (300..1800 seconds).
 
diff --git a/docs/resources/vstp.md b/docs/resources/vstp.md
index ee0e5edc..34542732 100644
--- a/docs/resources/vstp.md
+++ b/docs/resources/vstp.md
@@ -28,11 +28,11 @@ The following arguments are supported:
   Need to be `default` (for root level) or the name of routing instance.  
   Defaults to `default`.
 - **bpdu_block_on_edge** (Optional, Boolean)  
-  Block BPDU on all interfaces configured as edge (BPDU Protect)
+  Block BPDU on all interfaces configured as edge (BPDU Protect).
 - **disable** (Optional, Boolean)  
   Disable STP.
 - **force_version_stp** (Optional, Boolean)  
-  Force protocol version stp.
+  Force protocol version STP.
 - **priority_hold_time** (Optional, Number)  
   Hold time before switching to primary priority when core domain becomes up (1..255 seconds).
 - **system_id** (Optional, Block Set)  
diff --git a/docs/resources/vstp_vlan.md b/docs/resources/vstp_vlan.md
index d60d3439..98659a52 100644
--- a/docs/resources/vstp_vlan.md
+++ b/docs/resources/vstp_vlan.md
@@ -25,9 +25,9 @@ The following arguments are supported:
   Need to be `default` (for root level) or name of routing instance.  
   Defaults to `default`.
 - **backup_bridge_priority** (Optional, String)  
-  Priority of the bridge (in increments of 4k - 4k,8k,..60k) (4096..61440).
+  Priority of the bridge (in increments of 4k - 4k,8k,..60k).
 - **bridge_priority** (Optional, String)  
-  Priority of the bridge (in increments of 4k - 0,4k,8k,..60k) (0..61440).
+  Priority of the bridge (in increments of 4k - 0,4k,8k,..60k).
 - **forward_delay** (Optional, Number)  
   Time spent in listening or learning state (4..30 seconds).
 - **hello_time** (Optional, Number)  
diff --git a/docs/resources/vstp_vlan_group.md b/docs/resources/vstp_vlan_group.md
index cbbcf4f2..725c0e0a 100644
--- a/docs/resources/vstp_vlan_group.md
+++ b/docs/resources/vstp_vlan_group.md
@@ -26,11 +26,11 @@ The following arguments are supported:
   Need to be `default` (for root level) or name of routing instance.  
   Defaults to `default`.
 - **vlan** (Required, Set of String)  
-  VLAN IDs or VLAN ID ranges [1..4094].
+  VLAN IDs or VLAN ID ranges (1..4094).
 - **backup_bridge_priority** (Optional, String)  
-  Priority of the bridge (in increments of 4k - 4k,8k,..60k) (4096..61440).
+  Priority of the bridge (in increments of 4k - 4k,8k,..60k).
 - **bridge_priority** (Optional, String)  
-  Priority of the bridge (in increments of 4k - 0,4k,8k,..60k) (0..61440).
+  Priority of the bridge (in increments of 4k - 0,4k,8k,..60k).
 - **forward_delay** (Optional, Number)  
   Time spent in listening or learning state (4..30 seconds).
 - **hello_time** (Optional, Number)  
diff --git a/go.mod b/go.mod
index b82614dc..9b07214b 100644
--- a/go.mod
+++ b/go.mod
@@ -5,20 +5,20 @@ go 1.21.0
 require (
 	github.com/google/go-cmp v0.6.0
 	github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320
-	github.com/hashicorp/terraform-plugin-framework v1.8.0
+	github.com/hashicorp/terraform-plugin-framework v1.9.0
 	github.com/hashicorp/terraform-plugin-framework-validators v0.12.0
-	github.com/hashicorp/terraform-plugin-go v0.22.2
-	github.com/hashicorp/terraform-plugin-mux v0.15.0
+	github.com/hashicorp/terraform-plugin-go v0.23.0
+	github.com/hashicorp/terraform-plugin-mux v0.16.0
 	github.com/hashicorp/terraform-plugin-sdk/v2 v2.33.0
-	github.com/hashicorp/terraform-plugin-testing v1.7.0
+	github.com/hashicorp/terraform-plugin-testing v1.8.0
 	github.com/jeremmfr/go-netconf v0.5.0
 	github.com/jeremmfr/go-utils v0.12.0
 	github.com/jeremmfr/junosdecode v1.1.1
-	golang.org/x/crypto v0.22.0
+	golang.org/x/crypto v0.24.0
 )
 
 require (
-	github.com/ProtonMail/go-crypto v1.1.0-alpha.0 // indirect
+	github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect
 	github.com/agext/levenshtein v1.2.2 // indirect
 	github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
 	github.com/cloudflare/circl v1.3.7 // indirect
@@ -27,16 +27,16 @@ require (
 	github.com/hashicorp/errwrap v1.0.0 // indirect
 	github.com/hashicorp/go-checkpoint v0.5.0 // indirect
 	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
-	github.com/hashicorp/go-hclog v1.6.2 // indirect
+	github.com/hashicorp/go-hclog v1.6.3 // indirect
 	github.com/hashicorp/go-multierror v1.1.1 // indirect
 	github.com/hashicorp/go-plugin v1.6.0 // indirect
 	github.com/hashicorp/go-uuid v1.0.3 // indirect
 	github.com/hashicorp/go-version v1.6.0 // indirect
-	github.com/hashicorp/hc-install v0.6.3 // indirect
-	github.com/hashicorp/hcl/v2 v2.20.0 // indirect
+	github.com/hashicorp/hc-install v0.6.4 // indirect
+	github.com/hashicorp/hcl/v2 v2.20.1 // indirect
 	github.com/hashicorp/logutils v1.0.0 // indirect
-	github.com/hashicorp/terraform-exec v0.20.0 // indirect
-	github.com/hashicorp/terraform-json v0.21.0 // indirect
+	github.com/hashicorp/terraform-exec v0.21.0 // indirect
+	github.com/hashicorp/terraform-json v0.22.1 // indirect
 	github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
 	github.com/hashicorp/terraform-registry-address v0.2.3 // indirect
 	github.com/hashicorp/terraform-svchost v0.1.1 // indirect
@@ -52,16 +52,17 @@ require (
 	github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
 	github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
 	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
-	github.com/zclconf/go-cty v1.14.3 // indirect
-	golang.org/x/mod v0.15.0 // indirect
-	golang.org/x/net v0.23.0 // indirect
-	golang.org/x/sys v0.19.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
-	golang.org/x/tools v0.13.0 // indirect
+	github.com/zclconf/go-cty v1.14.4 // indirect
+	golang.org/x/mod v0.17.0 // indirect
+	golang.org/x/net v0.25.0 // indirect
+	golang.org/x/sync v0.7.0 // indirect
+	golang.org/x/sys v0.21.0 // indirect
+	golang.org/x/text v0.16.0 // indirect
+	golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
 	google.golang.org/appengine v1.6.8 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240227224415-6ceb2ff114de // indirect
 	google.golang.org/grpc v1.63.2 // indirect
-	google.golang.org/protobuf v1.33.0 // indirect
+	google.golang.org/protobuf v1.34.0 // indirect
 )
 
 replace github.com/hashicorp/terraform-plugin-sdk/v2 => github.com/jeremmfr/terraform-plugin-sdk/v2 v2.33.1-0.20240302165942-47aab524cbd3
diff --git a/go.sum b/go.sum
index b056c9db..6ccab276 100644
--- a/go.sum
+++ b/go.sum
@@ -2,8 +2,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
 dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
 github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
 github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
-github.com/ProtonMail/go-crypto v1.1.0-alpha.0 h1:nHGfwXmFvJrSR9xu8qL7BkO4DqTHXE9N5vPhgY2I+j0=
-github.com/ProtonMail/go-crypto v1.1.0-alpha.0/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
+github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg=
+github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
 github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
 github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
 github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec=
@@ -27,8 +27,8 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66D
 github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
 github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
 github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
-github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
-github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
+github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys=
+github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY=
 github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
 github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
 github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
@@ -51,8 +51,8 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
 github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI=
 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs=
-github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I=
-github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
+github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
+github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
 github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
 github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
 github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A=
@@ -62,28 +62,28 @@ github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/C
 github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
 github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
-github.com/hashicorp/hc-install v0.6.3 h1:yE/r1yJvWbtrJ0STwScgEnCanb0U9v7zp0Gbkmcoxqs=
-github.com/hashicorp/hc-install v0.6.3/go.mod h1:KamGdbodYzlufbWh4r9NRo8y6GLHWZP2GBtdnms1Ln0=
-github.com/hashicorp/hcl/v2 v2.20.0 h1:l++cRs/5jQOiKVvqXZm/P1ZEfVXJmvLS9WSVxkaeTb4=
-github.com/hashicorp/hcl/v2 v2.20.0/go.mod h1:WmcD/Ym72MDOOx5F62Ly+leloeu6H7m0pG7VBiU6pQk=
+github.com/hashicorp/hc-install v0.6.4 h1:QLqlM56/+SIIGvGcfFiwMY3z5WGXT066suo/v9Km8e0=
+github.com/hashicorp/hc-install v0.6.4/go.mod h1:05LWLy8TD842OtgcfBbOT0WMoInBMUSHjmDx10zuBIA=
+github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc=
+github.com/hashicorp/hcl/v2 v2.20.1/go.mod h1:TZDqQ4kNKCbh1iJp99FdPiUaVDDUPivbqxZulxDYqL4=
 github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y=
 github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
-github.com/hashicorp/terraform-exec v0.20.0 h1:DIZnPsqzPGuUnq6cH8jWcPunBfY+C+M8JyYF3vpnuEo=
-github.com/hashicorp/terraform-exec v0.20.0/go.mod h1:ckKGkJWbsNqFKV1itgMnE0hY9IYf1HoiekpuN0eWoDw=
-github.com/hashicorp/terraform-json v0.21.0 h1:9NQxbLNqPbEMze+S6+YluEdXgJmhQykRyRNd+zTI05U=
-github.com/hashicorp/terraform-json v0.21.0/go.mod h1:qdeBs11ovMzo5puhrRibdD6d2Dq6TyE/28JiU4tIQxk=
-github.com/hashicorp/terraform-plugin-framework v1.8.0 h1:P07qy8RKLcoBkCrY2RHJer5AEvJnDuXomBgou6fD8kI=
-github.com/hashicorp/terraform-plugin-framework v1.8.0/go.mod h1:/CpTukO88PcL/62noU7cuyaSJ4Rsim+A/pa+3rUVufY=
+github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ=
+github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg=
+github.com/hashicorp/terraform-json v0.22.1 h1:xft84GZR0QzjPVWs4lRUwvTcPnegqlyS7orfb5Ltvec=
+github.com/hashicorp/terraform-json v0.22.1/go.mod h1:JbWSQCLFSXFFhg42T7l9iJwdGXBYV8fmmD6o/ML4p3A=
+github.com/hashicorp/terraform-plugin-framework v1.9.0 h1:caLcDoxiRucNi2hk8+j3kJwkKfvHznubyFsJMWfZqKU=
+github.com/hashicorp/terraform-plugin-framework v1.9.0/go.mod h1:qBXLDn69kM97NNVi/MQ9qgd1uWWsVftGSnygYG1tImM=
 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc=
 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg=
-github.com/hashicorp/terraform-plugin-go v0.22.2 h1:5o8uveu6eZUf5J7xGPV0eY0TPXg3qpmwX9sce03Bxnc=
-github.com/hashicorp/terraform-plugin-go v0.22.2/go.mod h1:drq8Snexp9HsbFZddvyLHN6LuWHHndSQg+gV+FPkcIM=
+github.com/hashicorp/terraform-plugin-go v0.23.0 h1:AALVuU1gD1kPb48aPQUjug9Ir/125t+AAurhqphJ2Co=
+github.com/hashicorp/terraform-plugin-go v0.23.0/go.mod h1:1E3Cr9h2vMlahWMbsSEcNrOCxovCZhOOIXjFHbjc/lQ=
 github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0=
 github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow=
-github.com/hashicorp/terraform-plugin-mux v0.15.0 h1:+/+lDx0WUsIOpkAmdwBIoFU8UP9o2eZASoOnLsWbKME=
-github.com/hashicorp/terraform-plugin-mux v0.15.0/go.mod h1:9ezplb1Dyq394zQ+ldB0nvy/qbNAz3mMoHHseMTMaKo=
-github.com/hashicorp/terraform-plugin-testing v1.7.0 h1:I6aeCyZ30z4NiI3tzyDoO6fS7YxP5xSL1ceOon3gTe8=
-github.com/hashicorp/terraform-plugin-testing v1.7.0/go.mod h1:sbAreCleJNOCz+y5vVHV8EJkIWZKi/t4ndKiUjM9vao=
+github.com/hashicorp/terraform-plugin-mux v0.16.0 h1:RCzXHGDYwUwwqfYYWJKBFaS3fQsWn/ZECEiW7p2023I=
+github.com/hashicorp/terraform-plugin-mux v0.16.0/go.mod h1:PF79mAsPc8CpusXPfEVa4X8PtkB+ngWoiUClMrNZlYo=
+github.com/hashicorp/terraform-plugin-testing v1.8.0 h1:wdYIgwDk4iO933gC4S8KbKdnMQShu6BXuZQPScmHvpk=
+github.com/hashicorp/terraform-plugin-testing v1.8.0/go.mod h1:o2kOgf18ADUaZGhtOl0YCkfIxg01MAiMATT2EtIHlZk=
 github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI=
 github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM=
 github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ=
@@ -109,8 +109,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
-github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
 github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
 github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
 github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -136,10 +134,10 @@ github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
 github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
-github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
-github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
-github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
+github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
+github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
 github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
@@ -153,26 +151,28 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV
 github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
 github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/zclconf/go-cty v1.14.3 h1:1JXy1XroaGrzZuG6X9dt7HL6s9AwbY+l4UNL8o5B6ho=
-github.com/zclconf/go-cty v1.14.3/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
+github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8=
+github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
+github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI=
+github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
-golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
+golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
+golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
-golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
+golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
-golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
+golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
-golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -185,24 +185,24 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
-golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
+golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
-golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
+golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
+golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
-golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
-golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
+golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
-golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -214,8 +214,8 @@ google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM=
 google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
-google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4=
+google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/internal/junos/constants.go b/internal/junos/constants.go
index 377cb058..8ac8049a 100644
--- a/internal/junos/constants.go
+++ b/internal/junos/constants.go
@@ -13,9 +13,7 @@ const (
 	PipeDisplaySet         = " | display set"
 	PipeDisplaySetRelative = PipeDisplaySet + " relative"
 
-	RoutingInstancesWS  = "routing-instances " // routing-instances word + space
-	SetRoutingInstances = SetLS + RoutingInstancesWS
-	DelRoutingInstances = DeleteLS + RoutingInstancesWS
+	RoutingInstancesWS = "routing-instances " // routing-instances word + space
 
 	RoutingOptionsWS = "routing-options "
 	RibInet60WS      = "rib inet6.0 "
diff --git a/internal/providerfwk/data_source_interface_logical.go b/internal/providerfwk/data_source_interface_logical.go
index 3e2ed9da..e6b52f5d 100644
--- a/internal/providerfwk/data_source_interface_logical.go
+++ b/internal/providerfwk/data_source_interface_logical.go
@@ -103,6 +103,10 @@ func (dsc *interfaceLogicalDataSource) Schema(
 				Computed:    true,
 				Description: "Interface disabled.",
 			},
+			"encapsulation": schema.StringAttribute{
+				Computed:    true,
+				Description: "Logical link-layer encapsulation.",
+			},
 			"routing_instance": schema.StringAttribute{
 				Computed:    true,
 				Description: "Routing_instance where the interface is.",
@@ -271,6 +275,7 @@ type interfaceLogicalDataSourceData struct {
 	Name                     types.String                      `tfsdk:"name"`
 	Description              types.String                      `tfsdk:"description"`
 	Disable                  types.Bool                        `tfsdk:"disable"`
+	Encapsulation            types.String                      `tfsdk:"encapsulation"`
 	RoutingInstance          types.String                      `tfsdk:"routing_instance"`
 	SecurityInboundProtocols []types.String                    `tfsdk:"security_inbound_protocols"`
 	SecurityInboundServices  []types.String                    `tfsdk:"security_inbound_services"`
@@ -414,6 +419,7 @@ func (dscData *interfaceLogicalDataSourceData) copyFromResourceData(rscData inte
 	dscData.Name = rscData.Name
 	dscData.Description = rscData.Description
 	dscData.Disable = rscData.Disable
+	dscData.Encapsulation = rscData.Encapsulation
 	dscData.FamilyInet = rscData.FamilyInet
 	dscData.FamilyInet6 = rscData.FamilyInet6
 	dscData.RoutingInstance = rscData.RoutingInstance
diff --git a/internal/providerfwk/data_source_routing_instance.go b/internal/providerfwk/data_source_routing_instance.go
index b5ba674c..693236d3 100644
--- a/internal/providerfwk/data_source_routing_instance.go
+++ b/internal/providerfwk/data_source_routing_instance.go
@@ -109,6 +109,16 @@ func (dsc *routingInstanceDataSource) Schema(
 				Computed:    true,
 				Description: "List of interfaces in routing instance.",
 			},
+			"remote_vtep_list": schema.SetAttribute{
+				ElementType: types.StringType,
+				Computed:    true,
+				Description: "Static remote VXLAN tunnel endpoints.",
+			},
+			"remote_vtep_v6_list": schema.SetAttribute{
+				ElementType: types.StringType,
+				Computed:    true,
+				Description: "Static ipv6 remote VXLAN tunnel endpoints.",
+			},
 			"route_distinguisher": schema.StringAttribute{
 				Computed:    true,
 				Description: "Route distinguisher for this instance.",
@@ -160,6 +170,8 @@ type routingInstanceDataSourceData struct {
 	InstanceExport      []types.String `tfsdk:"instance_export"`
 	InstanceImport      []types.String `tfsdk:"instance_import"`
 	Interface           []types.String `tfsdk:"interface"`
+	RemoteVtepList      []types.String `tfsdk:"remote_vtep_list"`
+	RemoteVtepV6List    []types.String `tfsdk:"remote_vtep_v6_list"`
 	RouteDistinguisher  types.String   `tfsdk:"route_distinguisher"`
 	RouterID            types.String   `tfsdk:"router_id"`
 	VRFExport           []types.String `tfsdk:"vrf_export"`
@@ -207,6 +219,8 @@ func (dscData *routingInstanceDataSourceData) copyFromResourceData(data any) {
 	dscData.InstanceExport = rscData.InstanceExport
 	dscData.InstanceImport = rscData.InstanceImport
 	dscData.Interface = rscData.Interface
+	dscData.RemoteVtepList = rscData.RemoteVtepList
+	dscData.RemoteVtepV6List = rscData.RemoteVtepV6List
 	dscData.RouteDistinguisher = rscData.RouteDistinguisher
 	dscData.RouterID = rscData.RouterID
 	dscData.VRFExport = rscData.VRFExport
diff --git a/internal/providerfwk/provider.go b/internal/providerfwk/provider.go
index 99338ced..19a940bf 100644
--- a/internal/providerfwk/provider.go
+++ b/internal/providerfwk/provider.go
@@ -261,6 +261,8 @@ func (p *junosProvider) Resources(_ context.Context) []func() resource.Resource
 		newPolicyoptionsPolicyStatementResource,
 		newPolicyoptionsPrefixListResource,
 		newRoutingInstanceResource,
+		newRstpResource,
+		newRstpInterfaceResource,
 		newSecurityResource,
 		newSecurityAddressBookResource,
 		newSecurityGlobalPolicyResource,
@@ -270,6 +272,7 @@ func (p *junosProvider) Resources(_ context.Context) []func() resource.Resource
 		newSecurityIpsecPolicyResource,
 		newSecurityIpsecProposalResource,
 		newSecurityIpsecVpnResource,
+		newSecurityLogStreamResource,
 		newSecurityNatDestinationResource,
 		newSecurityNatDestinationPoolResource,
 		newSecurityNatSourceResource,
@@ -301,6 +304,10 @@ func (p *junosProvider) Resources(_ context.Context) []func() resource.Resource
 		newSystemTacplusServerResource,
 		newVirtualChassisResource,
 		newVlanResource,
+		newVstpResource,
+		newVstpInterfaceResource,
+		newVstpVlanResource,
+		newVstpVlanGroupResource,
 	}
 }
 
diff --git a/internal/providerfwk/resource_aggregate_route.go b/internal/providerfwk/resource_aggregate_route.go
index 15f26955..ad898524 100644
--- a/internal/providerfwk/resource_aggregate_route.go
+++ b/internal/providerfwk/resource_aggregate_route.go
@@ -493,7 +493,7 @@ func (rsc *aggregateRoute) ImportState(
 func checkAggregateRouteExists(
 	_ context.Context, destination, routingInstance string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showPrefix := junos.CmdShowConfig
 	switch routingInstance {
@@ -508,11 +508,11 @@ func checkAggregateRouteExists(
 			showPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
-	showConfig, err := junSess.Command(showPrefix + "aggregate route " + destination + junos.PipeDisplaySet)
+	showConfig, err := junSess.Command(showPrefix +
+		"aggregate route " + destination + junos.PipeDisplaySet)
 	if err != nil {
 		return false, err
 	}
-
 	if showConfig == junos.EmptyW {
 		return false, nil
 	}
@@ -551,6 +551,7 @@ func (rscData *aggregateRouteData) set(
 		}
 	}
 	setPrefix += "aggregate route " + rscData.Destination.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -603,9 +604,7 @@ func (rscData *aggregateRouteData) set(
 
 func (rscData *aggregateRouteData) read(
 	_ context.Context, destination, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showPrefix := junos.CmdShowConfig
 	switch routingInstance {
 	case junos.DefaultW, "":
@@ -619,16 +618,17 @@ func (rscData *aggregateRouteData) read(
 			showPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
-	showConfig, err := junSess.Command(showPrefix + "aggregate route " + destination + junos.PipeDisplaySetRelative)
+	showConfig, err := junSess.Command(showPrefix +
+		"aggregate route " + destination + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
-
 	if showConfig != junos.EmptyW {
 		rscData.Destination = types.StringValue(destination)
-		rscData.RoutingInstance = types.StringValue(routingInstance)
-		if rscData.RoutingInstance.ValueString() == "" {
+		if routingInstance == "" {
 			rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+		} else {
+			rscData.RoutingInstance = types.StringValue(routingInstance)
 		}
 		rscData.fillID()
 		for _, item := range strings.Split(showConfig, "\n") {
@@ -700,6 +700,7 @@ func (rscData *aggregateRouteData) del(
 			delPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
+
 	configSet := []string{
 		delPrefix + "aggregate route " + rscData.Destination.ValueString(),
 	}
diff --git a/internal/providerfwk/resource_application.go b/internal/providerfwk/resource_application.go
index dc8cbf61..de049e4e 100644
--- a/internal/providerfwk/resource_application.go
+++ b/internal/providerfwk/resource_application.go
@@ -692,6 +692,7 @@ func (block *applicationBlockTerm) configSet(
 	error, // error
 ) {
 	setPrefix += "term " + block.Name.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 		setPrefix + "protocol " + block.Protocol.ValueString(),
@@ -742,9 +743,7 @@ func (block *applicationBlockTerm) configSet(
 
 func (rscData *applicationData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"applications application " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_application_set.go b/internal/providerfwk/resource_application_set.go
index 84e20346..6dba3b5f 100644
--- a/internal/providerfwk/resource_application_set.go
+++ b/internal/providerfwk/resource_application_set.go
@@ -358,9 +358,7 @@ func (rscData *applicationSetData) set(
 
 func (rscData *applicationSetData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"applications application-set " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_bgp_group.go b/internal/providerfwk/resource_bgp_group.go
index ee7f76a9..01d2738d 100644
--- a/internal/providerfwk/resource_bgp_group.go
+++ b/internal/providerfwk/resource_bgp_group.go
@@ -888,7 +888,7 @@ func (rsc *bgpGroup) ValidateConfig(
 		resp.Diagnostics.AddAttributeError(
 			path.Root("advertise_peer_as"),
 			tfdiag.ConflictConfigErrSummary,
-			"advertise_peer_as and no_advertise_peer_as can't be true in same time ",
+			"advertise_peer_as and no_advertise_peer_as can't be true in same time",
 		)
 	}
 	if !config.KeepAll.IsNull() && !config.KeepAll.IsUnknown() &&
@@ -896,7 +896,7 @@ func (rsc *bgpGroup) ValidateConfig(
 		resp.Diagnostics.AddAttributeError(
 			path.Root("keep_all"),
 			tfdiag.ConflictConfigErrSummary,
-			"keep_all and keep_none can't be true in same time ",
+			"keep_all and keep_none can't be true in same time",
 		)
 	}
 	if !config.AuthenticationKey.IsNull() && !config.AuthenticationKey.IsUnknown() {
@@ -1084,7 +1084,7 @@ func (rsc *bgpGroup) ValidateConfig(
 						path.Root("family_evpn").AtListIndex(i).AtName("accepted_prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in accepted_prefix_limit block in family_evpn block ",
+							" in accepted_prefix_limit block in family_evpn block",
 					)
 				}
 			}
@@ -1104,7 +1104,7 @@ func (rsc *bgpGroup) ValidateConfig(
 						path.Root("family_evpn").AtListIndex(i).AtName("prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in prefix_limit block family_evpn block ",
+							" in prefix_limit block family_evpn block",
 					)
 				}
 			}
@@ -1147,7 +1147,7 @@ func (rsc *bgpGroup) ValidateConfig(
 						path.Root("family_inet").AtListIndex(i).AtName("accepted_prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in accepted_prefix_limit block in family_inet block ",
+							" in accepted_prefix_limit block in family_inet block",
 					)
 				}
 			}
@@ -1167,7 +1167,7 @@ func (rsc *bgpGroup) ValidateConfig(
 						path.Root("family_inet").AtListIndex(i).AtName("prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in prefix_limit block family_inet block ",
+							" in prefix_limit block family_inet block",
 					)
 				}
 			}
@@ -1210,7 +1210,7 @@ func (rsc *bgpGroup) ValidateConfig(
 						path.Root("family_inet6").AtListIndex(i).AtName("accepted_prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in accepted_prefix_limit block in family_inet6 block ",
+							" in accepted_prefix_limit block in family_inet6 block",
 					)
 				}
 			}
@@ -1230,7 +1230,7 @@ func (rsc *bgpGroup) ValidateConfig(
 						path.Root("family_inet6").AtListIndex(i).AtName("prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in prefix_limit block family_inet6 block ",
+							" in prefix_limit block family_inet6 block",
 					)
 				}
 			}
@@ -1537,22 +1537,16 @@ func checkBgpGroupExists(
 	routingInstance string,
 	junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
-	var showConfig string
-	if routingInstance == "" || routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols bgp group \"" + name + "\"" + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols bgp group \"" + name + "\"" + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols bgp group \"" + name + "\"" + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
 	}
 	if showConfig == junos.EmptyW {
 		return false, nil
@@ -1578,11 +1572,12 @@ func (rscData *bgpGroupData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set protocols bgp group \"" + rscData.Name.ValueString() + "\" "
+	setPrefix := junos.SetLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + v +
-			" protocols bgp group \"" + rscData.Name.ValueString() + "\" "
+		setPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	setPrefix += "protocols bgp group \"" + rscData.Name.ValueString() + "\" "
+
 	configSet := []string{
 		setPrefix + "type " + rscData.Type.ValueString(),
 	}
@@ -1789,23 +1784,15 @@ func (rscData *bgpGroupData) set(
 
 func (rscData *bgpGroupData) read(
 	_ context.Context, name, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
-	var showConfig string
-	if routingInstance == "" || routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols bgp group \"" + name + "\"" + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols bgp group \"" + name + "\"" + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols bgp group \"" + name + "\"" + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
 	}
 	if showConfig != junos.EmptyW {
 		rscData.Name = types.StringValue(name)
@@ -2020,11 +2007,11 @@ func (rscData *bgpGroupData) delOpts(
 	_ context.Context, junSess *junos.Session,
 ) error {
 	configSet := make([]string, 0)
-	delPrefix := "delete protocols bgp group \"" + rscData.Name.ValueString() + "\" "
+	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + v +
-			" protocols bgp group \"" + rscData.Name.ValueString() + "\" "
+		delPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	delPrefix += "protocols bgp group \"" + rscData.Name.ValueString() + "\" "
 
 	configSet = append(configSet,
 		delPrefix+"accept-remote-nexthop",
@@ -2073,13 +2060,13 @@ func (rscData *bgpGroupData) delOpts(
 func (rscData *bgpGroupData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	configSet := make([]string, 1)
+	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		configSet[0] = junos.DelRoutingInstances + v +
-			" protocols bgp group \"" + rscData.Name.ValueString() + "\""
-	} else {
-		configSet[0] = junos.DeleteW +
-			" protocols bgp group \"" + rscData.Name.ValueString() + "\""
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+
+	configSet := []string{
+		delPrefix + "protocols bgp group \"" + rscData.Name.ValueString() + "\"",
 	}
 
 	return junSess.ConfigSet(configSet)
diff --git a/internal/providerfwk/resource_bgp_neighbor.go b/internal/providerfwk/resource_bgp_neighbor.go
index 24dbbdcd..0936be5b 100644
--- a/internal/providerfwk/resource_bgp_neighbor.go
+++ b/internal/providerfwk/resource_bgp_neighbor.go
@@ -887,7 +887,7 @@ func (rsc *bgpNeighbor) ValidateConfig(
 		resp.Diagnostics.AddAttributeError(
 			path.Root("advertise_peer_as"),
 			tfdiag.ConflictConfigErrSummary,
-			"advertise_peer_as and no_advertise_peer_as can't be true in same time ",
+			"advertise_peer_as and no_advertise_peer_as can't be true in same time",
 		)
 	}
 	if !config.KeepAll.IsNull() && !config.KeepAll.IsUnknown() &&
@@ -895,7 +895,7 @@ func (rsc *bgpNeighbor) ValidateConfig(
 		resp.Diagnostics.AddAttributeError(
 			path.Root("keep_all"),
 			tfdiag.ConflictConfigErrSummary,
-			"keep_all and keep_none can't be true in same time ",
+			"keep_all and keep_none can't be true in same time",
 		)
 	}
 	if !config.AuthenticationKey.IsNull() && !config.AuthenticationKey.IsUnknown() {
@@ -1083,7 +1083,7 @@ func (rsc *bgpNeighbor) ValidateConfig(
 						path.Root("family_evpn").AtListIndex(i).AtName("accepted_prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in accepted_prefix_limit block in family_evpn block ",
+							" in accepted_prefix_limit block in family_evpn block",
 					)
 				}
 			}
@@ -1103,7 +1103,7 @@ func (rsc *bgpNeighbor) ValidateConfig(
 						path.Root("family_evpn").AtListIndex(i).AtName("prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in prefix_limit block family_evpn block ",
+							" in prefix_limit block family_evpn block",
 					)
 				}
 			}
@@ -1146,7 +1146,7 @@ func (rsc *bgpNeighbor) ValidateConfig(
 						path.Root("family_inet").AtListIndex(i).AtName("accepted_prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in accepted_prefix_limit block in family_inet block ",
+							" in accepted_prefix_limit block in family_inet block",
 					)
 				}
 			}
@@ -1166,7 +1166,7 @@ func (rsc *bgpNeighbor) ValidateConfig(
 						path.Root("family_inet").AtListIndex(i).AtName("prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in prefix_limit block family_inet block ",
+							" in prefix_limit block family_inet block",
 					)
 				}
 			}
@@ -1209,7 +1209,7 @@ func (rsc *bgpNeighbor) ValidateConfig(
 						path.Root("family_inet6").AtListIndex(i).AtName("accepted_prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in accepted_prefix_limit block in family_inet6 block ",
+							" in accepted_prefix_limit block in family_inet6 block",
 					)
 				}
 			}
@@ -1229,7 +1229,7 @@ func (rsc *bgpNeighbor) ValidateConfig(
 						path.Root("family_inet6").AtListIndex(i).AtName("prefix_limit").AtName("teardown_idle_timeout"),
 						tfdiag.ConflictConfigErrSummary,
 						"teardown_idle_timeout and teardown_idle_timeout_forever cannot be configured together"+
-							" in prefix_limit block family_inet6 block ",
+							" in prefix_limit block family_inet6 block",
 					)
 				}
 			}
@@ -1573,24 +1573,16 @@ func checkBgpNeighborExists(
 	group string,
 	junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
-	var showConfig string
-	if routingInstance == junos.DefaultW || routingInstance == "" {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols bgp group \"" + group + "\"" +
-			" neighbor " + ip + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols bgp group \"" + group + "\"" +
-			" neighbor " + ip + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols bgp group \"" + group + "\" neighbor " + ip + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
 	}
 	if showConfig == junos.EmptyW {
 		return false, nil
@@ -1624,13 +1616,12 @@ func (rscData *bgpNeighborData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set protocols bgp group \"" + rscData.Group.ValueString() + "\"" +
-		" neighbor " + rscData.IP.ValueString() + " "
+	setPrefix := junos.SetLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + v +
-			" protocols bgp group \"" + rscData.Group.ValueString() + "\"" +
-			" neighbor " + rscData.IP.ValueString() + " "
+		setPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	setPrefix += "protocols bgp group \"" + rscData.Group.ValueString() + "\" neighbor " + rscData.IP.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -1841,25 +1832,15 @@ func (rscData *bgpNeighborData) read(
 	routingInstance,
 	group string,
 	junSess *junos.Session,
-) (
-	err error,
-) {
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols bgp group \"" + group + "\"" +
-			" neighbor " + ip + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols bgp group \"" + group + "\"" +
-			" neighbor " + ip + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols bgp group \"" + group + "\" neighbor " + ip + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
 	}
 	if showConfig != junos.EmptyW {
 		rscData.IP = types.StringValue(ip)
@@ -2073,14 +2054,11 @@ func (rscData *bgpNeighborData) delOpts(
 	_ context.Context, junSess *junos.Session,
 ) error {
 	configSet := make([]string, 0)
-	delPrefix := junos.DeleteW +
-		" protocols bgp group \"" + rscData.Group.ValueString() + "\"" +
-		" neighbor " + rscData.IP.ValueString() + " "
+	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + v +
-			" protocols bgp group \"" + rscData.Group.ValueString() + "\"" +
-			" neighbor " + rscData.IP.ValueString() + " "
+		delPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	delPrefix += "protocols bgp group \"" + rscData.Group.ValueString() + "\" neighbor " + rscData.IP.ValueString() + " "
 
 	configSet = append(configSet,
 		delPrefix+"accept-remote-nexthop",
@@ -2129,15 +2107,13 @@ func (rscData *bgpNeighborData) delOpts(
 func (rscData *bgpNeighborData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	configSet := make([]string, 1)
+	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		configSet[0] = junos.DelRoutingInstances + v +
-			" protocols bgp group \"" + rscData.Group.ValueString() + "\"" +
-			" neighbor " + rscData.IP.ValueString()
-	} else {
-		configSet[0] = junos.DeleteW +
-			" protocols bgp group \"" + rscData.Group.ValueString() + "\"" +
-			" neighbor " + rscData.IP.ValueString()
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+
+	configSet := []string{
+		delPrefix + "protocols bgp group \"" + rscData.Group.ValueString() + "\" neighbor " + rscData.IP.ValueString(),
 	}
 
 	return junSess.ConfigSet(configSet)
diff --git a/internal/providerfwk/resource_bridge_domain.go b/internal/providerfwk/resource_bridge_domain.go
index 48cd2921..6957d743 100644
--- a/internal/providerfwk/resource_bridge_domain.go
+++ b/internal/providerfwk/resource_bridge_domain.go
@@ -219,6 +219,13 @@ func (rsc *bridgeDomain) Schema(
 							int64validator.Between(0, 16777214),
 						},
 					},
+					"vni_extend_evpn": schema.BoolAttribute{
+						Optional:    true,
+						Description: "Extend VNI to EVPN.",
+						Validators: []validator.Bool{
+							tfvalidator.BoolTrue(),
+						},
+					},
 					"decapsulate_accept_inner_vlan": schema.BoolAttribute{
 						Optional:    true,
 						Description: "Accept VXLAN packets with inner VLAN.",
@@ -254,6 +261,17 @@ func (rsc *bridgeDomain) Schema(
 							tfvalidator.BoolTrue(),
 						},
 					},
+					"static_remote_vtep_list": schema.SetAttribute{
+						ElementType: types.StringType,
+						Optional:    true,
+						Description: "Configure bridge domain specific static remote VXLAN tunnel endpoints.",
+						Validators: []validator.Set{
+							setvalidator.SizeAtLeast(1),
+							setvalidator.ValueStringsAre(
+								tfvalidator.StringIPAddress().IPv4Only(),
+							),
+						},
+					},
 					"unreachable_vtep_aging_timer": schema.Int64Attribute{
 						Optional:    true,
 						Description: "Unreachable VXLAN tunnel endpoint removal timer.",
@@ -261,13 +279,6 @@ func (rsc *bridgeDomain) Schema(
 							int64validator.Between(300, 1800),
 						},
 					},
-					"vni_extend_evpn": schema.BoolAttribute{
-						Optional:    true,
-						Description: "Extend VNI to EVPN.",
-						Validators: []validator.Bool{
-							tfvalidator.BoolTrue(),
-						},
-					},
 				},
 				PlanModifiers: []planmodifier.Object{
 					tfplanmodifier.BlockRemoveNull(),
@@ -289,41 +300,54 @@ type bridgeDomainData struct {
 	IsolatedVLAN     types.Int64             `tfsdk:"isolated_vlan"`
 	RoutingInterface types.String            `tfsdk:"routing_interface"`
 	ServiceID        types.Int64             `tfsdk:"service_id"`
-	VLANID           types.Int64             `tfsdk:"vlan_id"`
-	VLANIDList       []types.String          `tfsdk:"vlan_id_list"`
-	VXLAN            *bridgeDomainBlockVXLAN `tfsdk:"vxlan"`
+	VlanID           types.Int64             `tfsdk:"vlan_id"`
+	VlanIDList       []types.String          `tfsdk:"vlan_id_list"`
+	Vxlan            *bridgeDomainBlockVxlan `tfsdk:"vxlan"`
 }
 
 type bridgeDomainConfig struct {
-	ID               types.String            `tfsdk:"id"`
-	Name             types.String            `tfsdk:"name"`
-	RoutingInstance  types.String            `tfsdk:"routing_instance"`
-	CommunityVlans   types.Set               `tfsdk:"community_vlans"`
-	Description      types.String            `tfsdk:"description"`
-	DomainID         types.Int64             `tfsdk:"domain_id"`
-	DomainTypeBridge types.Bool              `tfsdk:"domain_type_bridge"`
-	Interface        types.Set               `tfsdk:"interface"`
-	IsolatedVLAN     types.Int64             `tfsdk:"isolated_vlan"`
-	RoutingInterface types.String            `tfsdk:"routing_interface"`
-	ServiceID        types.Int64             `tfsdk:"service_id"`
-	VLANID           types.Int64             `tfsdk:"vlan_id"`
-	VLANIDList       types.Set               `tfsdk:"vlan_id_list"`
-	VXLAN            *bridgeDomainBlockVXLAN `tfsdk:"vxlan"`
+	ID               types.String                  `tfsdk:"id"`
+	Name             types.String                  `tfsdk:"name"`
+	RoutingInstance  types.String                  `tfsdk:"routing_instance"`
+	CommunityVlans   types.Set                     `tfsdk:"community_vlans"`
+	Description      types.String                  `tfsdk:"description"`
+	DomainID         types.Int64                   `tfsdk:"domain_id"`
+	DomainTypeBridge types.Bool                    `tfsdk:"domain_type_bridge"`
+	Interface        types.Set                     `tfsdk:"interface"`
+	IsolatedVLAN     types.Int64                   `tfsdk:"isolated_vlan"`
+	RoutingInterface types.String                  `tfsdk:"routing_interface"`
+	ServiceID        types.Int64                   `tfsdk:"service_id"`
+	VlanID           types.Int64                   `tfsdk:"vlan_id"`
+	VlanIDList       types.Set                     `tfsdk:"vlan_id_list"`
+	Vxlan            *bridgeDomainBlockVxlanConfig `tfsdk:"vxlan"`
 }
 
 func (rscConfig *bridgeDomainConfig) isEmpty() bool {
 	return tfdata.CheckBlockIsEmpty(rscConfig, "ID", "Name", "RoutingInstance")
 }
 
-type bridgeDomainBlockVXLAN struct {
-	VNI                        types.Int64  `tfsdk:"vni"`
+type bridgeDomainBlockVxlan struct {
+	Vni                        types.Int64    `tfsdk:"vni"`
+	VniExtendEvpn              types.Bool     `tfsdk:"vni_extend_evpn"`
+	DecapsulateAcceptInnerVlan types.Bool     `tfsdk:"decapsulate_accept_inner_vlan"`
+	EncapsulateInnerVlan       types.Bool     `tfsdk:"encapsulate_inner_vlan"`
+	IngressNodeReplication     types.Bool     `tfsdk:"ingress_node_replication"`
+	MulticastGroup             types.String   `tfsdk:"multicast_group"`
+	OvsdbManaged               types.Bool     `tfsdk:"ovsdb_managed"`
+	StaticRemoteVtepList       []types.String `tfsdk:"static_remote_vtep_list"`
+	UnreachableVtepAgingTimer  types.Int64    `tfsdk:"unreachable_vtep_aging_timer"`
+}
+
+type bridgeDomainBlockVxlanConfig struct {
+	Vni                        types.Int64  `tfsdk:"vni"`
+	VniExtendEvpn              types.Bool   `tfsdk:"vni_extend_evpn"`
 	DecapsulateAcceptInnerVlan types.Bool   `tfsdk:"decapsulate_accept_inner_vlan"`
 	EncapsulateInnerVlan       types.Bool   `tfsdk:"encapsulate_inner_vlan"`
 	IngressNodeReplication     types.Bool   `tfsdk:"ingress_node_replication"`
 	MulticastGroup             types.String `tfsdk:"multicast_group"`
 	OvsdbManaged               types.Bool   `tfsdk:"ovsdb_managed"`
+	StaticRemoteVtepList       types.Set    `tfsdk:"static_remote_vtep_list"`
 	UnreachableVtepAgingTimer  types.Int64  `tfsdk:"unreachable_vtep_aging_timer"`
-	VNIExtendEvpn              types.Bool   `tfsdk:"vni_extend_evpn"`
 }
 
 func (rsc *bridgeDomain) ValidateConfig(
@@ -343,16 +367,16 @@ func (rsc *bridgeDomain) ValidateConfig(
 		)
 	}
 
-	if !config.VLANID.IsNull() && !config.VLANID.IsUnknown() &&
-		!config.VLANIDList.IsNull() && !config.VLANIDList.IsUnknown() {
+	if !config.VlanID.IsNull() && !config.VlanID.IsUnknown() &&
+		!config.VlanIDList.IsNull() && !config.VlanIDList.IsUnknown() {
 		resp.Diagnostics.AddAttributeError(
 			path.Root("vlan_id"),
 			tfdiag.ConflictConfigErrSummary,
 			"vlan_id and vlan_id_list cannot be configured together",
 		)
 	}
-	if config.VXLAN != nil {
-		if config.VXLAN.VNI.IsNull() {
+	if config.Vxlan != nil {
+		if config.Vxlan.Vni.IsNull() {
 			resp.Diagnostics.AddAttributeError(
 				path.Root("vxlan").AtName("vni"),
 				tfdiag.MissingConfigErrSummary,
@@ -554,17 +578,17 @@ func (rsc *bridgeDomain) ImportState(
 func checkBridgeDomainExists(
 	_ context.Context, name, routingInstance string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showPrefix := junos.CmdShowConfig
 	if routingInstance != "" && routingInstance != junos.DefaultW {
 		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
-	showConfig, err := junSess.Command(showPrefix + "bridge-domains \"" + name + "\"" + junos.PipeDisplaySet)
+	showConfig, err := junSess.Command(showPrefix +
+		"bridge-domains \"" + name + "\"" + junos.PipeDisplaySet)
 	if err != nil {
 		return false, err
 	}
-
 	if showConfig == junos.EmptyW {
 		return false, nil
 	}
@@ -590,12 +614,11 @@ func (rscData *bridgeDomainData) set(
 	path.Path, error,
 ) {
 	configSet := make([]string, 0)
-
 	setPrefix := junos.SetLS
-	routingInstance := rscData.RoutingInstance.ValueString()
-	if routingInstance != "" && routingInstance != junos.DefaultW {
-		setPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		setPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	setPrefixProtocolsEvpn := setPrefix + "protocols evpn "
 	setPrefix += "bridge-domains \"" + rscData.Name.ValueString() + "\" "
 
 	for _, v := range rscData.CommunityVlans {
@@ -625,44 +648,42 @@ func (rscData *bridgeDomainData) set(
 		configSet = append(configSet, setPrefix+"service-id "+
 			utils.ConvI64toa(rscData.ServiceID.ValueInt64()))
 	}
-	if !rscData.VLANID.IsNull() {
+	if !rscData.VlanID.IsNull() {
 		configSet = append(configSet, setPrefix+"vlan-id "+
-			utils.ConvI64toa(rscData.VLANID.ValueInt64()))
+			utils.ConvI64toa(rscData.VlanID.ValueInt64()))
 	}
-	for _, v := range rscData.VLANIDList {
+	for _, v := range rscData.VlanIDList {
 		configSet = append(configSet, setPrefix+"vlan-id-list "+v.ValueString())
 	}
-	if rscData.VXLAN != nil {
+	if rscData.Vxlan != nil {
 		configSet = append(configSet, setPrefix+"vxlan vni "+
-			utils.ConvI64toa(rscData.VXLAN.VNI.ValueInt64()))
-
-		if rscData.VXLAN.VNIExtendEvpn.ValueBool() {
-			if routingInstance != "" && routingInstance != junos.DefaultW {
-				configSet = append(configSet, junos.SetRoutingInstances+routingInstance+" protocols evpn extended-vni-list "+
-					utils.ConvI64toa(rscData.VXLAN.VNI.ValueInt64()))
-			} else {
-				configSet = append(configSet, "set protocols evpn extended-vni-list "+
-					utils.ConvI64toa(rscData.VXLAN.VNI.ValueInt64()))
-			}
+			utils.ConvI64toa(rscData.Vxlan.Vni.ValueInt64()))
+
+		if rscData.Vxlan.VniExtendEvpn.ValueBool() {
+			configSet = append(configSet, setPrefixProtocolsEvpn+"extended-vni-list "+
+				utils.ConvI64toa(rscData.Vxlan.Vni.ValueInt64()))
 		}
-		if rscData.VXLAN.DecapsulateAcceptInnerVlan.ValueBool() {
+		if rscData.Vxlan.DecapsulateAcceptInnerVlan.ValueBool() {
 			configSet = append(configSet, setPrefix+"vxlan decapsulate-accept-inner-vlan")
 		}
-		if rscData.VXLAN.EncapsulateInnerVlan.ValueBool() {
+		if rscData.Vxlan.EncapsulateInnerVlan.ValueBool() {
 			configSet = append(configSet, setPrefix+"vxlan encapsulate-inner-vlan")
 		}
-		if rscData.VXLAN.IngressNodeReplication.ValueBool() {
+		if rscData.Vxlan.IngressNodeReplication.ValueBool() {
 			configSet = append(configSet, setPrefix+"vxlan ingress-node-replication")
 		}
-		if v := rscData.VXLAN.MulticastGroup.ValueString(); v != "" {
+		if v := rscData.Vxlan.MulticastGroup.ValueString(); v != "" {
 			configSet = append(configSet, setPrefix+"vxlan multicast-group "+v)
 		}
-		if rscData.VXLAN.OvsdbManaged.ValueBool() {
+		if rscData.Vxlan.OvsdbManaged.ValueBool() {
 			configSet = append(configSet, setPrefix+"vxlan ovsdb-managed")
 		}
-		if !rscData.VXLAN.UnreachableVtepAgingTimer.IsNull() {
+		for _, v := range rscData.Vxlan.StaticRemoteVtepList {
+			configSet = append(configSet, setPrefix+"vxlan static-remote-vtep-list "+v.ValueString())
+		}
+		if !rscData.Vxlan.UnreachableVtepAgingTimer.IsNull() {
 			configSet = append(configSet, setPrefix+"vxlan unreachable-vtep-aging-timer "+
-				utils.ConvI64toa(rscData.VXLAN.UnreachableVtepAgingTimer.ValueInt64()))
+				utils.ConvI64toa(rscData.Vxlan.UnreachableVtepAgingTimer.ValueInt64()))
 		}
 	}
 
@@ -671,18 +692,16 @@ func (rscData *bridgeDomainData) set(
 
 func (rscData *bridgeDomainData) read(
 	_ context.Context, name, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showPrefix := junos.CmdShowConfig
 	if routingInstance != "" && routingInstance != junos.DefaultW {
 		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
-	showConfig, err := junSess.Command(showPrefix + "bridge-domains \"" + name + "\"" + junos.PipeDisplaySetRelative)
+	showConfig, err := junSess.Command(showPrefix +
+		"bridge-domains \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
-
 	if showConfig != junos.EmptyW {
 		rscData.Name = types.StringValue(name)
 		if routingInstance == "" {
@@ -726,31 +745,26 @@ func (rscData *bridgeDomainData) read(
 					return err
 				}
 			case balt.CutPrefixInString(&itemTrim, "vlan-id "):
-				rscData.VLANID, err = tfdata.ConvAtoi64Value(itemTrim)
+				rscData.VlanID, err = tfdata.ConvAtoi64Value(itemTrim)
 				if err != nil {
 					return err
 				}
 			case balt.CutPrefixInString(&itemTrim, "vlan-id-list "):
-				rscData.VLANIDList = append(rscData.VLANIDList, types.StringValue(itemTrim))
+				rscData.VlanIDList = append(rscData.VlanIDList, types.StringValue(itemTrim))
 			case balt.CutPrefixInString(&itemTrim, "vxlan "):
-				if rscData.VXLAN == nil {
-					rscData.VXLAN = &bridgeDomainBlockVXLAN{}
+				if rscData.Vxlan == nil {
+					rscData.Vxlan = &bridgeDomainBlockVxlan{}
 				}
 				switch {
 				case balt.CutPrefixInString(&itemTrim, "vni "):
-					rscData.VXLAN.VNI, err = tfdata.ConvAtoi64Value(itemTrim)
+					rscData.Vxlan.Vni, err = tfdata.ConvAtoi64Value(itemTrim)
 					if err != nil {
 						return err
 					}
-					showPrefixEvpn := junos.CmdShowConfig
-					if routingInstance != "" && routingInstance != junos.DefaultW {
-						showPrefixEvpn += junos.RoutingInstancesWS + routingInstance + " "
-					}
-					showConfigEvpn, err := junSess.Command(showPrefixEvpn + "protocols evpn" + junos.PipeDisplaySetRelative)
+					showConfigEvpn, err := junSess.Command(showPrefix + "protocols evpn" + junos.PipeDisplaySetRelative)
 					if err != nil {
 						return err
 					}
-
 					if showConfigEvpn != junos.EmptyW {
 						for _, itemEvpn := range strings.Split(showConfigEvpn, "\n") {
 							if strings.Contains(itemEvpn, junos.XMLStartTagConfigOut) {
@@ -759,25 +773,27 @@ func (rscData *bridgeDomainData) read(
 							if strings.Contains(itemEvpn, junos.XMLEndTagConfigOut) {
 								break
 							}
-							if strings.HasPrefix(itemEvpn, junos.SetLS+"extended-vni-list "+itemTrim) {
-								rscData.VXLAN.VNIExtendEvpn = types.BoolValue(true)
+							if itemEvpn == junos.SetLS+"extended-vni-list "+itemTrim {
+								rscData.Vxlan.VniExtendEvpn = types.BoolValue(true)
 
 								break
 							}
 						}
 					}
 				case itemTrim == "decapsulate-accept-inner-vlan":
-					rscData.VXLAN.DecapsulateAcceptInnerVlan = types.BoolValue(true)
+					rscData.Vxlan.DecapsulateAcceptInnerVlan = types.BoolValue(true)
 				case itemTrim == "encapsulate-inner-vlan":
-					rscData.VXLAN.EncapsulateInnerVlan = types.BoolValue(true)
+					rscData.Vxlan.EncapsulateInnerVlan = types.BoolValue(true)
 				case itemTrim == "ingress-node-replication":
-					rscData.VXLAN.IngressNodeReplication = types.BoolValue(true)
+					rscData.Vxlan.IngressNodeReplication = types.BoolValue(true)
 				case balt.CutPrefixInString(&itemTrim, "multicast-group "):
-					rscData.VXLAN.MulticastGroup = types.StringValue(itemTrim)
+					rscData.Vxlan.MulticastGroup = types.StringValue(itemTrim)
 				case itemTrim == "ovsdb-managed":
-					rscData.VXLAN.OvsdbManaged = types.BoolValue(true)
+					rscData.Vxlan.OvsdbManaged = types.BoolValue(true)
+				case balt.CutPrefixInString(&itemTrim, "static-remote-vtep-list "):
+					rscData.Vxlan.StaticRemoteVtepList = append(rscData.Vxlan.StaticRemoteVtepList, types.StringValue(itemTrim))
 				case balt.CutPrefixInString(&itemTrim, "unreachable-vtep-aging-timer "):
-					rscData.VXLAN.UnreachableVtepAgingTimer, err = tfdata.ConvAtoi64Value(itemTrim)
+					rscData.Vxlan.UnreachableVtepAgingTimer, err = tfdata.ConvAtoi64Value(itemTrim)
 					if err != nil {
 						return err
 					}
@@ -794,8 +810,9 @@ func (rscData *bridgeDomainData) delOpts(
 ) error {
 	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + v + " "
+		delPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	delPrefixProtocolsEvpn := delPrefix + "protocols evpn "
 	delPrefix += "bridge-domains \"" + rscData.Name.ValueString() + "\" "
 
 	configSet := []string{
@@ -813,15 +830,10 @@ func (rscData *bridgeDomainData) delOpts(
 	for _, v := range rscData.Interface {
 		configSet = append(configSet, delPrefix+"interface "+v.ValueString())
 	}
-	if rscData.VXLAN != nil {
-		if rscData.VXLAN.VNIExtendEvpn.ValueBool() {
-			if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-				configSet = append(configSet, junos.DelRoutingInstances+v+" "+
-					"protocols evpn extended-vni-list "+utils.ConvI64toa(rscData.VXLAN.VNI.ValueInt64()))
-			} else {
-				configSet = append(configSet, junos.DeleteLS+
-					"protocols evpn extended-vni-list "+utils.ConvI64toa(rscData.VXLAN.VNI.ValueInt64()))
-			}
+	if rscData.Vxlan != nil {
+		if rscData.Vxlan.VniExtendEvpn.ValueBool() {
+			configSet = append(configSet, delPrefixProtocolsEvpn+
+				"extended-vni-list "+utils.ConvI64toa(rscData.Vxlan.Vni.ValueInt64()))
 		}
 	}
 
@@ -831,22 +843,18 @@ func (rscData *bridgeDomainData) delOpts(
 func (rscData *bridgeDomainData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	configSet := make([]string, 0, 1)
+	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		configSet = append(configSet, junos.DelRoutingInstances+v+
-			" bridge-domains \""+rscData.Name.ValueString()+"\"")
-	} else {
-		configSet = append(configSet, "delete bridge-domains \""+rscData.Name.ValueString()+"\"")
-	}
-	if rscData.VXLAN != nil {
-		if rscData.VXLAN.VNIExtendEvpn.ValueBool() {
-			if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-				configSet = append(configSet, junos.DelRoutingInstances+v+" "+
-					"protocols evpn extended-vni-list "+utils.ConvI64toa(rscData.VXLAN.VNI.ValueInt64()))
-			} else {
-				configSet = append(configSet, junos.DeleteLS+
-					"protocols evpn extended-vni-list "+utils.ConvI64toa(rscData.VXLAN.VNI.ValueInt64()))
-			}
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+
+	configSet := []string{
+		delPrefix + "bridge-domains \"" + rscData.Name.ValueString() + "\"",
+	}
+	if rscData.Vxlan != nil {
+		if rscData.Vxlan.VniExtendEvpn.ValueBool() {
+			configSet = append(configSet, delPrefix+
+				"protocols evpn extended-vni-list "+utils.ConvI64toa(rscData.Vxlan.Vni.ValueInt64()))
 		}
 	}
 
diff --git a/internal/providerfwk/resource_eventoptions_destination.go b/internal/providerfwk/resource_eventoptions_destination.go
index fc8c5b88..5669b1f6 100644
--- a/internal/providerfwk/resource_eventoptions_destination.go
+++ b/internal/providerfwk/resource_eventoptions_destination.go
@@ -389,9 +389,7 @@ func (rscData *eventoptionsDestinationData) set(
 
 func (rscData *eventoptionsDestinationData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"event-options destinations \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_eventoptions_generate_event.go b/internal/providerfwk/resource_eventoptions_generate_event.go
index 98056b00..3646f2e0 100644
--- a/internal/providerfwk/resource_eventoptions_generate_event.go
+++ b/internal/providerfwk/resource_eventoptions_generate_event.go
@@ -368,9 +368,7 @@ func (rscData *eventoptionsGenerateEventData) set(
 
 func (rscData *eventoptionsGenerateEventData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"event-options generate-event \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_eventoptions_policy.go b/internal/providerfwk/resource_eventoptions_policy.go
index e5065336..071d3a4c 100644
--- a/internal/providerfwk/resource_eventoptions_policy.go
+++ b/internal/providerfwk/resource_eventoptions_policy.go
@@ -1316,8 +1316,8 @@ func (block *eventoptionsPolicyBlockThen) configSet(
 	path.Path, // pathErr
 	error, // error
 ) {
-	setPrefix += "then "
 	configSet := make([]string, 0)
+	setPrefix += "then "
 
 	if block.Ignore.ValueBool() {
 		configSet = append(configSet, setPrefix+"ignore")
@@ -1389,8 +1389,8 @@ func (block *eventoptionsPolicyBlockThenBlockChangeConfigurtion) configSet(
 	path.Path, // pathErr
 	error, // error
 ) {
-	setPrefix += "change-configuration "
 	configSet := make([]string, 0, len(block.Commands))
+	setPrefix += "change-configuration "
 
 	for _, v := range block.Commands {
 		configSet = append(configSet, setPrefix+"commands \""+v.ValueString()+"\"")
@@ -1443,6 +1443,7 @@ func (block *eventoptionsPolicyBlockThenBlockEventScript) configSet(
 	error, // error
 ) {
 	setPrefix += "event-script \"" + block.Filename.ValueString() + "\" "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -1486,8 +1487,8 @@ func (block *eventoptionsPolicyBlockThenBlockExecuteCommands) configSet(
 	path.Path, // pathErr
 	error, // error
 ) {
-	setPrefix += "execute-commands "
 	configSet := make([]string, 0, len(block.Commands))
+	setPrefix += "execute-commands "
 
 	for _, v := range block.Commands {
 		configSet = append(configSet, setPrefix+"commands \""+v.ValueString()+"\"")
@@ -1521,6 +1522,7 @@ func (block *eventoptionsPolicyBlockThenBlockUpload) configSet(
 ) {
 	setPrefix += "upload filename \"" + block.Filename.ValueString() + "\"" +
 		" destination \"" + block.Destination.ValueString() + "\" "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -1558,6 +1560,7 @@ func (block *eventoptionsPolicyBlockThenBlockDestination) configSet(
 	error, // error
 ) {
 	setPrefix += "destination \"" + block.Name.ValueString() + "\" "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -1591,8 +1594,8 @@ func (block *eventoptionsPolicyBlockWithin) configSet(
 	path.Path, // pathErr
 	error, // error
 ) {
-	setPrefix += "within " + utils.ConvI64toa(block.TimeInterval.ValueInt64()) + " "
 	configSet := make([]string, 0)
+	setPrefix += "within " + utils.ConvI64toa(block.TimeInterval.ValueInt64()) + " "
 
 	for _, v := range block.Events {
 		configSet = append(configSet, setPrefix+"events \""+v.ValueString()+"\"")
@@ -1619,9 +1622,7 @@ func (block *eventoptionsPolicyBlockWithin) configSet(
 
 func (rscData *eventoptionsPolicyData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"event-options policy \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_evpn.go b/internal/providerfwk/resource_evpn.go
index 387bdddb..cdd9ddc2 100644
--- a/internal/providerfwk/resource_evpn.go
+++ b/internal/providerfwk/resource_evpn.go
@@ -581,7 +581,11 @@ func (rsc *evpn) ImportState(
 }
 
 func (rscData *evpnData) fillID() {
-	rscData.ID = types.StringValue(rscData.RoutingInstance.ValueString())
+	if v := rscData.RoutingInstance.ValueString(); v != "" {
+		rscData.ID = types.StringValue(v)
+	} else {
+		rscData.ID = types.StringValue(junos.DefaultW)
+	}
 }
 
 func (rscData *evpnData) nullID() bool {
@@ -593,6 +597,7 @@ func (rscData *evpnData) set(
 ) (
 	path.Path, error,
 ) {
+	configSet := make([]string, 0)
 	setPrefix := junos.SetLS
 	setSwitchRIPrefix := junos.SetLS
 	switch routingInstance := rscData.RoutingInstance.ValueString(); routingInstance {
@@ -609,14 +614,12 @@ func (rscData *evpnData) set(
 			return path.Root("default_gateway"),
 				fmt.Errorf("default_gateway cannot be configured when routing_instance = %q", junos.DefaultW)
 		}
-		setPrefix += "protocols evpn "
 		setSwitchRIPrefix += "switch-options "
 	default:
-		setPrefix += junos.RoutingInstancesWS + routingInstance + " protocols evpn "
+		setPrefix += junos.RoutingInstancesWS + routingInstance + " "
 		setSwitchRIPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
-
-	configSet := make([]string, 0)
+	setPrefix += "protocols evpn "
 
 	if rscData.RoutingInstanceEvpn.ValueBool() {
 		if rscData.SwitchOrRIOptions == nil {
@@ -686,31 +689,30 @@ func (rscData *evpnData) set(
 
 func (rscData *evpnData) read(
 	_ context.Context, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showPrefix := junos.CmdShowConfig
-	showSwitchRIPrefix := junos.CmdShowConfig
-	switch routingInstance {
-	case junos.DefaultW, "":
-		showPrefix += "protocols evpn"
-		showSwitchRIPrefix += "switch-options"
-	default:
-		showPrefix += junos.RoutingInstancesWS + routingInstance + " protocols evpn"
-		showSwitchRIPrefix += junos.RoutingInstancesWS + routingInstance
-	}
-
-	showConfig, err := junSess.Command(showPrefix + junos.PipeDisplaySetRelative)
+	showSwitchRI := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+		showSwitchRI += junos.RoutingInstancesWS + routingInstance
+	} else {
+		showSwitchRI += "switch-options"
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols evpn" + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
-	showConfigSwitchRI, err := junSess.Command(showSwitchRIPrefix + junos.PipeDisplaySetRelative)
+	showConfigSwitchRI, err := junSess.Command(showSwitchRI + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
-
 	if showConfig != junos.EmptyW {
-		rscData.RoutingInstance = types.StringValue(routingInstance)
+		if routingInstance == "" {
+			rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+		} else {
+			rscData.RoutingInstance = types.StringValue(routingInstance)
+		}
 		rscData.fillID()
 		for _, item := range strings.Split(showConfig, "\n") {
 			if strings.Contains(item, junos.XMLStartTagConfigOut) {
@@ -801,12 +803,12 @@ func (rscData *evpnData) delOpts(
 	delSwitchRIPrefix := junos.DeleteLS
 	switch routingInstance := rscData.RoutingInstance.ValueString(); routingInstance {
 	case junos.DefaultW, "":
-		delPrefix += "protocols evpn "
 		delSwitchRIPrefix += "switch-options "
 	default:
-		delPrefix += junos.RoutingInstancesWS + routingInstance + " protocols evpn "
+		delPrefix += junos.RoutingInstancesWS + routingInstance + " "
 		delSwitchRIPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
+	delPrefix += "protocols evpn "
 
 	configSet := []string{
 		delPrefix + "default-gateway",
@@ -835,19 +837,18 @@ func (rscData *evpnData) delOpts(
 func (rscData *evpnData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	delLine := junos.DeleteLS
+	delPrefix := junos.DeleteLS
 	delSwitchRIPrefix := junos.DeleteLS
 	switch routingInstance := rscData.RoutingInstance.ValueString(); routingInstance {
 	case junos.DefaultW, "":
-		delLine += "protocols evpn"
 		delSwitchRIPrefix += "switch-options "
 	default:
-		delLine += junos.RoutingInstancesWS + routingInstance + " protocols evpn"
+		delPrefix += junos.RoutingInstancesWS + routingInstance + " "
 		delSwitchRIPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
 
 	configSet := []string{
-		delLine,
+		delPrefix + "protocols evpn",
 	}
 
 	if rscData.RoutingInstanceEvpn.ValueBool() {
diff --git a/internal/providerfwk/resource_firewall_filter.go b/internal/providerfwk/resource_firewall_filter.go
index 52cbb59d..5a0cb512 100644
--- a/internal/providerfwk/resource_firewall_filter.go
+++ b/internal/providerfwk/resource_firewall_filter.go
@@ -1989,9 +1989,7 @@ func (block *firewallFilterBlockTermBlockThen) configSet(setPrefix string) []str
 
 func (rscData *firewallFilterData) read(
 	_ context.Context, name, family string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"firewall family " + family + " filter \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_firewall_policer.go b/internal/providerfwk/resource_firewall_policer.go
index 79d637b9..f0a137a0 100644
--- a/internal/providerfwk/resource_firewall_policer.go
+++ b/internal/providerfwk/resource_firewall_policer.go
@@ -547,7 +547,7 @@ func (rsc *firewallPolicer) ImportState(
 func checkFirewallPolicerExists(
 	_ context.Context, name string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"firewall policer \"" + name + "\"" + junos.PipeDisplaySet)
@@ -629,9 +629,7 @@ func (rscData *firewallPolicerData) set(
 
 func (rscData *firewallPolicerData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"firewall policer \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_forwardingoptions_evpn_vxlan.go b/internal/providerfwk/resource_forwardingoptions_evpn_vxlan.go
index acad3e33..8ac3d290 100644
--- a/internal/providerfwk/resource_forwardingoptions_evpn_vxlan.go
+++ b/internal/providerfwk/resource_forwardingoptions_evpn_vxlan.go
@@ -311,7 +311,7 @@ func (rscData *forwardingoptionsEvpnVxlanData) set(
 	configSet := make([]string, 0)
 	setPrefix := junos.SetLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + v + " "
+		setPrefix += junos.RoutingInstancesWS + v + " "
 	}
 	setPrefix += "forwarding-options evpn-vxlan "
 
@@ -324,14 +324,11 @@ func (rscData *forwardingoptionsEvpnVxlanData) set(
 
 func (rscData *forwardingoptionsEvpnVxlanData) read(
 	_ context.Context, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showPrefix := junos.CmdShowConfig
 	if routingInstance != "" && routingInstance != junos.DefaultW {
 		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
-
 	showConfig, err := junSess.Command(showPrefix +
 		"forwarding-options evpn-vxlan" + junos.PipeDisplaySetRelative)
 	if err != nil {
@@ -366,7 +363,7 @@ func (rscData *forwardingoptionsEvpnVxlanData) del(
 ) error {
 	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + v + " "
+		delPrefix += junos.RoutingInstancesWS + v + " "
 	}
 	delPrefix += "forwarding-options evpn-vxlan "
 
diff --git a/internal/providerfwk/resource_forwardingoptions_sampling.go b/internal/providerfwk/resource_forwardingoptions_sampling.go
index 3ef7b648..d7bba663 100644
--- a/internal/providerfwk/resource_forwardingoptions_sampling.go
+++ b/internal/providerfwk/resource_forwardingoptions_sampling.go
@@ -1377,11 +1377,11 @@ func (rscData *forwardingoptionsSamplingData) set(
 	path.Path, error,
 ) {
 	configSet := make([]string, 0)
-	setPrefix := "set forwarding-options sampling "
-
+	setPrefix := junos.SetLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + v + " forwarding-options sampling "
+		setPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	setPrefix += "forwarding-options sampling "
 
 	if rscData.Disable.ValueBool() {
 		configSet = append(configSet, setPrefix+"disable")
@@ -1824,18 +1824,13 @@ func (block *forwardingoptionsSamplingBlockOutputBlockInterface) configSet(setPr
 
 func (rscData *forwardingoptionsSamplingData) read(
 	_ context.Context, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
-	var showConfig string
+) error {
+	showPrefix := junos.CmdShowConfig
 	if routingInstance != "" && routingInstance != junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			junos.RoutingInstancesWS + routingInstance + " " +
-			"forwarding-options sampling" + junos.PipeDisplaySetRelative)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"forwarding-options sampling" + junos.PipeDisplaySetRelative)
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
+	showConfig, err := junSess.Command(showPrefix +
+		"forwarding-options sampling" + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
@@ -2246,10 +2241,12 @@ func (block *forwardingoptionsSamplingBlockOutputBlockInterface) read(itemTrim s
 func (rscData *forwardingoptionsSamplingData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	delPrefix := "delete forwarding-options sampling "
+	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + v + " forwarding-options sampling "
+		delPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	delPrefix += "forwarding-options sampling "
+
 	configSet := []string{
 		delPrefix + junos.DisableW,
 		delPrefix + "pre-rewrite-tos",
diff --git a/internal/providerfwk/resource_forwardingoptions_sampling_instance.go b/internal/providerfwk/resource_forwardingoptions_sampling_instance.go
index 0dffa07a..26f6b597 100644
--- a/internal/providerfwk/resource_forwardingoptions_sampling_instance.go
+++ b/internal/providerfwk/resource_forwardingoptions_sampling_instance.go
@@ -1292,17 +1292,14 @@ func (rsc *forwardingoptionsSamplingInstance) ImportState(
 func checkForwardingoptionsSamplingInstanceExists(
 	_ context.Context, name, routingInstance string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
-	var showConfig string
+	showPrefix := junos.CmdShowConfig
 	if routingInstance != "" && routingInstance != junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			junos.RoutingInstancesWS + routingInstance + " " +
-			"forwarding-options sampling instance \"" + name + "\"" + junos.PipeDisplaySet)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"forwarding-options sampling instance \"" + name + "\"" + junos.PipeDisplaySet)
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
+	showConfig, err := junSess.Command(showPrefix +
+		"forwarding-options sampling instance \"" + name + "\"" + junos.PipeDisplaySet)
 	if err != nil {
 		return false, err
 	}
@@ -1331,12 +1328,11 @@ func (rscData *forwardingoptionsSamplingInstanceData) set(
 	path.Path, error,
 ) {
 	configSet := make([]string, 0)
-	setPrefix := "set forwarding-options sampling instance \"" + rscData.Name.ValueString() + "\" "
-
+	setPrefix := junos.SetLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + v +
-			" forwarding-options sampling instance \"" + rscData.Name.ValueString() + "\" "
+		setPrefix += junos.RoutingInstancesWS + v + " "
 	}
+	setPrefix += "forwarding-options sampling instance \"" + rscData.Name.ValueString() + "\" "
 
 	if rscData.Disable.ValueBool() {
 		configSet = append(configSet, setPrefix+"disable")
@@ -1762,18 +1758,13 @@ func (block *forwardingoptionsSamplingInstanceBlockOutputBlockInterface) configS
 
 func (rscData *forwardingoptionsSamplingInstanceData) read(
 	_ context.Context, name, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
-	var showConfig string
+) error {
+	showPrefix := junos.CmdShowConfig
 	if routingInstance != "" && routingInstance != junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			junos.RoutingInstancesWS + routingInstance + " " +
-			"forwarding-options sampling instance \"" + name + "\"" + junos.PipeDisplaySetRelative)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"forwarding-options sampling instance \"" + name + "\"" + junos.PipeDisplaySetRelative)
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
+	showConfig, err := junSess.Command(showPrefix +
+		"forwarding-options sampling instance \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
@@ -2153,13 +2144,13 @@ func (block *forwardingoptionsSamplingInstanceBlockOutputBlockInterface) read(it
 func (rscData *forwardingoptionsSamplingInstanceData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	configSet := make([]string, 1)
+	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		configSet[0] = junos.DelRoutingInstances + v +
-			" forwarding-options sampling instance \"" + rscData.Name.ValueString() + "\""
-	} else {
-		configSet[0] = junos.DeleteW +
-			" forwarding-options sampling instance \"" + rscData.Name.ValueString() + "\""
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+
+	configSet := []string{
+		delPrefix + "forwarding-options sampling instance \"" + rscData.Name.ValueString() + "\"",
 	}
 
 	return junSess.ConfigSet(configSet)
diff --git a/internal/providerfwk/resource_forwardingoptions_storm_control_profile.go b/internal/providerfwk/resource_forwardingoptions_storm_control_profile.go
index 01b677ec..ff4258d0 100644
--- a/internal/providerfwk/resource_forwardingoptions_storm_control_profile.go
+++ b/internal/providerfwk/resource_forwardingoptions_storm_control_profile.go
@@ -394,7 +394,7 @@ func (rsc *forwardingoptionsStormControlProfile) ImportState(
 func checkForwardingoptionsStormControlProfileExists(
 	_ context.Context, name string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"forwarding-options storm-control-profiles \"" + name + "\"" + junos.PipeDisplaySet)
@@ -464,9 +464,7 @@ func (rscData *forwardingoptionsStormControlProfileData) set(
 
 func (rscData *forwardingoptionsStormControlProfileData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"forwarding-options storm-control-profiles \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_generate_route.go b/internal/providerfwk/resource_generate_route.go
index 0eaa1e00..d6a936a5 100644
--- a/internal/providerfwk/resource_generate_route.go
+++ b/internal/providerfwk/resource_generate_route.go
@@ -511,7 +511,7 @@ func (rsc *generateRoute) ImportState(
 func checkGenerateRouteExists(
 	_ context.Context, destination, routingInstance string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showPrefix := junos.CmdShowConfig
 	switch routingInstance {
@@ -526,11 +526,11 @@ func checkGenerateRouteExists(
 			showPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
-	showConfig, err := junSess.Command(showPrefix + "generate route " + destination + junos.PipeDisplaySet)
+	showConfig, err := junSess.Command(showPrefix +
+		"generate route " + destination + junos.PipeDisplaySet)
 	if err != nil {
 		return false, err
 	}
-
 	if showConfig == junos.EmptyW {
 		return false, nil
 	}
@@ -569,6 +569,7 @@ func (rscData *generateRouteData) set(
 		}
 	}
 	setPrefix += "generate route " + rscData.Destination.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -624,9 +625,7 @@ func (rscData *generateRouteData) set(
 
 func (rscData *generateRouteData) read(
 	_ context.Context, destination, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showPrefix := junos.CmdShowConfig
 	switch routingInstance {
 	case junos.DefaultW, "":
@@ -640,14 +639,18 @@ func (rscData *generateRouteData) read(
 			showPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
-	showConfig, err := junSess.Command(showPrefix + "generate route " + destination + junos.PipeDisplaySetRelative)
+	showConfig, err := junSess.Command(showPrefix +
+		"generate route " + destination + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
-
 	if showConfig != junos.EmptyW {
 		rscData.Destination = types.StringValue(destination)
-		rscData.RoutingInstance = types.StringValue(routingInstance)
+		if routingInstance == "" {
+			rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+		} else {
+			rscData.RoutingInstance = types.StringValue(routingInstance)
+		}
 		rscData.fillID()
 		for _, item := range strings.Split(showConfig, "\n") {
 			if strings.Contains(item, junos.XMLStartTagConfigOut) {
@@ -720,6 +723,7 @@ func (rscData *generateRouteData) del(
 			delPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
+
 	configSet := []string{
 		delPrefix + "generate route " + rscData.Destination.ValueString(),
 	}
diff --git a/internal/providerfwk/resource_iccp.go b/internal/providerfwk/resource_iccp.go
index b6f3c7bd..4f653541 100644
--- a/internal/providerfwk/resource_iccp.go
+++ b/internal/providerfwk/resource_iccp.go
@@ -223,6 +223,7 @@ func (rscData *iccpData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set protocols iccp "
+
 	configSet := []string{
 		setPrefix + "local-ip-addr " + rscData.LocalIPAddr.ValueString(),
 	}
@@ -240,15 +241,12 @@ func (rscData *iccpData) set(
 
 func (rscData *iccpData) read(
 	_ context.Context, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"protocols iccp" + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
-
 	if showConfig != junos.EmptyW {
 		rscData.fillID()
 		for _, item := range strings.Split(showConfig, "\n") {
diff --git a/internal/providerfwk/resource_iccp_peer.go b/internal/providerfwk/resource_iccp_peer.go
index c00a9be4..ced93360 100644
--- a/internal/providerfwk/resource_iccp_peer.go
+++ b/internal/providerfwk/resource_iccp_peer.go
@@ -518,9 +518,7 @@ func (rscData *iccpPeerData) set(
 
 func (rscData *iccpPeerData) read(
 	_ context.Context, ipAddress string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"protocols iccp peer " + ipAddress + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_interface_logical.go b/internal/providerfwk/resource_interface_logical.go
index da9f5062..74291047 100644
--- a/internal/providerfwk/resource_interface_logical.go
+++ b/internal/providerfwk/resource_interface_logical.go
@@ -130,6 +130,14 @@ func (rsc *interfaceLogical) Schema(
 					tfvalidator.BoolTrue(),
 				},
 			},
+			"encapsulation": schema.StringAttribute{
+				Optional:    true,
+				Description: "Logical link-layer encapsulation.",
+				Validators: []validator.String{
+					stringvalidator.LengthAtLeast(1),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
 			"routing_instance": schema.StringAttribute{
 				Optional:    true,
 				Description: "Add this interface in routing_instance.",
@@ -1017,6 +1025,7 @@ type interfaceLogicalData struct {
 	St0AlsoOnDestroy         types.Bool                        `tfsdk:"st0_also_on_destroy"`
 	Description              types.String                      `tfsdk:"description"`
 	Disable                  types.Bool                        `tfsdk:"disable"`
+	Encapsulation            types.String                      `tfsdk:"encapsulation"`
 	RoutingInstance          types.String                      `tfsdk:"routing_instance"`
 	SecurityInboundProtocols []types.String                    `tfsdk:"security_inbound_protocols"`
 	SecurityInboundServices  []types.String                    `tfsdk:"security_inbound_services"`
@@ -1034,6 +1043,7 @@ type interfaceLogicalConfig struct {
 	St0AlsoOnDestroy         types.Bool                              `tfsdk:"st0_also_on_destroy"`
 	Description              types.String                            `tfsdk:"description"`
 	Disable                  types.Bool                              `tfsdk:"disable"`
+	Encapsulation            types.String                            `tfsdk:"encapsulation"`
 	RoutingInstance          types.String                            `tfsdk:"routing_instance"`
 	SecurityInboundProtocols types.Set                               `tfsdk:"security_inbound_protocols"`
 	SecurityInboundServices  types.Set                               `tfsdk:"security_inbound_services"`
@@ -2291,6 +2301,7 @@ func (rscData *interfaceLogicalData) set(
 	}
 
 	setPrefix := "set interfaces " + rscData.Name.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -2305,6 +2316,9 @@ func (rscData *interfaceLogicalData) set(
 		}
 		configSet = append(configSet, setPrefix+"disable")
 	}
+	if v := rscData.Encapsulation.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"encapsulation "+v)
+	}
 	if rscData.FamilyInet != nil {
 		configSet = append(configSet, setPrefix+"family inet")
 
@@ -2405,7 +2419,7 @@ func (rscData *interfaceLogicalData) set(
 		}
 	}
 	if v := rscData.RoutingInstance.ValueString(); v != "" {
-		configSet = append(configSet, junos.SetRoutingInstances+v+" interface "+rscData.Name.ValueString())
+		configSet = append(configSet, junos.SetLS+junos.RoutingInstancesWS+v+" interface "+rscData.Name.ValueString())
 	}
 	if securityZone := rscData.SecurityZone.ValueString(); securityZone != "" {
 		configSet = append(configSet, "set security zones security-zone "+securityZone+
@@ -2466,6 +2480,7 @@ func (block *interfaceLogicalBlockFamilyInetBlockAddress) configSet(
 	error, // error
 ) {
 	setPrefix += "family inet address " + block.CidrIP.ValueString()
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -2569,6 +2584,7 @@ func (block *interfaceLogicalBlockFamilyInet6BlockAddress) configSet(
 	error, // error
 ) {
 	setPrefix += "family inet6 address " + block.CidrIP.ValueString()
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -2668,6 +2684,7 @@ func (block *interfaceLogicalBlockFamilyInetBlockDhcp) configSet(setPrefix strin
 	} else {
 		setPrefix += " "
 	}
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -2736,6 +2753,7 @@ func (block *interfaceLogicalBlockFamilyInetBlockDhcp) configSet(setPrefix strin
 
 func (block *interfaceLogicalBlockFamilyInet6BlockDhcpV6Client) configSet(setPrefix string) []string {
 	setPrefix += "family inet6 dhcpv6-client "
+
 	configSet := []string{
 		setPrefix + "client-identifier duid-type " + block.ClientIdentifierDuidType.ValueString(),
 		setPrefix + "client-type " + block.ClientType.ValueString(),
@@ -2786,7 +2804,6 @@ func (rscData *interfaceLogicalData) read(
 	if err != nil {
 		return err
 	}
-
 	rscData.Name = types.StringValue(name)
 	rscData.fillID()
 	if showConfig != junos.EmptyW {
@@ -2807,6 +2824,8 @@ func (rscData *interfaceLogicalData) read(
 				rscData.Description = types.StringValue(strings.Trim(itemTrim, "\""))
 			case itemTrim == "disable":
 				rscData.Disable = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "encapsulation "):
+				rscData.Encapsulation = types.StringValue(itemTrim)
 			case balt.CutPrefixInString(&itemTrim, "family inet6"):
 				if rscData.FamilyInet6 == nil {
 					rscData.FamilyInet6 = &interfaceLogicalBlockFamilyInet6{}
@@ -3288,7 +3307,6 @@ func (rscData *interfaceLogicalData) readSecurityZoneInboundTraffic(
 	if err != nil {
 		return err
 	}
-
 	if showConfig != junos.EmptyW {
 		for _, item := range strings.Split(showConfig, "\n") {
 			if strings.Contains(item, junos.XMLStartTagConfigOut) {
@@ -3345,9 +3363,11 @@ func (rscData *interfaceLogicalData) delOpts(
 	_ context.Context, junSess *junos.Session,
 ) error {
 	delPrefix := "delete interfaces " + rscData.Name.ValueString() + " "
+
 	configSet := []string{
 		delPrefix + "description",
 		delPrefix + "disable",
+		delPrefix + "encapsulation",
 		delPrefix + "family inet",
 		delPrefix + "family inet6",
 		delPrefix + "tunnel",
@@ -3372,7 +3392,7 @@ func (rscData *interfaceLogicalData) delRoutingInstance(
 	_ context.Context, junSess *junos.Session,
 ) error {
 	configSet := []string{
-		junos.DelRoutingInstances + rscData.RoutingInstance.ValueString() +
+		junos.DeleteLS + junos.RoutingInstancesWS + rscData.RoutingInstance.ValueString() +
 			" interface " + rscData.Name.ValueString(),
 	}
 
diff --git a/internal/providerfwk/resource_interface_physical.go b/internal/providerfwk/resource_interface_physical.go
index 6736cdb5..8b8e6662 100644
--- a/internal/providerfwk/resource_interface_physical.go
+++ b/internal/providerfwk/resource_interface_physical.go
@@ -1770,6 +1770,7 @@ func (rscData *interfacePhysicalData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set interfaces " + rscData.Name.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -1962,7 +1963,6 @@ func (block *interfacePhysicalBlockParentEtherOpts) configSet(
 	error, // error
 ) {
 	configSet := make([]string, 0)
-
 	switch {
 	case strings.HasPrefix(interfaceName, "ae"):
 		setPrefix += "aggregated-ether-options "
@@ -2162,7 +2162,6 @@ func (rscData *interfacePhysicalData) read(
 	if err != nil {
 		return err
 	}
-
 	rscData.Name = types.StringValue(name)
 	rscData.fillID()
 	if showConfig != junos.EmptyW {
diff --git a/internal/providerfwk/resource_multichassis.go b/internal/providerfwk/resource_multichassis.go
index 816d101d..8ccd64d0 100644
--- a/internal/providerfwk/resource_multichassis.go
+++ b/internal/providerfwk/resource_multichassis.go
@@ -264,6 +264,7 @@ func (rscData *multichassisData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set multi-chassis "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -281,15 +282,12 @@ func (rscData *multichassisData) set(
 
 func (rscData *multichassisData) read(
 	_ context.Context, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"multi-chassis" + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
-
 	if showConfig != junos.EmptyW {
 		rscData.fillID()
 		for _, item := range strings.Split(showConfig, "\n") {
diff --git a/internal/providerfwk/resource_multichassis_protection_peer.go b/internal/providerfwk/resource_multichassis_protection_peer.go
index dbb2e8ef..72c22fce 100644
--- a/internal/providerfwk/resource_multichassis_protection_peer.go
+++ b/internal/providerfwk/resource_multichassis_protection_peer.go
@@ -287,6 +287,7 @@ func (rscData *multichassisProtectionPeerData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set multi-chassis multi-chassis-protection " + rscData.IPAddress.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 		setPrefix + "interface " + rscData.Interface.ValueString(),
@@ -302,9 +303,7 @@ func (rscData *multichassisProtectionPeerData) set(
 
 func (rscData *multichassisProtectionPeerData) read(
 	_ context.Context, ipAddress string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"multi-chassis multi-chassis-protection " + ipAddress + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_oam_gretunnel_interface.go b/internal/providerfwk/resource_oam_gretunnel_interface.go
index 97d1c64e..7e46566f 100644
--- a/internal/providerfwk/resource_oam_gretunnel_interface.go
+++ b/internal/providerfwk/resource_oam_gretunnel_interface.go
@@ -313,6 +313,7 @@ func (rscData *oamGretunnelInterfaceData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set protocols oam gre-tunnel interface " + rscData.Name.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -331,9 +332,7 @@ func (rscData *oamGretunnelInterfaceData) set(
 
 func (rscData *oamGretunnelInterfaceData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"protocols oam gre-tunnel interface " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_ospf.go b/internal/providerfwk/resource_ospf.go
index 8762ebaf..31f1482f 100644
--- a/internal/providerfwk/resource_ospf.go
+++ b/internal/providerfwk/resource_ospf.go
@@ -806,10 +806,9 @@ func (rscData *ospfData) set(
 ) {
 	configSet := make([]string, 0)
 	setPrefix := junos.SetLS
-
 	routingInstance := rscData.RoutingInstance.ValueString()
 	if routingInstance != "" && routingInstance != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + routingInstance + " "
+		setPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
 	ospfVersion := junos.OspfV2
 	if rscData.Version.ValueString() == "v3" {
@@ -910,6 +909,7 @@ func (rscData *ospfData) set(
 
 func (block *ospfBlockDatabaseProtection) configSet(setPrefix string) []string {
 	setPrefix += "database-protection "
+
 	configSet := []string{
 		setPrefix + "maximum-lsa " + utils.ConvI64toa(block.MaximumLsa.ValueInt64()),
 	}
@@ -978,6 +978,7 @@ func (block *ospfBlockGracefulRestart) configSet(
 
 func (block *ospfBlockOverload) configSet(setPrefix string) []string {
 	setPrefix += "overload "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -1024,30 +1025,30 @@ func (block *ospfBlockSpfOptions) configSet(setPrefix string) []string {
 
 func (rscData *ospfData) read(
 	_ context.Context, version, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
-	var showConfig string
+) error {
 	ospfVersion := junos.OspfV2
 	if version == "v3" {
 		ospfVersion = junos.OspfV3
 	}
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols " + ospfVersion + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols " + ospfVersion + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
+	if version == "v3" {
+		rscData.Version = types.StringValue(version)
 	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols " + ospfVersion + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
+		rscData.Version = types.StringValue("v2")
+	}
+	if routingInstance == "" {
+		rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+	} else {
+		rscData.RoutingInstance = types.StringValue(routingInstance)
 	}
-
-	rscData.Version = types.StringValue(version)
-	rscData.RoutingInstance = types.StringValue(routingInstance)
 	rscData.fillID()
 	if showConfig != junos.EmptyW {
 		for _, item := range strings.Split(showConfig, "\n") {
@@ -1259,7 +1260,7 @@ func (rscData *ospfData) del(
 	}
 	delPrefix := junos.DeleteLS
 	if v := rscData.RoutingInstance.ValueString(); v != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + v + " "
+		delPrefix += junos.RoutingInstancesWS + v + " "
 	}
 	delPrefix += "protocols " + ospfVersion + " "
 
@@ -1284,6 +1285,7 @@ func (rscData *ospfData) del(
 		"sham-link",
 		"spf-options",
 	}
+
 	configSet := make([]string, len(listLinesToDelete))
 	for k, line := range listLinesToDelete {
 		configSet[k] = delPrefix + line
diff --git a/internal/providerfwk/resource_ospf_area.go b/internal/providerfwk/resource_ospf_area.go
index c004a06f..fb47c516 100644
--- a/internal/providerfwk/resource_ospf_area.go
+++ b/internal/providerfwk/resource_ospf_area.go
@@ -1697,41 +1697,28 @@ func (rsc *ospfArea) ImportState(
 func checkOspfAreaExists(
 	_ context.Context, areaID, version, realm, routingInstance string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
-	var showConfig string
-	ospfVersion := junos.OspfV2
-	if version == "v3" {
-		ospfVersion = junos.OspfV3
-	} else if realm != "" {
-		return false, errors.New("realm can't set if version != v3")
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
-	switch {
-	case (routingInstance == junos.DefaultW || routingInstance == "") && realm == "":
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols " + ospfVersion + " area " + areaID + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
-	case (routingInstance == junos.DefaultW || routingInstance == "") && realm != "":
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols " + ospfVersion + " realm " + realm + " area " + areaID + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
-	case realm != "":
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols " + ospfVersion + " realm " + realm + " area " + areaID + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
-	default:
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols " + ospfVersion + " area " + areaID + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
+	if version == "v3" {
+		showPrefix += "protocols " + junos.OspfV3 + " "
+	} else {
+		showPrefix += "protocols " + junos.OspfV2 + " "
+		if realm != "" {
+			return false, errors.New("realm can't set if version != v3")
 		}
 	}
+	if realm != "" {
+		showPrefix += "realm " + realm + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"area " + areaID + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
+	}
 	if showConfig == junos.EmptyW {
 		return false, nil
 	}
@@ -1772,15 +1759,16 @@ func (rscData *ospfAreaData) set(
 	configSet := make([]string, 0)
 	setPrefix := junos.SetLS
 	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + v + " "
+		setPrefix += junos.RoutingInstancesWS + v + " "
 	}
-	ospfVersion := junos.OspfV2
 	if rscData.Version.ValueString() == "v3" {
-		ospfVersion = junos.OspfV3
-	} else if rscData.Realm.ValueString() != "" {
-		return path.Root("realm"), errors.New("realm can't set if version != v3")
+		setPrefix += "protocols " + junos.OspfV3 + " "
+	} else {
+		setPrefix += "protocols " + junos.OspfV2 + " "
+		if rscData.Realm.ValueString() != "" {
+			return path.Root("realm"), errors.New("realm can't set if version != v3")
+		}
 	}
-	setPrefix += "protocols " + ospfVersion + " "
 	if v := rscData.Realm.ValueString(); v != "" {
 		setPrefix += "realm " + v + " "
 	}
@@ -1876,6 +1864,7 @@ func (block *ospfAreaBlockInterface) configSet(
 	error, // error
 ) {
 	setPrefix += "interface " + block.Name.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -2135,6 +2124,7 @@ func (block *ospfAreaBlockInterfaceBlockBfdLivenessDetection) configSet(setPrefi
 
 func (block *ospfAreaBlockAreaRange) configSet(setPrefix string) []string {
 	setPrefix += "area-range " + block.Range.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -2161,6 +2151,7 @@ func (block *ospfAreaBlockNssa) configSet(
 	error, // error
 ) {
 	setPrefix += "nssa "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -2208,6 +2199,7 @@ func (block *ospfAreaBlockVirtualLink) configSet(setPrefix string) []string {
 		" neighbor-id " + block.NeighborID.ValueString() +
 		" transit-area " + block.TransitArea.ValueString() +
 		" "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -2250,43 +2242,27 @@ func (block *ospfAreaBlockVirtualLink) configSet(setPrefix string) []string {
 
 func (rscData *ospfAreaData) read(
 	_ context.Context, areaID, version, realm, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
-	var showConfig string
-	ospfVersion := junos.OspfV2
-	if version == "v3" {
-		ospfVersion = junos.OspfV3
-	} else if realm != "" {
-		return errors.New("realm can't set if version != v3")
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
-	switch {
-	case (routingInstance == junos.DefaultW || routingInstance == "") && realm == "":
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols " + ospfVersion + " area " + areaID + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
-	case (routingInstance == junos.DefaultW || routingInstance == "") && realm != "":
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols " + ospfVersion + " realm " + realm + " area " + areaID + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
-	case realm != "":
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols " + ospfVersion + " realm " + realm + " area " + areaID + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
-		}
-	default:
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols " + ospfVersion + " area " + areaID + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return err
+	if version == "v3" {
+		showPrefix += "protocols " + junos.OspfV3 + " "
+	} else {
+		showPrefix += "protocols " + junos.OspfV2 + " "
+		if realm != "" {
+			return errors.New("realm can't set if version != v3")
 		}
 	}
-
+	if realm != "" {
+		showPrefix += "realm " + realm + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"area " + areaID + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
 	if showConfig != junos.EmptyW {
 		rscData.AreaID = types.StringValue(areaID)
 		if version == "v3" {
@@ -2707,31 +2683,24 @@ func (block *ospfAreaBlockNssa) read(itemTrim string) (err error) {
 func (rscData *ospfAreaData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	configSet := make([]string, 0, 1)
-	ospfVersion := junos.OspfV2
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
 	if rscData.Version.ValueString() == "v3" {
-		ospfVersion = junos.OspfV3
-	} else if rscData.Realm.ValueString() != "" {
-		return errors.New("realm can't set if version != v3")
+		delPrefix += "protocols " + junos.OspfV3 + " "
+	} else {
+		delPrefix += "protocols " + junos.OspfV2 + " "
+		if rscData.Realm.ValueString() != "" {
+			return errors.New("realm can't set if version != v3")
+		}
 	}
-	routingInstance := junos.DefaultW
-	if v := rscData.RoutingInstance.ValueString(); v != "" {
-		routingInstance = v
+	if v := rscData.Realm.ValueString(); v != "" {
+		delPrefix += "realm " + v + " "
 	}
-	realm := rscData.Realm.ValueString()
-	switch {
-	case (routingInstance == junos.DefaultW || routingInstance == "") && realm == "":
-		configSet = append(configSet, junos.DeleteW+
-			" protocols "+ospfVersion+" area "+rscData.AreaID.ValueString())
-	case (routingInstance == junos.DefaultW || routingInstance == "") && realm != "":
-		configSet = append(configSet, junos.DeleteW+
-			" protocols "+ospfVersion+" realm "+realm+" area "+rscData.AreaID.ValueString())
-	case realm != "":
-		configSet = append(configSet, junos.DelRoutingInstances+routingInstance+
-			" protocols "+ospfVersion+" realm "+realm+" area "+rscData.AreaID.ValueString())
-	default:
-		configSet = append(configSet, junos.DelRoutingInstances+routingInstance+
-			" protocols "+ospfVersion+" area "+rscData.AreaID.ValueString())
+
+	configSet := []string{
+		delPrefix + "area " + rscData.AreaID.ValueString(),
 	}
 
 	return junSess.ConfigSet(configSet)
diff --git a/internal/providerfwk/resource_policyoptions_as_path.go b/internal/providerfwk/resource_policyoptions_as_path.go
index 9a4b809f..8a52df50 100644
--- a/internal/providerfwk/resource_policyoptions_as_path.go
+++ b/internal/providerfwk/resource_policyoptions_as_path.go
@@ -318,9 +318,7 @@ func (rscData *policyoptionsASPathData) set(
 
 func (rscData *policyoptionsASPathData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"policy-options as-path \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_policyoptions_as_path_group.go b/internal/providerfwk/resource_policyoptions_as_path_group.go
index f6b3c119..930647c5 100644
--- a/internal/providerfwk/resource_policyoptions_as_path_group.go
+++ b/internal/providerfwk/resource_policyoptions_as_path_group.go
@@ -385,9 +385,7 @@ func (rscData *policyoptionsASPathGroupData) set(
 
 func (rscData *policyoptionsASPathGroupData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"policy-options as-path-group \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_policyoptions_community.go b/internal/providerfwk/resource_policyoptions_community.go
index 3e1c57be..1599b9bd 100644
--- a/internal/providerfwk/resource_policyoptions_community.go
+++ b/internal/providerfwk/resource_policyoptions_community.go
@@ -351,9 +351,7 @@ func (rscData *policyoptionsCommunityData) set(
 
 func (rscData *policyoptionsCommunityData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"policy-options community \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_policyoptions_policy_statement.go b/internal/providerfwk/resource_policyoptions_policy_statement.go
index c8d8f825..e0301523 100644
--- a/internal/providerfwk/resource_policyoptions_policy_statement.go
+++ b/internal/providerfwk/resource_policyoptions_policy_statement.go
@@ -1804,7 +1804,7 @@ func (rsc *policyoptionsPolicyStatement) ImportState(
 func checkPolicyoptionsPolicyStatementExists(
 	_ context.Context, name string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"policy-options policy-statement \"" + name + "\"" + junos.PipeDisplaySet)
@@ -2236,9 +2236,7 @@ func (block *policyoptionsPolicyStatementBlockThen) configSet(
 
 func (rscData *policyoptionsPolicyStatementData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"policy-options policy-statement \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_policyoptions_prefix_list.go b/internal/providerfwk/resource_policyoptions_prefix_list.go
index a564606c..fa004294 100644
--- a/internal/providerfwk/resource_policyoptions_prefix_list.go
+++ b/internal/providerfwk/resource_policyoptions_prefix_list.go
@@ -317,9 +317,7 @@ func (rscData *policyoptionsPrefixListData) set(
 
 func (rscData *policyoptionsPrefixListData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"policy-options prefix-list \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_routing_instance.go b/internal/providerfwk/resource_routing_instance.go
index c0da3dbc..618d3cd9 100644
--- a/internal/providerfwk/resource_routing_instance.go
+++ b/internal/providerfwk/resource_routing_instance.go
@@ -11,6 +11,7 @@ import (
 	"github.com/jeremmfr/terraform-provider-junos/internal/tfvalidator"
 
 	"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
 	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
 	"github.com/hashicorp/terraform-plugin-framework/path"
 	"github.com/hashicorp/terraform-plugin-framework/resource"
@@ -169,6 +170,28 @@ func (rsc *routingInstance) Schema(
 					),
 				},
 			},
+			"remote_vtep_list": schema.SetAttribute{
+				ElementType: types.StringType,
+				Optional:    true,
+				Description: "Configure static remote VXLAN tunnel endpoints.",
+				Validators: []validator.Set{
+					setvalidator.SizeAtLeast(1),
+					setvalidator.ValueStringsAre(
+						tfvalidator.StringIPAddress().IPv4Only(),
+					),
+				},
+			},
+			"remote_vtep_v6_list": schema.SetAttribute{
+				ElementType: types.StringType,
+				Optional:    true,
+				Description: "Configure static ipv6 remote VXLAN tunnel endpoints.",
+				Validators: []validator.Set{
+					setvalidator.SizeAtLeast(1),
+					setvalidator.ValueStringsAre(
+						tfvalidator.StringIPAddress().IPv6Only(),
+					),
+				},
+			},
 			"route_distinguisher": schema.StringAttribute{
 				Optional:    true,
 				Description: "Route distinguisher for this instance.",
@@ -270,6 +293,8 @@ type routingInstanceData struct {
 	Description             types.String   `tfsdk:"description"`
 	InstanceExport          []types.String `tfsdk:"instance_export"`
 	InstanceImport          []types.String `tfsdk:"instance_import"`
+	RemoteVtepList          []types.String `tfsdk:"remote_vtep_list"`
+	RemoteVtepV6List        []types.String `tfsdk:"remote_vtep_v6_list"`
 	RouteDistinguisher      types.String   `tfsdk:"route_distinguisher"`
 	RouterID                types.String   `tfsdk:"router_id"`
 	VRFExport               []types.String `tfsdk:"vrf_export"`
@@ -292,6 +317,8 @@ type routingInstanceConfig struct {
 	Description             types.String `tfsdk:"description"`
 	InstanceExport          types.List   `tfsdk:"instance_export"`
 	InstanceImport          types.List   `tfsdk:"instance_import"`
+	RemoteVtepList          types.Set    `tfsdk:"remote_vtep_list"`
+	RemoteVtepV6List        types.Set    `tfsdk:"remote_vtep_v6_list"`
 	RouteDistinguisher      types.String `tfsdk:"route_distinguisher"`
 	RouterID                types.String `tfsdk:"router_id"`
 	VRFExport               types.List   `tfsdk:"vrf_export"`
@@ -536,7 +563,7 @@ func (rscData *routingInstanceData) set(
 	path.Path, error,
 ) {
 	configSet := make([]string, 0)
-	setPrefix := junos.SetRoutingInstances + rscData.Name.ValueString() + " "
+	setPrefix := junos.SetLS + junos.RoutingInstancesWS + rscData.Name.ValueString() + " "
 
 	if rscData.ConfigureTypeSingly.ValueBool() {
 		if rscData.Type.ValueString() != "" {
@@ -586,6 +613,12 @@ func (rscData *routingInstanceData) set(
 	for _, v := range rscData.InstanceImport {
 		configSet = append(configSet, setPrefix+junos.RoutingOptionsWS+"instance-import \""+v.ValueString()+"\"")
 	}
+	for _, v := range rscData.RemoteVtepList {
+		configSet = append(configSet, setPrefix+"remote-vtep-list "+v.ValueString())
+	}
+	for _, v := range rscData.RemoteVtepV6List {
+		configSet = append(configSet, setPrefix+"remote-vtep-v6-list "+v.ValueString())
+	}
 	if v := rscData.VTEPSourceInterface.ValueString(); v != "" {
 		configSet = append(configSet, setPrefix+"vtep-source-interface "+v)
 	}
@@ -595,9 +628,7 @@ func (rscData *routingInstanceData) set(
 
 func (rscData *routingInstanceData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		junos.RoutingInstancesWS + name + junos.PipeDisplaySetRelative)
 	if err != nil {
@@ -619,6 +650,10 @@ func (rscData *routingInstanceData) read(
 				rscData.Description = types.StringValue(strings.Trim(itemTrim, "\""))
 			case balt.CutPrefixInString(&itemTrim, "instance-type "):
 				rscData.Type = types.StringValue(itemTrim)
+			case balt.CutPrefixInString(&itemTrim, "remote-vtep-list "):
+				rscData.RemoteVtepList = append(rscData.RemoteVtepList, types.StringValue(itemTrim))
+			case balt.CutPrefixInString(&itemTrim, "remote-vtep-v6-list "):
+				rscData.RemoteVtepV6List = append(rscData.RemoteVtepV6List, types.StringValue(itemTrim))
 			case balt.CutPrefixInString(&itemTrim, "route-distinguisher "):
 				rscData.RouteDistinguisher = types.StringValue(itemTrim)
 			case balt.CutPrefixInString(&itemTrim, junos.RoutingOptionsWS+"autonomous-system "):
@@ -660,25 +695,27 @@ func (rscData *routingInstanceData) read(
 func (rscData *routingInstanceData) delOpts(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	configSet := make([]string, 0)
-	setPrefix := junos.DelRoutingInstances + rscData.Name.ValueString() + " "
+	configSet := make([]string, 0, 50)
+	delPrefix := junos.DeleteLS + junos.RoutingInstancesWS + rscData.Name.ValueString() + " "
 	configSet = append(configSet,
-		setPrefix+"description",
-		setPrefix+junos.RoutingOptionsWS+"autonomous-system",
-		setPrefix+junos.RoutingOptionsWS+"instance-export",
-		setPrefix+junos.RoutingOptionsWS+"instance-import",
-		setPrefix+junos.RoutingOptionsWS+"router-id",
-		setPrefix+"vtep-source-interface",
+		delPrefix+"description",
+		delPrefix+junos.RoutingOptionsWS+"autonomous-system",
+		delPrefix+junos.RoutingOptionsWS+"instance-export",
+		delPrefix+junos.RoutingOptionsWS+"instance-import",
+		delPrefix+"remote-vtep-list",
+		delPrefix+"remote-vtep-v6-list",
+		delPrefix+junos.RoutingOptionsWS+"router-id",
+		delPrefix+"vtep-source-interface",
 	)
 	if !rscData.ConfigureTypeSingly.ValueBool() {
-		configSet = append(configSet, setPrefix+"instance-type")
+		configSet = append(configSet, delPrefix+"instance-type")
 	}
 	if !rscData.ConfigureRDVrfOptSingly.ValueBool() {
 		configSet = append(configSet,
-			setPrefix+"route-distinguisher",
-			setPrefix+"vrf-export",
-			setPrefix+"vrf-import",
-			setPrefix+"vrf_target",
+			delPrefix+"route-distinguisher",
+			delPrefix+"vrf-export",
+			delPrefix+"vrf-import",
+			delPrefix+"vrf_target",
 		)
 	}
 
@@ -689,7 +726,7 @@ func (rscData *routingInstanceData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
 	configSet := []string{
-		junos.DelRoutingInstances + rscData.Name.ValueString(),
+		junos.DeleteLS + junos.RoutingInstancesWS + rscData.Name.ValueString(),
 	}
 
 	return junSess.ConfigSet(configSet)
diff --git a/internal/providerfwk/resource_rstp.go b/internal/providerfwk/resource_rstp.go
new file mode 100644
index 00000000..70a08762
--- /dev/null
+++ b/internal/providerfwk/resource_rstp.go
@@ -0,0 +1,745 @@
+package providerfwk
+
+import (
+	"context"
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdata"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdiag"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfvalidator"
+	"github.com/jeremmfr/terraform-provider-junos/internal/utils"
+
+	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+	"github.com/hashicorp/terraform-plugin-framework/path"
+	"github.com/hashicorp/terraform-plugin-framework/resource"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+	balt "github.com/jeremmfr/go-utils/basicalter"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+	_ resource.Resource                   = &rstp{}
+	_ resource.ResourceWithConfigure      = &rstp{}
+	_ resource.ResourceWithValidateConfig = &rstp{}
+	_ resource.ResourceWithImportState    = &rstp{}
+)
+
+type rstp struct {
+	client *junos.Client
+}
+
+func newRstpResource() resource.Resource {
+	return &rstp{}
+}
+
+func (rsc *rstp) typeName() string {
+	return providerName + "_rstp"
+}
+
+func (rsc *rstp) junosName() string {
+	return "protocols rstp"
+}
+
+func (rsc *rstp) junosClient() *junos.Client {
+	return rsc.client
+}
+
+func (rsc *rstp) Metadata(
+	_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse,
+) {
+	resp.TypeName = rsc.typeName()
+}
+
+func (rsc *rstp) Configure(
+	ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse,
+) {
+	// Prevent panic if the provider has not been configured.
+	if req.ProviderData == nil {
+		return
+	}
+	client, ok := req.ProviderData.(*junos.Client)
+	if !ok {
+		unexpectedResourceConfigureType(ctx, req, resp)
+
+		return
+	}
+	rsc.client = client
+}
+
+func (rsc *rstp) Schema(
+	_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse,
+) {
+	resp.Schema = schema.Schema{
+		Description: "Configure static configuration in `" + rsc.junosName() + "` block",
+		Attributes: map[string]schema.Attribute{
+			"id": schema.StringAttribute{
+				Computed:    true,
+				Description: "An identifier for the resource with format `<routing_instance>`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.UseStateForUnknown(),
+				},
+			},
+			"routing_instance": schema.StringAttribute{
+				Optional:    true,
+				Computed:    true,
+				Default:     stringdefault.StaticString(junos.DefaultW),
+				Description: "Routing instance for rstp protocol if not root level.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+			"backup_bridge_priority": schema.StringAttribute{
+				Optional:    true,
+				Description: "Priority of the bridge.",
+				Validators: []validator.String{
+					stringvalidator.RegexMatches(regexp.MustCompile(
+						`^\d\d?k$`),
+						"must be a number with increments of 4k - 4k,8k,..60k",
+					),
+				},
+			},
+			"bpdu_block_on_edge": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Block BPDU on all interfaces configured as edge (BPDU Protect).",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"bpdu_destination_mac_address_provider_bridge_group": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Destination MAC address in the spanning tree BPDUs is 802.1ad provider bridge group address.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"bridge_priority": schema.StringAttribute{
+				Optional:    true,
+				Description: "Priority of the bridge.",
+				Validators: []validator.String{
+					stringvalidator.RegexMatches(regexp.MustCompile(
+						`^(0|\d\d?k)$`),
+						"must be a number with increments of 4k - 0,4k,8k,..60k",
+					),
+				},
+			},
+			"disable": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Disable STP.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"extended_system_id": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Extended system identifier.",
+				Validators: []validator.Int64{
+					int64validator.Between(0, 4095),
+				},
+			},
+			"force_version_stp": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Force protocol version STP.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"forward_delay": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Time spent in listening or learning state (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(4, 30),
+				},
+			},
+			"hello_time": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Time interval between configuration BPDUs (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(1, 10),
+				},
+			},
+			"max_age": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Maximum age of received protocol bpdu (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(6, 40),
+				},
+			},
+			"priority_hold_time": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Hold time before switching to primary priority when core domain becomes up (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(1, 255),
+				},
+			},
+			"system_identifier": schema.StringAttribute{
+				Optional:    true,
+				Description: "System identifier to represent this node.",
+				Validators: []validator.String{
+					tfvalidator.StringMACAddress().WithMac48ColonHexa(),
+				},
+			},
+			"vpls_flush_on_topology_change": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Enable VPLS MAC flush on root protected CE interface receiving topology change.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+		},
+		Blocks: map[string]schema.Block{
+			"system_id": schema.SetNestedBlock{
+				Description: "For each ID, System ID to IP mapping.",
+				NestedObject: schema.NestedBlockObject{
+					Attributes: map[string]schema.Attribute{
+						"id": schema.StringAttribute{
+							Required:    true,
+							Description: "System ID.",
+							Validators: []validator.String{
+								tfvalidator.StringMACAddress().WithMac48ColonHexa(),
+							},
+						},
+						"ip_address": schema.StringAttribute{
+							Optional:    true,
+							Description: "Peer ID (IP Address).",
+							Validators: []validator.String{
+								tfvalidator.StringCIDR(),
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+//nolint:lll
+type rstpData struct {
+	ID                                           types.String        `tfsdk:"id"`
+	RoutingInstance                              types.String        `tfsdk:"routing_instance"`
+	BackupBridgePriority                         types.String        `tfsdk:"backup_bridge_priority"`
+	BpduBlockOnEdge                              types.Bool          `tfsdk:"bpdu_block_on_edge"`
+	BpduDestinationMacAddressProviderBridgeGroup types.Bool          `tfsdk:"bpdu_destination_mac_address_provider_bridge_group"`
+	BridgePriority                               types.String        `tfsdk:"bridge_priority"`
+	Disable                                      types.Bool          `tfsdk:"disable"`
+	ExtendedSystemID                             types.Int64         `tfsdk:"extended_system_id"`
+	ForceVersionStp                              types.Bool          `tfsdk:"force_version_stp"`
+	ForwardDelay                                 types.Int64         `tfsdk:"forward_delay"`
+	HelloTime                                    types.Int64         `tfsdk:"hello_time"`
+	MaxAge                                       types.Int64         `tfsdk:"max_age"`
+	PriorityHoldTime                             types.Int64         `tfsdk:"priority_hold_time"`
+	SystemIdentifier                             types.String        `tfsdk:"system_identifier"`
+	VplsFlushOnTopologyChange                    types.Bool          `tfsdk:"vpls_flush_on_topology_change"`
+	SystemID                                     []rstpBlockSystemID `tfsdk:"system_id"`
+}
+
+type rstpConfig struct {
+	ID                                           types.String `tfsdk:"id"`
+	RoutingInstance                              types.String `tfsdk:"routing_instance"`
+	BackupBridgePriority                         types.String `tfsdk:"backup_bridge_priority"`
+	BpduBlockOnEdge                              types.Bool   `tfsdk:"bpdu_block_on_edge"`
+	BpduDestinationMacAddressProviderBridgeGroup types.Bool   `tfsdk:"bpdu_destination_mac_address_provider_bridge_group"`
+	BridgePriority                               types.String `tfsdk:"bridge_priority"`
+	Disable                                      types.Bool   `tfsdk:"disable"`
+	ExtendedSystemID                             types.Int64  `tfsdk:"extended_system_id"`
+	ForceVersionStp                              types.Bool   `tfsdk:"force_version_stp"`
+	ForwardDelay                                 types.Int64  `tfsdk:"forward_delay"`
+	HelloTime                                    types.Int64  `tfsdk:"hello_time"`
+	MaxAge                                       types.Int64  `tfsdk:"max_age"`
+	PriorityHoldTime                             types.Int64  `tfsdk:"priority_hold_time"`
+	SystemIdentifier                             types.String `tfsdk:"system_identifier"`
+	VplsFlushOnTopologyChange                    types.Bool   `tfsdk:"vpls_flush_on_topology_change"`
+	SystemID                                     types.Set    `tfsdk:"system_id"`
+}
+
+type rstpBlockSystemID struct {
+	ID        types.String `tfsdk:"id"`
+	IPAddress types.String `tfsdk:"ip_address"`
+}
+
+func (rsc *rstp) ValidateConfig(
+	ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse,
+) {
+	var config rstpConfig
+	resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	if !config.BackupBridgePriority.IsNull() && !config.BackupBridgePriority.IsUnknown() {
+		if v, err := strconv.Atoi(strings.TrimSuffix(
+			config.BackupBridgePriority.ValueString(), "k",
+		)); err == nil {
+			if v%4 != 0 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("backup_bridge_priority"),
+					"Bad Value Error",
+					"backup_bridge_priority must be a multiple of 4k",
+				)
+			}
+			if v < 4 || v > 60 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("backup_bridge_priority"),
+					"Bad Value Error",
+					"backup_bridge_priority must be between 4k and 60k",
+				)
+			}
+			if !config.BridgePriority.IsNull() && !config.BridgePriority.IsUnknown() {
+				if bridgePriority, err := strconv.Atoi(strings.TrimSuffix(
+					config.BridgePriority.ValueString(), "k",
+				)); err == nil {
+					if v <= bridgePriority {
+						resp.Diagnostics.AddAttributeError(
+							path.Root("backup_bridge_priority"),
+							"Bad Value Error",
+							"backup_bridge_priority must be worse (higher value) than bridge_priority",
+						)
+					}
+				}
+			}
+		}
+	}
+	if !config.BridgePriority.IsNull() && !config.BridgePriority.IsUnknown() {
+		if v, err := strconv.Atoi(strings.TrimSuffix(
+			config.BridgePriority.ValueString(), "k",
+		)); err == nil {
+			if v%4 != 0 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("bridge_priority"),
+					"Bad Value Error",
+					"bridge_priority must be a multiple of 4k",
+				)
+			}
+			if v < 0 || v > 60 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("bridge_priority"),
+					"Bad Value Error",
+					"bridge_priority must be between 0 and 60k",
+				)
+			}
+		}
+	}
+	if !config.SystemID.IsNull() && !config.SystemID.IsUnknown() {
+		var systemID []rstpBlockSystemID
+		asDiags := config.SystemID.ElementsAs(ctx, &systemID, false)
+		if asDiags.HasError() {
+			resp.Diagnostics.Append(asDiags...)
+
+			return
+		}
+		systemIDID := make(map[string]struct{})
+		for _, block := range systemID {
+			if block.ID.IsUnknown() {
+				continue
+			}
+			id := block.ID.ValueString()
+			if _, ok := systemIDID[id]; ok {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("system_id"),
+					tfdiag.DuplicateConfigErrSummary,
+					fmt.Sprintf("multiple system_id blocks with the same id %q", id),
+				)
+			}
+			systemIDID[id] = struct{}{}
+		}
+	}
+}
+
+func (rsc *rstp) Create(
+	ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse,
+) {
+	var plan rstpData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceCreate(
+		ctx,
+		rsc,
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+				instanceExists, err := checkRoutingInstanceExists(fnCtx, v, junSess)
+				if err != nil {
+					resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+					return false
+				}
+				if !instanceExists {
+					resp.Diagnostics.AddAttributeError(
+						path.Root("routing_instance"),
+						tfdiag.MissingConfigErrSummary,
+						fmt.Sprintf("routing instance %q doesn't exist", v),
+					)
+
+					return false
+				}
+			}
+
+			return true
+		},
+		nil,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *rstp) Read(
+	ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse,
+) {
+	var state, data rstpData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	junSess, err := rsc.junosClient().StartNewSession(ctx)
+	if err != nil {
+		resp.Diagnostics.AddError(tfdiag.StartSessErrSummary, err.Error())
+
+		return
+	}
+	defer junSess.Close()
+
+	junos.MutexLock()
+	if v := state.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		instanceExists, err := checkRoutingInstanceExists(ctx, v, junSess)
+		if err != nil {
+			junos.MutexUnlock()
+			resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+			return
+		}
+		if !instanceExists {
+			junos.MutexUnlock()
+			resp.State.RemoveResource(ctx)
+
+			return
+		}
+	}
+
+	err = data.read(ctx, state.RoutingInstance.ValueString(), junSess)
+	junos.MutexUnlock()
+	if err != nil {
+		resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+		return
+	}
+
+	if data.nullID() {
+		resp.State.RemoveResource(ctx)
+
+		return
+	}
+
+	resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (rsc *rstp) Update(
+	ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse,
+) {
+	var plan, state rstpData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceUpdate(
+		ctx,
+		rsc,
+		&state,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *rstp) Delete(
+	ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse,
+) {
+	var state rstpData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceDelete(
+		ctx,
+		rsc,
+		&state,
+		resp,
+	)
+}
+
+func (rsc *rstp) ImportState(
+	ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse,
+) {
+	junSess, err := rsc.junosClient().StartNewSession(ctx)
+	if err != nil {
+		resp.Diagnostics.AddError(tfdiag.StartSessErrSummary, err.Error())
+
+		return
+	}
+	defer junSess.Close()
+
+	if req.ID != junos.DefaultW {
+		instanceExists, err := checkRoutingInstanceExists(ctx, req.ID, junSess)
+		if err != nil {
+			resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+			return
+		}
+		if !instanceExists {
+			resp.Diagnostics.AddError(
+				tfdiag.NotFoundErrSummary,
+				fmt.Sprintf("routing instance %q doesn't exist", req.ID),
+			)
+
+			return
+		}
+	}
+
+	var data rstpData
+	if err := data.read(ctx, req.ID, junSess); err != nil {
+		resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+		return
+	}
+	if data.nullID() {
+		resp.Diagnostics.AddError(
+			tfdiag.NotFoundErrSummary,
+			defaultResourceImportDontFindMessage(rsc, req.ID)+
+				" (id must be <routing_instance>)",
+		)
+
+		return
+	}
+
+	resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
+}
+
+func (rscData *rstpData) fillID() {
+	if v := rscData.RoutingInstance.ValueString(); v != "" {
+		rscData.ID = types.StringValue(v)
+	} else {
+		rscData.ID = types.StringValue(junos.DefaultW)
+	}
+}
+
+func (rscData *rstpData) nullID() bool {
+	return rscData.ID.IsNull()
+}
+
+func (rscData *rstpData) set(
+	_ context.Context, junSess *junos.Session,
+) (
+	path.Path, error,
+) {
+	configSet := make([]string, 0)
+	setPrefix := junos.SetLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		setPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	setPrefix += "protocols rstp "
+
+	if v := rscData.BackupBridgePriority.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"backup-bridge-priority "+v)
+	}
+	if rscData.BpduBlockOnEdge.ValueBool() {
+		configSet = append(configSet, setPrefix+"bpdu-block-on-edge")
+	}
+	if rscData.BpduDestinationMacAddressProviderBridgeGroup.ValueBool() {
+		configSet = append(configSet, setPrefix+"bpdu-destination-mac-address provider-bridge-group")
+	}
+	if v := rscData.BridgePriority.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"bridge-priority "+v)
+	}
+	if rscData.Disable.ValueBool() {
+		configSet = append(configSet, setPrefix+"disable")
+	}
+	if !rscData.ExtendedSystemID.IsNull() {
+		configSet = append(configSet, setPrefix+"extended-system-id "+
+			utils.ConvI64toa(rscData.ExtendedSystemID.ValueInt64()))
+	}
+	if rscData.ForceVersionStp.ValueBool() {
+		configSet = append(configSet, setPrefix+"force-version stp")
+	}
+	if !rscData.ForwardDelay.IsNull() {
+		configSet = append(configSet, setPrefix+"forward-delay "+
+			utils.ConvI64toa(rscData.ForwardDelay.ValueInt64()))
+	}
+	if !rscData.HelloTime.IsNull() {
+		configSet = append(configSet, setPrefix+"hello-time "+
+			utils.ConvI64toa(rscData.HelloTime.ValueInt64()))
+	}
+	if !rscData.MaxAge.IsNull() {
+		configSet = append(configSet, setPrefix+"max-age "+
+			utils.ConvI64toa(rscData.MaxAge.ValueInt64()))
+	}
+	if !rscData.PriorityHoldTime.IsNull() {
+		configSet = append(configSet, setPrefix+"priority-hold-time "+
+			utils.ConvI64toa(rscData.PriorityHoldTime.ValueInt64()))
+	}
+	if v := rscData.SystemIdentifier.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"system-identifier "+v)
+	}
+	if rscData.VplsFlushOnTopologyChange.ValueBool() {
+		configSet = append(configSet, setPrefix+"vpls-flush-on-topology-change")
+	}
+	systemIDID := make(map[string]struct{})
+	for _, block := range rscData.SystemID {
+		id := block.ID.ValueString()
+		if _, ok := systemIDID[id]; ok {
+			return path.Root("system_id"),
+				fmt.Errorf("multiple system_id blocks with the same id %q", id)
+		}
+		systemIDID[id] = struct{}{}
+
+		configSet = append(configSet, setPrefix+"system-id "+id)
+		if v := block.IPAddress.ValueString(); v != "" {
+			configSet = append(configSet, setPrefix+"system-id "+id+" ip-address "+v)
+		}
+	}
+
+	return path.Empty(), junSess.ConfigSet(configSet)
+}
+
+func (rscData *rstpData) read(
+	_ context.Context, routingInstance string, junSess *junos.Session,
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols rstp" + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
+	if routingInstance == "" {
+		rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+	} else {
+		rscData.RoutingInstance = types.StringValue(routingInstance)
+	}
+	rscData.fillID()
+	if showConfig != junos.EmptyW {
+		for _, item := range strings.Split(showConfig, "\n") {
+			if strings.Contains(item, junos.XMLStartTagConfigOut) {
+				continue
+			}
+			if strings.Contains(item, junos.XMLEndTagConfigOut) {
+				break
+			}
+			itemTrim := strings.TrimPrefix(item, junos.SetLS)
+			switch {
+			case balt.CutPrefixInString(&itemTrim, "backup-bridge-priority "):
+				rscData.BackupBridgePriority = types.StringValue(itemTrim)
+			case itemTrim == "bpdu-block-on-edge":
+				rscData.BpduBlockOnEdge = types.BoolValue(true)
+			case itemTrim == "bpdu-destination-mac-address provider-bridge-group":
+				rscData.BpduDestinationMacAddressProviderBridgeGroup = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "bridge-priority "):
+				rscData.BridgePriority = types.StringValue(itemTrim)
+			case itemTrim == junos.DisableW:
+				rscData.Disable = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "extended-system-id "):
+				rscData.ExtendedSystemID, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case itemTrim == "force-version stp":
+				rscData.ForceVersionStp = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "forward-delay "):
+				rscData.ForwardDelay, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "hello-time "):
+				rscData.HelloTime, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "max-age "):
+				rscData.MaxAge, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "priority-hold-time "):
+				rscData.PriorityHoldTime, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "system-identifier "):
+				rscData.SystemIdentifier = types.StringValue(itemTrim)
+			case itemTrim == "vpls-flush-on-topology-change":
+				rscData.VplsFlushOnTopologyChange = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "system-id "):
+				itemTrimFields := strings.Split(itemTrim, " ")
+				switch len(itemTrimFields) { // <id> (ip-address <ip_address>)?
+				case 1:
+					rscData.SystemID = append(rscData.SystemID, rstpBlockSystemID{
+						ID: types.StringValue(itemTrimFields[0]),
+					})
+				case 3:
+					rscData.SystemID = append(rscData.SystemID, rstpBlockSystemID{
+						ID:        types.StringValue(itemTrimFields[0]),
+						IPAddress: types.StringValue(itemTrimFields[2]),
+					})
+				default:
+					return fmt.Errorf(junos.CantReadValuesNotEnoughFields, "system-id", itemTrim)
+				}
+			}
+		}
+	}
+
+	return nil
+}
+
+func (rscData *rstpData) del(
+	_ context.Context, junSess *junos.Session,
+) error {
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	delPrefix += "protocols rstp "
+
+	listLinesToDelete := []string{
+		"backup-bridge-priority",
+		"bpdu-block-on-edge",
+		"bpdu-destination-mac-address",
+		"bridge-priority",
+		"disable",
+		"extended-system-id",
+		"force-version",
+		"forward-delay",
+		"hello-time",
+		"max-age",
+		"priority-hold-time",
+		"system-identifier",
+		"vpls-flush-on-topology-change",
+	}
+
+	configSet := make([]string, len(listLinesToDelete), len(listLinesToDelete)+len(rscData.SystemID))
+	for k, line := range listLinesToDelete {
+		configSet[k] = delPrefix + line
+	}
+	for _, block := range rscData.SystemID {
+		configSet = append(configSet, delPrefix+"system-id "+block.ID.ValueString())
+	}
+
+	return junSess.ConfigSet(configSet)
+}
diff --git a/internal/providerfwk/resource_rstp_interface.go b/internal/providerfwk/resource_rstp_interface.go
new file mode 100644
index 00000000..c6eb366e
--- /dev/null
+++ b/internal/providerfwk/resource_rstp_interface.go
@@ -0,0 +1,538 @@
+package providerfwk
+
+import (
+	"context"
+	"fmt"
+	"strings"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdata"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdiag"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfvalidator"
+	"github.com/jeremmfr/terraform-provider-junos/internal/utils"
+
+	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+	"github.com/hashicorp/terraform-plugin-framework/path"
+	"github.com/hashicorp/terraform-plugin-framework/resource"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+	balt "github.com/jeremmfr/go-utils/basicalter"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+	_ resource.Resource                   = &rstpInterface{}
+	_ resource.ResourceWithConfigure      = &rstpInterface{}
+	_ resource.ResourceWithValidateConfig = &rstpInterface{}
+	_ resource.ResourceWithImportState    = &rstpInterface{}
+)
+
+type rstpInterface struct {
+	client *junos.Client
+}
+
+func newRstpInterfaceResource() resource.Resource {
+	return &rstpInterface{}
+}
+
+func (rsc *rstpInterface) typeName() string {
+	return providerName + "_rstp_interface"
+}
+
+func (rsc *rstpInterface) junosName() string {
+	return "rstp interface"
+}
+
+func (rsc *rstpInterface) junosClient() *junos.Client {
+	return rsc.client
+}
+
+func (rsc *rstpInterface) Metadata(
+	_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse,
+) {
+	resp.TypeName = rsc.typeName()
+}
+
+func (rsc *rstpInterface) Configure(
+	ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse,
+) {
+	// Prevent panic if the provider has not been configured.
+	if req.ProviderData == nil {
+		return
+	}
+	client, ok := req.ProviderData.(*junos.Client)
+	if !ok {
+		unexpectedResourceConfigureType(ctx, req, resp)
+
+		return
+	}
+	rsc.client = client
+}
+
+func (rsc *rstpInterface) Schema(
+	_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse,
+) {
+	resp.Schema = schema.Schema{
+		Description: defaultResourceSchemaDescription(rsc),
+		Attributes: map[string]schema.Attribute{
+			"id": schema.StringAttribute{
+				Computed: true,
+				Description: "An identifier for the resource with format " +
+					"`<name>" + junos.IDSeparator + "<routing_instance>`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.UseStateForUnknown(),
+				},
+			},
+			"name": schema.StringAttribute{
+				Required:    true,
+				Description: "Interface name or `all`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthAtLeast(1),
+					tfvalidator.StringFormat(tfvalidator.InterfaceFormat),
+					tfvalidator.StringDotExclusion(),
+				},
+			},
+			"routing_instance": schema.StringAttribute{
+				Optional:    true,
+				Computed:    true,
+				Default:     stringdefault.StaticString(junos.DefaultW),
+				Description: "Routing instance for rstp protocol if not root level.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+			"access_trunk": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Send/Receive untagged RSTP BPDUs on this interface.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"bpdu_timeout_action_alarm": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Generate an alarm on BPDU expiry (Loop Protect).",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"bpdu_timeout_action_block": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Block the interface on BPDU expiry (Loop Protect).",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"cost": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Cost of the interface.",
+				Validators: []validator.Int64{
+					int64validator.Between(1, 200000000),
+				},
+			},
+			"edge": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Port is an edge port.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"mode": schema.StringAttribute{
+				Optional:    true,
+				Description: "Interface mode (P2P or shared).",
+				Validators: []validator.String{
+					stringvalidator.OneOf("point-to-point", "shared"),
+				},
+			},
+			"no_root_port": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Do not allow the interface to become root (Root Protect).",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"priority": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Interface priority (in increments of 16).",
+				Validators: []validator.Int64{
+					int64validator.Between(0, 240),
+				},
+			},
+		},
+	}
+}
+
+type rstpInterfaceData struct {
+	ID                     types.String `tfsdk:"id"`
+	Name                   types.String `tfsdk:"name"`
+	RoutingInstance        types.String `tfsdk:"routing_instance"`
+	AccessTrunk            types.Bool   `tfsdk:"access_trunk"`
+	BpduTimeoutActionAlarm types.Bool   `tfsdk:"bpdu_timeout_action_alarm"`
+	BpduTimeoutActionBlock types.Bool   `tfsdk:"bpdu_timeout_action_block"`
+	Cost                   types.Int64  `tfsdk:"cost"`
+	Edge                   types.Bool   `tfsdk:"edge"`
+	Mode                   types.String `tfsdk:"mode"`
+	NoRootPort             types.Bool   `tfsdk:"no_root_port"`
+	Priority               types.Int64  `tfsdk:"priority"`
+}
+
+func (rsc *rstpInterface) ValidateConfig(
+	ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse,
+) {
+	var config rstpInterfaceData
+	resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	if !config.Priority.IsNull() && !config.Priority.IsUnknown() {
+		if config.Priority.ValueInt64()%16 != 0 {
+			resp.Diagnostics.AddAttributeError(
+				path.Root("priority"),
+				"Bad Value Error",
+				"priority must be a multiple of 16",
+			)
+		}
+	}
+}
+
+func (rsc *rstpInterface) Create(
+	ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse,
+) {
+	var plan rstpInterfaceData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+	if plan.Name.ValueString() == "" {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("name"),
+			"Empty Name",
+			defaultResourceCouldNotCreateWithEmptyMessage(rsc, "name"),
+		)
+
+		return
+	}
+
+	defaultResourceCreate(
+		ctx,
+		rsc,
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+				instanceExists, err := checkRoutingInstanceExists(fnCtx, v, junSess)
+				if err != nil {
+					resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+					return false
+				}
+				if !instanceExists {
+					resp.Diagnostics.AddAttributeError(
+						path.Root("routing_instance"),
+						tfdiag.MissingConfigErrSummary,
+						fmt.Sprintf("routing instance %q doesn't exist", v),
+					)
+
+					return false
+				}
+			}
+			interfaceExists, err := checkRstpInterfaceExists(
+				fnCtx,
+				plan.Name.ValueString(),
+				plan.RoutingInstance.ValueString(),
+				junSess,
+			)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+				return false
+			}
+			if interfaceExists {
+				if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+					resp.Diagnostics.AddError(
+						tfdiag.DuplicateConfigErrSummary,
+						defaultResourceAlreadyExistsInRoutingInstanceMessage(rsc, plan.Name, v),
+					)
+				} else {
+					resp.Diagnostics.AddError(
+						tfdiag.DuplicateConfigErrSummary,
+						defaultResourceAlreadyExistsMessage(rsc, plan.Name),
+					)
+				}
+
+				return false
+			}
+
+			return true
+		},
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			interfaceExists, err := checkRstpInterfaceExists(
+				fnCtx,
+				plan.Name.ValueString(),
+				plan.RoutingInstance.ValueString(),
+				junSess,
+			)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PostCheckErrSummary, err.Error())
+
+				return false
+			}
+			if !interfaceExists {
+				if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+					resp.Diagnostics.AddError(
+						tfdiag.NotFoundErrSummary,
+						defaultResourceDoesNotExistsInRoutingInstanceAfterCommitMessage(rsc, plan.Name, v),
+					)
+				} else {
+					resp.Diagnostics.AddError(
+						tfdiag.NotFoundErrSummary,
+						defaultResourceDoesNotExistsAfterCommitMessage(rsc, plan.Name),
+					)
+				}
+
+				return false
+			}
+
+			return true
+		},
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *rstpInterface) Read(
+	ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse,
+) {
+	var state, data rstpInterfaceData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	var _ resourceDataReadFrom2String = &data
+	defaultResourceRead(
+		ctx,
+		rsc,
+		[]string{
+			state.Name.ValueString(),
+			state.RoutingInstance.ValueString(),
+		},
+		&data,
+		nil,
+		resp,
+	)
+}
+
+func (rsc *rstpInterface) Update(
+	ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse,
+) {
+	var plan, state rstpInterfaceData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceUpdate(
+		ctx,
+		rsc,
+		&state,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *rstpInterface) Delete(
+	ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse,
+) {
+	var state rstpInterfaceData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceDelete(
+		ctx,
+		rsc,
+		&state,
+		resp,
+	)
+}
+
+func (rsc *rstpInterface) ImportState(
+	ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse,
+) {
+	var data rstpInterfaceData
+
+	var _ resourceDataReadFrom2String = &data
+	defaultResourceImportState(
+		ctx,
+		rsc,
+		&data,
+		req,
+		resp,
+		defaultResourceImportDontFindMessage(rsc, req.ID)+
+			" (id must be <name>"+junos.IDSeparator+"<routing_instance>)",
+	)
+}
+
+func checkRstpInterfaceExists(
+	_ context.Context, name, routingInstance string, junSess *junos.Session,
+) (
+	bool, error,
+) {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols rstp interface " + name + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
+	}
+	if showConfig == junos.EmptyW {
+		return false, nil
+	}
+
+	return true, nil
+}
+
+func (rscData *rstpInterfaceData) fillID() {
+	if v := rscData.RoutingInstance.ValueString(); v != "" {
+		rscData.ID = types.StringValue(rscData.Name.ValueString() + junos.IDSeparator + v)
+	} else {
+		rscData.ID = types.StringValue(rscData.Name.ValueString() + junos.IDSeparator + junos.DefaultW)
+	}
+}
+
+func (rscData *rstpInterfaceData) nullID() bool {
+	return rscData.ID.IsNull()
+}
+
+func (rscData *rstpInterfaceData) set(
+	_ context.Context, junSess *junos.Session,
+) (
+	path.Path, error,
+) {
+	setPrefix := junos.SetLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		setPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	setPrefix += "protocols rstp interface " + rscData.Name.ValueString() + " "
+
+	configSet := []string{
+		setPrefix,
+	}
+
+	if rscData.AccessTrunk.ValueBool() {
+		configSet = append(configSet, setPrefix+"access-trunk")
+	}
+	if rscData.BpduTimeoutActionAlarm.ValueBool() {
+		configSet = append(configSet, setPrefix+"bpdu-timeout-action alarm")
+	}
+	if rscData.BpduTimeoutActionBlock.ValueBool() {
+		configSet = append(configSet, setPrefix+"bpdu-timeout-action block")
+	}
+	if !rscData.Cost.IsNull() {
+		configSet = append(configSet, setPrefix+"cost "+
+			utils.ConvI64toa(rscData.Cost.ValueInt64()))
+	}
+	if rscData.Edge.ValueBool() {
+		configSet = append(configSet, setPrefix+"edge")
+	}
+	if v := rscData.Mode.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"mode "+v)
+	}
+	if rscData.NoRootPort.ValueBool() {
+		configSet = append(configSet, setPrefix+"no-root-port")
+	}
+	if !rscData.Priority.IsNull() {
+		configSet = append(configSet, setPrefix+"priority "+
+			utils.ConvI64toa(rscData.Priority.ValueInt64()))
+	}
+
+	return path.Empty(), junSess.ConfigSet(configSet)
+}
+
+func (rscData *rstpInterfaceData) read(
+	_ context.Context, name, routingInstance string, junSess *junos.Session,
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols rstp interface " + name + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
+	if showConfig != junos.EmptyW {
+		rscData.Name = types.StringValue(name)
+		if routingInstance == "" {
+			rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+		} else {
+			rscData.RoutingInstance = types.StringValue(routingInstance)
+		}
+		rscData.fillID()
+		for _, item := range strings.Split(showConfig, "\n") {
+			if strings.Contains(item, junos.XMLStartTagConfigOut) {
+				continue
+			}
+			if strings.Contains(item, junos.XMLEndTagConfigOut) {
+				break
+			}
+			itemTrim := strings.TrimPrefix(item, junos.SetLS)
+			switch {
+			case itemTrim == "access-trunk":
+				rscData.AccessTrunk = types.BoolValue(true)
+			case itemTrim == "bpdu-timeout-action alarm":
+				rscData.BpduTimeoutActionAlarm = types.BoolValue(true)
+			case itemTrim == "bpdu-timeout-action block":
+				rscData.BpduTimeoutActionBlock = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "cost "):
+				rscData.Cost, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case itemTrim == "edge":
+				rscData.Edge = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "mode "):
+				rscData.Mode = types.StringValue(itemTrim)
+			case itemTrim == "no-root-port":
+				rscData.NoRootPort = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "priority "):
+				rscData.Priority, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			}
+		}
+	}
+
+	return nil
+}
+
+func (rscData *rstpInterfaceData) del(
+	_ context.Context, junSess *junos.Session,
+) error {
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+
+	configSet := []string{
+		delPrefix + "protocols rstp interface " + rscData.Name.ValueString(),
+	}
+
+	return junSess.ConfigSet(configSet)
+}
diff --git a/internal/providerfwk/resource_rstp_interface_test.go b/internal/providerfwk/resource_rstp_interface_test.go
new file mode 100644
index 00000000..9bddf2a4
--- /dev/null
+++ b/internal/providerfwk/resource_rstp_interface_test.go
@@ -0,0 +1,82 @@
+package providerfwk_test
+
+import (
+	"os"
+	"testing"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+
+	"github.com/hashicorp/terraform-plugin-testing/config"
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccResourceRstpInterface_basic(t *testing.T) {
+	if os.Getenv("TESTACC_SWITCH") == "" {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ResourceName:      "junos_rstp_interface.all",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
+
+// export TESTACC_INTERFACE=<inteface> for choose interface available else it's xe-0/0/3.
+func TestAccResourceRstpInterface_switch(t *testing.T) {
+	if os.Getenv("TESTACC_SWITCH") != "" {
+		testaccInterface := junos.DefaultInterfaceSwitchTestAcc
+		if iface := os.Getenv("TESTACC_INTERFACE"); iface != "" {
+			testaccInterface = iface
+		}
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_rstp_interface.all",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_rstp_interface.all2",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_rstp_interface.testacc_rstp_interface",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providerfwk/resource_rstp_test.go b/internal/providerfwk/resource_rstp_test.go
new file mode 100644
index 00000000..842bdb8c
--- /dev/null
+++ b/internal/providerfwk/resource_rstp_test.go
@@ -0,0 +1,56 @@
+package providerfwk_test
+
+import (
+	"os"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/config"
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccResourceRstp_basic(t *testing.T) {
+	if os.Getenv("TESTACC_SWITCH") == "" {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ResourceName:      "junos_rstp.testacc_rstp",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
+
+func TestAccResourceRstp_switch(t *testing.T) {
+	if os.Getenv("TESTACC_SWITCH") != "" {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ResourceName:      "junos_rstp.testacc_ri_rstp",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providerfwk/resource_security.go b/internal/providerfwk/resource_security.go
index 0b08a0c3..8b4196c0 100644
--- a/internal/providerfwk/resource_security.go
+++ b/internal/providerfwk/resource_security.go
@@ -2094,8 +2094,8 @@ func (rscData *securityData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set security "
 	configSet := make([]string, 0)
+	setPrefix := "set security "
 
 	if rscData.Alg != nil {
 		if rscData.Alg.isEmpty() {
@@ -2217,8 +2217,8 @@ func (rscData *securityData) set(
 }
 
 func (block *securityBlockAlg) configSet() []string {
-	setPrefix := "set security alg "
 	configSet := make([]string, 0)
+	setPrefix := "set security alg "
 
 	if block.DNSDisable.ValueBool() {
 		configSet = append(configSet, setPrefix+"dns disable")
@@ -2271,8 +2271,8 @@ func (block *securityBlockFlow) configSet() (
 	path.Path, // pathErr
 	error, // error
 ) {
-	setPrefix := "set security flow "
 	configSet := make([]string, 0)
+	setPrefix := "set security flow "
 
 	if block.AdvancedOptions != nil {
 		if block.AdvancedOptions.isEmpty() {
@@ -2449,8 +2449,8 @@ func (block *securityBlockFlow) configSet() (
 }
 
 func (block *securityBlockForwardingOptions) configSet() []string {
-	setPrefix := "set security forwarding-options "
 	configSet := make([]string, 0)
+	setPrefix := "set security forwarding-options "
 
 	if v := block.Inet6Mode.ValueString(); v != "" {
 		configSet = append(configSet, setPrefix+"family inet6 mode "+v)
@@ -2466,8 +2466,8 @@ func (block *securityBlockForwardingOptions) configSet() []string {
 }
 
 func (block *securityBlockIdpSecurityPackage) configSet() []string {
-	setPrefix := "set security idp security-package "
 	configSet := make([]string, 0)
+	setPrefix := "set security idp security-package "
 
 	if block.AutomaticEnable.ValueBool() {
 		configSet = append(configSet, setPrefix+"automatic enable")
@@ -2496,8 +2496,8 @@ func (block *securityBlockIdpSecurityPackage) configSet() []string {
 }
 
 func (block *securityBlockIdpSensorConfiguration) configSet() []string {
-	setPrefix := "set security idp sensor-configuration "
 	configSet := make([]string, 0)
+	setPrefix := "set security idp sensor-configuration "
 
 	if !block.LogCacheSize.IsNull() {
 		configSet = append(configSet, setPrefix+"log cache-size "+
@@ -2563,8 +2563,8 @@ func (block *securityBlockIkeTraceoptions) configSet() (
 	path.Path, // pathErr
 	error, // error
 ) {
-	setPrefix := "set security ike traceoptions "
 	configSet := make([]string, 0)
+	setPrefix := "set security ike traceoptions "
 
 	if block.File != nil {
 		if block.File.isEmpty() {
@@ -2618,8 +2618,8 @@ func (block *securityBlockLog) configSet() (
 	path.Path, // pathErr
 	error, // error
 ) {
-	setPrefix := "set security log "
 	configSet := make([]string, 0)
+	setPrefix := "set security log "
 
 	if block.Disable.ValueBool() {
 		configSet = append(configSet, setPrefix+"disable")
@@ -2697,8 +2697,8 @@ func (block *securityBlockLog) configSet() (
 }
 
 func (block *securityBlockNatSource) configSet() []string {
-	setPrefix := "set security nat source "
 	configSet := make([]string, 0)
+	setPrefix := "set security nat source "
 
 	if block.AddressPersistent.ValueBool() {
 		configSet = append(configSet, setPrefix+"address-persistent")
@@ -2749,8 +2749,8 @@ func (block *securityBlockNatSource) configSet() []string {
 }
 
 func (block *securityBlockUserIdentificationAuthSource) configSet() []string {
-	setPrefix := "set security user-identification authentication-source "
 	configSet := make([]string, 0)
+	setPrefix := "set security user-identification authentication-source "
 
 	if !block.ADAuthPriority.IsNull() {
 		configSet = append(configSet, setPrefix+"active-directory-authentication-table priority "+
@@ -2777,8 +2777,8 @@ func (block *securityBlockUserIdentificationAuthSource) configSet() []string {
 }
 
 func (block *securityBlockUtm) configSet() []string {
-	setPrefix := "set security utm "
 	configSet := make([]string, 0)
+	setPrefix := "set security utm "
 
 	if v := block.FeatureProfileWebFilteringType.ValueString(); v != "" {
 		configSet = append(configSet, setPrefix+"feature-profile web-filtering type "+v)
@@ -2807,9 +2807,7 @@ func (block *securityBlockUtm) configSet() []string {
 
 func (rscData *securityData) read(
 	_ context.Context, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_address_book.go b/internal/providerfwk/resource_security_address_book.go
index c6c93d16..da88bce3 100644
--- a/internal/providerfwk/resource_security_address_book.go
+++ b/internal/providerfwk/resource_security_address_book.go
@@ -832,9 +832,7 @@ func (rscData *securityAddressBookData) set(
 
 func (rscData *securityAddressBookData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security address-book \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_global_policy.go b/internal/providerfwk/resource_security_global_policy.go
index dc399b59..c68100eb 100644
--- a/internal/providerfwk/resource_security_global_policy.go
+++ b/internal/providerfwk/resource_security_global_policy.go
@@ -691,9 +691,7 @@ func (rscData *securityGlobalPolicyData) set(
 
 func (rscData *securityGlobalPolicyData) read(
 	_ context.Context, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security policies global" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_ike_gateway.go b/internal/providerfwk/resource_security_ike_gateway.go
index da9a42ab..d9bd2279 100644
--- a/internal/providerfwk/resource_security_ike_gateway.go
+++ b/internal/providerfwk/resource_security_ike_gateway.go
@@ -565,7 +565,7 @@ func (rsc *securityIkeGateway) ValidateConfig(
 			resp.Diagnostics.AddAttributeError(
 				path.Root("aaa").AtName("access_profile"),
 				tfdiag.ConflictConfigErrSummary,
-				"only one of access_profile or client_username/client_password must be specifiedin aaa block ",
+				"only one of access_profile or client_username/client_password must be specifiedin aaa block",
 			)
 		}
 		if config.Aaa.ClientUsername.IsNull() && !config.Aaa.ClientPassword.IsNull() {
@@ -954,9 +954,7 @@ func (rscData *securityIkeGatewayData) set(
 
 func (rscData *securityIkeGatewayData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security ike gateway \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_ike_policy.go b/internal/providerfwk/resource_security_ike_policy.go
index f70a23aa..345f5f43 100644
--- a/internal/providerfwk/resource_security_ike_policy.go
+++ b/internal/providerfwk/resource_security_ike_policy.go
@@ -431,9 +431,7 @@ func (rscData *securityIkePolicyData) set(
 
 func (rscData *securityIkePolicyData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security ike policy \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_ike_proposal.go b/internal/providerfwk/resource_security_ike_proposal.go
index c65b650d..a035dd68 100644
--- a/internal/providerfwk/resource_security_ike_proposal.go
+++ b/internal/providerfwk/resource_security_ike_proposal.go
@@ -361,9 +361,7 @@ func (rscData *securityIkeProposalData) set(
 
 func (rscData *securityIkeProposalData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security ike proposal \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_ipsec_policy.go b/internal/providerfwk/resource_security_ipsec_policy.go
index d7612673..c96a9e4d 100644
--- a/internal/providerfwk/resource_security_ipsec_policy.go
+++ b/internal/providerfwk/resource_security_ipsec_policy.go
@@ -373,9 +373,7 @@ func (rscData *securityIpsecPolicyData) set(
 
 func (rscData *securityIpsecPolicyData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security ipsec policy " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_ipsec_proposal.go b/internal/providerfwk/resource_security_ipsec_proposal.go
index 0175ea7b..6cfd629a 100644
--- a/internal/providerfwk/resource_security_ipsec_proposal.go
+++ b/internal/providerfwk/resource_security_ipsec_proposal.go
@@ -358,9 +358,7 @@ func (rscData *securityIpsecProposalData) set(
 
 func (rscData *securityIpsecProposalData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security ipsec proposal " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_ipsec_vpn.go b/internal/providerfwk/resource_security_ipsec_vpn.go
index 8cff07d2..37eb09e4 100644
--- a/internal/providerfwk/resource_security_ipsec_vpn.go
+++ b/internal/providerfwk/resource_security_ipsec_vpn.go
@@ -1010,9 +1010,7 @@ func (rscData *securityIpsecVpnData) set(
 
 func (rscData *securityIpsecVpnData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security ipsec vpn \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_log_stream.go b/internal/providerfwk/resource_security_log_stream.go
new file mode 100644
index 00000000..8acdb527
--- /dev/null
+++ b/internal/providerfwk/resource_security_log_stream.go
@@ -0,0 +1,698 @@
+package providerfwk
+
+import (
+	"context"
+	"errors"
+	"strings"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdata"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdiag"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfplanmodifier"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfvalidator"
+	"github.com/jeremmfr/terraform-provider-junos/internal/utils"
+
+	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/listvalidator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+	"github.com/hashicorp/terraform-plugin-framework/path"
+	"github.com/hashicorp/terraform-plugin-framework/resource"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+	balt "github.com/jeremmfr/go-utils/basicalter"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+	_ resource.Resource                   = &securityLogStream{}
+	_ resource.ResourceWithConfigure      = &securityLogStream{}
+	_ resource.ResourceWithValidateConfig = &securityLogStream{}
+	_ resource.ResourceWithImportState    = &securityLogStream{}
+	_ resource.ResourceWithUpgradeState   = &securityLogStream{}
+)
+
+type securityLogStream struct {
+	client *junos.Client
+}
+
+func newSecurityLogStreamResource() resource.Resource {
+	return &securityLogStream{}
+}
+
+func (rsc *securityLogStream) typeName() string {
+	return providerName + "_security_log_stream"
+}
+
+func (rsc *securityLogStream) junosName() string {
+	return "security log stream"
+}
+
+func (rsc *securityLogStream) junosClient() *junos.Client {
+	return rsc.client
+}
+
+func (rsc *securityLogStream) Metadata(
+	_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse,
+) {
+	resp.TypeName = rsc.typeName()
+}
+
+func (rsc *securityLogStream) Configure(
+	ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse,
+) {
+	// Prevent panic if the provider has not been configured.
+	if req.ProviderData == nil {
+		return
+	}
+	client, ok := req.ProviderData.(*junos.Client)
+	if !ok {
+		unexpectedResourceConfigureType(ctx, req, resp)
+
+		return
+	}
+	rsc.client = client
+}
+
+func (rsc *securityLogStream) Schema(
+	_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse,
+) {
+	resp.Schema = schema.Schema{
+		Version:     1,
+		Description: defaultResourceSchemaDescription(rsc),
+		Attributes: map[string]schema.Attribute{
+			"id": schema.StringAttribute{
+				Computed:    true,
+				Description: "An identifier for the resource with format `<name>`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.UseStateForUnknown(),
+				},
+			},
+			"name": schema.StringAttribute{
+				Required:    true,
+				Description: "Name of security log stream.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+			"category": schema.ListAttribute{
+				ElementType: types.StringType,
+				Optional:    true,
+				Description: "Selects the type of events that may be logged.",
+				Validators: []validator.List{
+					listvalidator.SizeAtLeast(1),
+					listvalidator.ValueStringsAre(
+						stringvalidator.LengthAtLeast(1),
+						tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+					),
+				},
+			},
+			"filter_threat_attack": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Threat-attack security events are logged.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"format": schema.StringAttribute{
+				Optional:    true,
+				Description: "Specify the log stream format.",
+				Validators: []validator.String{
+					stringvalidator.OneOf("binary", "sd-syslog", "syslog", "welf"),
+				},
+			},
+			"rate_limit": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Rate-limit for security logs.",
+				Validators: []validator.Int64{
+					int64validator.Between(1, 65535),
+				},
+			},
+			"severity": schema.StringAttribute{
+				Optional:    true,
+				Description: "Severity threshold for security logs.",
+				Validators: []validator.String{
+					stringvalidator.OneOf(junos.SyslogSeverity()...),
+				},
+			},
+		},
+		Blocks: map[string]schema.Block{
+			"file": schema.SingleNestedBlock{
+				Description: "Configure log file options for logs in local file.",
+				Attributes: map[string]schema.Attribute{
+					"name": schema.StringAttribute{
+						Required:    false, // true when SingleNestedBlock is specified
+						Optional:    true,
+						Description: "Name of local log file.",
+						Validators: []validator.String{
+							stringvalidator.LengthBetween(1, 250),
+							tfvalidator.StringDoubleQuoteExclusion(),
+							tfvalidator.StringSpaceExclusion(),
+							tfvalidator.StringRuneExclusion('/', '%'),
+						},
+					},
+					"allow_duplicates": schema.BoolAttribute{
+						Optional:    true,
+						Description: "To disable log consolidation.",
+						Validators: []validator.Bool{
+							tfvalidator.BoolTrue(),
+						},
+					},
+					"rotation": schema.Int64Attribute{
+						Optional:    true,
+						Description: "Maximum number of rotate files.",
+						Validators: []validator.Int64{
+							int64validator.Between(2, 19),
+						},
+					},
+					"size": schema.Int64Attribute{
+						Optional:    true,
+						Description: "Maximum size of local log file in megabytes.",
+						Validators: []validator.Int64{
+							int64validator.Between(1, 3),
+						},
+					},
+				},
+				PlanModifiers: []planmodifier.Object{
+					tfplanmodifier.BlockRemoveNull(),
+				},
+			},
+			"host": schema.SingleNestedBlock{
+				Description: "Configure destination to send security logs to.",
+				Attributes: map[string]schema.Attribute{
+					"ip_address": schema.StringAttribute{
+						Required:    false, // true when SingleNestedBlock is specified
+						Optional:    true,
+						Description: "IP address.",
+						Validators: []validator.String{
+							stringvalidator.LengthBetween(1, 250),
+							tfvalidator.StringDoubleQuoteExclusion(),
+							tfvalidator.StringSpaceExclusion(),
+						},
+					},
+					"port": schema.Int64Attribute{
+						Optional:    true,
+						Description: "Host port number.",
+						Validators: []validator.Int64{
+							int64validator.Between(1, 65535),
+						},
+					},
+					"routing_instance": schema.StringAttribute{
+						Optional:    true,
+						Description: "Routing instance name.",
+						Validators: []validator.String{
+							stringvalidator.LengthBetween(1, 63),
+							tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+						},
+					},
+				},
+				PlanModifiers: []planmodifier.Object{
+					tfplanmodifier.BlockRemoveNull(),
+				},
+			},
+			"transport": schema.SingleNestedBlock{
+				Description: "Set security log transport settings.",
+				Attributes: map[string]schema.Attribute{
+					"protocol": schema.StringAttribute{
+						Optional:    true,
+						Description: "Set security log transport protocol for the device.",
+						Validators: []validator.String{
+							stringvalidator.OneOf("tcp", "tls", "udp"),
+						},
+					},
+					"tcp_connections": schema.Int64Attribute{
+						Optional:    true,
+						Description: "Set tcp connection number per-stream.",
+						Validators: []validator.Int64{
+							int64validator.Between(1, 5),
+						},
+					},
+					"tls_profile": schema.StringAttribute{
+						Optional:    true,
+						Description: "TLS profile.",
+						Validators: []validator.String{
+							stringvalidator.LengthAtLeast(1),
+							tfvalidator.StringDoubleQuoteExclusion(),
+						},
+					},
+				},
+				PlanModifiers: []planmodifier.Object{
+					tfplanmodifier.BlockRemoveNull(),
+				},
+			},
+		},
+	}
+}
+
+type securityLogStreamData struct {
+	ID                 types.String                     `tfsdk:"id"`
+	Name               types.String                     `tfsdk:"name"`
+	Category           []types.String                   `tfsdk:"category"`
+	FilterThreatAttack types.Bool                       `tfsdk:"filter_threat_attack"`
+	Format             types.String                     `tfsdk:"format"`
+	RateLimit          types.Int64                      `tfsdk:"rate_limit"`
+	Severity           types.String                     `tfsdk:"severity"`
+	File               *securityLogStreamBlockFile      `tfsdk:"file"`
+	Host               *securityLogStreamBlockHost      `tfsdk:"host"`
+	Transport          *securityLogStreamBlockTransport `tfsdk:"transport"`
+}
+
+type securityLogStreamConfig struct {
+	ID                 types.String                     `tfsdk:"id"`
+	Name               types.String                     `tfsdk:"name"`
+	Category           types.List                       `tfsdk:"category"`
+	FilterThreatAttack types.Bool                       `tfsdk:"filter_threat_attack"`
+	Format             types.String                     `tfsdk:"format"`
+	RateLimit          types.Int64                      `tfsdk:"rate_limit"`
+	Severity           types.String                     `tfsdk:"severity"`
+	File               *securityLogStreamBlockFile      `tfsdk:"file"`
+	Host               *securityLogStreamBlockHost      `tfsdk:"host"`
+	Transport          *securityLogStreamBlockTransport `tfsdk:"transport"`
+}
+
+type securityLogStreamBlockFile struct {
+	Name            types.String `tfsdk:"name"`
+	AllowDuplicates types.Bool   `tfsdk:"allow_duplicates"`
+	Rotation        types.Int64  `tfsdk:"rotation"`
+	Size            types.Int64  `tfsdk:"size"`
+}
+
+func (block *securityLogStreamBlockFile) hasKnownValue() bool {
+	return tfdata.CheckBlockHasKnownValue(block)
+}
+
+type securityLogStreamBlockHost struct {
+	IPAddress       types.String `tfsdk:"ip_address"`
+	Port            types.Int64  `tfsdk:"port"`
+	RoutingInstance types.String `tfsdk:"routing_instance"`
+}
+
+func (block *securityLogStreamBlockHost) hasKnownValue() bool {
+	return tfdata.CheckBlockHasKnownValue(block)
+}
+
+type securityLogStreamBlockTransport struct {
+	Protocol       types.String `tfsdk:"protocol"`
+	TCPConnections types.Int64  `tfsdk:"tcp_connections"`
+	TLSProfile     types.String `tfsdk:"tls_profile"`
+}
+
+func (rsc *securityLogStream) ValidateConfig(
+	ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse,
+) {
+	var config securityLogStreamConfig
+	resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	if !config.Category.IsNull() && !config.Category.IsUnknown() &&
+		!config.FilterThreatAttack.IsNull() && !config.FilterThreatAttack.IsUnknown() {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("category"),
+			tfdiag.ConflictConfigErrSummary,
+			"category and filter_threat_attack cannot be configured together",
+		)
+	}
+	if config.File != nil && config.File.hasKnownValue() &&
+		config.Host != nil && config.Host.hasKnownValue() {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("file"),
+			tfdiag.ConflictConfigErrSummary,
+			"file and host cannot be configured together",
+		)
+	}
+	if config.File != nil && config.File.Name.IsNull() {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("file").AtName("name"),
+			tfdiag.MissingConfigErrSummary,
+			"name must be specified in file block",
+		)
+	}
+	if config.Host != nil && config.Host.IPAddress.IsNull() {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("host").AtName("ip_address"),
+			tfdiag.MissingConfigErrSummary,
+			"ip_address must be specified in host block",
+		)
+	}
+	if config.Transport != nil &&
+		!config.Transport.Protocol.IsNull() && !config.Transport.Protocol.IsUnknown() &&
+		config.Transport.Protocol.ValueString() != "tls" &&
+		!config.Transport.TLSProfile.IsNull() && !config.Transport.TLSProfile.IsUnknown() {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("transport").AtName("protocol"),
+			tfdiag.ConflictConfigErrSummary,
+			"protocol must be 'tls' with tls_profile"+
+				" in transport block",
+		)
+	}
+}
+
+func (rsc *securityLogStream) Create(
+	ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse,
+) {
+	var plan securityLogStreamData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+	if plan.Name.ValueString() == "" {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("name"),
+			"Empty Name",
+			defaultResourceCouldNotCreateWithEmptyMessage(rsc, "name"),
+		)
+
+		return
+	}
+
+	defaultResourceCreate(
+		ctx,
+		rsc,
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			if !junSess.CheckCompatibilitySecurity() {
+				resp.Diagnostics.AddError(
+					tfdiag.CompatibilityErrSummary,
+					rsc.junosName()+junSess.SystemInformation.NotCompatibleMsg(),
+				)
+
+				return false
+			}
+			logStreamExists, err := checkSecurityLogStreamExists(fnCtx, plan.Name.ValueString(), junSess)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+				return false
+			}
+			if logStreamExists {
+				resp.Diagnostics.AddError(
+					tfdiag.DuplicateConfigErrSummary,
+					defaultResourceAlreadyExistsMessage(rsc, plan.Name),
+				)
+
+				return false
+			}
+
+			return true
+		},
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			logStreamExists, err := checkSecurityLogStreamExists(fnCtx, plan.Name.ValueString(), junSess)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+				return false
+			}
+			if !logStreamExists {
+				resp.Diagnostics.AddError(
+					tfdiag.NotFoundErrSummary,
+					defaultResourceDoesNotExistsAfterCommitMessage(rsc, plan.Name),
+				)
+
+				return false
+			}
+
+			return true
+		},
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *securityLogStream) Read(
+	ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse,
+) {
+	var state, data securityLogStreamData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	var _ resourceDataReadFrom1String = &data
+	defaultResourceRead(
+		ctx,
+		rsc,
+		[]string{
+			state.Name.ValueString(),
+		},
+		&data,
+		nil,
+		resp,
+	)
+}
+
+func (rsc *securityLogStream) Update(
+	ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse,
+) {
+	var plan, state securityLogStreamData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceUpdate(
+		ctx,
+		rsc,
+		&state,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *securityLogStream) Delete(
+	ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse,
+) {
+	var state securityLogStreamData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceDelete(
+		ctx,
+		rsc,
+		&state,
+		resp,
+	)
+}
+
+func (rsc *securityLogStream) ImportState(
+	ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse,
+) {
+	var data securityLogStreamData
+
+	var _ resourceDataReadFrom1String = &data
+	defaultResourceImportState(
+		ctx,
+		rsc,
+		&data,
+		req,
+		resp,
+		defaultResourceImportDontFindIDStrMessage(rsc, req.ID, "name"),
+	)
+}
+
+func checkSecurityLogStreamExists(
+	_ context.Context, name string, junSess *junos.Session,
+) (
+	bool, error,
+) {
+	showConfig, err := junSess.Command(junos.CmdShowConfig +
+		"security log stream " + name + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
+	}
+	if showConfig == junos.EmptyW {
+		return false, nil
+	}
+
+	return true, nil
+}
+
+func (rscData *securityLogStreamData) fillID() {
+	rscData.ID = types.StringValue(rscData.Name.ValueString())
+}
+
+func (rscData *securityLogStreamData) nullID() bool {
+	return rscData.ID.IsNull()
+}
+
+func (rscData *securityLogStreamData) set(
+	_ context.Context, junSess *junos.Session,
+) (
+	path.Path, error,
+) {
+	setPrefix := "set security log stream " + rscData.Name.ValueString() + " "
+
+	configSet := []string{
+		setPrefix,
+	}
+
+	for _, v := range rscData.Category {
+		configSet = append(configSet, setPrefix+"category "+v.ValueString())
+	}
+	if rscData.FilterThreatAttack.ValueBool() {
+		configSet = append(configSet, setPrefix+"filter threat-attack")
+	}
+	if v := rscData.Format.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"format "+v)
+	}
+	if !rscData.RateLimit.IsNull() {
+		configSet = append(configSet, setPrefix+"rate-limit "+
+			utils.ConvI64toa(rscData.RateLimit.ValueInt64()))
+	}
+	if v := rscData.Severity.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"severity "+v)
+	}
+	if rscData.File != nil {
+		configSet = append(configSet, setPrefix+"file name \""+rscData.File.Name.ValueString()+"\"")
+		if rscData.File.AllowDuplicates.ValueBool() {
+			configSet = append(configSet, setPrefix+"file allow-duplicates")
+		}
+		if !rscData.File.Rotation.IsNull() {
+			configSet = append(configSet, setPrefix+"file rotation "+
+				utils.ConvI64toa(rscData.File.Rotation.ValueInt64()))
+		}
+		if !rscData.File.Size.IsNull() {
+			configSet = append(configSet, setPrefix+"file size "+
+				utils.ConvI64toa(rscData.File.Size.ValueInt64()))
+		}
+	}
+	if rscData.Host != nil {
+		configSet = append(configSet, setPrefix+"host \""+rscData.Host.IPAddress.ValueString()+"\"")
+		if !rscData.Host.Port.IsNull() {
+			configSet = append(configSet, setPrefix+"host port "+
+				utils.ConvI64toa(rscData.Host.Port.ValueInt64()))
+		}
+		if v := rscData.Host.RoutingInstance.ValueString(); v != "" {
+			configSet = append(configSet, setPrefix+"host routing-instance "+v)
+		}
+	}
+	if rscData.Transport != nil {
+		configSet = append(configSet, setPrefix+"transport")
+		if v := rscData.Transport.Protocol.ValueString(); v != "" {
+			configSet = append(configSet, setPrefix+"transport protocol "+v)
+			if v != "tls" && rscData.Transport.TLSProfile.ValueString() != "" {
+				return path.Root("transport").AtName("protocol"),
+					errors.New("protocol must be 'tls' with tls_profile" +
+						" in transport block")
+			}
+		}
+		if !rscData.Transport.TCPConnections.IsNull() {
+			configSet = append(configSet, setPrefix+"transport tcp-connections "+
+				utils.ConvI64toa(rscData.Transport.TCPConnections.ValueInt64()))
+		}
+		if v := rscData.Transport.TLSProfile.ValueString(); v != "" {
+			configSet = append(configSet, setPrefix+"transport tls-profile \""+v+"\"")
+		}
+	}
+
+	return path.Empty(), junSess.ConfigSet(configSet)
+}
+
+func (rscData *securityLogStreamData) read(
+	_ context.Context, name string, junSess *junos.Session,
+) error {
+	showConfig, err := junSess.Command(junos.CmdShowConfig +
+		"security log stream " + name + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
+	if showConfig != junos.EmptyW {
+		rscData.Name = types.StringValue(name)
+		rscData.fillID()
+		for _, item := range strings.Split(showConfig, "\n") {
+			if strings.Contains(item, junos.XMLStartTagConfigOut) {
+				continue
+			}
+			if strings.Contains(item, junos.XMLEndTagConfigOut) {
+				break
+			}
+			itemTrim := strings.TrimPrefix(item, junos.SetLS)
+			switch {
+			case balt.CutPrefixInString(&itemTrim, "category "):
+				rscData.Category = append(rscData.Category, types.StringValue(itemTrim))
+			case itemTrim == "filter threat-attack":
+				rscData.FilterThreatAttack = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "format "):
+				rscData.Format = types.StringValue(itemTrim)
+			case balt.CutPrefixInString(&itemTrim, "rate-limit "):
+				rscData.RateLimit, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "severity "):
+				rscData.Severity = types.StringValue(itemTrim)
+			case balt.CutPrefixInString(&itemTrim, "file "):
+				if rscData.File == nil {
+					rscData.File = &securityLogStreamBlockFile{}
+				}
+				switch {
+				case balt.CutPrefixInString(&itemTrim, "name "):
+					rscData.File.Name = types.StringValue(strings.Trim(itemTrim, "\""))
+				case itemTrim == "allow-duplicates":
+					rscData.File.AllowDuplicates = types.BoolValue(true)
+				case balt.CutPrefixInString(&itemTrim, "rotation "):
+					rscData.File.Rotation, err = tfdata.ConvAtoi64Value(itemTrim)
+					if err != nil {
+						return err
+					}
+				case balt.CutPrefixInString(&itemTrim, "size "):
+					rscData.File.Size, err = tfdata.ConvAtoi64Value(itemTrim)
+					if err != nil {
+						return err
+					}
+				}
+			case balt.CutPrefixInString(&itemTrim, "host "):
+				if rscData.Host == nil {
+					rscData.Host = &securityLogStreamBlockHost{}
+				}
+				switch {
+				case balt.CutPrefixInString(&itemTrim, "port "):
+					rscData.Host.Port, err = tfdata.ConvAtoi64Value(itemTrim)
+					if err != nil {
+						return err
+					}
+				case balt.CutPrefixInString(&itemTrim, "routing-instance "):
+					rscData.Host.RoutingInstance = types.StringValue(itemTrim)
+				default:
+					rscData.Host.IPAddress = types.StringValue(strings.Trim(itemTrim, "\""))
+				}
+			case balt.CutPrefixInString(&itemTrim, "transport"):
+				if rscData.Transport == nil {
+					rscData.Transport = &securityLogStreamBlockTransport{}
+				}
+				switch {
+				case balt.CutPrefixInString(&itemTrim, " protocol "):
+					rscData.Transport.Protocol = types.StringValue(itemTrim)
+				case balt.CutPrefixInString(&itemTrim, " tcp-connections "):
+					rscData.Transport.TCPConnections, err = tfdata.ConvAtoi64Value(itemTrim)
+					if err != nil {
+						return err
+					}
+				case balt.CutPrefixInString(&itemTrim, " tls-profile "):
+					rscData.Transport.TLSProfile = types.StringValue(strings.Trim(itemTrim, "\""))
+				}
+			}
+		}
+	}
+
+	return nil
+}
+
+func (rscData *securityLogStreamData) del(
+	_ context.Context, junSess *junos.Session,
+) error {
+	configSet := []string{
+		"delete security log stream " + rscData.Name.ValueString(),
+	}
+
+	return junSess.ConfigSet(configSet)
+}
diff --git a/internal/providerfwk/resource_security_log_stream_test.go b/internal/providerfwk/resource_security_log_stream_test.go
new file mode 100644
index 00000000..1430738f
--- /dev/null
+++ b/internal/providerfwk/resource_security_log_stream_test.go
@@ -0,0 +1,34 @@
+package providerfwk_test
+
+import (
+	"os"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/config"
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccResourceSecurityLogStream_basic(t *testing.T) {
+	if os.Getenv("TESTACC_SRX") != "" {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ResourceName:      "junos_security_log_stream.testacc_logstream",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providerfwk/resource_security_nat_destination_pool.go b/internal/providerfwk/resource_security_nat_destination_pool.go
index 88cb76ac..024a39d9 100644
--- a/internal/providerfwk/resource_security_nat_destination_pool.go
+++ b/internal/providerfwk/resource_security_nat_destination_pool.go
@@ -341,6 +341,7 @@ func (rscData *securityNatDestinationPoolData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set security nat destination pool " + rscData.Name.ValueString() + " "
+
 	configSet := []string{
 		setPrefix + "address " + rscData.Address.ValueString(),
 	}
diff --git a/internal/providerfwk/resource_security_nat_static.go b/internal/providerfwk/resource_security_nat_static.go
index 1b782ce1..b43d4149 100644
--- a/internal/providerfwk/resource_security_nat_static.go
+++ b/internal/providerfwk/resource_security_nat_static.go
@@ -898,9 +898,7 @@ func (rscData *securityNatStaticData) set(
 
 func (rscData *securityNatStaticData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security nat static rule-set " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_nat_static_rule.go b/internal/providerfwk/resource_security_nat_static_rule.go
index 045fa464..a251eed7 100644
--- a/internal/providerfwk/resource_security_nat_static_rule.go
+++ b/internal/providerfwk/resource_security_nat_static_rule.go
@@ -589,6 +589,7 @@ func (rscData *securityNatStaticRuleData) set(
 	setPrefix := "set security nat static " +
 		"rule-set " + rscData.RuleSet.ValueString() +
 		" rule " + rscData.Name.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
diff --git a/internal/providerfwk/resource_security_policy.go b/internal/providerfwk/resource_security_policy.go
index 4c1debb4..601e0c8f 100644
--- a/internal/providerfwk/resource_security_policy.go
+++ b/internal/providerfwk/resource_security_policy.go
@@ -945,9 +945,7 @@ func (block *securityPolicyBlockPolicyBlockPermitApplicationServices) configSet(
 
 func (rscData *securityPolicyData) read(
 	_ context.Context, fromZone, toZone string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security policies from-zone " + fromZone + " to-zone " + toZone + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_policy_tunnel_pair_policy.go b/internal/providerfwk/resource_security_policy_tunnel_pair_policy.go
index 3831bd32..221b6353 100644
--- a/internal/providerfwk/resource_security_policy_tunnel_pair_policy.go
+++ b/internal/providerfwk/resource_security_policy_tunnel_pair_policy.go
@@ -397,9 +397,7 @@ func (rscData *securityPolicyTunnelPairPolicyData) set(
 
 func (rscData *securityPolicyTunnelPairPolicyData) read(
 	_ context.Context, zoneA, policyAtoB, zoneB, policyBtoA string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security policies from-zone " + zoneA + " to-zone " + zoneB + " policy " + policyAtoB +
 		" then permit tunnel pair-policy" + junos.PipeDisplaySet)
diff --git a/internal/providerfwk/resource_security_test.go b/internal/providerfwk/resource_security_test.go
index 303f65b2..d32e89d1 100644
--- a/internal/providerfwk/resource_security_test.go
+++ b/internal/providerfwk/resource_security_test.go
@@ -22,8 +22,7 @@ func TestAccResourceSecurity_basic(t *testing.T) {
 			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
 			Steps: []resource.TestStep{
 				{
-					ConfigDirectory:    config.TestStepDirectory(),
-					ExpectNonEmptyPlan: true,
+					ConfigDirectory: config.TestStepDirectory(),
 				},
 				{
 					ConfigDirectory: config.TestStepDirectory(),
diff --git a/internal/providerfwk/resource_security_zone.go b/internal/providerfwk/resource_security_zone.go
index f8d45f8b..cf08bc73 100644
--- a/internal/providerfwk/resource_security_zone.go
+++ b/internal/providerfwk/resource_security_zone.go
@@ -995,9 +995,7 @@ func (rscData *securityZoneData) set(
 
 func (rscData *securityZoneData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security zones security-zone " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
@@ -1155,6 +1153,7 @@ func (rscData *securityZoneData) delOpts(
 		listLinesToDelete = append(listLinesToDelete, "address-book")
 	}
 	delPrefix := "delete security zones security-zone " + rscData.Name.ValueString() + " "
+
 	configSet := make([]string, len(listLinesToDelete))
 	for k, line := range listLinesToDelete {
 		configSet[k] = delPrefix + line
diff --git a/internal/providerfwk/resource_security_zone_book_address.go b/internal/providerfwk/resource_security_zone_book_address.go
index 0428e437..28c424fe 100644
--- a/internal/providerfwk/resource_security_zone_book_address.go
+++ b/internal/providerfwk/resource_security_zone_book_address.go
@@ -518,9 +518,7 @@ func (rscData *securityZoneBookAddressData) set(
 
 func (rscData *securityZoneBookAddressData) read(
 	_ context.Context, zone, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security zones security-zone " + zone + " address-book address " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_security_zone_book_address_set.go b/internal/providerfwk/resource_security_zone_book_address_set.go
index df934d47..255df734 100644
--- a/internal/providerfwk/resource_security_zone_book_address_set.go
+++ b/internal/providerfwk/resource_security_zone_book_address_set.go
@@ -411,9 +411,7 @@ func (rscData *securityZoneBookAddressSetData) set(
 
 func (rscData *securityZoneBookAddressSetData) read(
 	_ context.Context, zone, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"security zones security-zone " + zone + " address-book address-set " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_services_flowmonitoring_v9_template.go b/internal/providerfwk/resource_services_flowmonitoring_v9_template.go
index 42fe06bf..59492429 100644
--- a/internal/providerfwk/resource_services_flowmonitoring_v9_template.go
+++ b/internal/providerfwk/resource_services_flowmonitoring_v9_template.go
@@ -624,9 +624,7 @@ func (rscData *servicesFlowMonitoringV9TemplateData) set(
 
 func (rscData *servicesFlowMonitoringV9TemplateData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"services flow-monitoring version9 template \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_services_flowmonitoring_vipfix_template.go b/internal/providerfwk/resource_services_flowmonitoring_vipfix_template.go
index e22c8101..774f3405 100644
--- a/internal/providerfwk/resource_services_flowmonitoring_vipfix_template.go
+++ b/internal/providerfwk/resource_services_flowmonitoring_vipfix_template.go
@@ -620,9 +620,7 @@ func (rscData *servicesFlowMonitoringVIPFixTemplateData) set(
 
 func (rscData *servicesFlowMonitoringVIPFixTemplateData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"services flow-monitoring version-ipfix template \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_snmp.go b/internal/providerfwk/resource_snmp.go
index 44613a76..76b626e4 100644
--- a/internal/providerfwk/resource_snmp.go
+++ b/internal/providerfwk/resource_snmp.go
@@ -482,8 +482,8 @@ func (rscData *snmpData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set snmp "
 	configSet := make([]string, 0)
+	setPrefix := "set snmp "
 
 	if rscData.ARP.ValueBool() {
 		configSet = append(configSet, setPrefix+"arp")
@@ -561,9 +561,7 @@ func (rscData *snmpData) set(
 
 func (rscData *snmpData) read(
 	_ context.Context, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"snmp" + junos.PipeDisplaySetRelative)
 	if err != nil {
@@ -662,6 +660,7 @@ func (rscData *snmpData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
 	delPrefix := "delete snmp "
+
 	configSet := []string{
 		delPrefix + "arp",
 		delPrefix + "contact",
diff --git a/internal/providerfwk/resource_snmp_clientlist.go b/internal/providerfwk/resource_snmp_clientlist.go
index 24d182dd..d4186f15 100644
--- a/internal/providerfwk/resource_snmp_clientlist.go
+++ b/internal/providerfwk/resource_snmp_clientlist.go
@@ -288,6 +288,7 @@ func (rscData *snmpClientlistData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set snmp client-list \"" + rscData.Name.ValueString() + "\" "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -301,9 +302,7 @@ func (rscData *snmpClientlistData) set(
 
 func (rscData *snmpClientlistData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"snmp client-list \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_snmp_community.go b/internal/providerfwk/resource_snmp_community.go
index cfeda98e..a18463a7 100644
--- a/internal/providerfwk/resource_snmp_community.go
+++ b/internal/providerfwk/resource_snmp_community.go
@@ -448,8 +448,8 @@ func (rscData *snmpCommunityData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set snmp community \"" + rscData.Name.ValueString() + "\" "
 	configSet := make([]string, 0)
+	setPrefix := "set snmp community \"" + rscData.Name.ValueString() + "\" "
 
 	if rscData.AuthorizationReadOnly.ValueBool() {
 		configSet = append(configSet, setPrefix+"authorization read-only")
@@ -498,9 +498,7 @@ func (rscData *snmpCommunityData) set(
 
 func (rscData *snmpCommunityData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"snmp community \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_snmp_v3_community.go b/internal/providerfwk/resource_snmp_v3_community.go
index 322f46c2..b96c650f 100644
--- a/internal/providerfwk/resource_snmp_v3_community.go
+++ b/internal/providerfwk/resource_snmp_v3_community.go
@@ -313,6 +313,7 @@ func (rscData *snmpV3CommunityData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set snmp v3 snmp-community \"" + rscData.CommunityIndex.ValueString() + "\" "
+
 	configSet := []string{
 		setPrefix + "security-name \"" + rscData.SecurityName.ValueString() + "\"",
 	}
@@ -332,9 +333,7 @@ func (rscData *snmpV3CommunityData) set(
 
 func (rscData *snmpV3CommunityData) read(
 	_ context.Context, communityIndex string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"snmp v3 snmp-community \"" + communityIndex + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_snmp_v3_usm_user.go b/internal/providerfwk/resource_snmp_v3_usm_user.go
index 887d420f..96d1c70e 100644
--- a/internal/providerfwk/resource_snmp_v3_usm_user.go
+++ b/internal/providerfwk/resource_snmp_v3_usm_user.go
@@ -261,7 +261,7 @@ func (rsc *snmpV3UsmUser) ValidateConfig(
 			resp.Diagnostics.AddAttributeError(
 				path.Root("authentication_type"),
 				tfdiag.MissingConfigErrSummary,
-				"authentication_key or authentication_password must be specified when authentication_type != authentication-none ",
+				"authentication_key or authentication_password must be specified when authentication_type != authentication-none",
 			)
 		}
 	} else if config.AuthenticationType.IsNull() || config.AuthenticationType.ValueString() == "authentication-none" {
@@ -294,7 +294,7 @@ func (rsc *snmpV3UsmUser) ValidateConfig(
 			resp.Diagnostics.AddAttributeError(
 				path.Root("privacy_type"),
 				tfdiag.MissingConfigErrSummary,
-				"privacy_key or privacy_password must be specified when privacy_type != privacy-none ",
+				"privacy_key or privacy_password must be specified when privacy_type != privacy-none",
 			)
 		}
 	} else if config.PrivacyType.IsNull() || config.PrivacyType.ValueString() == "privacy-none" {
@@ -586,41 +586,36 @@ func checkSnmpV3UsmUserExists(
 ) (
 	bool, error,
 ) {
+	showPrefix := junos.CmdShowConfig + "snmp v3 usm "
 	switch engineType {
 	case "local":
-		showConfig, err := junSess.Command(junos.CmdShowConfig +
-			"snmp v3 usm local-engine user \"" + name + "\"" + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
-		if showConfig == junos.EmptyW {
-			return false, nil
-		}
+		showPrefix += "local-engine "
 	case "remote":
-		showConfig, err := junSess.Command(junos.CmdShowConfig +
-			"snmp v3 usm remote-engine \"" + engineID + "\" user \"" + name + "\"" + junos.PipeDisplaySet)
-		if err != nil {
-			return false, err
-		}
-		if showConfig == junos.EmptyW {
-			return false, nil
-		}
+		showPrefix += "remote-engine \"" + engineID + "\" "
 	default:
 		return false, fmt.Errorf("can't check config with engine_type %q", engineType)
 	}
+	showConfig, err := junSess.Command(showPrefix +
+		"user \"" + name + "\"" + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
+	}
+	if showConfig == junos.EmptyW {
+		return false, nil
+	}
 
 	return true, nil
 }
 
 func (rscData *snmpV3UsmUserData) fillID() {
-	switch rscData.EngineType.ValueString() {
-	case "remote":
+	switch v := rscData.EngineType.ValueString(); v {
+	case "local":
 		rscData.ID = types.StringValue(
-			"remote" + junos.IDSeparator + rscData.EngineID.ValueString() + junos.IDSeparator + rscData.Name.ValueString(),
+			v + junos.IDSeparator + rscData.Name.ValueString(),
 		)
-	case "local":
+	case "remote":
 		rscData.ID = types.StringValue(
-			"local" + junos.IDSeparator + rscData.Name.ValueString(),
+			v + junos.IDSeparator + rscData.EngineID.ValueString() + junos.IDSeparator + rscData.Name.ValueString(),
 		)
 	}
 }
@@ -634,16 +629,17 @@ func (rscData *snmpV3UsmUserData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set snmp v3 usm " +
-		"local-engine user \"" + rscData.Name.ValueString() + "\" "
-	if v := rscData.EngineType.ValueString(); v == "remote" {
-		setPrefix = "set snmp v3 usm " +
-			"remote-engine \"" + rscData.EngineID.ValueString() + "\" " +
-			"user \"" + rscData.Name.ValueString() + "\" "
-	} else if v != "local" {
+	configSet := make([]string, 0)
+	setPrefix := "set snmp v3 usm "
+	switch v := rscData.EngineType.ValueString(); v {
+	case "local":
+		setPrefix += "local-engine "
+	case "remote":
+		setPrefix += "remote-engine \"" + rscData.EngineID.ValueString() + "\" "
+	default:
 		return path.Root("engine_type"), fmt.Errorf("can't set config with engine_type %q", v)
 	}
-	configSet := make([]string, 0)
+	setPrefix += "user \"" + rscData.Name.ValueString() + "\" "
 
 	if authenticationType := rscData.AuthenticationType.ValueString(); authenticationType != "authentication-none" {
 		if rscData.AuthenticationKey.ValueString() == "" && rscData.AuthenticationPassword.ValueString() == "" {
@@ -700,18 +696,19 @@ func (rscData *snmpV3UsmUserData) set(
 
 func (rscData *snmpV3UsmUserData) read(
 	_ context.Context, name, engineType, engineID string, junSess *junos.Session,
-) (
-	err error,
-) {
-	showCommand := junos.CmdShowConfig +
-		"snmp v3 usm local-engine user \"" + name + "\"" + junos.PipeDisplaySetRelative
-	if engineType == "remote" {
-		showCommand = junos.CmdShowConfig +
-			"snmp v3 usm remote-engine \"" + engineID + "\" user \"" + name + "\"" + junos.PipeDisplaySetRelative
-	} else {
-		engineType = "local"
+) error {
+	showPrefix := junos.CmdShowConfig + "snmp v3 usm "
+	switch engineType {
+	case "remote":
+		showPrefix += "remote-engine \"" + engineID + "\" "
+	default:
+		if engineType != "local" {
+			engineType = "local"
+		}
+		showPrefix += "local-engine "
 	}
-	showConfig, err := junSess.Command(showCommand)
+	showConfig, err := junSess.Command(showPrefix +
+		"user \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
@@ -759,14 +756,18 @@ func (rscData *snmpV3UsmUserData) read(
 func (rscData *snmpV3UsmUserData) del(
 	_ context.Context, junSess *junos.Session,
 ) error {
-	configSet := []string{
-		"delete snmp v3 usm " +
-			"local-engine user \"" + rscData.Name.ValueString() + "\"",
+	delPrefix := junos.DeleteLS + "snmp v3 usm "
+	switch v := rscData.EngineType.ValueString(); v {
+	case "local":
+		delPrefix += "local-engine "
+	case "remote":
+		delPrefix += "remote-engine \"" + rscData.EngineID.ValueString() + "\" "
+	default:
+		return fmt.Errorf("can't del config with engine_type %q", v)
 	}
-	if rscData.EngineType.ValueString() == "remote" {
-		configSet[0] = "delete snmp v3 usm " +
-			"remote-engine \"" + rscData.EngineID.ValueString() + "\" " +
-			"user \"" + rscData.Name.ValueString() + "\""
+
+	configSet := []string{
+		delPrefix + "user \"" + rscData.Name.ValueString() + "\"",
 	}
 
 	return junSess.ConfigSet(configSet)
diff --git a/internal/providerfwk/resource_snmp_v3_vacm_accessgroup.go b/internal/providerfwk/resource_snmp_v3_vacm_accessgroup.go
index 7d1b87ee..10d66b89 100644
--- a/internal/providerfwk/resource_snmp_v3_vacm_accessgroup.go
+++ b/internal/providerfwk/resource_snmp_v3_vacm_accessgroup.go
@@ -564,8 +564,8 @@ func (rscData *snmpV3VacmAccessgroupData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set snmp v3 vacm access group \"" + rscData.Name.ValueString() + "\" "
 	configSet := make([]string, 0)
+	setPrefix := "set snmp v3 vacm access group \"" + rscData.Name.ValueString() + "\" "
 
 	defaultContextPrefixModelLevel := make(map[string]struct{})
 	for _, block := range rscData.DefaultContextPrefix {
@@ -642,9 +642,7 @@ func (rscData *snmpV3VacmAccessgroupData) set(
 
 func (rscData *snmpV3VacmAccessgroupData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"snmp v3 vacm access group \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_snmp_v3_vacm_securitytogroup.go b/internal/providerfwk/resource_snmp_v3_vacm_securitytogroup.go
index ecd86c2d..37e996f0 100644
--- a/internal/providerfwk/resource_snmp_v3_vacm_securitytogroup.go
+++ b/internal/providerfwk/resource_snmp_v3_vacm_securitytogroup.go
@@ -333,9 +333,7 @@ func (rscData *snmpV3VacmSecuritytogroupData) set(
 
 func (rscData *snmpV3VacmSecuritytogroupData) read(
 	_ context.Context, model, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"snmp v3 vacm security-to-group security-model " + model + " security-name \"" + name + "\"" +
 		junos.PipeDisplaySetRelative)
diff --git a/internal/providerfwk/resource_snmp_view.go b/internal/providerfwk/resource_snmp_view.go
index 17b8d44c..c67ee36e 100644
--- a/internal/providerfwk/resource_snmp_view.go
+++ b/internal/providerfwk/resource_snmp_view.go
@@ -329,8 +329,8 @@ func (rscData *snmpViewData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set snmp view \"" + rscData.Name.ValueString() + "\" "
 	configSet := make([]string, 0)
+	setPrefix := "set snmp view \"" + rscData.Name.ValueString() + "\" "
 
 	for _, v := range rscData.OIDInclude {
 		configSet = append(configSet, setPrefix+"oid \""+v.ValueString()+"\" include")
@@ -344,9 +344,7 @@ func (rscData *snmpViewData) set(
 
 func (rscData *snmpViewData) read(
 	_ context.Context, name string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"snmp view \"" + name + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_static_route.go b/internal/providerfwk/resource_static_route.go
index 54af5d87..f2c4d951 100644
--- a/internal/providerfwk/resource_static_route.go
+++ b/internal/providerfwk/resource_static_route.go
@@ -798,9 +798,10 @@ func (rsc *staticRoute) ImportState(
 	)
 }
 
-func checkStaticRouteExists(_ context.Context, destination, routingInstance string, junSess *junos.Session,
+func checkStaticRouteExists(
+	_ context.Context, destination, routingInstance string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showPrefix := junos.CmdShowConfig
 	switch routingInstance {
@@ -815,11 +816,11 @@ func checkStaticRouteExists(_ context.Context, destination, routingInstance stri
 			showPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
-	showConfig, err := junSess.Command(showPrefix + "static route " + destination + junos.PipeDisplaySet)
+	showConfig, err := junSess.Command(showPrefix +
+		"static route " + destination + junos.PipeDisplaySet)
 	if err != nil {
 		return false, err
 	}
-
 	if showConfig == junos.EmptyW {
 		return false, nil
 	}
@@ -959,9 +960,7 @@ func (rscData *staticRouteData) set(
 
 func (rscData *staticRouteData) read(
 	_ context.Context, destination, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showPrefix := junos.CmdShowConfig
 	switch routingInstance {
 	case junos.DefaultW, "":
@@ -975,16 +974,17 @@ func (rscData *staticRouteData) read(
 			showPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
-	showConfig, err := junSess.Command(showPrefix + "static route " + destination + junos.PipeDisplaySetRelative)
+	showConfig, err := junSess.Command(showPrefix +
+		"static route " + destination + junos.PipeDisplaySetRelative)
 	if err != nil {
 		return err
 	}
-
 	if showConfig != junos.EmptyW {
 		rscData.Destination = types.StringValue(destination)
-		rscData.RoutingInstance = types.StringValue(routingInstance)
-		if rscData.RoutingInstance.ValueString() == "" {
+		if routingInstance == "" {
 			rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+		} else {
+			rscData.RoutingInstance = types.StringValue(routingInstance)
 		}
 		rscData.fillID()
 		for _, item := range strings.Split(showConfig, "\n") {
@@ -1097,6 +1097,7 @@ func (rscData *staticRouteData) del(
 			delPrefix += "rib " + routingInstance + ".inet6.0 "
 		}
 	}
+
 	configSet := []string{
 		delPrefix + "static route " + rscData.Destination.ValueString(),
 	}
diff --git a/internal/providerfwk/resource_switch_options.go b/internal/providerfwk/resource_switch_options.go
index 8d7c3ea3..37a1a5a7 100644
--- a/internal/providerfwk/resource_switch_options.go
+++ b/internal/providerfwk/resource_switch_options.go
@@ -10,6 +10,7 @@ import (
 	"github.com/jeremmfr/terraform-provider-junos/internal/utils"
 
 	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
 	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
 	"github.com/hashicorp/terraform-plugin-framework/path"
 	"github.com/hashicorp/terraform-plugin-framework/resource"
@@ -87,6 +88,28 @@ func (rsc *switchOptions) Schema(
 				Optional:    true,
 				Description: "Clean supported lines when destroy this resource.",
 			},
+			"remote_vtep_list": schema.SetAttribute{
+				ElementType: types.StringType,
+				Optional:    true,
+				Description: "Configure static remote VXLAN tunnel endpoints.",
+				Validators: []validator.Set{
+					setvalidator.SizeAtLeast(1),
+					setvalidator.ValueStringsAre(
+						tfvalidator.StringIPAddress().IPv4Only(),
+					),
+				},
+			},
+			"remote_vtep_v6_list": schema.SetAttribute{
+				ElementType: types.StringType,
+				Optional:    true,
+				Description: "Configure static ipv6 remote VXLAN tunnel endpoints.",
+				Validators: []validator.Set{
+					setvalidator.SizeAtLeast(1),
+					setvalidator.ValueStringsAre(
+						tfvalidator.StringIPAddress().IPv6Only(),
+					),
+				},
+			},
 			"service_id": schema.Int64Attribute{
 				Optional:    true,
 				Description: "Service ID required if multi-chassis AE is part of a bridge-domain.",
@@ -108,10 +131,12 @@ func (rsc *switchOptions) Schema(
 }
 
 type switchOptionsData struct {
-	ID                  types.String `tfsdk:"id"`
-	CleanOnDestroy      types.Bool   `tfsdk:"clean_on_destroy"`
-	ServiceID           types.Int64  `tfsdk:"service_id"`
-	VTEPSourceInterface types.String `tfsdk:"vtep_source_interface"`
+	ID                  types.String   `tfsdk:"id"`
+	CleanOnDestroy      types.Bool     `tfsdk:"clean_on_destroy"`
+	RemoteVtepList      []types.String `tfsdk:"remote_vtep_list"`
+	RemoteVtepV6List    []types.String `tfsdk:"remote_vtep_v6_list"`
+	ServiceID           types.Int64    `tfsdk:"service_id"`
+	VTEPSourceInterface types.String   `tfsdk:"vtep_source_interface"`
 }
 
 func (rsc *switchOptions) Create(
@@ -225,6 +250,12 @@ func (rscData *switchOptionsData) set(
 	configSet := make([]string, 0)
 	setPrefix := "set switch-options "
 
+	for _, v := range rscData.RemoteVtepList {
+		configSet = append(configSet, setPrefix+"remote-vtep-list "+v.ValueString())
+	}
+	for _, v := range rscData.RemoteVtepV6List {
+		configSet = append(configSet, setPrefix+"remote-vtep-v6-list "+v.ValueString())
+	}
 	if !rscData.ServiceID.IsNull() {
 		configSet = append(configSet, setPrefix+"service-id "+
 			utils.ConvI64toa(rscData.ServiceID.ValueInt64()))
@@ -238,9 +269,7 @@ func (rscData *switchOptionsData) set(
 
 func (rscData *switchOptionsData) read(
 	_ context.Context, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"switch-options" + junos.PipeDisplaySetRelative)
 	if err != nil {
@@ -257,6 +286,10 @@ func (rscData *switchOptionsData) read(
 			}
 			itemTrim := strings.TrimPrefix(item, junos.SetLS)
 			switch {
+			case balt.CutPrefixInString(&itemTrim, "remote-vtep-list "):
+				rscData.RemoteVtepList = append(rscData.RemoteVtepList, types.StringValue(itemTrim))
+			case balt.CutPrefixInString(&itemTrim, "remote-vtep-v6-list "):
+				rscData.RemoteVtepV6List = append(rscData.RemoteVtepV6List, types.StringValue(itemTrim))
 			case balt.CutPrefixInString(&itemTrim, "service-id "):
 				rscData.ServiceID, err = tfdata.ConvAtoi64Value(itemTrim)
 				if err != nil {
@@ -277,6 +310,8 @@ func (rscData *switchOptionsData) del(
 	delPrefix := "delete switch-options "
 
 	configSet := []string{
+		delPrefix + "remote-vtep-list",
+		delPrefix + "remote-vtep-v6-list",
 		delPrefix + "service-id",
 		delPrefix + "vtep-source-interface",
 	}
diff --git a/internal/providerfwk/resource_system.go b/internal/providerfwk/resource_system.go
index 3c7084d7..8b9988b3 100644
--- a/internal/providerfwk/resource_system.go
+++ b/internal/providerfwk/resource_system.go
@@ -3223,6 +3223,7 @@ func (block *systemBlockAccounting) configSet() (
 
 func (block *systemBlockAccountingBlockDestinationRadiusServer) configSet() []string {
 	setPrefix := "set system accounting destination radius server " + block.Address.ValueString() + " "
+
 	configSet := []string{
 		setPrefix + "secret \"" + block.Secret.ValueString() + "\"",
 	}
@@ -3278,6 +3279,7 @@ func (block *systemBlockAccountingBlockDestinationRadiusServer) configSet() []st
 
 func (block *systemBlockAccountingBlockDestinationTacplusServer) configSet() []string {
 	setPrefix := "set system accounting destination tacplus server " + block.Address.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -3966,9 +3968,7 @@ func (block *systemBlockSyslog) configSet() (
 
 func (rscData *systemData) read(
 	_ context.Context, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"system" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_system_radius_server.go b/internal/providerfwk/resource_system_radius_server.go
index cc6b6a6a..7b0bb59a 100644
--- a/internal/providerfwk/resource_system_radius_server.go
+++ b/internal/providerfwk/resource_system_radius_server.go
@@ -351,7 +351,7 @@ func (rsc *systemRadiusServer) ImportState(
 func checkSystemRadiusServerExists(
 	_ context.Context, address string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"system radius-server " + address + junos.PipeDisplaySet)
@@ -379,6 +379,7 @@ func (rscData *systemRadiusServerData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set system radius-server " + rscData.Address.ValueString() + " "
+
 	configSet := []string{
 		setPrefix + "secret \"" + rscData.Secret.ValueString() + "\"",
 	}
@@ -434,9 +435,7 @@ func (rscData *systemRadiusServerData) set(
 
 func (rscData *systemRadiusServerData) read(
 	_ context.Context, address string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"system radius-server " + address + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_system_syslog_file.go b/internal/providerfwk/resource_system_syslog_file.go
index d46e5946..45f37995 100644
--- a/internal/providerfwk/resource_system_syslog_file.go
+++ b/internal/providerfwk/resource_system_syslog_file.go
@@ -810,9 +810,7 @@ func (rscData *systemSyslogFileData) set(
 
 func (rscData *systemSyslogFileData) read(
 	_ context.Context, filename string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"system syslog file \"" + filename + "\"" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_system_syslog_host.go b/internal/providerfwk/resource_system_syslog_host.go
index 8ee648fc..99426747 100644
--- a/internal/providerfwk/resource_system_syslog_host.go
+++ b/internal/providerfwk/resource_system_syslog_host.go
@@ -583,9 +583,7 @@ func (rscData *systemSyslogHostData) set(
 
 func (rscData *systemSyslogHostData) read(
 	_ context.Context, host string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"system syslog host " + host + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_system_syslog_user.go b/internal/providerfwk/resource_system_syslog_user.go
index 30f6fc57..53fda0d7 100644
--- a/internal/providerfwk/resource_system_syslog_user.go
+++ b/internal/providerfwk/resource_system_syslog_user.go
@@ -484,9 +484,7 @@ func (rscData *systemSyslogUserData) set(
 
 func (rscData *systemSyslogUserData) read(
 	_ context.Context, username string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"system syslog user " + username + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_system_tacplus_server.go b/internal/providerfwk/resource_system_tacplus_server.go
index 3b9d01f4..2fc67c3e 100644
--- a/internal/providerfwk/resource_system_tacplus_server.go
+++ b/internal/providerfwk/resource_system_tacplus_server.go
@@ -293,7 +293,7 @@ func (rsc *systemTacplusServer) ImportState(
 func checkSystemTacplusServerExists(
 	_ context.Context, address string, junSess *junos.Session,
 ) (
-	_ bool, err error,
+	bool, error,
 ) {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"system tacplus-server " + address + junos.PipeDisplaySet)
@@ -321,6 +321,7 @@ func (rscData *systemTacplusServerData) set(
 	path.Path, error,
 ) {
 	setPrefix := "set system tacplus-server " + rscData.Address.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -351,9 +352,7 @@ func (rscData *systemTacplusServerData) set(
 
 func (rscData *systemTacplusServerData) read(
 	_ context.Context, address string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"system tacplus-server " + address + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_virtual_chassis.go b/internal/providerfwk/resource_virtual_chassis.go
index c4085f49..b1d06b07 100644
--- a/internal/providerfwk/resource_virtual_chassis.go
+++ b/internal/providerfwk/resource_virtual_chassis.go
@@ -604,8 +604,8 @@ func (rscData *virtualChassisData) set(
 ) (
 	path.Path, error,
 ) {
-	setPrefix := "set virtual-chassis "
 	configSet := make([]string, 0)
+	setPrefix := "set virtual-chassis "
 
 	if rscData.AutoSWUpdate.ValueBool() {
 		configSet = append(configSet, setPrefix+"auto-sw-update")
@@ -689,8 +689,8 @@ func (rscData *virtualChassisData) set(
 }
 
 func (block *virtualChassisBlockMember) configSet() []string {
-	setPrefix := "set virtual-chassis member " + utils.ConvI64toa(block.ID.ValueInt64()) + " "
 	configSet := make([]string, 0, 1)
+	setPrefix := "set virtual-chassis member " + utils.ConvI64toa(block.ID.ValueInt64()) + " "
 
 	if v := block.Location.ValueString(); v != "" {
 		configSet = append(configSet, setPrefix+"location \""+v+"\"")
@@ -714,6 +714,7 @@ func (block *virtualChassisBlockMember) configSet() []string {
 
 func (block *virtualChassisBlockTraceoptionsBlockFile) configSet() []string {
 	setPrefix := "set virtual-chassis traceoptions file "
+
 	configSet := []string{
 		setPrefix + "\"" + block.Name.ValueString() + "\"",
 	}
@@ -744,9 +745,7 @@ func (block *virtualChassisBlockTraceoptionsBlockFile) configSet() []string {
 
 func (rscData *virtualChassisData) read(
 	_ context.Context, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showConfig, err := junSess.Command(junos.CmdShowConfig +
 		"virtual-chassis" + junos.PipeDisplaySetRelative)
 	if err != nil {
diff --git a/internal/providerfwk/resource_vlan.go b/internal/providerfwk/resource_vlan.go
index 71c2e932..c554d648 100644
--- a/internal/providerfwk/resource_vlan.go
+++ b/internal/providerfwk/resource_vlan.go
@@ -270,6 +270,17 @@ func (rsc *vlan) Schema(
 							tfvalidator.BoolTrue(),
 						},
 					},
+					"static_remote_vtep_list": schema.SetAttribute{
+						ElementType: types.StringType,
+						Optional:    true,
+						Description: "Configure vlan specific static remote VXLAN tunnel endpoints.",
+						Validators: []validator.Set{
+							setvalidator.SizeAtLeast(1),
+							setvalidator.ValueStringsAre(
+								tfvalidator.StringIPAddress().IPv4Only(),
+							),
+						},
+					},
 					"translation_vni": schema.Int64Attribute{
 						Optional:    true,
 						Description: "Translated VXLAN identifier.",
@@ -313,22 +324,22 @@ type vlanData struct {
 }
 
 type vlanConfig struct {
-	ID                  types.String    `tfsdk:"id"`
-	Name                types.String    `tfsdk:"name"`
-	RoutingInstance     types.String    `tfsdk:"routing_instance"`
-	CommunityVlans      types.Set       `tfsdk:"community_vlans"`
-	Description         types.String    `tfsdk:"description"`
-	ForwardFilterInput  types.String    `tfsdk:"forward_filter_input"`
-	ForwardFilterOutput types.String    `tfsdk:"forward_filter_output"`
-	ForwardFloodInput   types.String    `tfsdk:"forward_flood_input"`
-	IsolatedVlan        types.String    `tfsdk:"isolated_vlan"`
-	L3Interface         types.String    `tfsdk:"l3_interface"`
-	NoARPSuppression    types.Bool      `tfsdk:"no_arp_suppression"`
-	PrivateVlan         types.String    `tfsdk:"private_vlan"`
-	ServiceID           types.Int64     `tfsdk:"service_id"`
-	VlanID              types.String    `tfsdk:"vlan_id"`
-	VlanIDList          types.Set       `tfsdk:"vlan_id_list"`
-	Vxlan               *vlanBlockVxlan `tfsdk:"vxlan"`
+	ID                  types.String          `tfsdk:"id"`
+	Name                types.String          `tfsdk:"name"`
+	RoutingInstance     types.String          `tfsdk:"routing_instance"`
+	CommunityVlans      types.Set             `tfsdk:"community_vlans"`
+	Description         types.String          `tfsdk:"description"`
+	ForwardFilterInput  types.String          `tfsdk:"forward_filter_input"`
+	ForwardFilterOutput types.String          `tfsdk:"forward_filter_output"`
+	ForwardFloodInput   types.String          `tfsdk:"forward_flood_input"`
+	IsolatedVlan        types.String          `tfsdk:"isolated_vlan"`
+	L3Interface         types.String          `tfsdk:"l3_interface"`
+	NoARPSuppression    types.Bool            `tfsdk:"no_arp_suppression"`
+	PrivateVlan         types.String          `tfsdk:"private_vlan"`
+	ServiceID           types.Int64           `tfsdk:"service_id"`
+	VlanID              types.String          `tfsdk:"vlan_id"`
+	VlanIDList          types.Set             `tfsdk:"vlan_id_list"`
+	Vxlan               *vlanBlockVxlanConfig `tfsdk:"vxlan"`
 }
 
 func (rscConfig *vlanConfig) isEmpty() bool {
@@ -336,12 +347,25 @@ func (rscConfig *vlanConfig) isEmpty() bool {
 }
 
 type vlanBlockVxlan struct {
+	Vni                       types.Int64    `tfsdk:"vni"`
+	VniExtendEvpn             types.Bool     `tfsdk:"vni_extend_evpn"`
+	EncapsulateInnerVlan      types.Bool     `tfsdk:"encapsulate_inner_vlan"`
+	IngressNodeReplication    types.Bool     `tfsdk:"ingress_node_replication"`
+	MulticastGroup            types.String   `tfsdk:"multicast_group"`
+	OvsdbManaged              types.Bool     `tfsdk:"ovsdb_managed"`
+	StaticRemoteVtepList      []types.String `tfsdk:"static_remote_vtep_list"`
+	TranslationVni            types.Int64    `tfsdk:"translation_vni"`
+	UnreachableVtepAgingTimer types.Int64    `tfsdk:"unreachable_vtep_aging_timer"`
+}
+
+type vlanBlockVxlanConfig struct {
 	Vni                       types.Int64  `tfsdk:"vni"`
 	VniExtendEvpn             types.Bool   `tfsdk:"vni_extend_evpn"`
 	EncapsulateInnerVlan      types.Bool   `tfsdk:"encapsulate_inner_vlan"`
 	IngressNodeReplication    types.Bool   `tfsdk:"ingress_node_replication"`
 	MulticastGroup            types.String `tfsdk:"multicast_group"`
 	OvsdbManaged              types.Bool   `tfsdk:"ovsdb_managed"`
+	StaticRemoteVtepList      types.Set    `tfsdk:"static_remote_vtep_list"`
 	TranslationVni            types.Int64  `tfsdk:"translation_vni"`
 	UnreachableVtepAgingTimer types.Int64  `tfsdk:"unreachable_vtep_aging_timer"`
 }
@@ -606,7 +630,6 @@ func checkVlanExists(
 	if routingInstance != "" && routingInstance != junos.DefaultW {
 		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
-
 	showConfig, err := junSess.Command(showPrefix +
 		"vlans " + name + junos.PipeDisplaySet)
 	if err != nil {
@@ -701,6 +724,9 @@ func (rscData *vlanData) set(
 		if rscData.Vxlan.OvsdbManaged.ValueBool() {
 			configSet = append(configSet, setPrefix+"vxlan ovsdb-managed")
 		}
+		for _, v := range rscData.Vxlan.StaticRemoteVtepList {
+			configSet = append(configSet, setPrefix+"vxlan static-remote-vtep-list "+v.ValueString())
+		}
 		if !rscData.Vxlan.TranslationVni.IsNull() {
 			configSet = append(configSet, setPrefix+"vxlan translation-vni "+
 				utils.ConvI64toa(rscData.Vxlan.TranslationVni.ValueInt64()))
@@ -716,14 +742,11 @@ func (rscData *vlanData) set(
 
 func (rscData *vlanData) read(
 	_ context.Context, name, routingInstance string, junSess *junos.Session,
-) (
-	err error,
-) {
+) error {
 	showPrefix := junos.CmdShowConfig
 	if routingInstance != "" && routingInstance != junos.DefaultW {
 		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
 	}
-
 	showConfig, err := junSess.Command(showPrefix +
 		"vlans " + name + junos.PipeDisplaySetRelative)
 	if err != nil {
@@ -808,6 +831,8 @@ func (rscData *vlanData) read(
 					rscData.Vxlan.MulticastGroup = types.StringValue(itemTrim)
 				case itemTrim == "ovsdb-managed":
 					rscData.Vxlan.OvsdbManaged = types.BoolValue(true)
+				case balt.CutPrefixInString(&itemTrim, "static-remote-vtep-list "):
+					rscData.Vxlan.StaticRemoteVtepList = append(rscData.Vxlan.StaticRemoteVtepList, types.StringValue(itemTrim))
 				case balt.CutPrefixInString(&itemTrim, "translation-vni "):
 					rscData.Vxlan.TranslationVni, err = tfdata.ConvAtoi64Value(itemTrim)
 					if err != nil {
diff --git a/internal/providerfwk/resource_vlan_test.go b/internal/providerfwk/resource_vlan_test.go
index 70a22baa..59b02f65 100644
--- a/internal/providerfwk/resource_vlan_test.go
+++ b/internal/providerfwk/resource_vlan_test.go
@@ -59,3 +59,20 @@ func TestAccResourceVlan_basic(t *testing.T) {
 		})
 	}
 }
+
+func TestAccResourceVlan_router(t *testing.T) {
+	if os.Getenv("TESTACC_ROUTER") != "" {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providerfwk/resource_vstp.go b/internal/providerfwk/resource_vstp.go
new file mode 100644
index 00000000..9607c962
--- /dev/null
+++ b/internal/providerfwk/resource_vstp.go
@@ -0,0 +1,549 @@
+package providerfwk
+
+import (
+	"context"
+	"fmt"
+	"strings"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdata"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdiag"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfvalidator"
+	"github.com/jeremmfr/terraform-provider-junos/internal/utils"
+
+	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+	"github.com/hashicorp/terraform-plugin-framework/path"
+	"github.com/hashicorp/terraform-plugin-framework/resource"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+	balt "github.com/jeremmfr/go-utils/basicalter"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+	_ resource.Resource                   = &vstp{}
+	_ resource.ResourceWithConfigure      = &vstp{}
+	_ resource.ResourceWithValidateConfig = &vstp{}
+	_ resource.ResourceWithImportState    = &vstp{}
+)
+
+type vstp struct {
+	client *junos.Client
+}
+
+func newVstpResource() resource.Resource {
+	return &vstp{}
+}
+
+func (rsc *vstp) typeName() string {
+	return providerName + "_vstp"
+}
+
+func (rsc *vstp) junosName() string {
+	return "protocols vstp"
+}
+
+func (rsc *vstp) junosClient() *junos.Client {
+	return rsc.client
+}
+
+func (rsc *vstp) Metadata(
+	_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse,
+) {
+	resp.TypeName = rsc.typeName()
+}
+
+func (rsc *vstp) Configure(
+	ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse,
+) {
+	// Prevent panic if the provider has not been configured.
+	if req.ProviderData == nil {
+		return
+	}
+	client, ok := req.ProviderData.(*junos.Client)
+	if !ok {
+		unexpectedResourceConfigureType(ctx, req, resp)
+
+		return
+	}
+	rsc.client = client
+}
+
+func (rsc *vstp) Schema(
+	_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse,
+) {
+	resp.Schema = schema.Schema{
+		Description: "Configure static configuration in `" + rsc.junosName() + "` block",
+		Attributes: map[string]schema.Attribute{
+			"id": schema.StringAttribute{
+				Computed:    true,
+				Description: "An identifier for the resource with format `<routing_instance>`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.UseStateForUnknown(),
+				},
+			},
+			"routing_instance": schema.StringAttribute{
+				Optional:    true,
+				Computed:    true,
+				Default:     stringdefault.StaticString(junos.DefaultW),
+				Description: "Routing instance for vstp protocol if not root level.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+
+			"bpdu_block_on_edge": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Block BPDU on all interfaces configured as edge (BPDU Protect).",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"disable": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Disable STP.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"force_version_stp": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Force protocol version STP.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"priority_hold_time": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Hold time before switching to primary priority when core domain becomes up (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(1, 255),
+				},
+			},
+			"vpls_flush_on_topology_change": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Enable VPLS MAC flush on root protected CE interface receiving topology change.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+		},
+		Blocks: map[string]schema.Block{
+			"system_id": schema.SetNestedBlock{
+				Description: "For each ID, System ID to IP mapping.",
+				NestedObject: schema.NestedBlockObject{
+					Attributes: map[string]schema.Attribute{
+						"id": schema.StringAttribute{
+							Required:    true,
+							Description: "System ID.",
+							Validators: []validator.String{
+								tfvalidator.StringMACAddress().WithMac48ColonHexa(),
+							},
+						},
+						"ip_address": schema.StringAttribute{
+							Optional:    true,
+							Description: "Peer ID (IP Address).",
+							Validators: []validator.String{
+								tfvalidator.StringCIDR(),
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+}
+
+type vstpData struct {
+	ID                        types.String        `tfsdk:"id"`
+	RoutingInstance           types.String        `tfsdk:"routing_instance"`
+	BpduBlockOnEdge           types.Bool          `tfsdk:"bpdu_block_on_edge"`
+	Disable                   types.Bool          `tfsdk:"disable"`
+	ForceVersionStp           types.Bool          `tfsdk:"force_version_stp"`
+	PriorityHoldTime          types.Int64         `tfsdk:"priority_hold_time"`
+	VplsFlushOnTopologyChange types.Bool          `tfsdk:"vpls_flush_on_topology_change"`
+	SystemID                  []vstpBlockSystemID `tfsdk:"system_id"`
+}
+
+type vstpConfig struct {
+	ID                        types.String `tfsdk:"id"`
+	RoutingInstance           types.String `tfsdk:"routing_instance"`
+	BpduBlockOnEdge           types.Bool   `tfsdk:"bpdu_block_on_edge"`
+	Disable                   types.Bool   `tfsdk:"disable"`
+	ForceVersionStp           types.Bool   `tfsdk:"force_version_stp"`
+	PriorityHoldTime          types.Int64  `tfsdk:"priority_hold_time"`
+	VplsFlushOnTopologyChange types.Bool   `tfsdk:"vpls_flush_on_topology_change"`
+	SystemID                  types.Set    `tfsdk:"system_id"`
+}
+
+type vstpBlockSystemID struct {
+	ID        types.String `tfsdk:"id"`
+	IPAddress types.String `tfsdk:"ip_address"`
+}
+
+func (rsc *vstp) ValidateConfig(
+	ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse,
+) {
+	var config vstpConfig
+	resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	if !config.SystemID.IsNull() && !config.SystemID.IsUnknown() {
+		var systemID []vstpBlockSystemID
+		asDiags := config.SystemID.ElementsAs(ctx, &systemID, false)
+		if asDiags.HasError() {
+			resp.Diagnostics.Append(asDiags...)
+
+			return
+		}
+		systemIDID := make(map[string]struct{})
+		for _, block := range systemID {
+			if block.ID.IsUnknown() {
+				continue
+			}
+			id := block.ID.ValueString()
+			if _, ok := systemIDID[id]; ok {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("system_id"),
+					tfdiag.DuplicateConfigErrSummary,
+					fmt.Sprintf("multiple system_id blocks with the same id %q", id),
+				)
+			}
+			systemIDID[id] = struct{}{}
+		}
+	}
+}
+
+func (rsc *vstp) Create(
+	ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse,
+) {
+	var plan vstpData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceCreate(
+		ctx,
+		rsc,
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+				instanceExists, err := checkRoutingInstanceExists(fnCtx, v, junSess)
+				if err != nil {
+					resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+					return false
+				}
+				if !instanceExists {
+					resp.Diagnostics.AddAttributeError(
+						path.Root("routing_instance"),
+						tfdiag.MissingConfigErrSummary,
+						fmt.Sprintf("routing instance %q doesn't exist", v),
+					)
+
+					return false
+				}
+			}
+
+			return true
+		},
+		nil,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *vstp) Read(
+	ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse,
+) {
+	var state, data vstpData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	junSess, err := rsc.junosClient().StartNewSession(ctx)
+	if err != nil {
+		resp.Diagnostics.AddError(tfdiag.StartSessErrSummary, err.Error())
+
+		return
+	}
+	defer junSess.Close()
+
+	junos.MutexLock()
+	if v := state.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		instanceExists, err := checkRoutingInstanceExists(ctx, v, junSess)
+		if err != nil {
+			junos.MutexUnlock()
+			resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+			return
+		}
+		if !instanceExists {
+			junos.MutexUnlock()
+			resp.State.RemoveResource(ctx)
+
+			return
+		}
+	}
+
+	err = data.read(ctx, state.RoutingInstance.ValueString(), junSess)
+	junos.MutexUnlock()
+	if err != nil {
+		resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+		return
+	}
+
+	if data.nullID() {
+		resp.State.RemoveResource(ctx)
+
+		return
+	}
+
+	resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
+}
+
+func (rsc *vstp) Update(
+	ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse,
+) {
+	var plan, state vstpData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceUpdate(
+		ctx,
+		rsc,
+		&state,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *vstp) Delete(
+	ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse,
+) {
+	var state vstpData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceDelete(
+		ctx,
+		rsc,
+		&state,
+		resp,
+	)
+}
+
+func (rsc *vstp) ImportState(
+	ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse,
+) {
+	junSess, err := rsc.junosClient().StartNewSession(ctx)
+	if err != nil {
+		resp.Diagnostics.AddError(tfdiag.StartSessErrSummary, err.Error())
+
+		return
+	}
+	defer junSess.Close()
+
+	if req.ID != junos.DefaultW {
+		instanceExists, err := checkRoutingInstanceExists(ctx, req.ID, junSess)
+		if err != nil {
+			resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+			return
+		}
+		if !instanceExists {
+			resp.Diagnostics.AddError(
+				tfdiag.NotFoundErrSummary,
+				fmt.Sprintf("routing instance %q doesn't exist", req.ID),
+			)
+
+			return
+		}
+	}
+
+	var data vstpData
+	if err := data.read(ctx, req.ID, junSess); err != nil {
+		resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+		return
+	}
+	if data.nullID() {
+		resp.Diagnostics.AddError(
+			tfdiag.NotFoundErrSummary,
+			defaultResourceImportDontFindMessage(rsc, req.ID)+
+				" (id must be <routing_instance>)",
+		)
+
+		return
+	}
+
+	resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
+}
+
+func (rscData *vstpData) fillID() {
+	if v := rscData.RoutingInstance.ValueString(); v != "" {
+		rscData.ID = types.StringValue(v)
+	} else {
+		rscData.ID = types.StringValue(junos.DefaultW)
+	}
+}
+
+func (rscData *vstpData) nullID() bool {
+	return rscData.ID.IsNull()
+}
+
+func (rscData *vstpData) set(
+	_ context.Context, junSess *junos.Session,
+) (
+	path.Path, error,
+) {
+	configSet := make([]string, 0)
+	setPrefix := junos.SetLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		setPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	setPrefix += "protocols vstp "
+
+	if rscData.BpduBlockOnEdge.ValueBool() {
+		configSet = append(configSet, setPrefix+"bpdu-block-on-edge")
+	}
+	if rscData.Disable.ValueBool() {
+		configSet = append(configSet, setPrefix+"disable")
+	}
+	if rscData.ForceVersionStp.ValueBool() {
+		configSet = append(configSet, setPrefix+"force-version stp")
+	}
+
+	if !rscData.PriorityHoldTime.IsNull() {
+		configSet = append(configSet, setPrefix+"priority-hold-time "+
+			utils.ConvI64toa(rscData.PriorityHoldTime.ValueInt64()))
+	}
+	if rscData.VplsFlushOnTopologyChange.ValueBool() {
+		configSet = append(configSet, setPrefix+"vpls-flush-on-topology-change")
+	}
+	systemIDID := make(map[string]struct{})
+	for _, block := range rscData.SystemID {
+		id := block.ID.ValueString()
+		if _, ok := systemIDID[id]; ok {
+			return path.Root("system_id"),
+				fmt.Errorf("multiple system_id blocks with the same id %q", id)
+		}
+		systemIDID[id] = struct{}{}
+
+		configSet = append(configSet, setPrefix+"system-id "+id)
+		if v := block.IPAddress.ValueString(); v != "" {
+			configSet = append(configSet, setPrefix+"system-id "+id+" ip-address "+v)
+		}
+	}
+
+	return path.Empty(), junSess.ConfigSet(configSet)
+}
+
+func (rscData *vstpData) read(
+	_ context.Context, routingInstance string, junSess *junos.Session,
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols vstp" + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
+	if routingInstance == "" {
+		rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+	} else {
+		rscData.RoutingInstance = types.StringValue(routingInstance)
+	}
+	rscData.fillID()
+	if showConfig != junos.EmptyW {
+		for _, item := range strings.Split(showConfig, "\n") {
+			if strings.Contains(item, junos.XMLStartTagConfigOut) {
+				continue
+			}
+			if strings.Contains(item, junos.XMLEndTagConfigOut) {
+				break
+			}
+			itemTrim := strings.TrimPrefix(item, junos.SetLS)
+			switch {
+			case itemTrim == "bpdu-block-on-edge":
+				rscData.BpduBlockOnEdge = types.BoolValue(true)
+			case itemTrim == junos.DisableW:
+				rscData.Disable = types.BoolValue(true)
+			case itemTrim == "force-version stp":
+				rscData.ForceVersionStp = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "priority-hold-time "):
+				rscData.PriorityHoldTime, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case itemTrim == "vpls-flush-on-topology-change":
+				rscData.VplsFlushOnTopologyChange = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "system-id "):
+				itemTrimFields := strings.Split(itemTrim, " ")
+				switch len(itemTrimFields) { // <id> (ip-address <ip_address>)?
+				case 1:
+					rscData.SystemID = append(rscData.SystemID, vstpBlockSystemID{
+						ID: types.StringValue(itemTrimFields[0]),
+					})
+				case 3:
+					rscData.SystemID = append(rscData.SystemID, vstpBlockSystemID{
+						ID:        types.StringValue(itemTrimFields[0]),
+						IPAddress: types.StringValue(itemTrimFields[2]),
+					})
+				default:
+					return fmt.Errorf(junos.CantReadValuesNotEnoughFields, "system-id", itemTrim)
+				}
+			}
+		}
+	}
+
+	return nil
+}
+
+func (rscData *vstpData) del(
+	_ context.Context, junSess *junos.Session,
+) error {
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	delPrefix += "protocols vstp "
+
+	listLinesToDelete := []string{
+		"bpdu-block-on-edge",
+		"disable",
+		"force-version",
+		"priority-hold-time",
+		"vpls-flush-on-topology-change",
+	}
+
+	configSet := make([]string, len(listLinesToDelete), len(listLinesToDelete)+len(rscData.SystemID))
+	for k, line := range listLinesToDelete {
+		configSet[k] = delPrefix + line
+	}
+	for _, block := range rscData.SystemID {
+		configSet = append(configSet, delPrefix+"system-id "+block.ID.ValueString())
+	}
+
+	return junSess.ConfigSet(configSet)
+}
diff --git a/internal/providerfwk/resource_vstp_interface.go b/internal/providerfwk/resource_vstp_interface.go
new file mode 100644
index 00000000..490da5d4
--- /dev/null
+++ b/internal/providerfwk/resource_vstp_interface.go
@@ -0,0 +1,778 @@
+package providerfwk
+
+import (
+	"context"
+	"fmt"
+	"regexp"
+	"strings"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdata"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdiag"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfvalidator"
+	"github.com/jeremmfr/terraform-provider-junos/internal/utils"
+
+	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+	"github.com/hashicorp/terraform-plugin-framework/path"
+	"github.com/hashicorp/terraform-plugin-framework/resource"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+	balt "github.com/jeremmfr/go-utils/basicalter"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+	_ resource.Resource                   = &vstpInterface{}
+	_ resource.ResourceWithConfigure      = &vstpInterface{}
+	_ resource.ResourceWithValidateConfig = &vstpInterface{}
+	_ resource.ResourceWithImportState    = &vstpInterface{}
+)
+
+type vstpInterface struct {
+	client *junos.Client
+}
+
+func newVstpInterfaceResource() resource.Resource {
+	return &vstpInterface{}
+}
+
+func (rsc *vstpInterface) typeName() string {
+	return providerName + "_vstp_interface"
+}
+
+func (rsc *vstpInterface) junosName() string {
+	return "vstp interface"
+}
+
+func (rsc *vstpInterface) junosClient() *junos.Client {
+	return rsc.client
+}
+
+func (rsc *vstpInterface) Metadata(
+	_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse,
+) {
+	resp.TypeName = rsc.typeName()
+}
+
+func (rsc *vstpInterface) Configure(
+	ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse,
+) {
+	// Prevent panic if the provider has not been configured.
+	if req.ProviderData == nil {
+		return
+	}
+	client, ok := req.ProviderData.(*junos.Client)
+	if !ok {
+		unexpectedResourceConfigureType(ctx, req, resp)
+
+		return
+	}
+	rsc.client = client
+}
+
+func (rsc *vstpInterface) Schema(
+	_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse,
+) {
+	resp.Schema = schema.Schema{
+		Description: defaultResourceSchemaDescription(rsc),
+		Attributes: map[string]schema.Attribute{
+			"id": schema.StringAttribute{
+				Computed: true,
+				Description: "An identifier for the resource with format " +
+					"`<name>" + junos.IDSeparator + junos.IDSeparator + "<routing_instance>`, " +
+					"`<name>" + junos.IDSeparator + "v_<vlan>" + junos.IDSeparator + "<routing_instance>` or " +
+					"`<name>" + junos.IDSeparator + "vg_<vlan_group>" + junos.IDSeparator + "<routing_instance>`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.UseStateForUnknown(),
+				},
+			},
+			"name": schema.StringAttribute{
+				Required:    true,
+				Description: "Interface name or `all`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthAtLeast(1),
+					tfvalidator.StringFormat(tfvalidator.InterfaceFormat),
+					tfvalidator.StringDotExclusion(),
+				},
+			},
+			"routing_instance": schema.StringAttribute{
+				Optional:    true,
+				Computed:    true,
+				Default:     stringdefault.StaticString(junos.DefaultW),
+				Description: "Routing instance for vstp protocol if not root level.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+			"vlan": schema.StringAttribute{
+				Optional:    true,
+				Description: "Configure interface in VSTP vlan.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.RegexMatches(regexp.MustCompile(
+						`^(409[0-4]|(40[0-8]|[1-3]\d\d|[1-9]\d|[1-9])\d|[1-9]|all)$`),
+						"must be a VLAN id (1..4094) or all"),
+				},
+			},
+			"vlan_group": schema.StringAttribute{
+				Optional:    true,
+				Description: "Configure interface in VSTP vlan-group.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+			"access_trunk": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Send/Receive untagged RSTP BPDUs on this interface.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"bpdu_timeout_action_alarm": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Generate an alarm on BPDU expiry (Loop Protect).",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"bpdu_timeout_action_block": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Block the interface on BPDU expiry (Loop Protect).",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"cost": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Cost of the interface.",
+				Validators: []validator.Int64{
+					int64validator.Between(1, 200000000),
+				},
+			},
+			"edge": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Port is an edge port.",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"mode": schema.StringAttribute{
+				Optional:    true,
+				Description: "Interface mode (P2P or shared).",
+				Validators: []validator.String{
+					stringvalidator.OneOf("point-to-point", "shared"),
+				},
+			},
+			"no_root_port": schema.BoolAttribute{
+				Optional:    true,
+				Description: "Do not allow the interface to become root (Root Protect).",
+				Validators: []validator.Bool{
+					tfvalidator.BoolTrue(),
+				},
+			},
+			"priority": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Interface priority (in increments of 16).",
+				Validators: []validator.Int64{
+					int64validator.Between(0, 240),
+				},
+			},
+		},
+	}
+}
+
+type vstpInterfaceData struct {
+	ID                     types.String `tfsdk:"id"`
+	Name                   types.String `tfsdk:"name"`
+	RoutingInstance        types.String `tfsdk:"routing_instance"`
+	Vlan                   types.String `tfsdk:"vlan"`
+	VlanGroup              types.String `tfsdk:"vlan_group"`
+	AccessTrunk            types.Bool   `tfsdk:"access_trunk"`
+	BpduTimeoutActionAlarm types.Bool   `tfsdk:"bpdu_timeout_action_alarm"`
+	BpduTimeoutActionBlock types.Bool   `tfsdk:"bpdu_timeout_action_block"`
+	Cost                   types.Int64  `tfsdk:"cost"`
+	Edge                   types.Bool   `tfsdk:"edge"`
+	Mode                   types.String `tfsdk:"mode"`
+	NoRootPort             types.Bool   `tfsdk:"no_root_port"`
+	Priority               types.Int64  `tfsdk:"priority"`
+}
+
+func (rsc *vstpInterface) ValidateConfig(
+	ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse,
+) {
+	var config vstpInterfaceData
+	resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	if !config.Vlan.IsNull() && !config.Vlan.IsUnknown() &&
+		!config.VlanGroup.IsNull() && !config.VlanGroup.IsUnknown() {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("vlan"),
+			tfdiag.ConflictConfigErrSummary,
+			"vlan and vlan_group cannot be configured together",
+		)
+	}
+	if !config.Priority.IsNull() && !config.Priority.IsUnknown() {
+		if config.Priority.ValueInt64()%16 != 0 {
+			resp.Diagnostics.AddAttributeError(
+				path.Root("priority"),
+				"Bad Value Error",
+				"priority must be a multiple of 16",
+			)
+		}
+	}
+}
+
+func (rsc *vstpInterface) Create(
+	ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse,
+) {
+	var plan vstpInterfaceData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+	if plan.Name.ValueString() == "" {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("name"),
+			"Empty Name",
+			defaultResourceCouldNotCreateWithEmptyMessage(rsc, "name"),
+		)
+
+		return
+	}
+	if !plan.Vlan.IsNull() && !plan.VlanGroup.IsNull() {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("vlan"),
+			tfdiag.ConflictConfigErrSummary,
+			"vlan and vlan_group cannot be configured together",
+		)
+
+		return
+	}
+
+	defaultResourceCreate(
+		ctx,
+		rsc,
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+				instanceExists, err := checkRoutingInstanceExists(fnCtx, v, junSess)
+				if err != nil {
+					resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+					return false
+				}
+				if !instanceExists {
+					resp.Diagnostics.AddAttributeError(
+						path.Root("routing_instance"),
+						tfdiag.MissingConfigErrSummary,
+						fmt.Sprintf("routing instance %q doesn't exist", v),
+					)
+
+					return false
+				}
+			}
+			if v := plan.Vlan.ValueString(); v != "" {
+				vlanExists, err := checkVstpVlanExists(fnCtx, v, plan.RoutingInstance.ValueString(), junSess)
+				if err != nil {
+					resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+					return false
+				}
+				if !vlanExists {
+					if vRI := plan.RoutingInstance.ValueString(); vRI != "" && vRI != junos.DefaultW {
+						resp.Diagnostics.AddAttributeError(
+							path.Root("vlan"),
+							tfdiag.MissingConfigErrSummary,
+							fmt.Sprintf("vstp vlan %q in routing-instance %q doesn't exist", v, vRI),
+						)
+					} else {
+						resp.Diagnostics.AddAttributeError(
+							path.Root("vlan"),
+							tfdiag.MissingConfigErrSummary,
+							fmt.Sprintf("vstp vlan %q doesn't exist", v),
+						)
+					}
+
+					return false
+				}
+			}
+			if v := plan.VlanGroup.ValueString(); v != "" {
+				groupExists, err := checkVstpVlanGroupExists(fnCtx, v, plan.RoutingInstance.ValueString(), junSess)
+				if err != nil {
+					resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+					return false
+				}
+				if !groupExists {
+					if vRI := plan.RoutingInstance.ValueString(); vRI != "" && vRI != junos.DefaultW {
+						resp.Diagnostics.AddAttributeError(
+							path.Root("vlan_group"),
+							tfdiag.MissingConfigErrSummary,
+							fmt.Sprintf("vstp vlan-group group %q in routing-instance %q doesn't exist", v, vRI),
+						)
+					} else {
+						resp.Diagnostics.AddAttributeError(
+							path.Root("vlan_group"),
+							tfdiag.MissingConfigErrSummary,
+							fmt.Sprintf("vstp vlan-group group %q doesn't exist", v),
+						)
+					}
+
+					return false
+				}
+			}
+			interfaceExists, err := checkVstpInterfaceExists(
+				fnCtx,
+				plan.Name.ValueString(),
+				plan.RoutingInstance.ValueString(),
+				plan.Vlan.ValueString(),
+				plan.VlanGroup.ValueString(),
+				junSess,
+			)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+				return false
+			}
+			if interfaceExists {
+				if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+					switch {
+					case plan.Vlan.ValueString() != "":
+						resp.Diagnostics.AddError(
+							tfdiag.DuplicateConfigErrSummary,
+							fmt.Sprintf(rsc.junosName()+" %q already exists in routing-instance %q in vlan %q",
+								plan.Name.ValueString(), v, plan.Vlan.ValueString(),
+							),
+						)
+					case plan.VlanGroup.ValueString() != "":
+						resp.Diagnostics.AddError(
+							tfdiag.DuplicateConfigErrSummary,
+							fmt.Sprintf(rsc.junosName()+" %q already exists in routing-instance %q in vlan-group group %q",
+								plan.Name.ValueString(), v, plan.VlanGroup.ValueString(),
+							),
+						)
+					default:
+						resp.Diagnostics.AddError(
+							tfdiag.DuplicateConfigErrSummary,
+							defaultResourceAlreadyExistsInRoutingInstanceMessage(rsc, plan.Name, v),
+						)
+					}
+				} else {
+					switch {
+					case plan.Vlan.ValueString() != "":
+						resp.Diagnostics.AddError(
+							tfdiag.DuplicateConfigErrSummary,
+							fmt.Sprintf(rsc.junosName()+" %q already exists in vlan %q",
+								plan.Name.ValueString(), plan.Vlan.ValueString(),
+							),
+						)
+					case plan.VlanGroup.ValueString() != "":
+						resp.Diagnostics.AddError(
+							tfdiag.DuplicateConfigErrSummary,
+							fmt.Sprintf(rsc.junosName()+" %q already exists in vlan-group group %q",
+								plan.Name.ValueString(), plan.VlanGroup.ValueString(),
+							),
+						)
+					default:
+						resp.Diagnostics.AddError(
+							tfdiag.DuplicateConfigErrSummary,
+							defaultResourceAlreadyExistsMessage(rsc, plan.Name),
+						)
+					}
+				}
+
+				return false
+			}
+
+			return true
+		},
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			interfaceExists, err := checkVstpInterfaceExists(
+				fnCtx,
+				plan.Name.ValueString(),
+				plan.RoutingInstance.ValueString(),
+				plan.Vlan.ValueString(),
+				plan.VlanGroup.ValueString(),
+				junSess,
+			)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PostCheckErrSummary, err.Error())
+
+				return false
+			}
+			if !interfaceExists {
+				if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+					switch {
+					case plan.Vlan.ValueString() != "":
+						resp.Diagnostics.AddError(
+							tfdiag.NotFoundErrSummary,
+							fmt.Sprintf(rsc.junosName()+" %q does not exists in routing-instance %q in vlan %q after commit "+
+								"=> check your config",
+								plan.Name.ValueString(), v, plan.Vlan.ValueString()),
+						)
+					case plan.VlanGroup.ValueString() != "":
+						resp.Diagnostics.AddError(
+							tfdiag.NotFoundErrSummary,
+							fmt.Sprintf(rsc.junosName()+" %q does not exists in routing-instance %q in vlan-group group %q after commit "+
+								"=> check your config",
+								plan.Name.ValueString(), v, plan.VlanGroup.ValueString()),
+						)
+					default:
+						resp.Diagnostics.AddError(
+							tfdiag.NotFoundErrSummary,
+							defaultResourceDoesNotExistsInRoutingInstanceAfterCommitMessage(rsc, plan.Name, v),
+						)
+					}
+				} else {
+					switch {
+					case plan.Vlan.ValueString() != "":
+						resp.Diagnostics.AddError(
+							tfdiag.NotFoundErrSummary,
+							fmt.Sprintf(rsc.junosName()+" %q does not exists in vlan %q after commit "+
+								"=> check your config",
+								plan.Name.ValueString(), plan.Vlan.ValueString()),
+						)
+					case plan.VlanGroup.ValueString() != "":
+						resp.Diagnostics.AddError(
+							tfdiag.NotFoundErrSummary,
+							fmt.Sprintf(rsc.junosName()+" %q does not exists in vlan-group group %q after commit "+
+								"=> check your config",
+								plan.Name.ValueString(), plan.VlanGroup.ValueString()),
+						)
+					default:
+						resp.Diagnostics.AddError(
+							tfdiag.NotFoundErrSummary,
+							defaultResourceDoesNotExistsAfterCommitMessage(rsc, plan.Name),
+						)
+					}
+				}
+
+				return false
+			}
+
+			return true
+		},
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *vstpInterface) Read(
+	ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse,
+) {
+	var state, data vstpInterfaceData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	var _ resourceDataReadFrom4String = &data
+	defaultResourceRead(
+		ctx,
+		rsc,
+		[]string{
+			state.Name.ValueString(),
+			state.RoutingInstance.ValueString(),
+			state.Vlan.ValueString(),
+			state.VlanGroup.ValueString(),
+		},
+		&data,
+		nil,
+		resp,
+	)
+}
+
+func (rsc *vstpInterface) Update(
+	ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse,
+) {
+	var plan, state vstpInterfaceData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceUpdate(
+		ctx,
+		rsc,
+		&state,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *vstpInterface) Delete(
+	ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse,
+) {
+	var state vstpInterfaceData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceDelete(
+		ctx,
+		rsc,
+		&state,
+		resp,
+	)
+}
+
+func (rsc *vstpInterface) ImportState(
+	ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse,
+) {
+	junSess, err := rsc.junosClient().StartNewSession(ctx)
+	if err != nil {
+		resp.Diagnostics.AddError(tfdiag.StartSessErrSummary, err.Error())
+
+		return
+	}
+	defer junSess.Close()
+
+	idList := strings.Split(req.ID, junos.IDSeparator)
+	var name, routingInstance, vlan, vlanGroup string
+	switch len(idList) {
+	case 1:
+		name = idList[0]
+	case 2:
+		name = idList[0]
+		routingInstance = idList[1]
+	default:
+		name = idList[0]
+		routingInstance = idList[2]
+		if balt.CutPrefixInString(&idList[1], "v_") {
+			vlan = idList[1]
+		} else if balt.CutPrefixInString(&idList[1], "vg_") {
+			vlanGroup = idList[1]
+		}
+	}
+
+	var data vstpInterfaceData
+	if err := data.read(ctx, name, routingInstance, vlan, vlanGroup, junSess); err != nil {
+		resp.Diagnostics.AddError(tfdiag.ConfigReadErrSummary, err.Error())
+
+		return
+	}
+
+	if data.nullID() {
+		resp.Diagnostics.AddError(
+			tfdiag.NotFoundErrSummary,
+			fmt.Sprintf("don't find "+rsc.junosName()+" with id %q"+
+				" (id must be <name>"+junos.IDSeparator+junos.IDSeparator+"<routing_instance>, "+
+				"<name>"+junos.IDSeparator+"v_<vlan>"+junos.IDSeparator+"<routing_instance> or "+
+				"<name>"+junos.IDSeparator+"vg_<vlan_group>"+junos.IDSeparator+"<routing_instance>)",
+				req.ID),
+		)
+
+		return
+	}
+
+	resp.Diagnostics.Append(resp.State.Set(ctx, data)...)
+}
+
+func checkVstpInterfaceExists(
+	_ context.Context, name, routingInstance, vlan, vlanGroup string, junSess *junos.Session,
+) (
+	bool, error,
+) {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showPrefix += "protocols vstp "
+	if vlan != "" {
+		showPrefix += "vlan " + vlan + " "
+	} else if vlanGroup != "" {
+		showPrefix += "vlan-group group " + vlanGroup + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"interface " + name + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
+	}
+	if showConfig == junos.EmptyW {
+		return false, nil
+	}
+
+	return true, nil
+}
+
+func (rscData *vstpInterfaceData) fillID() {
+	idPrefix := rscData.Name.ValueString() + junos.IDSeparator
+	if rscData.Vlan.ValueString() != "" {
+		idPrefix += "v_" + rscData.Vlan.ValueString()
+	} else if rscData.VlanGroup.ValueString() != "" {
+		idPrefix += "vg_" + rscData.VlanGroup.ValueString()
+	}
+
+	if v := rscData.RoutingInstance.ValueString(); v != "" {
+		rscData.ID = types.StringValue(idPrefix + junos.IDSeparator + v)
+	} else {
+		rscData.ID = types.StringValue(idPrefix + junos.IDSeparator + junos.DefaultW)
+	}
+}
+
+func (rscData *vstpInterfaceData) nullID() bool {
+	return rscData.ID.IsNull()
+}
+
+func (rscData *vstpInterfaceData) set(
+	_ context.Context, junSess *junos.Session,
+) (
+	path.Path, error,
+) {
+	setPrefix := junos.SetLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		setPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	setPrefix += "protocols vstp "
+	if v := rscData.Vlan.ValueString(); v != "" {
+		setPrefix += "vlan " + v + " "
+	} else if v := rscData.VlanGroup.ValueString(); v != "" {
+		setPrefix += "vlan-group group " + v + " "
+	}
+	setPrefix += "interface " + rscData.Name.ValueString() + " "
+
+	configSet := []string{
+		setPrefix,
+	}
+
+	if rscData.AccessTrunk.ValueBool() {
+		configSet = append(configSet, setPrefix+"access-trunk")
+	}
+	if rscData.BpduTimeoutActionAlarm.ValueBool() {
+		configSet = append(configSet, setPrefix+"bpdu-timeout-action alarm")
+	}
+	if rscData.BpduTimeoutActionBlock.ValueBool() {
+		configSet = append(configSet, setPrefix+"bpdu-timeout-action block")
+	}
+	if !rscData.Cost.IsNull() {
+		configSet = append(configSet, setPrefix+"cost "+
+			utils.ConvI64toa(rscData.Cost.ValueInt64()))
+	}
+	if rscData.Edge.ValueBool() {
+		configSet = append(configSet, setPrefix+"edge")
+	}
+	if v := rscData.Mode.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"mode "+v)
+	}
+	if rscData.NoRootPort.ValueBool() {
+		configSet = append(configSet, setPrefix+"no-root-port")
+	}
+	if !rscData.Priority.IsNull() {
+		configSet = append(configSet, setPrefix+"priority "+
+			utils.ConvI64toa(rscData.Priority.ValueInt64()))
+	}
+
+	return path.Empty(), junSess.ConfigSet(configSet)
+}
+
+func (rscData *vstpInterfaceData) read(
+	_ context.Context, name, routingInstance, vlan, vlanGroup string, junSess *junos.Session,
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showPrefix += "protocols vstp "
+	if vlan != "" {
+		showPrefix += "vlan " + vlan + " "
+	} else if vlanGroup != "" {
+		showPrefix += "vlan-group group " + vlanGroup + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"interface " + name + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
+	if showConfig != junos.EmptyW {
+		rscData.Name = types.StringValue(name)
+		if routingInstance == "" {
+			rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+		} else {
+			rscData.RoutingInstance = types.StringValue(routingInstance)
+		}
+		if vlan != "" {
+			rscData.Vlan = types.StringValue(vlan)
+		} else if vlanGroup != "" {
+			rscData.VlanGroup = types.StringValue(vlanGroup)
+		}
+		rscData.fillID()
+		for _, item := range strings.Split(showConfig, "\n") {
+			if strings.Contains(item, junos.XMLStartTagConfigOut) {
+				continue
+			}
+			if strings.Contains(item, junos.XMLEndTagConfigOut) {
+				break
+			}
+			itemTrim := strings.TrimPrefix(item, junos.SetLS)
+			switch {
+			case itemTrim == "access-trunk":
+				rscData.AccessTrunk = types.BoolValue(true)
+			case itemTrim == "bpdu-timeout-action alarm":
+				rscData.BpduTimeoutActionAlarm = types.BoolValue(true)
+			case itemTrim == "bpdu-timeout-action block":
+				rscData.BpduTimeoutActionBlock = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "cost "):
+				rscData.Cost, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case itemTrim == "edge":
+				rscData.Edge = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "mode "):
+				rscData.Mode = types.StringValue(itemTrim)
+			case itemTrim == "no-root-port":
+				rscData.NoRootPort = types.BoolValue(true)
+			case balt.CutPrefixInString(&itemTrim, "priority "):
+				rscData.Priority, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			}
+		}
+	}
+
+	return nil
+}
+
+func (rscData *vstpInterfaceData) del(
+	_ context.Context, junSess *junos.Session,
+) error {
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	delPrefix += "protocols vstp "
+	if v := rscData.Vlan.ValueString(); v != "" {
+		delPrefix += "vlan " + v + " "
+	} else if v := rscData.VlanGroup.ValueString(); v != "" {
+		delPrefix += "vlan-group group " + v + " "
+	}
+
+	configSet := []string{
+		delPrefix + "interface " + rscData.Name.ValueString(),
+	}
+
+	return junSess.ConfigSet(configSet)
+}
diff --git a/internal/providerfwk/resource_vstp_interface_test.go b/internal/providerfwk/resource_vstp_interface_test.go
new file mode 100644
index 00000000..725b9f42
--- /dev/null
+++ b/internal/providerfwk/resource_vstp_interface_test.go
@@ -0,0 +1,87 @@
+package providerfwk_test
+
+import (
+	"os"
+	"testing"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+
+	"github.com/hashicorp/terraform-plugin-testing/config"
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+// export TESTACC_INTERFACE=<inteface> for choose interface available else it's xe-0/0/3.
+func TestAccResourceVstpInterface_basic(t *testing.T) {
+	if os.Getenv("TESTACC_SWITCH") != "" {
+		testaccInterface := junos.DefaultInterfaceSwitchTestAcc
+		if iface := os.Getenv("TESTACC_INTERFACE"); iface != "" {
+			testaccInterface = iface
+		}
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_vstp_interface.testacc_vstp_interface",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_vstp_interface.testacc_vstp_interface2",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_vstp_interface.testacc_vstp_interface3",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_vstp_interface.testacc_vstp_interface4",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_vstp_interface.testacc_vstp_interface5",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+				{
+					ConfigVariables: map[string]config.Variable{
+						"interface": config.StringVariable(testaccInterface),
+					},
+					ResourceName:      "junos_vstp_interface.testacc_vstp_interface6",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providerfwk/resource_vstp_test.go b/internal/providerfwk/resource_vstp_test.go
new file mode 100644
index 00000000..7b45e435
--- /dev/null
+++ b/internal/providerfwk/resource_vstp_test.go
@@ -0,0 +1,31 @@
+package providerfwk_test
+
+import (
+	"os"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/config"
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccResourceVstp_basic(t *testing.T) {
+	if os.Getenv("TESTACC_SWITCH") != "" {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ResourceName:      "junos_vstp.testacc_ri_vstp",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providerfwk/resource_vstp_vlan.go b/internal/providerfwk/resource_vstp_vlan.go
new file mode 100644
index 00000000..963cf691
--- /dev/null
+++ b/internal/providerfwk/resource_vstp_vlan.go
@@ -0,0 +1,595 @@
+package providerfwk
+
+import (
+	"context"
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdata"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdiag"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfvalidator"
+	"github.com/jeremmfr/terraform-provider-junos/internal/utils"
+
+	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+	"github.com/hashicorp/terraform-plugin-framework/path"
+	"github.com/hashicorp/terraform-plugin-framework/resource"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+	balt "github.com/jeremmfr/go-utils/basicalter"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+	_ resource.Resource                   = &vstpVlan{}
+	_ resource.ResourceWithConfigure      = &vstpVlan{}
+	_ resource.ResourceWithValidateConfig = &vstpVlan{}
+	_ resource.ResourceWithImportState    = &vstpVlan{}
+)
+
+type vstpVlan struct {
+	client *junos.Client
+}
+
+func newVstpVlanResource() resource.Resource {
+	return &vstpVlan{}
+}
+
+func (rsc *vstpVlan) typeName() string {
+	return providerName + "_vstp_vlan"
+}
+
+func (rsc *vstpVlan) junosName() string {
+	return "vstp vlan"
+}
+
+func (rsc *vstpVlan) junosClient() *junos.Client {
+	return rsc.client
+}
+
+func (rsc *vstpVlan) Metadata(
+	_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse,
+) {
+	resp.TypeName = rsc.typeName()
+}
+
+func (rsc *vstpVlan) Configure(
+	ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse,
+) {
+	// Prevent panic if the provider has not been configured.
+	if req.ProviderData == nil {
+		return
+	}
+	client, ok := req.ProviderData.(*junos.Client)
+	if !ok {
+		unexpectedResourceConfigureType(ctx, req, resp)
+
+		return
+	}
+	rsc.client = client
+}
+
+func (rsc *vstpVlan) Schema(
+	_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse,
+) {
+	resp.Schema = schema.Schema{
+		Description: defaultResourceSchemaDescription(rsc),
+		Attributes: map[string]schema.Attribute{
+			"id": schema.StringAttribute{
+				Computed: true,
+				Description: "An identifier for the resource with format " +
+					"`<vlan_id>" + junos.IDSeparator + "<routing_instance>`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.UseStateForUnknown(),
+				},
+			},
+			"vlan_id": schema.StringAttribute{
+				Required:    true,
+				Description: "VLAN id or `all`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.RegexMatches(regexp.MustCompile(
+						`^(409[0-4]|(40[0-8]|[1-3]\d\d|[1-9]\d|[1-9])\d|[1-9]|all)$`),
+						"must be a VLAN id (1..4094) or all"),
+				},
+			},
+			"routing_instance": schema.StringAttribute{
+				Optional:    true,
+				Computed:    true,
+				Default:     stringdefault.StaticString(junos.DefaultW),
+				Description: "Routing instance for vstp protocol if not root level.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+			"backup_bridge_priority": schema.StringAttribute{
+				Optional:    true,
+				Description: "Priority of the bridge.",
+				Validators: []validator.String{
+					stringvalidator.RegexMatches(regexp.MustCompile(
+						`^\d\d?k$`),
+						"must be a number with increments of 4k - 4k,8k,..60k",
+					),
+				},
+			},
+			"bridge_priority": schema.StringAttribute{
+				Optional:    true,
+				Description: "Priority of the bridge.",
+				Validators: []validator.String{
+					stringvalidator.RegexMatches(regexp.MustCompile(
+						`^(0|\d\d?k)$`),
+						"must be a number with increments of 4k - 0,4k,8k,..60k",
+					),
+				},
+			},
+			"forward_delay": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Time spent in listening or learning state (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(4, 30),
+				},
+			},
+			"hello_time": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Time interval between configuration BPDUs (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(1, 10),
+				},
+			},
+			"max_age": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Maximum age of received protocol bpdu (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(6, 40),
+				},
+			},
+			"system_identifier": schema.StringAttribute{
+				Optional:    true,
+				Description: "System identifier to represent this node.",
+				Validators: []validator.String{
+					tfvalidator.StringMACAddress().WithMac48ColonHexa(),
+				},
+			},
+		},
+	}
+}
+
+type vstpVlanData struct {
+	ID                   types.String `tfsdk:"id"`
+	VlanID               types.String `tfsdk:"vlan_id"`
+	RoutingInstance      types.String `tfsdk:"routing_instance"`
+	BackupBridgePriority types.String `tfsdk:"backup_bridge_priority"`
+	BridgePriority       types.String `tfsdk:"bridge_priority"`
+	ForwardDelay         types.Int64  `tfsdk:"forward_delay"`
+	HelloTime            types.Int64  `tfsdk:"hello_time"`
+	MaxAge               types.Int64  `tfsdk:"max_age"`
+	SystemIdentifier     types.String `tfsdk:"system_identifier"`
+}
+
+func (rsc *vstpVlan) ValidateConfig(
+	ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse,
+) {
+	var config vstpVlanData
+	resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	if !config.BackupBridgePriority.IsNull() && !config.BackupBridgePriority.IsUnknown() {
+		if v, err := strconv.Atoi(strings.TrimSuffix(
+			config.BackupBridgePriority.ValueString(), "k",
+		)); err == nil {
+			if v%4 != 0 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("backup_bridge_priority"),
+					"Bad Value Error",
+					"backup_bridge_priority must be a multiple of 4k",
+				)
+			}
+			if v < 4 || v > 60 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("backup_bridge_priority"),
+					"Bad Value Error",
+					"backup_bridge_priority must be between 4k and 60k",
+				)
+			}
+			if !config.BridgePriority.IsNull() && !config.BridgePriority.IsUnknown() {
+				if bridgePriority, err := strconv.Atoi(strings.TrimSuffix(
+					config.BridgePriority.ValueString(), "k",
+				)); err == nil {
+					if v <= bridgePriority {
+						resp.Diagnostics.AddAttributeError(
+							path.Root("backup_bridge_priority"),
+							"Bad Value Error",
+							"backup_bridge_priority must be worse (higher value) than bridge_priority",
+						)
+					}
+				}
+			}
+		}
+	}
+	if !config.BridgePriority.IsNull() && !config.BridgePriority.IsUnknown() {
+		if v, err := strconv.Atoi(strings.TrimSuffix(
+			config.BridgePriority.ValueString(), "k",
+		)); err == nil {
+			if v%4 != 0 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("bridge_priority"),
+					"Bad Value Error",
+					"bridge_priority must be a multiple of 4k",
+				)
+			}
+			if v < 0 || v > 60 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("bridge_priority"),
+					"Bad Value Error",
+					"bridge_priority must be between 0 and 60k",
+				)
+			}
+		}
+	}
+}
+
+func (rsc *vstpVlan) Create(
+	ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse,
+) {
+	var plan vstpVlanData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+	if plan.VlanID.ValueString() == "" {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("vlan_id"),
+			"Empty Vlan ID",
+			defaultResourceCouldNotCreateWithEmptyMessage(rsc, "vlan_id"),
+		)
+
+		return
+	}
+
+	defaultResourceCreate(
+		ctx,
+		rsc,
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+				instanceExists, err := checkRoutingInstanceExists(fnCtx, v, junSess)
+				if err != nil {
+					resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+					return false
+				}
+				if !instanceExists {
+					resp.Diagnostics.AddAttributeError(
+						path.Root("routing_instance"),
+						tfdiag.MissingConfigErrSummary,
+						fmt.Sprintf("routing instance %q doesn't exist", v),
+					)
+
+					return false
+				}
+			}
+			vlanExists, err := checkVstpVlanExists(
+				fnCtx,
+				plan.VlanID.ValueString(),
+				plan.RoutingInstance.ValueString(),
+				junSess,
+			)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+				return false
+			}
+			if vlanExists {
+				if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+					resp.Diagnostics.AddError(
+						tfdiag.DuplicateConfigErrSummary,
+						defaultResourceAlreadyExistsInRoutingInstanceMessage(rsc, plan.VlanID, v),
+					)
+				} else {
+					resp.Diagnostics.AddError(
+						tfdiag.DuplicateConfigErrSummary,
+						defaultResourceAlreadyExistsMessage(rsc, plan.VlanID),
+					)
+				}
+
+				return false
+			}
+
+			return true
+		},
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			vlanExists, err := checkVstpVlanExists(
+				fnCtx,
+				plan.VlanID.ValueString(),
+				plan.RoutingInstance.ValueString(),
+				junSess,
+			)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PostCheckErrSummary, err.Error())
+
+				return false
+			}
+			if !vlanExists {
+				if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+					resp.Diagnostics.AddError(
+						tfdiag.NotFoundErrSummary,
+						defaultResourceDoesNotExistsInRoutingInstanceAfterCommitMessage(rsc, plan.VlanID, v),
+					)
+				} else {
+					resp.Diagnostics.AddError(
+						tfdiag.NotFoundErrSummary,
+						defaultResourceDoesNotExistsAfterCommitMessage(rsc, plan.VlanID),
+					)
+				}
+
+				return false
+			}
+
+			return true
+		},
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *vstpVlan) Read(
+	ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse,
+) {
+	var state, data vstpVlanData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	var _ resourceDataReadFrom2String = &data
+	defaultResourceRead(
+		ctx,
+		rsc,
+		[]string{
+			state.VlanID.ValueString(),
+			state.RoutingInstance.ValueString(),
+		},
+		&data,
+		nil,
+		resp,
+	)
+}
+
+func (rsc *vstpVlan) Update(
+	ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse,
+) {
+	var plan, state vstpVlanData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	var _ resourceDataDelWithOpts = &state
+	defaultResourceUpdate(
+		ctx,
+		rsc,
+		&state,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *vstpVlan) Delete(
+	ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse,
+) {
+	var state vstpVlanData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceDelete(
+		ctx,
+		rsc,
+		&state,
+		resp,
+	)
+}
+
+func (rsc *vstpVlan) ImportState(
+	ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse,
+) {
+	var data vstpVlanData
+
+	var _ resourceDataReadFrom2String = &data
+	defaultResourceImportState(
+		ctx,
+		rsc,
+		&data,
+		req,
+		resp,
+		defaultResourceImportDontFindMessage(rsc, req.ID)+
+			" (id must be <vlan_id>"+junos.IDSeparator+"<routing_instance>)",
+	)
+}
+
+func checkVstpVlanExists(
+	_ context.Context, vlanID, routingInstance string, junSess *junos.Session,
+) (
+	bool, error,
+) {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols vstp vlan " + vlanID + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
+	}
+	if showConfig == junos.EmptyW {
+		return false, nil
+	}
+
+	return true, nil
+}
+
+func (rscData *vstpVlanData) fillID() {
+	if v := rscData.RoutingInstance.ValueString(); v != "" {
+		rscData.ID = types.StringValue(rscData.VlanID.ValueString() + junos.IDSeparator + v)
+	} else {
+		rscData.ID = types.StringValue(rscData.VlanID.ValueString() + junos.IDSeparator + junos.DefaultW)
+	}
+}
+
+func (rscData *vstpVlanData) nullID() bool {
+	return rscData.ID.IsNull()
+}
+
+func (rscData *vstpVlanData) set(
+	_ context.Context, junSess *junos.Session,
+) (
+	path.Path, error,
+) {
+	setPrefix := junos.SetLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		setPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	setPrefix += "protocols vstp vlan " + rscData.VlanID.ValueString() + " "
+
+	configSet := []string{
+		setPrefix,
+	}
+
+	if v := rscData.BackupBridgePriority.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"backup-bridge-priority "+v)
+	}
+	if v := rscData.BridgePriority.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"bridge-priority "+v)
+	}
+	if !rscData.ForwardDelay.IsNull() {
+		configSet = append(configSet, setPrefix+"forward-delay "+
+			utils.ConvI64toa(rscData.ForwardDelay.ValueInt64()))
+	}
+	if !rscData.HelloTime.IsNull() {
+		configSet = append(configSet, setPrefix+"hello-time "+
+			utils.ConvI64toa(rscData.HelloTime.ValueInt64()))
+	}
+	if !rscData.MaxAge.IsNull() {
+		configSet = append(configSet, setPrefix+"max-age "+
+			utils.ConvI64toa(rscData.MaxAge.ValueInt64()))
+	}
+	if v := rscData.SystemIdentifier.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"system-identifier "+v)
+	}
+
+	return path.Empty(), junSess.ConfigSet(configSet)
+}
+
+func (rscData *vstpVlanData) read(
+	_ context.Context, vlanID, routingInstance string, junSess *junos.Session,
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols vstp vlan " + vlanID + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
+	if showConfig != junos.EmptyW {
+		rscData.VlanID = types.StringValue(vlanID)
+		if routingInstance == "" {
+			rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+		} else {
+			rscData.RoutingInstance = types.StringValue(routingInstance)
+		}
+		rscData.fillID()
+		for _, item := range strings.Split(showConfig, "\n") {
+			if strings.Contains(item, junos.XMLStartTagConfigOut) {
+				continue
+			}
+			if strings.Contains(item, junos.XMLEndTagConfigOut) {
+				break
+			}
+			itemTrim := strings.TrimPrefix(item, junos.SetLS)
+			switch {
+			case balt.CutPrefixInString(&itemTrim, "backup-bridge-priority "):
+				rscData.BackupBridgePriority = types.StringValue(itemTrim)
+			case balt.CutPrefixInString(&itemTrim, "bridge-priority "):
+				rscData.BridgePriority = types.StringValue(itemTrim)
+			case balt.CutPrefixInString(&itemTrim, "forward-delay "):
+				rscData.ForwardDelay, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "hello-time "):
+				rscData.HelloTime, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "max-age "):
+				rscData.MaxAge, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "system-identifier "):
+				rscData.SystemIdentifier = types.StringValue(itemTrim)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (rscData *vstpVlanData) delOpts(
+	_ context.Context, junSess *junos.Session,
+) error {
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	delPrefix += "protocols vstp vlan " + rscData.VlanID.ValueString() + " "
+
+	listLinesToDelete := []string{
+		"backup-bridge-priority",
+		"bridge-priority",
+		"forward-delay",
+		"hello-time",
+		"max-age",
+		"system-identifier",
+	}
+
+	configSet := make([]string, len(listLinesToDelete))
+	for k, line := range listLinesToDelete {
+		configSet[k] = delPrefix + line
+	}
+
+	return junSess.ConfigSet(configSet)
+}
+
+func (rscData *vstpVlanData) del(
+	_ context.Context, junSess *junos.Session,
+) error {
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+
+	configSet := []string{
+		delPrefix + "protocols vstp vlan " + rscData.VlanID.ValueString(),
+	}
+
+	return junSess.ConfigSet(configSet)
+}
diff --git a/internal/providerfwk/resource_vstp_vlan_group.go b/internal/providerfwk/resource_vstp_vlan_group.go
new file mode 100644
index 00000000..7d72cbc7
--- /dev/null
+++ b/internal/providerfwk/resource_vstp_vlan_group.go
@@ -0,0 +1,626 @@
+package providerfwk
+
+import (
+	"context"
+	"fmt"
+	"regexp"
+	"strconv"
+	"strings"
+
+	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdata"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfdiag"
+	"github.com/jeremmfr/terraform-provider-junos/internal/tfvalidator"
+	"github.com/jeremmfr/terraform-provider-junos/internal/utils"
+
+	"github.com/hashicorp/terraform-plugin-framework-validators/int64validator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/setvalidator"
+	"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
+	"github.com/hashicorp/terraform-plugin-framework/path"
+	"github.com/hashicorp/terraform-plugin-framework/resource"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier"
+	"github.com/hashicorp/terraform-plugin-framework/schema/validator"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+	balt "github.com/jeremmfr/go-utils/basicalter"
+)
+
+// Ensure the implementation satisfies the expected interfaces.
+var (
+	_ resource.Resource                   = &vstpVlanGroup{}
+	_ resource.ResourceWithConfigure      = &vstpVlanGroup{}
+	_ resource.ResourceWithValidateConfig = &vstpVlanGroup{}
+	_ resource.ResourceWithImportState    = &vstpVlanGroup{}
+)
+
+type vstpVlanGroup struct {
+	client *junos.Client
+}
+
+func newVstpVlanGroupResource() resource.Resource {
+	return &vstpVlanGroup{}
+}
+
+func (rsc *vstpVlanGroup) typeName() string {
+	return providerName + "_vstp_vlan_group"
+}
+
+func (rsc *vstpVlanGroup) junosName() string {
+	return "vstp vlan-group group"
+}
+
+func (rsc *vstpVlanGroup) junosClient() *junos.Client {
+	return rsc.client
+}
+
+func (rsc *vstpVlanGroup) Metadata(
+	_ context.Context, _ resource.MetadataRequest, resp *resource.MetadataResponse,
+) {
+	resp.TypeName = rsc.typeName()
+}
+
+func (rsc *vstpVlanGroup) Configure(
+	ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse,
+) {
+	// Prevent panic if the provider has not been configured.
+	if req.ProviderData == nil {
+		return
+	}
+	client, ok := req.ProviderData.(*junos.Client)
+	if !ok {
+		unexpectedResourceConfigureType(ctx, req, resp)
+
+		return
+	}
+	rsc.client = client
+}
+
+func (rsc *vstpVlanGroup) Schema(
+	_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse,
+) {
+	resp.Schema = schema.Schema{
+		Description: defaultResourceSchemaDescription(rsc),
+		Attributes: map[string]schema.Attribute{
+			"id": schema.StringAttribute{
+				Computed: true,
+				Description: "An identifier for the resource with format " +
+					"`<name>" + junos.IDSeparator + "<routing_instance>`.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.UseStateForUnknown(),
+				},
+			},
+			"name": schema.StringAttribute{
+				Required:    true,
+				Description: "VLAN group name.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+			"routing_instance": schema.StringAttribute{
+				Optional:    true,
+				Computed:    true,
+				Default:     stringdefault.StaticString(junos.DefaultW),
+				Description: "Routing instance for vstp protocol if not root level.",
+				PlanModifiers: []planmodifier.String{
+					stringplanmodifier.RequiresReplace(),
+				},
+				Validators: []validator.String{
+					stringvalidator.LengthBetween(1, 63),
+					tfvalidator.StringFormat(tfvalidator.DefaultFormat),
+				},
+			},
+			"vlan": schema.SetAttribute{
+				ElementType: types.StringType,
+				Required:    true,
+				Description: " VLAN IDs or VLAN ID ranges.",
+				Validators: []validator.Set{
+					setvalidator.SizeAtLeast(1),
+					setvalidator.ValueStringsAre(
+						stringvalidator.RegexMatches(regexp.MustCompile(
+							`^(409[0-4]|(40[0-8]|[1-3]\d\d|[1-9]\d|[1-9])\d|[1-9])`+
+								`(-(409[0-4]|(40[0-8]|[1-3]\d\d|[1-9]\d|[1-9])\d|[1-9]))?$`),
+							"must be a VLAN id (1..4094) or a range of VLAN id (1..4094)-(1..4094)"),
+					),
+				},
+			},
+			"backup_bridge_priority": schema.StringAttribute{
+				Optional:    true,
+				Description: "Priority of the bridge.",
+				Validators: []validator.String{
+					stringvalidator.RegexMatches(regexp.MustCompile(
+						`^\d\d?k$`),
+						"must be a number with increments of 4k - 4k,8k,..60k",
+					),
+				},
+			},
+			"bridge_priority": schema.StringAttribute{
+				Optional:    true,
+				Description: "Priority of the bridge.",
+				Validators: []validator.String{
+					stringvalidator.RegexMatches(regexp.MustCompile(
+						`^(0|\d\d?k)$`),
+						"must be a number with increments of 4k - 0,4k,8k,..60k",
+					),
+				},
+			},
+			"forward_delay": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Time spent in listening or learning state (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(4, 30),
+				},
+			},
+			"hello_time": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Time interval between configuration BPDUs (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(1, 10),
+				},
+			},
+			"max_age": schema.Int64Attribute{
+				Optional:    true,
+				Description: "Maximum age of received protocol bpdu (seconds).",
+				Validators: []validator.Int64{
+					int64validator.Between(6, 40),
+				},
+			},
+			"system_identifier": schema.StringAttribute{
+				Optional:    true,
+				Description: "System identifier to represent this node.",
+				Validators: []validator.String{
+					tfvalidator.StringMACAddress().WithMac48ColonHexa(),
+				},
+			},
+		},
+	}
+}
+
+type vstpVlanGroupData struct {
+	ID                   types.String   `tfsdk:"id"`
+	Name                 types.String   `tfsdk:"name"`
+	RoutingInstance      types.String   `tfsdk:"routing_instance"`
+	Vlan                 []types.String `tfsdk:"vlan"`
+	BackupBridgePriority types.String   `tfsdk:"backup_bridge_priority"`
+	BridgePriority       types.String   `tfsdk:"bridge_priority"`
+	ForwardDelay         types.Int64    `tfsdk:"forward_delay"`
+	HelloTime            types.Int64    `tfsdk:"hello_time"`
+	MaxAge               types.Int64    `tfsdk:"max_age"`
+	SystemIdentifier     types.String   `tfsdk:"system_identifier"`
+}
+
+type vstpVlanGroupConfig struct {
+	ID                   types.String `tfsdk:"id"`
+	Name                 types.String `tfsdk:"name"`
+	RoutingInstance      types.String `tfsdk:"routing_instance"`
+	Vlan                 types.Set    `tfsdk:"vlan"`
+	BackupBridgePriority types.String `tfsdk:"backup_bridge_priority"`
+	BridgePriority       types.String `tfsdk:"bridge_priority"`
+	ForwardDelay         types.Int64  `tfsdk:"forward_delay"`
+	HelloTime            types.Int64  `tfsdk:"hello_time"`
+	MaxAge               types.Int64  `tfsdk:"max_age"`
+	SystemIdentifier     types.String `tfsdk:"system_identifier"`
+}
+
+func (rsc *vstpVlanGroup) ValidateConfig(
+	ctx context.Context, req resource.ValidateConfigRequest, resp *resource.ValidateConfigResponse,
+) {
+	var config vstpVlanGroupConfig
+	resp.Diagnostics.Append(req.Config.Get(ctx, &config)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	if !config.BackupBridgePriority.IsNull() && !config.BackupBridgePriority.IsUnknown() {
+		if v, err := strconv.Atoi(strings.TrimSuffix(
+			config.BackupBridgePriority.ValueString(), "k",
+		)); err == nil {
+			if v%4 != 0 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("backup_bridge_priority"),
+					"Bad Value Error",
+					"backup_bridge_priority must be a multiple of 4k",
+				)
+			}
+			if v < 4 || v > 60 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("backup_bridge_priority"),
+					"Bad Value Error",
+					"backup_bridge_priority must be between 4k and 60k",
+				)
+			}
+			if !config.BridgePriority.IsNull() && !config.BridgePriority.IsUnknown() {
+				if bridgePriority, err := strconv.Atoi(strings.TrimSuffix(
+					config.BridgePriority.ValueString(), "k",
+				)); err == nil {
+					if v <= bridgePriority {
+						resp.Diagnostics.AddAttributeError(
+							path.Root("backup_bridge_priority"),
+							"Bad Value Error",
+							"backup_bridge_priority must be worse (higher value) than bridge_priority",
+						)
+					}
+				}
+			}
+		}
+	}
+	if !config.BridgePriority.IsNull() && !config.BridgePriority.IsUnknown() {
+		if v, err := strconv.Atoi(strings.TrimSuffix(
+			config.BridgePriority.ValueString(), "k",
+		)); err == nil {
+			if v%4 != 0 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("bridge_priority"),
+					"Bad Value Error",
+					"bridge_priority must be a multiple of 4k",
+				)
+			}
+			if v < 0 || v > 60 {
+				resp.Diagnostics.AddAttributeError(
+					path.Root("bridge_priority"),
+					"Bad Value Error",
+					"bridge_priority must be between 0 and 60k",
+				)
+			}
+		}
+	}
+}
+
+func (rsc *vstpVlanGroup) Create(
+	ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse,
+) {
+	var plan vstpVlanGroupData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+	if plan.Name.ValueString() == "" {
+		resp.Diagnostics.AddAttributeError(
+			path.Root("name"),
+			"Empty Name",
+			defaultResourceCouldNotCreateWithEmptyMessage(rsc, "name"),
+		)
+
+		return
+	}
+
+	defaultResourceCreate(
+		ctx,
+		rsc,
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+				instanceExists, err := checkRoutingInstanceExists(fnCtx, v, junSess)
+				if err != nil {
+					resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+					return false
+				}
+				if !instanceExists {
+					resp.Diagnostics.AddAttributeError(
+						path.Root("routing_instance"),
+						tfdiag.MissingConfigErrSummary,
+						fmt.Sprintf("routing instance %q doesn't exist", v),
+					)
+
+					return false
+				}
+			}
+			groupExists, err := checkVstpVlanGroupExists(
+				fnCtx,
+				plan.Name.ValueString(),
+				plan.RoutingInstance.ValueString(),
+				junSess,
+			)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PreCheckErrSummary, err.Error())
+
+				return false
+			}
+			if groupExists {
+				if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+					resp.Diagnostics.AddError(
+						tfdiag.DuplicateConfigErrSummary,
+						defaultResourceAlreadyExistsInRoutingInstanceMessage(rsc, plan.Name, v),
+					)
+				} else {
+					resp.Diagnostics.AddError(
+						tfdiag.DuplicateConfigErrSummary,
+						defaultResourceAlreadyExistsMessage(rsc, plan.Name),
+					)
+				}
+
+				return false
+			}
+
+			return true
+		},
+		func(fnCtx context.Context, junSess *junos.Session) bool {
+			groupExists, err := checkVstpVlanGroupExists(
+				fnCtx,
+				plan.Name.ValueString(),
+				plan.RoutingInstance.ValueString(),
+				junSess,
+			)
+			if err != nil {
+				resp.Diagnostics.AddError(tfdiag.PostCheckErrSummary, err.Error())
+
+				return false
+			}
+			if !groupExists {
+				if v := plan.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+					resp.Diagnostics.AddError(
+						tfdiag.NotFoundErrSummary,
+						defaultResourceDoesNotExistsInRoutingInstanceAfterCommitMessage(rsc, plan.Name, v),
+					)
+				} else {
+					resp.Diagnostics.AddError(
+						tfdiag.NotFoundErrSummary,
+						defaultResourceDoesNotExistsAfterCommitMessage(rsc, plan.Name),
+					)
+				}
+
+				return false
+			}
+
+			return true
+		},
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *vstpVlanGroup) Read(
+	ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse,
+) {
+	var state, data vstpVlanGroupData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	var _ resourceDataReadFrom2String = &data
+	defaultResourceRead(
+		ctx,
+		rsc,
+		[]string{
+			state.Name.ValueString(),
+			state.RoutingInstance.ValueString(),
+		},
+		&data,
+		nil,
+		resp,
+	)
+}
+
+func (rsc *vstpVlanGroup) Update(
+	ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse,
+) {
+	var plan, state vstpVlanGroupData
+	resp.Diagnostics.Append(req.Plan.Get(ctx, &plan)...)
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	var _ resourceDataDelWithOpts = &state
+	defaultResourceUpdate(
+		ctx,
+		rsc,
+		&state,
+		&plan,
+		resp,
+	)
+}
+
+func (rsc *vstpVlanGroup) Delete(
+	ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse,
+) {
+	var state vstpVlanGroupData
+	resp.Diagnostics.Append(req.State.Get(ctx, &state)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	defaultResourceDelete(
+		ctx,
+		rsc,
+		&state,
+		resp,
+	)
+}
+
+func (rsc *vstpVlanGroup) ImportState(
+	ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse,
+) {
+	var data vstpVlanGroupData
+
+	var _ resourceDataReadFrom2String = &data
+	defaultResourceImportState(
+		ctx,
+		rsc,
+		&data,
+		req,
+		resp,
+		defaultResourceImportDontFindMessage(rsc, req.ID)+
+			" (id must be <name>"+junos.IDSeparator+"<routing_instance>)",
+	)
+}
+
+func checkVstpVlanGroupExists(
+	_ context.Context, name, routingInstance string, junSess *junos.Session,
+) (
+	bool, error,
+) {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols vstp vlan-group group " + name + junos.PipeDisplaySet)
+	if err != nil {
+		return false, err
+	}
+	if showConfig == junos.EmptyW {
+		return false, nil
+	}
+
+	return true, nil
+}
+
+func (rscData *vstpVlanGroupData) fillID() {
+	if v := rscData.RoutingInstance.ValueString(); v != "" {
+		rscData.ID = types.StringValue(rscData.Name.ValueString() + junos.IDSeparator + v)
+	} else {
+		rscData.ID = types.StringValue(rscData.Name.ValueString() + junos.IDSeparator + junos.DefaultW)
+	}
+}
+
+func (rscData *vstpVlanGroupData) nullID() bool {
+	return rscData.ID.IsNull()
+}
+
+func (rscData *vstpVlanGroupData) set(
+	_ context.Context, junSess *junos.Session,
+) (
+	path.Path, error,
+) {
+	configSet := make([]string, 0, len(rscData.Vlan))
+	setPrefix := junos.SetLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		setPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	setPrefix += "protocols vstp vlan-group group " + rscData.Name.ValueString() + " "
+
+	for _, v := range rscData.Vlan {
+		configSet = append(configSet, setPrefix+"vlan "+v.ValueString())
+	}
+	if v := rscData.BackupBridgePriority.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"backup-bridge-priority "+v)
+	}
+	if v := rscData.BridgePriority.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"bridge-priority "+v)
+	}
+	if !rscData.ForwardDelay.IsNull() {
+		configSet = append(configSet, setPrefix+"forward-delay "+
+			utils.ConvI64toa(rscData.ForwardDelay.ValueInt64()))
+	}
+	if !rscData.HelloTime.IsNull() {
+		configSet = append(configSet, setPrefix+"hello-time "+
+			utils.ConvI64toa(rscData.HelloTime.ValueInt64()))
+	}
+	if !rscData.MaxAge.IsNull() {
+		configSet = append(configSet, setPrefix+"max-age "+
+			utils.ConvI64toa(rscData.MaxAge.ValueInt64()))
+	}
+	if v := rscData.SystemIdentifier.ValueString(); v != "" {
+		configSet = append(configSet, setPrefix+"system-identifier "+v)
+	}
+
+	return path.Empty(), junSess.ConfigSet(configSet)
+}
+
+func (rscData *vstpVlanGroupData) read(
+	_ context.Context, name, routingInstance string, junSess *junos.Session,
+) error {
+	showPrefix := junos.CmdShowConfig
+	if routingInstance != "" && routingInstance != junos.DefaultW {
+		showPrefix += junos.RoutingInstancesWS + routingInstance + " "
+	}
+	showConfig, err := junSess.Command(showPrefix +
+		"protocols vstp vlan-group group " + name + junos.PipeDisplaySetRelative)
+	if err != nil {
+		return err
+	}
+	if showConfig != junos.EmptyW {
+		rscData.Name = types.StringValue(name)
+		if routingInstance == "" {
+			rscData.RoutingInstance = types.StringValue(junos.DefaultW)
+		} else {
+			rscData.RoutingInstance = types.StringValue(routingInstance)
+		}
+		rscData.fillID()
+		for _, item := range strings.Split(showConfig, "\n") {
+			if strings.Contains(item, junos.XMLStartTagConfigOut) {
+				continue
+			}
+			if strings.Contains(item, junos.XMLEndTagConfigOut) {
+				break
+			}
+			itemTrim := strings.TrimPrefix(item, junos.SetLS)
+			switch {
+			case balt.CutPrefixInString(&itemTrim, "vlan "):
+				rscData.Vlan = append(rscData.Vlan, types.StringValue(itemTrim))
+			case balt.CutPrefixInString(&itemTrim, "backup-bridge-priority "):
+				rscData.BackupBridgePriority = types.StringValue(itemTrim)
+			case balt.CutPrefixInString(&itemTrim, "bridge-priority "):
+				rscData.BridgePriority = types.StringValue(itemTrim)
+			case balt.CutPrefixInString(&itemTrim, "forward-delay "):
+				rscData.ForwardDelay, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "hello-time "):
+				rscData.HelloTime, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "max-age "):
+				rscData.MaxAge, err = tfdata.ConvAtoi64Value(itemTrim)
+				if err != nil {
+					return err
+				}
+			case balt.CutPrefixInString(&itemTrim, "system-identifier "):
+				rscData.SystemIdentifier = types.StringValue(itemTrim)
+			}
+		}
+	}
+
+	return nil
+}
+
+func (rscData *vstpVlanGroupData) delOpts(
+	_ context.Context, junSess *junos.Session,
+) error {
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+	delPrefix += "protocols vstp vlan-group group " + rscData.Name.ValueString() + " "
+
+	listLinesToDelete := []string{
+		"backup-bridge-priority",
+		"bridge-priority",
+		"forward-delay",
+		"hello-time",
+		"max-age",
+		"system-identifier",
+		"vlan",
+	}
+
+	configSet := make([]string, len(listLinesToDelete))
+	for k, line := range listLinesToDelete {
+		configSet[k] = delPrefix + line
+	}
+
+	return junSess.ConfigSet(configSet)
+}
+
+func (rscData *vstpVlanGroupData) del(
+	_ context.Context, junSess *junos.Session,
+) error {
+	delPrefix := junos.DeleteLS
+	if v := rscData.RoutingInstance.ValueString(); v != "" && v != junos.DefaultW {
+		delPrefix += junos.RoutingInstancesWS + v + " "
+	}
+
+	configSet := []string{
+		delPrefix + "protocols vstp vlan-group group " + rscData.Name.ValueString(),
+	}
+
+	return junSess.ConfigSet(configSet)
+}
diff --git a/internal/providerfwk/resource_vstp_vlan_group_test.go b/internal/providerfwk/resource_vstp_vlan_group_test.go
new file mode 100644
index 00000000..9f40f1b5
--- /dev/null
+++ b/internal/providerfwk/resource_vstp_vlan_group_test.go
@@ -0,0 +1,31 @@
+package providerfwk_test
+
+import (
+	"os"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/config"
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccResourceVstpVlanGroup_basic(t *testing.T) {
+	if os.Getenv("TESTACC_SWITCH") != "" {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ResourceName:      "junos_vstp_vlan_group.testacc_ri_vstp_vlan_group",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providerfwk/resource_vstp_vlan_test.go b/internal/providerfwk/resource_vstp_vlan_test.go
new file mode 100644
index 00000000..cc541a67
--- /dev/null
+++ b/internal/providerfwk/resource_vstp_vlan_test.go
@@ -0,0 +1,31 @@
+package providerfwk_test
+
+import (
+	"os"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/config"
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+)
+
+func TestAccResourceVstpVlan_basic(t *testing.T) {
+	if os.Getenv("TESTACC_SWITCH") != "" {
+		resource.Test(t, resource.TestCase{
+			PreCheck:                 func() { testAccPreCheck(t) },
+			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ResourceName:      "junos_vstp_vlan.testacc_ri_vstp_vlan",
+					ImportState:       true,
+					ImportStateVerify: true,
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providerfwk/resourcedata_bgp.go b/internal/providerfwk/resourcedata_bgp.go
index 28143d8e..83109c24 100644
--- a/internal/providerfwk/resourcedata_bgp.go
+++ b/internal/providerfwk/resourcedata_bgp.go
@@ -116,6 +116,7 @@ func (block *bgpBlockBfdLivenessDetection) configSet(setPrefix string) []string
 
 func (block *bgpBlockBgpErrorTolerance) configSet(setPrefix string) []string {
 	setPrefix += "bgp-error-tolerance"
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -137,6 +138,7 @@ func (block *bgpBlockBgpErrorTolerance) configSet(setPrefix string) []string {
 
 func (block *bgpBlockBgpMultipath) configSet(setPrefix string) []string {
 	setPrefix += "multipath"
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -162,6 +164,7 @@ func (block *bgpBlockFamily) configSet(
 	error, // error
 ) {
 	setPrefix += block.NlriType.ValueString() + " "
+
 	configSet := []string{
 		setPrefix,
 	}
@@ -216,6 +219,7 @@ func (block *bgpBlockFamily) configSet(
 
 func (block *bgpBlockGracefulRestart) configSet(setPrefix string) []string {
 	setPrefix += "graceful-restart"
+
 	configSet := []string{
 		setPrefix,
 	}
diff --git a/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/1/main.tf
index 033694e3..2aafcff9 100644
--- a/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/1/main.tf
+++ b/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/1/main.tf
@@ -32,6 +32,7 @@ resource "junos_routing_instance" "testacc_bridge_ri" {
   route_distinguisher   = "10:11"
   vrf_target            = "target:1:200"
   vtep_source_interface = junos_interface_logical.testacc_bridge_ri.name
+  remote_vtep_list      = ["192.0.2.136", "192.0.2.36"]
 }
 resource "junos_evpn" "testacc_bridge_ri" {
   routing_instance = junos_routing_instance.testacc_bridge_ri.name
diff --git a/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/4/main.tf b/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/4/main.tf
index 702d952d..5b912618 100644
--- a/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/4/main.tf
+++ b/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/4/main.tf
@@ -27,6 +27,7 @@ resource "junos_routing_instance" "testacc_bridge_ri" {
   route_distinguisher   = "10:11"
   vrf_target            = "target:1:200"
   vtep_source_interface = junos_interface_logical.testacc_bridge_ri.name
+  remote_vtep_list      = ["192.0.2.136", "192.0.2.36"]
 }
 resource "junos_evpn" "testacc_bridge_ri" {
   routing_instance = junos_routing_instance.testacc_bridge_ri.name
@@ -48,6 +49,7 @@ resource "junos_bridge_domain" "testacc_bridge_ri" {
   service_id = 12
   vlan_id    = 13
   vxlan {
-    vni = 15
+    vni                     = 15
+    static_remote_vtep_list = ["192.0.2.136", "192.0.2.36"]
   }
 }
diff --git a/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/5/main.tf b/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/5/main.tf
index 07cefaba..7a44871f 100644
--- a/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/5/main.tf
+++ b/internal/providerfwk/testdata/TestAccResourceBridgeDomain_basic/5/main.tf
@@ -27,6 +27,7 @@ resource "junos_routing_instance" "testacc_bridge_ri" {
   route_distinguisher   = "10:11"
   vrf_target            = "target:1:200"
   vtep_source_interface = junos_interface_logical.testacc_bridge_ri.name
+  remote_vtep_list      = ["192.0.2.136", "192.0.2.36"]
 }
 resource "junos_evpn" "testacc_bridge_ri" {
   routing_instance = junos_routing_instance.testacc_bridge_ri.name
@@ -47,6 +48,7 @@ resource "junos_bridge_domain" "testacc_bridge_ri" {
   service_id = 12
   vlan_id    = 13
   vxlan {
-    vni = 15
+    vni                     = 15
+    static_remote_vtep_list = ["192.0.2.36"]
   }
 }
diff --git a/internal/providerfwk/testdata/TestAccResourceInterfaceLogical_basic/5/main.tf b/internal/providerfwk/testdata/TestAccResourceInterfaceLogical_basic/5/main.tf
index fa6c2e23..eebcdfc1 100644
--- a/internal/providerfwk/testdata/TestAccResourceInterfaceLogical_basic/5/main.tf
+++ b/internal/providerfwk/testdata/TestAccResourceInterfaceLogical_basic/5/main.tf
@@ -44,5 +44,6 @@ resource "junos_interface_logical" "testacc_interface_logical" {
   }
 }
 resource "junos_interface_logical" "testacc_interface_logical2" {
-  name = "${junos_interface_physical.testacc_interface_logical_phy.name}.101"
+  name          = "${junos_interface_physical.testacc_interface_logical_phy.name}.101"
+  encapsulation = "dix"
 }
diff --git a/internal/providerfwk/testdata/TestAccResourceRoutingInstance_router/1/main.tf b/internal/providerfwk/testdata/TestAccResourceRoutingInstance_router/1/main.tf
index 762f2ece..4b0a80ab 100644
--- a/internal/providerfwk/testdata/TestAccResourceRoutingInstance_router/1/main.tf
+++ b/internal/providerfwk/testdata/TestAccResourceRoutingInstance_router/1/main.tf
@@ -51,4 +51,6 @@ resource "junos_routing_instance" "testacc_routingInst4" {
   route_distinguisher = "8:9"
   vrf_export          = [junos_policyoptions_policy_statement.testacc_routingInst2.name]
   vrf_target_auto     = true
+  remote_vtep_list    = ["192.0.2.135", "192.0.2.35"]
+  remote_vtep_v6_list = ["fe80::34"]
 }
diff --git a/internal/providerfwk/testdata/TestAccResourceRoutingInstance_router/2/main.tf b/internal/providerfwk/testdata/TestAccResourceRoutingInstance_router/2/main.tf
index 8fe6060c..b9e776e7 100644
--- a/internal/providerfwk/testdata/TestAccResourceRoutingInstance_router/2/main.tf
+++ b/internal/providerfwk/testdata/TestAccResourceRoutingInstance_router/2/main.tf
@@ -74,4 +74,5 @@ resource "junos_routing_instance" "testacc_routingInst4" {
   route_distinguisher = "10:11"
   vrf_export          = [junos_policyoptions_policy_statement.testacc_routingInst2.name]
   vrf_target_auto     = true
+  remote_vtep_list    = ["192.0.2.35"]
 }
diff --git a/internal/providerfwk/testdata/TestAccResourceRstpInterface_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceRstpInterface_basic/1/main.tf
new file mode 100644
index 00000000..ebf42560
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstpInterface_basic/1/main.tf
@@ -0,0 +1,3 @@
+resource "junos_rstp_interface" "all" {
+  name = "all"
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstpInterface_basic/2/main.tf b/internal/providerfwk/testdata/TestAccResourceRstpInterface_basic/2/main.tf
new file mode 100644
index 00000000..d62533a8
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstpInterface_basic/2/main.tf
@@ -0,0 +1,10 @@
+resource "junos_rstp_interface" "all" {
+  name                      = "all"
+  access_trunk              = true
+  bpdu_timeout_action_alarm = true
+  bpdu_timeout_action_block = true
+  cost                      = 16
+  edge                      = true
+  mode                      = "shared"
+  priority                  = 240
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/1/main.tf b/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/1/main.tf
new file mode 100644
index 00000000..13b33679
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/1/main.tf
@@ -0,0 +1,13 @@
+resource "junos_rstp_interface" "all" {
+  name = "all"
+}
+
+resource "junos_routing_instance" "testacc_rstp_interface" {
+  name = "testacc_rstp_intface"
+  type = "virtual-switch"
+}
+
+resource "junos_rstp_interface" "all2" {
+  name             = "all"
+  routing_instance = junos_routing_instance.testacc_rstp_interface.name
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/2/main.tf b/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/2/main.tf
new file mode 100644
index 00000000..5110c820
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/2/main.tf
@@ -0,0 +1,37 @@
+resource "junos_rstp_interface" "all" {
+  name                      = "all"
+  access_trunk              = true
+  bpdu_timeout_action_alarm = true
+  bpdu_timeout_action_block = true
+  cost                      = 16
+  edge                      = true
+  mode                      = "shared"
+  priority                  = 240
+}
+
+resource "junos_interface_physical" "testacc_rstp_interface" {
+  name         = var.interface
+  vlan_members = ["default"]
+}
+
+resource "junos_rstp_interface" "testacc_rstp_interface" {
+  name         = junos_interface_physical.testacc_rstp_interface.name
+  no_root_port = true
+}
+
+resource "junos_routing_instance" "testacc_rstp_interface" {
+  name = "testacc_rstp_interface"
+  type = "virtual-switch"
+}
+
+resource "junos_rstp_interface" "all2" {
+  name                      = "all"
+  routing_instance          = junos_routing_instance.testacc_rstp_interface.name
+  access_trunk              = true
+  bpdu_timeout_action_alarm = true
+  bpdu_timeout_action_block = true
+  cost                      = 16
+  edge                      = true
+  mode                      = "shared"
+  priority                  = 240
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/2/variables.tf b/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/2/variables.tf
new file mode 100644
index 00000000..d5ed041c
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstpInterface_switch/2/variables.tf
@@ -0,0 +1,3 @@
+variable "interface" {
+  type = string
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstp_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceRstp_basic/1/main.tf
new file mode 100644
index 00000000..2a315f8e
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstp_basic/1/main.tf
@@ -0,0 +1,3 @@
+resource "junos_rstp" "testacc_rstp" {
+  disable = true
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstp_basic/2/main.tf b/internal/providerfwk/testdata/TestAccResourceRstp_basic/2/main.tf
new file mode 100644
index 00000000..43dd5a6a
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstp_basic/2/main.tf
@@ -0,0 +1,7 @@
+resource "junos_rstp" "testacc_rstp" {
+  backup_bridge_priority = "32k"
+  bridge_priority        = "16k"
+  system_id {
+    id = "00:22:33:44:55:aa"
+  }
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstp_basic/3/main.tf b/internal/providerfwk/testdata/TestAccResourceRstp_basic/3/main.tf
new file mode 100644
index 00000000..490d6dd6
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstp_basic/3/main.tf
@@ -0,0 +1,20 @@
+resource "junos_rstp" "testacc_rstp" {
+  backup_bridge_priority                             = "60k"
+  bridge_priority                                    = "4k"
+  bpdu_destination_mac_address_provider_bridge_group = true
+  extended_system_id                                 = 0
+  force_version_stp                                  = true
+  forward_delay                                      = 20
+  hello_time                                         = 5
+  max_age                                            = 22
+  priority_hold_time                                 = 100
+  system_id {
+    id = "00:11:22:33:44:55"
+  }
+  system_id {
+    id         = "00:22:33:44:55:66"
+    ip_address = "192.0.2.4/24"
+  }
+  system_identifier             = "66:55:44:33:22:11"
+  vpls_flush_on_topology_change = true
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstp_switch/1/main.tf b/internal/providerfwk/testdata/TestAccResourceRstp_switch/1/main.tf
new file mode 100644
index 00000000..4888e4ce
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstp_switch/1/main.tf
@@ -0,0 +1,16 @@
+resource "junos_rstp" "testacc_rstp" {
+  bpdu_block_on_edge = true
+}
+
+resource "junos_routing_instance" "testacc_rstp" {
+  name = "testacc_rstp"
+  type = "virtual-switch"
+}
+
+resource "junos_rstp" "testacc_ri_rstp" {
+  routing_instance = junos_routing_instance.testacc_rstp.name
+  bridge_priority  = 0
+  system_id {
+    id = "00:11:22:33:44:56"
+  }
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceRstp_switch/2/main.tf b/internal/providerfwk/testdata/TestAccResourceRstp_switch/2/main.tf
new file mode 100644
index 00000000..01ef1de1
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceRstp_switch/2/main.tf
@@ -0,0 +1,32 @@
+resource "junos_rstp" "testacc_rstp" {
+  bpdu_block_on_edge     = true
+  backup_bridge_priority = "8k"
+  bridge_priority        = 0
+}
+
+resource "junos_routing_instance" "testacc_rstp" {
+  name = "testacc_rstp"
+  type = "virtual-switch"
+}
+
+resource "junos_rstp" "testacc_ri_rstp" {
+  routing_instance                                   = junos_routing_instance.testacc_rstp.name
+  backup_bridge_priority                             = "60k"
+  bridge_priority                                    = "4k"
+  bpdu_destination_mac_address_provider_bridge_group = true
+  extended_system_id                                 = 0
+  force_version_stp                                  = true
+  forward_delay                                      = 20
+  hello_time                                         = 5
+  max_age                                            = 22
+  priority_hold_time                                 = 100
+  system_id {
+    id = "00:11:22:33:44:55"
+  }
+  system_id {
+    id         = "00:22:33:44:55:aa"
+    ip_address = "192.0.2.4/31"
+  }
+  system_identifier             = "66:55:44:33:22:11"
+  vpls_flush_on_topology_change = true
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/1/main.tf
new file mode 100644
index 00000000..40a675a3
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/1/main.tf
@@ -0,0 +1,10 @@
+import {
+  to = junos_security.security
+  id = "security"
+}
+
+resource "junos_security" "security" {
+  log {
+    source_address = "192.0.2.2"
+  }
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/2/main.tf b/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/2/main.tf
new file mode 100644
index 00000000..6f0a9bd5
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/2/main.tf
@@ -0,0 +1,42 @@
+resource "junos_routing_instance" "testacc_logstream" {
+  lifecycle {
+    create_before_destroy = true
+  }
+  name = "testacclogstream"
+}
+resource "junos_services_ssl_initiation_profile" "testacc_logstream" {
+  lifecycle {
+    create_before_destroy = true
+  }
+  name = "test@cc logstream"
+}
+
+resource "junos_security_log_stream" "testacc_logstream" {
+  name     = "testacc_logstream"
+  category = ["idp"]
+  format   = "syslog"
+  host {
+    ip_address       = "AHostN@me"
+    port             = 514
+    routing_instance = junos_routing_instance.testacc_logstream.name
+  }
+  rate_limit = 50
+  severity   = "error"
+  transport {
+    protocol        = "tls"
+    tcp_connections = 3
+    tls_profile     = junos_services_ssl_initiation_profile.testacc_logstream.name
+  }
+}
+
+
+resource "junos_security_log_stream" "testacc_logstream2" {
+  name   = "testacc_logstream2"
+  format = "syslog"
+  host {
+    ip_address = "192.0.2.1"
+  }
+  transport {
+    protocol = "udp"
+  }
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/3/main.tf b/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/3/main.tf
new file mode 100644
index 00000000..2c6be6b4
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceSecurityLogStream_basic/3/main.tf
@@ -0,0 +1,14 @@
+resource "junos_security_log_stream" "testacc_logstream" {
+  name = "testacc_logstream"
+  file {
+    name             = "#File@test.txt"
+    allow_duplicates = true
+    size             = 3
+    rotation         = 3
+  }
+  filter_threat_attack = true
+}
+resource "junos_security_log_stream" "testacc_logstream2" {
+  name = "testacc_logstream2"
+  transport {}
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceSecurity_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceSecurity_basic/1/main.tf
index 66ad5141..412bd264 100644
--- a/internal/providerfwk/testdata/TestAccResourceSecurity_basic/1/main.tf
+++ b/internal/providerfwk/testdata/TestAccResourceSecurity_basic/1/main.tf
@@ -1,3 +1,8 @@
+import {
+  to = junos_system.system
+  id = "system"
+}
+
 resource "junos_system" "system" {
   tracing_dest_override_syslog_host = "192.0.2.13"
 }
diff --git a/internal/providerfwk/testdata/TestAccResourceSwitchOptions_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceSwitchOptions_basic/1/main.tf
index d87cf93a..e3089693 100644
--- a/internal/providerfwk/testdata/TestAccResourceSwitchOptions_basic/1/main.tf
+++ b/internal/providerfwk/testdata/TestAccResourceSwitchOptions_basic/1/main.tf
@@ -10,6 +10,8 @@ resource "junos_interface_logical" "testacc_switchOpts" {
   }
 }
 resource "junos_switch_options" "testacc_switchOpts" {
+  remote_vtep_list      = ["192.0.2.134", "192.0.2.34"]
+  remote_vtep_v6_list   = ["fe80::34"]
   service_id            = 111
   vtep_source_interface = junos_interface_logical.testacc_switchOpts.name
 }
diff --git a/internal/providerfwk/testdata/TestAccResourceVlan_router/1/main.tf b/internal/providerfwk/testdata/TestAccResourceVlan_router/1/main.tf
new file mode 100644
index 00000000..b14c2291
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVlan_router/1/main.tf
@@ -0,0 +1,64 @@
+
+resource "junos_routing_options" "testacc_vlan_vxlan" {
+  clean_on_destroy = true
+  router_id        = "192.0.2.18"
+}
+resource "junos_interface_logical" "testacc_vlan_vxlan" {
+  depends_on = [
+    junos_routing_options.testacc_vlan_vxlan,
+  ]
+  name        = "lo0.0"
+  description = "testacc_vlan_vxlan"
+  family_inet {
+    address {
+      cidr_ip = "192.0.2.18/32"
+    }
+  }
+}
+resource "junos_switch_options" "testacc_vlan_vxlan" {
+  clean_on_destroy      = true
+  vtep_source_interface = junos_interface_logical.testacc_vlan_vxlan.name
+}
+resource "junos_policyoptions_community" "testacc_vlan_vxlan" {
+  lifecycle {
+    create_before_destroy = true
+  }
+  name    = "testacc_vlan_vxlan"
+  members = ["target:65000:100"]
+}
+resource "junos_policyoptions_policy_statement" "testacc_vlan_vxlan" {
+  lifecycle {
+    create_before_destroy = true
+  }
+  name = "testacc_vlan_vxlan"
+  from {
+    bgp_community = [junos_policyoptions_community.testacc_vlan_vxlan.name]
+  }
+  then {
+    action = "accept"
+  }
+}
+resource "junos_evpn" "testacc_vlan_vxlan" {
+  depends_on = [
+    junos_switch_options.testacc_vlan_vxlan,
+  ]
+  encapsulation = "vxlan"
+  switch_or_ri_options {
+    route_distinguisher = "20:1"
+    vrf_target          = "target:20:2"
+    vrf_import          = [junos_policyoptions_policy_statement.testacc_vlan_vxlan.name]
+    vrf_export          = [junos_policyoptions_policy_statement.testacc_vlan_vxlan.name]
+  }
+}
+
+resource "junos_vlan" "testacc_vlan_vxlan" {
+  depends_on = [
+    junos_evpn.testacc_vlan_vxlan,
+  ]
+  name    = "testacc_vlan_vxlan"
+  vlan_id = 1020
+  vxlan {
+    vni                     = 102010
+    static_remote_vtep_list = ["192.0.2.136", "192.0.2.36"]
+  }
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVlan_router/2/main.tf b/internal/providerfwk/testdata/TestAccResourceVlan_router/2/main.tf
new file mode 100644
index 00000000..43a38464
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVlan_router/2/main.tf
@@ -0,0 +1,63 @@
+resource "junos_routing_options" "testacc_vlan_vxlan" {
+  clean_on_destroy = true
+  router_id        = "192.0.2.18"
+}
+resource "junos_interface_logical" "testacc_vlan_vxlan" {
+  depends_on = [
+    junos_routing_options.testacc_vlan_vxlan,
+  ]
+  name        = "lo0.0"
+  description = "testacc_vlan_vxlan"
+  family_inet {
+    address {
+      cidr_ip = "192.0.2.18/32"
+    }
+  }
+}
+resource "junos_switch_options" "testacc_vlan_vxlan" {
+  clean_on_destroy      = true
+  vtep_source_interface = junos_interface_logical.testacc_vlan_vxlan.name
+}
+resource "junos_policyoptions_community" "testacc_vlan_vxlan" {
+  lifecycle {
+    create_before_destroy = true
+  }
+  name    = "testacc_vlan_vxlan"
+  members = ["target:65000:100"]
+}
+resource "junos_policyoptions_policy_statement" "testacc_vlan_vxlan" {
+  lifecycle {
+    create_before_destroy = true
+  }
+  name = "testacc_vlan_vxlan"
+  from {
+    bgp_community = [junos_policyoptions_community.testacc_vlan_vxlan.name]
+  }
+  then {
+    action = "accept"
+  }
+}
+resource "junos_evpn" "testacc_vlan_vxlan" {
+  depends_on = [
+    junos_switch_options.testacc_vlan_vxlan,
+  ]
+  encapsulation = "vxlan"
+  switch_or_ri_options {
+    route_distinguisher = "20:1"
+    vrf_target          = "target:20:2"
+    vrf_import          = [junos_policyoptions_policy_statement.testacc_vlan_vxlan.name]
+    vrf_export          = [junos_policyoptions_policy_statement.testacc_vlan_vxlan.name]
+  }
+}
+
+resource "junos_vlan" "testacc_vlan_vxlan" {
+  depends_on = [
+    junos_evpn.testacc_vlan_vxlan,
+  ]
+  name    = "testacc_vlan_vxlan"
+  vlan_id = 1020
+  vxlan {
+    vni                     = 102010
+    static_remote_vtep_list = ["192.0.2.136"]
+  }
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/1/main.tf
new file mode 100644
index 00000000..5ac5b03a
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/1/main.tf
@@ -0,0 +1,50 @@
+resource "junos_vstp_interface" "testacc_vstp_interface" {
+  name = "all"
+}
+resource "junos_vstp_vlan" "testacc_vstp_interface2" {
+  vlan_id = "10"
+}
+resource "junos_interface_physical" "testacc_vstp_interface2" {
+  name         = var.interface
+  description  = "testacc_vstp_interface2"
+  vlan_members = ["15"]
+}
+resource "junos_vstp_interface" "testacc_vstp_interface2" {
+  name = junos_interface_physical.testacc_vstp_interface2.name
+  vlan = junos_vstp_vlan.testacc_vstp_interface2.vlan_id
+}
+resource "junos_vstp_vlan_group" "testacc_vstp_interface3" {
+  name = "testacc_vstp_interface2"
+  vlan = ["11"]
+}
+resource "junos_vstp_interface" "testacc_vstp_interface3" {
+  name       = "all"
+  vlan_group = junos_vstp_vlan_group.testacc_vstp_interface3.name
+}
+resource "junos_routing_instance" "testacc_vstp_interface" {
+  name = "testacc_vstp_intface"
+  type = "virtual-switch"
+}
+resource "junos_vstp_interface" "testacc_vstp_interface4" {
+  name             = "all"
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+}
+resource "junos_vstp_vlan" "testacc_vstp_interface5" {
+  vlan_id          = "all"
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+}
+resource "junos_vstp_interface" "testacc_vstp_interface5" {
+  name             = "all"
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+  vlan             = junos_vstp_vlan.testacc_vstp_interface5.vlan_id
+}
+resource "junos_vstp_vlan_group" "testacc_vstp_interface6" {
+  name             = "testacc_vstp_interface6"
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+  vlan             = ["13"]
+}
+resource "junos_vstp_interface" "testacc_vstp_interface6" {
+  name             = var.interface
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+  vlan_group       = junos_vstp_vlan_group.testacc_vstp_interface6.name
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/1/variables.tf b/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/1/variables.tf
new file mode 100644
index 00000000..d5ed041c
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/1/variables.tf
@@ -0,0 +1,3 @@
+variable "interface" {
+  type = string
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/2/main.tf b/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/2/main.tf
new file mode 100644
index 00000000..133ca2a4
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/2/main.tf
@@ -0,0 +1,63 @@
+resource "junos_vstp_interface" "testacc_vstp_interface" {
+  name                      = "all"
+  bpdu_timeout_action_alarm = true
+  bpdu_timeout_action_block = true
+  cost                      = 101
+  edge                      = true
+  priority                  = 32
+}
+resource "junos_vstp_vlan" "testacc_vstp_interface2" {
+  vlan_id = "10"
+}
+resource "junos_interface_physical" "testacc_vstp_interface2" {
+  name         = var.interface
+  description  = "testacc_vstp_interface2"
+  vlan_members = ["15"]
+}
+resource "junos_vstp_interface" "testacc_vstp_interface2" {
+  name         = junos_interface_physical.testacc_vstp_interface2.name
+  access_trunk = true
+  mode         = "shared"
+  no_root_port = true
+  vlan         = junos_vstp_vlan.testacc_vstp_interface2.vlan_id
+}
+resource "junos_vstp_vlan_group" "testacc_vstp_interface3" {
+  name = "testacc_vstp_interface2"
+  vlan = ["11"]
+}
+resource "junos_vstp_interface" "testacc_vstp_interface3" {
+  name       = "all"
+  priority   = 32
+  vlan_group = junos_vstp_vlan_group.testacc_vstp_interface3.name
+}
+resource "junos_routing_instance" "testacc_vstp_interface" {
+  name = "testacc_vstp_intface"
+  type = "virtual-switch"
+}
+resource "junos_vstp_interface" "testacc_vstp_interface4" {
+  name             = "all"
+  edge             = true
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+}
+resource "junos_vstp_vlan" "testacc_vstp_interface5" {
+  vlan_id          = "all"
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+}
+resource "junos_vstp_interface" "testacc_vstp_interface5" {
+  name             = "all"
+  mode             = "point-to-point"
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+  vlan             = junos_vstp_vlan.testacc_vstp_interface5.vlan_id
+}
+resource "junos_vstp_vlan_group" "testacc_vstp_interface6" {
+  name             = "testacc_vstp_interface6"
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+  vlan             = ["13"]
+}
+resource "junos_vstp_interface" "testacc_vstp_interface6" {
+  name             = var.interface
+  no_root_port     = true
+  priority         = 64
+  routing_instance = junos_routing_instance.testacc_vstp_interface.name
+  vlan_group       = junos_vstp_vlan_group.testacc_vstp_interface6.name
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/2/variables.tf b/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/2/variables.tf
new file mode 100644
index 00000000..d5ed041c
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstpInterface_basic/2/variables.tf
@@ -0,0 +1,3 @@
+variable "interface" {
+  type = string
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstpVlanGroup_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceVstpVlanGroup_basic/1/main.tf
new file mode 100644
index 00000000..31a01afb
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstpVlanGroup_basic/1/main.tf
@@ -0,0 +1,14 @@
+resource "junos_vstp_vlan_group" "testacc_vstp_vlan_group" {
+  name = "vlanGroup"
+  vlan = ["10"]
+}
+resource "junos_routing_instance" "testacc_vstp_vlan_group" {
+  name = "testacc_vstp_vlan_group"
+  type = "virtual-switch"
+}
+resource "junos_vstp_vlan_group" "testacc_ri_vstp_vlan_group" {
+  routing_instance = junos_routing_instance.testacc_vstp_vlan_group.name
+  name             = "vlanGroupRI"
+  vlan             = ["12"]
+  bridge_priority  = "16k"
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstpVlanGroup_basic/2/main.tf b/internal/providerfwk/testdata/TestAccResourceVstpVlanGroup_basic/2/main.tf
new file mode 100644
index 00000000..c595053c
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstpVlanGroup_basic/2/main.tf
@@ -0,0 +1,22 @@
+
+resource "junos_vstp_vlan_group" "testacc_vstp_vlan_group" {
+  name                   = "vlanGroup"
+  vlan                   = ["10"]
+  backup_bridge_priority = "8k"
+  bridge_priority        = "4k"
+  hello_time             = 2
+}
+resource "junos_routing_instance" "testacc_vstp_vlan_group" {
+  name = "testacc_vstp_vlan_group"
+  type = "virtual-switch"
+}
+resource "junos_vstp_vlan_group" "testacc_ri_vstp_vlan_group" {
+  routing_instance       = junos_routing_instance.testacc_vstp_vlan_group.name
+  name                   = "vlanGroupRI"
+  vlan                   = ["12", "11"]
+  backup_bridge_priority = "20k"
+  forward_delay          = 22
+  hello_time             = 3
+  max_age                = 24
+  system_identifier      = "00:aa:bc:ed:ff:11"
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstpVlan_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceVstpVlan_basic/1/main.tf
new file mode 100644
index 00000000..358e50fe
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstpVlan_basic/1/main.tf
@@ -0,0 +1,20 @@
+resource "junos_vstp_vlan" "testacc_vstp_vlan" {
+  vlan_id = "10"
+}
+resource "junos_vstp_vlan" "testacc_vstp_vlan_all" {
+  vlan_id = "all"
+}
+resource "junos_routing_instance" "testacc_vstp_vlan" {
+  name = "testacc_vstp_vlan"
+  type = "virtual-switch"
+}
+resource "junos_vstp_vlan" "testacc_ri_vstp_vlan" {
+  routing_instance = junos_routing_instance.testacc_vstp_vlan.name
+  vlan_id          = "11"
+  bridge_priority  = "16k"
+}
+resource "junos_vstp_vlan" "testacc_ri_vstp_vlan_all" {
+  routing_instance  = junos_routing_instance.testacc_vstp_vlan.name
+  vlan_id           = "all"
+  system_identifier = "00:aa:bc:ed:ff:11"
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstpVlan_basic/2/main.tf b/internal/providerfwk/testdata/TestAccResourceVstpVlan_basic/2/main.tf
new file mode 100644
index 00000000..31a322e4
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstpVlan_basic/2/main.tf
@@ -0,0 +1,26 @@
+resource "junos_vstp_vlan" "testacc_vstp_vlan" {
+  vlan_id                = "10"
+  backup_bridge_priority = "8k"
+  bridge_priority        = "4k"
+}
+resource "junos_vstp_vlan" "testacc_vstp_vlan_all" {
+  vlan_id    = "all"
+  hello_time = 2
+}
+resource "junos_routing_instance" "testacc_vstp_vlan" {
+  name = "testacc_vstp_vlan"
+  type = "virtual-switch"
+}
+resource "junos_vstp_vlan" "testacc_ri_vstp_vlan" {
+  routing_instance       = junos_routing_instance.testacc_vstp_vlan.name
+  vlan_id                = "11"
+  backup_bridge_priority = "20k"
+  bridge_priority        = 0
+  forward_delay          = 22
+  hello_time             = 3
+  max_age                = 24
+}
+resource "junos_vstp_vlan" "testacc_ri_vstp_vlan_all" {
+  routing_instance = junos_routing_instance.testacc_vstp_vlan.name
+  vlan_id          = "all"
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstp_basic/1/main.tf b/internal/providerfwk/testdata/TestAccResourceVstp_basic/1/main.tf
new file mode 100644
index 00000000..65bb9d66
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstp_basic/1/main.tf
@@ -0,0 +1,13 @@
+resource "junos_vstp" "testacc_vstp" {
+  bpdu_block_on_edge = true
+}
+resource "junos_routing_instance" "testacc_vstp" {
+  name = "testacc_vstp"
+  type = "virtual-switch"
+}
+resource "junos_vstp" "testacc_ri_vstp" {
+  routing_instance = junos_routing_instance.testacc_vstp.name
+  system_id {
+    id = "00:11:22:33:44:56"
+  }
+}
diff --git a/internal/providerfwk/testdata/TestAccResourceVstp_basic/2/main.tf b/internal/providerfwk/testdata/TestAccResourceVstp_basic/2/main.tf
new file mode 100644
index 00000000..96656b21
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccResourceVstp_basic/2/main.tf
@@ -0,0 +1,21 @@
+resource "junos_vstp" "testacc_vstp" {
+  disable = true
+}
+resource "junos_routing_instance" "testacc_vstp" {
+  name = "testacc_vstp"
+  type = "virtual-switch"
+}
+resource "junos_vstp" "testacc_ri_vstp" {
+  routing_instance   = junos_routing_instance.testacc_vstp.name
+  bpdu_block_on_edge = true
+  force_version_stp  = true
+  priority_hold_time = 10
+  system_id {
+    id = "00:11:22:33:44:55"
+  }
+  system_id {
+    id         = "00:22:33:44:55:aa"
+    ip_address = "192.0.2.4/31"
+  }
+  vpls_flush_on_topology_change = true
+}
diff --git a/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/1/main.tf b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/1/main.tf
new file mode 100644
index 00000000..40a675a3
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/1/main.tf
@@ -0,0 +1,10 @@
+import {
+  to = junos_security.security
+  id = "security"
+}
+
+resource "junos_security" "security" {
+  log {
+    source_address = "192.0.2.2"
+  }
+}
diff --git a/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/1/provider.tf b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/1/provider.tf
new file mode 120000
index 00000000..472a1114
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/1/provider.tf
@@ -0,0 +1 @@
+../2/provider.tf
\ No newline at end of file
diff --git a/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/2/main.tf b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/2/main.tf
new file mode 100644
index 00000000..e575dcf9
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/2/main.tf
@@ -0,0 +1,29 @@
+resource "junos_routing_instance" "testacc_logstream" {
+  lifecycle {
+    create_before_destroy = true
+  }
+  name = "testacclogstream"
+}
+
+resource "junos_security_log_stream" "testacc_logstream" {
+  name     = "testacc_logstream"
+  category = ["idp"]
+  format   = "syslog"
+  host {
+    ip_address       = "192.0.2.1"
+    port             = 514
+    routing_instance = junos_routing_instance.testacc_logstream.name
+  }
+  rate_limit = 50
+  severity   = "error"
+}
+resource "junos_security_log_stream" "testacc_logstream2" {
+  name = "testacc_logstream2"
+  file {
+    name             = "test"
+    allow_duplicates = true
+    size             = 3
+    rotation         = 3
+  }
+  filter_threat_attack = true
+}
diff --git a/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/2/provider.tf b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/2/provider.tf
new file mode 100644
index 00000000..713fa309
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/2/provider.tf
@@ -0,0 +1,10 @@
+terraform {
+  required_providers {
+    junos = {
+      source  = "registry.terraform.io/jeremmfr/junos"
+      version = "1.33.0"
+    }
+  }
+}
+
+provider "junos" {}
diff --git a/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/3/main.tf b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/3/main.tf
new file mode 120000
index 00000000..19701121
--- /dev/null
+++ b/internal/providerfwk/testdata/TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic/3/main.tf
@@ -0,0 +1 @@
+../2/main.tf
\ No newline at end of file
diff --git a/internal/providerfwk/upgradestate_bridge_domain.go b/internal/providerfwk/upgradestate_bridge_domain.go
index fc7f4d64..5e6357d4 100644
--- a/internal/providerfwk/upgradestate_bridge_domain.go
+++ b/internal/providerfwk/upgradestate_bridge_domain.go
@@ -105,11 +105,11 @@ func upgradeBridgeDomainStateV0toV1(
 		IsolatedVLAN     types.Int64    `tfsdk:"isolated_vlan"`
 		RoutingInterface types.String   `tfsdk:"routing_interface"`
 		ServiceID        types.Int64    `tfsdk:"service_id"`
-		VLANID           types.Int64    `tfsdk:"vlan_id"`
-		VLANIDList       []types.String `tfsdk:"vlan_id_list"`
-		VXLAN            []struct {
-			VNI                        types.Int64  `tfsdk:"vni"`
-			VNIExtendEvpn              types.Bool   `tfsdk:"vni_extend_evpn"`
+		VlanID           types.Int64    `tfsdk:"vlan_id"`
+		VlanIDList       []types.String `tfsdk:"vlan_id_list"`
+		Vxlan            []struct {
+			Vni                        types.Int64  `tfsdk:"vni"`
+			VniExtendEvpn              types.Bool   `tfsdk:"vni_extend_evpn"`
 			DecapsulateAcceptInnerVlan types.Bool   `tfsdk:"decapsulate_accept_inner_vlan"`
 			EncapsulateInnerVlan       types.Bool   `tfsdk:"encapsulate_inner_vlan"`
 			IngressNodeReplication     types.Bool   `tfsdk:"ingress_node_replication"`
@@ -136,18 +136,18 @@ func upgradeBridgeDomainStateV0toV1(
 	dataV1.IsolatedVLAN = dataV0.IsolatedVLAN
 	dataV1.RoutingInterface = dataV0.RoutingInterface
 	dataV1.ServiceID = dataV0.ServiceID
-	dataV1.VLANID = dataV0.VLANID
-	dataV1.VLANIDList = dataV0.VLANIDList
-	if len(dataV0.VXLAN) > 0 {
-		dataV1.VXLAN = &bridgeDomainBlockVXLAN{
-			VNIExtendEvpn:              dataV0.VXLAN[0].VNIExtendEvpn,
-			DecapsulateAcceptInnerVlan: dataV0.VXLAN[0].DecapsulateAcceptInnerVlan,
-			EncapsulateInnerVlan:       dataV0.VXLAN[0].EncapsulateInnerVlan,
-			IngressNodeReplication:     dataV0.VXLAN[0].IngressNodeReplication,
-			OvsdbManaged:               dataV0.VXLAN[0].OvsdbManaged,
-			VNI:                        dataV0.VXLAN[0].VNI,
-			MulticastGroup:             dataV0.VXLAN[0].MulticastGroup,
-			UnreachableVtepAgingTimer:  dataV0.VXLAN[0].UnreachableVtepAgingTimer,
+	dataV1.VlanID = dataV0.VlanID
+	dataV1.VlanIDList = dataV0.VlanIDList
+	if len(dataV0.Vxlan) > 0 {
+		dataV1.Vxlan = &bridgeDomainBlockVxlan{
+			Vni:                        dataV0.Vxlan[0].Vni,
+			VniExtendEvpn:              dataV0.Vxlan[0].VniExtendEvpn,
+			DecapsulateAcceptInnerVlan: dataV0.Vxlan[0].DecapsulateAcceptInnerVlan,
+			EncapsulateInnerVlan:       dataV0.Vxlan[0].EncapsulateInnerVlan,
+			IngressNodeReplication:     dataV0.Vxlan[0].IngressNodeReplication,
+			OvsdbManaged:               dataV0.Vxlan[0].OvsdbManaged,
+			MulticastGroup:             dataV0.Vxlan[0].MulticastGroup,
+			UnreachableVtepAgingTimer:  dataV0.Vxlan[0].UnreachableVtepAgingTimer,
 		}
 	}
 
diff --git a/internal/providerfwk/upgradestate_security_log_stream.go b/internal/providerfwk/upgradestate_security_log_stream.go
new file mode 100644
index 00000000..c34c5579
--- /dev/null
+++ b/internal/providerfwk/upgradestate_security_log_stream.go
@@ -0,0 +1,136 @@
+package providerfwk
+
+import (
+	"context"
+
+	"github.com/hashicorp/terraform-plugin-framework/resource"
+	"github.com/hashicorp/terraform-plugin-framework/resource/schema"
+	"github.com/hashicorp/terraform-plugin-framework/types"
+)
+
+func (rsc *securityLogStream) UpgradeState(_ context.Context) map[int64]resource.StateUpgrader {
+	return map[int64]resource.StateUpgrader{
+		0: {
+			PriorSchema: &schema.Schema{
+				Attributes: map[string]schema.Attribute{
+					"id": schema.StringAttribute{
+						Computed: true,
+					},
+					"name": schema.StringAttribute{
+						Required: true,
+					},
+					"category": schema.ListAttribute{
+						ElementType: types.StringType,
+						Optional:    true,
+					},
+					"filter_threat_attack": schema.BoolAttribute{
+						Optional: true,
+					},
+					"format": schema.StringAttribute{
+						Optional: true,
+					},
+					"rate_limit": schema.Int64Attribute{
+						Optional: true,
+					},
+					"severity": schema.StringAttribute{
+						Optional: true,
+					},
+				},
+				Blocks: map[string]schema.Block{
+					"file": schema.ListNestedBlock{
+						NestedObject: schema.NestedBlockObject{
+							Attributes: map[string]schema.Attribute{
+								"name": schema.StringAttribute{
+									Required: true,
+								},
+								"allow_duplicates": schema.BoolAttribute{
+									Optional: true,
+								},
+								"rotation": schema.Int64Attribute{
+									Optional: true,
+								},
+								"size": schema.Int64Attribute{
+									Optional: true,
+								},
+							},
+						},
+					},
+					"host": schema.ListNestedBlock{
+						NestedObject: schema.NestedBlockObject{
+							Attributes: map[string]schema.Attribute{
+								"ip_address": schema.StringAttribute{
+									Required: true,
+								},
+								"port": schema.Int64Attribute{
+									Optional: true,
+								},
+								"routing_instance": schema.StringAttribute{
+									Optional: true,
+								},
+							},
+						},
+					},
+				},
+			},
+			StateUpgrader: upgradeSecurityLogStreamV0toV1,
+		},
+	}
+}
+
+func upgradeSecurityLogStreamV0toV1(
+	ctx context.Context, req resource.UpgradeStateRequest, resp *resource.UpgradeStateResponse,
+) {
+	type modelV0 struct {
+		ID                 types.String   `tfsdk:"id"`
+		Name               types.String   `tfsdk:"name"`
+		Category           []types.String `tfsdk:"category"`
+		FilterThreatAttack types.Bool     `tfsdk:"filter_threat_attack"`
+		Format             types.String   `tfsdk:"format"`
+		RateLimit          types.Int64    `tfsdk:"rate_limit"`
+		Severity           types.String   `tfsdk:"severity"`
+		File               []struct {
+			Name            types.String `tfsdk:"name"`
+			AllowDuplicates types.Bool   `tfsdk:"allow_duplicates"`
+			Rotation        types.Int64  `tfsdk:"rotation"`
+			Size            types.Int64  `tfsdk:"size"`
+		} `tfsdk:"file"`
+		Host []struct {
+			IPAddress       types.String `tfsdk:"ip_address"`
+			Port            types.Int64  `tfsdk:"port"`
+			RoutingInstance types.String `tfsdk:"routing_instance"`
+		} `tfsdk:"host"`
+	}
+
+	var dataV0 modelV0
+	resp.Diagnostics.Append(req.State.Get(ctx, &dataV0)...)
+	if resp.Diagnostics.HasError() {
+		return
+	}
+
+	var dataV1 securityLogStreamData
+	dataV1.ID = dataV0.ID
+	dataV1.Name = dataV0.Name
+	dataV1.Category = dataV0.Category
+	dataV1.FilterThreatAttack = dataV0.FilterThreatAttack
+	dataV1.Format = dataV0.Format
+	dataV1.RateLimit = dataV0.RateLimit
+	dataV1.Severity = dataV0.Severity
+	if len(dataV0.File) > 0 {
+		dataV1.File = &securityLogStreamBlockFile{
+			Name:            dataV0.File[0].Name,
+			AllowDuplicates: dataV0.File[0].AllowDuplicates,
+			Rotation:        dataV0.File[0].Rotation,
+			Size:            dataV0.File[0].Size,
+		}
+	}
+
+	if len(dataV0.Host) > 0 {
+		dataV1.Host = &securityLogStreamBlockHost{
+			IPAddress:       dataV0.Host[0].IPAddress,
+			Port:            dataV0.Host[0].Port,
+			RoutingInstance: dataV0.Host[0].RoutingInstance,
+		}
+	}
+
+	resp.Diagnostics.Append(resp.State.Set(ctx, dataV1)...)
+}
diff --git a/internal/providerfwk/upgradestate_security_log_stream_test.go b/internal/providerfwk/upgradestate_security_log_stream_test.go
new file mode 100644
index 00000000..714541d4
--- /dev/null
+++ b/internal/providerfwk/upgradestate_security_log_stream_test.go
@@ -0,0 +1,37 @@
+package providerfwk_test
+
+import (
+	"os"
+	"testing"
+
+	"github.com/hashicorp/terraform-plugin-testing/config"
+	"github.com/hashicorp/terraform-plugin-testing/helper/resource"
+	"github.com/hashicorp/terraform-plugin-testing/plancheck"
+)
+
+func TestAccUpgradeStateResourceSecurityLogStream_V0toV1_basic(t *testing.T) {
+	if os.Getenv("TESTACC_UPGRADE_STATE") == "" {
+		return
+	}
+	if os.Getenv("TESTACC_SRX") != "" {
+		resource.Test(t, resource.TestCase{
+			Steps: []resource.TestStep{
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ConfigDirectory: config.TestStepDirectory(),
+				},
+				{
+					ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
+					ConfigDirectory:          config.TestStepDirectory(),
+					ConfigPlanChecks: resource.ConfigPlanChecks{
+						PreApply: []plancheck.PlanCheck{
+							plancheck.ExpectEmptyPlan(),
+						},
+					},
+				},
+			},
+		})
+	}
+}
diff --git a/internal/providersdk/constants.go b/internal/providersdk/constants.go
index 4e97290a..1be2e1b0 100644
--- a/internal/providersdk/constants.go
+++ b/internal/providersdk/constants.go
@@ -1,3 +1,10 @@
 package providersdk
 
+import "github.com/jeremmfr/terraform-provider-junos/internal/junos"
+
 const failedConvAtoiError = "failed to convert value from '%s' to integer: %w"
+
+const (
+	setRoutingInstances = junos.SetLS + junos.RoutingInstancesWS
+	delRoutingInstances = junos.DeleteLS + junos.RoutingInstancesWS
+)
diff --git a/internal/providersdk/provider.go b/internal/providersdk/provider.go
index 85553727..a10a2639 100644
--- a/internal/providersdk/provider.go
+++ b/internal/providersdk/provider.go
@@ -194,15 +194,11 @@ func Provider() *schema.Provider {
 
 			"junos_routing_options": resourceRoutingOptions(),
 
-			"junos_rstp":           resourceRstp(),
-			"junos_rstp_interface": resourceRstpInterface(),
-
 			"junos_security_dynamic_address_feed_server":                 resourceSecurityDynamicAddressFeedServer(),
 			"junos_security_dynamic_address_name":                        resourceSecurityDynamicAddressName(),
 			"junos_security_idp_custom_attack":                           resourceSecurityIdpCustomAttack(),
 			"junos_security_idp_custom_attack_group":                     resourceSecurityIdpCustomAttackGroup(),
 			"junos_security_idp_policy":                                  resourceSecurityIdpPolicy(),
-			"junos_security_log_stream":                                  resourceSecurityLogStream(),
 			"junos_security_screen":                                      resourceSecurityScreen(),
 			"junos_security_screen_whitelist":                            resourceSecurityScreenWhiteList(),
 			"junos_security_utm_custom_url_category":                     resourceSecurityUtmCustomURLCategory(),
@@ -228,11 +224,6 @@ func Provider() *schema.Provider {
 			"junos_system_ntp_server":                      resourceSystemNtpServer(),
 			"junos_system_root_authentication":             resourceSystemRootAuthentication(),
 			"junos_system_services_dhcp_localserver_group": resourceSystemServicesDhcpLocalServerGroup(),
-
-			"junos_vstp":            resourceVstp(),
-			"junos_vstp_interface":  resourceVstpInterface(),
-			"junos_vstp_vlan":       resourceVstpVlan(),
-			"junos_vstp_vlan_group": resourceVstpVlanGroup(),
 		},
 		DataSourcesMap: map[string]*schema.Resource{
 			"junos_system_information": dataSourceSystemInformation(),
diff --git a/internal/providersdk/resource_access_address_assignment_pool.go b/internal/providersdk/resource_access_address_assignment_pool.go
index 6f7e51e8..01767b0c 100644
--- a/internal/providersdk/resource_access_address_assignment_pool.go
+++ b/internal/providersdk/resource_access_address_assignment_pool.go
@@ -752,7 +752,7 @@ func setAccessAddressAssignPool(d *schema.ResourceData, junSess *junos.Session)
 
 	setPrefix := junos.SetLS
 	if d.Get("routing_instance").(string) != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + d.Get("routing_instance").(string) + " "
+		setPrefix = setRoutingInstances + d.Get("routing_instance").(string) + " "
 	}
 	setPrefix += "access address-assignment pool " + d.Get("name").(string) + " "
 
@@ -1366,7 +1366,7 @@ func delAccessAddressAssignPool(name, instance string, junSess *junos.Session) e
 	if instance == junos.DefaultW {
 		configSet = append(configSet, "delete access address-assignment pool "+name)
 	} else {
-		configSet = append(configSet, junos.DelRoutingInstances+instance+" access address-assignment pool "+name)
+		configSet = append(configSet, delRoutingInstances+instance+" access address-assignment pool "+name)
 	}
 
 	return junSess.ConfigSet(configSet)
diff --git a/internal/providersdk/resource_forwardingoptions_dhcprelay.go b/internal/providersdk/resource_forwardingoptions_dhcprelay.go
index d830019a..93621c1d 100644
--- a/internal/providersdk/resource_forwardingoptions_dhcprelay.go
+++ b/internal/providersdk/resource_forwardingoptions_dhcprelay.go
@@ -788,7 +788,7 @@ func setForwardingOptionsDhcpRelay( //nolint:gocognit,gocyclo
 
 	setPrefix := junos.SetLS
 	if d.Get("routing_instance").(string) != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + d.Get("routing_instance").(string) + " "
+		setPrefix = setRoutingInstances + d.Get("routing_instance").(string) + " "
 	}
 	if d.Get("version").(string) == "v6" {
 		setPrefix += "forwarding-options dhcp-relay dhcpv6 "
@@ -1555,9 +1555,9 @@ func delForwardingOptionsDhcpRelay(instance, version string, junSess *junos.Sess
 	case instance == junos.DefaultW && version == "v4":
 		delPrefix = junos.DeleteLS + "forwarding-options dhcp-relay "
 	case instance != junos.DefaultW && version == "v6":
-		delPrefix = junos.DelRoutingInstances + instance + " forwarding-options dhcp-relay dhcpv6 "
+		delPrefix = delRoutingInstances + instance + " forwarding-options dhcp-relay dhcpv6 "
 	case instance != junos.DefaultW && version == "v4":
-		delPrefix = junos.DelRoutingInstances + instance + " forwarding-options dhcp-relay "
+		delPrefix = delRoutingInstances + instance + " forwarding-options dhcp-relay "
 	}
 	listLinesToDelete := []string{
 		"access-profile",
diff --git a/internal/providersdk/resource_forwardingoptions_dhcprelay_group.go b/internal/providersdk/resource_forwardingoptions_dhcprelay_group.go
index 37dc22e1..3eb77847 100644
--- a/internal/providersdk/resource_forwardingoptions_dhcprelay_group.go
+++ b/internal/providersdk/resource_forwardingoptions_dhcprelay_group.go
@@ -885,7 +885,7 @@ func setForwardingOptionsDhcpRelayGroup(d *schema.ResourceData, junSess *junos.S
 
 	setPrefix := junos.SetLS
 	if d.Get("routing_instance").(string) != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + d.Get("routing_instance").(string) + " "
+		setPrefix = setRoutingInstances + d.Get("routing_instance").(string) + " "
 	}
 	if d.Get("version").(string) == "v6" {
 		setPrefix += "forwarding-options dhcp-relay dhcpv6 group " + d.Get("name").(string) + " "
@@ -1675,10 +1675,10 @@ func delForwardingOptionsDhcpRelayGroup(name, instance, version string, junSess
 	case instance == junos.DefaultW && version == "v4":
 		configSet = append(configSet, junos.DeleteLS+"forwarding-options dhcp-relay group "+name)
 	case instance != junos.DefaultW && version == "v6":
-		configSet = append(configSet, junos.DelRoutingInstances+instance+" "+
+		configSet = append(configSet, delRoutingInstances+instance+" "+
 			"forwarding-options dhcp-relay dhcpv6 group "+name)
 	case instance != junos.DefaultW && version == "v4":
-		configSet = append(configSet, junos.DelRoutingInstances+instance+" "+
+		configSet = append(configSet, delRoutingInstances+instance+" "+
 			"forwarding-options dhcp-relay group "+name)
 	}
 
diff --git a/internal/providersdk/resource_forwardingoptions_dhcprelay_servergroup.go b/internal/providersdk/resource_forwardingoptions_dhcprelay_servergroup.go
index 36d8d438..2ae80539 100644
--- a/internal/providersdk/resource_forwardingoptions_dhcprelay_servergroup.go
+++ b/internal/providersdk/resource_forwardingoptions_dhcprelay_servergroup.go
@@ -367,7 +367,7 @@ func setForwardingOptionsDhcpRelayServerGroup(d *schema.ResourceData, junSess *j
 
 	setPrefix := junos.SetLS
 	if d.Get("routing_instance").(string) != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + d.Get("routing_instance").(string) + " "
+		setPrefix = setRoutingInstances + d.Get("routing_instance").(string) + " "
 	}
 	if d.Get("version").(string) == "v6" {
 		setPrefix += "forwarding-options dhcp-relay dhcpv6 server-group " + d.Get("name").(string) + " "
@@ -429,10 +429,10 @@ func delForwardingOptionsDhcpRelayServerGroup(name, instance, version string, ju
 	case instance == junos.DefaultW && version == "v4":
 		configSet = append(configSet, junos.DeleteLS+"forwarding-options dhcp-relay server-group "+name)
 	case instance != junos.DefaultW && version == "v6":
-		configSet = append(configSet, junos.DelRoutingInstances+instance+" "+
+		configSet = append(configSet, delRoutingInstances+instance+" "+
 			"forwarding-options dhcp-relay dhcpv6 server-group "+name)
 	case instance != junos.DefaultW && version == "v4":
-		configSet = append(configSet, junos.DelRoutingInstances+instance+" "+
+		configSet = append(configSet, delRoutingInstances+instance+" "+
 			"forwarding-options dhcp-relay server-group "+name)
 	}
 
diff --git a/internal/providersdk/resource_igmp_snooping_vlan.go b/internal/providersdk/resource_igmp_snooping_vlan.go
index b371611c..d8babbec 100644
--- a/internal/providersdk/resource_igmp_snooping_vlan.go
+++ b/internal/providersdk/resource_igmp_snooping_vlan.go
@@ -418,7 +418,7 @@ func setIgmpSnoopingVlan(d *schema.ResourceData, junSess *junos.Session) error {
 
 	setPrefix := junos.SetLS
 	if rI := d.Get("routing_instance").(string); rI != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + rI + " "
+		setPrefix = setRoutingInstances + rI + " "
 	}
 	setPrefix += "protocols igmp-snooping vlan " + d.Get("name").(string) + " "
 
@@ -586,7 +586,7 @@ func delIgmpSnoopingVlan(name, routingInstance string, junSess *junos.Session) e
 	if routingInstance == junos.DefaultW {
 		configSet = append(configSet, "delete protocols igmp-snooping vlan "+name)
 	} else {
-		configSet = append(configSet, junos.DelRoutingInstances+routingInstance+" protocols igmp-snooping vlan "+name)
+		configSet = append(configSet, delRoutingInstances+routingInstance+" protocols igmp-snooping vlan "+name)
 	}
 
 	return junSess.ConfigSet(configSet)
diff --git a/internal/providersdk/resource_rip_group.go b/internal/providersdk/resource_rip_group.go
index 8ed75da4..85eaceb9 100644
--- a/internal/providersdk/resource_rip_group.go
+++ b/internal/providersdk/resource_rip_group.go
@@ -498,7 +498,7 @@ func setRipGroup(d *schema.ResourceData, junSess *junos.Session) error {
 
 	setPrefix := junos.SetLS
 	if rI := d.Get("routing_instance").(string); rI != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + rI + " "
+		setPrefix = setRoutingInstances + rI + " "
 	}
 	if d.Get("ng").(bool) {
 		setPrefix += "protocols ripng group "
@@ -726,7 +726,7 @@ func delRipGroup(
 ) error {
 	delPrefix := junos.DeleteLS
 	if routingInstance != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + routingInstance + " "
+		delPrefix = delRoutingInstances + routingInstance + " "
 	}
 	if ripNg {
 		delPrefix += "protocols ripng group "
diff --git a/internal/providersdk/resource_rip_neighbor.go b/internal/providersdk/resource_rip_neighbor.go
index 0425d62a..432c10e3 100644
--- a/internal/providersdk/resource_rip_neighbor.go
+++ b/internal/providersdk/resource_rip_neighbor.go
@@ -622,7 +622,7 @@ func setRipNeighbor(d *schema.ResourceData, junSess *junos.Session) error {
 
 	setPrefix := junos.SetLS
 	if rI := d.Get("routing_instance").(string); rI != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + rI + " "
+		setPrefix = setRoutingInstances + rI + " "
 	}
 	if d.Get("ng").(bool) {
 		setPrefix += "protocols ripng group "
@@ -932,7 +932,7 @@ func delRipNeighbor(
 ) error {
 	delPrefix := junos.DeleteLS
 	if routingInstance != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + routingInstance + " "
+		delPrefix = delRoutingInstances + routingInstance + " "
 	}
 	if ripNg {
 		delPrefix += "protocols ripng group "
diff --git a/internal/providersdk/resource_rstp.go b/internal/providersdk/resource_rstp.go
deleted file mode 100644
index 86418e34..00000000
--- a/internal/providersdk/resource_rstp.go
+++ /dev/null
@@ -1,586 +0,0 @@
-package providersdk
-
-import (
-	"context"
-	"fmt"
-	"regexp"
-	"slices"
-	"strconv"
-	"strings"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
-	balt "github.com/jeremmfr/go-utils/basicalter"
-)
-
-type rstpOptions struct {
-	bpduBlockOnEdge             bool
-	bpduDestMACAddProvBridgeGrp bool
-	disable                     bool
-	forceVersionStp             bool
-	vplsFlushOnTopologyChange   bool
-	extendedSystemID            int
-	forwardDelay                int
-	helloTime                   int
-	maxAge                      int
-	priorityHoldTime            int
-	backupBridgePriority        string
-	bridgePriority              string
-	routingInstance             string
-	systemIdentifier            string
-	systemID                    []map[string]interface{}
-}
-
-func resourceRstp() *schema.Resource {
-	return &schema.Resource{
-		CreateWithoutTimeout: resourceRstpCreate,
-		ReadWithoutTimeout:   resourceRstpRead,
-		UpdateWithoutTimeout: resourceRstpUpdate,
-		DeleteWithoutTimeout: resourceRstpDelete,
-		Importer: &schema.ResourceImporter{
-			StateContext: resourceRstpImport,
-		},
-		Schema: map[string]*schema.Schema{
-			"routing_instance": {
-				Type:             schema.TypeString,
-				Optional:         true,
-				ForceNew:         true,
-				Default:          junos.DefaultW,
-				ValidateDiagFunc: validateNameObjectJunos([]string{}, 64, formatDefault),
-			},
-			"backup_bridge_priority": {
-				Type:     schema.TypeString,
-				Optional: true,
-				ValidateFunc: validation.StringMatch(regexp.MustCompile(
-					`^\d\d?k$`), "must be a number with increments of 4k - 4k,8k,..60k"),
-			},
-			"bpdu_block_on_edge": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"bpdu_destination_mac_address_provider_bridge_group": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"bridge_priority": {
-				Type:     schema.TypeString,
-				Optional: true,
-				ValidateFunc: validation.StringMatch(regexp.MustCompile(
-					`^(0|\d\d?k)$`), "must be a number with increments of 4k - 0,4k,8k,..60k"),
-			},
-			"disable": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"extended_system_id": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(0, 4095),
-				Default:      -1,
-			},
-			"force_version_stp": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"forward_delay": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(4, 30),
-			},
-			"hello_time": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(1, 10),
-			},
-			"max_age": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(6, 40),
-			},
-			"priority_hold_time": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(1, 255),
-			},
-			"system_id": {
-				Type:     schema.TypeSet,
-				Optional: true,
-				Elem: &schema.Resource{
-					Schema: map[string]*schema.Schema{
-						"id": {
-							Type:         schema.TypeString,
-							Required:     true,
-							ValidateFunc: validation.IsMACAddress,
-						},
-						"ip_address": {
-							Type:         schema.TypeString,
-							Optional:     true,
-							Default:      "",
-							ValidateFunc: validation.IsCIDR,
-						},
-					},
-				},
-			},
-			"system_identifier": {
-				Type:         schema.TypeString,
-				Optional:     true,
-				ValidateFunc: validation.IsMACAddress,
-			},
-			"vpls_flush_on_topology_change": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-		},
-	}
-}
-
-func resourceRstpCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeCreateSetFile() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := setRstp(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.SetId(d.Get("routing_instance").(string))
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(d.Get("routing_instance").(string), junSess)
-		if err != nil {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns, diag.FromErr(err)...)
-		}
-		if !instanceExists {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns,
-				diag.FromErr(fmt.Errorf("routing instance %v doesn't exist", d.Get("routing_instance").(string)))...)
-		}
-	}
-	if err := setRstp(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "create resource junos_rstp")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.SetId(d.Get("routing_instance").(string))
-
-	return append(diagWarns, resourceRstpReadWJunSess(d, junSess)...)
-}
-
-func resourceRstpRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-
-	return resourceRstpReadWJunSess(d, junSess)
-}
-
-func resourceRstpReadWJunSess(d *schema.ResourceData, junSess *junos.Session) diag.Diagnostics {
-	junos.MutexLock()
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(d.Get("routing_instance").(string), junSess)
-		if err != nil {
-			junos.MutexUnlock()
-
-			return diag.FromErr(err)
-		}
-		if !instanceExists {
-			junos.MutexUnlock()
-			d.SetId("")
-
-			return nil
-		}
-	}
-	rstpOptions, err := readRstp(d.Get("routing_instance").(string), junSess)
-	junos.MutexUnlock()
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	fillRstpData(d, rstpOptions)
-
-	return nil
-}
-
-func resourceRstpUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	d.Partial(true)
-	clt := m.(*junos.Client)
-	if clt.FakeUpdateAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delRstp(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		if err := setRstp(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.Partial(false)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delRstp(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if err := setRstp(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "update resource junos_rstp")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.Partial(false)
-
-	return append(diagWarns, resourceRstpReadWJunSess(d, junSess)...)
-}
-
-func resourceRstpDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeDeleteAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delRstp(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delRstp(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "delete resource junos_rstp")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-
-	return diagWarns
-}
-
-func resourceRstpImport(ctx context.Context, d *schema.ResourceData, m interface{},
-) ([]*schema.ResourceData, error) {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return nil, err
-	}
-	defer junSess.Close()
-	if d.Id() != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(d.Id(), junSess)
-		if err != nil {
-			return nil, err
-		}
-		if !instanceExists {
-			return nil, fmt.Errorf("routing instance %v doesn't exist", d.Id())
-		}
-	}
-	result := make([]*schema.ResourceData, 1)
-	rstpOptions, err := readRstp(d.Id(), junSess)
-	if err != nil {
-		return nil, err
-	}
-	fillRstpData(d, rstpOptions)
-	result[0] = d
-
-	return result, nil
-}
-
-func setRstp(d *schema.ResourceData, junSess *junos.Session) error {
-	configSet := make([]string, 0)
-	setPrefix := junos.SetLS
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + d.Get("routing_instance").(string) + " "
-	}
-	setPrefix += "protocols rstp "
-
-	if v := d.Get("backup_bridge_priority").(string); v != "" {
-		configSet = append(configSet, setPrefix+"backup-bridge-priority "+v)
-	}
-	if d.Get("bpdu_block_on_edge").(bool) {
-		configSet = append(configSet, setPrefix+"bpdu-block-on-edge")
-	}
-	if d.Get("bpdu_destination_mac_address_provider_bridge_group").(bool) {
-		configSet = append(configSet, setPrefix+"bpdu-destination-mac-address provider-bridge-group")
-	}
-	if v := d.Get("bridge_priority").(string); v != "" {
-		configSet = append(configSet, setPrefix+"bridge-priority "+v)
-	}
-	if d.Get("disable").(bool) {
-		configSet = append(configSet, setPrefix+"disable")
-	}
-	if v := d.Get("extended_system_id").(int); v != -1 {
-		configSet = append(configSet, setPrefix+"extended-system-id "+strconv.Itoa(v))
-	}
-	if d.Get("force_version_stp").(bool) {
-		configSet = append(configSet, setPrefix+"force-version stp")
-	}
-	if v := d.Get("forward_delay").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"forward-delay "+strconv.Itoa(v))
-	}
-	if v := d.Get("hello_time").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"hello-time "+strconv.Itoa(v))
-	}
-	if v := d.Get("max_age").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"max-age "+strconv.Itoa(v))
-	}
-	if v := d.Get("priority_hold_time").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"priority-hold-time "+strconv.Itoa(v))
-	}
-	systemIDList := make([]string, 0)
-	for _, mSysID := range d.Get("system_id").(*schema.Set).List() {
-		systemID := mSysID.(map[string]interface{})
-		if slices.Contains(systemIDList, systemID["id"].(string)) {
-			return fmt.Errorf("multiple blocks system_id with the same id '%s'", systemID["id"].(string))
-		}
-		systemIDList = append(systemIDList, systemID["id"].(string))
-		configSet = append(configSet, setPrefix+"system-id "+systemID["id"].(string))
-		if ipAdd := systemID["ip_address"].(string); ipAdd != "" {
-			configSet = append(configSet, setPrefix+"system-id "+systemID["id"].(string)+" ip-address "+ipAdd)
-		}
-	}
-	if v := d.Get("system_identifier").(string); v != "" {
-		configSet = append(configSet, setPrefix+"system-identifier "+v)
-	}
-	if d.Get("vpls_flush_on_topology_change").(bool) {
-		configSet = append(configSet, setPrefix+"vpls-flush-on-topology-change")
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func readRstp(routingInstance string, junSess *junos.Session,
-) (confRead rstpOptions, err error) {
-	// default -1
-	confRead.extendedSystemID = -1
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols rstp" + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return confRead, err
-		}
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols rstp" + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return confRead, err
-		}
-	}
-
-	confRead.routingInstance = routingInstance
-	if showConfig != junos.EmptyW {
-		for _, item := range strings.Split(showConfig, "\n") {
-			if strings.Contains(item, junos.XMLStartTagConfigOut) {
-				continue
-			}
-			if strings.Contains(item, junos.XMLEndTagConfigOut) {
-				break
-			}
-			itemTrim := strings.TrimPrefix(item, junos.SetLS)
-			switch {
-			case balt.CutPrefixInString(&itemTrim, "backup-bridge-priority "):
-				confRead.backupBridgePriority = itemTrim
-			case itemTrim == "bpdu-block-on-edge":
-				confRead.bpduBlockOnEdge = true
-			case itemTrim == "bpdu-destination-mac-address provider-bridge-group":
-				confRead.bpduDestMACAddProvBridgeGrp = true
-			case balt.CutPrefixInString(&itemTrim, "bridge-priority "):
-				confRead.bridgePriority = itemTrim
-			case itemTrim == junos.DisableW:
-				confRead.disable = true
-			case balt.CutPrefixInString(&itemTrim, "extended-system-id "):
-				confRead.extendedSystemID, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case itemTrim == "force-version stp":
-				confRead.forceVersionStp = true
-			case balt.CutPrefixInString(&itemTrim, "forward-delay "):
-				confRead.forwardDelay, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "hello-time "):
-				confRead.helloTime, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "max-age "):
-				confRead.maxAge, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "priority-hold-time "):
-				confRead.priorityHoldTime, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "system-id "):
-				itemTrimFields := strings.Split(itemTrim, " ")
-				switch len(itemTrimFields) { // <id> (ip-address <ip_address>)?
-				case 1:
-					confRead.systemID = append(confRead.systemID, map[string]interface{}{
-						"id":         itemTrimFields[0],
-						"ip_address": "",
-					})
-				case 3:
-					confRead.systemID = append(confRead.systemID, map[string]interface{}{
-						"id":         itemTrimFields[0],
-						"ip_address": itemTrimFields[2],
-					})
-				default:
-					return confRead, fmt.Errorf(junos.CantReadValuesNotEnoughFields, "system-id", itemTrim)
-				}
-			case balt.CutPrefixInString(&itemTrim, "system-identifier "):
-				confRead.systemIdentifier = itemTrim
-			case itemTrim == "vpls-flush-on-topology-change":
-				confRead.vplsFlushOnTopologyChange = true
-			}
-		}
-	}
-
-	return confRead, nil
-}
-
-func delRstp(d *schema.ResourceData, junSess *junos.Session) error {
-	delPrefix := junos.DeleteLS
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + d.Get("routing_instance").(string) + " "
-	}
-	delPrefix += "protocols rstp "
-
-	listLinesToDelete := []string{
-		"backup-bridge-priority",
-		"bpdu-block-on-edge",
-		"bpdu-destination-mac-address",
-		"bridge-priority",
-		"disable",
-		"extended-system-id",
-		"force-version",
-		"forward-delay",
-		"hello-time",
-		"max-age",
-		"priority-hold-time",
-		"system-identifier",
-		"vpls-flush-on-topology-change",
-	}
-	configSet := make([]string,
-		len(listLinesToDelete), len(listLinesToDelete)+len(d.Get("system_id").(*schema.Set).List()))
-	for k, line := range listLinesToDelete {
-		configSet[k] = delPrefix + line
-	}
-	if d.HasChange("system_id") {
-		oSysID, _ := d.GetChange("system_id")
-		for _, mSysID := range oSysID.(*schema.Set).List() {
-			systemID := mSysID.(map[string]interface{})
-			configSet = append(configSet, delPrefix+"system-id "+systemID["id"].(string))
-		}
-	} else {
-		for _, mSysID := range d.Get("system_id").(*schema.Set).List() {
-			systemID := mSysID.(map[string]interface{})
-			configSet = append(configSet, delPrefix+"system-id "+systemID["id"].(string))
-		}
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func fillRstpData(d *schema.ResourceData, rstpOptions rstpOptions) {
-	if tfErr := d.Set("routing_instance", rstpOptions.routingInstance); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("backup_bridge_priority", rstpOptions.backupBridgePriority); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bpdu_block_on_edge", rstpOptions.bpduBlockOnEdge); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set(
-		"bpdu_destination_mac_address_provider_bridge_group",
-		rstpOptions.bpduDestMACAddProvBridgeGrp,
-	); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bridge_priority", rstpOptions.bridgePriority); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("disable", rstpOptions.disable); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("extended_system_id", rstpOptions.extendedSystemID); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("force_version_stp", rstpOptions.forceVersionStp); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("forward_delay", rstpOptions.forwardDelay); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("hello_time", rstpOptions.helloTime); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("max_age", rstpOptions.maxAge); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("priority_hold_time", rstpOptions.priorityHoldTime); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("system_id", rstpOptions.systemID); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("system_identifier", rstpOptions.systemIdentifier); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("vpls_flush_on_topology_change", rstpOptions.vplsFlushOnTopologyChange); tfErr != nil {
-		panic(tfErr)
-	}
-}
diff --git a/internal/providersdk/resource_rstp_interface.go b/internal/providersdk/resource_rstp_interface.go
deleted file mode 100644
index 2c5bdcf7..00000000
--- a/internal/providersdk/resource_rstp_interface.go
+++ /dev/null
@@ -1,495 +0,0 @@
-package providersdk
-
-import (
-	"context"
-	"fmt"
-	"strconv"
-	"strings"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
-	balt "github.com/jeremmfr/go-utils/basicalter"
-)
-
-type rstpInterfaceOptions struct {
-	accessTrunk            bool
-	bpduTimeoutActionAlarm bool
-	bpduTimeoutActionBlock bool
-	edge                   bool
-	noRootPort             bool
-	cost                   int
-	priority               int
-	mode                   string
-	name                   string
-	routingInstance        string
-}
-
-func resourceRstpInterface() *schema.Resource {
-	return &schema.Resource{
-		CreateWithoutTimeout: resourceRstpInterfaceCreate,
-		ReadWithoutTimeout:   resourceRstpInterfaceRead,
-		UpdateWithoutTimeout: resourceRstpInterfaceUpdate,
-		DeleteWithoutTimeout: resourceRstpInterfaceDelete,
-		Importer: &schema.ResourceImporter{
-			StateContext: resourceRstpInterfaceImport,
-		},
-		Schema: map[string]*schema.Schema{
-			"name": {
-				Type:     schema.TypeString,
-				Required: true,
-				ForceNew: true,
-				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
-					value := v.(string)
-					if strings.Count(value, ".") > 0 {
-						errors = append(errors, fmt.Errorf(
-							"%q in %q cannot have a dot", value, k))
-					}
-
-					return
-				},
-			},
-			"routing_instance": {
-				Type:             schema.TypeString,
-				Optional:         true,
-				ForceNew:         true,
-				Default:          junos.DefaultW,
-				ValidateDiagFunc: validateNameObjectJunos([]string{}, 64, formatDefault),
-			},
-			"access_trunk": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"bpdu_timeout_action_alarm": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"bpdu_timeout_action_block": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"cost": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(1, 200000000),
-			},
-			"edge": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"mode": {
-				Type:         schema.TypeString,
-				Optional:     true,
-				ValidateFunc: validation.StringInSlice([]string{"point-to-point", "shared"}, false),
-			},
-			"no_root_port": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"priority": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				Default:      -1,
-				ValidateFunc: validation.IntBetween(0, 240),
-			},
-		},
-	}
-}
-
-func resourceRstpInterfaceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeCreateSetFile() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := setRstpInterface(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.SetId(d.Get("name").(string) + junos.IDSeparator + d.Get("routing_instance").(string))
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(d.Get("routing_instance").(string), junSess)
-		if err != nil {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns, diag.FromErr(err)...)
-		}
-		if !instanceExists {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns,
-				diag.FromErr(fmt.Errorf("routing instance %v doesn't exist", d.Get("routing_instance").(string)))...)
-		}
-	}
-	rstpInterfaceExists, err := checkRstpInterfaceExists(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		junSess,
-	)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if rstpInterfaceExists {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-		if d.Get("routing_instance").(string) == junos.DefaultW {
-			return append(diagWarns, diag.FromErr(fmt.Errorf("protocols rstp interface %v already exists",
-				d.Get("name").(string)))...)
-		}
-
-		return append(diagWarns, diag.FromErr(fmt.Errorf(
-			"protocols rstp interface %v already exists in routing-instance %v",
-			d.Get("name").(string), d.Get("routing_instance").(string)))...)
-	}
-
-	if err := setRstpInterface(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "create resource junos_rstp_interface")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	rstpInterfaceExists, err = checkRstpInterfaceExists(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		junSess,
-	)
-	if err != nil {
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if rstpInterfaceExists {
-		d.SetId(d.Get("name").(string) + junos.IDSeparator + d.Get("routing_instance").(string))
-	} else {
-		if d.Get("routing_instance").(string) == junos.DefaultW {
-			return append(diagWarns, diag.FromErr(fmt.Errorf("protocols rstp interface %v not exists after commit "+
-				"=> check your config", d.Get("name").(string)))...)
-		}
-
-		return append(diagWarns, diag.FromErr(fmt.Errorf(
-			"protocols rstp interface %v not exists in routing-instance %v after commit "+
-				"=> check your config", d.Get("name").(string), d.Get("routing_instance").(string)))...)
-	}
-
-	return append(diagWarns, resourceRstpInterfaceReadWJunSess(d, junSess)...)
-}
-
-func resourceRstpInterfaceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-
-	return resourceRstpInterfaceReadWJunSess(d, junSess)
-}
-
-func resourceRstpInterfaceReadWJunSess(d *schema.ResourceData, junSess *junos.Session,
-) diag.Diagnostics {
-	junos.MutexLock()
-	rstpInterfaceOptions, err := readRstpInterface(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		junSess,
-	)
-	junos.MutexUnlock()
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	if rstpInterfaceOptions.name == "" {
-		d.SetId("")
-	} else {
-		fillRstpInterfaceData(d, rstpInterfaceOptions)
-	}
-
-	return nil
-}
-
-func resourceRstpInterfaceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	d.Partial(true)
-	clt := m.(*junos.Client)
-	if clt.FakeUpdateAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delRstpInterface(d.Get("name").(string), d.Get("routing_instance").(string), junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		if err := setRstpInterface(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.Partial(false)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delRstpInterface(d.Get("name").(string), d.Get("routing_instance").(string), junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if err := setRstpInterface(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "update resource junos_rstp_interface")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.Partial(false)
-
-	return append(diagWarns, resourceRstpInterfaceReadWJunSess(d, junSess)...)
-}
-
-func resourceRstpInterfaceDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeDeleteAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delRstpInterface(d.Get("name").(string), d.Get("routing_instance").(string), junSess); err != nil {
-			return diag.FromErr(err)
-		}
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delRstpInterface(d.Get("name").(string), d.Get("routing_instance").(string), junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "delete resource junos_rstp_interface")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-
-	return diagWarns
-}
-
-func resourceRstpInterfaceImport(ctx context.Context, d *schema.ResourceData, m interface{},
-) ([]*schema.ResourceData, error) {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return nil, err
-	}
-	defer junSess.Close()
-	result := make([]*schema.ResourceData, 1)
-	idSplit := strings.Split(d.Id(), junos.IDSeparator)
-	if len(idSplit) < 2 {
-		return nil, fmt.Errorf("missing element(s) in id with separator %v", junos.IDSeparator)
-	}
-	rstpInterfaceExists, err := checkRstpInterfaceExists(idSplit[0], idSplit[1], junSess)
-	if err != nil {
-		return nil, err
-	}
-	if !rstpInterfaceExists {
-		return nil, fmt.Errorf("don't find protocols rstp interface with id '%v' "+
-			"(id must be <name>"+junos.IDSeparator+"<routing_instance>)", d.Id())
-	}
-	rstpInterfaceOptions, err := readRstpInterface(idSplit[0], idSplit[1], junSess)
-	if err != nil {
-		return nil, err
-	}
-	fillRstpInterfaceData(d, rstpInterfaceOptions)
-
-	result[0] = d
-
-	return result, nil
-}
-
-func checkRstpInterfaceExists(name, routingInstance string, junSess *junos.Session,
-) (_ bool, err error) {
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols rstp interface " + name + junos.PipeDisplaySet)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols rstp interface " + name + junos.PipeDisplaySet)
-	}
-	if err != nil {
-		return false, err
-	}
-	if showConfig == junos.EmptyW {
-		return false, nil
-	}
-
-	return true, nil
-}
-
-func setRstpInterface(d *schema.ResourceData, junSess *junos.Session) error {
-	configSet := make([]string, 0)
-
-	setPrefix := junos.SetLS
-	if rI := d.Get("routing_instance").(string); rI != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + rI + " "
-	}
-	setPrefix += "protocols rstp interface " + d.Get("name").(string) + " "
-
-	configSet = append(configSet, setPrefix)
-	if d.Get("access_trunk").(bool) {
-		configSet = append(configSet, setPrefix+"access-trunk")
-	}
-	if d.Get("bpdu_timeout_action_alarm").(bool) {
-		configSet = append(configSet, setPrefix+"bpdu-timeout-action alarm")
-	}
-	if d.Get("bpdu_timeout_action_block").(bool) {
-		configSet = append(configSet, setPrefix+"bpdu-timeout-action block")
-	}
-	if v := d.Get("cost").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"cost "+strconv.Itoa(v))
-	}
-	if d.Get("edge").(bool) {
-		configSet = append(configSet, setPrefix+"edge")
-	}
-	if v := d.Get("mode").(string); v != "" {
-		configSet = append(configSet, setPrefix+"mode "+v)
-	}
-	if d.Get("no_root_port").(bool) {
-		configSet = append(configSet, setPrefix+"no-root-port")
-	}
-	if v := d.Get("priority").(int); v != -1 {
-		configSet = append(configSet, setPrefix+"priority "+strconv.Itoa(v))
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func readRstpInterface(name, routingInstance string, junSess *junos.Session,
-) (confRead rstpInterfaceOptions, err error) {
-	// default -1
-	confRead.priority = -1
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols rstp interface " + name + junos.PipeDisplaySetRelative)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols rstp interface " + name + junos.PipeDisplaySetRelative)
-	}
-	if err != nil {
-		return confRead, err
-	}
-	if showConfig != junos.EmptyW {
-		confRead.name = name
-		confRead.routingInstance = routingInstance
-		for _, item := range strings.Split(showConfig, "\n") {
-			if strings.Contains(item, junos.XMLStartTagConfigOut) {
-				continue
-			}
-			if strings.Contains(item, junos.XMLEndTagConfigOut) {
-				break
-			}
-			itemTrim := strings.TrimPrefix(item, junos.SetLS)
-			switch {
-			case itemTrim == "access-trunk":
-				confRead.accessTrunk = true
-			case itemTrim == "bpdu-timeout-action alarm":
-				confRead.bpduTimeoutActionAlarm = true
-			case itemTrim == "bpdu-timeout-action block":
-				confRead.bpduTimeoutActionBlock = true
-			case balt.CutPrefixInString(&itemTrim, "cost "):
-				confRead.cost, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case itemTrim == "edge":
-				confRead.edge = true
-			case balt.CutPrefixInString(&itemTrim, "mode "):
-				confRead.mode = itemTrim
-			case itemTrim == "no-root-port":
-				confRead.noRootPort = true
-			case balt.CutPrefixInString(&itemTrim, "priority "):
-				confRead.priority, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			}
-		}
-	}
-
-	return confRead, nil
-}
-
-func delRstpInterface(name, routingInstance string, junSess *junos.Session) error {
-	configSet := make([]string, 0, 1)
-
-	if routingInstance == junos.DefaultW {
-		configSet = append(configSet, "delete protocols rstp interface "+name)
-	} else {
-		configSet = append(configSet, junos.DelRoutingInstances+routingInstance+" protocols rstp interface "+name)
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func fillRstpInterfaceData(d *schema.ResourceData, rstpInterfaceOptions rstpInterfaceOptions) {
-	if tfErr := d.Set("name", rstpInterfaceOptions.name); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("routing_instance", rstpInterfaceOptions.routingInstance); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("access_trunk", rstpInterfaceOptions.accessTrunk); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bpdu_timeout_action_alarm", rstpInterfaceOptions.bpduTimeoutActionAlarm); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bpdu_timeout_action_block", rstpInterfaceOptions.bpduTimeoutActionBlock); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("cost", rstpInterfaceOptions.cost); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("edge", rstpInterfaceOptions.edge); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("mode", rstpInterfaceOptions.mode); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("no_root_port", rstpInterfaceOptions.noRootPort); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("priority", rstpInterfaceOptions.priority); tfErr != nil {
-		panic(tfErr)
-	}
-}
diff --git a/internal/providersdk/resource_rstp_interface_test.go b/internal/providersdk/resource_rstp_interface_test.go
deleted file mode 100644
index 9104db72..00000000
--- a/internal/providersdk/resource_rstp_interface_test.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package providersdk_test
-
-import (
-	"fmt"
-	"os"
-	"testing"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
-)
-
-// export TESTACC_INTERFACE=<inteface> for choose interface available else it's xe-0/0/3.
-func TestAccResourceRstpInterface_basic(t *testing.T) {
-	if os.Getenv("TESTACC_SWITCH") != "" {
-		testaccInterface := junos.DefaultInterfaceSwitchTestAcc
-		if iface := os.Getenv("TESTACC_INTERFACE"); iface != "" {
-			testaccInterface = iface
-		}
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config: testAccResourceRstpInterfaceSWConfigCreate(),
-				},
-				{
-					Config: testAccResourceRstpInterfaceSWConfigUpdate(testaccInterface),
-				},
-				{
-					ResourceName:      "junos_rstp_interface.all",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-				{
-					ResourceName:      "junos_rstp_interface.all2",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-				{
-					ResourceName:      "junos_rstp_interface.testacc_rstp_interface",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	} else {
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config: testAccResourceRstpInterfaceConfigCreate(),
-				},
-				{
-					Config: testAccResourceRstpInterfaceConfigUpdate(),
-				},
-				{
-					ResourceName:      "junos_rstp_interface.all",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	}
-}
-
-func testAccResourceRstpInterfaceSWConfigCreate() string {
-	return `
-resource "junos_rstp_interface" "all" {
-  name = "all"
-}
-
-resource "junos_routing_instance" "testacc_rstp_interface" {
-  name = "testacc_rstp_intface"
-  type = "virtual-switch"
-}
-
-resource "junos_rstp_interface" "all2" {
-  name             = "all"
-  routing_instance = junos_routing_instance.testacc_rstp_interface.name
-}
-`
-}
-
-func testAccResourceRstpInterfaceSWConfigUpdate(interFace string) string {
-	return fmt.Sprintf(`
-resource "junos_rstp_interface" "all" {
-  name                      = "all"
-  access_trunk              = true
-  bpdu_timeout_action_alarm = true
-  bpdu_timeout_action_block = true
-  cost                      = 16
-  edge                      = true
-  mode                      = "shared"
-  priority                  = 240
-}
-
-resource "junos_interface_physical" "testacc_rstp_interface" {
-  name         = "%s"
-  vlan_members = ["default"]
-}
-
-resource "junos_rstp_interface" "testacc_rstp_interface" {
-  name         = junos_interface_physical.testacc_rstp_interface.name
-  no_root_port = true
-}
-
-resource "junos_routing_instance" "testacc_rstp_interface" {
-  name = "testacc_rstp_interface"
-  type = "virtual-switch"
-}
-
-resource "junos_rstp_interface" "all2" {
-  name                      = "all"
-  routing_instance          = junos_routing_instance.testacc_rstp_interface.name
-  access_trunk              = true
-  bpdu_timeout_action_alarm = true
-  bpdu_timeout_action_block = true
-  cost                      = 16
-  edge                      = true
-  mode                      = "shared"
-  priority                  = 240
-}
-`, interFace)
-}
-
-func testAccResourceRstpInterfaceConfigCreate() string {
-	return `
-resource "junos_rstp_interface" "all" {
-  name = "all"
-}
-`
-}
-
-func testAccResourceRstpInterfaceConfigUpdate() string {
-	return `
-resource "junos_rstp_interface" "all" {
-  name                      = "all"
-  access_trunk              = true
-  bpdu_timeout_action_alarm = true
-  bpdu_timeout_action_block = true
-  cost                      = 16
-  edge                      = true
-  mode                      = "shared"
-  priority                  = 240
-}
-`
-}
diff --git a/internal/providersdk/resource_rstp_test.go b/internal/providersdk/resource_rstp_test.go
deleted file mode 100644
index 7235ffea..00000000
--- a/internal/providersdk/resource_rstp_test.go
+++ /dev/null
@@ -1,150 +0,0 @@
-package providersdk_test
-
-import (
-	"os"
-	"testing"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
-)
-
-func TestAccResourceRstp_basic(t *testing.T) {
-	if os.Getenv("TESTACC_SWITCH") != "" {
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config: testAccResourceRstpSWConfigCreate(),
-				},
-				{
-					Config: testAccResourceRstpSWConfigUpdate(),
-				},
-				{
-					ResourceName:      "junos_rstp.testacc_ri_rstp",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	} else {
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config: testAccResourceRstpConfigCreate(),
-				},
-				{
-					Config: testAccResourceRstpConfigUpdate(),
-				},
-				{
-					Config: testAccResourceRstpConfigUpdate2(),
-				},
-				{
-					ResourceName:      "junos_rstp.testacc_rstp",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	}
-}
-
-func testAccResourceRstpSWConfigCreate() string {
-	return `
-resource "junos_rstp" "testacc_rstp" {
-  bpdu_block_on_edge = true
-}
-resource "junos_routing_instance" "testacc_rstp" {
-  name = "testacc_rstp"
-  type = "virtual-switch"
-}
-resource "junos_rstp" "testacc_ri_rstp" {
-  routing_instance = junos_routing_instance.testacc_rstp.name
-  bridge_priority  = 0
-  system_id {
-    id = "00:11:22:33:44:56"
-  }
-}
-`
-}
-
-func testAccResourceRstpSWConfigUpdate() string {
-	return `
-resource "junos_rstp" "testacc_rstp" {
-  bpdu_block_on_edge     = true
-  backup_bridge_priority = "8k"
-  bridge_priority        = 0
-}
-resource "junos_routing_instance" "testacc_rstp" {
-  name = "testacc_rstp"
-  type = "virtual-switch"
-}
-resource "junos_rstp" "testacc_ri_rstp" {
-  routing_instance                                   = junos_routing_instance.testacc_rstp.name
-  backup_bridge_priority                             = "60k"
-  bridge_priority                                    = "4k"
-  bpdu_destination_mac_address_provider_bridge_group = true
-  extended_system_id                                 = 0
-  force_version_stp                                  = true
-  forward_delay                                      = 20
-  hello_time                                         = 5
-  max_age                                            = 22
-  priority_hold_time                                 = 100
-  system_id {
-    id = "00:11:22:33:44:55"
-  }
-  system_id {
-    id         = "00:22:33:44:55:aa"
-    ip_address = "192.0.2.4/31"
-  }
-  system_identifier             = "66:55:44:33:22:11"
-  vpls_flush_on_topology_change = true
-}
-`
-}
-
-func testAccResourceRstpConfigCreate() string {
-	return `
-resource "junos_rstp" "testacc_rstp" {
-  disable = true
-}
-`
-}
-
-func testAccResourceRstpConfigUpdate() string {
-	return `
-resource "junos_rstp" "testacc_rstp" {
-  backup_bridge_priority = "32k"
-  bridge_priority        = "16k"
-  system_id {
-    id = "00:22:33:44:55:aa"
-  }
-}
-`
-}
-
-func testAccResourceRstpConfigUpdate2() string {
-	return `
-resource "junos_rstp" "testacc_rstp" {
-  backup_bridge_priority                             = "60k"
-  bridge_priority                                    = "4k"
-  bpdu_destination_mac_address_provider_bridge_group = true
-  extended_system_id                                 = 0
-  force_version_stp                                  = true
-  forward_delay                                      = 20
-  hello_time                                         = 5
-  max_age                                            = 22
-  priority_hold_time                                 = 100
-  system_id {
-    id = "00:11:22:33:44:55"
-  }
-  system_id {
-    id         = "00:22:33:44:55:66"
-    ip_address = "192.0.2.4/24"
-  }
-  system_identifier             = "66:55:44:33:22:11"
-  vpls_flush_on_topology_change = true
-}
-`
-}
diff --git a/internal/providersdk/resource_security_log_stream.go b/internal/providersdk/resource_security_log_stream.go
deleted file mode 100644
index a0fa87f4..00000000
--- a/internal/providersdk/resource_security_log_stream.go
+++ /dev/null
@@ -1,503 +0,0 @@
-package providersdk
-
-import (
-	"context"
-	"fmt"
-	"strconv"
-	"strings"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
-	balt "github.com/jeremmfr/go-utils/basicalter"
-)
-
-type securityLogStreamOptions struct {
-	filterThreatAttack bool
-	rateLimit          int
-	name               string
-	format             string
-	severity           string
-	category           []string
-	file               []map[string]interface{}
-	host               []map[string]interface{}
-}
-
-func resourceSecurityLogStream() *schema.Resource {
-	return &schema.Resource{
-		CreateWithoutTimeout: resourceSecurityLogStreamCreate,
-		ReadWithoutTimeout:   resourceSecurityLogStreamRead,
-		UpdateWithoutTimeout: resourceSecurityLogStreamUpdate,
-		DeleteWithoutTimeout: resourceSecurityLogStreamDelete,
-		Importer: &schema.ResourceImporter{
-			StateContext: resourceSecurityLogStreamImport,
-		},
-		Schema: map[string]*schema.Schema{
-			"name": {
-				Type:     schema.TypeString,
-				ForceNew: true,
-				Required: true,
-			},
-			"category": {
-				Type:          schema.TypeList,
-				Optional:      true,
-				MinItems:      1,
-				Elem:          &schema.Schema{Type: schema.TypeString},
-				ConflictsWith: []string{"filter_threat_attack"},
-			},
-			"file": {
-				Type:          schema.TypeList,
-				Optional:      true,
-				MaxItems:      1,
-				ConflictsWith: []string{"host"},
-				Elem: &schema.Resource{
-					Schema: map[string]*schema.Schema{
-						"name": {
-							Type:     schema.TypeString,
-							Required: true,
-						},
-						"allow_duplicates": {
-							Type:     schema.TypeBool,
-							Optional: true,
-						},
-						"rotation": {
-							Type:         schema.TypeInt,
-							Optional:     true,
-							ValidateFunc: validation.IntBetween(2, 19),
-						},
-						"size": {
-							Type:         schema.TypeInt,
-							Optional:     true,
-							ValidateFunc: validation.IntBetween(1, 3),
-						},
-					},
-				},
-			},
-			"filter_threat_attack": {
-				Type:          schema.TypeBool,
-				Optional:      true,
-				ConflictsWith: []string{"category"},
-			},
-			"format": {
-				Type:     schema.TypeString,
-				Optional: true,
-				ValidateFunc: validation.StringInSlice([]string{
-					"binary", "sd-syslog", "syslog", "welf",
-				}, false),
-			},
-			"host": {
-				Type:          schema.TypeList,
-				Optional:      true,
-				MaxItems:      1,
-				ConflictsWith: []string{"file"},
-				Elem: &schema.Resource{
-					Schema: map[string]*schema.Schema{
-						"ip_address": {
-							Type:     schema.TypeString,
-							Required: true,
-						},
-						"port": {
-							Type:         schema.TypeInt,
-							Optional:     true,
-							ValidateFunc: validation.IntBetween(1, 65535),
-						},
-						"routing_instance": {
-							Type:             schema.TypeString,
-							Optional:         true,
-							ValidateDiagFunc: validateNameObjectJunos([]string{"default"}, 64, formatDefault),
-						},
-					},
-				},
-			},
-			"rate_limit": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(1, 65535),
-			},
-			"severity": {
-				Type:         schema.TypeString,
-				Optional:     true,
-				ValidateFunc: validation.StringInSlice(junos.SyslogSeverity(), false),
-			},
-		},
-	}
-}
-
-func resourceSecurityLogStreamCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeCreateSetFile() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := setSecurityLogStream(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.SetId(d.Get("name").(string))
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if !junSess.CheckCompatibilitySecurity() {
-		return diag.FromErr(fmt.Errorf("security log stream "+
-			"not compatible with Junos device %s", junSess.SystemInformation.HardwareModel))
-	}
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	securityLogStreamExists, err := checkSecurityLogStreamExists(d.Get("name").(string), junSess)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if securityLogStreamExists {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(fmt.Errorf("security log stream %v already exists", d.Get("name").(string)))...)
-	}
-
-	if err := setSecurityLogStream(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "create resource junos_security_log_stream")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	securityLogStreamExists, err = checkSecurityLogStreamExists(d.Get("name").(string), junSess)
-	if err != nil {
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if securityLogStreamExists {
-		d.SetId(d.Get("name").(string))
-	} else {
-		return append(diagWarns, diag.FromErr(fmt.Errorf("security log stream %v "+
-			"not exists after commit => check your config", d.Get("name").(string)))...)
-	}
-
-	return append(diagWarns, resourceSecurityLogStreamReadWJunSess(d, junSess)...)
-}
-
-func resourceSecurityLogStreamRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-
-	return resourceSecurityLogStreamReadWJunSess(d, junSess)
-}
-
-func resourceSecurityLogStreamReadWJunSess(d *schema.ResourceData, junSess *junos.Session,
-) diag.Diagnostics {
-	junos.MutexLock()
-	securityLogStreamOptions, err := readSecurityLogStream(d.Get("name").(string), junSess)
-	junos.MutexUnlock()
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	if securityLogStreamOptions.name == "" {
-		d.SetId("")
-	} else {
-		fillSecurityLogStreamData(d, securityLogStreamOptions)
-	}
-
-	return nil
-}
-
-func resourceSecurityLogStreamUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	d.Partial(true)
-	clt := m.(*junos.Client)
-	if clt.FakeUpdateAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delLogStream(d.Get("name").(string), junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		if err := setSecurityLogStream(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.Partial(false)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delLogStream(d.Get("name").(string), junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if err := setSecurityLogStream(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "update resource junos_security_log_stream")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.Partial(false)
-
-	return append(diagWarns, resourceSecurityLogStreamReadWJunSess(d, junSess)...)
-}
-
-func resourceSecurityLogStreamDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeDeleteAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delLogStream(d.Get("name").(string), junSess); err != nil {
-			return diag.FromErr(err)
-		}
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delLogStream(d.Get("name").(string), junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "delete resource junos_security_log_stream")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-
-	return diagWarns
-}
-
-func resourceSecurityLogStreamImport(ctx context.Context, d *schema.ResourceData, m interface{},
-) ([]*schema.ResourceData, error) {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return nil, err
-	}
-	defer junSess.Close()
-	result := make([]*schema.ResourceData, 1)
-	securityLogStreamExists, err := checkSecurityLogStreamExists(d.Id(), junSess)
-	if err != nil {
-		return nil, err
-	}
-	if !securityLogStreamExists {
-		return nil, fmt.Errorf("don't find security log stream with id '%v' (id must be <name>)", d.Id())
-	}
-	securityLogStreamOptions, err := readSecurityLogStream(d.Id(), junSess)
-	if err != nil {
-		return nil, err
-	}
-	fillSecurityLogStreamData(d, securityLogStreamOptions)
-
-	result[0] = d
-
-	return result, nil
-}
-
-func checkSecurityLogStreamExists(securityLogStream string, junSess *junos.Session) (bool, error) {
-	showConfig, err := junSess.Command(junos.CmdShowConfig +
-		"security log stream \"" + securityLogStream + "\"" + junos.PipeDisplaySet)
-	if err != nil {
-		return false, err
-	}
-	if showConfig == junos.EmptyW {
-		return false, nil
-	}
-
-	return true, nil
-}
-
-func setSecurityLogStream(d *schema.ResourceData, junSess *junos.Session) error {
-	configSet := make([]string, 0)
-
-	setPrefix := "set security log stream \"" + d.Get("name").(string) + "\" "
-	for _, v := range d.Get("category").([]interface{}) {
-		configSet = append(configSet, setPrefix+"category "+v.(string))
-	}
-	for _, v := range d.Get("file").([]interface{}) {
-		file := v.(map[string]interface{})
-		configSet = append(configSet, setPrefix+"file name "+file["name"].(string))
-		if file["allow_duplicates"].(bool) {
-			configSet = append(configSet, setPrefix+"file allow-duplicates")
-		}
-		if file["rotation"].(int) != 0 {
-			configSet = append(configSet, setPrefix+"file rotation "+strconv.Itoa(file["rotation"].(int)))
-		}
-		if file["size"].(int) != 0 {
-			configSet = append(configSet, setPrefix+"file size "+strconv.Itoa(file["size"].(int)))
-		}
-	}
-	if d.Get("filter_threat_attack").(bool) {
-		configSet = append(configSet, setPrefix+"filter threat-attack")
-	}
-	if d.Get("format").(string) != "" {
-		configSet = append(configSet, setPrefix+"format "+d.Get("format").(string))
-	}
-	for _, v := range d.Get("host").([]interface{}) {
-		host := v.(map[string]interface{})
-		configSet = append(configSet, setPrefix+"host "+host["ip_address"].(string))
-		if host["port"].(int) != 0 {
-			configSet = append(configSet, setPrefix+"host port "+strconv.Itoa(
-				host["port"].(int)))
-		}
-		if host["routing_instance"].(string) != "" {
-			configSet = append(configSet, setPrefix+"host routing-instance "+
-				host["routing_instance"].(string))
-		}
-	}
-	if d.Get("rate_limit").(int) != 0 {
-		configSet = append(configSet, setPrefix+"rate-limit "+
-			strconv.Itoa(d.Get("rate_limit").(int)))
-	}
-	if d.Get("severity").(string) != "" {
-		configSet = append(configSet, setPrefix+"severity "+
-			d.Get("severity").(string))
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func readSecurityLogStream(securityLogStream string, junSess *junos.Session,
-) (confRead securityLogStreamOptions, err error) {
-	showConfig, err := junSess.Command(junos.CmdShowConfig +
-		"security log stream \"" + securityLogStream + "\"" + junos.PipeDisplaySetRelative)
-	if err != nil {
-		return confRead, err
-	}
-	if showConfig != junos.EmptyW {
-		confRead.name = securityLogStream
-		for _, item := range strings.Split(showConfig, "\n") {
-			if strings.Contains(item, junos.XMLStartTagConfigOut) {
-				continue
-			}
-			if strings.Contains(item, junos.XMLEndTagConfigOut) {
-				break
-			}
-			itemTrim := strings.TrimPrefix(item, junos.SetLS)
-			switch {
-			case balt.CutPrefixInString(&itemTrim, "category "):
-				confRead.category = append(confRead.category, itemTrim)
-			case balt.CutPrefixInString(&itemTrim, "file "):
-				if len(confRead.file) == 0 {
-					confRead.file = append(confRead.file, map[string]interface{}{
-						"name":             "",
-						"allow_duplicates": false,
-						"rotation":         0,
-						"size":             0,
-					})
-				}
-				switch {
-				case balt.CutPrefixInString(&itemTrim, "name "):
-					confRead.file[0]["name"] = itemTrim
-				case itemTrim == "allow-duplicates":
-					confRead.file[0]["allow_duplicates"] = true
-				case balt.CutPrefixInString(&itemTrim, "rotation "):
-					confRead.file[0]["rotation"], err = strconv.Atoi(itemTrim)
-					if err != nil {
-						return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-					}
-				case balt.CutPrefixInString(&itemTrim, "size "):
-					confRead.file[0]["size"], err = strconv.Atoi(itemTrim)
-					if err != nil {
-						return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-					}
-				}
-			case itemTrim == "filter threat-attack":
-				confRead.filterThreatAttack = true
-			case balt.CutPrefixInString(&itemTrim, "format "):
-				confRead.format = itemTrim
-			case balt.CutPrefixInString(&itemTrim, "host "):
-				if len(confRead.host) == 0 {
-					confRead.host = append(confRead.host, map[string]interface{}{
-						"ip_address":       "",
-						"port":             0,
-						"routing_instance": "",
-					})
-				}
-				switch {
-				case balt.CutPrefixInString(&itemTrim, "port "):
-					confRead.host[0]["port"], err = strconv.Atoi(itemTrim)
-					if err != nil {
-						return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-					}
-				case balt.CutPrefixInString(&itemTrim, "routing-instance "):
-					confRead.host[0]["routing_instance"] = itemTrim
-				default:
-					confRead.host[0]["ip_address"] = itemTrim
-				}
-			case balt.CutPrefixInString(&itemTrim, "rate-limit "):
-				confRead.rateLimit, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "severity "):
-				confRead.severity = itemTrim
-			}
-		}
-	}
-
-	return confRead, nil
-}
-
-func delLogStream(securityLogStream string, junSess *junos.Session) error {
-	configSet := make([]string, 0, 1)
-	configSet = append(configSet, "delete security log stream \""+securityLogStream+"\"")
-
-	return junSess.ConfigSet(configSet)
-}
-
-func fillSecurityLogStreamData(d *schema.ResourceData, securityLogStreamOptions securityLogStreamOptions) {
-	if tfErr := d.Set("name", securityLogStreamOptions.name); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("category", securityLogStreamOptions.category); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("file", securityLogStreamOptions.file); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("filter_threat_attack", securityLogStreamOptions.filterThreatAttack); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("format", securityLogStreamOptions.format); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("host", securityLogStreamOptions.host); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("rate_limit", securityLogStreamOptions.rateLimit); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("severity", securityLogStreamOptions.severity); tfErr != nil {
-		panic(tfErr)
-	}
-}
diff --git a/internal/providersdk/resource_security_log_stream_test.go b/internal/providersdk/resource_security_log_stream_test.go
deleted file mode 100644
index 463da0db..00000000
--- a/internal/providersdk/resource_security_log_stream_test.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package providersdk_test
-
-import (
-	"os"
-	"testing"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
-)
-
-func TestAccResourceSecurityLogStream_basic(t *testing.T) {
-	if os.Getenv("TESTACC_SRX") != "" {
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config:             testAccResourceSecurityLogStreamConfigPreCreate(),
-					ExpectNonEmptyPlan: true,
-				},
-				{
-					Config: testAccResourceSecurityLogStreamConfigCreate(),
-					Check: resource.ComposeTestCheckFunc(
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"category.#", "1"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"category.0", "idp"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"format", "syslog"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"host.#", "1"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"host.0.ip_address", "192.0.2.1"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"host.0.port", "514"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"host.0.routing_instance", "testacclogstream"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"rate_limit", "50"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"severity", "error"),
-					),
-				},
-				{
-					Config: testAccResourceSecurityLogStreamConfigUpdate(),
-					Check: resource.ComposeTestCheckFunc(
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"file.#", "1"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"file.0.name", "test"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"file.0.allow_duplicates", "true"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"file.0.size", "3"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"file.0.rotation", "3"),
-						resource.TestCheckResourceAttr("junos_security_log_stream.testacc_logstream",
-							"filter_threat_attack", "true"),
-					),
-				},
-				{
-					ResourceName:      "junos_security_log_stream.testacc_logstream",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	}
-}
-
-func testAccResourceSecurityLogStreamConfigPreCreate() string {
-	return `
-resource "junos_security" "security" {
-  log {
-    source_address = "192.0.2.2"
-  }
-}
-`
-}
-
-func testAccResourceSecurityLogStreamConfigCreate() string {
-	return `
-resource "junos_routing_instance" "testacc_logstream" {
-  lifecycle {
-    create_before_destroy = true
-  }
-  name = "testacclogstream"
-}
-resource "junos_security_log_stream" "testacc_logstream" {
-  name     = "testacc_logstream"
-  category = ["idp"]
-  format   = "syslog"
-  host {
-    ip_address       = "192.0.2.1"
-    port             = 514
-    routing_instance = junos_routing_instance.testacc_logstream.name
-  }
-  rate_limit = 50
-  severity   = "error"
-}
-`
-}
-
-func testAccResourceSecurityLogStreamConfigUpdate() string {
-	return `
-resource "junos_security_log_stream" "testacc_logstream" {
-  name = "testacc_logstream"
-  file {
-    name             = "test"
-    allow_duplicates = true
-    size             = 3
-    rotation         = 3
-  }
-  filter_threat_attack = true
-}
-`
-}
diff --git a/internal/providersdk/resource_system_services_dhcp_localserver_group.go b/internal/providersdk/resource_system_services_dhcp_localserver_group.go
index 2a0fdd3b..7e46ac6e 100644
--- a/internal/providersdk/resource_system_services_dhcp_localserver_group.go
+++ b/internal/providersdk/resource_system_services_dhcp_localserver_group.go
@@ -1072,7 +1072,7 @@ func setSystemServicesDhcpLocalServerGroup(d *schema.ResourceData, junSess *juno
 
 	setPrefix := junos.SetLS
 	if d.Get("routing_instance").(string) != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + d.Get("routing_instance").(string) + " "
+		setPrefix = setRoutingInstances + d.Get("routing_instance").(string) + " "
 	}
 	if d.Get("version").(string) == "v6" {
 		setPrefix += "system services dhcp-local-server dhcpv6 group " + d.Get("name").(string) + " "
@@ -2090,10 +2090,10 @@ func delSystemServicesDhcpLocalServerGroup(name, instance, version string, junSe
 	case instance == junos.DefaultW && version == "v4":
 		configSet = append(configSet, "delete system services dhcp-local-server group "+name)
 	case instance != junos.DefaultW && version == "v6":
-		configSet = append(configSet, junos.DelRoutingInstances+instance+" "+
+		configSet = append(configSet, delRoutingInstances+instance+" "+
 			"system services dhcp-local-server dhcpv6 group "+name)
 	case instance != junos.DefaultW && version == "v4":
-		configSet = append(configSet, junos.DelRoutingInstances+instance+" "+
+		configSet = append(configSet, delRoutingInstances+instance+" "+
 			"system services dhcp-local-server group "+name)
 	}
 
diff --git a/internal/providersdk/resource_vstp.go b/internal/providersdk/resource_vstp.go
deleted file mode 100644
index 55983d6f..00000000
--- a/internal/providersdk/resource_vstp.go
+++ /dev/null
@@ -1,445 +0,0 @@
-package providersdk
-
-import (
-	"context"
-	"fmt"
-	"slices"
-	"strconv"
-	"strings"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
-	balt "github.com/jeremmfr/go-utils/basicalter"
-)
-
-type vstpOptions struct {
-	bpduBlockOnEdge           bool
-	disable                   bool
-	forceVersionStp           bool
-	vplsFlushOnTopologyChange bool
-	priorityHoldTime          int
-	routingInstance           string
-	systemID                  []map[string]interface{}
-}
-
-func resourceVstp() *schema.Resource {
-	return &schema.Resource{
-		CreateWithoutTimeout: resourceVstpCreate,
-		ReadWithoutTimeout:   resourceVstpRead,
-		UpdateWithoutTimeout: resourceVstpUpdate,
-		DeleteWithoutTimeout: resourceVstpDelete,
-		Importer: &schema.ResourceImporter{
-			StateContext: resourceVstpImport,
-		},
-		Schema: map[string]*schema.Schema{
-			"routing_instance": {
-				Type:             schema.TypeString,
-				Optional:         true,
-				ForceNew:         true,
-				Default:          junos.DefaultW,
-				ValidateDiagFunc: validateNameObjectJunos([]string{}, 64, formatDefault),
-			},
-			"bpdu_block_on_edge": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"disable": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"force_version_stp": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"priority_hold_time": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(1, 255),
-			},
-			"system_id": {
-				Type:     schema.TypeSet,
-				Optional: true,
-				Elem: &schema.Resource{
-					Schema: map[string]*schema.Schema{
-						"id": {
-							Type:         schema.TypeString,
-							Required:     true,
-							ValidateFunc: validation.IsMACAddress,
-						},
-						"ip_address": {
-							Type:         schema.TypeString,
-							Optional:     true,
-							Default:      "",
-							ValidateFunc: validation.IsCIDR,
-						},
-					},
-				},
-			},
-			"vpls_flush_on_topology_change": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-		},
-	}
-}
-
-func resourceVstpCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeCreateSetFile() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := setVstp(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.SetId(d.Get("routing_instance").(string))
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(d.Get("routing_instance").(string), junSess)
-		if err != nil {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns, diag.FromErr(err)...)
-		}
-		if !instanceExists {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns,
-				diag.FromErr(fmt.Errorf("routing instance %v doesn't exist", d.Get("routing_instance").(string)))...)
-		}
-	}
-	if err := setVstp(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "create resource junos_vstp")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.SetId(d.Get("routing_instance").(string))
-
-	return append(diagWarns, resourceVstpReadWJunSess(d, junSess)...)
-}
-
-func resourceVstpRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-
-	return resourceVstpReadWJunSess(d, junSess)
-}
-
-func resourceVstpReadWJunSess(d *schema.ResourceData, junSess *junos.Session) diag.Diagnostics {
-	junos.MutexLock()
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(d.Get("routing_instance").(string), junSess)
-		if err != nil {
-			junos.MutexUnlock()
-
-			return diag.FromErr(err)
-		}
-		if !instanceExists {
-			junos.MutexUnlock()
-			d.SetId("")
-
-			return nil
-		}
-	}
-	vstpOptions, err := readVstp(d.Get("routing_instance").(string), junSess)
-	junos.MutexUnlock()
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	fillVstpData(d, vstpOptions)
-
-	return nil
-}
-
-func resourceVstpUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	d.Partial(true)
-	clt := m.(*junos.Client)
-	if clt.FakeUpdateAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delVstp(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		if err := setVstp(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.Partial(false)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delVstp(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if err := setVstp(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "update resource junos_vstp")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.Partial(false)
-
-	return append(diagWarns, resourceVstpReadWJunSess(d, junSess)...)
-}
-
-func resourceVstpDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeDeleteAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delVstp(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delVstp(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "delete resource junos_vstp")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-
-	return diagWarns
-}
-
-func resourceVstpImport(ctx context.Context, d *schema.ResourceData, m interface{},
-) ([]*schema.ResourceData, error) {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return nil, err
-	}
-	defer junSess.Close()
-	if d.Id() != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(d.Id(), junSess)
-		if err != nil {
-			return nil, err
-		}
-		if !instanceExists {
-			return nil, fmt.Errorf("routing instance %v doesn't exist", d.Id())
-		}
-	}
-	result := make([]*schema.ResourceData, 1)
-	vstpOptions, err := readVstp(d.Id(), junSess)
-	if err != nil {
-		return nil, err
-	}
-	fillVstpData(d, vstpOptions)
-	result[0] = d
-
-	return result, nil
-}
-
-func setVstp(d *schema.ResourceData, junSess *junos.Session) error {
-	configSet := make([]string, 0)
-	setPrefix := junos.SetLS
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + d.Get("routing_instance").(string) + " "
-	}
-	setPrefix += "protocols vstp "
-
-	if d.Get("bpdu_block_on_edge").(bool) {
-		configSet = append(configSet, setPrefix+"bpdu-block-on-edge")
-	}
-	if d.Get("disable").(bool) {
-		configSet = append(configSet, setPrefix+"disable")
-	}
-	if d.Get("force_version_stp").(bool) {
-		configSet = append(configSet, setPrefix+"force-version stp")
-	}
-	if v := d.Get("priority_hold_time").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"priority-hold-time "+strconv.Itoa(v))
-	}
-	systemIDList := make([]string, 0)
-	for _, mSysID := range d.Get("system_id").(*schema.Set).List() {
-		systemID := mSysID.(map[string]interface{})
-		if slices.Contains(systemIDList, systemID["id"].(string)) {
-			return fmt.Errorf("multiple blocks system_id with the same id '%s'", systemID["id"].(string))
-		}
-		systemIDList = append(systemIDList, systemID["id"].(string))
-		configSet = append(configSet, setPrefix+"system-id "+systemID["id"].(string))
-		if ipAdd := systemID["ip_address"].(string); ipAdd != "" {
-			configSet = append(configSet, setPrefix+"system-id "+systemID["id"].(string)+" ip-address "+ipAdd)
-		}
-	}
-	if d.Get("vpls_flush_on_topology_change").(bool) {
-		configSet = append(configSet, setPrefix+"vpls-flush-on-topology-change")
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func readVstp(routingInstance string, junSess *junos.Session,
-) (confRead vstpOptions, err error) {
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols vstp" + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return confRead, err
-		}
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols vstp" + junos.PipeDisplaySetRelative)
-		if err != nil {
-			return confRead, err
-		}
-	}
-	confRead.routingInstance = routingInstance
-	if showConfig != junos.EmptyW {
-		for _, item := range strings.Split(showConfig, "\n") {
-			if strings.Contains(item, junos.XMLStartTagConfigOut) {
-				continue
-			}
-			if strings.Contains(item, junos.XMLEndTagConfigOut) {
-				break
-			}
-			itemTrim := strings.TrimPrefix(item, junos.SetLS)
-			switch {
-			case itemTrim == "bpdu-block-on-edge":
-				confRead.bpduBlockOnEdge = true
-			case itemTrim == junos.DisableW:
-				confRead.disable = true
-			case itemTrim == "force-version stp":
-				confRead.forceVersionStp = true
-			case balt.CutPrefixInString(&itemTrim, "priority-hold-time "):
-				confRead.priorityHoldTime, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "system-id "):
-				itemTrimFields := strings.Split(itemTrim, " ")
-				switch len(itemTrimFields) { // <id> (ip-address <ip_address>)?
-				case 1:
-					confRead.systemID = append(confRead.systemID, map[string]interface{}{
-						"id":         itemTrimFields[0],
-						"ip_address": "",
-					})
-				case 3:
-					confRead.systemID = append(confRead.systemID, map[string]interface{}{
-						"id":         itemTrimFields[0],
-						"ip_address": itemTrimFields[2],
-					})
-				default:
-					return confRead, fmt.Errorf(junos.CantReadValuesNotEnoughFields, "system-id", itemTrim)
-				}
-			case itemTrim == "vpls-flush-on-topology-change":
-				confRead.vplsFlushOnTopologyChange = true
-			}
-		}
-	}
-
-	return confRead, nil
-}
-
-func delVstp(d *schema.ResourceData, junSess *junos.Session) error {
-	delPrefix := junos.DeleteLS
-	if d.Get("routing_instance").(string) != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + d.Get("routing_instance").(string) + " "
-	}
-	delPrefix += "protocols vstp "
-
-	listLinesToDelete := []string{
-		"bpdu-block-on-edge",
-		"disable",
-		"force-version",
-		"priority-hold-time",
-		"vpls-flush-on-topology-change",
-	}
-	configSet := make([]string,
-		len(listLinesToDelete), len(listLinesToDelete)+len(d.Get("system_id").(*schema.Set).List()))
-	for k, line := range listLinesToDelete {
-		configSet[k] = delPrefix + line
-	}
-	if d.HasChange("system_id") {
-		oSysID, _ := d.GetChange("system_id")
-		for _, mSysID := range oSysID.(*schema.Set).List() {
-			systemID := mSysID.(map[string]interface{})
-			configSet = append(configSet, delPrefix+"system-id "+systemID["id"].(string))
-		}
-	} else {
-		for _, mSysID := range d.Get("system_id").(*schema.Set).List() {
-			systemID := mSysID.(map[string]interface{})
-			configSet = append(configSet, delPrefix+"system-id "+systemID["id"].(string))
-		}
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func fillVstpData(d *schema.ResourceData, vstpOptions vstpOptions) {
-	if tfErr := d.Set("routing_instance", vstpOptions.routingInstance); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bpdu_block_on_edge", vstpOptions.bpduBlockOnEdge); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("disable", vstpOptions.disable); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("force_version_stp", vstpOptions.forceVersionStp); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("priority_hold_time", vstpOptions.priorityHoldTime); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("system_id", vstpOptions.systemID); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("vpls_flush_on_topology_change", vstpOptions.vplsFlushOnTopologyChange); tfErr != nil {
-		panic(tfErr)
-	}
-}
diff --git a/internal/providersdk/resource_vstp_interface.go b/internal/providersdk/resource_vstp_interface.go
deleted file mode 100644
index 7aff11f4..00000000
--- a/internal/providersdk/resource_vstp_interface.go
+++ /dev/null
@@ -1,792 +0,0 @@
-package providersdk
-
-import (
-	"context"
-	"errors"
-	"fmt"
-	"regexp"
-	"strconv"
-	"strings"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
-	balt "github.com/jeremmfr/go-utils/basicalter"
-)
-
-type vstpInterfaceOptions struct {
-	accessTrunk            bool
-	bpduTimeoutActionAlarm bool
-	bpduTimeoutActionBlock bool
-	edge                   bool
-	noRootPort             bool
-	cost                   int
-	priority               int
-	mode                   string
-	name                   string
-	routingInstance        string
-	vlan                   string
-	vlanGroup              string
-}
-
-func resourceVstpInterface() *schema.Resource {
-	return &schema.Resource{
-		CreateWithoutTimeout: resourceVstpInterfaceCreate,
-		ReadWithoutTimeout:   resourceVstpInterfaceRead,
-		UpdateWithoutTimeout: resourceVstpInterfaceUpdate,
-		DeleteWithoutTimeout: resourceVstpInterfaceDelete,
-		Importer: &schema.ResourceImporter{
-			StateContext: resourceVstpInterfaceImport,
-		},
-		Schema: map[string]*schema.Schema{
-			"name": {
-				Type:     schema.TypeString,
-				Required: true,
-				ForceNew: true,
-				ValidateFunc: func(v interface{}, k string) (ws []string, errors []error) {
-					value := v.(string)
-					if strings.Count(value, ".") > 0 {
-						errors = append(errors, fmt.Errorf(
-							"%q in %q cannot have a dot", value, k))
-					}
-
-					return
-				},
-			},
-			"routing_instance": {
-				Type:             schema.TypeString,
-				Optional:         true,
-				ForceNew:         true,
-				Default:          junos.DefaultW,
-				ValidateDiagFunc: validateNameObjectJunos([]string{}, 64, formatDefault),
-			},
-			"vlan": {
-				Type:     schema.TypeString,
-				Optional: true,
-				ForceNew: true,
-				ValidateFunc: validation.StringMatch(regexp.MustCompile(
-					`^all|[0-9]{1,4}$`), "must be 'all' or a VLAN id"),
-				ConflictsWith: []string{"vlan_group"},
-			},
-			"vlan_group": {
-				Type:             schema.TypeString,
-				Optional:         true,
-				ForceNew:         true,
-				ValidateDiagFunc: validateNameObjectJunos([]string{}, 64, formatDefault),
-				ConflictsWith:    []string{"vlan"},
-			},
-			"access_trunk": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"bpdu_timeout_action_alarm": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"bpdu_timeout_action_block": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"cost": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(1, 200000000),
-			},
-			"edge": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"mode": {
-				Type:         schema.TypeString,
-				Optional:     true,
-				ValidateFunc: validation.StringInSlice([]string{"point-to-point", "shared"}, false),
-			},
-			"no_root_port": {
-				Type:     schema.TypeBool,
-				Optional: true,
-			},
-			"priority": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				Default:      -1,
-				ValidateFunc: validation.IntBetween(0, 240),
-			},
-		},
-	}
-}
-
-type vstpInterfaceVIdType int
-
-const (
-	vstpInterfaceVIdTypeNone vstpInterfaceVIdType = iota
-	vstpInterfaceVIdTypeVlan
-	vstpInterfaceVIdTypeVlanGroup
-)
-
-func (vType vstpInterfaceVIdType) prefix() string {
-	switch vType {
-	case vstpInterfaceVIdTypeNone:
-		return ""
-	case vstpInterfaceVIdTypeVlan:
-		return "v_"
-	case vstpInterfaceVIdTypeVlanGroup:
-		return "vg_"
-	}
-
-	return ""
-}
-
-func resourceVstpInterfaceNewID(d *schema.ResourceData) string {
-	name := d.Get("name").(string)
-	routingInstance := d.Get("routing_instance").(string)
-	vlan := d.Get("vlan").(string)
-	vlanGroup := d.Get("vlan_group").(string)
-	switch {
-	case vlan != "":
-		return name + junos.IDSeparator +
-			vstpInterfaceVIdTypeVlan.prefix() + vlan + junos.IDSeparator +
-			routingInstance
-	case vlanGroup != "":
-		return name + junos.IDSeparator +
-			vstpInterfaceVIdTypeVlanGroup.prefix() + vlanGroup + junos.IDSeparator +
-			routingInstance
-	default:
-		return name + junos.IDSeparator +
-			vstpInterfaceVIdTypeNone.prefix() + junos.IDSeparator +
-			routingInstance
-	}
-}
-
-func resourceVstpInterfaceReadID(resourceID string) (vType vstpInterfaceVIdType, name, vName, routingInstnace string) {
-	ressIDSplit := strings.Split(resourceID, junos.IDSeparator)
-	switch len(ressIDSplit) {
-	case 1:
-		return vstpInterfaceVIdTypeNone,
-			ressIDSplit[0],
-			"",
-			""
-	case 2:
-		return vstpInterfaceVIdTypeNone,
-			ressIDSplit[0],
-			"",
-			ressIDSplit[1]
-	default:
-		switch {
-		case balt.CutPrefixInString(&ressIDSplit[1], vstpInterfaceVIdTypeVlan.prefix()):
-			return vstpInterfaceVIdTypeVlan,
-				ressIDSplit[0],
-				ressIDSplit[1],
-				ressIDSplit[2]
-		case balt.CutPrefixInString(&ressIDSplit[1], vstpInterfaceVIdTypeVlanGroup.prefix()):
-			return vstpInterfaceVIdTypeVlanGroup,
-				ressIDSplit[0],
-				ressIDSplit[1],
-				ressIDSplit[2]
-		default:
-			return vstpInterfaceVIdTypeNone,
-				ressIDSplit[0],
-				ressIDSplit[1],
-				ressIDSplit[2]
-		}
-	}
-}
-
-func resourceVstpInterfaceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeCreateSetFile() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := setVstpInterface(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.SetId(resourceVstpInterfaceNewID(d))
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	vstpInterfaceVIdType, name, _, routingInstance := resourceVstpInterfaceReadID(resourceVstpInterfaceNewID(d))
-	vlan := d.Get("vlan").(string)
-	vlanGroup := d.Get("vlan_group").(string)
-	if routingInstance != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(routingInstance, junSess)
-		if err != nil {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns, diag.FromErr(err)...)
-		}
-		if !instanceExists {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns,
-				diag.FromErr(fmt.Errorf("routing instance %v doesn't exist", routingInstance))...)
-		}
-	}
-	if vlan != "" {
-		vstpVlanExists, err := checkVstpVlanExists(vlan, routingInstance, junSess)
-		if err != nil {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns, diag.FromErr(err)...)
-		}
-		if !vstpVlanExists {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-			if routingInstance == junos.DefaultW {
-				return append(diagWarns,
-					diag.FromErr(fmt.Errorf("protocol vstp vlan %v doesn't exist", vlan))...)
-			}
-
-			return append(diagWarns,
-				diag.FromErr(fmt.Errorf("protocol vstp vlan %v in routing-instance %v doesn't exist", vlan, routingInstance))...)
-		}
-	}
-	if vlanGroup != "" {
-		vstpVlanGroupExists, err := checkVstpVlanGroupExists(vlanGroup, routingInstance, junSess)
-		if err != nil {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns, diag.FromErr(err)...)
-		}
-		if !vstpVlanGroupExists {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-			if routingInstance == junos.DefaultW {
-				return append(diagWarns,
-					diag.FromErr(fmt.Errorf("protocol vstp vlan-group group %v doesn't exist", vlanGroup))...)
-			}
-
-			return append(diagWarns,
-				diag.FromErr(fmt.Errorf(
-					"protocol vstp vlan-group group %v in routing-instance %v doesn't exist", vlanGroup, routingInstance))...)
-		}
-	}
-	vstpInterfaceExists, err := checkVstpInterfaceExists(name, routingInstance, vlan, vlanGroup, junSess)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if vstpInterfaceExists {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-		switch vstpInterfaceVIdType {
-		case vstpInterfaceVIdTypeNone:
-			if routingInstance == junos.DefaultW {
-				return append(diagWarns, diag.FromErr(fmt.Errorf("protocols vstp interface %v already exists",
-					name))...)
-			}
-
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp interface %v already exists in routing-instance %v", name, routingInstance))...)
-		case vstpInterfaceVIdTypeVlan:
-			if routingInstance == junos.DefaultW {
-				return append(diagWarns, diag.FromErr(fmt.Errorf("protocols vstp interface %v in vlan %v already exists",
-					name, vlan))...)
-			}
-
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp interface %v already exists in vlan %s in routing-instance %v",
-				name, vlan, routingInstance))...)
-		case vstpInterfaceVIdTypeVlanGroup:
-			if routingInstance == junos.DefaultW {
-				return append(diagWarns, diag.FromErr(fmt.Errorf("protocols vstp interface %v in vlan-group %v already exists",
-					name, vlanGroup))...)
-			}
-
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp interface %v already exists in vlan-group %v in routing-instance %v",
-				name, vlanGroup, routingInstance))...)
-		}
-	}
-	if err := setVstpInterface(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "create resource junos_vstp_interface")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	vstpInterfaceExists, err = checkVstpInterfaceExists(name, routingInstance, vlan, vlanGroup, junSess)
-	if err != nil {
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if vstpInterfaceExists {
-		d.SetId(resourceVstpInterfaceNewID(d))
-	} else {
-		switch vstpInterfaceVIdType {
-		case vstpInterfaceVIdTypeNone:
-			if routingInstance == junos.DefaultW {
-				return append(diagWarns, diag.FromErr(fmt.Errorf("protocols vstp interface %v not exists after commit "+
-					"=> check your config", name))...)
-			}
-
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp interface %v not exists in routing-instance %v after commit "+
-					"=> check your config", name, routingInstance))...)
-		case vstpInterfaceVIdTypeVlan:
-			if routingInstance == junos.DefaultW {
-				return append(diagWarns, diag.FromErr(fmt.Errorf(
-					"protocols vstp interface %v in vlan %v not exists after commit "+
-						"=> check your config", name, vlan))...)
-			}
-
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp interface %v not exists in vlan %v in routing-instance %v after commit "+
-					"=> check your config", name, vlan, routingInstance))...)
-		case vstpInterfaceVIdTypeVlanGroup:
-			if routingInstance == junos.DefaultW {
-				return append(diagWarns, diag.FromErr(fmt.Errorf(
-					"protocols vstp interface %v in vlan-group %v not exists after commit "+
-						"=> check your config", name, vlanGroup))...)
-			}
-
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp interface %v not exists in vlan-group %v in routing-instance %v after commit "+
-					"=> check your config",
-				name, vlanGroup, routingInstance))...)
-		}
-	}
-
-	return append(diagWarns, resourceVstpInterfaceReadWJunSess(d, junSess)...)
-}
-
-func resourceVstpInterfaceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-
-	return resourceVstpInterfaceReadWJunSess(d, junSess)
-}
-
-func resourceVstpInterfaceReadWJunSess(d *schema.ResourceData, junSess *junos.Session,
-) diag.Diagnostics {
-	junos.MutexLock()
-	vstpInterfaceOptions, err := readVstpInterface(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		d.Get("vlan").(string),
-		d.Get("vlan_group").(string),
-		junSess,
-	)
-	junos.MutexUnlock()
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	if vstpInterfaceOptions.name == "" {
-		d.SetId("")
-	} else {
-		fillVstpInterfaceData(d, vstpInterfaceOptions)
-	}
-
-	return nil
-}
-
-func resourceVstpInterfaceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	d.Partial(true)
-	clt := m.(*junos.Client)
-	if clt.FakeUpdateAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delVstpInterface(
-			d.Get("name").(string),
-			d.Get("routing_instance").(string),
-			d.Get("vlan").(string),
-			d.Get("vlan_group").(string),
-			junSess,
-		); err != nil {
-			return diag.FromErr(err)
-		}
-		if err := setVstpInterface(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.Partial(false)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delVstpInterface(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		d.Get("vlan").(string),
-		d.Get("vlan_group").(string),
-		junSess,
-	); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if err := setVstpInterface(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "update resource junos_vstp_interface")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.Partial(false)
-
-	return append(diagWarns, resourceVstpInterfaceReadWJunSess(d, junSess)...)
-}
-
-func resourceVstpInterfaceDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeDeleteAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delVstpInterface(
-			d.Get("name").(string),
-			d.Get("routing_instance").(string),
-			d.Get("vlan").(string),
-			d.Get("vlan_group").(string),
-			junSess,
-		); err != nil {
-			return diag.FromErr(err)
-		}
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delVstpInterface(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		d.Get("vlan").(string),
-		d.Get("vlan_group").(string),
-		junSess,
-	); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "delete resource junos_vstp_interface")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-
-	return diagWarns
-}
-
-func resourceVstpInterfaceImport(ctx context.Context, d *schema.ResourceData, m interface{},
-) ([]*schema.ResourceData, error) {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return nil, err
-	}
-	defer junSess.Close()
-	result := make([]*schema.ResourceData, 1)
-	if len(strings.Split(d.Id(), junos.IDSeparator)) < 3 {
-		return nil, fmt.Errorf("missing element(s) in id with separator %v", junos.IDSeparator)
-	}
-	vType, name, vName, routingInstance := resourceVstpInterfaceReadID(d.Id())
-	var vstpInterfaceExists bool
-	switch vType {
-	case vstpInterfaceVIdTypeNone:
-		vstpInterfaceExists, err = checkVstpInterfaceExists(name, routingInstance, "", "", junSess)
-	case vstpInterfaceVIdTypeVlan:
-		vstpInterfaceExists, err = checkVstpInterfaceExists(name, routingInstance, vName, "", junSess)
-	case vstpInterfaceVIdTypeVlanGroup:
-		vstpInterfaceExists, err = checkVstpInterfaceExists(name, routingInstance, "", vName, junSess)
-	}
-	if err != nil {
-		return nil, err
-	}
-	if !vstpInterfaceExists {
-		return nil, fmt.Errorf("don't find protocols vstp interface with id '%v' "+
-			"(id must be <name>"+junos.IDSeparator+junos.IDSeparator+"<routing_instance>, "+
-			"<name>"+junos.IDSeparator+"%s<vlan>"+junos.IDSeparator+"<routing_instance> or "+
-			"<name>"+junos.IDSeparator+"%s<vlan_group>"+junos.IDSeparator+"<routing_instance>)",
-			d.Id(),
-			vstpInterfaceVIdTypeVlan.prefix(),
-			vstpInterfaceVIdTypeVlanGroup.prefix(),
-		)
-	}
-	var vstpInterfaceOptions vstpInterfaceOptions
-	switch vType {
-	case vstpInterfaceVIdTypeNone:
-		vstpInterfaceOptions, err = readVstpInterface(name, routingInstance, "", "", junSess)
-	case vstpInterfaceVIdTypeVlan:
-		vstpInterfaceOptions, err = readVstpInterface(name, routingInstance, vName, "", junSess)
-	case vstpInterfaceVIdTypeVlanGroup:
-		vstpInterfaceOptions, err = readVstpInterface(name, routingInstance, "", vName, junSess)
-	}
-	if err != nil {
-		return nil, err
-	}
-	fillVstpInterfaceData(d, vstpInterfaceOptions)
-	d.SetId(resourceVstpInterfaceNewID(d))
-	result[0] = d
-
-	return result, nil
-}
-
-func checkVstpInterfaceExists(name, routingInstance, vlan, vlanGroup string, junSess *junos.Session,
-) (_ bool, err error) {
-	var showConfig string
-	if vlan != "" && vlanGroup != "" {
-		return false, errors.New("internal error: checkVstpInterfaceExists called with vlan and vlanGroup")
-	}
-	if routingInstance == junos.DefaultW {
-		switch {
-		case vlan != "":
-			showConfig, err = junSess.Command(junos.CmdShowConfig +
-				"protocols vstp vlan " + vlan + " interface " + name + junos.PipeDisplaySet)
-		case vlanGroup != "":
-			showConfig, err = junSess.Command(junos.CmdShowConfig +
-				"protocols vstp vlan-group group " + vlanGroup + " interface " + name + junos.PipeDisplaySet)
-		default:
-			showConfig, err = junSess.Command(junos.CmdShowConfig +
-				"protocols vstp interface " + name + junos.PipeDisplaySet)
-		}
-	} else {
-		switch {
-		case vlan != "":
-			showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-				"protocols vstp vlan " + vlan + " interface " + name + junos.PipeDisplaySet)
-		case vlanGroup != "":
-			showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-				"protocols vstp vlan-group group " + vlanGroup + " interface " + name + junos.PipeDisplaySet)
-		default:
-			showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-				"protocols vstp interface " + name + junos.PipeDisplaySet)
-		}
-	}
-	if err != nil {
-		return false, err
-	}
-	if showConfig == junos.EmptyW {
-		return false, nil
-	}
-
-	return true, nil
-}
-
-func setVstpInterface(d *schema.ResourceData, junSess *junos.Session) error {
-	configSet := make([]string, 0)
-
-	name := d.Get("name").(string)
-	vlan := d.Get("vlan").(string)
-	vlanGroup := d.Get("vlan_group").(string)
-	setPrefix := junos.SetLS
-	if rI := d.Get("routing_instance").(string); rI != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + rI + " "
-	}
-	switch {
-	case vlan != "":
-		setPrefix += "protocols vstp vlan " + vlan + " interface " + name + " "
-	case vlanGroup != "":
-		setPrefix += "protocols vstp vlan-group group " + vlanGroup + " interface " + name + " "
-	default:
-		setPrefix += "protocols vstp interface " + name + " "
-	}
-
-	configSet = append(configSet, setPrefix)
-	if d.Get("access_trunk").(bool) {
-		configSet = append(configSet, setPrefix+"access-trunk")
-	}
-	if d.Get("bpdu_timeout_action_alarm").(bool) {
-		configSet = append(configSet, setPrefix+"bpdu-timeout-action alarm")
-	}
-	if d.Get("bpdu_timeout_action_block").(bool) {
-		configSet = append(configSet, setPrefix+"bpdu-timeout-action block")
-	}
-	if v := d.Get("cost").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"cost "+strconv.Itoa(v))
-	}
-	if d.Get("edge").(bool) {
-		configSet = append(configSet, setPrefix+"edge")
-	}
-	if v := d.Get("mode").(string); v != "" {
-		configSet = append(configSet, setPrefix+"mode "+v)
-	}
-	if d.Get("no_root_port").(bool) {
-		configSet = append(configSet, setPrefix+"no-root-port")
-	}
-	if v := d.Get("priority").(int); v != -1 {
-		configSet = append(configSet, setPrefix+"priority "+strconv.Itoa(v))
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func readVstpInterface(name, routingInstance, vlan, vlanGroup string, junSess *junos.Session,
-) (confRead vstpInterfaceOptions, err error) {
-	// default -1
-	confRead.priority = -1
-	if vlan != "" && vlanGroup != "" {
-		return confRead, errors.New("internal error: readVstpInterface called with vlan and vlanGroup")
-	}
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		switch {
-		case vlan != "":
-			showConfig, err = junSess.Command(junos.CmdShowConfig +
-				"protocols vstp vlan " + vlan + " interface " + name + junos.PipeDisplaySetRelative)
-		case vlanGroup != "":
-			showConfig, err = junSess.Command(junos.CmdShowConfig +
-				"protocols vstp vlan-group group " + vlanGroup + " interface " + name + junos.PipeDisplaySetRelative)
-		default:
-			showConfig, err = junSess.Command(junos.CmdShowConfig +
-				"protocols vstp interface " + name + junos.PipeDisplaySetRelative)
-		}
-	} else {
-		switch {
-		case vlan != "":
-			showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-				"protocols vstp vlan " + vlan + " interface " + name + junos.PipeDisplaySetRelative)
-		case vlanGroup != "":
-			showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-				"protocols vstp vlan-group group " + vlanGroup + " interface " + name + junos.PipeDisplaySetRelative)
-		default:
-			showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-				"protocols vstp interface " + name + junos.PipeDisplaySetRelative)
-		}
-	}
-	if err != nil {
-		return confRead, err
-	}
-	if showConfig != junos.EmptyW {
-		confRead.name = name
-		confRead.routingInstance = routingInstance
-		confRead.vlan = vlan
-		confRead.vlanGroup = vlanGroup
-		for _, item := range strings.Split(showConfig, "\n") {
-			if strings.Contains(item, junos.XMLStartTagConfigOut) {
-				continue
-			}
-			if strings.Contains(item, junos.XMLEndTagConfigOut) {
-				break
-			}
-			itemTrim := strings.TrimPrefix(item, junos.SetLS)
-			switch {
-			case itemTrim == "access-trunk":
-				confRead.accessTrunk = true
-			case itemTrim == "bpdu-timeout-action alarm":
-				confRead.bpduTimeoutActionAlarm = true
-			case itemTrim == "bpdu-timeout-action block":
-				confRead.bpduTimeoutActionBlock = true
-			case balt.CutPrefixInString(&itemTrim, "cost "):
-				confRead.cost, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case itemTrim == "edge":
-				confRead.edge = true
-			case balt.CutPrefixInString(&itemTrim, "mode "):
-				confRead.mode = itemTrim
-			case itemTrim == "no-root-port":
-				confRead.noRootPort = true
-			case balt.CutPrefixInString(&itemTrim, "priority "):
-				confRead.priority, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			}
-		}
-	}
-
-	return confRead, nil
-}
-
-func delVstpInterface(name, routingInstance, vlan, vlanGroup string, junSess *junos.Session) error {
-	configSet := make([]string, 0, 1)
-	if vlan != "" && vlanGroup != "" {
-		return errors.New("internal error: delVstpInterface called with vlan and vlanGroup")
-	}
-	if routingInstance == junos.DefaultW {
-		switch {
-		case vlan != "":
-			configSet = append(configSet, "delete protocols vstp vlan "+vlan+" interface "+name)
-		case vlanGroup != "":
-			configSet = append(configSet, "delete protocols vstp vlan-group group "+vlanGroup+" interface "+name)
-		default:
-			configSet = append(configSet, "delete protocols vstp interface "+name)
-		}
-	} else {
-		switch {
-		case vlan != "":
-			configSet = append(configSet, junos.DelRoutingInstances+routingInstance+
-				" protocols vstp vlan "+vlan+" interface "+name)
-		case vlanGroup != "":
-			configSet = append(configSet, junos.DelRoutingInstances+routingInstance+
-				" protocols vstp vlan-group group "+vlanGroup+" interface "+name)
-		default:
-			configSet = append(configSet, junos.DelRoutingInstances+routingInstance+
-				" protocols vstp interface "+name)
-		}
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func fillVstpInterfaceData(d *schema.ResourceData, vstpInterfaceOptions vstpInterfaceOptions) {
-	if tfErr := d.Set("name", vstpInterfaceOptions.name); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("routing_instance", vstpInterfaceOptions.routingInstance); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("vlan", vstpInterfaceOptions.vlan); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("vlan_group", vstpInterfaceOptions.vlanGroup); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("access_trunk", vstpInterfaceOptions.accessTrunk); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bpdu_timeout_action_alarm", vstpInterfaceOptions.bpduTimeoutActionAlarm); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bpdu_timeout_action_block", vstpInterfaceOptions.bpduTimeoutActionBlock); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("cost", vstpInterfaceOptions.cost); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("edge", vstpInterfaceOptions.edge); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("mode", vstpInterfaceOptions.mode); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("no_root_port", vstpInterfaceOptions.noRootPort); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("priority", vstpInterfaceOptions.priority); tfErr != nil {
-		panic(tfErr)
-	}
-}
diff --git a/internal/providersdk/resource_vstp_interface_test.go b/internal/providersdk/resource_vstp_interface_test.go
deleted file mode 100644
index b5b0d27a..00000000
--- a/internal/providersdk/resource_vstp_interface_test.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package providersdk_test
-
-import (
-	"fmt"
-	"os"
-	"testing"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
-)
-
-// export TESTACC_INTERFACE=<inteface> for choose interface available else it's xe-0/0/3.
-func TestAccResourceVstpInterface_basic(t *testing.T) {
-	if os.Getenv("TESTACC_SWITCH") != "" {
-		testaccInterface := junos.DefaultInterfaceSwitchTestAcc
-		if iface := os.Getenv("TESTACC_INTERFACE"); iface != "" {
-			testaccInterface = iface
-		}
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config: testAccResourceVstpInterfaceSWConfigCreate(testaccInterface),
-				},
-				{
-					Config: testAccResourceVstpInterfaceSWConfigUpdate(testaccInterface),
-				},
-				{
-					ResourceName:      "junos_vstp_interface.testacc_vstp_interface",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-				{
-					ResourceName:      "junos_vstp_interface.testacc_vstp_interface2",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-				{
-					ResourceName:      "junos_vstp_interface.testacc_vstp_interface3",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-				{
-					ResourceName:      "junos_vstp_interface.testacc_vstp_interface4",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-				{
-					ResourceName:      "junos_vstp_interface.testacc_vstp_interface5",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-				{
-					ResourceName:      "junos_vstp_interface.testacc_vstp_interface6",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	}
-}
-
-func testAccResourceVstpInterfaceSWConfigCreate(interFace string) string {
-	return fmt.Sprintf(`
-resource "junos_vstp_interface" "testacc_vstp_interface" {
-  name = "all"
-}
-resource "junos_vstp_vlan" "testacc_vstp_interface2" {
-  vlan_id = "10"
-}
-resource "junos_interface_physical" "testacc_vstp_interface2" {
-  name         = "%s"
-  description  = "testacc_vstp_interface2"
-  vlan_members = ["15"]
-}
-resource "junos_vstp_interface" "testacc_vstp_interface2" {
-  name = junos_interface_physical.testacc_vstp_interface2.name
-  vlan = junos_vstp_vlan.testacc_vstp_interface2.vlan_id
-}
-resource "junos_vstp_vlan_group" "testacc_vstp_interface3" {
-  name = "testacc_vstp_interface2"
-  vlan = ["11"]
-}
-resource "junos_vstp_interface" "testacc_vstp_interface3" {
-  name       = "all"
-  vlan_group = junos_vstp_vlan_group.testacc_vstp_interface3.name
-}
-resource "junos_routing_instance" "testacc_vstp_interface" {
-  name = "testacc_vstp_intface"
-  type = "virtual-switch"
-}
-resource "junos_vstp_interface" "testacc_vstp_interface4" {
-  name             = "all"
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-}
-resource "junos_vstp_vlan" "testacc_vstp_interface5" {
-  vlan_id          = "all"
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-}
-resource "junos_vstp_interface" "testacc_vstp_interface5" {
-  name             = "all"
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-  vlan             = junos_vstp_vlan.testacc_vstp_interface5.vlan_id
-}
-resource "junos_vstp_vlan_group" "testacc_vstp_interface6" {
-  name             = "testacc_vstp_interface6"
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-  vlan             = ["13"]
-}
-resource "junos_vstp_interface" "testacc_vstp_interface6" {
-  name             = "%s"
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-  vlan_group       = junos_vstp_vlan_group.testacc_vstp_interface6.name
-}
-`, interFace, interFace)
-}
-
-func testAccResourceVstpInterfaceSWConfigUpdate(interFace string) string {
-	return fmt.Sprintf(`
-resource "junos_vstp_interface" "testacc_vstp_interface" {
-  name                      = "all"
-  bpdu_timeout_action_alarm = true
-  bpdu_timeout_action_block = true
-  cost                      = 101
-  edge                      = true
-  priority                  = 32
-}
-resource "junos_vstp_vlan" "testacc_vstp_interface2" {
-  vlan_id = "10"
-}
-resource "junos_interface_physical" "testacc_vstp_interface2" {
-  name         = "%s"
-  description  = "testacc_vstp_interface2"
-  vlan_members = ["15"]
-}
-resource "junos_vstp_interface" "testacc_vstp_interface2" {
-  name         = junos_interface_physical.testacc_vstp_interface2.name
-  access_trunk = true
-  mode         = "shared"
-  no_root_port = true
-  vlan         = junos_vstp_vlan.testacc_vstp_interface2.vlan_id
-}
-resource "junos_vstp_vlan_group" "testacc_vstp_interface3" {
-  name = "testacc_vstp_interface2"
-  vlan = ["11"]
-}
-resource "junos_vstp_interface" "testacc_vstp_interface3" {
-  name       = "all"
-  priority   = 32
-  vlan_group = junos_vstp_vlan_group.testacc_vstp_interface3.name
-}
-resource "junos_routing_instance" "testacc_vstp_interface" {
-  name = "testacc_vstp_intface"
-  type = "virtual-switch"
-}
-resource "junos_vstp_interface" "testacc_vstp_interface4" {
-  name             = "all"
-  edge             = true
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-}
-resource "junos_vstp_vlan" "testacc_vstp_interface5" {
-  vlan_id          = "all"
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-}
-resource "junos_vstp_interface" "testacc_vstp_interface5" {
-  name             = "all"
-  mode             = "point-to-point"
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-  vlan             = junos_vstp_vlan.testacc_vstp_interface5.vlan_id
-}
-resource "junos_vstp_vlan_group" "testacc_vstp_interface6" {
-  name             = "testacc_vstp_interface6"
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-  vlan             = ["13"]
-}
-resource "junos_vstp_interface" "testacc_vstp_interface6" {
-  name             = "%s"
-  no_root_port     = true
-  priority         = 64
-  routing_instance = junos_routing_instance.testacc_vstp_interface.name
-  vlan_group       = junos_vstp_vlan_group.testacc_vstp_interface6.name
-}
-`, interFace, interFace)
-}
diff --git a/internal/providersdk/resource_vstp_test.go b/internal/providersdk/resource_vstp_test.go
deleted file mode 100644
index f72bf6d3..00000000
--- a/internal/providersdk/resource_vstp_test.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package providersdk_test
-
-import (
-	"os"
-	"testing"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
-)
-
-func TestAccResourceVstp_basic(t *testing.T) {
-	if os.Getenv("TESTACC_SWITCH") != "" {
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config: testAccResourceVstpSWConfigCreate(),
-				},
-				{
-					Config: testAccResourceVstpSWConfigUpdate(),
-				},
-				{
-					ResourceName:      "junos_vstp.testacc_ri_vstp",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	}
-}
-
-func testAccResourceVstpSWConfigCreate() string {
-	return `
-resource "junos_vstp" "testacc_vstp" {
-  bpdu_block_on_edge = true
-}
-resource "junos_routing_instance" "testacc_vstp" {
-  name = "testacc_vstp"
-  type = "virtual-switch"
-}
-resource "junos_vstp" "testacc_ri_vstp" {
-  routing_instance = junos_routing_instance.testacc_vstp.name
-  system_id {
-    id = "00:11:22:33:44:56"
-  }
-}
-`
-}
-
-func testAccResourceVstpSWConfigUpdate() string {
-	return `
-resource "junos_vstp" "testacc_vstp" {
-  disable = true
-}
-resource "junos_routing_instance" "testacc_vstp" {
-  name = "testacc_vstp"
-  type = "virtual-switch"
-}
-resource "junos_vstp" "testacc_ri_vstp" {
-  routing_instance   = junos_routing_instance.testacc_vstp.name
-  bpdu_block_on_edge = true
-  force_version_stp  = true
-  priority_hold_time = 10
-  system_id {
-    id = "00:11:22:33:44:55"
-  }
-  system_id {
-    id         = "00:22:33:44:55:aa"
-    ip_address = "192.0.2.4/31"
-  }
-  vpls_flush_on_topology_change = true
-}
-`
-}
diff --git a/internal/providersdk/resource_vstp_vlan.go b/internal/providersdk/resource_vstp_vlan.go
deleted file mode 100644
index 9cbcd625..00000000
--- a/internal/providersdk/resource_vstp_vlan.go
+++ /dev/null
@@ -1,479 +0,0 @@
-package providersdk
-
-import (
-	"context"
-	"fmt"
-	"regexp"
-	"strconv"
-	"strings"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
-	balt "github.com/jeremmfr/go-utils/basicalter"
-)
-
-type vstpVlanOptions struct {
-	forwardDelay         int
-	helloTime            int
-	maxAge               int
-	backupBridgePriority string
-	bridgePriority       string
-	vlanID               string
-	routingInstance      string
-	systemIdentifier     string
-}
-
-func resourceVstpVlan() *schema.Resource {
-	return &schema.Resource{
-		CreateWithoutTimeout: resourceVstpVlanCreate,
-		ReadWithoutTimeout:   resourceVstpVlanRead,
-		UpdateWithoutTimeout: resourceVstpVlanUpdate,
-		DeleteWithoutTimeout: resourceVstpVlanDelete,
-		Importer: &schema.ResourceImporter{
-			StateContext: resourceVstpVlanImport,
-		},
-		Schema: map[string]*schema.Schema{
-			"vlan_id": {
-				Type:     schema.TypeString,
-				Required: true,
-				ForceNew: true,
-				ValidateFunc: validation.StringMatch(regexp.MustCompile(
-					`^all|[0-9]{1,4}$`), "must be 'all' or a VLAN id"),
-			},
-			"routing_instance": {
-				Type:             schema.TypeString,
-				Optional:         true,
-				ForceNew:         true,
-				Default:          junos.DefaultW,
-				ValidateDiagFunc: validateNameObjectJunos([]string{}, 64, formatDefault),
-			},
-			"backup_bridge_priority": {
-				Type:     schema.TypeString,
-				Optional: true,
-				ValidateFunc: validation.StringMatch(regexp.MustCompile(
-					`^\d\d?k$`), "must be a number with increments of 4k - 4k,8k,..60k"),
-			},
-			"bridge_priority": {
-				Type:     schema.TypeString,
-				Optional: true,
-				ValidateFunc: validation.StringMatch(regexp.MustCompile(
-					`^(0|\d\d?k)$`), "must be a number with increments of 4k - 0,4k,8k,..60k"),
-			},
-			"forward_delay": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(4, 30),
-			},
-			"hello_time": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(1, 10),
-			},
-			"max_age": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(6, 40),
-			},
-			"system_identifier": {
-				Type:         schema.TypeString,
-				Optional:     true,
-				ValidateFunc: validation.IsMACAddress,
-			},
-		},
-	}
-}
-
-func resourceVstpVlanCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	routingInstance := d.Get("routing_instance").(string)
-	vlanID := d.Get("vlan_id").(string)
-	if clt.FakeCreateSetFile() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := setVstpVlan(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.SetId(vlanID + junos.IDSeparator + routingInstance)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if routingInstance != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(routingInstance, junSess)
-		if err != nil {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns, diag.FromErr(err)...)
-		}
-		if !instanceExists {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns,
-				diag.FromErr(fmt.Errorf("routing instance %v doesn't exist", d.Get("routing_instance").(string)))...)
-		}
-	}
-	vstpVlanExists, err := checkVstpVlanExists(vlanID, routingInstance, junSess)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if vstpVlanExists {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-		if routingInstance != junos.DefaultW {
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp vlan %v already exists in routing-instance %v", vlanID, routingInstance))...)
-		}
-
-		return append(diagWarns, diag.FromErr(fmt.Errorf("protocols vstp vlan %v already exists", vlanID))...)
-	}
-	if err := setVstpVlan(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "create resource junos_vstp_vlan")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	vstpVlanExists, err = checkVstpVlanExists(vlanID, routingInstance, junSess)
-	if err != nil {
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if vstpVlanExists {
-		d.SetId(vlanID + junos.IDSeparator + routingInstance)
-	} else {
-		if routingInstance != junos.DefaultW {
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp vlan %v not exists in routing-instance %v after commit "+
-					"=> check your config", vlanID, routingInstance))...)
-		}
-
-		return append(diagWarns, diag.FromErr(fmt.Errorf("protocols vstp vlan %v not exists after commit "+
-			"=> check your config", vlanID))...)
-	}
-
-	return append(diagWarns, resourceVstpVlanReadWJunSess(d, junSess)...)
-}
-
-func resourceVstpVlanRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-
-	return resourceVstpVlanReadWJunSess(d, junSess)
-}
-
-func resourceVstpVlanReadWJunSess(d *schema.ResourceData, junSess *junos.Session,
-) diag.Diagnostics {
-	junos.MutexLock()
-	vstpVlanOptions, err := readVstpVlan(d.Get("vlan_id").(string), d.Get("routing_instance").(string), junSess)
-	junos.MutexUnlock()
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	if vstpVlanOptions.vlanID == "" {
-		d.SetId("")
-	} else {
-		fillVstpVlanData(d, vstpVlanOptions)
-	}
-
-	return nil
-}
-
-func resourceVstpVlanUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	d.Partial(true)
-	clt := m.(*junos.Client)
-	if clt.FakeUpdateAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delVstpVlan(d.Get("vlan_id").(string), d.Get("routing_instance").(string), false, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		if err := setVstpVlan(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.Partial(false)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delVstpVlan(
-		d.Get("vlan_id").(string),
-		d.Get("routing_instance").(string),
-		false,
-		junSess,
-	); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if err := setVstpVlan(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "update resource junos_vstp_vlan")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.Partial(false)
-
-	return append(diagWarns, resourceVstpVlanReadWJunSess(d, junSess)...)
-}
-
-func resourceVstpVlanDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeDeleteAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delVstpVlan(d.Get("vlan_id").(string), d.Get("routing_instance").(string), true, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delVstpVlan(
-		d.Get("vlan_id").(string),
-		d.Get("routing_instance").(string),
-		true,
-		junSess,
-	); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "delete resource junos_vstp_vlan")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-
-	return diagWarns
-}
-
-func resourceVstpVlanImport(ctx context.Context, d *schema.ResourceData, m interface{},
-) ([]*schema.ResourceData, error) {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return nil, err
-	}
-	defer junSess.Close()
-	result := make([]*schema.ResourceData, 1)
-	idSplit := strings.Split(d.Id(), junos.IDSeparator)
-	if len(idSplit) < 2 {
-		return nil, fmt.Errorf("missing element(s) in id with separator %v", junos.IDSeparator)
-	}
-	vstpVlanExists, err := checkVstpVlanExists(idSplit[0], idSplit[1], junSess)
-	if err != nil {
-		return nil, err
-	}
-	if !vstpVlanExists {
-		return nil, fmt.Errorf("don't find protocols vstp vlan with id '%v' "+
-			"(id must be <vlan_id>"+junos.IDSeparator+"<routing_instance>", d.Id())
-	}
-	vstpVlanOptions, err := readVstpVlan(idSplit[0], idSplit[1], junSess)
-	if err != nil {
-		return nil, err
-	}
-	fillVstpVlanData(d, vstpVlanOptions)
-
-	result[0] = d
-
-	return result, nil
-}
-
-func checkVstpVlanExists(vlanID, routingInstance string, junSess *junos.Session,
-) (_ bool, err error) {
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols vstp vlan " + vlanID + junos.PipeDisplaySet)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols vstp vlan " + vlanID + junos.PipeDisplaySet)
-	}
-	if err != nil {
-		return false, err
-	}
-	if showConfig == junos.EmptyW {
-		return false, nil
-	}
-
-	return true, nil
-}
-
-func setVstpVlan(d *schema.ResourceData, junSess *junos.Session) error {
-	configSet := make([]string, 0, 1)
-
-	setPrefix := junos.SetLS
-	if rI := d.Get("routing_instance").(string); rI != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + rI + " "
-	}
-	setPrefix += "protocols vstp vlan " + d.Get("vlan_id").(string) + " "
-
-	configSet = append(configSet, setPrefix)
-	if v := d.Get("backup_bridge_priority").(string); v != "" {
-		configSet = append(configSet, setPrefix+"backup-bridge-priority "+v)
-	}
-	if v := d.Get("bridge_priority").(string); v != "" {
-		configSet = append(configSet, setPrefix+"bridge-priority "+v)
-	}
-	if v := d.Get("forward_delay").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"forward-delay "+strconv.Itoa(v))
-	}
-	if v := d.Get("hello_time").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"hello-time "+strconv.Itoa(v))
-	}
-	if v := d.Get("max_age").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"max-age "+strconv.Itoa(v))
-	}
-	if v := d.Get("system_identifier").(string); v != "" {
-		configSet = append(configSet, setPrefix+"system-identifier "+v)
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func readVstpVlan(vlanID, routingInstance string, junSess *junos.Session,
-) (confRead vstpVlanOptions, err error) {
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols vstp vlan " + vlanID + junos.PipeDisplaySetRelative)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols vstp vlan " + vlanID + junos.PipeDisplaySetRelative)
-	}
-	if err != nil {
-		return confRead, err
-	}
-	if showConfig != junos.EmptyW {
-		confRead.vlanID = vlanID
-		confRead.routingInstance = routingInstance
-		for _, item := range strings.Split(showConfig, "\n") {
-			if strings.Contains(item, junos.XMLStartTagConfigOut) {
-				continue
-			}
-			if strings.Contains(item, junos.XMLEndTagConfigOut) {
-				break
-			}
-			itemTrim := strings.TrimPrefix(item, junos.SetLS)
-			switch {
-			case balt.CutPrefixInString(&itemTrim, "backup-bridge-priority "):
-				confRead.backupBridgePriority = itemTrim
-			case balt.CutPrefixInString(&itemTrim, "bridge-priority "):
-				confRead.bridgePriority = itemTrim
-			case balt.CutPrefixInString(&itemTrim, "forward-delay "):
-				confRead.forwardDelay, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "hello-time "):
-				confRead.helloTime, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "max-age "):
-				confRead.maxAge, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "system-identifier "):
-				confRead.systemIdentifier = itemTrim
-			}
-		}
-	}
-
-	return confRead, nil
-}
-
-func delVstpVlan(vlanID, routingInstance string, deleteAll bool, junSess *junos.Session) error {
-	delPrefix := junos.DeleteLS
-	if routingInstance != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + routingInstance + " "
-	}
-	delPrefix += "protocols vstp vlan " + vlanID + " "
-
-	if deleteAll {
-		return junSess.ConfigSet([]string{delPrefix})
-	}
-	listLinesToDelete := []string{
-		"backup-bridge-priority",
-		"bridge-priority",
-		"forward-delay",
-		"hello-time",
-		"max-age",
-		"system-identifier",
-	}
-	configSet := make([]string, len(listLinesToDelete))
-	for k, line := range listLinesToDelete {
-		configSet[k] = delPrefix + line
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func fillVstpVlanData(d *schema.ResourceData, vstpVlanOptions vstpVlanOptions) {
-	if tfErr := d.Set("vlan_id", vstpVlanOptions.vlanID); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("routing_instance", vstpVlanOptions.routingInstance); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("backup_bridge_priority", vstpVlanOptions.backupBridgePriority); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bridge_priority", vstpVlanOptions.bridgePriority); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("forward_delay", vstpVlanOptions.forwardDelay); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("hello_time", vstpVlanOptions.helloTime); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("max_age", vstpVlanOptions.maxAge); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("system_identifier", vstpVlanOptions.systemIdentifier); tfErr != nil {
-		panic(tfErr)
-	}
-}
diff --git a/internal/providersdk/resource_vstp_vlan_group.go b/internal/providersdk/resource_vstp_vlan_group.go
deleted file mode 100644
index 8d65fd0e..00000000
--- a/internal/providersdk/resource_vstp_vlan_group.go
+++ /dev/null
@@ -1,508 +0,0 @@
-package providersdk
-
-import (
-	"context"
-	"fmt"
-	"regexp"
-	"strconv"
-	"strings"
-
-	"github.com/jeremmfr/terraform-provider-junos/internal/junos"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
-	balt "github.com/jeremmfr/go-utils/basicalter"
-)
-
-type vstpVlanGroupOptions struct {
-	forwardDelay         int
-	helloTime            int
-	maxAge               int
-	backupBridgePriority string
-	bridgePriority       string
-	name                 string
-	routingInstance      string
-	systemIdentifier     string
-	vlan                 []string
-}
-
-func resourceVstpVlanGroup() *schema.Resource {
-	return &schema.Resource{
-		CreateWithoutTimeout: resourceVstpVlanGroupCreate,
-		ReadWithoutTimeout:   resourceVstpVlanGroupRead,
-		UpdateWithoutTimeout: resourceVstpVlanGroupUpdate,
-		DeleteWithoutTimeout: resourceVstpVlanGroupDelete,
-		Importer: &schema.ResourceImporter{
-			StateContext: resourceVstpVlanGroupImport,
-		},
-		Schema: map[string]*schema.Schema{
-			"name": {
-				Type:             schema.TypeString,
-				Required:         true,
-				ForceNew:         true,
-				ValidateDiagFunc: validateNameObjectJunos([]string{}, 64, formatDefault),
-			},
-			"routing_instance": {
-				Type:             schema.TypeString,
-				Optional:         true,
-				ForceNew:         true,
-				Default:          junos.DefaultW,
-				ValidateDiagFunc: validateNameObjectJunos([]string{}, 64, formatDefault),
-			},
-			"vlan": {
-				Type:     schema.TypeSet,
-				Required: true,
-				Elem:     &schema.Schema{Type: schema.TypeString},
-			},
-			"backup_bridge_priority": {
-				Type:     schema.TypeString,
-				Optional: true,
-				ValidateFunc: validation.StringMatch(regexp.MustCompile(
-					`^\d\d?k$`), "must be a number with increments of 4k - 4k,8k,..60k"),
-			},
-			"bridge_priority": {
-				Type:     schema.TypeString,
-				Optional: true,
-				ValidateFunc: validation.StringMatch(regexp.MustCompile(
-					`^(0|\d\d?k)$`), "must be a number with increments of 4k - 0,4k,8k,..60k"),
-			},
-			"forward_delay": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(4, 30),
-			},
-			"hello_time": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(1, 10),
-			},
-			"max_age": {
-				Type:         schema.TypeInt,
-				Optional:     true,
-				ValidateFunc: validation.IntBetween(6, 40),
-			},
-			"system_identifier": {
-				Type:         schema.TypeString,
-				Optional:     true,
-				ValidateFunc: validation.IsMACAddress,
-			},
-		},
-	}
-}
-
-func resourceVstpVlanGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	routingInstance := d.Get("routing_instance").(string)
-	name := d.Get("name").(string)
-	if clt.FakeCreateSetFile() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := setVstpVlanGroup(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.SetId(name + junos.IDSeparator + routingInstance)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if routingInstance != junos.DefaultW {
-		instanceExists, err := checkRoutingInstanceExists(routingInstance, junSess)
-		if err != nil {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns, diag.FromErr(err)...)
-		}
-		if !instanceExists {
-			appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-			return append(diagWarns,
-				diag.FromErr(fmt.Errorf("routing instance %v doesn't exist", d.Get("routing_instance").(string)))...)
-		}
-	}
-	vstpVlanGroupExists, err := checkVstpVlanGroupExists(name, routingInstance, junSess)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if vstpVlanGroupExists {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-		if routingInstance != junos.DefaultW {
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp vlan-group group %v already exists in routing-instance %v",
-				name, routingInstance))...)
-		}
-
-		return append(diagWarns, diag.FromErr(fmt.Errorf("protocols vstp vlan-group group %v already exists",
-			name))...)
-	}
-	if err := setVstpVlanGroup(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "create resource junos_vstp_vlan_group")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	vstpVlanGroupExists, err = checkVstpVlanGroupExists(name, routingInstance, junSess)
-	if err != nil {
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if vstpVlanGroupExists {
-		d.SetId(name + junos.IDSeparator + routingInstance)
-	} else {
-		if routingInstance != junos.DefaultW {
-			return append(diagWarns, diag.FromErr(fmt.Errorf(
-				"protocols vstp vlan-group group %v not exists in routing-instance %v after commit "+
-					"=> check your config", name, routingInstance))...)
-		}
-
-		return append(diagWarns, diag.FromErr(fmt.Errorf("protocols vstp vlan-group group %v not exists after commit "+
-			"=> check your config", name))...)
-	}
-
-	return append(diagWarns, resourceVstpVlanGroupReadWJunSess(d, junSess)...)
-}
-
-func resourceVstpVlanGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-
-	return resourceVstpVlanGroupReadWJunSess(d, junSess)
-}
-
-func resourceVstpVlanGroupReadWJunSess(d *schema.ResourceData, junSess *junos.Session,
-) diag.Diagnostics {
-	junos.MutexLock()
-	vstpVlanGroupOptions, err := readVstpVlanGroup(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		junSess,
-	)
-	junos.MutexUnlock()
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	if vstpVlanGroupOptions.name == "" {
-		d.SetId("")
-	} else {
-		fillVstpVlanGroupData(d, vstpVlanGroupOptions)
-	}
-
-	return nil
-}
-
-func resourceVstpVlanGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	d.Partial(true)
-	clt := m.(*junos.Client)
-	if clt.FakeUpdateAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delVstpVlanGroup(
-			d.Get("name").(string),
-			d.Get("routing_instance").(string),
-			false,
-			junSess,
-		); err != nil {
-			return diag.FromErr(err)
-		}
-		if err := setVstpVlanGroup(d, junSess); err != nil {
-			return diag.FromErr(err)
-		}
-		d.Partial(false)
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delVstpVlanGroup(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		false,
-		junSess,
-	); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	if err := setVstpVlanGroup(d, junSess); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "update resource junos_vstp_vlan_group")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	d.Partial(false)
-
-	return append(diagWarns, resourceVstpVlanGroupReadWJunSess(d, junSess)...)
-}
-
-func resourceVstpVlanGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
-	clt := m.(*junos.Client)
-	if clt.FakeDeleteAlso() {
-		junSess := clt.NewSessionWithoutNetconf(ctx)
-		if err := delVstpVlanGroup(
-			d.Get("name").(string),
-			d.Get("routing_instance").(string),
-			true,
-			junSess,
-		); err != nil {
-			return diag.FromErr(err)
-		}
-
-		return nil
-	}
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return diag.FromErr(err)
-	}
-	defer junSess.Close()
-	if err := junSess.ConfigLock(ctx); err != nil {
-		return diag.FromErr(err)
-	}
-	var diagWarns diag.Diagnostics
-	if err := delVstpVlanGroup(
-		d.Get("name").(string),
-		d.Get("routing_instance").(string),
-		true,
-		junSess,
-	); err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-	warns, err := junSess.CommitConf(ctx, "delete resource junos_vstp_vlan_group")
-	appendDiagWarns(&diagWarns, warns)
-	if err != nil {
-		appendDiagWarns(&diagWarns, junSess.ConfigClear())
-
-		return append(diagWarns, diag.FromErr(err)...)
-	}
-
-	return diagWarns
-}
-
-func resourceVstpVlanGroupImport(ctx context.Context, d *schema.ResourceData, m interface{},
-) ([]*schema.ResourceData, error) {
-	clt := m.(*junos.Client)
-	junSess, err := clt.StartNewSession(ctx)
-	if err != nil {
-		return nil, err
-	}
-	defer junSess.Close()
-	result := make([]*schema.ResourceData, 1)
-	idSplit := strings.Split(d.Id(), junos.IDSeparator)
-	if len(idSplit) < 2 {
-		return nil, fmt.Errorf("missing element(s) in id with separator %v", junos.IDSeparator)
-	}
-	vstpVlanGroupExists, err := checkVstpVlanGroupExists(idSplit[0], idSplit[1], junSess)
-	if err != nil {
-		return nil, err
-	}
-	if !vstpVlanGroupExists {
-		return nil, fmt.Errorf("don't find protocols vstp vlan-group group with id '%v' "+
-			"(id must be <name>"+junos.IDSeparator+"<routing_instance>", d.Id())
-	}
-	vstpVlanGroupOptions, err := readVstpVlanGroup(idSplit[0], idSplit[1], junSess)
-	if err != nil {
-		return nil, err
-	}
-	fillVstpVlanGroupData(d, vstpVlanGroupOptions)
-
-	result[0] = d
-
-	return result, nil
-}
-
-func checkVstpVlanGroupExists(name, routingInstance string, junSess *junos.Session,
-) (_ bool, err error) {
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols vstp vlan-group group " + name + junos.PipeDisplaySet)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols vstp vlan-group group " + name + junos.PipeDisplaySet)
-	}
-	if err != nil {
-		return false, err
-	}
-	if showConfig == junos.EmptyW {
-		return false, nil
-	}
-
-	return true, nil
-}
-
-func setVstpVlanGroup(d *schema.ResourceData, junSess *junos.Session) error {
-	configSet := make([]string, 0)
-
-	setPrefix := junos.SetLS
-	if rI := d.Get("routing_instance").(string); rI != junos.DefaultW {
-		setPrefix = junos.SetRoutingInstances + rI + " "
-	}
-	setPrefix += "protocols vstp vlan-group group " + d.Get("name").(string) + " "
-
-	for _, vlan := range sortSetOfString(d.Get("vlan").(*schema.Set).List()) {
-		configSet = append(configSet, setPrefix+"vlan "+vlan)
-	}
-	if v := d.Get("backup_bridge_priority").(string); v != "" {
-		configSet = append(configSet, setPrefix+"backup-bridge-priority "+v)
-	}
-	if v := d.Get("bridge_priority").(string); v != "" {
-		configSet = append(configSet, setPrefix+"bridge-priority "+v)
-	}
-	if v := d.Get("forward_delay").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"forward-delay "+strconv.Itoa(v))
-	}
-	if v := d.Get("hello_time").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"hello-time "+strconv.Itoa(v))
-	}
-	if v := d.Get("max_age").(int); v != 0 {
-		configSet = append(configSet, setPrefix+"max-age "+strconv.Itoa(v))
-	}
-	if v := d.Get("system_identifier").(string); v != "" {
-		configSet = append(configSet, setPrefix+"system-identifier "+v)
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func readVstpVlanGroup(name, routingInstance string, junSess *junos.Session,
-) (confRead vstpVlanGroupOptions, err error) {
-	var showConfig string
-	if routingInstance == junos.DefaultW {
-		showConfig, err = junSess.Command(junos.CmdShowConfig +
-			"protocols vstp vlan-group group " + name + junos.PipeDisplaySetRelative)
-	} else {
-		showConfig, err = junSess.Command(junos.CmdShowConfig + junos.RoutingInstancesWS + routingInstance + " " +
-			"protocols vstp vlan-group group " + name + junos.PipeDisplaySetRelative)
-	}
-	if err != nil {
-		return confRead, err
-	}
-	if showConfig != junos.EmptyW {
-		confRead.name = name
-		confRead.routingInstance = routingInstance
-		for _, item := range strings.Split(showConfig, "\n") {
-			if strings.Contains(item, junos.XMLStartTagConfigOut) {
-				continue
-			}
-			if strings.Contains(item, junos.XMLEndTagConfigOut) {
-				break
-			}
-			itemTrim := strings.TrimPrefix(item, junos.SetLS)
-			switch {
-			case balt.CutPrefixInString(&itemTrim, "vlan "):
-				confRead.vlan = append(confRead.vlan, itemTrim)
-			case balt.CutPrefixInString(&itemTrim, "backup-bridge-priority "):
-				confRead.backupBridgePriority = itemTrim
-			case balt.CutPrefixInString(&itemTrim, "bridge-priority "):
-				confRead.bridgePriority = itemTrim
-			case balt.CutPrefixInString(&itemTrim, "forward-delay "):
-				confRead.forwardDelay, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "hello-time "):
-				confRead.helloTime, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "max-age "):
-				confRead.maxAge, err = strconv.Atoi(itemTrim)
-				if err != nil {
-					return confRead, fmt.Errorf(failedConvAtoiError, itemTrim, err)
-				}
-			case balt.CutPrefixInString(&itemTrim, "system-identifier "):
-				confRead.systemIdentifier = itemTrim
-			}
-		}
-	}
-
-	return confRead, nil
-}
-
-func delVstpVlanGroup(name, routingInstance string, deleteAll bool, junSess *junos.Session) error {
-	delPrefix := junos.DeleteLS
-	if routingInstance != junos.DefaultW {
-		delPrefix = junos.DelRoutingInstances + routingInstance + " "
-	}
-	delPrefix += "protocols vstp vlan-group group " + name + " "
-
-	if deleteAll {
-		return junSess.ConfigSet([]string{delPrefix})
-	}
-	listLinesToDelete := []string{
-		"backup-bridge-priority",
-		"bridge-priority",
-		"forward-delay",
-		"hello-time",
-		"max-age",
-		"system-identifier",
-		"vlan",
-	}
-	configSet := make([]string, len(listLinesToDelete))
-	for k, line := range listLinesToDelete {
-		configSet[k] = delPrefix + line
-	}
-
-	return junSess.ConfigSet(configSet)
-}
-
-func fillVstpVlanGroupData(d *schema.ResourceData, vstpVlanGroupOptions vstpVlanGroupOptions) {
-	if tfErr := d.Set("name", vstpVlanGroupOptions.name); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("routing_instance", vstpVlanGroupOptions.routingInstance); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("vlan", vstpVlanGroupOptions.vlan); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("backup_bridge_priority", vstpVlanGroupOptions.backupBridgePriority); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("bridge_priority", vstpVlanGroupOptions.bridgePriority); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("forward_delay", vstpVlanGroupOptions.forwardDelay); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("hello_time", vstpVlanGroupOptions.helloTime); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("max_age", vstpVlanGroupOptions.maxAge); tfErr != nil {
-		panic(tfErr)
-	}
-	if tfErr := d.Set("system_identifier", vstpVlanGroupOptions.systemIdentifier); tfErr != nil {
-		panic(tfErr)
-	}
-}
diff --git a/internal/providersdk/resource_vstp_vlan_group_test.go b/internal/providersdk/resource_vstp_vlan_group_test.go
deleted file mode 100644
index 53472645..00000000
--- a/internal/providersdk/resource_vstp_vlan_group_test.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package providersdk_test
-
-import (
-	"os"
-	"testing"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
-)
-
-func TestAccResourceVstpVlanGroup_basic(t *testing.T) {
-	if os.Getenv("TESTACC_SWITCH") != "" {
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config: testAccResourceVstpVlanGroupSWConfigCreate(),
-				},
-				{
-					Config: testAccResourceVstpVlanGroupSWConfigUpdate(),
-				},
-				{
-					ResourceName:      "junos_vstp_vlan_group.testacc_ri_vstp_vlan_group",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	}
-}
-
-func testAccResourceVstpVlanGroupSWConfigCreate() string {
-	return `
-resource "junos_vstp_vlan_group" "testacc_vstp_vlan_group" {
-  name = "vlanGroup"
-  vlan = ["10"]
-}
-resource "junos_routing_instance" "testacc_vstp_vlan_group" {
-  name = "testacc_vstp_vlan_group"
-  type = "virtual-switch"
-}
-resource "junos_vstp_vlan_group" "testacc_ri_vstp_vlan_group" {
-  routing_instance = junos_routing_instance.testacc_vstp_vlan_group.name
-  name             = "vlanGroupRI"
-  vlan             = ["12"]
-  bridge_priority  = "16k"
-}
-`
-}
-
-func testAccResourceVstpVlanGroupSWConfigUpdate() string {
-	return `
-resource "junos_vstp_vlan_group" "testacc_vstp_vlan_group" {
-  name                   = "vlanGroup"
-  vlan                   = ["10"]
-  backup_bridge_priority = "8k"
-  bridge_priority        = "4k"
-  hello_time             = 2
-}
-resource "junos_routing_instance" "testacc_vstp_vlan_group" {
-  name = "testacc_vstp_vlan_group"
-  type = "virtual-switch"
-}
-resource "junos_vstp_vlan_group" "testacc_ri_vstp_vlan_group" {
-  routing_instance       = junos_routing_instance.testacc_vstp_vlan_group.name
-  name                   = "vlanGroupRI"
-  vlan                   = ["12", "11"]
-  backup_bridge_priority = "20k"
-  forward_delay          = 22
-  hello_time             = 3
-  max_age                = 24
-  system_identifier      = "00:aa:bc:ed:ff:11"
-}
-`
-}
diff --git a/internal/providersdk/resource_vstp_vlan_test.go b/internal/providersdk/resource_vstp_vlan_test.go
deleted file mode 100644
index 931baaf4..00000000
--- a/internal/providersdk/resource_vstp_vlan_test.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package providersdk_test
-
-import (
-	"os"
-	"testing"
-
-	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
-)
-
-func TestAccResourceVstpVlan_basic(t *testing.T) {
-	if os.Getenv("TESTACC_SWITCH") != "" {
-		resource.Test(t, resource.TestCase{
-			PreCheck:                 func() { testAccPreCheck(t) },
-			ProtoV5ProviderFactories: testAccProtoV5ProviderFactories,
-			Steps: []resource.TestStep{
-				{
-					Config: testAccResourceVstpVlanSWConfigCreate(),
-				},
-				{
-					Config: testAccResourceVstpVlanSWConfigUpdate(),
-				},
-				{
-					ResourceName:      "junos_vstp_vlan.testacc_ri_vstp_vlan",
-					ImportState:       true,
-					ImportStateVerify: true,
-				},
-			},
-		})
-	}
-}
-
-func testAccResourceVstpVlanSWConfigCreate() string {
-	return `
-resource "junos_vstp_vlan" "testacc_vstp_vlan" {
-  vlan_id = "10"
-}
-resource "junos_vstp_vlan" "testacc_vstp_vlan_all" {
-  vlan_id = "all"
-}
-resource "junos_routing_instance" "testacc_vstp_vlan" {
-  name = "testacc_vstp_vlan"
-  type = "virtual-switch"
-}
-resource "junos_vstp_vlan" "testacc_ri_vstp_vlan" {
-  routing_instance = junos_routing_instance.testacc_vstp_vlan.name
-  vlan_id          = "11"
-  bridge_priority  = "16k"
-}
-resource "junos_vstp_vlan" "testacc_ri_vstp_vlan_all" {
-  routing_instance  = junos_routing_instance.testacc_vstp_vlan.name
-  vlan_id           = "all"
-  system_identifier = "00:aa:bc:ed:ff:11"
-}
-`
-}
-
-func testAccResourceVstpVlanSWConfigUpdate() string {
-	return `
-resource "junos_vstp_vlan" "testacc_vstp_vlan" {
-  vlan_id                = "10"
-  backup_bridge_priority = "8k"
-  bridge_priority        = "4k"
-}
-resource "junos_vstp_vlan" "testacc_vstp_vlan_all" {
-  vlan_id    = "all"
-  hello_time = 2
-}
-resource "junos_routing_instance" "testacc_vstp_vlan" {
-  name = "testacc_vstp_vlan"
-  type = "virtual-switch"
-}
-resource "junos_vstp_vlan" "testacc_ri_vstp_vlan" {
-  routing_instance       = junos_routing_instance.testacc_vstp_vlan.name
-  vlan_id                = "11"
-  backup_bridge_priority = "20k"
-  bridge_priority        = 0
-  forward_delay          = 22
-  hello_time             = 3
-  max_age                = 24
-}
-resource "junos_vstp_vlan" "testacc_ri_vstp_vlan_all" {
-  routing_instance = junos_routing_instance.testacc_vstp_vlan.name
-  vlan_id          = "all"
-}
-`
-}