terraform コマンドのバージョンをプロジェクトごとに明記しておいても、それぞれのプロジェクトごとに都度指定のバージョンのバイナリを落としてくるのはちょっと面倒くさいので、 それを docker をつかって解決できないか考えてみました。以下のものを使います。
- Docker
- hashicorp/terraform dockerイメージ
- direnv
まず、Docker Hub には hashicorp が terraform の 公式 docker image を公開しているのでこれを使って以下のようなシェルスクリプトを書きます。
bin/terraform:
#!/bin/bash ROOT_DIR=$(cd $(dirname $0); pwd -P | xargs dirname) exec docker run \ -it \ --rm \ --workdir=$(pwd -P) \ -v "${ROOT_DIR}:${ROOT_DIR}" \ -e "TF_VAR_AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}" \ -e "TF_VAR_AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}" \ hashicorp/terraform:0.12.25 $*
キモの部分は -v "${ROOT_DIR}:${ROOT_DIR}"
と --workdir=$(pwd -P)
の部分で、 ROOT_DIR
が /Users/username/foo-project
というパスだった場合に、コンテナに /Users/username/foo-project
というパスが生成され、ホストの /Users/username/foo-project
がマウントされます。そしてさらにコンテナでコマンドを実行するときのワーキングディレクトリを --workdir=$(pwd -P)
で指定するとホストとコンテナでパス構成とカレントディレクトリが一致するので、ホスト上の実行ファイルのような感覚で使用することができます。
また、--rm
オプションをつけているので実行するたびにゴミが増えていくということもありません。
terraform から環境変数に触りたい場合は -e
オプションで任意の環境変数を渡しておきます。
さらに direnv を使うとプロジェクトごとに有効な環境変数やPATH
を設定できて便利です。
.envrc:
if [ -f .envrc.local ]; then source .envrc.local fi PATH_add bin
.envrc.local:
export AWS_ACCESS_KEY_ID=xxxxx export AWS_SECRET_ACCESS_KEY=xxxxx
ここまですると、以下のようにホスト所にインストールされた terraform コマンドと同様に使うことが出来ます。
terraform plan
これらをまとめると以下のようなディレクトリ構成になります。
ディレクトリ構成:
/Users/username/foo-project # project-root ├── .envrc # direnv の設定ファイル ├── .envrc.local # バージョン管理しない ├── .envrc.local.sample # .envrc.localの雛形 ├── bin │ └── terraform # ポータブルなterraformコマンド └── terraform # terraformのファイル郡 ├── enviromnents │ └── production │ └── main.tf └── modules └── main ├── ec2.tf ...