見出し画像

Terraform Cloudを活用したECSデプロイとインフラ管理の実践

の2日目の記事です。

はじめに

こんにちは、Hubble の SRE エンジニアの佐藤慎吾です。
今回は、私たちの会社で行っているインフラの管理とアプリケーションのデプロイ方法について紹介します。
TerraformTerraform Cloud を活用し、シンプルで透過性の高いデプロイを実現しています。

Hubble では、インフラ管理の効率的に安全に進めるために、
Terraform と Terraform Cloud を使用しています。
特に、コンテナのオーケストレーションツールには AWS の
ECS(Elastic Container Service)
を利用しており、ECS のタスク定義やサービス自体も Terraform で管理しています。

デプロイの流れ

デプロイプロセスは以下の手順で行っています。

  1. GitHub Actions で変更を検知:リポジトリに変更が加わると、自動的にワークフローがトリガーされます。

  2. Docker イメージのビルドと Push:変更内容を反映した Docker イメージをビルドし、AWS の**ECR(Elastic Container Registry)**に Push します。

  3. Terraform Cloud の変数更新:Terraform Cloud の API を使用して、該当するワークスペースの変数 image_tag を新しい Docker イメージのタグに更新します。

  4. Terraform Apply の実行:Terraform Cloud で terraform apply を実行し、ECS のタスク定義を新しい Docker イメージで更新します。

ポイント

  • image_tag を variables として管理

    • ECS のタスク定義で使用する Docker イメージのタグを variables として管理することで、その値を変えて、Terraform Apply するだけで、簡単にアプリのバージョンの更新ができます。

  • Terraform Cloud の活用

    • Terraform Cloud の API とワークスペースを活用し、自動化されたデプロイフローを構築しています。

  • ワークスペースの分離

    • ワークスペースを分離することで、ECS 関連の変更のみを迅速に適用でき、デプロイ時間を短縮できます。

ワークスペースの分離

デプロイに関しては Terraform Cloud で、以下の 2 つのワークスペースを用意しています。

  • アプリを動かす上で必要な前提リソース用のワークスペース

    • VPC、データベース、サブネット、セキュリティグループなどのインフラリソースを管理。

    • デプロイ時に必要な情報は output で出力しておき、ECS 関連のワークスペースでtfe_outputsを使って取得します。

  • ECS 関連のデプロイ時のみ必要なリソース用のワークスペース

    • ECS のタスク定義や ECS サービス等を管理。

なぜ分離するのか

ワークスペースを分離することで、以下のメリットがあります。

  • 複雑な条件分岐の排除

    • Terraform コードがシンプルになり、可読性と保守性が向上します。ワークスペースを一緒にしていると、条件分岐が必須になったり、アプリの実態がない(イメージがない)にもかかわらず、タスク定義やサービス等を定義せねばならない場合もあり、直感的ではなくなります。可読性も下がると考えています。ただし、まずアプリがあって、インフラはそのアプリのためのものであるという思想の場合は、まず先行してイメージがビルドされていると思うので、その場合はワークスペースを分離せずにまとめても、条件分岐等が発生することはなく、自然に管理できるかもしれません。

  • デプロイ速度の向上

    • ECS 関連の変更のみを迅速に適用でき、デプロイ時間を短縮できます。Terraform Plan / Apply はリソースが増えれば増えるほど時間がかかるため、ワークスペースを分離することで、ECS 関連のリソースのみを管理することができ、デプロイ時間を短縮できます。

  • 安全性の確保

    • 重要なインフラリソースへの影響を最小限に抑えることができます。

そもそも、なぜ Terraform でタスク定義や ECS を管理するのか

メリット

下記のようなメリットがあると考えています。

  • Terraform と Terraform Cloud を組み合わせて使うことにより、圧倒的に簡単にデプロイの自動化が実現できる。

  • デプロイ前に data block を使って、依存関係にあるリソースの存在チェックが簡単にできる。

  • ほぼ全ての AWS 関連のリソースを Terraform で管理できるという一貫性のあるインフラ管理ができる。

  • module 化すれば、似たようなタスク定義やサービスを作る時に、簡単に構築できる。for_each で大量生産も可能。

デメリット

下記のようなデメリットがあると考えています。

  • 複雑なデプロイ手法に対応できない。

    • Terraform で ECS サービスを更新する場合、必然的にローリングアップデートになる。

    • Terraform でテクニカルなことをやろうとすると、コードが複雑になる。

  • 同時実行数に制限があり、デプロイが始まるまでに時間がかかる可能性がある。

    • Terraform Cloud の有料プランは、同時に Plan や Apply できるワークスペースの上限数が決まっています。(Enterprise プランではその限りではないと思うが)そのため、デプロイ対象のサービスやデプロイ回数が多いような組織では、適していない可能性がある。

    • 対して、AWS CodePipeline 等の CICD に特化したサービスはスケーラビリティが高いので、その点は気にならない。

さいごに

今回は、Terraform と Terraform Cloud を活用した ECS デプロイとインフラ管理の実践について紹介しました。
これが最適だとは限らないので、あくまで参考程度にしていただければ幸いです。

技術とは関係ないですが、僕の84歳のおばあちゃんが、
Microsoft Surfaceでイラスト描いて、LINEスタンプとしてリリースしているので、
よければチェックしてみてください。

また、Hubbleでは、一緒に働く仲間を絶賛募集中です!
気になる方は採用情報をチェックチェック!

明日のHubbleQiita Advent Calendarの記事を担当するのは
バックエンドエンジニアのoaktomeさんです!


いいなと思ったら応援しよう!