コンテンツにスキップ

ベストプラクティス

すべてのTerraformデプロイメントはユニークですが、成功するための準備を整えるために、以下のベストプラクティスに従ってください。

Terraformリソースを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.tf

モジュールを避ける(または控えめに使用する)

Terraformモジュールは、抽象化されたインターフェースで複数のリソースをロジックとともにカプセル化する方法です。モジュールがデフォルトのロードバランサーをプール、いくつかの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プロバイダーの外部に潜在的なロジックバグを考慮しなければならないからです。

リソースをTerraformに移行する

Cloudflareは、既存のリソースをCloudflareに移行するためにcf-terraformingの使用を推奨しています。

一部のリソースをTerraformの外で管理する

一部のリソースをTerraform内で管理し、他のリソースを別のツールで管理することは全く問題ありませんが、同じリソースに対して両方を行っていないことを確認してください

別々の環境を使用する

別々の環境(ステージング、QA、UAT、プロダクション)を安全に管理するために、別々のCloudflareアカウントと別々のドメイン(例:example.comexample-staging.com)を使用してください。

これは、アカウントレベルで定義された一部の製品が共有されているため(ロードバランサーモニターやプールなど)、同じアカウント内にある場合はそれらに対して孤立した変更を行うことができないからです。別々のアカウントを使用することは、DNSSECのようなものをテストする場合にも有益です。これは、誤って設定するとドメイン全体に影響を及ぼす可能性があります。

ドリフトを最小限に抑えるために、Terraformと両方のドメインで実行されるCI/CDパイプラインを使用して、必要に応じて同期を保つようにしてください。

認証情報を安全に保管する

Cloudflareの認証情報をプレーンテキストで保存することは推奨しません。

ローカルでは、cf-vaultのようなサードパーティツールを使用してCloudflareの認証情報を保存できます。

CIパイプラインでは、内部または秘密のストレージツール(Vaultなど)を使用してください。