← Провайдер Cloudflare Terraform / terraform / advanced-topics
Рекомендации
Хотя каждое развёртывание Terraform уникально, следуйте этим рекомендациям, чтобы добиться успешного результата.
Управление ресурсами через Terraform
Terraform работает наиболее эффективно, когда он управляет всеми изменениями и жизненным циклом ресурса.
После любой операции с конфигурацией Terraform пытается устранить расхождения, синхронизируя удалённое состояние с локальным. Если между локальным и удалённым состоянием есть различия (например, из-за управления ресурсами вне Terraform), может потребоваться удалить и заново создать ресурс в файле состояния (обычно через импорт), поскольку не все ресурсы поддерживают обновление на месте.
Структура каталогов
Cloudflare рекомендует использовать структуру каталогов, основанную на сочетании аккаунтов, зон и продуктов, чтобы изолировать изменения. Такой подход позволяет назначать ответственных с высокой точностью и ограничивать операции Terraform конкретным продуктом в пределах зоны. Кроме того, он точнее соответствует роли по умолчанию, а также дополнительные инструменты, такие как хранилище AWS или GCP, настроив права доступа для отдельных файлов состояния.
Для продуктов с широким набором функций, таких как Rulesets, можно пойти ещё дальше, разделив их на уровне фаз (WAF, правила перенаправления, правила источника).
example-tf/
├── demo_account_a # per account segregation of resources
│ ├── users # top level directory for account members as they are "zoneless"
│ │ ├── provider.tf # `provider.tf` is for configuring the providers
│ │ ├── users.tf # `<subject>.tf` (users.tf) is for managing the individual resources
│ │ └── vars.tf # manage all variables for this component
│ ├── zone_a # group all zone based features together
│ │ ├── dns # individual (or grouped, your choice) of products or features to manage together
│ │ │ ├── dns.tf # `<subject>.tf` (dns.tf) is for managing the individual resources
│ │ │ ├── provider.tf # `provider.tf` is for configuring the providers
│ │ │ └── vars.tf # manage all variables for this component
│ │ └── page_rules # ... same as above but for 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 и, возможно, правилом Page Rules. Конечный пользователь может использовать его следующим образом:
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 рекомендует использовать cf-terraforming , чтобы перенести существующие ресурсы в Cloudflare.
Управление частью ресурсов вне Terraform
Вполне допустимо управлять одними ресурсами через Terraform, а другими с помощью иного инструмента, но убедитесь, что вы не выполнение обоих действий для одного и того же ресурса.
Используйте отдельные окружения
Чтобы безопасно управлять отдельными средами (staging, QA, UAT, production), используйте отдельные аккаунты Cloudflare с отдельными доменами (например, example.com и example-staging.com).
Это связано с тем, что некоторые продукты, определённые на уровне аккаунта, являются общими (например, мониторы и пулы Load Balancer), и вы не можете внести изолированное изменение в них, если они находятся в одном аккаунте. Использование отдельных аккаунтов также полезно, если вы планируете тестировать такие функции, как DNSSEC, которые при неправильной настройке могут повлиять на весь домен.
Чтобы свести к минимуму расхождения, используйте Terraform и CI/CD-конвейер, который выполняется для обоих доменов и поддерживает их синхронизацию по мере необходимости.
Храните учётные данные в безопасности
Мы не рекомендуем хранить учётные данные Cloudflare в незашифрованном виде.
Локально можно использовать сторонний инструмент, например cf-vault ↗ для хранения учетных данных Cloudflare.
Для CI-конвейеров используйте внутренний инструмент или хранилище секретов (например, Vault ↗).