Fourthwall uses Entri Connect to configure DNS when you attach a custom domain. For most creators, the wizard is enough: grant access to your registrar, let Entri create the records, and wait for the domain to sync.

That breaks down when Cloudflare is managed with Terraform or OpenTofu. Entri creates records outside version control, outside review, and outside drift detection. If the rest of your zone lives in code, your shop DNS should too.

Why Cloudflare Proxy Breaks Fourthwall SSL

When Cloudflare proxying is enabled, traffic flows through Cloudflare’s Anycast network before reaching the origin. Cloudflare terminates SSL and serves its own certificate for the domain.

Fourthwall expects a direct DNS-only A record so its certificate provisioner can validate the domain. If Cloudflare is proxying the record, validation can fail and the domain may remain stuck on “Syncing.”

Fourthwall’s docs say “use DNS Only in Cloudflare.” In Terraform, that means:

resource "cloudflare_dns_record" "shop_a" {
  zone_id = var.zone_id
  name    = "shop.yourdomain.com"
  content = var.shop_ip
  type    = "A"
  ttl     = 1
  proxied = false # Required for Fourthwall SSL provisioning
}

proxied defaults to false in the Cloudflare provider, but make it explicit. Proxy status is the first thing to check when a Fourthwall domain does not sync, and it is a recurring issue in Cloudflare Community support threads.

The 2-Record Problem

Fourthwall’s help center tells you to add:

  • An A record pointing shop.yourdomain.com to their origin IP
  • A CNAME pointing www.shop.yourdomain.com to shop.yourdomain.com

That connects the storefront, but it does not cover transactional email, support routing, or email authentication.

Fourthwall uses SendGrid for transactional email, Zendesk for support routing, and ImprovMX for email forwarding. Each service needs its own DNS records.

The full record set is in Fourthwall’s Domain Connect automation template, the JSON file used by the Entri integration. If you bypass Entri and manage DNS yourself, this template is the source of truth.

The complete setup requires:

Shop Routing (2 Records)

shop.yourdomain.com         A      → Fourthwall origin IP
www.shop.yourdomain.com     CNAME  → shop.yourdomain.com

SendGrid Transactional Email (3 Records)

Order confirmations, receipts, and shipping updates route through SendGrid. These CNAME records authenticate Fourthwall’s sending identity:

em-fw.support.shop.yourdomain.com          CNAME → <sendgrid-subuser>.sendgrid.net
s1._domainkey.support.shop.yourdomain.com  CNAME → s1.domainkey.<sendgrid-subuser>.sendgrid.net
s2._domainkey.support.shop.yourdomain.com  CNAME → s2.domainkey.<sendgrid-subuser>.sendgrid.net

Zendesk Support Routing (9 Records)

support.shop.yourdomain.com routes customer support email through Zendesk. It needs MX records, routing CNAMEs, DKIM records, and a domain ownership token:

support.shop.yourdomain.com                MX    → mx1.fourthwall.com (priority 10)
support.shop.yourdomain.com                MX    → mx2.fourthwall.com (priority 20)
zendesk1.support.shop.yourdomain.com       CNAME → mail1.zendesk.com
zendesk2.support.shop.yourdomain.com       CNAME → mail2.zendesk.com
zendesk3.support.shop.yourdomain.com       CNAME → mail3.zendesk.com
zendesk4.support.shop.yourdomain.com       CNAME → mail4.zendesk.com
zendesk1._domainkey.support.shop...        CNAME → zendesk1._domainkey.zendesk.com
zendesk2._domainkey.support.shop...        CNAME → zendesk2._domainkey.zendesk.com
zendeskverification.support.shop...        TXT   → <your-zendesk-token>

Email Authentication (2 Records)

SPF and DMARC define which services can send from support.shop and reject unauthorized mail:

support.shop.yourdomain.com      TXT → v=spf1 include:_spf.google.com include:mail.zendesk.com include:spf.fourthwall.com include:sendgrid.net ~all
_dmarc.support.shop.yourdomain.com  TXT → v=DMARC1; p=reject; pct=100; rua=mailto:dmarc@fourthwall.com

That is 15 records in total. Creating them once is tedious. Repeating the work for multiple shops or a DNS migration is exactly what Terraform should handle.

Automating It With Terraform

According to Store Leads, Fourthwall had more than 20,800 active stores and 44% year-over-year growth in Q1 2026. Agencies and technical creators should not have to hand-build the same DNS setup for every new shop.

I built a Terraform module that codifies the full record set:

module "shop" {
  source  = "m11s-io/modules/cloudflare//modules/fourthwall-shop"
  version = "~> 0.1"

  zone_id                    = cloudflare_zone.yourdomain.id
  domain                     = "yourdomain.com"
  shop_ip                    = "34.117.223.165"
  zendesk_verification_token = "your-zendesk-verification-token"
  sendgrid_subuser           = "u12345678.wl001"
}

One block creates all 15 records, enforces proxied = false where required, and sets the correct TTLs and MX priorities. The module is available on GitHub and the Terraform Registry.

Finding the Zendesk Token and SendGrid Subuser

Fourthwall shows both values in the shop domain settings after you enter a custom domain. They are shop-specific.

  • sendgrid_subuser → the SendGrid CNAME target prefix
  • zendesk_verification_token → the Zendesk verification TXT value

Store them in an ignored terraform.tfvars file or load them from a secrets manager with a data source.

Managing Multiple Shops

For multiple creator brands or client shops, use for_each:

locals {
  shops = {
    creator-one = {
      zone_id                    = cloudflare_zone.creator_one.id
      domain                     = "creator-one.com"
      shop_ip                    = "34.117.223.165"
      zendesk_verification_token = "abc123"
      sendgrid_subuser           = "u11111111.wl001"
    }
    creator-two = {
      zone_id                    = cloudflare_zone.creator_two.id
      domain                     = "creator-two.com"
      shop_ip                    = "34.117.223.165"
      zendesk_verification_token = "def456"
      sendgrid_subuser           = "u22222222.wl001"
    }
  }
}

module "shops" {
  for_each = local.shops
  source   = "github.com/m11s-io/terraform-cloudflare-modules//modules/fourthwall-shop"

  zone_id                    = each.value.zone_id
  domain                     = each.value.domain
  shop_ip                    = each.value.shop_ip
  zendesk_verification_token = each.value.zendesk_verification_token
  sendgrid_subuser           = each.value.sendgrid_subuser
}

Each shop gets the complete 15-record setup from one tofu apply or terraform apply.

The fourthwall-shop module is part of terraform-cloudflare-modules. The same repo includes:

  • email-routing — enables Cloudflare Email Routing with forwarding rules, a catch-all address, and DMARC.
  • tunnel — provisions a Cloudflare Zero Trust tunnel with ingress routing and secret generation.

Planned modules include zone-security for standard TLS and HTTPS hardening, and www-redirect for bulk www to apex redirects.

Verifying the Setup

After terraform apply, confirm the key records resolve before connecting the domain in Fourthwall:

# Shop A record: should return Fourthwall's origin IP, not a Cloudflare IP
dig +short shop.yourdomain.com A

# SendGrid CNAME
dig +short em-fw.support.shop.yourdomain.com CNAME

# Zendesk MX
dig +short support.shop.yourdomain.com MX

# DMARC
dig +short _dmarc.support.shop.yourdomain.com TXT

Fourthwall shows “Active” after the A record propagates and SSL provisioning completes. This usually takes about 15 minutes, but newly transferred domains can take up to 48 hours.

If the domain stays on “Syncing” past 30 minutes, check proxy status first. Run dig +short shop.yourdomain.com; if it returns a Cloudflare IP instead of Fourthwall’s origin IP, the record is still proxied.


Fourthwall’s documented setup covers the storefront. The full custom-domain setup covers storefront routing, SSL, transactional email, support routing, SPF, and DMARC. Keep those records in version control and let Terraform manage them consistently.

View the module on the Terraform Registry →