← Cloudflare Tunnel / tunnel / deployment-guides
Terraform
Terraform ↗ je nástroj infrastructure as code, který vám umožňuje definovat tunely a spravovat je spolu s ostatní infrastrukturou. Tento návod nasadí:
- Virtuální stroj GCP, na kterém běží webový server
- Cloudflare Tunnel, který zpřístupní server přes internet
- (Volitelné) Zásada Cloudflare Access, která určuje, kdo se může připojit
Předpoklady
1. Nainstalujte Terraform
Viz Průvodce instalací Terraformu ↗ pro váš operační systém.
2. Nainstalujte gcloud CLI
-
Instalace gcloud CLI ↗ tak, aby Terraform mohl pracovat s vaším účtem GCP.
-
Ověřte se pomocí CLI spuštěním:
gcloud auth application-default login
3. Vytvořte token Cloudflare API
Vytvořte token API tak, aby Terraform mohl pracovat s vaším účtem Cloudflare. Token by měl obsahovat minimálně následující oprávnění:
| Typ | Položka | Oprávnění |
|---|---|---|
| Účet | Cloudflare Tunnel | Úprava |
| Účet | Access: aplikace a zásady | Úprava |
| Zóna | DNS | Úprava |
4. Vytvořte konfigurační adresář
Terraform funguje prostřednictvím pracovního adresáře, který obsahuje konfigurační soubory. Konfiguraci můžete uložit do více souborů nebo jen do jednoho: Terraform vyhodnotí všechny konfigurační soubory v adresáři, jako by byly v jediném dokumentu.
-
Vytvořte složku pro konfiguraci Terraform:
mkdir cloudflare-tf -
Přejděte do adresáře:
cd cloudflare-tf
5. Vytvořte konfigurační soubory Terraform
Definujte vstupní proměnné
Následující proměnné budou předány do konfigurace GCP a Cloudflare.
-
Ve svém konfiguračním adresáři vytvořte
.tfsoubor:touch variables.tf -
Otevřete soubor v textovém editoru a zkopírujte a vložte následující:
# GCP variables variable "gcp_project_id" { description = "Google Cloud Platform (GCP) project ID" type = string } variable "zone" { description = "Geographical zone for the GCP VM instance" type = string } variable "machine_type" { description = "Machine type for the GCP VM instance" type = string } # Cloudflare variables variable "cloudflare_zone" { description = "Domain used to expose the GCP VM instance to the Internet" type = string } variable "cloudflare_zone_id" { description = "Zone ID for your domain" type = string } variable "cloudflare_account_id" { description = "Account ID for your Cloudflare account" type = string sensitive = true } variable "cloudflare_email" { description = "Email address for your Cloudflare account" type = string sensitive = true } variable "cloudflare_token" { description = "Cloudflare API token" type = string sensitive = true }
Přiřaďte hodnoty proměnným
-
Ve svém konfiguračním adresáři vytvořte
.tfvarssoubor:touch terraform.tfvarsTerraform tyto proměnné automaticky použije, pokud je soubor pojmenován
terraform.tfvars, jinak bude nutné soubor s proměnnými předat ručně. -
Přidejte následující proměnné do
terraform.tfvars. Nezapomeňte upravit příklad podle svých vlastních hodnot.cloudflare_zone = "example.com" cloudflare_zone_id = "023e105f4ecef8ad9ca31a8372d0c353" cloudflare_account_id = "372e67954025e0ba6aaa6d586b9e0b59" cloudflare_email = "[email protected]" cloudflare_token = "y3AalHS_E7Vabk3c3lX950F90_Xl7YtjSlzyFn_X" gcp_project_id = "testvm-123" zone = "us-central1-a" machine_type = "e2-medium"
Nakonfigurujte poskytovatele Terraform
Budete muset deklarovat poskytovatelé ↗ použitý k zajištění infrastruktury.
-
Ve svém konfiguračním adresáři vytvořte
.tfsoubor:touch providers.tf -
Přidejte následující poskytovatele do
providers.tf.randomposkytovatel se používá k vygenerování tajného klíče tunelu.terraform { required_providers { cloudflare = { source = "cloudflare/cloudflare" version = ">= 5.8.2" } google = { source = "hashicorp/google" } } required_version = ">= 1.2" } # Providers provider "cloudflare" { api_token = var.cloudflare_token } provider "google" { project = var.gcp_project_id } provider "random" { }terraform { required_providers { cloudflare = { source = "cloudflare/cloudflare" version = ">= 4.40.0, < 5.0.0" } google = { source = "hashicorp/google" } random = { source = "hashicorp/random" } } required_version = ">= 1.2" } # Providers provider "cloudflare" { api_token = var.cloudflare_token } provider "google" { project = var.gcp_project_id } provider "random" { }
Nakonfigurujte prostředky Cloudflare
Následující konfigurace upraví nastavení ve vašem účtu Cloudflare.
-
Ve svém konfiguračním adresáři vytvořte
.tfsoubor:touch Cloudflare-config.tf -
Přidejte následující prostředky do
Cloudflare-config.tf:# Creates a new remotely-managed tunnel for the GCP VM. resource "cloudflare_zero_trust_tunnel_cloudflared" "gcp_tunnel" { account_id = var.cloudflare_account_id name = "Terraform GCP tunnel" config_src = "cloudflare" } # Reads the token used to run the tunnel on the server. data "cloudflare_zero_trust_tunnel_cloudflared_token" "gcp_tunnel_token" { account_id = var.cloudflare_account_id tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id } # Creates the CNAME record that routes http_app.${var.cloudflare_zone} to the tunnel. resource "cloudflare_dns_record" "http_app" { zone_id = var.cloudflare_zone_id name = "http_app" content = "${cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id}.cfargotunnel.com" type = "CNAME" ttl = 1 proxied = true } # Configures tunnel with a published application for clientless access. resource "cloudflare_zero_trust_tunnel_cloudflared_config" "gcp_tunnel_config" { tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id account_id = var.cloudflare_account_id config = { ingress = [ { hostname = "http_app.${var.cloudflare_zone}" service = "http://httpbin:80" }, { service = "http_status:404" } ] } } # (Optional) Routes internal IP of GCP instance through the tunnel for private network access using WARP. resource "cloudflare_zero_trust_tunnel_cloudflared_route" "example_tunnel_route" { account_id = var.cloudflare_account_id tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id network = google_compute_instance.http_server.network_interface.0.network_ip comment = "Example tunnel route" } # Creates a reusable Access policy. resource "cloudflare_zero_trust_access_policy" "allow_emails" { account_id = var.cloudflare_account_id name = "Allow email addresses" decision = "allow" include = [ { email = { email = var.cloudflare_email } }, { email_domain = { domain = "@example.com" } } ] } # Creates an Access application to control who can connect to the public hostname. resource "cloudflare_zero_trust_access_application" "http_app" { account_id = var.cloudflare_account_id type = "self_hosted" name = "Access application for http_app.${var.cloudflare_zone}" domain = "http_app.${var.cloudflare_zone}" policies = [ { id = cloudflare_zero_trust_access_policy.allow_emails.id precedence = 1 } ] }# Generates a 32-byte secret for the tunnel. resource "random_bytes" "tunnel_secret" { byte_length = 32 } # Creates a new remotely-managed tunnel for the GCP VM. resource "cloudflare_zero_trust_tunnel_cloudflared" "gcp_tunnel" { account_id = var.cloudflare_account_id name = "Terraform GCP tunnel" secret = random_bytes.tunnel_secret.base64 } # Creates the CNAME record that routes http_app.${var.cloudflare_zone} to the tunnel. resource "cloudflare_record" "http_app" { zone_id = var.cloudflare_zone_id name = "http_app" content = "${cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.cname}" type = "CNAME" proxied = true } # Configures tunnel with a published application for clientless access. resource "cloudflare_zero_trust_tunnel_cloudflared_config" "gcp_tunnel_config" { tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id account_id = var.cloudflare_account_id config { ingress_rule { hostname = "${cloudflare_record.http_app.hostname}" service = "http://httpbin:80" } ingress_rule { service = "http_status:404" } } } # (Optional) Route internal IP of GCP instance through the tunnel for private network access using WARP. resource "cloudflare_zero_trust_tunnel_route" "example_tunnel_route" { account_id = var.cloudflare_account_id tunnel_id = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.id network = google_compute_instance.http_server.network_interface.0.network_ip comment = "Example tunnel route" } # Creates an Access application to control who can connect to the public hostname. resource "cloudflare_zero_trust_access_application" "http_app" { account_id = var.cloudflare_account_id name = "Access application for http_app.${var.cloudflare_zone}" domain = "http_app.${var.cloudflare_zone}" } # Creates a (legacy) Access policy for the Access application. resource "cloudflare_zero_trust_access_policy" "allow_emails" { application_id = cloudflare_zero_trust_access_application.http_app.id account_id = var.cloudflare_account_id name = "Example policy for http_app.${var.cloudflare_zone}" precedence = "1" decision = "allow" include { email = [var.cloudflare_email] } }
Chcete-li se dozvědět více o těchto zdrojích, přečtěte si Dokumentace poskytovatele Cloudflare ↗.
Nakonfigurujte prostředky GCP
Následující konfigurace definuje specifikace virtuálního počítače GCP a nastavuje spouštěcí skript, který se spustí při startu.
-
Ve svém konfiguračním adresáři vytvořte
.tfsoubor:touch GCP-config.tf -
Přidejte následující obsah do
GCP-config.tf:# OS the server will use data "google_compute_image" "image" { family = "ubuntu-2204-lts" project = "ubuntu-os-cloud" } # GCP Instance resource resource "google_compute_instance" "http_server" { name = "test" machine_type = var.machine_type zone = var.zone tags = [] boot_disk { initialize_params { image = data.google_compute_image.image.self_link } } network_interface { network = "default" access_config { //Ephemeral IP } } // Optional config to make instance ephemeral /* scheduling { preemptible = true automatic_restart = false } */ // Pass the tunnel token to the GCP server so that the server can install and run the tunnel upon startup. metadata_startup_script = templatefile("./install-tunnel.tftpl", { tunnel_token = data.cloudflare_zero_trust_tunnel_cloudflared_token.gcp_tunnel_token.token }) }# OS the server will use data "google_compute_image" "image" { family = "ubuntu-2204-lts" project = "ubuntu-os-cloud" } # GCP Instance resource resource "google_compute_instance" "http_server" { name = "test" machine_type = var.machine_type zone = var.zone tags = [] boot_disk { initialize_params { image = data.google_compute_image.image.self_link } } network_interface { network = "default" access_config { //Ephemeral IP } } // Optional config to make instance ephemeral /* scheduling { preemptible = true automatic_restart = false } */ // Pass the tunnel token to the GCP server so that the server can install and run the tunnel upon startup. metadata_startup_script = templatefile("./install-tunnel.tftpl", { tunnel_token = cloudflare_zero_trust_tunnel_cloudflared.gcp_tunnel.tunnel_token }) }
Vytvořit spouštěcí skript
Následující skript nainstaluje cloudflared a spusťte tunel jako službu. Tento příklad také nainstaluje odlehčenou aplikaci HTTP, kterou můžete použít k otestování konektivity.
-
Ve svém konfiguračním adresáři vytvořte soubor šablony Terraform:
touch install-tunnel.tftpl -
Otevřete soubor v textovém editoru a zkopírujte a vložte následující bash skript:
# Script to install Cloudflare Tunnel and Docker resources # Docker configuration cd /tmp sudo apt-get install software-properties-common # Retrieving the docker repository for this OS curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable" # The OS is updated and docker is installed sudo apt update -y && sudo apt upgrade -y sudo apt install docker docker-compose -y # Add the HTTPBin application and run it on localhost:8080. cat > /tmp/docker-compose.yml << "EOF" version: '3' services: httpbin: image: kennethreitz/httpbin restart: always container_name: httpbin ports: - 8080:80 cloudflared: image: cloudflare/cloudflared:latest restart: always container_name: cloudflared command: tunnel run --token ${tunnel_token} EOF cd /tmp sudo docker-compose up -d
6. Nasaďte Terraform
Chcete-li nasadit konfigurační soubory:
-
Inicializujte svůj konfigurační adresář:
terraform init -
Zobrazte náhled všeho, co bude vytvořeno:
terraform plan -
Použijte konfiguraci:
terraform apply
Aktivace instance GCP a tunelu může trvat několik minut. Nový tunel si můžete zobrazit na kartě Cloudflare dashboard ↗ v části Sítě > Tunnels.
7. Otestujte připojení
-
V Cloudflare dashboard ↗, přejděte na Sítě > Tunnels a ověřte, že váš tunel je Aktivní.
-
(Volitelné) Pokud jste nakonfigurovali Access, přejděte do Security > Access > Aplikace a ověřte, že zásada Access povoluje váš e-mail Cloudflare.
-
Z libovolného zařízení otevřete prohlížeč a přejděte na
http_app.<CLOUDFLARE_ZONE>(napříkladhttp_app.example.com).Pokud jste nakonfigurovali Access, zobrazí se přihlašovací stránka Access. Přihlaste se pomocí svého e-mailu Cloudflare.
-
Mělo by se zobrazit domovská stránka HTTPBin, což potvrzuje, že tunel správně směruje provoz.