はじめに
こんにちは!Sreake事業部 横尾(@866mfs)です。
3-shakeでは、社員なら誰でもGoogle Cloud の各種サービスを検証できる、検証環境アカウント(ここでは ”test.org” と表記)が存在します。
今回は、そんなGoogle Cloud検証環境についてのお話です。
背景
私たちの組織では、上記の検証環境利用時には下記のような課題がありました。
- 誰でもプロジェクトを作成可能(プロジェクトの課金紐付けは要情シス申請)なので、アカウント統制が皆無のカオス状態
- 未使用のプロジェクト・リソースがそのままになってしまっていることも多々ある
- コスト管理についてモニタリングの仕組みが出来ていないので、それなりの高額請求になってしまっていることもしばしば
- セキュリティ的に問題が無い使われ方か把握できていない
- 新入社員が把握できていない / 離職者のアセットや権限が放置されている
そこで、本活動では3-shakeのSreake事業部 SREが、これら課題を解決するための一時的な小規模チーム(以降:Google Cloud 検証環境整備チーム)を作成し改善活動を行いました。
基本方針
取り組みは各自の工数の10~20%とし、参画している案件に支障をきたさないかつ、改善のパフォーマンスを考慮した上で、費用対効果がとても低い活動については実施しない方針とします。
また、メインとする改善活動の期間は2か月と限定し、スコープ内で出来る範囲のことに取り組むこととしました。
これが「頑張りすぎず」の意味です!
やったこと
活動目標と意義を明確化
経験ある方はお分かりかと思いますが、このような組織ガバナンス活動においてはゴールが明確でないといつまでもダラダラと続いてしまったり、途中で頓挫してしまいがちなので、まずはこの活動が目指す意義を以下のように定義し、メンバーの認識を合わせることとしました。
Sreakeのエンジニアが安心して快適に検証環境を利用できるように、検証用アカウントの管理・改善活動を行う
それぞれに込めた想いは以下です。
- 「Sreakeのエンジニア」
- 最小限のスコープとするため他事業部は考慮しない
- 「安心して」
- コスト / セキュリティ面ともに安心・安全な状態に
- 「快適に」
- コスト / セキュリティ面を考慮しすぎて開発者体験が悪くならないように
- 「管理・改善」
- 仕組みと体制作りを行う
- 形骸化しないように利用状況の把握や認知を行い、ユーザビリティ向上のための活動は継続して実施
- 属人化しないように、責任範囲を広げていく(手離れさせることも重要)
Cloud Nativeな視点を取り入れる
今回の活動においては、SREとして普段プラクティスを実践する中で大切にしている考え方(トイル削減や自動化など)はもちろん、Cloud Nativeな視点も入れつつ実践していくことで、k8sを中心とした将来的な周辺エコシステムとGoogle Cloudを連携した利活用を促進できるようにしました。
Cloud Nativeの定義は人によって様々だと思いますが、そもそも”テクニカル”な意味での「Cloud Native」とは何だろうかと?気になったので調べてみました。
すると、CNCF曰く以下のように定義されています。
クラウドネイティブ技術は、パブリッククラウド、プライベートクラウド、ハイブリッドクラウドなどの近代的でダイナミックな環境において、スケーラブルなアプリケーションを構築および実行するための能力を組織にもたらします。
このアプローチの代表例に、コンテナ、サービスメッシュ、マイクロサービス、イミュータブルインフラストラクチャ、および宣言型APIがあります。
これらの手法により、回復性、管理力、および可観測性のある疎結合システムが実現します。 これらを堅牢な自動化と組み合わせることで、エンジニアはインパクトのある変更を最小限の労力で頻繁かつ予測どおりに行うことができます。
Cloud Native Computing Foundationは、オープンソースでベンダー中立プロジェクトのエコシステムを育成・維持して、このパラダイムの採用を促進したいと考えてます。 私たちは最先端のパターンを民主化し、これらのイノベーションを誰もが利用できるようにします。
https://github.com/cncf/toc/blob/main/DEFINITION.md#日本語版
ポイントを捉えると以下のような解釈ができると思います。
- 疎結合である
- 復元力がある
- 管理しやすい
- 可観測である
- 堅牢な自動化により、頻繁かつ期待通りに最小限の労力で大きな変更が可能
これら視点を加えながら考えていきました。
現状把握
当初のフォルダ・プロジェクト状況は特段管理上のルールや仕組みを設けていないことから以下のような無法地帯構成となっていました。
パッと見た感じでもいけてないポイントは以下のようにあります。
- 組織配下にフォルダ・プロジェクトが無秩序に乱立
- MyFirstProject大量発生
- 権限に制限は無く、他プロジェクトも自由に参照・更新・削除可能
- どのプロジェクトが使用中か分からない🤦
- etc..
(「まあ、検証環境だから」ということで全て放置されていました)
フォルダ構成設計
そこでまずは、各種フォルダでの利用者スコープを明確にし、無法地帯となっているフォルダ構成を適切に管理するために、組織としてあるべきフォルダ構成を以下のように設計しました。
第1階層
事業部ごとでプロジェクト運用の仕方や使い方が異なるため、組織横断とはせず事業部単位でのフォルダ管理とすることで、責任範囲の明確化と独立性の高い構成としました。
sharedフォルダには、事業部横断での活動に関するプロジェクトを格納しています。
第2階層
今回は、sreake事業部についての事例なのでここからは、sreakeフォルダ配下に焦点を当てて見ます。
第2階層には、検証のメインとするsandboxフォルダと事業部内で活動中のいくつかのプロジェクトを配置しました。
sandboxフォルダ配下
sandboxフォルダ配下には、事業部メンバーの個人フォルダを作成し、各自のフォルダ配下にプロジェクトを作成して検証を行います。
- 「社員番号_name」フォルダという命名規則の元、個人フォルダを作成
- 命名規則統一と責任範囲の明確化による管理のしやすさを向上
一方、sreakeフォルダ直下に存在する個別の2つのプロジェクトは以下のような目的から直下に配置しています。
terraform
(後述)- stateファイルを管理するGCSが存在するプロジェクト
management
- コストアラートに関するリソースを管理するプロジェクト
権限設計
次に、定義したフォルダ構成に対して「誰にどのレベルの権限が付与されるべきか」を考えていきました。こちらがtest.orgのプロジェクト階層構造となっています。(一部抜粋)
Google Cloudはリソース階層を使用したアクセス制御が行われるため、最小限の労力で大きな変更が可能となるよう、基本的に権限は「継承」する形となるように定義しました。
以下2つのGoogle Groupを作成し、各RoleはGoogle Cloud IAMベストプラクティスに沿う形でGoogle Groupにアタッチする形式で付与を行いました。
- Adminグループ(admin@3-shake.com)
- 運用に携わる検証環境整備チームメンバーで構成
- 継承Role
roles/resourcemanager.folderAdmin
- Stuffグループ(stuff@3-shake.com)
- Sreake事業部メンバー(adminグループのメンバー含む)全員で構成
- 継承Role
roles/browser
- フォルダ、組織、許可ポリシーなど、プロジェクトの階層を参照する権限
roles/viewer
- sandbox配下の全てのプロジェクトのviewer権限
メンバー全員が所属するGoogle Groupとは別に、個人アカウントに対して以下の権限が付与されるように設計しました。
- 個人アカウント(user-account@3-shake.com)
roles/resourcemanager.folderCreater
- 個人フォルダ内でのフォルダ作成権限
roles/resourcemanager.projectCreater
- 個人フォルダ内でのプロジェクト作成権限
roles/owner
- 新規に作成したプロジェクトでの権限
Terraformでの構成管理
各フォルダに対応するアクセス制御を検討する中で、当初は手動での管理を想定していました。しかし、今後の運用負荷や組織のスケーリングを考慮した時に、やはりIaCとして構成管理をしておいたほうがメリットが大きいのではないかという仮説のもとTerraformを使用して構成管理を実施することを決定しました。
Terraformのディレクトリ構成は以下のように実施しました。
.
├── README.md
├── main.tf
├── modules
│ ├── managed-folders
│ │ ├── budget.tf
│ │ ├── folders.tf
│ │ ├── iam.tf
│ │ ├── outputs.tf
│ │ └── variables.tf
│ └── personal-sandbox-folder
│ ├── folders.tf
│ ├── iam.tf
│ └── variables.tf
├── provider.tf
└── variables.tf
軸となる各フォルダ・ファイルの役割は以下です。
main.tf
- moduleを呼び出し / resource作成処理
modules/managed-folders
- 第2階層のフォルダリソースを管理する
- フォルダに対するRoleを管理
modules/personal-sandbox-folder
- 第3階層以下(sandboxフォルダ配下)のフォルダリソースを管理
variables.tf
- メンバー情報をvariableとして保持
- メンバースケール時には当ファイルにuser_accountとfolder_nameを、追記および削除後、PRを作成しGitでの管理が可能
- PRのマージ後に
terraform apply
を行い対象メンバーのフォルダが作成されるとtfstateでの管理が可能
variable "personal_sandbox_folders" {
type = list(object({
folder_name = string
user_account = string
}))
description = "個人のサンドボックスフォルダの作成に必要な値のマップのリスト"
default = [
{
user_account = "your-email-1@3-shake.com"
folder_name = "社員番号_name_1"
},
{
user_account = "your-email-2@3-shake.com"
folder_name = "社員番号_name_2"
},
IaCスコープ限定による責任範囲の明確化
各メンバーの責任範囲を考える際に意識したこととして以下があります。
- 権限委譲を行うことで運用負荷を軽減しつつ、各メンバーがガバナンス意識を持って使用できること
そのため、「個人フォルダ(社員番号_nameXX)配下のプロジェクトやリソースについては、当該メンバーが責任を担うこと」とし、TerraformでのIaCスコープはフォルダレイヤーのみに限定しました。
個人フォルダ配下はIaCスコープには含めず、新プロジェクト作成時の権限もroles/owner
がアタッチされるようにしました。
そのため、個人フォルダ配下ではフォルダやプロジェクトを自由に作成可能です。
個人フォルダ作成時に設定されたIAM ポリシーによって、他のメンバーはリソースの作成や編集を行えないようになっていますが、個人フォルダ内で他メンバーと一緒に検証を行いたい場合は、プロジェクトの作成者が「他メンバーがプリンシパルとなるIAM ポリシー」を作成して同プロジェクト内にて一緒に検証を行うことも可能です。
既存プロジェクト要否確認
決定した構成に基づき、元々、全33プロジェクトあったうちの、18プロジェクトを削除しました。
プロジェクトを削除するに際には、アナウンスの頭出しからメンバーへのヒアリング、整理実行までの期間をおよそ10日前後取り、活動周知や合意形成の期間を十分に確保しながら行いました。
(このあたりは結構気を遣ったポイントです。)
また、削除したプロジェクトの中には、既に不要なのにもかかわらず稼働中のリソース(消し忘れリソース)などもあり、それらの削除も同時に行えたため(具体的な金額の記載は控えますが、)直接的な金銭的コストカットにも寄与できました!
啓蒙活動(ドキュメント整備)
そもそもの活動背景から認知してもらうため、ドキュメントを作成し活動の展開を行い、事業部メンバーが集う会での周知など、メンバー各人にオーナーシップを持ってもらう啓蒙活動も実施しました。
Opsへの落とし込み
これまでGoogle Cloud検証環境は、使いたい人が自由にプロジェクトを作成するような環境となっており、運用は全く定まっていませんでした。よくありがちのように、有識者がなんとなくの場当たり的な対応で管理を行っていました。しかし、それでは組織がスケーリングする中で、問題にいつか直面する日が来てしまいます。
そこで極力、運用フローとして乗せやすい入社時・離職時のオンボーディング & オフボーディングにメインとして組み込む形式で「環境の周知から管理対応まで」実施できるように、以下のように運用を検討しました。
メンバー追加および削除に必要なveriable.tf
への記述は、追加メンバーにて手動で実施してもらい、運用チームへのPRをあげてもらうことで管理することとします。
やらなかったこと
以下に記載のことは本活動の意義である「Sreakeのエンジニアが安心して快適に検証環境を利用できるように、検証用アカウントの管理・改善活動を行う」に対して、費用対効果の観点やあるべき姿への本質的なズレから実施しませんでした。
他事業部関連プロジェクトへの介入
今回はスコープを最小限にするという点から他事業部に関することはフォルダー作成・プロジェクト配置のみを行い、中身の精緻化については実施しませんでした。(各事業部ごとに統制が異なるため、それぞれに運用チームを用意していくことが本来あるべき姿と考えています)
CI/CD
組織のスケールやシュリンクが現状頻繁に発生しない点と、CI/CD構築に対する稼働コストパフォーマンスの観点からこのタイミングで実施することは見送りました。
組織ポリシーの適用
Google Cloudには組織ポリシーと呼ばれる、組織レベルからリソース使用に関わる制約を適用する機能が存在します。これはクラウドガバナンスの統制において、他のパブリッククラウドでも同様の機能として頻繁に用いられます。
今回も例にも漏れず以下のように検討を行いました。
- 適用した方が良さそうな制約を選定
iam.allowedPolicyMemberDomains
constraints/gcp.resourceLocations
constraints/compute.vmExternalIpAccess
etc..
- 制約に対する脅威とリスクの洗い出し
- チーム内にて協議
協議の結果、組織ポリシーを適用することがGoogle Cloud検証環境利用における本質的な課題解決につながらないかつ、あくまでも「検証環境」という位置付けのため「利用制限・運用負荷は最小限にし、検証の柔軟性が下がらない」ことを考慮し実施しませんでした。ただ、組織ポリシーの使用に関する議論の実施についてはとても有意義なこととなりました。
活動を通して得られたこと
ここまでのGoogle Cloud検証環境整備活動を通して主に得られたことをまとめます。
1. 一定レベルのクラウドガバナンス
権限管理、構成管理を適切に実施することで、クラウドガバナンスレベルの水準底上げ
(メンバー各自のガバナンス意識に依存してしまう部分も一定あり)
2. 運用負荷低減
極力、運用の自動化を推進することで定常的に行う作業の削減(トイル削減)
現在は月次でMTGを実施し、利用状況のモニタリング、運用事項のブラッシュアップへ向けたディスカッションを実施中
3. コストモニタリング・利用状況の可視化が容易
事業部ごとやメンバーごとのフォルダ構成としたことにより、Billing Reportの標準的なフィルタリングのみでコストやリソース使用状況が取得可能
4. Cloud Nativeな視点で構成
- 疎結合である
- 利用に際して事業部間 / メンバー間での依存関係が無く、独立性が高い構成
- 復元力がある
- Terraformで構成管理をしているため即時のプロビジョニング / リカバリーが可能
- 管理しやすい
- 構成内容が明文化されているかつ冪等性のある構成を実現
- 可観測である
- 差分検知にはPR、証跡はGoogle Cloud各種サービスログと連携することでさらなるクラウドガバナンス向上が期待
- 堅牢な自動化により、頻繁かつ期待通りに最小限の労力で大きな変更が可能
- 組織のスケール対して最小限の変更かつ、運用フローと統合して利用環境のスケールが可能
まとめ
ここまで様々な活動を実施して、Google Cloud 検証環境をCloud Nativeな視点から、良い感じに整えられたと感じています。
もちろん、まだまだ改善点やクラウドガバナンスのさらなる強化は必要だと感じています。
そしてなにより大切なことは、施策の実施よりもメンバー1人1人が、検証環境の位置付けを認知しガバナンス意識を高く持ち続けてもらうことだと思います。テクニカルな施策だけに留まらず、啓蒙活動も継続して実施することで無法地帯へ回帰しないようにこれからも見守っていきたいと思います。
最後に、このブログと同内容で、Jagu’e’r Cloud Native #12 ハイブリッド Meetup でも登壇しているので、ご興味ある方はそちらも合わせてご覧いただければと思います。
SREがGoogle Cloud検証環境をCloud Nativeな視点で、 頑張りすぎずでも良い感じに整えた話
今後できそうなこと
最後におまけとして、「クラウドガバナンス強化に向けて今後こんな取り組みも出来そうかも」と思ったことを記述します。
CloudRunを活用したログ分析基盤
- Google Cloudに関する様々なログ情報(Cloud AuditLogs, Cloud AssetInventory, Cloud Billingなど)を一元的にBigQueryに集約
- 監視したいメトリクスをBigQueryから、Cloud Run Jobs or Cloud Functionsをスケジューリングし定期的にクエリを実行し収集することでモニタリング結果の閾値検出をSlack通知
Slack通知bot
- Billing Reportからプロジェクト単位で抜粋して条件をユーザが選択できるSlack通知ボット
- Cloud Audit Logsを併用してresource createrを特定し、リソース使用の有無を選択できる機能
- Cloud Monitoring と Cloud Run を使用したカスタム通知を応用
参考
- 「VM 時代の開発とKubernetes による Cloud Native な開発のこれから」Infra Study Meetup #2 / infrastudy2-k8s
- 新米Google Cloud管理者の奮闘記のその後 〜Organizationの秩序を維持する試み〜