terraform initが面倒でbackend情報の別管理もしたくないのでMakefile化してみる
Terraformで構築するプロジェクトを始めるときに terraform init
を実行する必要がある。backendにS3を指定していると、バケット名などを聞かれる。または -backend-config
オプションで指定しないといけない。.tfvarsのファイルに書くこともできない。環境に依存する設定情報を集約できない。
もちろん、環境に依存する情報を.tfファイルに直書きしたくもない。
そこで、 terraform.tfvars
の内容とbackendの情報の両方を1つの設定ファイルにまとめて、スクリプトで強引に terraform init
を自動化してみる。
ここでは、以下のようなTerraformのファイルを対象にする。
variable aws_profile {}
variable aws_region {}
variable resource_prefix {}
terraform {
backend "s3" { }
}
provider "aws" {
profile = var.aws_profile
region = var.aws_region
}
resource "aws_s3_bucket" "static_website" {
bucket = "${var.resource_prefix}-sample"
}
設定ファイル config
は次のように書く。
この設定ファイルから terraform.tfvars
を自動作成するのと、 terraform init
を自動実行させる。
aws_profile="default"
aws_region="ap-northeast-1"
resource_prefix="foo"
tf_backend_config_bucket="foo-terraform-bucket"
tf_backend_config_key="foo/terraform.tfstate"
tf_backend_config_profile="default"
tf_backend_config_region="ap-northeast-1"
この設定ファイルは .tfvars の形式としてそのまま使える。したがって、terraform.tfvars
を自動作成するには cp config terraform.tfvars
を実行するだけでよい。
terraform init
を自動実行させるスクリプトは以下の通り。
# Load the configuration file and run `terraform init`.
set -Ceu
cd $(dirname $0)
. config
backend_configs=$(
for key in $(set | sed -E -e 's/^([^=]+)=.*$/\1/g'); do
if [[ $key =~ ^tf_backend_config_ ]]; then
key2=$(echo $key | sed 's/tf_backend_config_//g')
value=$(eval echo \$${key})
echo -n " -backend-config=${key2}=${value}"
fi
done
)
terraform_init_command="terraform init ${backend_configs}"
echo $terraform_init_command
$terraform_init_command
設定ファイル config
は .tfvars の形式だけではなく、シェルスクリプトからもそのまま読める形式になっているので、シェルスクリプトから実行して設定値をシェル変数として取り込んでいる。
シェル変数の名前が tf_backend_config_
で始まる変数を -backend-config
で渡すようにしている。
この中で前回の以下の記事のワンライナーを使っている。
必要なソースファイルは以下の5つ。
main.tf
terraform-init.sh
config
Makefile
.gitignore
上3つはすでにご紹介した。
Makefile
は以下の通り。
build: aws-deployed
aws-deployed: .terraform terraform.tfvars
terraform apply
touch aws-deployed
.terraform: main.tf terraform-init.sh config
bash ./terraform-init.sh
terraform.tfvars: config
cp config terraform.tfvars
.gitignore
に書くべき内容は以下の通り。
/aws-deployed
/.terraform
/*.tfvars
/config
この内容で make
を実行するだけで、 terraform init
と terraform apply
を実行してくれる。
ここまででやりたいことはできたけど、以下のような警告が出てしまう。
│ Warning: Value for undeclared variable
│
│ The root module does not declare a variable named "tf_backend_config_profile" but a value was found in file "terraform.tfvars". If you meant to use this value, add a "variable" block to the configuration.
│
│ To silence these warnings, use TF_VAR_... environment variables to provide certain "global" settings to all configurations in your organization. To reduce the verbosity of these warnings, use the -compact-warnings option.
╵
terraform init
のときにしか利用せず、 main.tf
からは参照されていない変数が terraform.tfvars
に存在するのが原因。
非常に場当たり的だが、 terraform.tfvars
を生成するときに除外することにした。新しい Makefile
は以下の通り。
build: aws-deployed
aws-deployed: .terraform terraform.tfvars
terraform apply
touch aws-deployed
.terraform: main.tf terraform-init.sh config
bash ./terraform-init.sh
terraform.tfvars: config
cat config | grep -v '^tf_backend_config_' > terraform.tfvars