ProvisioningをDocker Composeで完結させる

Web Frontend 開発環境を Docker 化する記事BFF(Web API)開発環境を Docker 化する記事に続いて「IaaS の Provisioning を Docker 化する」方法を考えてみました。

PoC を目的としたプロジェクトなどで Web アプリケーション開発の初期のシステム設計だけサクッと手伝う場合などがあり、そのような場合は例えば IaaS 上のシステム設計と Provisioning くらいまでを考えて再現性を担保した上で共有できると後々プロジェクトとシステムの運用が省力化できます。

ただ、IaaS 上でシステムを維持するためには各 IaaS の CLI や Terraform など、普段 Web アプリケーション開発を専門にしている方にはなじみが薄いツールが登場します。
これらのツールの導入手順を書くだけでも README が長くなってしまいますし、毎回同じような内容になりがちな手順は書く場合も読む場合も負担です。

そこでそれらの IaaS 関連ツールや設定作業をコード化し隠蔽し「プロジェクトメンバー全員が IaaS 構成を 1 日程度のハンズオンで扱えるようになる」方法を考えてみました。

Prepare

今回は「GCP プロジェクトを Terraform で provisioning する」開発プロジェクトを想定してみます。
先々の CI/CD なども考慮し Terraform の適用には個人と紐づいた Google アカウントではなく専用のサービスアカウントを使うことにします。

まずはプロジェクトに合わせて Dockerfile を用意します。

続いてこの Dockerfile を Docker Compose から使うために docker-compose.yml を用意します。

ここまでで docker-compose up すると provisioning と名付けた Docker Compose のサービスが 1 つ起動し以下をやってくれるようになります。

  • IaaS の CLI(今回は gcloud コマンド)の認証
  • Terraform の tfstate ファイル保存用 GCS バケット作成
  • terraform init

docker-compose.yml 内で参照している GCP サービスアカウントの鍵ファイルは config/credentials/google-cloud-keyfile.json に置くと docker-compose up 時に読み込まれ activate されます。
環境変数の値は例えば次のように .env ファイルに書いておけば同じく docker-compose up した際に読み込まれます。

TF_VAR_basename=example-service
CLOUDSDK_CORE_PROJECT=example-gcp-project
TF_VAR_gcp_project_id=example-gcp-project
PROJECT_UNIQUE_ID=example-1234

.env ファイル生成自体もスクリプト化しても良いですし、Git で管理しても、逆にパスワードなどを描く場合は Git の管理から外しても良いでしょう。

例えば本番と開発環境など"よく似た"複数の環境を構築し維持する場合は、鍵ファイルと .env ファイルの 2 つを差し替えるだけで対応できます。

How to provision

このように Provisioning の仕組みを Docker と Docker Compose に閉じ込めることで、README に書く手順は数ステップで済みます。

That’s all

このように IaC 部分を Docker Compose 内で完結させることで、Web Frontend 開発環境を Docker 化する記事BFF(Web API)開発環境を Docker 化する記事のように開発環境で Docker Compose を使っているプロジェクトであれば、新たな技術スタックを必要な部分だけ学びながら環境構築を行えます。

一方で Docker に依存してしまうので、プロジェクトやチームとして Docker 経験値が極めて少ない場合には先に Docker 自体に慣れる必要があるでしょう。

また依存と手順の分岐が少ないので、一度この構成を経験した人が provisioning 部分を新たなプロジェクトに導入することも容易です。
特に IaaS や provisioning に関しては「もし x がまだであれば x1 を、済んでいれば x2 を実行」「y がローカルで 1 度実行されていれば y2 から行う」「z がリモートで済んでいれば z1 はスキップする」などなど手順が煩雑になりがちですが、この方法では極力そのような分岐を減らしています。

もちろん、いわゆる「フルスタックエンジニア」のように全員が IaaS も運用可能な設計をしてビジネスロジックも Web Frontend も開発できる体制であればこのような工夫は必要ないのかもしれませんが、やはり多くの場合どこかに特化するもので個人的には到底全てを一人でやり切れる気はしません。

そこでこのようにコード化しつつ隠蔽することで、プロジェクトメンバーが少し増えたり期間が延びても、参画したばかりでも必要最小限の運用をすぐに行えるようになり、時間が取れればコード化されているので読み進めることで理解を深めることができるのではと考えました。
実際このような仕組みを導入したプロジェクトでは数時間のハンズオンで IaaS の構成を管理していただけるようになりました。