📜

tfvarsとtfbackend切替環境でのtfmigrate実行用スクリプト

2023/11/25に公開

はじめに

最近出会った Zenn の記事「Terraform で module を使わずに複数環境を構築する」で紹介されている考え方に納得した&スクリプトが非常に便利だったので、これを元に既存案件の Terraform 環境をリファクタリングしています。

ところが、Terraform の Module の廃止を考えたときにマイグレーションで非常に不便な目にあったので、スクリプトを作成しました。
とはいってもロジックは前述のスクリプトのロジックをそのまま拝借したものです。

動作確認済み環境

  • Terraform 1.1.4

Terraform の Module 廃止に伴う問題

Module を廃止する場合、必ず遭遇するであろう問題が state 上の名称変更です。
なぜなら、モジュールを用いてデプロイしたリソースには必ずmodule.の prefix が付与され、Module を廃止するということは同じコードを移植してもこの prefix 分、state 名の差が発生します。
すべての環境においてModule を必須としていた場合、対象の数は膨大です。

そこでtfmigrate の出番になってくるわけですが、tfmigrate は前述のスクリプトのように自動で環境別の情報を読み取ってくれるわけではありません。
*.tfvars*.tfbackendを受け渡す必要があります。

さらに、これは個別の事情ではあるのですが、リファクタリング中の環境はaws-vaultを利用してスイッチロール環境を必須としていたので、更にコマンドが長くなるという事情がありました。

スクリプトを使わない場合
TF_CLI_ARGS_plan="-var-file=prd.tfvars" aws-vault exec [aws_profile_name] -- tfmigrate plan tfmigrate.hcl --backend-config=./prd.tfbackend

本来リファクタリングのタスクに集中したい中に、この問題があると流石に我慢ならないので、今回のスクリプトの作成に至りました。

スクリプトを使った場合

スクリプトを使った場合、受け渡す引数をよしなに補完してくれるので、aws-vault を利用しても以下のように短く書けます。

スクリプトを使う場合
aws-vault exec [aws_profile_name] -- ./tfmigrate.sh prd plan tfmigrate.hcl

スクリプト

スクリプトのコードはこちらに掲載しています。

コード
tfmigrate.sh
#!/bin/bash
set -euo pipefail

function usage() {
  cat <<EOF
Usage: $0 [-help] <env> <command> [args]
  env          : environment [stg/prd/...]
  command      : tfmigrate command [plan/apply/list/...]
  args         : subcommand [e.g. list "--config"] and tfmigrate command options (see : tfmigrate <command> -help)
EOF
}

### =========================== Main ========================== ###

if [ "$1" = '-h' ] || [ "$1" = '-help' ] ; then
  usage
  exit 0
fi

# Exit with an error if there are no arguments following <command>
if [ $# -lt 2 ] ; then
  echo -e "[ERROR] Invalid parameters\n"
  usage
  exit 128
fi

# tfmigrate.sh <env> <command> [args]

TF_ENV=$1
TFMG_COMMAND=$2
TFMG_ARGS=${@:3}

# Split processing because specifying -var-file and --backend-config in a command without these option will cause an error
case $TFMG_COMMAND in
  apply | plan)
    # shellcheck disable=SC2086
    # Using "${TFMG_ARGS}" is recommended but it throws an error when multiple arguments are specified so we remove the double quotes
    TF_CLI_ARGS_plan="-var-file=${TF_ENV}.tfvars" tfmigrate "${TFMG_COMMAND}" ${TFMG_ARGS} --backend-config=${TF_ENV}.tfbackend;;
  list)
    # shellcheck disable=SC2086
    # Using "${TFMG_ARGS}" is recommended but it throws an error when multiple arguments are specified so we remove the double quotes
    TF_CLI_ARGS_plan="-var-file=${TF_ENV}.tfvars" tfmigrate "${TFMG_COMMAND}" ${TFMG_ARGS};;
  *)
    # shellcheck disable=SC2086
    tfmigrate "${TFMG_COMMAND}" ${TFMG_ARGS};;
esac
導入方法

必要に応じてファイルtfmigrate.shとして保存後、実行権限を付与してください。

chmod +x tfmigrate.sh

おわりに

まだ動作確認までしかしていないのですが、この後もリファクタリングが続くので、必要に応じてスクリプトを改修予定です。

Discussion