diff --git a/modules/cloud-config-container/simple-nva/README.md b/modules/cloud-config-container/simple-nva/README.md
new file mode 100644
index 0000000000..7fbb109d4d
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/README.md
@@ -0,0 +1,79 @@
+# Google Cloud DNS Module
+
+This module allows for the creation of a NVA (Network Virtual Appliance) to be used for experiments and as a stub for future appliances deployment.
+
+This NVA can be used to interconnect up to 8 VPCs.
+
+## Examples
+
+### Simple example
+
+```hcl
+# Interfaces configuration
+locals {
+ network_interfaces = [
+ {
+ addresses = null
+ name = "dev"
+ nat = false
+ network = "dev_vpc_self_link"
+ routes = ["10.128.0.0/9"]
+ subnetwork = "dev_vpc_nva_subnet_self_link"
+ },
+ {
+ addresses = null
+ name = "prod"
+ nat = false
+ network = "prod_vpc_self_link"
+ routes = ["10.0.0.0/9"]
+ subnetwork = "prod_vpc_nva_subnet_self_link"
+ }
+}
+
+# NVA config
+module "nva-cloud-config" {
+ source = "../../../cloud-foundation-fabric/modules/cloud-config-container/simple-nva"
+ enable_health_checks = true
+ network_interfaces = local.network_interfaces
+}
+
+# COS VM
+module "nva" {
+ source = "../../modules/compute-vm"
+ project_id = "myproject"
+ instance_type = "e2-standard-2"
+ name = "nva"
+ can_ip_forward = true
+ zone = "europe-west8-a"
+ tags = ["nva"]
+ network_interfaces = local.network_interfaces
+ boot_disk = {
+ image = "projects/cos-cloud/global/images/family/cos-stable"
+ size = 10
+ type = "pd-balanced"
+ }
+ metadata = {
+ user-data = module.nva-cloud-config.cloud_config
+ }
+}
+```
+
+
+## Variables
+
+| name | description | type | required | default |
+|---|---|:---:|:---:|:---:|
+| [network_interfaces](variables.tf#L29) | Network interfaces configuration. | list(object({…}))
| ✓ | |
+| [cloud_config](variables.tf#L17) | Cloud config template path. If null default will be used. | string
| | null
|
+| [enable_health_checks](variables.tf#L23) | Configures routing to enable responses to health check probes. | bool
| | false
|
+| [test_instance](variables-instance.tf#L17) | Test/development instance attributes, leave null to skip creation. | object({…})
| | null
|
+| [test_instance_defaults](variables-instance.tf#L30) | Test/development instance defaults used for optional configuration. If image is null, COS stable will be used. | object({…})
| | {…}
|
+
+## Outputs
+
+| name | description | sensitive |
+|---|---|:---:|
+| [cloud_config](outputs.tf#L17) | Rendered cloud-config file to be passed as user-data instance metadata. | |
+| [test_instance](outputs-instance.tf#L17) | Optional test instance name and address. | |
+
+
diff --git a/modules/cloud-config-container/simple-nva/cloud-config.yaml b/modules/cloud-config-container/simple-nva/cloud-config.yaml
new file mode 100644
index 0000000000..f7dc2607f9
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/cloud-config.yaml
@@ -0,0 +1,38 @@
+#cloud-config
+
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+write_files:
+%{ for path, data in files }
+ - path: ${path}
+ owner: ${lookup(data, "owner", "root")}
+ permissions: ${lookup(data, "permissions", "0644")}
+ content: |
+ ${indent(6, data.content)}
+%{ endfor }
+
+bootcmd:
+ - systemctl start node-problem-detector
+
+runcmd:
+ - iptables --policy FORWARD ACCEPT
+%{if enable_health_checks ~}
+%{ for interface in network_interfaces ~}
+ - /var/run/nva/policy_based_routing.sh ${interface.name}
+%{ for route in interface.routes ~}
+ - ip route add ${route} via `curl http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/${interface.number}/gateway -H "Metadata-Flavor:Google"` dev ${interface.name}
+%{ endfor ~}
+%{ endfor ~}
+%{ endif ~}
diff --git a/modules/cloud-config-container/simple-nva/files/ipprefix_by_netmask.sh b/modules/cloud-config-container/simple-nva/files/ipprefix_by_netmask.sh
new file mode 100644
index 0000000000..405c164982
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/files/ipprefix_by_netmask.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# https://stackoverflow.com/questions/50413579/bash-convert-netmask-in-cidr-notation
+c=0 x=0$(printf '%o' $${1//./ })
+while [ $x -gt 0 ]; do
+ let c+=$((x % 2)) 'x>>=1'
+done
+echo $c
diff --git a/modules/cloud-config-container/simple-nva/files/policy_based_routing.sh b/modules/cloud-config-container/simple-nva/files/policy_based_routing.sh
new file mode 100644
index 0000000000..42ed0dcb15
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/files/policy_based_routing.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+IF_NAME=$1
+IF_NUMBER=$(echo $1 | sed -e s/eth//)
+IF_GW=$(curl http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/$IF_NUMBER/gateway -H "Metadata-Flavor: Google")
+IF_IP=$(curl http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/$IF_NUMBER/ip -H "Metadata-Flavor: Google")
+IF_NETMASK=$(curl http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/$IF_NUMBER/subnetmask -H "Metadata-Flavor: Google")
+IF_IP_PREFIX=$(/var/run/nva/ipprefix_by_netmask.sh $IF_NETMASK)
+IP_LB=$(ip r show table local | grep "$IF_NAME proto 66" | cut -f 2 -d " ")
+grep -qxF "$((200 + $IF_NUMBER)) hc-$IF_NAME" /etc/iproute2/rt_tables || echo "$((200 + $IF_NUMBER)) hc-$IF_NAME" >>/etc/iproute2/rt_tables
+ip route add $IF_GW src $IF_IP dev $IF_NAME table hc-$IF_NAME
+ip route add default via $IF_GW dev $IF_NAME table hc-$IF_NAME
+ip rule add from $IP_LB/32 table hc-$IF_NAME
diff --git a/modules/cloud-config-container/simple-nva/instance.tf b/modules/cloud-config-container/simple-nva/instance.tf
new file mode 120000
index 0000000000..bdef596b6d
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/instance.tf
@@ -0,0 +1 @@
+../instance.tf
\ No newline at end of file
diff --git a/modules/cloud-config-container/simple-nva/main.tf b/modules/cloud-config-container/simple-nva/main.tf
new file mode 100644
index 0000000000..5b9663bd3d
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/main.tf
@@ -0,0 +1,50 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+locals {
+ cloud_config = templatefile(local.template, merge({
+ files = local.files
+ enable_health_checks = var.enable_health_checks
+ network_interfaces = local.network_interfaces
+ }))
+
+ files = {
+ "/var/run/nva/ipprefix_by_netmask.sh" = {
+ content = file("${path.module}/files/ipprefix_by_netmask.sh")
+ owner = "root"
+ permissions = "0744"
+ }
+ "/var/run/nva/policy_based_routing.sh" = {
+ content = file("${path.module}/files/policy_based_routing.sh")
+ owner = "root"
+ permissions = "0744"
+ }
+ }
+
+ network_interfaces = [
+ for index, interface in var.network_interfaces : {
+ name = "eth${index}"
+ number = index
+ routes = interface.routes
+ }
+ ]
+
+ template = (
+ var.cloud_config == null
+ ? "${path.module}/cloud-config.yaml"
+ : var.cloud_config
+ )
+}
diff --git a/modules/cloud-config-container/simple-nva/outputs-instance.tf b/modules/cloud-config-container/simple-nva/outputs-instance.tf
new file mode 120000
index 0000000000..ea9e240458
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/outputs-instance.tf
@@ -0,0 +1 @@
+../outputs-instance.tf
\ No newline at end of file
diff --git a/modules/cloud-config-container/simple-nva/outputs.tf b/modules/cloud-config-container/simple-nva/outputs.tf
new file mode 100644
index 0000000000..7d8d41656b
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/outputs.tf
@@ -0,0 +1,20 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+output "cloud_config" {
+ description = "Rendered cloud-config file to be passed as user-data instance metadata."
+ value = local.cloud_config
+}
diff --git a/modules/cloud-config-container/simple-nva/variables-instance.tf b/modules/cloud-config-container/simple-nva/variables-instance.tf
new file mode 120000
index 0000000000..94af61e4dd
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/variables-instance.tf
@@ -0,0 +1 @@
+../variables-instance.tf
\ No newline at end of file
diff --git a/modules/cloud-config-container/simple-nva/variables.tf b/modules/cloud-config-container/simple-nva/variables.tf
new file mode 100644
index 0000000000..9307ddacec
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/variables.tf
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2022 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+variable "cloud_config" {
+ description = "Cloud config template path. If null default will be used."
+ type = string
+ default = null
+}
+
+variable "enable_health_checks" {
+ description = "Configures routing to enable responses to health check probes."
+ type = bool
+ default = false
+}
+
+variable "network_interfaces" {
+ description = "Network interfaces configuration."
+ type = list(object({
+ routes = optional(list(string))
+ }))
+}
diff --git a/modules/cloud-config-container/simple-nva/versions.tf b/modules/cloud-config-container/simple-nva/versions.tf
new file mode 100644
index 0000000000..8abac788a0
--- /dev/null
+++ b/modules/cloud-config-container/simple-nva/versions.tf
@@ -0,0 +1,29 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+terraform {
+ required_version = ">= 1.3.0"
+ required_providers {
+ google = {
+ source = "hashicorp/google"
+ version = ">= 4.32.0" # tftest
+ }
+ google-beta = {
+ source = "hashicorp/google-beta"
+ version = ">= 4.32.0" # tftest
+ }
+ }
+}
+
+