Terraform Cloud を使う利点 #
Terraform Cloud を使用すると、Terraform の state ファイルをクラウドで管理できるため、ローカル環境に依存せずに Infrastructure as Code (IaC) を実現できます。
cf-terraforming について #
cf-terraforming
は、既存の Cloudflare リソースを Terraform のコードとしてエクスポートするツールです。これを利用して、Cloudflare の設定を Terraform で管理しようとしましたが、いくつかの問題に遭遇しました。
バージョンに関する問題 #
まず、cf-terraforming
を実行した際に以下のエラーが発生しました。
$ cf-terraforming --resource-type cloudflare_record import --email xxx --token xxx -z xxx -v
DEBU[0000] initializing cloudflare-go with API Token account_Id= zone_id=xxx
DEBU[0003] initializing Terraform in .
DEBU[0004] detected provider version=5.5.0
FATA[0004] failed to fetch API endpoint: GET "https://api.cloudflare.com/client/v4/": 400 Bad Request {"success":false,"errors":[{"code":7000,"message":"No route for that URI"}],"messages":[],"result":null}
このエラーは、使用している cf-terraforming
が Cloudflare API の v4 系にしか対応していないことが原因でした。当時は Terraform provider のバージョン 5 系を使用していたため、API のエンドポイントが見つからなかったようです。
一時的に Terraform provider を 4 系にダウングレードすることで、この問題を回避しました。しかし、将来的には Zero Trust の管理も Terraform で行いたかったため、最終的には 5 系に戻すことにしました。
Terraform provider のバージョンを変更した際には、terraform init -upgrade
を実行して変更を反映させる必要があります。
ちなみに、Terraform provider の v4 ではリソース名が cloudflare_record
でしたが、v5 では cloudflare_dns_record
に変更されています。そのため、cf-terraforming
で出力されたリソース名を書き換える必要がありました。
インポート時のエラー #
次に、Terraform の import を実行した際に以下のエラーが発生しました。
╷
│ Warning: Value for var.CLOUDFLARE_API_TOKEN unavailable
│
│ The value of variable "CLOUDFLARE_API_TOKEN" is marked as sensitive in the remote workspace. This operation always runs locally, so the value for that
│ variable is not available.
╵
╷
│ Error: Invalid provider configuration
│
│ on /Users/kaz/dev/cha-dev/provider.tf line 10:
│ 10: provider "cloudflare" {
│
│ The configuration for provider["registry.terraform.io/cloudflare/cloudflare"] depends on values that cannot be determined until apply.
╵
Terraform の import はローカルで実行されるため、Terraform Cloud で設定された API トークンを読み込むことができません。そのため、一時的に terraform.tfvars
ファイルに API トークンを記述してインポートを試みました。
この際、terraform.tfvars
で API トークンをダブルクォートで囲んでいなかったため、以下のエラーが発生しました。
│ Error: Variables not allowed
│
│ on terraform.tfvars line 1:
API トークンをダブルクォートで囲むことで、この問題を解決しました。
Email Routing との競合 #
Terraform で apply を実行した際に、Email Routing で管理されている DNS レコードに対して API エラーが発生しました。
Error: failed to make http request
│
│ DELETE
│ "https://api.cloudflare.com/client/v4/zones/zoneid/dns_records/recordid":
│ 400 Bad Request
│ {"result":null,"success":false,"errors":[{"code":1046,"message":"This
│ record is managed by Email Routing. Disable Email Routing to modify/remove
│ this record."}],"messages":[]}
╵
Email Routing で管理されている DNS レコードは、Terraform から直接管理できないため、該当のリソースを Terraform のコードから削除する必要がありました。
しかし、リソースを削除すると Terraform が削除を試み、同じエラーが発生しました。
この問題を解決するために、terraform state rm
コマンドを使用して、Terraform の state ファイルから該当のリソースを削除しました。
terraform state rm <resource_address>
record id について #
後々分かったことですが、dnsレコードをterraformにimportするときに必要なrecordidはダッシュボードの監査ログのリソースIDのことでした。
まとめ #
Terraform Cloud を使用して Cloudflare の DNS レコードを管理する際には、いくつかの問題に遭遇する可能性があります。しかし、これらの問題を解決することで、Terraform による Cloudflare の IaC を実現できます。
今後は、Pages や Zero Trust の設定も Terraform で管理できるように進めていきたいと思います。