弊社(Voicy)もサービス開始から7年経ち、レガシーな部分も散見されます。私はSREとして今年の6月に入社したばかりなので、7年間の歴史の10分の1もいないわけですが・・・
入社した当初に動いていたプロジェクトとして、Terraformのリファクタがありました。
それについて本日は書いていきたいと思います。
レガシーな部分
VoicyのTerraformの何がレガシーか?
バージョン
まず、Terraformのバージョンが古いです。
本日現在 1.6.6 が最新で、1.7.0 の rc1 も出ています。
リファクタし始めた当初、バージョンは 0.12.x でした。
弊社はAWSを使用しているので、aws モジュールとの絡みもあるのですが、新しくしなくても動いているというのがいけないんでしょうね。
構造的問題
次に、構造の問題です。
.
└── dev_stage_prod
├── main.tf
├── main.tf_dev
├── main.tf_stage
├── main.tf_prod
├── output.tf
├── provider.tf
├── variable.tf
└── vpc.tf
terraform は plan や apply を実行する際に、main.tf を参照して実行するわけですが、環境がいくつかある場合、やり方がいくつかあります。terraform 的にはワークスペースを使用するというが、一応推奨されていた方法ではないかと思います。
ですが、この環境、main.tf が環境ごとに用意されており、実行する際に、編集・コピペして使用する感じになっていました。
この手法の、メリット・デメリット挙げてみます。
[メリット]
- 環境ごとに main.tf をコピー・編集するだけで、環境ごとに異なる構成をプロビジョニングできる
- 構成がシンプル
[デメリット]
- 環境ごとに main.tf をコピー・編集する必要があり、手間がかかる
- 環境ごとに main.tf があるので、誤った環境のものを適用する可能性がある
リファクタの方法
リファクタの方法も色々ありますし、さまざまな検討をしました。
どんな方法があるか?
例えばですが・・・
- ディレクトリ構造の利用
- ワークスペースの使用
- 変数ファイルの活用
- モジュールの使用
- 環境変数の使用
- 分岐戦略の採用
どの方法を採用したか?
メリデメを検討した結果、Voicyで採用されたのは、ディレクトリで環境分けをし、shared モジュールを使用するが、シムリンクは採用しないという方針となりました。
.
├── dev
│ ├── main.tf
│ ├── provider.tf
│ └── variable.tf
├── prod
│ ├── main.tf
│ ├── provider.tf
│ └── variable.tf
├── shared
│ ├── iam.tf
│ ├── network.tf
│ ├── output.tf
│ └── variable.tf
└── stage
├── main.tf
├── provider.tf
└── variable.tf
この方法のメリデメ
それでは、この方法のメリット・デメリットも確認していきましょう。
- ディレクトリ分けすることで、環境分けが明確
- shared モジュール採用により、共通部分は共通部分で重複を排除できる
- コピペで失敗することがない
後はリファクタするのみ
元々の構造から、新しい構造への変更は、なかなか大変な作業です。
shared モジュールへの変更もあり、作業量的にもかなりなものでした。
ですが、必要な部分のリファクタが終わり、次はバージョンアップですね。。。
バージョンアップはなぜ行う?
リファクタするだけであれば、バージョンアップはサポート切れとかを考えなければ必要ない作業です。
いや、やった方がいいのは確かです。
では、なぜやるか?
Terraform も CI/CD したいよね
今までローカル実行を行なってきた Terraform なのですが、CI/CD やっていきたいよねという話になりました。で、何を使うかの検討を行ったのですが、最終的に Atlantis を使用することになりました。
Atlantis とはなんぞや?
Atlantisとは、Terraformを以下のように進化させるツールです。
https://www.runatlantis.io/
- プルリクエスト駆動のワークフロー:PRで自動実行できる
- 自動化されたプランと適用:plan/apply の自動実行
- チームのコラボレーションと透明性:チーム内でレビューできる
- セキュリティとアクセス制御:実行承認
- 状態管理の簡素化:ローカルで状態管理する必要がない
- 柔軟性と拡張性:様々なカスタマイズが可能
- 履歴の追跡と監査:証跡が取れる
いや、便利よね。
バージョンアップ関係ある?
Atlantis を github 上で実行すると、SecretManagerから読み込みしているセキュリティ情報が、github 上に残ってしまうのです(0.12.xとかだと・・・)。バージョンアップ必須です。
- 0.12.x ダメダメ
- 0.13.x ダメダメ
- 0.14.x sensitive に対応
ということで、とりあえず 0.14.x にあげることになりました。
0.14.x でもダメ
0.14.x は sensitive に対応はしているのですが、tfstate には残ってしまうという問題が出てしまいました。ということで、もう一段階あげて、0.15.x へとバージョンアップを行い、一応の問題解決が見られました。
Atlantis 入れてどう?
Atlantis入れてどうなった?という部分です。
良い部分
よかった点をあげていきたいと思います。
- github 上で実行することで、証跡が残る
- 誰が実行したかわかる
- 実行前レビューをするようになる
微妙な部分
若干微妙な部分についても
- 権限周りは絞りきれない
- ローカルから実行しようと思えばできる
- 自動 apply はこわい
今後
今後ですが、引き続きのバージョンアップや、自動 apply などやっていきたいと思っています。
We're hiring
絶賛、エンジニア(だけではなく)募集してます。
カジュアル面談もやっていますので、お待ちしています。