@@ -74,32 +74,7 @@ You will need to declare the [providers](https://registry.terraform.io/browse/pr
7474
75752 . Add the following providers to ` providers.tf ` . The ` random ` provider is used to generate a tunnel secret.
7676
77- ``` txt
78- terraform {
79- required_providers {
80- cloudflare = {
81- source = "cloudflare/cloudflare"
82- }
83- google = {
84- source = "hashicorp/google"
85- }
86- random = {
87- source = "hashicorp/random"
88- }
89- }
90- required_version = ">= 0.13"
91- }
92-
93- # Providers
94- provider "cloudflare" {
95- api_token = var.cloudflare_token
96- }
97- provider "google" {
98- project = var.gcp_project_id
99- }
100- provider "random" {
101- }
102- ```
77+ <Render file = " terraform/providers-v5" />
10378
10479### Configure Cloudflare resources
10580
@@ -113,30 +88,94 @@ The following configuration will modify settings in your Cloudflare account.
11388
114892 . Add the following resources to ` Cloudflare-config.tf ` :
11590
116- ``` txt
117- # Generates a 64-character secret for the tunnel.
118- # Using `random_password` means the result is treated as sensitive and, thus,
119- # not displayed in console output. Refer to: https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password
120- resource "random_password" "tunnel_secret" {
121- length = 64
122- }
12391
124- # Creates a new locally-managed tunnel for the GCP VM.
125- resource "cloudflare_tunnel" "auto_tunnel" {
126- account_id = var.cloudflare_account_id
127- name = "Ansible GCP tunnel"
128- secret = base64sha256(random_password.tunnel_secret.result)
129- }
130-
131- # Creates the CNAME record that routes ssh_app.${var.cloudflare_zone} to the tunnel.
132- resource "cloudflare_record" "ssh_app" {
133- zone_id = var.cloudflare_zone_id
134- name = "ssh_app"
135- value = "${cloudflare_argo_tunnel.auto_tunnel.id}.cfargotunnel.com"
136- type = "CNAME"
137- proxied = true
138- }
139- ```
92+ ``` tf
93+ # Generates a 32-byte secret for the tunnel.
94+ resource "random_bytes" "tunnel_secret" {
95+ byte_length = 32
96+ }
97+
98+ # Creates a new remotely-managed tunnel for the GCP VM.
99+ resource "cloudflare_zero_trust_tunnel_cloudflared" "gcp_tunnel" {
100+ account_id = var.cloudflare_account_id
101+ name = "Example GCP tunnel"
102+ tunnel_secret = random_bytes.tunnel_secret.base64
103+ }
104+
105+ # Reads the token used to run the tunnel on the server.
106+ data "cloudflare_zero_trust_tunnel_cloudflared_token" "gcp_tunnel_token" {
107+ account_id = var.cloudflare_account_id
108+ tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id
109+ }
110+
111+ # Creates the CNAME record that routes http_app.${var.cloudflare_zone} to the tunnel.
112+ resource "cloudflare_dns_record" "http_app" {
113+ zone_id = var.cloudflare_zone_id
114+ name = "http_app"
115+ content = "${cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id}.cfargotunnel.com"
116+ type = "CNAME"
117+ ttl = 1
118+ proxied = true
119+ }
120+
121+ # Configures tunnel with a public hostname route for clientless access.
122+ resource "cloudflare_zero_trust_tunnel_cloudflared_config" "gcp_tunnel_config" {
123+ tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id
124+ account_id = var.cloudflare_account_id
125+ config = {
126+ ingress = [
127+ {
128+ hostname = "http_app.${var.cloudflare_zone}"
129+ service = "http://localhost:80"
130+ },
131+ {
132+ service = "http_status:404"
133+ }
134+ ]
135+ }
136+ }
137+
138+ # (Optional) Routes internal IP of GCP instance through the tunnel for private network access using WARP.
139+ resource "cloudflare_zero_trust_tunnel_cloudflared_route" "example_tunnel_route" {
140+ account_id = var.cloudflare_account_id
141+ tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id
142+ network = google_compute_instance.http_server.network_interface.0.network_ip
143+ comment = "Example tunnel route"
144+ }
145+
146+ # Creates a reusable Access policy.
147+ resource "cloudflare_zero_trust_access_policy" "allow_emails" {
148+ account_id = var.cloudflare_account_id
149+ name = "Allow email addresses"
150+ decision = "allow"
151+ include = [
152+ {
153+ email = {
154+ email = var.cloudflare_email
155+ }
156+ },
157+ {
158+ email_domain = {
159+ domain = "@example.com"
160+ }
161+ }
162+ ]
163+ }
164+
165+ # Creates an Access application to control who can connect to the public hostname.
166+ resource "cloudflare_zero_trust_access_application" "http_app" {
167+ account_id = var.cloudflare_account_id
168+ type = "self_hosted"
169+ name = "Access application for http_app.${var.cloudflare_zone}"
170+ domain = "http_app.${var.cloudflare_zone}"
171+ policies = [
172+ {
173+ id = cloudflare_zero_trust_access_policy.allow_emails.id
174+ precedence = 1
175+ }
176+ ]
177+ }
178+ ```
140179
141180### Configure GCP resources
142181
@@ -219,20 +258,20 @@ The following Terraform resource exports the tunnel ID and other variables to `t
219258
2202592 . Copy and paste the following content into ` export.tf ` :
221260
222- ``` txt
223- resource "local_file" "tf_ansible_vars_file" {
224- content = <<-DOC
225- # Ansible vars_file containing variable values from Terraform.
226- tunnel_id: ${cloudflare_argo_tunnel.auto_tunnel .id}
227- account: ${var.cloudflare_account_id}
228- tunnel_name: ${cloudflare_argo_tunnel.auto_tunnel .name}
229- secret : ${random_id.tunnel_secret.b64_std }
230- zone: ${var.cloudflare_zone}
231- DOC
232-
233- filename = "./tf_ansible_vars_file.yml"
234- }
235- ```
261+ ``` tf
262+ resource "local_file" "tf_ansible_vars_file" {
263+ content = <<-DOC
264+ # Ansible vars_file containing variable values from Terraform.
265+ tunnel_id: ${cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel .id}
266+ account: ${var.cloudflare_account_id}
267+ tunnel_name: ${cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel .name}
268+ tunnel_token : ${data.cloudflare_zero_trust_tunnel_cloudflared_token.gcp_tunnel_token.token }
269+ zone: ${var.cloudflare_zone}
270+ DOC
271+
272+ filename = "./tf_ansible_vars_file.yml"
273+ }
274+ ```
236275
237276## 5. Create the Ansible playbook
238277
0 commit comments