Powered by AppSignal & Oban Pro

Zones, DNS Records, and DNS Settings

livebooks/zones_dns_settings.livemd

Zones, DNS Records, and DNS Settings

Section

This notebook shows how to use cloudflare_api to:

  • List and mutate zones (activation checks, cache purges, safe updates)
  • Manage DNS records (list, create, update, delete, existence checks)
  • Read and update DNS settings at the zone and account level

> ⚠️ Important: Many of these calls change live Cloudflare state. > Prefer running this notebook against a dedicated test account/zone > and double‑check each section before executing it.

1. Setup

Configure your Cloudflare credentials and IDs. The recommended approach is to use environment variables:

  • CLOUDFLARE_API_TOKEN
  • CLOUDFLARE_API_ACCOUNT_ID
  • CLOUDFLARE_API_ZONE_ID
token = System.fetch_env!("CLOUDFLARE_API_TOKEN")
account_id = System.fetch_env!("CLOUDFLARE_API_ACCOUNT_ID")
zone_id = System.fetch_env!("CLOUDFLARE_API_ZONE_ID")

# Zero-arity client function, convenient to pass around
c = CloudflareApi.client(token)

If you prefer, you can hard‑code values instead (not recommended for shared notebooks):

# token = "your-api-token"
# account_id = "your-account-id"
# zone_id = "your-zone-id"
# c = CloudflareApi.client(token)

2. Zones – read operations

2.1 List zones

{:ok, zones} = CloudflareApi.Zones.list(c)

zones
|> Enum.map(fn z -> {z["id"], z["name"]} end)

2.2 Fetch a specific zone

{:ok, zone} = CloudflareApi.Zones.get(c, zone_id)

zone

3. Zones – write operations

> ⚠️ These calls modify zone state. > Use a test zone if possible, and review parameters carefully.

3.1 Safe no‑op patch (write path)

This exercises patch/3 while preserving the current paused value.

{:ok, zone} = CloudflareApi.Zones.get(c, zone_id)
paused = Map.fetch!(zone, "paused")

{:ok, patched} = CloudflareApi.Zones.patch(c, zone_id, %{"paused" => paused})

patched["paused"]

3.2 Trigger an activation check

CloudflareApi.Zones.activation_check(c, zone_id)

3.3 Purge cache for a zone

> ⚠️ This clears cached content. It does not remove DNS or settings, but > may increase origin load temporarily.

CloudflareApi.Zones.purge_cache(c, zone_id, %{"purge_everything" => true})

3.4 (Optional) Create and delete a zone

Creating/deleting zones is usually only appropriate in automated provisioning flows. This shows the call pattern but may fail unless the domain is properly configured on Cloudflare.

new_zone_params = %{
  "name" => "your-test-domain.example"
  # Add other fields as required by the Cloudflare API,
  # e.g.: "account" => %{"id" => account_id}
}

# Create a new zone (may fail if the domain is not valid/owned)
# {:ok, created_zone} = CloudflareApi.Zones.create(c, new_zone_params)
# Once you have a test zone ID you want to remove:
# test_zone_id = created_zone["id"]
# CloudflareApi.Zones.delete(c, test_zone_id)

4. DNS records – read operations

4.1 List all DNS records for a zone

{:ok, records} = CloudflareApi.DnsRecords.list(c, zone_id)

Enum.map(records, fn record ->
  {record.type, record.hostname, record.ip}
end)

4.2 List records for a specific hostname

hostname = "www.example.com"

CloudflareApi.DnsRecords.list_for_hostname(c, zone_id, hostname)

4.3 List records using host + domain

host = "www"
domain = "example.com"

CloudflareApi.DnsRecords.list_for_host_domain(c, zone_id, host, domain)

4.4 Existence helper checks

CloudflareApi.DnsRecords.hostname_exists?(c, zone_id, "www.example.com")
CloudflareApi.DnsRecords.host_domain_exists?(c, zone_id, "www", "example.com")

5. DNS records – write operations

> ⚠️ These calls create/update/delete DNS records. > Use a test hostname under your zone and avoid touching production records.

5.1 Create a test A record

test_hostname = "livebook-test.example.com"
test_ip = "203.0.113.10" # example IP from RFC 5737

{:ok, record} = CloudflareApi.DnsRecords.create(c, zone_id, test_hostname, test_ip)

record

5.2 Update the test record

new_ip = "203.0.113.11"

{:ok, updated_record} =
  CloudflareApi.DnsRecords.update(
    c,
    zone_id,
    record.id,
    record.hostname,
    new_ip
  )

updated_record

5.3 Confirm the hostname exists

CloudflareApi.DnsRecords.hostname_exists?(c, zone_id, record.hostname)

5.4 Delete the test record

CloudflareApi.DnsRecords.delete(c, zone_id, record.id)

5.5 Verify the hostname no longer exists

CloudflareApi.DnsRecords.hostname_exists?(c, zone_id, record.hostname)

6. DNS settings – read operations

These helpers use CloudflareApi.DnsSettings to fetch DNS settings at the zone and account scopes.

6.1 Zone DNS settings

{:ok, zone_dns_settings} = CloudflareApi.DnsSettings.zone_settings(c, zone_id)

zone_dns_settings

You can inspect just the defaults, when present:

zone_dns_settings["zone_defaults"]

6.2 Account DNS settings

{:ok, account_dns_settings} = CloudflareApi.DnsSettings.account_settings(c, account_id)

account_dns_settings

7. DNS settings – write operations

> ⚠️ These calls can change how DNS behaves for your zone/account. > Start by reading the current settings and make only minimal, well‑understood > changes.

7.1 Safe zone DNS settings round‑trip

This exercises update_zone_settings/3 by sending back the existing zone_defaults unchanged (a logical no‑op).

{:ok, zone_dns_settings} = CloudflareApi.DnsSettings.zone_settings(c, zone_id)

zone_defaults = zone_dns_settings["zone_defaults"] || %{}

params = %{"zone_defaults" => zone_defaults}

{:ok, updated_zone_dns_settings} =
  CloudflareApi.DnsSettings.update_zone_settings(c, zone_id, params)

updated_zone_dns_settings["zone_defaults"] == zone_defaults

7.2 Account DNS settings (advanced)

Account‑level DNS settings apply across your entire account, so changes here can have wide impact. This section shows how to build the update payload starting from the current settings; you should only modify specific fields you understand.

{:ok, current_account_settings} =
  CloudflareApi.DnsSettings.account_settings(c, account_id)

updated_account_settings =
  current_account_settings
  # Example: update a nested setting safely, e.g.
  # |> put_in(["some_group", "some_flag"], true)

CloudflareApi.DnsSettings.update_account_settings(
  c,
  account_id,
  updated_account_settings
)

If the payload is invalid for your account, update_account_settings/3 returns {:error, errors} with the Cloudflare validation messages.