尝试改进Terraform的CI/CD流程
首先
这是LITALICO Engineers Advent Calendar 2023第四天的文章。昨天是关于生物认证的Flutter的文章,作者是@nonikeno。
我在 LITAILCO 的 SRE 团队担任经理,我的ID是 @tjinjin。最近我更加专注于管理工作,但是我想谈谈我们在自动化驱动下所取得的改进。
假设()
先决条件( )
基础条件( )
起点()
开端()
由于当前的 SRE 组在少数人员负责多种产品的情况下,创建一个无状态的环境非常重要。由于发布频率并不高,因此可能需要在指定的时间应用更改。
根据以上情况,目前采用以下流程来实现。
-
- TerraformのCI/CDはGitHub Actionsで実施
-
- PRでTerraform用のRoot directory以下の変更があった場合、実行ディレクトリ※(下記ディレクトリ構造のenv以下)を全部取ってきて、state単位で並列実行
-
- 差分が合ったものは、共通で管理しているcomposite-actions(自作)を使って、PRコメントを書く
- applyはPRがマージされたタイミングで任意のタイミングで実施
以下是目录映像的示例。该模块很少使用,而是通过使用名为terragrunt和project-resource的共享配置来重复使用产品内的常见设置。
├── README.md
├── env
│ ├── common
│ ├── dev
│ ├── prd
│ ├── shared ※ 環境を跨いで利用するリソースをここに配置する。
│ ├── stg
│ └── test
│ ├── backend-config.yml ※ terragruntで利用する環境設定ファイル。
│ ├── terragrunt.hcl -> ../../terragrunt/common/terragrunt.hcl
│ └── vpc ※コンポーネント毎に実行ディレクトリを用意する。
│ ├── (backend.tf)
│ ├── (env_locals.tf)
│ ├── locals.tf -> ../../../project-resource/vpc/locals.tf
│ ├── main.tf -> ../../../project-resource/vpc/main.tf
│ ├── outputs.tf -> ../../../project-resource/vpc/outputs.tf
│ ├── xxx.tf ※ 環境特有のリソースを記述する。
│ ├── xxx.tf ※ 環境特有のoutputを記述する。
│ ├── (provider.tf)
│ ├── terragrunt.hcl -> ../../../terragrunt/component/terragrunt.hcl
│ └── (version.tf)
├── modules
├── project-resource
│ └── vpc
│ ├── locals.tf ※ 変数を記述するtfファイル。map形式で各環境の変数を記載する。env/stage/componentにシンボリックリンクファイルを配置する。
│ ├── main.tf ※ リソースを記述するtfファイル。env/stage/componentにシンボリックリンクファイルを配置する。
│ └── outputs.tf ※ outputを記述するtfファイル。env/stage/componentにシンボリックリンクファイルを配置する。
└── terragrunt
├── common
│ └── terragrunt.hcl ※ terragruntの実設定ファイル。env/stageにシンボリックリンクファイルを配置する。
└── component
└── terragrunt.hcl ※ 上記を参照するためのファイル。env/stage/componentにシンボリックリンクファイルを配置する。
()で囲われているファイルはterragruntで作成されたファイルであることを示す。
以下是对评论的印象。
因为最近没有剩余能力,所以我一直在维持此操作,但是遇到了各种问题。
-
- Renovateを途中から導入したため、GHAの実行回数が増大しコスト増加に
-
- Terraform関連のPRを出した際に対してすべてのstateに対してplanが実行される。意図してapplyを待っているものに対しても差分は検出されるため、PRとは関係ないものもPRコメントに出てしまってレビューしづらい
hide commentする謎作業が多発
pushするごとにPRが走るので何度もコミットすると大変なことに
PRの出しづらさを感じさせる実装は利用者のコストが高い
我想要实现的目标。
为了满足上述要求,我按照以下要求进行了实施。
-
- GHAのコストを適正化したい
-
- PRの差分に関するもの以外はplanを実行しない
-
- stateとコードのずれは別の仕組みで担保する
- terraform planの結果はPR内で一つだけにしたい(plan実行のたびにコメントしたくない)
实施
变成了以下这个样子。
-
- PRではdiffで検知した対象のstateを検出し、それらに関連するplanのみを実行するためのshellを頑張って書きました。その結果をmatrixを使って実行しています
-
- 全体に対してterraform planを実行するworkflowを外出しし、 tf_plan というlabelが付与された場合にworkflowを実行する
-
- issueを作成し、tf_planラベルを実行することで、全体に対してのterraform planが実行され、その結果がissueコメントに起票される
-
- 差分のコメントは tfcmt で行うように見直し。tfcmtでコメントの更新をサポートしていたのでその方針を採用
tfcmt がコメントの更新をサポート
Renovateと組み合わせて、packageRulesでterraform関連の変更があった場合は、addLabelsで tf_plan を付与させることで、バージョンアップ時にplanを実行させる
触发器的形象如下:
name: "terraform_plan_all"
on:
issues:
types:
- labeled
pull_request:
types:
- labeled
我会附上由于问题而执行的Terraform计划的执行图像。
由于实施刚开始,我们将继续进行运营,但我认为我们已经实现了想要的目标。
未来
-
- RenovateによるPRでAuto Mergeを入れられてないので導入したい
- terraform fmtで差分を検知したときに、commitやPRを作るのではなく、PRコメントで変更を指摘しauthorが自分で気づいて直せるようにしたい
总结
我希望能努力建立一个能够以小团队的方式运营多产品的机制。我们积极招聘SRE人员!