巨大 tfstate に立ち向かう技術
by
Hayato Kawai
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
© 2024 Wantedly, Inc. 巨大 tfstate に立ち向かう技術 HashiTalks: Japan 2024 2024-11-13 Hayato Kawai (@fohte)
Slide 2
Slide 2 text
© 2024 Wantedly, Inc. 自己紹介 名前 Fohte (ふぉーて) 川井 颯人 (Hayato Kawai) 所属 ウォンテッドリー株式会社 趣味 🎮 🎹 https://techbookfest.org/product/fqhYCspDK80WBrGWJkEkP8?productVariantID=gzf9 X203XXhW87rBQnRxW2 Vim 入門書の 同人誌を作りました
Slide 3
Slide 3 text
© 2024 Wantedly, Inc. 究極の適材適所により、 シゴトでココロオドルひとを ふやすために Wantedlyはパーパス‧共感を軸にした、⼈と会社との出会いを2012 年から創出。 はたらくすべての⼈が共感を通じて「であい」「つながり」「つなが りを深める」ためのビジネスSNS「Wantedly」を提供しています。 1⼈でも多くの⼈がワクワクしたり、熱中してシゴトと向き合えるよ うな世界を実現するために、国境を超えて「はたらくすべての⼈の イ ンフラ」を創っていきます。 ウォンテッドリーの提供サービス
Slide 4
Slide 4 text
© 2024 Wantedly, Inc. 次世代型 採用管理システム 採⽤プロセスの悩みを解決 途中辞退を防ぐための業務を効率化 ● 繰り返しフローで候補者管理を⾃動化 ● 複数名の⾃動⽇程調整で80%時間を削減 多様化する採⽤プロセスに対応 ● 最適な選考プロセスを⾃由⾃在に構築 ● 多様なメンバーに適した権限 構造化⾯接で⾼精度の⾒極め可能 ● 採⽤基準の標準化‧カスタマイズ ● 各項⽬の評価を定量化 ウォンテッドリーの提供サービス (Wantedly Hire)
Slide 5
Slide 5 text
© 2024 Wantedly, Inc. 今日持ち帰ってほしいこと ● 巨大な tfstate はつらい ● が分割するのも一筋縄ではいかない ● 完璧を目指さず徐々に移行していこう
Slide 6
Slide 6 text
© 2024 Wantedly, Inc. ウォンテッドリーにおける Terraform の運用
Slide 7
Slide 7 text
© 2024 Wantedly, Inc. Wantedly を支えるインフラ環境 ● アプリケーションは Amazon EKS 上で 動いている ● Google Cloud も 一部で利用 https://docs.wantedly.dev/fields/infrastructure/infrastructure
Slide 8
Slide 8 text
© 2024 Wantedly, Inc. Terraform の利用箇所 青枠は Terraform で 管理している (つまりほとんどが Terraform 管理) https://docs.wantedly.dev/fields/infrastructure/infrastructure
Slide 9
Slide 9 text
© 2024 Wantedly, Inc. Terraform の CI/CD: GitHub Actions & tfaction ● ウォンテッドリーでは CI 環境として GitHub Actions を利用 中 ● Terraform の CI/CD を GitHub Actions で実現する フレームワークである tfaction を利用している ○ https://github.com/suzuki-shunsuke/tfaction ○ tfaction さえ導入すれば GitHub 上で Terraform の運用フローが作れる
Slide 10
Slide 10 text
© 2024 Wantedly, Inc. tfaction の紹介 ● GitHub での開発フローに則って terraform plan/apply が できる ○ PR を立てたら terraform plan が実行される ○ PR merge 時に terraform apply される ○ plan, apply 結果は PR にコメントされる https://suzuki-shunsuke.github.io/tfaction/docs/
Slide 11
Slide 11 text
© 2024 Wantedly, Inc. tfaction の紹介 ● monorepo に対応 ○ 1 つのリポジトリ内に複数の tfstate (= terraform init するディレクトリ) を置ける ○ それぞれのディレクトリに変更があったときだけ plan/apply される ● terraform apply 失敗時のフローも用意されている ○ https://suzuki-shunsuke.github.io/tfaction/docs/feature/follow-up-pr ● import や state mv などもコード管理・CI/CD できる ○ https://suzuki-shunsuke.github.io/tfaction/docs/feature/tfmigrate
Slide 12
Slide 12 text
© 2024 Wantedly, Inc. Terraform の CI/CD: Renovate ● Terraform 本体や provider、tfaction などの更新に 追従するための仕組みとして Renovate を利用 ● 利用しているバージョンを検知 => 更新があれば更新 PR を作成してくれる https://docs.renovatebot.com/
Slide 13
Slide 13 text
© 2024 Wantedly, Inc. 巨大 tfstate の歴史
Slide 14
Slide 14 text
© 2024 Wantedly, Inc. 言葉の定義: tfstate とはなにか ● ここでは便宜上 "tfstate" を 「terraform init を実行するディレクトリ」とします ○ *.tfstate というファイル (Terraform の state) がこの単位で作られること から "tfstate" と呼んでいます
Slide 15
Slide 15 text
© 2024 Wantedly, Inc. Terraform ディレクトリ構成 ● 単一リポジトリで管理 ● aws/ ○ CloudFront や WAF など 複数アプリケーションで跨いで 利用するリソース ● eks/ ○ EKS の Cluster, Node など ● monolith/ ○ それ以外 https://docs.wantedly.dev/fields/infrastructure/infrastructure
Slide 16
Slide 16 text
© 2024 Wantedly, Inc. このディレクトリ構成の課題 ● monolith がとにかく巨大になった ○ 先に述べたディレクトリ構成は明確な決まりがなかった ■ 「とりあえず monolith に置く」が多発 ○ resource 数は 1,000 をゆうに超える ○ plan/apply に 5 分以上かかる 😇
Slide 17
Slide 17 text
© 2024 Wantedly, Inc. monolith tfstate を分割する機運が生まれる ● 障害対応等で迅速に apply したいときに plan/apply が遅 くて困る ● configuration drift 発生時に apply できなくなる ○ Terraform 外で変更が発生したときに、その変更が巻き戻らないように Terraform コードへの変更が必要 ○ ちょっとした変更を加えたくても、まず drift を解消する手間がある
Slide 18
Slide 18 text
© 2024 Wantedly, Inc. monolith tfstate を分割する機運が生まれる ● どのリソースがどこに定義されているのかわからない ○ 特に新しく参加したインフラメンバーにとって認知負荷が高い ○ これもリソース定義が多すぎることが原因のひとつ
Slide 19
Slide 19 text
© 2024 Wantedly, Inc. plan/apply はなんとか高速化できる、が… ● 速度は並列数を上げると一定の改善ができた ○ terraform plan/apply には -parallelism オプションがある ■ デフォルト: 10 ■ これを 30 など増やせばよい ○ 5 分くらいが 2 分くらいまで短縮された 🎉
Slide 20
Slide 20 text
© 2024 Wantedly, Inc. plan/apply はなんとか高速化できる、が… ● が、今度は各サービスの API rate limit に引っ掛かる 問題が顕在化 ○ 具体的には大量に ElastiCache 系のリソースを定義している箇所で Describe* 系の API が多数発行され rate limit に引っ掛かっていた ○ API rate limit に引っ掛かると、大体の場合は時間を置いて plan/apply をやり直す必要があり、かなりの手間
Slide 21
Slide 21 text
© 2024 Wantedly, Inc. そして分割へ…
Slide 22
Slide 22 text
© 2024 Wantedly, Inc. 解決したい課題 ● plan/apply を高速化したい ● rate limit に引っ掛からないようにしたい ● 人にとってわかりやすい構成にしたい
Slide 23
Slide 23 text
© 2024 Wantedly, Inc. 課題にどう立ち向かうか ● monolith tfstate を細かい単位で分割していく ○ tfstate を小さくすればその分 plan/apply 速度は改善するはず ○ rate limit にも引っ掛かりにくくなるはず ○ tfstate の分割単位を工夫すれば人にとって分かりやすくなるはず
Slide 24
Slide 24 text
© 2024 Wantedly, Inc. tfstate 指針を決める tfstate の分割指針 ● アプリケーションや サービスごとに tfstate を わける ● 環境ごとに tfstate を わける 例 ● visit/ ○ sandbox/, qa/, prod/ ● hire/ ○ sandbox/, qa/, prod/ ● datadog/ ○ sandbox/, qa/, prod/
Slide 25
Slide 25 text
© 2024 Wantedly, Inc. 分割は一筋縄ではいかない ● 実際に分割するのはハードルが高い ○ 1,000 以上のリソースを適切な粒度で分割する、というのは時間がかかる ■ 数が多いと単に時間がかかる ○ 「適切な粒度」というのも先の例に嵌らないものもあり難しい ■ 困る例: 複数のアプリケーションから参照されている Aurora cluster は どう分割する? ● =>「初めから完璧を目指さない」という方針で進める
Slide 26
Slide 26 text
© 2024 Wantedly, Inc. 徐々に分割する 具体的にどうするか? ● monolith tfstate には新しいリソースを置かない
Slide 27
Slide 27 text
© 2024 Wantedly, Inc. 徐々に分割する ● 直近の例: Wantedly Hire 系のリソース定義は hire/ 下に 置く ● ただし必ず従わなくてもよい ○ tfstate の新規作成が手間なら一旦 monolith tfstate に置いてもよい ○ 「分割」はあくまでも困り事を解消するための手段なので、本来の仕事を優先する ○ 分割によって困り事が増えるのは本末転倒
Slide 28
Slide 28 text
© 2024 Wantedly, Inc. 徐々に分割する すでに monolith tfstate にあるリソースはどうする? ● すべては分割せず、困ったものから tfstate を 分割していく
Slide 29
Slide 29 text
© 2024 Wantedly, Inc. 徐々に分割する ● 具体例: rate limit に引っ掛かりがちだった ElastiCache の定義のみ elasticache/ ディレクトリに切り出す ○ 本来は ElastiCache が使われているサービスごとに分割したい ■ (Wantedly Visit で使っている ElastiCache は visit 配下に置く、など) ○ しかし「サービスごと」という分割の粒度を決めるのは、それはそれで大変 ○ 直近の困り事の解決を優先して、一旦分割しやすい elasticache/ という粒度で分割 する
Slide 30
Slide 30 text
© 2024 Wantedly, Inc. 分割して得られた嬉しさ ● 「完璧を目指さない」という方針のため分割は道半ば ● それでも直近の問題は解消された ○ 5 分かかっていた plan/apply は 10 秒ほどで終わるようになった ○ 分割したディレクトリで configuration drift が発生しても 他のディレクトリに影響がなくなった ○ API rate limit に引っ掛からなくなった
Slide 31
Slide 31 text
© 2024 Wantedly, Inc. ファイルの見通しもよくなった ● monolith tfstate はファイル単位でも monolithic になっ ていた ○ 例: ElastiCache cluster の定義はすべて elasticache.tf に置く ○ 中には 4,000 行近くのファイルも…
Slide 32
Slide 32 text
© 2024 Wantedly, Inc. ファイルの見通しもよくなった ● tfstate 分割に伴い ファイルを分割しやすくなっ た 例: ● hire/prod/ ○ s3.tf ○ cloudfront.tf ○ rds.tf
Slide 33
Slide 33 text
© 2024 Wantedly, Inc. Renovate PR を分割する ● Renovate が作成する PR の分割単位はパッケージごと ○ 例: AWS provider の更新 PR、Google Cloud provider の更新 PR、… ● つまり複数 tfstate をまたいで 1 つの PR が作成される
Slide 34
Slide 34 text
© 2024 Wantedly, Inc. Renovate PR を分割する これのつらいところ: ● AWS provider の更新があると大量の tfstate を変更した PR が作られる ○ 分割した tfstate ではほぼ全て AWS provider に依存しているため ● 頻繁に & 大量に plan/apply されるため CI 時間も無駄 ○ Renovate はベースブランチに更新があるとその更新を取り込むため、 頻繁に実行される
Slide 35
Slide 35 text
© 2024 Wantedly, Inc. Renovate PR を分割する ● 対策: Renovate PR を tfstate ごとに分割する ○ renovate.json 例: { "packageRules": [ { "matchManagers": ["terraform"], "matchDatasources": ["terraform-provider"], "additionalBranchPrefix": "{{packageFileDir}}-", "commitMessagePrefix": "{{packageFileDir}}: ", }, ] }
Slide 36
Slide 36 text
© 2024 Wantedly, Inc. 分割によって見えてきた新たな課題 ● Renovate PR が多い ○ tfstate の数 × provider 等のバージョン更新の回数だけ PR が作成される ○ 特に AWS provider は更新頻度も高く、利用している tfstate も多い ● tfstate ごとに分けるほどでもないファイルの変更が困難 ○ 例: tflint の設定ファイルは共通のルールを使いたい ○ Renovate と同様に複数の tfstate をまたいだ変更になるため plan/apply の 回数が多くなる
Slide 37
Slide 37 text
© 2024 Wantedly, Inc. 今日持ち帰ってほしいこと (再掲) ● 巨大な tfstate はつらい ● が分割するのも一筋縄ではいかない ● 完璧を目指さず徐々に移行していこう
Slide 38
Slide 38 text
© 2024 Wantedly, Inc. https://www.wantedly.com/projects/522096
Slide 39
Slide 39 text
© 2024 Wantedly, Inc. https://wantedly.connpass.com/event/332164/