Skip to content

Commit f8dbdc2

Browse files
[ZT] Create tunnel using Terraform (#21780)
* create tunnel using Terraform * fix components * move tunnel token steps to partial * configure virtual networks * no longer need to input tunnel_secret in v5 * Apply suggestions from code review Co-authored-by: marciocloudflare <[email protected]> --------- Co-authored-by: marciocloudflare <[email protected]>
1 parent bc17de3 commit f8dbdc2

File tree

9 files changed

+223
-70
lines changed

9 files changed

+223
-70
lines changed

src/content/docs/cloudflare-one/connections/connect-networks/configure-tunnels/remote-tunnel-permissions.mdx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { TabItem, Tabs, Render } from "~/components";
99

1010
A remotely-managed tunnel only requires the tunnel token to run. Anyone with access to the token will be able to run the tunnel.
1111

12-
## View the tunnel token
12+
## Get the tunnel token
1313

1414
To get the token for a remotely-managed tunnel:
1515

@@ -35,6 +35,13 @@ Make a `GET` request to the [Cloudflare Tunnel token](/api/resources/zero_trust/
3535
```
3636

3737
</TabItem>
38+
39+
<TabItem label="Terraform (v5)">
40+
41+
<Render file="terraform/get-tunnel-token" product="cloudflare-one" />
42+
43+
</TabItem>
44+
3845
</Tabs>
3946

4047
## Rotate a token without service disruption

src/content/docs/cloudflare-one/connections/connect-networks/deployment-guides/ansible.mdx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,16 +90,11 @@ The following configuration will modify settings in your Cloudflare account.
9090

9191

9292
```tf
93-
# Generates a 32-byte secret for the tunnel.
94-
resource "random_bytes" "tunnel_secret" {
95-
byte_length = 32
96-
}
9793
9894
# Creates a new remotely-managed tunnel for the GCP VM.
9995
resource "cloudflare_zero_trust_tunnel_cloudflared" "gcp_tunnel" {
10096
account_id = var.cloudflare_account_id
10197
name = "Ansible GCP tunnel"
102-
tunnel_secret = random_bytes.tunnel_secret.base64
10398
}
10499
105100
# Reads the token used to run the tunnel on the server.

src/content/docs/cloudflare-one/connections/connect-networks/deployment-guides/terraform.mdx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,16 +133,11 @@ The following configuration will modify settings in your Cloudflare account.
133133
<TabItem label="Terraform (v5)">
134134

135135
```tf
136-
# Generates a 32-byte secret for the tunnel.
137-
resource "random_bytes" "tunnel_secret" {
138-
byte_length = 32
139-
}
140136
141137
# Creates a new remotely-managed tunnel for the GCP VM.
142138
resource "cloudflare_zero_trust_tunnel_cloudflared" "gcp_tunnel" {
143139
account_id = var.cloudflare_account_id
144140
name = "Terraform GCP tunnel"
145-
tunnel_secret = random_bytes.tunnel_secret.base64
146141
}
147142
148143
# Reads the token used to run the tunnel on the server.

src/content/docs/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel-api.mdx

Lines changed: 2 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ sidebar:
55
order: 2
66
---
77

8-
import { Tabs, TabItem } from "~/components";
8+
import { Render } from "~/components";
99

1010
Follow this guide to set up a Cloudflare Tunnel using the API.
1111

@@ -142,49 +142,7 @@ To configure Zero Trust policies and connect as a user, refer to [Connect privat
142142

143143
Install `cloudflared` on your server and run the tunnel using the `token` value obtained in [2. Create a tunnel](#2-create-a-tunnel). You can also get the tunnel token using the [Cloudflare Tunnel token](/api/resources/zero_trust/subresources/tunnels/subresources/cloudflared/subresources/token/methods/get/) endpoint.
144144

145-
<Tabs> <TabItem label="Linux">
146-
147-
1. [Download and install](https://pkg.cloudflare.com/index.html) `cloudflared`.
148-
149-
2. Run the following command:
150-
151-
```sh
152-
sudo cloudflared service install <tunnel-token>
153-
```
154-
155-
</TabItem> <TabItem label="Windows">
156-
157-
1. [Download and install](/cloudflare-one/connections/connect-networks/downloads/#windows) `cloudflared`.
158-
159-
2. Open Command Prompt as administrator.
160-
161-
3. Run the following command:
162-
163-
```txt
164-
cloudflared.exe service install <tunnel-token>
165-
```
166-
167-
</TabItem> <TabItem label="macOS">
168-
169-
1. [Download and install](/cloudflare-one/connections/connect-networks/downloads/#macos) `cloudflared`.
170-
171-
2. Run the following command:
172-
173-
```sh
174-
sudo cloudflared service install <tunnel-token>
175-
```
176-
177-
</TabItem> <TabItem label="Docker">
178-
179-
1. Open a terminal window.
180-
181-
2. Run the following command:
182-
183-
```sh
184-
docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <tunnel-token>
185-
```
186-
187-
</TabItem> </Tabs>
145+
<Render file="tunnel/install-and-run-tunnel" product="cloudflare-one" />
188146

189147
## 5. Verify tunnel status
190148

src/content/docs/cloudflare-one/connections/connect-networks/private-net/cloudflared/tunnel-virtual-networks.mdx

Lines changed: 71 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ Here are a few scenarios where virtual networks may prove useful:
4646
The following example demonstrates how to add two overlapping IP routes to Cloudflare (`10.128.0.1/32` staging and `10.128.0.1/32` production).
4747

4848
<Tabs>
49-
<TabItem label="Dashboard">
49+
<TabItem label="Dashboard">
5050
To route overlapping IPs over virtual networks:
5151

5252
1. First, create two unique virtual networks:
@@ -67,10 +67,71 @@ The following example demonstrates how to add two overlapping IP routes to Cloud
6767

6868
We now have two overlapping IP addresses routed over `staging-vnet` and `production-vnet` respectively. You can use the Cloudflare WARP client to [switch between virtual networks](#connect-to-a-virtual-network).
6969

70-
</TabItem>
70+
</TabItem>
7171

72-
<TabItem label="cli">
73-
To route overlapping IPs over virtual networks:
72+
<TabItem label="Terraform (v5)">
73+
To route overlapping IPs over virtual networks:
74+
1. Add the following permission to your [`cloudflare_api_token`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/api_token):
75+
- `Cloudflare Tunnel Write`
76+
77+
2. Create two unique virtual networks:
78+
```tf
79+
resource "cloudflare_zero_trust_tunnel_cloudflared_virtual_network" "staging_vnet" {
80+
account_id = var.cloudflare_account_id
81+
name = "staging-vnet"
82+
comment = "Staging virtual network"
83+
is_default = false
84+
}
85+
86+
resource "cloudflare_zero_trust_tunnel_cloudflared_virtual_network" "production_vnet" {
87+
account_id = var.cloudflare_account_id
88+
name = "production-vnet"
89+
comment = "Production virtual network"
90+
is_default = false
91+
}
92+
```
93+
94+
3. Create a Cloudflare Tunnel for each private network:
95+
```tf
96+
resource "cloudflare_zero_trust_tunnel_cloudflared" "staging_tunnel" {
97+
account_id = var.cloudflare_account_id
98+
name = "Staging tunnel"
99+
config_src = "cloudflare"
100+
}
101+
102+
resource "cloudflare_zero_trust_tunnel_cloudflared" "production_tunnel" {
103+
account_id = var.cloudflare_account_id
104+
name = "Production tunnel"
105+
config_src = "cloudflare"
106+
}
107+
```
108+
109+
4. Route `10.128.0.1/32` through `Staging tunnel` and assign it to `staging-vnet`. Route `10.128.0.1/32` through `Production tunnel` and assign it to `production-vnet`.
110+
111+
```tf
112+
resource "cloudflare_zero_trust_tunnel_cloudflared_route" "staging_tunnel_route" {
113+
account_id = var.cloudflare_account_id
114+
tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.staging_tunnel.id
115+
network = "10.128.0.1/32"
116+
comment = "Staging tunnel route"
117+
virtual_network_id = cloudflare_zero_trust_tunnel_cloudflared_virtual_network.staging_vnet.id
118+
}
119+
120+
resource "cloudflare_zero_trust_tunnel_cloudflared_route" "production_tunnel_route" {
121+
account_id = var.cloudflare_account_id
122+
tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.production_tunnel.id
123+
network = "10.128.0.1/32"
124+
comment = "Production tunnel route"
125+
virtual_network_id = cloudflare_zero_trust_tunnel_cloudflared_virtual_network.production_vnet.id
126+
}
127+
```
128+
5. [Get the token](/cloudflare-one/connections/connect-networks/configure-tunnels/remote-tunnel-permissions/#get-the-tunnel-token) for each tunnel.
129+
130+
6. Using the tunnel tokens, run `Staging tunnel` in your staging environment and run `Production tunnel` in your production environment. Refer to [Install and run the tunnel](/cloudflare-one/connections/connect-networks/get-started/create-remote-tunnel-api/#4-install-and-run-the-tunnel).
131+
</TabItem>
132+
133+
<TabItem label="Locally-managed tunnels">
134+
To route overlapping IPs over virtual networks for [locally-managed tunnels](/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/):
74135

75136
1. Create a tunnel for each private network:
76137

@@ -113,10 +174,9 @@ The following example demonstrates how to add two overlapping IP routes to Cloud
113174
cloudflared tunnel vnet list
114175
```
115176

116-
{/* Commenting out notes within tabs for now
117177
:::note[Default virtual network]
118178
All accounts come pre-configured with a virtual network named `default`. You can choose a new default by typing `cloudflared tunnel vnet update --default <virtual-network-name>`.
119-
::: */}
179+
:::
120180

121181
4. Configure your tunnels with the IP/CIDR range of your private networks, and assign the tunnels to their respective virtual networks.
122182

@@ -162,7 +222,7 @@ The following example demonstrates how to add two overlapping IP routes to Cloud
162222
## Delete a virtual network
163223

164224
<Tabs>
165-
<TabItem label="Dashboard">
225+
<TabItem label="Dashboard">
166226
To delete a virtual network:
167227

168228
1. In [Zero Trust](https://one.dash.cloudflare.com/), go to **Networks** > **Tunnels** and ensure that no IP routes are assigned to the virtual network you are trying to delete. If your virtual network is in use, delete the route or reassign it to a different virtual network.
@@ -175,10 +235,10 @@ The following example demonstrates how to add two overlapping IP routes to Cloud
175235

176236
You can optionally delete the tunnel associated with your virtual network.
177237

178-
</TabItem>
238+
</TabItem>
179239

180-
<TabItem label="cli">
181-
To delete a virtual network:
240+
<TabItem label="Locally-managed tunnels">
241+
To delete a virtual network for [locally-managed tunnels](/cloudflare-one/connections/connect-networks/do-more-with-tunnels/local-management/):
182242

183243
1. Delete all IP routes in the virtual network. For example,
184244

@@ -200,7 +260,7 @@ The following example demonstrates how to add two overlapping IP routes to Cloud
200260

201261
You can verify that the virtual network was successfully deleted by typing `cloudflared tunnel vnet list`.
202262

203-
</TabItem>
263+
</TabItem>
204264
</Tabs>
205265

206266
## Connect to a virtual network

src/content/docs/learning-paths/replace-vpn/connect-private-network/cloudflared.mdx

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,61 @@ sidebar:
66

77
---
88

9-
import { Render } from "~/components"
9+
import { Render, Tabs, TabItem } from "~/components"
1010

1111
Cloudflare Tunnel is an outbound-only daemon service that can run on nearly any host machine and proxies local traffic once validated from the Cloudflare network. User traffic initiated from the WARP endpoint client onramps to Cloudflare, passes down your Cloudflare Tunnel connections, and terminates automatically in your local network. Traffic reaching your internal applications or services will carry the local source IP address of the host machine running the `cloudflared` daemon.
1212

1313
## Create a tunnel
1414

1515
To connect your private network:
1616

17+
<Tabs syncKey="dashPlusAPI">
18+
19+
<TabItem label="Dashboard">
20+
1721
<Render file="tunnel/create-tunnel" product="cloudflare-one" />
1822

1923
9. In the **Private Networks** tab, enter the CIDR of your private network (for example, `10.0.0.0/8`).
2024

2125
10. Select **Save tunnel**.
2226

27+
</TabItem>
28+
<TabItem label="Terraform (v5)">
29+
30+
1. Add the following permission to your [`cloudflare_api_token`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/api_token):
31+
- `Cloudflare Tunnel Write`
32+
33+
2. Create a tunnel using the [`cloudflare_zero_trust_tunnel_cloudflare`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared) resource.
34+
35+
```tf
36+
resource "cloudflare_zero_trust_tunnel_cloudflared" "example_tunnel" {
37+
account_id = var.cloudflare_account_id
38+
name = "Example tunnel"
39+
config_src = "cloudflare"
40+
}
41+
```
42+
43+
3. Route the CIDR of your private network through the tunnel using the [`cloudflare_zero_trust_tunnel_cloudflared_route`](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zero_trust_tunnel_cloudflared_route) resource:
44+
45+
```tf
46+
resource "cloudflare_zero_trust_tunnel_cloudflared_route" "example_tunnel_route" {
47+
account_id = var.cloudflare_account_id
48+
tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.example_tunnel.id
49+
network = "10.0.0.0/8"
50+
comment = "Example tunnel route"
51+
}
52+
```
53+
54+
4. Get the [token](/cloudflare-one/connections/connect-networks/configure-tunnels/remote-tunnel-permissions/) used to run the tunnel:
55+
<Render file="terraform/get-tunnel-token" product="cloudflare-one" />
56+
57+
5. Install `cloudflared` on a host machine in your private network and run the tunnel:
58+
59+
<Render file="tunnel/install-and-run-tunnel" product="cloudflare-one" />
60+
61+
</TabItem>
62+
</Tabs>
63+
2364
All internal applications and services in this IP range are now connected to Cloudflare.
2465

2566
:::note
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
{}
3+
4+
---
5+
6+
import { Details } from "~/components"
7+
8+
```tf
9+
data "cloudflare_zero_trust_tunnel_cloudflared_token" "tunnel_token" {
10+
account_id = var.cloudflare_account_id
11+
tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.example_tunnel.id
12+
}
13+
```
14+
15+
If your host machine is not managed in Terraform or you want to install the tunnel manually, you can output the token value to the CLI.
16+
<Details header="Example: Output to CLI" open = {false}>
17+
1. Output the tunnel token to the Terraform state file:
18+
```tf
19+
output "tunnel_token" {
20+
value = data.cloudflare_zero_trust_tunnel_cloudflared_token.tunnel_token.token
21+
sensitive = true
22+
}
23+
```
24+
2. Apply the configuration:
25+
```sh
26+
terraform apply
27+
```
28+
3. Read the tunnel token:
29+
```sh
30+
terraform output -raw tunnel_token
31+
```
32+
```sh output
33+
eyJhIj...
34+
```
35+
36+
</Details>
37+
38+
Alternatively, pass `data.cloudflare_zero_trust_tunnel_cloudflared_token.tunnel_token.token` directly into your host's Terraform configuration or store the token in your secret management tool.
39+
40+
<Details header="Example: Store in HashiCorp Vault" open = {false}>
41+
```tf
42+
resource "vault_generic_secret" "tunnel_token" {
43+
path = "kv/cloudflare/tunnel_token"
44+
45+
data_json = jsonencode({
46+
"TUNNEL_TOKEN" = data.cloudflare_zero_trust_tunnel_cloudflared_token.tunnel_token.token
47+
})
48+
}
49+
```
50+
</Details>

src/content/partials/cloudflare-one/terraform/providers-v5.mdx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ terraform {
1212
google = {
1313
source = "hashicorp/google"
1414
}
15-
random = {
16-
source = "hashicorp/random"
17-
}
1815
}
1916
required_version = ">= 1.2"
2017
}

0 commit comments

Comments
 (0)