ベストプラクティス
すべてのTerraformデプロイメントはユニークですが、成功するための準備を整えるために、以下のベストプラクティスに従ってください。
Terraformは、リソースの変更とライフサイクルをすべて管理する場合に最も効果的に機能します。
設定に対する操作の後、Terraformはリモートをローカル状態に同期させることで差異を調整しようとします。ローカルとリモートに差異がある場合(Terraformの外部でリソースを管理したことによる)、すべてのリソースがインプレース更新をサポートしているわけではないため、状態ファイル内のリソースを削除して再作成する必要があるかもしれません(通常はインポートを介して)。
Cloudflareは、変更を隔離するためにアカウント、ゾーン、製品の組み合わせに依存するディレクトリ構造の使用を推奨しています。このセットアップにより、特定の製品にスコープを絞ったTerraform操作を持つことができ、オーナーを細かく管理できます。また、Cloudflareのデフォルトロールや、AWSやGCPストレージなどの追加ツールとより密接に連携し、別々の状態ファイルに対する権限を設定できます。
Rulesetsのように多くの責任を含む製品については、フェーズレベル(WAF、リダイレクト、オリジンルール)でさらに分割することができます。
example-tf/├── demo_account_a # アカウントごとのリソースの分離│ ├── users # アカウントメンバーのためのトップレベルディレクトリ(ゾーンなし)│ │ ├── provider.tf # `provider.tf`はプロバイダーの設定用│ │ ├── users.tf # `<subject>.tf`(users.tf)は個々のリソースを管理するためのもの│ │ └── vars.tf # このコンポーネントのすべての変数を管理│ ├── zone_a # ゾーンベースの機能をまとめる│ │ ├── dns # 一緒に管理する製品や機能の個別(またはグループ化、選択可)│ │ │ ├── dns.tf # `<subject>.tf`(dns.tf)は個々のリソースを管理するためのもの│ │ │ ├── provider.tf # `provider.tf`はプロバイダーの設定用│ │ │ └── vars.tf # このコンポーネントのすべての変数を管理│ │ └── page_rules # ... 上記と同様だがページルール用│ │ ├── page_rules.tf│ │ ├── provider.tf│ │ └── vars.tf│ ├── zone_b│ │ ├── dns│ │ │ ├── dns.tf│ │ │ ├── provider.tf│ │ │ └── vars.tf│ │ └── page_rules│ │ ├── page_rules.tf│ │ ├── provider.tf│ │ └── vars.tf│ └── zone_c│ ├── dns│ │ ├── dns.tf│ │ ├── provider.tf│ │ └── vars.tf│ └── page_rules│ ├── page_rules.tf│ ├── provider.tf│ └── vars.tf└── demo_account_b ├── users │ ├── provider.tf │ ├── users.tf │ └── vars.tf ├── zone_a │ ├── dns │ │ ├── dns.tf │ │ ├── provider.tf │ │ └── vars.tf │ └── page_rules │ ├── page_rules.tf │ ├── provider.tf │ └── vars.tf ├── zone_b │ ├── dns │ │ ├── dns.tf │ │ ├── provider.tf │ │ └── vars.tf │ └── page_rules │ ├── page_rules.tf │ ├── provider.tf │ └── vars.tf └── zone_c ├── dns │ ├── dns.tf │ ├── provider.tf │ └── vars.tf └── page_rules ├── page_rules.tf ├── provider.tf └── vars.tfTerraformモジュールは、抽象化されたインターフェースで複数のリソースをロジックとともにカプセル化する方法です。モジュールがデフォルトのロードバランサーをプール、いくつかのDNSエントリ、そしておそらくページルールを設定する例を考えてみてください。エンドユーザーは次のように使用するかもしれません:
module "example" "an_example_site" { domain = "example.com" origin_ip = "192.168.0.1"}しかし、Terraformリソースの観点からは、上記の例は次のように翻訳されます:
resource "cloudflare_record" "example_1" { zone_id = var.cloudflare_zone_id name = "terraform" value = "198.51.100.11" type = "A" ttl = 3600}
resource "cloudflare_record" "example_2" { zone_id = var.cloudflare_zone_id name = "terraform" value = "198.51.100.12" type = "A" ttl = 3600}
resource "cloudflare_record" "example_3" { zone_id = var.cloudflare_zone_id name = "terraform" value = "198.51.100.13" type = "A" ttl = 3600}
resource "cloudflare_load_balancer" "bar" { zone_id = var.cloudflare_zone_id name = "example-load-balancer.example.com" fallback_pool_id = cloudflare_load_balancer_pool.foo.id default_pool_ids = [cloudflare_load_balancer_pool.foo.id] description = "example load balancer using geo-balancing" proxied = true steering_policy = "geo"
pop_pools { pop = "LAX" pool_ids = [cloudflare_load_balancer_pool.foo.id] }
country_pools { country = "US" pool_ids = [cloudflare_load_balancer_pool.foo.id] }
region_pools { region = "WNAM" pool_ids = [cloudflare_load_balancer_pool.foo.id] }
rules { name = "example rule" condition = "http.request.uri.path contains \"testing\"" fixed_response { message_body = "hello" status_code = 200 content_type = "html" location = "www.example.com" } }}
resource "cloudflare_load_balancer_pool" "example_lb_pool" { name = "example-lb-pool" origins { name = "example-1" address = "198.51.100.1" enabled = true }}
resource "cloudflare_page_rule" "example_page_rule" { zone_id = var.cloudflare_zone_id target = "sub.${var.cloudflare_zone}/page" priority = 1
actions { ssl = "flexible" email_obfuscation = "on" }}便利ではありますが、このセットアップは予期しない問題を引き起こす可能性があります。このモジュールが共有され、内部で変更が加えられた場合、モジュールはリソースが同期していないか、再作成される可能性があります。
モジュールを使用すると、デバッグや問題の再現が難しくなることもあります。なぜなら、TerraformコアやCloudflareプロバイダーの外部に潜在的なロジックバグを考慮しなければならないからです。
Cloudflareは、既存のリソースをCloudflareに移行するためにcf-terraformingの使用を推奨しています。
一部のリソースをTerraform内で管理し、他のリソースを別のツールで管理することは全く問題ありませんが、同じリソースに対して両方を行っていないことを確認してください。
別々の環境(ステージング、QA、UAT、プロダクション)を安全に管理するために、別々のCloudflareアカウントと別々のドメイン(例:example.comとexample-staging.com)を使用してください。
これは、アカウントレベルで定義された一部の製品が共有されているため(ロードバランサーモニターやプールなど)、同じアカウント内にある場合はそれらに対して孤立した変更を行うことができないからです。別々のアカウントを使用することは、DNSSECのようなものをテストする場合にも有益です。これは、誤って設定するとドメイン全体に影響を及ぼす可能性があります。
ドリフトを最小限に抑えるために、Terraformと両方のドメインで実行されるCI/CDパイプラインを使用して、必要に応じて同期を保つようにしてください。
Cloudflareの認証情報をプレーンテキストで保存することは推奨しません。
ローカルでは、cf-vault ↗のようなサードパーティツールを使用してCloudflareの認証情報を保存できます。
CIパイプラインでは、内部または秘密のストレージツール(Vault ↗など)を使用してください。