Atlantisを使ったterraformワークフロー自動化とアーキテクチャ
Terraformのチーム開発
小売流通ソリューション部、認証認可基盤開発チームの鵜久森です。
みなさんTerraformでチーム開発やってますか?
TerraformはAWSなどのインフラリソースの構築、変更、管理をコードで行えるIaCで、これがなくてはインフラ管理はできないというほど、近年のインフラ開発においてなくてはならないものです。
一方で、Terraformを使ってチーム開発をしていると、つらみを感じたり悩みをお持ちの方もいらっしゃるでしょう。「planを取ると自分の編集していない部分で差分が出てしまった」、「他メンバーのapplyがぶつかり合ってしまう」、「いつの間にかコードと実リソースの状態が乖離している(ドリフト)」、「Terraform実行のためにメンバーに強力な権限を付与しない」...などといったことです。
こういったつらみを解消するため、Terraformのワークフローを自動化し、メンバー開発のコラボレーション力を高めるツール類の利用が高まっており、その1つとしてTerraformのワークフローをGitHubなどのPull Requestに連携し、Pull Request上でplan/apply
などの操作を行うことができるAtlantisがあります。
今回は小売流通ソリューション部、認証認可基盤開発チームのAtlantisを使ったTerraformプロビジョニングアーキテクチャについて紹介します。
この記事の対象者
- 現在Terraformで運用をしている
- Terraformでチーム開発をしていて、冒頭で述べたようなつらみを感じている
- ワークフロー自動化ツールをいくつか検討中でAtlantisが候補に上がっているのでその検討材料にしたい
全体アーキテクチャ
私たちのAtlantis運用における全体アーキテクチャを紹介します。
図と照らし合わせながら、主要なポイントを説明します。
1. Atlantisを起動する
AtlantisはSaaSではないので、自分たちでAtlantisをデプロイする環境を用意する必要があります。自前でデプロイするので、ユーザー数やリソース数によってコストは変わらず、料金はインフラ利用コストだけです。
私たちはdev, staging, production環境とは別にAtlantis用のAWS環境を別途用意し、Atlantisはこの環境でECS Fargateを使ってデプロイしています。
ECS Fargateでデプロイする用のmoduleとして terraform-aws-atlantisが用意されています。これを利用してプロビジョニングすると、ELBやVPC、サブネット, ACMなど、Atlantisを起動するために必要なAWSリソースを一括作成してくれるので楽です。
2. GitHub Appを利用した連携
AtlantisはGitHub PRへのatlantis plan/apply
のコメントをWebhookとして受け取り、これをトリガーとしてterraform plan/apply
コマンドを実行します。
そして、Atlantisは実行したTerraformコマンドの結果を同PRへ投稿し、開発チームはその内容をPR上で確認、共有できるので、plan/apply
結果をもとにしたレビューや議論がとても楽にできます。
AtlantisがGitHubからのWebHookを受け取ったり、plan/apply
結果を投稿するので、AtlantisはGitHubリポジトリになんらかの方法でアクセスできる必要があります。
1つのやり方としてGitHub組織のユーザーにマシンユーザーを作り、Atlantisにこのマシンユーザーを使わせる方法があります。マシンユーザーを作るのはGitHub以外でもよく用いられる方法なので馴染みがある方も多いでしょう。一方で、マシンユーザーを作るとそのユーザ料金が必要になりますし、アクセストークンの権限管理とトークン自体の管理も面倒でセキュリティリスクが高まります。
もう1つの方法として、AtlantisはGitHub Appによる認証をサポートしています。
AtlantisのGitHub Appを組織のGitHub Appとして作成し、インフラ管理リポジトリにインストールします。
AtlantisはGitHub Appとしてリポジトリにアクセスし、plan/apply結果を投稿することができるので、マシンユーザーを用意する必要がありません。
注意点として、GitHub AppはGitHub Organization上に作成します。
個人のアカウントにGitHub Appを作成し、対象リポジトリにインストールした場合、その人がチームを卒業してOrganizationから離脱すると(厳密にはGitHub Appが削除されたタイミング)、GitHub Appが動かなくなってしまいます。
3. タスク冗長化
私たちはAtlantisをFargateタスクとしてデプロイしています。
1タスクのみで、冗長化はしていません。
Atlantis自体はterraformのワークフローを構成するだけで、例え止まったとしてもサービス、および利用するお客様に影響があるわけではなく、タスクを再起動すれば数分で復旧できるからです。
4. tfstateの管理場所
AWSをterraformでプロビジョニングし、チーム開発している時はtfstateをS3に置いていることがほとんどでしょう。では私たちのようにAtlantisをdev, staging, production等とは別の環境にデプロイする場合、tfstateはどこに置くべきでしょうか?
すなわち
- AtlantisがあるAWSアカウントにtfstateを置くか
- サービスをデプロイしているAWSアカウントそれぞれに置くか
です。
これは一概にどちらが良いとは言えないですが、例えばterraformを直接使う環境では、tfstateは同じAWSアカウントのS3に配置することが多いでしょうから、それに従いdevはdevに、productionはproductionに置くと、Atlantisについてよく知らない方にとっては分かりやすいでしょう。
一方でAtlantisがあるCICDアカウントに全環境のtfstateを置くと、AtlantisはCICDアカウントにあるtfstate管理バケットのアクセス権限さえあれば良く、IAMやS3バケットポリシーの設定&管理は楽だと思います。ただしこの場合、CICDアカウントに本番環境のtfstateを置くことになるので、CICDアカウントの管理がよりsensitiveになることに気をつけるべきでしょう。
また、tfstateを管理するバケットは暗号化やパブリックアクセスをブロックしておくことはもちろんですが、バージョニングも有効化しておきます。バージョニングを有効化することで、tfstateを誤って削除するリスクを最小限にします。tfstateを誤って削除すると悲惨なtfstate復旧作業を行うことになるので必ず設定しておきましょう。
5. Terraform実行ロール
TerraformはIaCによりインフラを管理するという性質上、非常に強い権限を必要とします。
Terraformを直接利用する場合、開発メンバーが直接terraform plan/apply
を実行しますが、そのために開発メンバーに常に強い権限を与えることになります。
Atlantisに実行経路を1本化することにより、メンバーへの強い権限付与を避けることができます。
Terraformワークフロー構築のセキュリティ観点に置ける最も強い動機と言っても過言ではないでしょう。
私たちの環境ではdev, staging, production各環境にterraform-managementという名のTerraform実行用のロールを用意しています。
強力な権限を持つterraform-managementは、AtlantisのECSタスクロールであるatlantis-task-roleのみが利用できます。
開発メンバーが持つIAMからは利用できません。
これにより、Terraform操作をAtlantisに絞り、GitHub PRを見れば全ての操作を確認可能となっています。
余談ですが、terraform-managementの信頼ポリシーに与えるのはECSのタスク実行ロールではなく、タスクロールです。間違えるとAtlantisがassume_roleできないので注意しましょう。
参考: Amazon ECS の IAM ロール
6. ストリーミングログ (ブラウザアクセス)
AtlantisはリアルタイムのTerraformログのストリーミングをサポートしており、ブラウザからterraform plan/apply
状況をリアルタイムで確認することができます。
Atlantisは実行結果をPRのコメントに投稿してくれるので、リアルタイムなストリーミングログが必要になるケースは少ないですが、apply完了にやたら時間がかかったりするときにリアルタイムログを見ればどういう状況か分かることがあるので役に立つことがあります。
注意点として、このストリーミングログページへの認証アクセスは、Basic認証のみのサポートとなっています(自前で別途用意しない限り)。
これはセキュリティ的に頼りないので、SecurityGroupでin方向アクセスをクラスメソッド代表IPアドレスに限定しています。かつ1ユーザーのみという制限もあるので、パスワードを共有せざるを得ないのですが、チーム内の共有に限定しています。
IPアドレスで社内アクセスのみという強力な制限をかけ、さらにパスワードでチーム内にのみアクセスを制限しています。
そもそもの話としてですが、私たちはTerraformで秘匿情報や個人情報を一切管理していないので、それらがストリーミングログから流出することはありません。
ただ、それらをTerraformで管理している環境では、ストリーミングログへのアクセスに対しできる限り強力なセキュリティを検討することが大事です。
※クラスメソッドの基幹ネットワークについて興味があれば別途こちらの記事をどうぞ
終わりに
小売流通ソリューション部、認証認可基盤開発チームにおける、Atlantisを活用したTerraformプロビジョニングアーキテクチャについてご紹介しました。
TerraformとAtlantisを組み合わせることで、インフラ管理の自動化と安全性を向上させ、チーム開発の効率を大幅に高めることができました。しかし、アーキテクチャの構築や運用においては、セキュリティや運用負荷、チームメンバーの利便性など、さまざまなポイントで検討が必要です。
私たちの取り組みが、これからTerraformやAtlantisを活用していく皆さんの一助となれば幸いです。今後もより良いIaC体験のため、運用改善を行なっていくので、シェアしていきたいと思います。