Error While creating CNAME at Cloudflare through Terraform

Viewed 793

What I did?

  • Created a terraform module with provider as cloudflare
provider "cloudflare" {
}
  • Provided token to the shell environment using variable CLOUDFLARE_API_TOKEN

  • Token have access to the zone say: example.com

  • Creating a CNAME record which is targeting to my S3 bucket using:

resource "cloudflare_record" "cname-bucket" {
  zone_id = var.domain
  name    = var.bucket_name
  value   = "${var.bucket_name}.s3-website.${var.region}.amazonaws.com"
  proxied = true
  type    = "CNAME"
}
  • After applying this module, getting error:
Error: failed to create DNS record: error from makeRequest: HTTP status 400: content "{\"success\":false,\"errors\":[{\"code\":7003,\"message\":\"Could not route to \\/zones\\/example.com\\/dns_records, perhaps your object identifier is invalid?\"},{\"code\":7000,\"message\":\"No route for that URI\"}],\"messages\":[],\"result\":null}"
  • When I tried creating the same using cloudflare with browser, everything works fine but when trying same with terraform, getting the above error.

  • Access my token have: example.com - DNS:Edit

What I need?

  • What I am doing wrong here?
  • How to create this CNAME record using terraform module?
3 Answers

It looks like the problem is zone_id = var.domain line in your cloudflare_record resource. You are using example.com as the zone_id , but instead you should be using your Cloudflare Zone ID.

You can find you Zone ID in your Cloudflare Dashboard for your domain: check in Overview , on the right column in the API section.

locals {
  domain = "example.com"
  hostname = "example.com" # TODO: Varies by environment
}

variable "CLOUDFLARE_ACCOUNT_ID" {}
variable "CLOUDFLARE_API_TOKEN" { sensitive = true }

provider "cloudflare" {
  api_token = var.CLOUDFLARE_API_TOKEN
  account_id = var.CLOUDFLARE_ACCOUNT_ID
}

resource "cloudflare_zone" "default" {
  zone = local.domain
  plan = "free"
}

resource "cloudflare_record" "a" {
  zone_id = cloudflare_zone.default.id
  name    = local.hostname
  value   = "192.0.2.1"
  type    = "A"
  ttl     = 1
  proxied = true
}

Source https://github.com/kriasoft/terraform-starter-kit

As an alternative to the other answers. You can use this module. In this case, your code will look like this:

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

variable "cloudflare_api_token" {
  type        = string
  sensitive   = true
  description = "The Cloudflare API token."
}

provider "cloudflare" {
  api_token = var.cloudflare_api_token
}

module "bucket" {
  source  = "registry.terraform.io/alex-feel/zone/cloudflare"
  version = "1.8.0"

  zone = var.domain # For instance, it may be example.com

  records = [
    {
      record_name = "bucket_cname"
      type        = "CNAME"
      name        = var.bucket_name                                             # A subdomain of the example.com domain
      value       = "${var.bucket_name}.s3-website.${var.region}.amazonaws.com" # Where the subdomain should point to
      proxied     = true
    }
  ]
}

To use the module with this configuration, your token must have at least the following privileges for the desired zone: DNS:Edit, Zone:Edit, Zone Settings:Edit. And to use all the features of the module, you need an additional privilege: Page Rules:Edit.

P.S. You do not need the zone_id for this configuration.

Related