Cloudflare Terraform プロバイダーを使ったインフラ設定のベストプラクティスガイド。Cloudflare リソースの Terraform コード作成、DNS レコード、WAF ルールセット、レート制限、DDoS 対策、Transform Rules、ロードバランサー、ゾーン設定などの .tf ファイル作成時に使用する。「Cloudflare の Terraform を書いて」「WAF ルールを Terraform で設定」「DNS レコードを追加」「レート制限を設定」「Cloudflare の設定をコードで管理」などのリクエストで起動する。
Cloudflare Terraform プロバイダー(v5)を使ってインフラ設定を作成する際のガイドライン。
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 5"
}
}
}
provider "cloudflare" {
# API トークンは環境変数 CLOUDFLARE_API_TOKEN から自動読み込み
}
認証情報は .tf ファイルにハードコードせず、環境変数を使う。
アカウント > ゾーン > プロダクト の階層で分離する。
project/
├── account_a/
│ ├── users/
│ │ ├── provider.tf
│ │ ├── users.tf
│ │ └── vars.tf
│ └── zone_a/
│ ├── dns/
│ │ ├── dns.tf
│ │ ├── provider.tf
│ │ └── vars.tf
│ └── waf/
│ ├── waf.tf
│ ├── provider.tf
│ └── vars.tf
ファイル命名規則:
provider.tf - プロバイダー設定<subject>.tf - リソース定義(dns.tf, waf.tf など)vars.tf - 変数定義CLOUDFLARE_API_TOKEN で渡すterraform.tfvars は .gitignore に含める.terraform/
*.tfstate*
.terraform.lock.hcl
terraform.tfvars
variable "zone_id" {
description = "Cloudflare Zone ID"
type = string
sensitive = true
}
variable "account_id" {
description = "Cloudflare Account ID"
type = string
sensitive = true
}
ダッシュボードや API で直接変更すると state が不一致になる。
ref がないと、ルールセット変更時にルール ID が変わる。
rules {
ref = "unique_rule_identifier" # 必須
description = "Rule description"
expression = "true"
action = "execute"
}
モジュールや dynamic ブロックは予期しない問題を引き起こしやすい。リソースを直接定義する方が安全。
staging と production でアカウントを分離する(例: example.com と example-staging.com)。アカウントレベルのリソース(LB モニター、プール等)が共有されるため。
| 項目 | ゾーンレベル | アカウントレベル |
|---|---|---|
| scope | 単一ゾーン | 複数ゾーン |
| kind | "zone" | "root" |
| ID パラメータ | zone_id | account_id |
| プラン要件 | なし | Enterprise + 有料アドオン |
| expression 要件 | なし | 末尾に and cf.zone.plan eq "ENT" |
| phase | 用途 |
|---|---|
http_request_firewall_managed | WAF Managed Rules |
http_request_firewall_custom | WAF カスタムルール |
http_ratelimit | レート制限ルール |
ddos_l7 | HTTP DDoS 対策 |
ddos_l4 | ネットワークレイヤー DDoS 対策 |
http_request_transform | URL リライト |
http_request_late_transform | リクエストヘッダー変更 |
http_response_headers_transform | レスポンスヘッダー変更 |
例外(skip)ルールは、対象のマネージドルールセット実行ルールの 前に 配置する。
resource "cloudflare_ruleset" "waf" {
# ...
rules { ... action = "skip" ... } # 1. 例外ルール(先)
rules { ... action = "execute" ... } # 2. 実行ルール(後)
}
cf-terraforming を使って既存の Cloudflare 設定を Terraform に取り込む。
# 設定ファイル生成
cf-terraforming generate \
--email $CLOUDFLARE_EMAIL \
--token $CLOUDFLARE_API_TOKEN \
-z $CLOUDFLARE_ZONE_ID \
--resource-type cloudflare_record > dns.tf
# state インポートコマンド生成
cf-terraforming import \
--resource-type cloudflare_record \
--email $CLOUDFLARE_EMAIL \
--key $CLOUDFLARE_API_KEY \
--zone $CLOUDFLARE_ZONE_ID
terraform {
backend "s3" {
bucket = "<BUCKET_NAME>"
key = "/some/key/terraform.tfstate"
region = "auto"
skip_credentials_validation = true
skip_metadata_api_check = true
skip_region_validation = true
skip_requesting_account_id = true
skip_s3_checksum = true
use_path_style = true
access_key = "<R2_ACCESS_KEY>"
secret_key = "<R2_ACCESS_SECRET>"
endpoints = {
s3 = "https://<ACCOUNT_ID>.r2.cloudflarestorage.com"
}
}
}