Cloudflare PagesのリソースをTerraform管理する
このブログはCloudflare Pages + Hugoでホスティングしているのですが、Hugoのバージョンを変えるなどCloudflare Pages側の設定をいじるタイミングがちょこちょこ発生します。
もう少しCloudflare色々触ってみたかったので、stateをR2で管理しながらPagesのリソースをTerraform管理してみます。
R2 bucket作成からアクセスまで
まずはR2のbucket作成します。
無料枠でもクレジットカード or Paypalの登録が必要です。
登録したらbucket作成し、R2専用のAPI Tokenも作成します。
Bucket作成
API Token作成
Token作成後にapi key, secretが作成されるので、以下のリンクを参考にクレデンシャルの設定と疎通確認をします。
1% cat .aws/config
2[cloudflare]
3region = auto
4
5% cat .aws/credentials
6[cloudflare]
7aws_access_key_id = key
8aws_secret_access_key = secret
9
10% aws s3api list-objects-v2 --endpoint-url https://[accountid].r2.cloudflarestorage.com --profile cloudflare --bucket tfstate
11{
12 "RequestCharged": null
13}
terraform backendの設定
基本的には以下の記事を参考に進めました。
Cloudflare R2でTerraformのStateを管理する方法: Cloudflare Meetup Nagano Vol.2 に登壇しました
ただしTerraform v1.6以降だと NotImplemented: STREAMING-UNSIGNED-PAYLOAD-TRAILER
のエラーが発生するなど少し挙動が変わっているため、以下の二行も追加してあげます。
ref: Support Cloudflare r2 for storing Terraform state
1 skip_requesting_account_id = true
2 skip_s3_checksum = true
最終的な設定は以下です。
1terraform {
2 required_providers {
3 cloudflare = {
4 source = "cloudflare/cloudflare"
5 version = "~> 4.0"
6 }
7 }
8
9 backend "s3" {
10 bucket = "tfstate"
11 key = "default.tfstate"
12 region = "us-east-1"
13 profile = "cloudflare"
14 endpoints = { s3 = "https://[accountid].r2.cloudflarestorage.com" }
15 skip_credentials_validation = true
16 skip_requesting_account_id = true
17 skip_s3_checksum = true
18 }
19}
その後にinitを実行し疎通確認します。
1% terraform init
2
3Initializing the backend...
4
5Successfully configured the backend "s3"! Terraform will automatically
6use this backend unless the backend configuration changes.
7
8Initializing provider plugins...
9- Finding cloudflare/cloudflare versions matching "~> 4.0"...
10- Installing cloudflare/cloudflare v4.21.0...
11- Installed cloudflare/cloudflare v4.21.0 (self-signed, key ID C76001609EE3B136)
12
13Partner and community providers are signed by their developers.
14If you'd like to know more about provider signing, you can read about it here:
15https://www.terraform.io/docs/cli/plugins/signing.html
16
17Terraform has created a lock file .terraform.lock.hcl to record the provider
18selections it made above. Include this file in your version control repository
19so that Terraform can guarantee to make the same selections by default when
20you run "terraform init" in the future.
21
22Terraform has been successfully initialized!
23
24You may now begin working with Terraform. Try running "terraform plan" to see
25any changes that are required for your infrastructure. All Terraform commands
26should now work.
27
28If you ever set or change modules or backend configuration for Terraform,
29rerun this command to reinitialize your working directory. If you forget, other
30commands will detect it and remind you to do so if necessary.
resourceのimport
あとは以下の流れで進めていきます。
- API Token設定
- provider設定
- 既存リソースのimport
User API Tokens からAPI Tokenを発行します。
1. Use environment variables for authentication を参考に環境変数に設定します。
1export CLOUDFLARE_API_TOKEN=xxx
その後にproviderの設定をします。
1provider "cloudflare" {
2 # token pulled from $CLOUDFLARE_API_TOKEN
3}
そして最後は既存のリソースのimportをします。
最終的なリソース定義
1resource "cloudflare_pages_project" "my-project" {
2 account_id = var.account_id
3 name = var.project_name
4 production_branch = var.production_branch
5
6 build_config {
7 build_command = var.build_command
8 destination_dir = var.destination_dir
9 web_analytics_tag = var.web_analytics_tag
10 web_analytics_token = var.web_analytics_token
11 }
12
13 deployment_configs {
14 preview {
15 always_use_latest_compatibility_date = false
16 fail_open = true
17 environment_variables = {
18 GO_VERSION = var.go_version
19 HUGO_VERSION = var.hugo_version
20 }
21 }
22 production {
23 always_use_latest_compatibility_date = false
24 fail_open = true
25 environment_variables = {
26 GO_VERSION = var.go_version
27 HUGO_VERSION = var.hugo_version
28 }
29 }
30 }
31
32 source {
33 type = "github"
34 config {
35 owner = var.repo_owner
36 repo_name = var.repo_name
37 production_branch = var.production_branch
38 pr_comments_enabled = true
39 deployments_enabled = true
40 production_deployment_enabled = true
41 preview_branch_includes = ["*"]
42 }
43 }
44
45}
46
47resource "cloudflare_pages_domain" "my-domain" {
48 account_id = var.account_id
49 project_name = var.project_name
50 domain = var.domain_name
51}
まとめ
思ったよりサクサクいけたのと、tfstate管理にR2結構良いんじゃないかなという感想。
API Token周りの概念が割と初見だとわかりにくいかもと思った。