IaCってなんだ?
最近IaCという言葉をよく聞くようになり、それと同時にTerraformというものもよく聞くようになった。
IaCってなんだ?と思い調べてみるとAWSのドキュメントを発見。
Infrastructure as Code (IaC) とは、手動のプロセスや設定の代わりにコードを使用してコンピューティングインフラストラクチャをプロビジョニングおよびサポートできることをいいます。
とのことらしい。
要するに今までGCPやAWSなどのインフラに関する設定をコンソール画面で行っていたが、それをコードでできるようにしようっていうものらしい。
それにより以下のメリットがあるとのこと。
- 環境を簡単に複製できる
- 設定エラーの低減ができる
- 設定がまとまるので管理がしやすくなる
企業のような大きいサービスをいくつも提供していたり、複数の環境が必要な場合であればIaCによるメリットはかなり大きいかなと思うが、個人の趣味開発程度でIaCが必要になるのかがイマイチイメージがわかない。
ということで実際にやってみて判断してみる。
IaCにはTerraformらしい
IaCツールとは簡単に調べてみたところ主に以下の2つが出てきた。
1つ目は「Terraform」で、2つ目が「Cloudformation」というものである。
上記の比較については少し前の話ではあるが、ZennにIaCツールの比較という記事があったので読んでみた。
とりあえずTerraformを選択しておくのが良いとのことで、「Terraform 入門」みたいな感じでGoogle検索をするとたくさん記事が出てきたので、インフラ知識があまりない僕でもできるかもしれないということでTerraformを使ってIaCデビューしてみることにした。
Terraformを使ってみよう
兎にも角にもまずはインストールをする。
今回はmacOSで使用するので、Terraform公式ドキュメントを参考にインストールする。
インストールは以下の通り。
$ brew tap hashicorp/tap
$ brew install hashicorp/tap/terraform
$ terraform -v
Terraform v1.6.6
on darwin_amd64
これでインストールが完了した。
インストール自体はめっちゃ簡単でとても良い。
とりあえずお試しでCloudflareをいじってみる
Terraformのインストール
今個人的にGCPとかAWSにおいているプロジェクトがないので、お試しということもありとりあえず自身のドメインのDNSをCloudflareで管理しているのでその部分をTerraformで管理できるようにしてみる。
こちらに関してもCloudflareのドキュメントがあるのでこれのチュートリアルを参考に進めていく。
ひとまず各種ファイルを準備する。
$ touch main.tf provider.tf variables.tf terraform.tfvars
$ tree
.
├── dns.tf
├── provider.tf
├── terraform.tfvars
└── variables.tf
このファイル構成が正解なのかは分からないが、ドキュメントを見る限りこんな感じが良いらしい。
それぞれのファイルの役割として、ふんわりと自分なりに理解しているのは以下の通りである。
- provider.tf
- Terraformでインフラを操作するためには、Providerと呼ばれるインフラとやり取りするためのプラグインを設定する必要があり、その設定を記述する。
- dns.tf
- 実際にDNSに関する設定を記述するファイル。
- variables.tf
- このディレクトリにあるTerraformのファイルの中で使用する変数について記述するファイル。
- terraform.tfvars
- 変数を記述するファイル。
Providerの設定と変数の設定
まずはCloudflareとやり取りをするためのプラグインのようなものであるProviderを記述する。
terraform {
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4.0"
}
}
}
provider "cloudflare" {
api_token = var.cloudflare_api_token
}
これでとりあえずProviderの設定はOK。
次にProviderに記述している var.cloudflare_api_token
について設定する。
variable "cloudflare_api_token" {
description = "value of cloudflare api token"
type = string
}
variable "cloudflare_zone_id" {
description = "value of cloudflare zone id"
type = string
}
これで cloudflare_api_token
と cloudflare_zone_id
という変数が使えるようになったので、実際の値を terraform.tfvars
に記述する。
cloudflare_api_token = "YOUR_API_TOKEN"
cloudflare_zone_id = "YOUR_ZONE_ID"
このトークンはCloudflareのダッシュボードから発行して、操作したいゾーンに対する編集権限を付与しておく。
Terraformの初期化
ここまで来たら以下のコマンドでProviderのインストールと初期化を行う。
$ terraform init
これによりいくつかのファイルやフォルダが生成される。
実際にDNSの設定を追加してみる
さぁここまでくればあとはTerraformでいじり放題。
実際に適当なサブドメインを追加するようなものを作ってみよう。
ひとまずCloudflare PagesにデプロイしているAstro製のサイトの独自ドメインとして設定する。
resource "cloudflare_record" "tf-test-record" {
name = "tf-test-record"
proxied = false
ttl = 1
type = "CNAME"
value = "portfolio-tf.pages.dev"
zone_id = var.cloudflare_zone_id
}
cloudflare_record
というのが実際に操作するリソースになり、それに必要なプロパティを渡すことで記述する。
記述が完了したら、このコードをいきなり適用するのではなく、ドライランしてどのような操作が行われるか確認することができる。
terraform plan
をしてみると、以下のようにドライランした結果が出てくる。
$ 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.tf-test-record will be created
+ resource "cloudflare_record" "tf-test-record" {
+ 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 = "tf-test-record"
+ proxiable = (known after apply)
+ proxied = false
+ ttl = 1
+ type = "CNAME"
+ value = "portfolio-tf.pages.dev"
+ zone_id = "YOUR_ZONE_ID"
}
Plan: 1 to add, 0 to change, 0 to destroy.
これにより設定した1つの設定が追加されることがわかる。
もしここで意図していない作成や削除、変更があった際には何かがおかしいと適用する前に気づくことができるので、かなり安心だ。
今回は1つの設定を追加することで間違いないので、実際に本番反映する。
本番反映時は、 terraform apply
をする。
$ 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.tf-test-record will be created
+ resource "cloudflare_record" "tf-test-record" {
+ 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 = "tf-test-record"
+ proxiable = (known after apply)
+ proxied = false
+ ttl = 1
+ type = "CNAME"
+ value = "portfolio-tf.pages.dev"
+ zone_id = "YOUR_ZONE_ID"
}
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:
先程の terraform plan
と同じように作成される設定について表示されて、Approveするように言われるのでApproveする。
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
loudflare_record.tf-test-record: Creating...
cloudflare_record.tf-test-record: Creation complete after 1s [id=6dca4e8d3a044c9883a035ce0fef2d2e]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
これで無事に追加されたようだ。
Cloudflareのダッシュボードで確認してみる
実際に追加されているのが確認できた!
本当にコードとコマンドラインだけでDNSの操作をすることができたので、今回追加したものは削除をする。
削除自体は dns.tf
に記述したコードを削除して terraform plan
で確認して、 terraform apply
をすることで削除される。
$ terraform apply
cloudflare_record.tf-test-record: Refreshing state... [id=6dca4e8d3a044c9883a035ce0fef2d2e]
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.tf-test-record will be destroyed
# (because cloudflare_record.tf-test-record is not in configuration)
- resource "cloudflare_record" "tf-test-record" {
- allow_overwrite = false -> null
- created_on = "2024-01-14T02:13:19.862411Z" -> null
- hostname = "tf-test-record.gardenia-710.com" -> null
- id = "6dca4e8d3a044c9883a035ce0fef2d2e" -> null
- metadata = {
- "auto_added" = "false"
- "managed_by_apps" = "false"
- "managed_by_argo_tunnel" = "false"
- "source" = "primary"
} -> null
- modified_on = "2024-01-14T02:13:19.862411Z" -> null
- name = "tf-test-record" -> null
- proxiable = true -> null
- proxied = false -> null
- tags = [] -> null
- ttl = 1 -> null
- type = "CNAME" -> null
- value = "portfolio-tf.pages.dev" -> null
- zone_id = "YOUR_ZONE_ID" -> null
}
Plan: 0 to add, 0 to change, 1 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.tf-test-record: Destroying... [id=6dca4e8d3a044c9883a035ce0fef2d2e]
cloudflare_record.tf-test-record: Destruction complete after 0s
Apply complete! Resources: 0 added, 0 changed, 1 destroyed.
これで掃除も完了!
その他のリソースの操作
CloudflareのProviderのドキュメントを読むと今回使用した cloudflare_record
以外のリソースに関する情報も記載されている。
PagesやWorkersに関するものや、R2やD1についてもTerraformで管理できるようなので今度試してみたい。
まとめ
IaCデビューということでTerraformを触ってみたが、予想以上に簡単で驚いた。
もちろん実際にGCPやAWS等を使用して1つのアプリケーションを運用しようとなったら様々なリソースを連携させる必要があるためもっと複雑にはなるため、今回とはまた違うと思うが、だからこそ一度型を作ってしまえば同じような環境の複製は簡単にできると感じた。
今度クラウドに何かをデプロイする必要があるときはTerraformで管理できるようにしてみたい。
ありがとうございました。