Manage Cloudflare Using Terraform

In this blog, we'll walk you through the steps to get started with managing Cloudflare using Terraform. This can save you time and ensure consistency across your Cloudflare setup. To do so, you'll need to generate an API token in Cloudflare. Make sure it is stored securely. We secure it using SOPS and AWS KMS.

Generating an API Token in Cloudflare

To generate an API token in Cloudflare, follow these steps:

  1. Log in to your Cloudflare account and navigate to the "API Tokens" section in the "My Profile" menu.
  2. Click the "Create Token" button and select the permissions you want the token to have. Give it a name and click "Create".

Securing the Cloudflare API Token with SOPS and AWS KMS

SOPS (Secrets OPerationS) is an open-source tool that allows for the encryption and decryption of files using different encryption engines, including AWS KMS, GCP KMS, and PGP

To secure the Cloudflare API token using SOPS and AWS KMS , follow these steps:

  1. Install SOPS on your system if you haven't already.
  2. Set up your AWS KMS key on aws account.
  3. Create a new file to store your Cloudflare API token and encrypt it using SOPS and your AWS KMS key
  4. To specify a creation rule for SOPS that applies to this file, create a .sops.yaml file in the directory and add a rule for the encrypted file.
  creation_rules:
      - kms: <arn>
        aws_profile: <profile>

Replace <arn> with your KMS arn, and <profile> with the  your aws profile.

Command to encrypt and decrypt the file

sops --encrypt --output <output_filename> <input file contain api token in format api_token: value> 

sops --decrypt --output <output_filename>

Authenticating with Cloudflare using Terraform

To authenticate with Cloudflare using Terraform, we can use Terragrunt to improve our Terraform code. You can follow these steps:

  1. In your Terraform configuration, use the Cloudflare provider.
  2. Create a terragrunt.hcl file in the same directory as your Terraform code.
  3. In the terragrunt.hcl file, define a secrets local variable that uses SOPS to decrypt your encrypted Cloudflare API token file. For example:
locals {
    secrets = yamldecode(sops_decrypt_file("${get_parent_terragrunt_dir()}/../secrets/<encrypted_file_name>.yml"))
}

4. In the inputs section of your terragrunt.hcl file, define an api_token input variable that references the api_token property of the secrets local variable. For example:

inputs = {
   api_token = local.secrets.api_token
}

5. In your provider.tf file, use the api_token variable to authenticate with the Cloudflare provider. For example:

terraform {
  required_providers {
    cloudflare = {
      source = "cloudflare/cloudflare"
      version = "3.32.0"
    }
  }
}

provider "cloudflare" {
  api_token = var.api_token
}

for version higher than 3.32, raises the Error: Provider produced invalid plan. this is due to cloudflare resource is forcing the optional configs and would not pass terraform plan until I added values to that

Generating Terraform code and importing state using ct-terraforming


To generate Terraform code for your existing Cloudflare infrastructure and import the current state, you can use ct-terraforming, a tool developed by Cloudflare. This can save you time and effort in setting up your Terraform configuration.

Here are the steps to use ct-terraforming:

  1. Install ct-terraforming
  2. Run ct-terraforming generate to generate Terraform code based on the exported YAML file:
cf-terraforming generate --resource-type "<resource-type>" --email <mail-id> --token <api-tpken> --zone <zone-id> > main.tf

This will generate a main.tf file in the current directory that contains the Terraform code to recreate your existing Cloudflare infrastructure.

3. Update the generated Terraform code to meet your specific needs, such as adding variables or modules.

4. Import the current state of your Cloudflare infrastructure into Terraform using terraform import. For example:

  cf-terraforming import --resource-type "<resource-type>" --email <mail-id> --token <api-tpken> --zone <zone-id>

This will import the current state of the specified Cloudflare zone into your Terraform state file.

View Comments