Skip to content

Publish applications with Terraform

This guide covers how to use the Cloudflare Terraform provider to quickly publish and secure a private application. In the following example, we will add a new public hostname route to an existing Cloudflare Tunnel, configure how cloudflared proxies traffic to the application, and secure the application with Cloudflare Access.

Prerequisites

1. Create a Terraform configuration directory

Terraform functions through a working directory that contains configuration files. You can store your configuration in multiple files or just one — Terraform will evaluate all of the configuration files in the directory as if they were in a single document.

  1. Create a folder for your Terraform configuration:

    Terminal window
    mkdir cloudflare-tf
  2. Change into the directory:

    Terminal window
    cd cloudflare-tf

2. Declare providers and variables

Create a .tf file and copy-paste the following example. Fill in your API token, account and zone information, and Tunnel ID.

Find the Tunnel ID

  1. In Zero Trust, go to Networks > Tunnels.
  2. Select the tunnel name.
  3. Copy the Tunnel ID.
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = "<API-TOKEN>"
}
variable "account_id" {
default = "<ACCOUNT-ID>"
}
variable "zone_id" {
default = "<ZONE-ID>"
}
variable "zone_name" {
default = "mycompany.com"
}
variable "tunnel_id" {
default = "<TUNNEL-ID>"
}

3. Configure Cloudflare resources

Add the following resources to your Terraform configuration.

Add public hostname route to Cloudflare Tunnel

Using the cloudflare_tunnel_config resource, create an ingress rule that maps your application to a public DNS record. This example makes localhost:8080 available on app.mycompany.com, sets the Connect Timeout, and enables Access JWT validation.

resource "cloudflare_tunnel_config" "example_config" {
account_id = var.account_id
tunnel_id = var.tunnel_id
config {
ingress_rule {
hostname = "app.${var.zone_name}"
service = "http://localhost:8080"
origin_request {
connect_timeout = "2m0s"
access {
required = true
team_name = "myteam"
aud_tag = [cloudflare_access_application.example_app.aud]
}
}
}
ingress_rule {
# Respond with a `404` status code when the request does not match any of the previous hostnames.
service = "http_status:404"
}
}
}

Create an Access application

Using the cloudflare_access_application resource, add the application to Cloudflare Access.

resource "cloudflare_access_application" "example_app" {
zone_id = var.zone_id
name = "Example application"
domain = "app.${var.zone_name}"
type = "self_hosted"
session_duration = "24h"
auto_redirect_to_identity = false
}

Create an Access policy

Using the cloudflare_access_policy resource, create a policy to secure the application. The following policy will only allow access to users who authenticate through your identity provider.

resource "cloudflare_access_policy" "example_policy" {
application_id = cloudflare_access_application.example_app.id
zone_id = var.zone_id
name = "Example policy"
precedence = "1"
decision = "allow"
include {
login_method = ["<IDP-UUID>"]
}
}

4. Deploy Terraform

To deploy the configuration files:

  1. Initialize your configuration directory:

    Terminal window
    terraform init
  2. Preview everything that will be created:

    Terminal window
    terraform plan
  3. Apply the configuration:

    Terminal window
    terraform apply

Users can now access the private application by going to the public URL and authenticating with Cloudflare Access. You can view your new tunnel route, Access application, and Access policy in Zero Trust. The new DNS record is shown in the Cloudflare dashboard.