前回の投稿にてAWSのCloud9上にTerraformとcf-terraformingの実行環境を用意しました.
今回は、この環境を使って実際にCloudflareに対して設定の変更をおこなってみようと思います.
本投稿では、認証関連の情報は作業ディレクトリ配下のファイルに纏めておきます.
email: "EMAIL-ADDRESS"
key: "CLOUDFLARE-API-KEY"
account: "CLOUDFLARE_ACCOUNT_ID"
zone: "ZONE-ID"
動作を再現される際には上記値はご利用の環境に応じたものに置き換えてえ実行してください.
Cloudflare側の設定
前回記事の最後に、既存の設定を引っ張ってくるという結果を記載いたしましたが、Cloudfareの既存の設定として以下が投入されています.
管理中のゾーンのAレコードとしてwww1が登録されています.
(既存管理方法としてCloudflareダッシュボードから設定を投入ずみという想定).
ここに新しくwww2のAレコードを登録します.
登録する内容は作業ディレクトリ内にwww2.tfとして以下を記述します.
(www1と異なるのは登録しているIPアドレスが異なる点のみです.)
touch www2.tf
resource "cloudflare_record" "www2" {
  name    = "www2"
  proxied = true
  ttl     = 1
  type    = "A"
  value   = "35.73.201.71"
  zone_id = "e877843d3b162b87089f8c956134fc1c"
}
こちらをCloud9上で保存して、terraformで設定を反映してみます.
まずはplanを実行.
terraform plan
develop:~/environment/cloudflare-terraform $ terraform plan
Terraform 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.www2 will be created
  + resource "cloudflare_record" "www2" {
      + allow_overwrite = false
      + created_on      = (known after apply)
      + hostname        = (known after apply)
      + id              = (known after apply)
      + metadata        = (known after apply)
      + modified_on     = (known after apply)
      + name            = "www2"
      + proxiable       = (known after apply)
      + proxied         = true
      + ttl             = 1
      + type            = "A"
      + value           = "35.73.201.71"
      + zone_id         = "e877843d3b162b87089f8c956134fc1c"
    }
Plan: 1 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.
develop:~/environment/cloudflare-terraform $ 
www2のレコードが追加される旨が出力されるので、適用(apply)します.
terraform apply
develop:~/environment/cloudflare-terraform $ terraform apply
Terraform 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.www2 will be created
  + resource "cloudflare_record" "www2" {
      + allow_overwrite = false
      + created_on      = (known after apply)
      + hostname        = (known after apply)
      + id              = (known after apply)
      + metadata        = (known after apply)
      + modified_on     = (known after apply)
      + name            = "www2"
      + proxiable       = (known after apply)
      + proxied         = true
      + ttl             = 1
      + type            = "A"
      + value           = "35.73.201.71"
      + zone_id         = "e877843d3b162b87089f8c956134fc1c"
    }
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
  Enter a value: yes
cloudflare_record.www2: Creating...
cloudflare_record.www2: Creation complete after 2s [id=c2e59abeb88667392ab9e888e14bad81]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
develop:~/environment/cloudflare-terraform $ 
作成されました.
Cloudflareのダッシュボードを確認してみると、
www2が追加されていることが確認できます.
もちろん、destroyの実行も可能です.
develop:~/environment/cloudflare-terraform $ terraform destroy
cloudflare_record.www2: Refreshing state... [id=c2e59abeb88667392ab9e888e14bad81]
:略:
cloudflare_record.www2: Destroying... [id=c2e59abeb88667392ab9e888e14bad81]
cloudflare_record.www2: Destruction complete after 0s
Destroy complete! Resources: 1 destroyed.
develop:~/environment/cloudflare-terraform $ 
ここまでの内容を纏めると、
- 新しいレコードをterrafromで管理するためにはTFファイルを新規作成すればよい
- 新しいTFファイルを元にapply/destroyを実施しても既存の設定には影響を与えていない
ことが確認できました.
では、既存のコンフィグであるwww1をTerraform管理下に持ってきます.
ひとまずは何も考えずにwww1.tfを作成してみます.
記述内容はcf-terraformingの実行結果をそのままファイルにしています.
cf-terraforming generate \
   --account $CLOUDFLARE_ACCOUNT_ID \
   --zone $CLOUDFLARE_ZONE_ID \
   --resource-type "cloudflare_record" > www1.tf
resource "cloudflare_record" "terraform_managed_resource_65b157b60750cdf47f36a4e275a83764" {
  name    = "www1"
  proxied = true
  ttl     = 1
  type    = "A"
  value   = "176.32.67.255"
  zone_id = "e877843d3b162b87089f8c956134fc1c"
}
この状況下で、先ほどと同じようにplanを実行すると、
develop:~/environment/cloudflare-terraform $ terraform plan
cloudflare_record.www2: Refreshing state... [id=1bf52e13290d7a3ae776a3e16781b581]
Terraform 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_65b157b60750cdf47f36a4e275a83764 will be created
  + resource "cloudflare_record" "terraform_managed_resource_65b157b60750cdf47f36a4e275a83764" {
  + 
:略:
Plan: 1 to add, 0 to change, 0 to destroy.
www1のレコードが新たに作成しようとする旨が表示されます.
このままApplyをしようとすると、、、
develop:~/environment/cloudflare-terraform $ terraform apply
cloudflare_record.www2: Refreshing state... [id=1bf52e13290d7a3ae776a3e16781b581]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
:略:
  Enter a value: yes
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Creating...
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Still creating... [10s elapsed]
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Still creating... [20s elapsed]
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Still creating... [30s elapsed]
╷
│ Error: expected DNS record to not already be present but already exists
│ 
│   with cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764,
│   on www1.tf line 1, in resource "cloudflare_record" "terraform_managed_resource_65b157b60750cdf47f36a4e275a83764":
│    1: resource "cloudflare_record" "terraform_managed_resource_65b157b60750cdf47f36a4e275a83764" {
│ 
╵
develop:~/environment/cloudflare-terraform $ 
Error: expected DNS record to not already be present but already existsと表示され作成に失敗します.
今回は設定内容が既存と完全に一致していた例ですが、設定の内容によっては一部のコンフィグレーションが変わっていると普通に登録できてしまうものもあります.
例えば、AレコードのIPアドレスだけを別のものに弄ってApplyした場合は以下のようになります.
上段が、Terraformで新たに追加したレコード、下段が既存のレコードです.
今回はあえて、既存のコンフィグと重なるような設定をいれてみましたが、本来、Terraformで運用を纏める場合にはStateファイルに既存の設定を管理できるように組み込んであげる必要があります.
その手順を記載します.
先に、不要なコンフィグレーションは削除しておきます.(www1の既存コンフィグのみが残ります)
terraform destroy
terraform import
Terraform Registryのcloudflare_recordを参考にImportを実施します.
コマンドの書式は
$ terraform import cloudflare_record.<管理リソース名> <ZoneID>/<RecordID>
となっています.
ZoneIDはCloudflareのダッシュボードのサイトのトップからも確認が可能です.
RecordIDはAPIによって確認ができます(ZoneIDも合わせて確認できます).
※ APIでリクエストを投げる手順に関してはこちらの記事を参照ください.
このRecordIDとZoneIDはcf-terraformingコマンドで出力したコマンド結果にも表示されています.
terraform importコマンドを実行します.
develop:~/environment/cloudflare-terraform $ terraform import cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764 e877843d3b162b87089f8c956134fc1c/65b157b60750cdf47f36a4e275a83764 
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Importing from ID "e877843d3b162b87089f8c956134fc1c/65b157b60750cdf47f36a4e275a83764"...
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Import prepared!
  Prepared cloudflare_record for import
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Refreshing state... [id=65b157b60750cdf47f36a4e275a83764]
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.
StateFileに既存のコンフィグレーションを取り入れることができました.
上記コマンドの
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764
部分は
cloudflare_record.部分は扱うリソースタイプ(今回はDNSレコードを対象としている)、
terraform_managed_resource_65b157b60750cdf47f36a4e275a83764部分は、TFファイルに記述されているリソース名
をそれぞれ指しています.
今回はcf-terraforming generateの出力結果をそのままTFファイルにしたため、
「terraform_managed_resource_」と「リソースID」の組み合わせで記述されていますが、
実際には運用を加味した命名規則で管理すると思います.
その場合、terraform importコマンドとTFコマンドの記述が一致していないとエラーになるのでご注意ください.
この状態で改めてplanを実行すると
develop:~/environment/cloudflare-terraform $ terraform plan
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Refreshing state... [id=65b157b60750cdf47f36a4e275a83764]
Terraform 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.www2 will be created
  + resource "cloudflare_record" "www2" {
      + allow_overwrite = false
      + created_on      = (known after apply)
      + hostname        = (known after apply)
      + id              = (known after apply)
      + metadata        = (known after apply)
      + modified_on     = (known after apply)
      + name            = "www2"
      + proxiable       = (known after apply)
      + proxied         = true
      + ttl             = 1
      + type            = "A"
      + value           = "35.73.201.71"
      + zone_id         = "e877843d3b162b87089f8c956134fc1c"
    }
Plan: 1 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.
となり、先ほどのdestroyで消してあったwww2のみが作成(www1は改めて作成の対象とはなっていない)ことが確認できます.
develop:~/environment/cloudflare-terraform $ terraform apply
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Refreshing state... [id=65b157b60750cdf47f36a4e275a83764]
Terraform 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.www2 will be created
  + resource "cloudflare_record" "www2" {
      + allow_overwrite = false
      + created_on      = (known after apply)
      + hostname        = (known after apply)
      + id              = (known after apply)
      + metadata        = (known after apply)
      + modified_on     = (known after apply)
      + name            = "www2"
      + proxiable       = (known after apply)
      + proxied         = true
      + ttl             = 1
      + type            = "A"
      + value           = "35.73.201.71"
      + zone_id         = "e877843d3b162b87089f8c956134fc1c"
    }
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
  Enter a value: yes
cloudflare_record.www2: Creating...
cloudflare_record.www2: Creation complete after 1s [id=6bc7e3b1de12dd5949ff891de66b767d]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
今度はエラーなくApplyが実行できました.
(2重に設定が投入されるという事もありません.)
www1もTerraformの管理下に入っているので、Destroyをしようとすると
develop:~/environment/cloudflare-terraform $ terraform destroy
cloudflare_record.www2: Refreshing state... [id=6bc7e3b1de12dd5949ff891de66b767d]
cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764: Refreshing state... [id=65b157b60750cdf47f36a4e275a83764]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  - destroy
Terraform will perform the following actions:
  # cloudflare_record.terraform_managed_resource_65b157b60750cdf47f36a4e275a83764 will be destroyed
  - resource "cloudflare_record" "terraform_managed_resource_65b157b60750cdf47f36a4e275a83764" {
      - created_on  = "2021-10-15T05:10:39.311599Z" -> null
      - hostname    = "www1.free.cfpoc.ted-tech.org" -> null
      - id          = "65b157b60750cdf47f36a4e275a83764" -> null
      - metadata    = {
          - "auto_added"             = "false"
          - "managed_by_apps"        = "false"
          - "managed_by_argo_tunnel" = "false"
          - "source"                 = "primary"
        } -> null
      - modified_on = "2021-10-15T05:10:39.311599Z" -> null
      - name        = "www1" -> null
      - proxiable   = true -> null
      - proxied     = true -> null
      - ttl         = 1 -> null
      - type        = "A" -> null
      - value       = "176.32.67.255" -> null
      - zone_id     = "e877843d3b162b87089f8c956134fc1c" -> null
      - timeouts {}
    }
  # cloudflare_record.www2 will be destroyed
  - resource "cloudflare_record" "www2" {
      - allow_overwrite = false -> null
      - created_on      = "2021-12-23T07:01:50.356317Z" -> null
      - hostname        = "www2.free.cfpoc.ted-tech.org" -> null
      - id              = "6bc7e3b1de12dd5949ff891de66b767d" -> null
      - metadata        = {
          - "auto_added"             = "false"
          - "managed_by_apps"        = "false"
          - "managed_by_argo_tunnel" = "false"
          - "source"                 = "primary"
        } -> null
      - modified_on     = "2021-12-23T07:01:50.356317Z" -> null
      - name            = "www2" -> null
      - proxiable       = true -> null
      - proxied         = true -> null
      - ttl             = 1 -> null
      - type            = "A" -> null
      - value           = "35.73.201.71" -> null
      - zone_id         = "e877843d3b162b87089f8c956134fc1c" -> null
    }
Plan: 0 to add, 0 to change, 2 to destroy.
Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.
  Enter a value:
削除対象にも含まれていることが確認できます.
これによりwww1はTFファイルでの管理が可能になります.
まとめ
terraformを使ってCloudflareの設定をコントロールするという記事を投稿をさせていただきました.
その中で今回は簡易な検証環境の展開方法と、実行する上での注意点を記載させていただきました.
cf-terraforming自体、現時点においてすべてのリソースタイプをカバーしている状況にはありませんが、更新も頻繁におこなわれているので興味がある方はチェックしてみることをお勧めします.
今回は深堀しなかったその他のリソースやcf-terraformingコマンドからのimportなど引き続き試してみたいと思います.
この投稿が皆様のお役に立てれば幸いです.
参考リンク






