Extending your Terraform configuration with the http provider
An example would be the 4.5.2 version of the Cloudflare Terraform provider w.r.t cloudflare_accounts
resource (with no pagination, and the API defaults to 20 items)
# 1. Configure required providersterraform { required_providers { http = { source = "hashicorp/http" version = "~> 3.0" } cloudflare = { source = "cloudflare/cloudflare" version = "~> 4.0" } }}
variable "cloudflare_api_token" { description = "Cloudflare API Token with Account Settings read permissions" type = string sensitive = true}
# 3. Configure the Cloudflare provider (optional, only if using Cloudflare resources)provider "cloudflare" { api_token = var.cloudflare_api_token}
# 4. Fetch first page of accounts (50 per page)data "http" "first_page" { url = "https://api.cloudflare.com/client/v4/accounts?per_page=50"
request_headers = { "Authorization" = "Bearer ${var.cloudflare_api_token}" "Content-Type" = "application/json" }}
# 5. Parse response and calculate paginationlocals { first_response = jsondecode(data.http.first_page.response_body)
# Check if request was successful success = try(local.first_response.success, false) first_results = local.success ? try(local.first_response.result, []) : [] total_pages = local.success ? try(local.first_response.result_info.total_pages, 1) : 0
# Create list of remaining pages (2, 3, 4, etc.) remaining_pages = local.total_pages > 1 ? range(2, local.total_pages + 1) : []}
# 6. Fetch remaining pages if neededdata "http" "remaining_pages" { for_each = local.success ? toset([for p in local.remaining_pages : tostring(p)]) : toset([])
url = "https://api.cloudflare.com/client/v4/accounts?page=${each.value}&per_page=50"
request_headers = { "Authorization" = "Bearer ${var.cloudflare_api_token}" "Content-Type" = "application/json" }}
# 7. Combine all resultslocals { remaining_results = flatten([ for page in data.http.remaining_pages : try(jsondecode(page.response_body).result, []) ])
# All accounts combined all_accounts = concat(local.first_results, local.remaining_results)
# Create lookup maps for easy access accounts_by_id = { for acc in local.all_accounts : acc.id => acc }
accounts_by_name = { for acc in local.all_accounts : acc.name => acc }}
# 8. Outputsoutput "success" { description = "Whether the API calls were successful" value = local.success}
output "error" { description = "Error message if authentication failed" value = local.success ? null : try(local.first_response.errors[0].message, "Unknown error")}
output "accounts" { description = "All Cloudflare accounts" value = local.all_accounts}
output "account_ids" { description = "List of all account IDs" value = [for acc in local.all_accounts : acc.id]}
output "account_names" { description = "List of all account names" value = [for acc in local.all_accounts : acc.name]}
output "total_accounts" { description = "Total number of accounts" value = length(local.all_accounts)}
Using Accounts in Resources
Section titled “Using Accounts in Resources”Example 1: Create Zones for Each Account
Section titled “Example 1: Create Zones for Each Account”# Create a zone in each accountresource "cloudflare_zone" "example" { for_each = local.accounts_by_id
account_id = each.key
zone = "example-${replace(lower(each.value.name), " ", "-")}.com" plan = "free" type = "full"}
Example 2: Access Specific Account by Name
Section titled “Example 2: Access Specific Account by Name”# Get a specific account by namelocals { production_account = try(local.accounts_by_name["Production"], null)}
resource "cloudflare_zone" "prod_zone" { count = local.production_account != null ? 1 : 0
account { id = local.production_account.id }
zone = "production.com" plan = "enterprise"}
Example 3: Filter Accounts by Criteria
Section titled “Example 3: Filter Accounts by Criteria”# Filter accounts by name patternlocals { prod_accounts = { for acc in local.all_accounts : acc.id => acc if strcontains(lower(acc.name), "prod") }
# Filter by account type enterprise_accounts = { for acc in local.all_accounts : acc.id => acc if try(acc.type, "") == "enterprise" }}