はじめに
こんにちは。ydogです。
Terraformの状態管理に Cloudflare R2 を使用する手順について解説していきます。
手順
難しい手順は特になく、以下のCloudflare公式ドキュメントに従って進めていくことで、R2をバックエンドに設定することができます。
- R2 バケットを作成
- R2 アクセス用のAPIキーを作成
- Terraformコードに定義する
-
terraform init -reconfigure
を実行
ここでは、特に3. Terraformコードに定義するの際の、認証情報の漏洩リスクを抑える方法について詳しく説明します。
Backend block
Terraformのbackend
ブロックでは、var
で始まる変数を利用することが出来ません。そのため、先程のリンク通りにコードを記述すると、認証情報をハードコードする必要があります。
terraform {
backend "s3" {
# 中略
access_key = "<YOUR_R2_ACCESS_KEY>"
secret_key = "<YOUR_R2_ACCESS_SECRET>"
endpoints = { s3 = "https://<YOUR_ACCOUNT_ID>.r2.cloudflarestorage.com" }
}
そのため、外部ファイルからバックエンドの情報を定義できる、*.tfbackend
ファイルを使用しましょう。
Backend block configuration overview#partial-configuration
実装
上記のbackend
ブロックを構成する場合、*.tfbackend
ファイルは、以下の通りになります。
access_key = "<YOUR_R2_ACCESS_KEY>"
secret_key = "<YOUR_R2_ACCESS_SECRET>"
endpoints = { s3 = "https://<YOUR_ACCOUNT_ID>.r2.cloudflarestorage.com" }
その後、cloudflare.tf
ファイルから認証情報の引数を省略します。
terraform {
backend "s3" {
bucket = "<YOUR_BUCKET_NAME>"
key = "/some/key/terraform.tfstate"
region = "auto"
skip_credentials_validation = true
skip_metadata_api_check = true
skip_region_validation = true
skip_requesting_account_id = true
skip_s3_checksum = true
use_path_style = true
}
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4"
}
}
}
これで、.gitignore
に*.tfbackend
を追加すれば、認証情報をGitリポジトリで管理する必要が無くなり、セキュリティを高くすることができます。
また、example.*.tfbackend
ファイルを作成し、Git管理することで、必要な認証情報を記録しておくのを推奨します。
感想
Cloudflare R2をバックエンドにしようと思ったきっかけである、Future Tech Blogでは、AWS
で始まる環境変数に、Cloudflareの認証情報を記載する方法が紹介されていたため、何となく違和感を感じていました。
しかし、そこから私なりに考え、この方法に辿り着きました。今回この記事を書くにあたって、特にTerraform、Cloudflare双方の公式ドキュメントを読むこととなり、今まで以上に知識が深まったのを実感しています。
このように、技術ブログのような二次情報で紹介されていない手法でも、一次情報を自分で集めて目的を達成できたことを忘れず、今後も学習を続けていきたいです。
おまけ
ここではCloudflare R2をバックエンドに指定する方法を紹介しましたが、このままではstate
ファイルをロックできません。
そこで、Amazon DynamoDB
を使用しても良いのですが、Terraformのバージョン1.10
以降から追加される、use_lockfile
引数をご紹介します。
詳細はこちらのZenn記事で解説されていますが、use_lockfile
をtrue
にすることによって、DynamoDBが不要になります。
最後にその設定を追加したコードを紹介して終了します。
terraform {
backend "s3" {
bucket = "<YOUR_BUCKET_NAME>"
key = "/some/key/terraform.tfstate"
region = "auto"
skip_credentials_validation = true
skip_metadata_api_check = true
skip_region_validation = true
skip_requesting_account_id = true
skip_s3_checksum = true
use_path_style = true
use_lockfile = true # State Lockを有効化
}
required_version = "~> 1.10.0" # Terraformバージョンを1.10以上に指定
required_providers {
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 4"
}
}
}