Skip to content
This repository was archived by the owner on Feb 14, 2024. It is now read-only.

Commit 0b2fd7e

Browse files
authored
feat(module/vpn): VPN module for GCP VM-Series deployments (#219)
1 parent 3061b2d commit 0b2fd7e

7 files changed

Lines changed: 543 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,4 +59,4 @@ terraform.tfvars.json
5959
# password, private keys, and other secrets. But allow example files.
6060
*.tfvars
6161
*.tfvars.json
62-
!*/example.tfvars
62+
!**/example.tfvars

modules/vpn/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
validate:
2+
@../../makefile.sh validate

modules/vpn/README.md

Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# VPN
2+
3+
This module makes it easy to deploy either GCP-to-GCP or GCP-to-On-prem VPN using [Cloud HA VPN](https://cloud.google.com/vpn/docs/concepts/overview#ha-vpn) including HA VPN Gateway itself. VPN includes one or more VPN instances (connections).
4+
5+
Each created VPN instance is represented by 1..4 VPN tunnels that taget remote VPN gateway(s) located in a single remote location. Remote VPN gateway(s) might have singe IP address (`redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"`) or 2 IP addresses (`redundancy_type = "TWO_IPS_REDUNDANCY"`).
6+
7+
## Example
8+
9+
```hcl
10+
data "google_compute_network" "test" {
11+
name = "<network_name>"
12+
project = "<project_id>"
13+
}
14+
15+
module "vpn" {
16+
source = "../../../modules/vpn"
17+
18+
project = "<project_id>"
19+
region = "us-central1"
20+
21+
vpn_gateway_name = "my-test-gateway"
22+
router_name = "my-test-router"
23+
network = data.google_compute_network.test.self_link
24+
25+
vpn_config = {
26+
router_asn = 65000
27+
local_network = "vpc-vpn"
28+
29+
router_advertise_config = {
30+
ip_ranges = {
31+
"10.10.0.0/16" : "GCP range 1"
32+
}
33+
mode = "CUSTOM"
34+
groups = null
35+
}
36+
37+
instances = {
38+
vpn-to-onprem1 = {
39+
name = "vpn-to-onprem1",
40+
peer_external_gateway = {
41+
redundancy_type = "SINGLE_IP_INTERNALLY_REDUNDANT"
42+
interfaces = [{
43+
id = 0
44+
ip_address = "1.1.1.1"
45+
}]
46+
},
47+
tunnels = {
48+
remote0 = {
49+
bgp_peer = {
50+
address = "169.254.1.2"
51+
asn = 65001
52+
}
53+
bgp_peer_options = null
54+
bgp_session_range = "169.254.1.1/30"
55+
ike_version = 2
56+
vpn_gateway_interface = 0
57+
peer_external_gateway_interface = 0
58+
shared_secret = "secret"
59+
}
60+
remote1 = {
61+
bgp_peer = {
62+
address = "169.254.1.6"
63+
asn = 65001
64+
}
65+
bgp_peer_options = null
66+
bgp_session_range = "169.254.1.5/30"
67+
ike_version = 2
68+
vpn_gateway_interface = 1
69+
peer_external_gateway_interface = null
70+
shared_secret = "secret"
71+
}
72+
}
73+
}
74+
vpn-to-onprem2 = {
75+
name = "vpn-to-onprem2",
76+
peer_external_gateway = {
77+
redundancy_type = "TWO_IPS_REDUNDANCY"
78+
interfaces = [{
79+
id = 0
80+
ip_address = "3.3.3.3"
81+
}, {
82+
id = 1
83+
ip_address = "4.4.4.4"
84+
}]
85+
},
86+
tunnels = {
87+
remote0 = {
88+
bgp_peer = {
89+
address = "169.254.2.2"
90+
asn = 65002
91+
}
92+
bgp_peer_options = null
93+
bgp_session_range = "169.254.2.1/30"
94+
ike_version = 2
95+
vpn_gateway_interface = 0
96+
peer_external_gateway_interface = 0
97+
shared_secret = "secret"
98+
}
99+
remote1 = {
100+
bgp_peer = {
101+
address = "169.254.2.6"
102+
asn = 65002
103+
}
104+
bgp_peer_options = null
105+
bgp_session_range = "169.254.2.5/30"
106+
ike_version = 2
107+
vpn_gateway_interface = 1
108+
peer_external_gateway_interface = 1
109+
shared_secret = "secret"
110+
}
111+
}
112+
}
113+
vpn-to-gcp = {
114+
name = "vpn-to-gcp",
115+
116+
peer_gcp_gateway = "https://www.googleapis.com/compute/v1/projects/<remote_project_id>/regions/<region>/vpnGateways/<remote_vpn_gw_name>"
117+
118+
tunnels = {
119+
remote0 = {
120+
bgp_peer = {
121+
address = "169.254.3.2"
122+
asn = 65003
123+
}
124+
bgp_peer_options = null
125+
bgp_session_range = "169.254.3.1/30"
126+
ike_version = 2
127+
vpn_gateway_interface = 0
128+
peer_external_gateway_interface = null
129+
shared_secret = "secret"
130+
}
131+
remote1 = {
132+
bgp_peer = {
133+
address = "169.254.3.6"
134+
asn = 65003
135+
}
136+
bgp_peer_options = null
137+
bgp_session_range = "169.254.3.5/30"
138+
ike_version = 2
139+
vpn_gateway_interface = 1
140+
peer_external_gateway_interface = 1
141+
shared_secret = "secret"
142+
}
143+
}
144+
}
145+
}
146+
}
147+
}
148+
```
149+
150+
## Reference
151+
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
152+
### Requirements
153+
154+
| Name | Version |
155+
|------|---------|
156+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.2, < 2.0 |
157+
| <a name="requirement_google"></a> [google](#requirement\_google) | >= 4.58 |
158+
159+
### Providers
160+
161+
| Name | Version |
162+
|------|---------|
163+
| <a name="provider_google"></a> [google](#provider\_google) | >= 4.58 |
164+
| <a name="provider_google-beta"></a> [google-beta](#provider\_google-beta) | n/a |
165+
| <a name="provider_random"></a> [random](#provider\_random) | n/a |
166+
167+
### Modules
168+
169+
No modules.
170+
171+
### Resources
172+
173+
| Name | Type |
174+
|------|------|
175+
| [google-beta_google_compute_vpn_tunnel.tunnels](https://registry.terraform.io/providers/hashicorp/google-beta/latest/docs/resources/google_compute_vpn_tunnel) | resource |
176+
| [google_compute_external_vpn_gateway.external_gateway](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_external_vpn_gateway) | resource |
177+
| [google_compute_ha_vpn_gateway.ha_gateway](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_ha_vpn_gateway) | resource |
178+
| [google_compute_router.router](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_router) | resource |
179+
| [google_compute_router_interface.router_interface](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_router_interface) | resource |
180+
| [google_compute_router_peer.bgp_peer](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_router_peer) | resource |
181+
| [random_id.secret](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource |
182+
183+
### Inputs
184+
185+
| Name | Description | Type | Default | Required |
186+
|------|-------------|------|---------|:--------:|
187+
| <a name="input_labels"></a> [labels](#input\_labels) | Labels for VPN components | `map(string)` | `{}` | no |
188+
| <a name="input_network"></a> [network](#input\_network) | VPC network ID that should be used for deployment | `string` | n/a | yes |
189+
| <a name="input_project"></a> [project](#input\_project) | n/a | `string` | `null` | no |
190+
| <a name="input_region"></a> [region](#input\_region) | Region to deploy VPN gateway in | `string` | n/a | yes |
191+
| <a name="input_router_name"></a> [router\_name](#input\_router\_name) | Cloud router name. The router is created by the module | `string` | `null` | no |
192+
| <a name="input_vpn_config"></a> [vpn\_config](#input\_vpn\_config) | VPN configuration from GCP to on-prem or from GCP to GCP.<br>If you'd like secrets to be randomly generated set `shared_secret` to empty string ("").<br><br>Example:<pre>vpn_config = {<br> router_asn = 65000<br> local_network = "vpc-vpn"<br><br> router_advertise_config = {<br> ip_ranges = {<br> "10.10.0.0/16" : "GCP range 1"<br> }<br> mode = "CUSTOM"<br> groups = null<br> }<br><br> instances = {<br> vpn-to-onprem = {<br> name = "vpn-to-onprem",<br> peer_external_gateway = {<br> redundancy_type = "TWO_IPS_REDUNDANCY"<br> interfaces = [{<br> id = 0<br> ip_address = "1.1.1.1"<br> }, {<br> id = 1<br> ip_address = "2.2.2.2"<br> }]<br> },<br> tunnels = {<br> remote0 = {<br> bgp_peer = {<br> address = "169.254.1.2"<br> asn = 65001<br> }<br> bgp_peer_options = null<br> bgp_session_range = "169.254.1.1/30"<br> ike_version = 2<br> vpn_gateway_interface = 0<br> peer_external_gateway_interface = 0<br> shared_secret = "secret"<br> }<br> remote1 = {<br> bgp_peer = {<br> address = "169.254.1.6"<br> asn = 65001<br> }<br> bgp_peer_options = null<br> bgp_session_range = "169.254.1.5/30"<br> ike_version = 2<br> vpn_gateway_interface = 1<br> peer_external_gateway_interface = 1<br> shared_secret = "secret"<br> }<br> }<br> }<br> }<br>}</pre> | `any` | n/a | yes |
193+
| <a name="input_vpn_gateway_name"></a> [vpn\_gateway\_name](#input\_vpn\_gateway\_name) | VPN gateway name. Gateway created by the module | `string` | n/a | yes |
194+
195+
### Outputs
196+
197+
| Name | Description |
198+
|------|-------------|
199+
| <a name="output_random_secret"></a> [random\_secret](#output\_random\_secret) | HA VPN IPsec tunnels secret that has been randomly generated |
200+
| <a name="output_vpn_gw_local_address_1"></a> [vpn\_gw\_local\_address\_1](#output\_vpn\_gw\_local\_address\_1) | HA VPN gateway IP address 1 |
201+
| <a name="output_vpn_gw_local_address_2"></a> [vpn\_gw\_local\_address\_2](#output\_vpn\_gw\_local\_address\_2) | HA VPN gateway IP address 2 |
202+
| <a name="output_vpn_gw_name"></a> [vpn\_gw\_name](#output\_vpn\_gw\_name) | HA VPN gateway name |
203+
| <a name="output_vpn_gw_self_link"></a> [vpn\_gw\_self\_link](#output\_vpn\_gw\_self\_link) | HA VPN gateway self\_link |
204+
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
205+
<!-- BEGIN_TF_DOCS -->
206+
## Requirements
207+
208+
| Name | Version |
209+
|------|---------|
210+
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.2, < 2.0 |
211+
| <a name="requirement_google"></a> [google](#requirement\_google) | == 4.58 |
212+
213+
## Providers
214+
215+
| Name | Version |
216+
|------|---------|
217+
| <a name="provider_google"></a> [google](#provider\_google) | == 4.58 |
218+
219+
## Modules
220+
221+
| Name | Source | Version |
222+
|------|--------|---------|
223+
| <a name="module_vpn_ha"></a> [vpn\_ha](#module\_vpn\_ha) | terraform-google-modules/vpn/google | 3.0.1 |
224+
225+
## Resources
226+
227+
| Name | Type |
228+
|------|------|
229+
| [google_compute_ha_vpn_gateway.ha_gateway](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_ha_vpn_gateway) | resource |
230+
231+
## Inputs
232+
233+
| Name | Description | Type | Default | Required |
234+
|------|-------------|------|---------|:--------:|
235+
| <a name="input_project"></a> [project](#input\_project) | n/a | `string` | `null` | no |
236+
| <a name="input_region"></a> [region](#input\_region) | Region to deploy VPN gateway in | `string` | n/a | yes |
237+
| <a name="input_vpc_network_id"></a> [vpc\_network\_id](#input\_vpc\_network\_id) | VPC network ID that should be used for deployment | `string` | n/a | yes |
238+
| <a name="input_vpn"></a> [vpn](#input\_vpn) | VPN configuration from GCP to on-prem or from GCP to GCP.<br>If you'd like secrets to be randomly generated set `shared_secret` to empty string ("").<br><br>Example:<pre>vpn = {<br>router_asn = 65000<br>local_network = "vpc-vpn"<br><br>router_advertise_config = {<br> ip_ranges = {<br> "10.10.0.0/16" : "GCP range 1"<br> }<br> mode = "CUSTOM"<br> groups = null<br>}<br><br>instances = {<br> vpn-to-onprem = {<br> name = "vpn-to-onprem",<br> peer_external_gateway = {<br> redundancy_type = "TWO_IPS_REDUNDANCY"<br> interfaces = [{<br> id = 0<br> ip_address = "1.1.1.1"<br> }, {<br> id = 1<br> ip_address = "2.2.2.2"<br> }]<br> },<br> tunnels = {<br> remote0 = {<br> bgp_peer = {<br> address = "169.254.1.2"<br> asn = 65001<br> }<br> bgp_peer_options = null<br> bgp_session_range = "169.254.1.1/30"<br> ike_version = 2<br> vpn_gateway_interface = 0<br> peer_external_gateway_interface = 0<br> shared_secret = "secret"<br> }<br> remote1 = {<br> bgp_peer = {<br> address = "169.254.1.6"<br> asn = 65001<br> }<br> bgp_peer_options = null<br> bgp_session_range = "169.254.1.5/30"<br> ike_version = 2<br> vpn_gateway_interface = 1<br> peer_external_gateway_interface = 1<br> shared_secret = "secret"<br> }<br> }<br> }<br>}</pre> | `any` | n/a | yes |
239+
| <a name="input_vpn_gateway_name"></a> [vpn\_gateway\_name](#input\_vpn\_gateway\_name) | VPN gateway name | `string` | n/a | yes |
240+
241+
## Outputs
242+
243+
| Name | Description |
244+
|------|-------------|
245+
| <a name="output_local_ipsec_gw2_address_2"></a> [local\_ipsec\_gw2\_address\_2](#output\_local\_ipsec\_gw2\_address\_2) | HA VPN gateway IP address 2 |
246+
| <a name="output_local_ipsec_gw_address_1"></a> [local\_ipsec\_gw\_address\_1](#output\_local\_ipsec\_gw\_address\_1) | HA VPN gateway IP address 1 |
247+
| <a name="output_random_secrets_map"></a> [random\_secrets\_map](#output\_random\_secrets\_map) | HA VPN IPsec tunnels secrets that were randomly generated |
248+
| <a name="output_vpn_gateway_name"></a> [vpn\_gateway\_name](#output\_vpn\_gateway\_name) | HA VPN gateway name |
249+
| <a name="output_vpn_gateway_self_link"></a> [vpn\_gateway\_self\_link](#output\_vpn\_gateway\_self\_link) | HA VPN gateway self\_link |
250+
<!-- END_TF_DOCS -->

0 commit comments

Comments
 (0)