☁️

【2025年振り返り】Cloud Praticaの学びをTerraform運用とGKE基盤の整備へ還元した1年

に公開

Cloud Pratica で得た知識を武器に、この1年で取り組んだ業務改善と自身の成長を振り返ります。

はじめに

Cloud Pratica とは

りょうまさんが今年立ち上げた、インフラ技術に特化したエンジニア向けオンラインスクールです。(以降は CP と略します)
カリキュラムの詳細は以下からご覧いただけます。
https://esa-pages.io/p/sharing/22089/posts/38/d4945bad94371c376867.html

自己紹介

CP 受講生の shinnosuke と申します。
2023年に新卒でエンジニアとして就職しました。
最初の2年は主にAWSを用いたインフラ構築・Next.jsを使った管理画面実装・Nest.jsを使ったバックエンドの運用保守を行っていました。
今年の4月からは新しいチームに移動し、Google Cloudを用いたインフラ構築やGoを使ったバックエンド開発を行っています。

振り返り

CP での学びを起点に、今年1年の業務を振り返っていきます。
単に技術を学んだという話ではなく、
その学びが実際の業務でどのように活きたのか、という視点で整理します。

1月~3月 : AWS基礎・実践の学びを業務に活かす

CP は 2月から受講し、まずは AWS の基礎・実践コースを学びました。
既に AWS を触っていたものの、「なんとなく運用していた部分」を体系立てて理解し直せたのが一番の収穫でした。

背景:CDK の抽象化で見えていなかった部分

業務では AWS CDK を使って ECS クラスターやタスク定義を構築していましたが、CDK が内部的に何を作っているのかを明確に理解していませんでした。

学習:AWS コンソールからの手作業で概念を理解

CP での基礎・実践コースでは、以下のような作業を通じて AWS の基本的な概念を学び直しました。

  • IAM Identity Center による SSO の設定
  • 命名規則(サフィックス・プレフィックス)の重要性
  • DNS 委任(サブドメインの委任)の仕組み
  • クラスター、タスク定義、サービスの作成

特に、コンソール画面から実際にリソースを作ることで、CDK が背後で何をしているのかが理解でき、抽象化されていた部分が体系的にはっきり見えるようになりました。

業務での活用例:ECS の cron 多重実行を防ぐ

当時の ECS は、Web サーバーと cron による定期実行を 同一タスク内にまとめていました。
この構成だとローリングアップデート中にタスクが一時的に複数起動し、cron が多重実行されることがあります。

そこで次の対応を行いました。

  1. 新しく起動したタスクでは cron を無効のまま起動する(Dockerfile / 起動スクリプトを修正)
  2. 古いタスクの終了を検知し、新タスクで cron を有効化する
    • ECS イベント → EventBridge → Lambda の流れで、ECS Exec 経由で crontab を有効化

この対応により、ローリングアップデート時の cron 多重実行を抑えられ、運用が安定しました。

この期間の成果は、CDK で見えづらかった AWS の仕組みを理解し直すことで、ECS 運用のトラブルに対して根本原因から対策を講じられるようになったことでした。

4月~6月 : Terraform を使った Google Cloud のインフラ構築

4月に新規プロジェクトへのチーム異動に伴い、最初に取り組んだのが Google Cloud のインフラを Terraform で継続運用するためのパイプライン構築でした。
この期間は Terraform のコードを書くことに加えて、変更を「安全に・速く・チームで」回せる状態にすることに注力しました。

既に存在していた設計の強み

プロジェクト初期段階で、以下のような基盤が構築されていました。

  • 変更の影響範囲を限定するための責務ごとの ルートモジュールや State ファイルの prefix 分割運用
  • plan/apply を GitHub Actions 経由に限定(ローカルでの実行を禁止)

この設計があったため、自分は、既存の仕組みの高速化・自動化に専念しました。

├── modules
│   └── gcp
│       ├── alert-policy
│       └── artifact-registry
├── platform
│   ├── iam
│   │   ├── dev
│   │   └── prd
│   └── network
│       ├── dev
│       └── prd
└── services
    ├── hogehoge
    │   ├── dev
    │   └── prd
    └── piyopiyo
        ├── dev
        └── prd

差分検知 × 並列実行で、PRの検証を高速化

当初は plan を手動で実行する形で、変更が複数のディレクトリにまたがる場合は、ディレクトリを切り替えながら順番に確認する必要がありました。
これだと検証に時間がかかり、PR のレビュー待ち時間も伸びやすくなります。

そこで、PR 作成時に 変更があったディレクトリを自動で特定し、対象ディレクトリすべてに対して次を 並列 で実行する仕組みにしました。

  • 静的解析(TFLint / Trivy)
  • terraform plan(tfcmt で PR にコメント)

結果として、変更が1つでも複数でも、PR を出すだけで必要な検証が自動的に走り、複数ディレクトリの静的解析 / plan を並列で回せる状態になりました。
これにより、検証の手間と待ち時間が減り、レビューもしやすくなりました。

参考:tfcmt
https://zenn.dev/shunsuke_suzuki/articles/improve-terraform-cicd-with-tfcmt

残課題:差分検知の限界(module 変更が検知できない)

一方で、差分検知が git diff ベースのため、modules 配下のみの変更は呼び出し側の差分として現れず、plan 対象から漏れる課題があります。
今は顕在化していませんが、module 更新が増えてきたタイミングで、以下のような modules のバージョン固定(タグ運用)などを検討していきたいです。

module "artifact_registry" {
-  source = "git::https://github.com/your-org/terraform-modules.git//modules/gcp/artifact-registry?ref=v1.1.0"
+  source = "git::https://github.com/your-org/terraform-modules.git//modules/gcp/artifact-registry?ref=v1.2.0"
}

PR を出すだけで複数ディレクトリの静的解析と plan が並列で完了するようになり、検証待ちと手作業を減らすことができました。

7月~9月 : GKE ワークロードの構築

Terraform による基盤整備が一段落した後は、GKE 上でワークロードを「チームで継続運用できる形」に整えていきました。
この期間に意識していたのは、単に動かすことではありません。運用の型(デプロイ・認証/認可・外部公開・障害時の切り分け)を揃えることです。

背景:クラスターと Argo CD はあるが、運用の型がない

GKE クラスターと Argo CD の導入は完了していました。
一方で、本格的なワークロード構築と運用設計はこれから、という状態でした。

当時の Argo CD は upstream の raw manifest を直接参照する構成でした。

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: argocd
resources:
- https://raw.githubusercontent.com/argoproj/argo-cd/v2.14.11/manifests/ha/install.yaml

この方式でも動作はしますが、運用面では次の課題がありました。

  • バージョンアップ時の差分が追いづらい(巨大マニフェストの追従になりやすい)
  • 上書きしたい設定(パラメータ)を、チームでレビューしやすい形で管理しづらい

運用整備1:Argo CD を Helm 管理に移行

CP での学びも踏まえ、Argo CD は Helm で管理する形に移行しました。

  • バージョン管理がしやすい(Chart/values の差分で追える)
  • values.yaml に上書きが集約され、意図が読みやすい
  • 将来の設定追加・調整も、運用として回しやすい

運用整備2:Adminユーザー運用をやめ、GitHub Teams ベースの SSO に移行

当初の Argo CD は admin ユーザーのみで運用されており、利用者が増えるほど「認証情報の共有」や「誰が何をしたかの追跡」が課題になりやすい状態でした。

CP では GitHub を使った SSO(個人の GitHub アカウントでログイン)を学びました。
その学びを業務に応用し、さらに一歩進めて次の形に移行しました。

  • admin アカウントを通常運用では使わない方針にし、無効化
  • GitHub SSO を導入し、ログインを個人に紐づける
  • 個人単位で Argo CD 側の設定を増やさず、GitHub Teams を“グループ”として扱い、権限付与はチーム単位に寄せる

運用としては、プラットフォームチーム / アプリケーションチームの2つの GitHub Team を作り、Argo CD の権限管理もチーム単位で運用しました。

この変更のメリットは以下です。

  • メンバーの追加・削除は GitHub Teams 側の操作で完結し、Argo CD 側の設定更新がほぼ不要
  • 認証が個人に紐づくため、監査性(誰が操作したか)が上がる
  • チームごとに権限を整理でき、事故が起きにくい運用にできる

結果として、Argo CD を「一部の管理者だけが触るツール」から、チームで安全に使えるデプロイ基盤に移行できました。

外部公開の設計:Gateway API を採用

当時の GKE はクラスターと Argo CD のみがある状態で、外部公開(ロードバランサ周り)の仕組みはこれから設計する段階でした。
そのため最初から、柔軟に設計できる Gateway API を前提に進めました。

CP では EKS で ALB(AWS Load Balancer Controller)を扱っていたため Gateway API は初見でしたが、GKE の公式ドキュメントに概念説明とマニフェスト例が揃っており、設計判断を進めやすかったです。
https://docs.cloud.google.com/kubernetes-engine/docs/concepts/gateway-api?hl=ja

採用理由として大きかったのは、プラットフォーム側の共通設定と、アプリケーション側のルーティング設定を分けて設計できる点です。
具体的には、外部公開の入口となる Gateway はプラットフォーム側で管理しつつ、各アプリケーションは自分たちの namespace に HTTPRoute を置いてホスト/パス/バックエンドのルーティングを定義できます。

この形にすると、入口(共通設定)は統一しながら、ルーティング変更はアプリケーション側で完結するため、安全な運用体制を実現できました。

苦労した点:ローリングアップデート時に 50x が発生(draining と Pod 終了のタイミング)

外部公開したワークロードで、デプロイのタイミングに 50x 系エラーが断続的に発生しました。
原因は、ロードバランサー側の切り替え・接続終了(draining)が完了する前に Pod が終了し、古い Pod 宛ての接続が残った状態でリクエストが流れてしまうケースがあったためです。

対策として、公式ドキュメントの考え方に沿って preStop を調整し、次の関係を満たすように設定しました。

preStop hook execution time >= BACKEND_SERVICE_DRAIN_TIMEOUT + DRAIN_LATENCY

また、preStop の待ち時間を確保しても、Pod が先に強制終了されてしまうと意味がないため、
terminationGracePeriodSeconds も含めて graceful shutdown の時間を見積もり、次の関係を満たすように設定しました。

terminationGracePeriodSeconds >= preStop の待ち時間 + アプリの終了処理(シャットダウン)時間


出典: GKE 公式ドキュメント(500-series errors)

これにより、Pod を落とす前に待ち時間を確保し、ロードバランサー側が endpoint の切り替え・接続終了を完了できるようになり、デプロイ時の 50x が大きく減りました。

参考(公式):
https://docs.cloud.google.com/kubernetes-engine/docs/troubleshooting/load-balancing?hl=ja#500-series-errors

この期間の成果は、GKE 上にアプリを載せるだけでなく、Argo CD の管理方法・認証/認可・外部公開・デプロイ時の安定性まで含めて「チームが安心して使えるプラットフォームの型」を作れたことでした。

10月~11月 : Go を使ったバックエンド開発と可観測性の向上

10月からはバックエンド開発に本格的に取り組むようになりました。既存マイクロサービスへの機能追加から始まり、11月には新規マイクロサービスの設計・実装も経験しました。

学習:Datadog コースを通じた APM とログ設計の理解

CP では 11月中旬から Datadog コースが開講され、ECS で稼働する Go アプリケーションの APM を確認する課題を行いました。
業務では Datadog は使用していませんが、この実習を通じて得た「可観測性の設計思想」は、現在の Google Cloud 環境での開発に非常に役立っています。
https://x.com/engineer_ryoma/status/1989592892642644030?s=20

業務での活用:Cloud Logging を活用した「調査しやすい」ログ設計

CP で学んだ「リクエスト単位で情報を束ねる」考え方を応用し、業務の Go 開発において以下のログ改善を行いました。

  • コンテキストへの Logger 注入とリクエストの紐付け
    Context に Logger を注入し、リクエスト単位でログをまとめる仕組みを整えました。これにより、現在は APM ツールを導入していなくても、将来的に Datadog 等を導入した際にリクエストごとのスパンを正しく計測・可視化できる下地を作ることができました。
  • マルチテナント調査を支える構造化ログ
    ログを構造化し、リクエスト ID だけでなく アカウント ID などの付随情報を一貫して出力するようにしました。これにより、特定のユーザーで発生した不具合の調査が格段にスムーズになりました。
  • ノイズ除去によるコスト最適化と検索性の向上
    ヘルスチェックなどの不要なアクセスログをアプリケーション側でフィルタリングして出力しないよう調整しました。これにより、Cloud Logging のストレージコストを抑制できるだけでなく、ログ検索時にわざわざクエリでヘルスチェックパスを除外する手間がなくなりました。

この期間の成果は、単にコードを書くだけでなく、「本番環境で何が起きているかを正しく把握し、運用コストまで意識した実装」ができるようになったことでした。

12月 : 既存 AWS プロジェクトの現状把握と向き合い

12月からは、長期間にわたってプロダクトを支えてきた AWS インフラを持つ別プロジェクトにも関わり始めました。
そこでは Lambda や DynamoDB を活用したサーバーレスアーキテクチャが採用されていますが、長年の運用と技術の変遷に伴い、以下のような構造的な課題が見えてきました。

  • デプロイ手法の多様化: 開発時期や当時の最適解に応じて、CDK、SAM、Serverless Framework など複数のツールが併存している
  • リソースの個別最適化: Elastic Beanstalk 等による ALB が各機能ごとに構築されており、共通基盤としての集約に伸び代がある

これらは、プロダクトが成長し続けてきた証(歴史的経緯)でもありますが、今後の開発スピードを加速させるためには、運用をシンプルにするための「標準化」が必要だと感じています。

CP の AWS 応用コースでは、API Gateway や Lambda を用いたサーバーレス設計のベストプラクティスを体系的に扱っています。その学びをコンパスに、既存の設計を尊重しつつも、今のチームにとってよりメンテナンスしやすい形への統合・改善を提案していきたいと考えています。

まとめ

今年1年を通じて、単に「技術を習得する」だけでなく、「チームが継続的に運用できる仕組みを設計する」という視点を持てるようになったことが最大の収穫でした。

その成長の土台には、常に Cloud Pratica での「なぜこの設定が必要なのか」という本質的な学びがありました。

  • 「書ける」から「回せる」IaCへ
    Terraformの基礎を学んだことで、単にリソースを作るだけでなく、並列実行や差分検知といった「レビューしやすく、止まらない運用」を Google Cloud 上で構築できました。
  • 「動く」から「安心できる」プラットフォームへ
    Kubernetesの仕組みを深く理解したことで、Argo CDの認証基盤整備や、draining調整による50xエラーの解消など、チームが自信を持ってデプロイできる環境を整えられました。

Cloud Pratica での学びは、環境やクラウドプロバイダーが変わっても揺るがない「判断基準(コンパス)」を自分の中に作ってくれました。単なる座学ではなく、実際に手を動かしながら「なぜ」を理解できたからこそ、現場の状況に合わせた最適なアプローチを判断できるようになったと感じています。

来年の抱負

来年は、今年得た知識と経験をベースに、さらに一段階深い学習と実践に取り組みたいと考えています。

業務での目標

  • AWS インフラの改善
    既存プロジェクトの課題解消に向けて、サーバーレスアーキテクチャの設計を体系的に理解し、実装に活かしていきます。
  • GKE プラットフォームの成熟化
    今年作った運用の型をさらに磨き、チーム規模の拡大に対応できる堅牢性を備えたプラットフォームへ進化させたいです。
  • アプリケーション開発(Go)の深化
    機能追加だけでなく、パフォーマンスを意識した実装ができるエンジニアを目指します。

個人的な学習目標

  • Kubernetes の体系的理解: Kubestronaut 認定を目指します。
  • 低レイヤーの知識習得: OS、CPU、データベース、ネットワークなどの基礎を学び、トラブルシューティングで迷わない地力を付けます。

インフラとアプリケーションの両方を理解し、プロダクトに対してより大きな価値を提供できるエンジニアを目指して、来年も成長を続けていきたいです。

Discussion