G-gen の武井です。
当記事では GitHub と Config Controller (Config Sync) を連携して Google Cloud (旧称 GCP) のリソース管理を自動化する方法について解説します。
当記事について
位置付け
以前 Google Cloud のブループリントを利用してリソース管理を自動化する方法を紹介しました。
ブループリントを使用する場合、GitOps パイプライン (自動化の仕組み) におけるソースコード管理には Cloud Source Repositories が用いられます。
Cloud Source Repositories には2024年3月時点では Pull request 機能がないため、GitHub を導入して Pull request をはじめとした コラボレーション機能を補完して利便性を向上 させる意図があります。
前提知識
内容の重複を避けるため、前述の過去記事で解説済みの事項は割愛しています。そのため、過去記事をお読みいただくことで当記事の理解が深まるものと考えます。
関連記事
前述の過去記事以外にも Config Controller に関する記事がございます。こちらも合わせてお読みいただけると幸いです。
変更点
概要
今回紹介するアーキテクチャは、前述のブループリントを最大限活用しつつも、GitOps パイプラインに GitHub に導入します。
GitOps パイプラインの構成
定義ファイルの Push 先が GitHub に変わるため、Pull request や Merge といったコラボレーション機能の活用、Mergeトリガーの CI/CD (リソース管理の自動化) が実現できます。
アーキテクチャ
今回の変更を図示すると以下のとおりです。
ポイントは、Cloud Source Repositories の source-repo を GitHub のミラーリングリポジトリに変更する点 にあります。
これにより、ブループリントを大幅に改修することなく、GitOps パイプラインの根幹にあたる Kpt によるレンダリング機能もそのまま活用できます。
変更前の構成
# | コンポーネント | 役割 |
---|---|---|
1 | source-repo | ローカルから push されるファイル一式を格納するリポジトリ |
2 | Build トリガー | 上記からレンダリングされたファイルを deployment-repo に push |
3 | deployment-repo | レンダリングされたファイル一式を格納するリポジトリ |
4 | Config Sync | deployment-repo に接続する GitOps サービス |
変更後の構成
# | コンポーネント | 役割 |
---|---|---|
1 | source-repo (GitHub) | ローカルから push されるファイル一式を格納するリポジトリ |
2 | source-repo (CSR) | GitHub をミラーリングするリポジトリ |
3 | Build トリガー | 上記からレンダリングされたファイルを deployment-repo に push |
4 | deployment-repo | レンダリングされたファイル一式を格納するリポジトリ |
5 | Config Sync | deployment-repo に接続する GitOps サービス |
実装手順
概要
ここからは実装手順を解説しますが、詳細は前述の過去記事にて解説済みのため変更点を中心に解説します。
事前準備
こちらの手順は変更ありませんので詳細については過去記事をご確認ください。
- 参考:事前準備
Config Controller の設定
こちらの手順は変更ありませんので詳細については過去記事をご確認ください。
GitOps パイプラインの設定
変更点のみ以降で解説します。
source-repositories.yaml の編集
過去記事には存在しない手順となります。
Cloud Source Repositories の source-repo
は GitHub ミラーのリポジトリとして手動で作成するため、定義ファイルから削除します。
# 変更前 apiVersion: sourcerepo.cnrm.cloud.google.com/v1beta1 kind: SourceRepoRepository metadata: name: source-repo # kpt-set: ${source-repo} namespace: config-control # kpt-set: ${namespace} annotations: cnrm.cloud.google.com/blueprint: cnrm/gitops/v0.6.1 cnrm.cloud.google.com/project-id: project-id # kpt-set: ${project-id} --- apiVersion: sourcerepo.cnrm.cloud.google.com/v1beta1 kind: SourceRepoRepository metadata: name: deployment-repo # kpt-set: ${deployment-repo} namespace: config-control # kpt-set: ${namespace} annotations: cnrm.cloud.google.com/blueprint: cnrm/gitops/v0.6.1 cnrm.cloud.google.com/project-id: project-id # kpt-set: ${project-id}
# 変更後、deployment-repo の定義だけ残す apiVersion: sourcerepo.cnrm.cloud.google.com/v1beta1 kind: SourceRepoRepository metadata: name: deployment-repo # kpt-set: ${deployment-repo} namespace: config-control # kpt-set: ${namespace} annotations: cnrm.cloud.google.com/blueprint: cnrm/gitops/v0.6.1 cnrm.cloud.google.com/project-id: project-id # kpt-set: ${project-id}
setters の定義
project-id
等の値を自身の環境に合わせて修正する点については変更ありませんが、source-repo
は以下のように定義します。
- 参考:setters の定義
# 変更前 apiVersion: v1 kind: ConfigMap metadata: # kpt-merge: /setters name: setters annotations: config.kubernetes.io/local-config: "true" internal.kpt.dev/upstream-identifier: '|ConfigMap|default|setters' data: # This should be the project where you deployed Config Controller project-id: project-id project-number: "1234567890123" # This should be the name of your Config Controller instance cluster-name: cluster-name # You can leave these defaults namespace: config-control deployment-repo: deployment-repo source-repo: source-repo
# 変更後 # cluster-name / project-id / project-number を環境固有の値に置換 # source-repo では GitHub リポジトリ `repo-owner/repo-name` の形式で定義する (GitHub リポジトリの URL から確認可能) # source-repo-meta という Key を用意し、値は `source-repo` と定義する apiVersion: v1 kind: ConfigMap metadata: # kpt-merge: /setters name: setters annotations: config.kubernetes.io/local-config: "true" internal.kpt.dev/upstream-identifier: '|ConfigMap|default|setters' data: # This should be the project where you deployed Config Controller project-id: sandbox-cc-test-prj project-number: "566560710327" # This should be the name of your Config Controller instance cluster-name: config-controller-1 # You can leave these defaults namespace: config-control deployment-repo: deployment-repo source-repo-meta: source-repo source-repo: ggenyutakei/source-repo
gitops/configsync/setters.yaml の定義
GitOps パイプラインのデプロイの前に、以下に従い configsync-dir
の値を config/landing-zone
に変更してください。
- 参考:対処方法
source-repo (GitHub ミラー) の手動作成
過去記事には存在しない手順となります。
以下の公式ガイドを参考に、上記 setters.yaml
で指定した GitHub リポジトリとミラーリングする Cloud Source リポジトリを作成してください。
Cloud Build トリガーの手動作成
過去記事には存在しない手順となります。
GitHub リポジトリへの Merge をトリガーにして Kpt によるレンダリング処理が実行されるよう、Cloud Build トリガーを手動で作成します。
手順は以下の公式ガイドを参照いただきつつ、パラメータについては以下に記します。
# | パラメーター | 設定値 |
---|---|---|
1 | イベント | ブランチに push する |
2 | ソース | 第1世代 |
3 | リポジトリ | ggenyutakei/source-repo |
4 | ブランチ | .* |
5 | 構成 | Cloud Build 構成ファイル |
6 | ロケーション | インライン ※詳細は以下 |
7 | 変数1 / 値1 | _ADMIN_CLUSTER_NAME / config-controller-1 |
8 | 変数2 / 値2 | _DEPLOYMENT_REPO / deployment-repo |
9 | 変数3 / 値3 | _SOURCE_REPO / ggenyutakei/source-repo |
# インラインYAML steps: - name: 'gcr.io/cloud-builders/gcloud:latest' args: - '-c' - > set -e gcloud source repos clone $_DEPLOYMENT_REPO . (git show-branch $BRANCH_NAME &>/dev/null) && (git checkout $BRANCH_NAME) || (git checkout -b $BRANCH_NAME) git config user.email $(gcloud auth list --filter=status:ACTIVE --format='value(account)') mkdir -p /deployment-workspace/config dir: /deployment-workspace id: Clone Deployment Repo entrypoint: /bin/sh volumes: - name: deployment-workspace path: /deployment-workspace timeout: 300s - name: 'gcr.io/kpt-dev/kpt:v1.0.0-beta.9' args: - '-c' - > set -eo pipefail SRC_DIR="." DEST_DIR="/hydrated-workspace/config" echo "Initializing kpt" kpt pkg init "$${SRC_DIR}" echo "Executing Kpt Functions..." kpt fn render "$${SRC_DIR}" --output="$${DEST_DIR}" --truncate-output=false echo "Removing local config" kpt fn eval "$${DEST_DIR}" -i gcr.io/kpt-fn/remove-local-config-resources:v0.1 id: Apply Hydration and Validation entrypoint: /bin/bash volumes: - name: hydrated-workspace path: /hydrated-workspace - name: 'gcr.io/cloud-builders/gcloud:latest' args: - '-c' - > set -e git pull origin $BRANCH_NAME || true # Ignore errors in case branch doesn't exist git rm -rf /deployment-workspace/config/* --ignore-unmatch cp -r /hydrated-workspace/config /deployment-workspace/ touch /deployment-workspace/config/.gitkeep # Configure Git to create commits with Cloud Build's service account git config user.email $(gcloud auth list --filter=status:ACTIVE --format='value(account)') git add -A git status if git diff --cached --exit-code; then echo "No changes"; true; else git commit -m "Resources from ${COMMIT_SHA}" && git push origin $BRANCH_NAME; fi printf "\n\nLatest deployment repo commit SHA: $(git rev-parse HEAD)\n" dir: /deployment-workspace id: Push Changes To Deployment Repo waitFor: - Apply Hydration and Validation entrypoint: /bin/sh volumes: - name: hydrated-workspace path: /hydrated-workspace - name: deployment-workspace path: /deployment-workspace timeout: 600s
source-repo リポジトリへの Push
GitOps パイプラインのデプロイに使用したファイル一式は、setters の中で指定した GitHub リポジトリ に Push してマージしてください。
ランディングゾーンのデプロイ
以下の手順でランディングゾーンをデプロイします。これ以外は過去記事から大きな変更はありません。
- GitHub リポジトリでブランチを切る
- ランディングゾーンのブループリントをダウンロードして上記ブランチに配置する
setters
を定義して GitHub リポジトリ に push、Pull request をへて Merge する
kpt
によるレンダリング、deployment-repo
への push はパイプラインが行いますので、上記手順を実行するだけでランディングゾーンがデプロイされます。
最後に
Config Controller は Kubernetes の仕組みを用いているため、Reconciliation Loop に基づきリソースをあるべき状態を維持しようと作用します。
この機能は組織ポリシーや VPC Service Controls など、クラウド環境におけるセキュリティの根幹をなす 予防的統制 (ガードレール) と相性がよく、予期せぬ変更が発生した場合でも Config Controller が検知・是正してくれ、セキュリティ強化・維持、運用効率化の両方を実現します。
予防的統制機能を Config Controller で管理する方法については今後執筆予定です。
武井 祐介 (記事一覧)
クラウドソリューション部所属。G-gen唯一の山梨県在住エンジニア
Google Cloud Partner Top Engineer 2024 に選出。IaC や CI/CD 周りのサービスやプロダクトが興味分野です。
趣味はロードバイク、ロードレースやサッカー観戦です。
Follow @ggenyutakei