TerraformでS3バケットを定義する際、同じ値を複数箇所で使うことがあります。例えば、以下のようなコードです。
resource "aws_s3_bucket" "main" { bucket = "${var.env}-${var.component}-${var.service}-app-log" tags = { Name = "${var.env}-${var.component}-${var.service}-app-log" Environment = var.env } }
この例では、bucket と tags.Name の両方で同じ文字列を使っており、バケット名を変更したい場合に 2箇所を同時に修正 する必要が出てきてしまいます。こうした繰り返しは、保守性を下げる要因になります。
local変数でまとめて再利用する
このようなケースでは、local値で変数化しておくと便利です。以下のようにすれば、変更箇所を1箇所に集約できます。
locals { bucket_name = "${var.env}-${var.component}-${var.service}-app-log" } resource "aws_s3_bucket" "main" { bucket = local.bucket_name tags = { Name = local.bucket_name Environment = var.env } }
format()を使って見通しを良くする
上記のような変数展開が複数連なると、見た目がややごちゃごちゃしてきます。その場合は format() 関数を使うことで、よりスッキリと書くことができます。
locals { bucket_name = format("%s-%s-%s-app-log", ${var.env}, ${var.component}, ${var.service}) }
複数のバケットを扱いたい場合は?
ここまではバケットが1つの場合でしたが、例えばログ用・データ用など、複数バケットを定義したいケースもよくあります。単純に書くと以下のようになります。
locals { app_log_bucket_name = format("%s-%s-%s-app-log", var.component, var.service, each.key) app_data_bucket_name = format("%s-%s-%s-app-data", var.component, var.service, each.key) } resource "aws_s3_bucket" "app_log" { bucket = local.app_log_bucket_name tags = { Name = local.app_log_bucket_name Environment = var.env } } resource "aws_s3_bucket" "app_data" { bucket = local.app_data_bucket_name tags = { Name = local.app_data_bucket_name Environment = var.env } }
この方法でも動きますが、バケットの種類が増えるたびにコードがどんどん膨らんでしまいます。
for_each + format()でスケーラブルにする
こうした繰り返しを避けるためには、for_each を使ってループ処理にするのが効果的です。
Terraformでは ループ内でlocal値を定義出来ないので、ループ内で直接 format() を使ってバケット名を構築します。
locals { buckets = [ "app-log", "app-data", "some-data1", "some-data2" ] bucket_name_format = "%s-%s-%s-%s" } resource "aws_s3_bucket" "main" { for_each = toset(local.buckets) bucket = format(local.bucket_name_format, var.env, var.component, var.service, each.key) tags = { Name = format(local.bucket_name_format, var.env, var.component, var.service, each.key) Environment = var.env } }
format() の呼び出しが2回出てきて若干冗長に見えるかもしれませんが、共通のフォーマット文字列をlocal値で管理している ため、バケット名の規則を変更したい場合は bucket_name_format を直すだけで済みます。
このようにしておけば、バケットの数が増えてもコードの保守性を高く保ちつつ、Terraform構成をスケーラブルに保てます。
それでは良いTerraformライフを引き続きお過ごしください。