Terraform が管理できるのは、自身が作成した設定か、後から明示的に知らせた設定だけです。Terraform は管理対象リソースの権威ある状態を把握することを前提にしているためです。どのリソースを管理し、それらがどのような状態にあるかは、次の 2 種類のファイルで判断します。変更のタイミングと方法も、これらのファイルから決まります。
- 設定ファイル ↗(拡張子
.tf)は、Terraform が管理するリソースの設定を定義します。チュートリアルの手順で扱ったのがこのファイルです。 - ローカルの state ファイル ↗ は、設定ファイルで定義したリソース名(例:
cloudflare_load_balancer.www-lb)を、Cloudflare 上に存在するリソースへ対応づけます。
チュートリアル で説明しているとおり、Terraform が Cloudflare の API を呼び出して新しいリソースを作成すると、その ID を state ファイルへ保存します。デフォルトでは、ディレクトリ内の terraform.tfstate を使いますが、リモートの場所 ↗ にもできます。これらの ID は、後で terraform plan と terraform apply を実行したときに参照され、最新の状態へ更新されます。
Cloudflare ダッシュボードへのログインや、api.cloudflare.com への curl 呼び出しなど、別の方法で Cloudflare を設定した場合、Terraform の state ファイルにはまだこれらのリソース ID がありません。既存の設定を管理するには、まず設定ファイルに同じ内容を再現し、ID とリソース名を指定してリソースを個別にインポートします。
cf-terraforming ↗ は、既存の Cloudflare ユーザーが Terraform を使い始めるためのツールです。現在、cf-terraforming は、指定したアカウントやゾーンから特定タイプのリソースをすべて取得し、Terraform の設定状態の生成を支援します。
始める前に、cf-terraforming をインストールします。
macOS で Homebrew を使っている場合は、ターミナルを開いて次のコマンドを実行します。
brew tap cloudflare/cloudflare
brew install cloudflare/cloudflare/cf-terraforming別の OS を使っている場合は、cf-terraforming の GitHub リポジトリから 最新リリースをダウンロード ↗ します。
ヘルプを表示するには、cf-terraforming または cf-terraforming -h を実行します。
cf-terraforming を使うときは、次の項目を指定します。
- 実行するコマンド(例:
generateまたはimport)。 - Cloudflare のユーザーメール —
--emailまたは-e。 - Cloudflare の API トークン —
--tokenまたは-t。 - リソースを取得するアカウントやゾーン —
--account/--zoneまたは-a/-z。 - 設定を生成する Cloudflare リソース。
対応リソースの一覧は、Terraform README ↗ にあります。
DNS レコードなど、既存の Cloudflare リソースを Terraform で管理し始めるには、次のものが必要です。
- そのリソースの Terraform 設定(
.tfファイルで定義) - そのリソースの状態を表す、対応する Terraform の state ファイル(
.tfstateファイルで定義)
Terraform の設定ファイルがまだない場合は、次のように provider ブロックを定義します。
provider 'cloudflare' {
# Cloudflare email saved in $CLOUDFLARE_EMAIL
# Cloudflare API token saved in $CLOUDFLARE_API_TOKEN
}認証情報は環境変数、またはソースファイルにコミットしない terraform autovars に保存してください。
Terraform で管理したいゾーンの DNS レコードについて、cf-terraforming generate を呼び出して Terraform 設定を生成します。
cf-terraforming generate --email $CLOUDFLARE_EMAIL --token $CLOUDFLARE_API_TOKEN -z 1109d899a5ff5fd74bc01e581693685b --resource-type cloudflare_record > importing-example.tf出力を importing-example.tf ファイルへリダイレクトしなかった場合、標準出力(ターミナルウィンドウ)には次のように表示されます。
resource "cloudflare_record" "terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31" {
name = "@"
type = "A"
ttl = 1
proxied = true
value = "192.0.2.1"
zone_id = "1109d899a5ff5fd74bc01e581693685b"
}
resource "cloudflare_record" "terraform_managed_resource_5e10399a590a45279f09aa8fb1163354" {
name = "www"
type = "CNAME"
ttl = 1
proxied = true
value = "mitigateddos.net"
zone_id = "1109d899a5ff5fd74bc01e581693685b"
}
resource "cloudflare_record" "terraform_managed_resource_de1cb74bae184b569bb7f83fefe72248" {
name = "a123"
type = "NS"
ttl = 300
proxied = false
value = "rafe.ns.cloudflare.com"
zone_id = "1109d899a5ff5fd74bc01e581693685b"
}
resource "cloudflare_record" "terraform_managed_resource_5799bb01054843eea726758f935d2aa2" {
name = "a123"
type = "NS"
ttl = 300
proxied = false
value = "terin.ns.cloudflare.com"
zone_id = "1109d899a5ff5fd74bc01e581693685b"
}この時点で terraform plan を実行すると、ローカルの state ファイルに存在しないため、これらのリソースがまだないものとして作成しようとします。
terraform planTerraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# cloudflare_record.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31 will be created
+ resource "cloudflare_record" "terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31" {
+ id = (known after apply)>
+ created_on = (known after apply)
+ domain = "mitigateddos.net"
+ hostname = (known after apply)
+ metadata = (known after apply)
+ modified_on = (known after apply)
+ name = "mitigateddos.net"
+ proxiable = (known after apply)
+ proxied = true
+ ttl = 1
+ type = "A"
+ value = "192.0.2.1"
+ zone_id = "1109d899a5ff5fd74bc01e581693685b"
}
# cloudflare_record.terraform_managed_resource_5e10399a590a45279f09aa8fb1163354 will be created
+ resource "cloudflare_record" "terraform_managed_resource_5e10399a590a45279f09aa8fb1163354" {
+ id = (known after apply)
+ created_on = (known after apply)
+ domain = "mitigateddos.net"
+ hostname = (known after apply)
+ metadata = (known after apply)
+ modified_on = (known after apply)
+ name = "www.mitigateddos.net"
+ proxiable = (known after apply)
+ proxied = true
+ ttl = 1
+ type = "CNAME"
+ value = "mitigateddos.net"
+ zone_id = "1109d899a5ff5fd74bc01e581693685b"
}
# cloudflare_record.terraform_managed_resource_de1cb74bae184b569bb7f83fefe72248 will be created
+ resource "cloudflare_record" "terraform_managed_resource_de1cb74bae184b569bb7f83fefe72248" {
+ id = (known after apply)
+ created_on = (known after apply)
+ domain = "mitigateddos.net"
+ hostname = (known after apply)
+ metadata = (known after apply)
+ modified_on = (known after apply)
+ name = "a123.mitigateddos.net"
+ proxiable = (known after apply)
+ proxied = false
+ ttl = 300
+ type = "NS"
+ value = "rafe.ns.cloudflare.com"
+ zone_id = "1109d899a5ff5fd74bc01e581693685b"
}
# cloudflare_record.terraform_managed_resource_5799bb01054843eea726758f935d2aa2 will be created
+ resource "cloudflare_record" "terraform_managed_resource_5799bb01054843eea726758f935d2aa2" {
+ id = (known after apply)
+ created_on = (known after apply)
+ domain = "mitigateddos.net"
+ hostname = (known after apply)
+ metadata = (known after apply)
+ modified_on = (known after apply)
+ name = "a123.mitigateddos.net"
+ proxiable = (known after apply)
+ proxied = false
+ ttl = 300
+ type = "NS"
+ value = "terin.ns.cloudflare.com"
+ zone_id = "1109d899a5ff5fd74bc01e581693685b"
}
Plan: 4 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't use the -out option to save this plan, so Terraform can't
guarantee to take exactly these actions if you run "terraform apply" now.これを正すには、Cloudflare 上の実際の状態を Terraform の state ファイル(.tfstate)へインポートします。
cf-terraforming では、設定のインポート時と同じリソースについて、ローカルの state(.tfstate ファイル)をインポートできます。
cf-terraforming import ... を実行すると、あとで手動で実行する必要がある terraform import ... コマンドの一覧が得られます。現時点では手動の手順ですが、将来は自動化される可能性があります。
-
次のコマンドを実行します。
cf-terraforming import --resource-type "cloudflare_record" --email $CLOUDFLARE_EMAIL --key $CLOUDFLARE_API_KEY --zone $CLOUDFLARE_ZONE_ID -
出力に含まれる各
terraform import ...コマンドをコピーして実行します。Terraform は各リソースを個別に Terraform の state へインポートします。
たとえば、最初のコマンド(cf-terraforming import ...)の出力に、次の terraform コマンドが含まれていたとします。
terraform import cloudflare_record.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31 1109d899a5ff5fd74bc01e581693685b/3c0b456bc2aa443089c5f40f45f51b31
terraform import cloudflare_record.terraform_managed_resource_5e10399a590a45279f09aa8fb1163354 1109d899a5ff5fd74bc01e581693685b/d09d916d059aa9fc8cb54bdd49deea5f
terraform import cloudflare_record.terraform_managed_resource_de1cb74bae184b569bb7f83fefe72248 1109d899a5ff5fd74bc01e581693685b/8d6ec0d02c5b22212ff673782c816ef8
terraform import cloudflare_record.terraform_managed_resource_5799bb01054843eea726758f935d2aa2 1109d899a5ff5fd74bc01e581693685b/3766b952a2dda4c47e71952aeef33c77各コマンドをターミナルで個別に実行します。
terraform import cloudflare_record.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31 1109d899a5ff5fd74bc01e581693685b/3c0b456bc2aa443089c5f40f45f51b31cloudflare_record.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31: Importing from ID "1109d899a5ff5fd74bc01e581693685b/3c0b456bc2aa443089c5f40f45f51b31"...
cloudflare_record.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31: Import complete!
Imported cloudflare_record [id=3c0b456bc2aa443089c5f40f45f51b31]
cloudflare_record.terraform_managed_resource_3c0b456bc2aa443089c5f40f45f51b31: Refreshing state... [id=3c0b456bc2aa443089c5f40f45f51b31]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.terraform import cloudflare_record.terraform_managed_resource_5e10399a590a45279f09aa8fb1163354 1109d899a5ff5fd74bc01e581693685b/d09d916d059aa9fc8cb54bdd49deea5fcloudflare_record.terraform_managed_resource_5e10399a590a45279f09aa8fb1163354: Importing from ID "1109d899a5ff5fd74bc01e581693685b/d09d916d059aa9fc8cb54bdd49deea5f"...
cloudflare_record.terraform_managed_resource_5e10399a590a45279f09aa8fb1163354: Import complete!
Imported cloudflare_record [id=d09d916d059aa9fc8cb54bdd49deea5f]
cloudflare_record.terraform_managed_resource_5e10399a590a45279f09aa8fb1163354: Refreshing state... [id=d09d916d059aa9fc8cb54bdd49deea5f]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.terraform import cloudflare_record.terraform_managed_resource_de1cb74bae184b569bb7f83fefe72248 1109d899a5ff5fd74bc01e581693685b/8d6ec0d02c5b22212ff673782c816ef8cloudflare_record.terraform_managed_resource_de1cb74bae184b569bb7f83fefe72248: Importing from ID "1109d899a5ff5fd74bc01e581693685b/8d6ec0d02c5b22212ff673782c816ef8"...
cloudflare_record.terraform_managed_resource_de1cb74bae184b569bb7f83fefe72248: Import complete!
Imported cloudflare_record [id=8d6ec0d02c5b22212ff673782c816ef8]
cloudflare_record.terraform_managed_resource_de1cb74bae184b569bb7f83fefe72248: Refreshing state... [id=8d6ec0d02c5b22212ff673782c816ef8]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.terraform import cloudflare_record.terraform_managed_resource_5799bb01054843eea726758f935d2aa2 1109d899a5ff5fd74bc01e581693685b/3766b952a2dda4c47e71952aeef33c77cloudflare_record.terraform_managed_resource_5799bb01054843eea726758f935d2aa2: Importing from ID "1109d899a5ff5fd74bc01e581693685b/3766b952a2dda4c47e71952aeef33c77"...
cloudflare_record.terraform_managed_resource_5799bb01054843eea726758f935d2aa2: Import complete!
Imported cloudflare_record [id=3766b952a2dda4c47e71952aeef33c77]
cloudflare_record.terraform_managed_resource_5799bb01054843eea726758f935d2aa2: Refreshing state... [id=3766b952a2dda4c47e71952aeef33c77]
Import successful!
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.この状態で terraform plan を実行すると、Terraform が cloudflare_record リソースを再作成しようとしなくなっていることがわかります。
terraform plan | grep changesNo changes. Infrastructure is up-to-date.