COS based simple networking appliance (#846)
This commit is contained in:
parent
8e6e365d1d
commit
5950797385
|
@ -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
|
||||
}
|
||||
}
|
||||
```
|
||||
<!-- BEGIN TFDOC -->
|
||||
|
||||
## Variables
|
||||
|
||||
| name | description | type | required | default |
|
||||
|---|---|:---:|:---:|:---:|
|
||||
| [network_interfaces](variables.tf#L29) | Network interfaces configuration. | <code title="list(object({ routes = optional(list(string)) }))">list(object({…}))</code> | ✓ | |
|
||||
| [cloud_config](variables.tf#L17) | Cloud config template path. If null default will be used. | <code>string</code> | | <code>null</code> |
|
||||
| [enable_health_checks](variables.tf#L23) | Configures routing to enable responses to health check probes. | <code>bool</code> | | <code>false</code> |
|
||||
| [test_instance](variables-instance.tf#L17) | Test/development instance attributes, leave null to skip creation. | <code title="object({ project_id = string zone = string name = string type = string network = string subnetwork = string })">object({…})</code> | | <code>null</code> |
|
||||
| [test_instance_defaults](variables-instance.tf#L30) | Test/development instance defaults used for optional configuration. If image is null, COS stable will be used. | <code title="object({ disks = map(object({ read_only = bool size = number })) image = string metadata = map(string) nat = bool service_account_roles = list(string) tags = list(string) })">object({…})</code> | | <code title="{ disks = {} image = null metadata = {} nat = false service_account_roles = [ "roles/logging.logWriter", "roles/monitoring.metricWriter" ] tags = ["ssh"] }">{…}</code> |
|
||||
|
||||
## 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. | |
|
||||
|
||||
<!-- END TFDOC -->
|
|
@ -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 ~}
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
../instance.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
|
||||
)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
../outputs-instance.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
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
../variables-instance.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))
|
||||
}))
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue