4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

CloudflareAdvent Calendar 2021

Day 25

Cloudflare + Hashicorp Terraform [ 後編 ]

Last updated at Posted at 2021-12-24

前回の投稿にてAWSのCloud9上にTerraformとcf-terraformingの実行環境を用意しました.
今回は、この環境を使って実際にCloudflareに対して設定の変更をおこなってみようと思います.

本投稿では、認証関連の情報は作業ディレクトリ配下のファイルに纏めておきます.

~/environment/cloudflare-terraform/.cf-terraforming.yaml
email: "EMAIL-ADDRESS"
key: "CLOUDFLARE-API-KEY"
account: "CLOUDFLARE_ACCOUNT_ID"
zone: "ZONE-ID"

動作を再現される際には上記値はご利用の環境に応じたものに置き換えてえ実行してください.

Cloudflare側の設定

前回記事の最後に、既存の設定を引っ張ってくるという結果を記載いたしましたが、Cloudfareの既存の設定として以下が投入されています.

image.png

管理中のゾーンのAレコードとしてwww1が登録されています.
(既存管理方法としてCloudflareダッシュボードから設定を投入ずみという想定).

ここに新しくwww2のAレコードを登録します.

登録する内容は作業ディレクトリ内にwww2.tfとして以下を記述します.
(www1と異なるのは登録しているIPアドレスが異なる点のみです.)

touch www2.tf

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のダッシュボードを確認してみると、

image.png

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
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した場合は以下のようになります.

image.png

上段が、Terraformで新たに追加したレコード、下段が既存のレコードです.

今回はあえて、既存のコンフィグと重なるような設定をいれてみましたが、本来、Terraformで運用を纏める場合にはStateファイルに既存の設定を管理できるように組み込んであげる必要があります.

その手順を記載します.

先に、不要なコンフィグレーションは削除しておきます.(www1の既存コンフィグのみが残ります)

terraform destroy

image.png

terraform import

Terraform Registryのcloudflare_recordを参考にImportを実施します.

コマンドの書式は

$ terraform import cloudflare_record.<管理リソース名> <ZoneID>/<RecordID>

となっています.
ZoneIDはCloudflareのダッシュボードのサイトのトップからも確認が可能です.

image.png

RecordIDはAPIによって確認ができます(ZoneIDも合わせて確認できます).

image.png

※ APIでリクエストを投げる手順に関してはこちらの記事を参照ください.

このRecordIDとZoneIDはcf-terraformingコマンドで出力したコマンド結果にも表示されています.

image.png

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重に設定が投入されるという事もありません.)

image.png

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など引き続き試してみたいと思います.

この投稿が皆様のお役に立てれば幸いです.

参考リンク

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?