Config Controller と Google Forms で Google Cloud プロジェクトを自動で作ってみる — 後編 : サンプル実装 -
みなさん、こんにちは。前回の前編では Config Controller と Google Forms を組み合わせて Google Cloud のフォルダとプロジェクトを自動でデプロイする仕組みの概要についてご紹介しました。後編となる本ブログ記事では、サンプルを利用して実際にこの仕組みを実装する方法についてご紹介します。
TL; DR
- 本ブログ記事の手順で実装を進めることで Google Cloud の組織配下にフォルダとプロジェクトを自動でデプロイする仕組みができます
- フォルダやプロジェクトの階層構造や IAM 権限の付与はテンプレートを変更することで自由にカスタマイズが可能です
成果物
今回のブログの手順によって構成した仕組みを実行すると、2 つのフォルダと 3 つのプロジェクトが以下の構成で作成されます。ユーザーには部署名、サービス名、管理者用グループ アドレスの 3 つを Google Forms で入力いただきます。
組織直下に作成されるフォルダは部署用のフォルダ、そのフォルダの配下に作成されるフォルダはサービス用のフォルダです。そしてサービス用のフォルダ配下に Production / Staging / Develop 環境用の 3 つのプロジェクトが作成されます。もちろんこの構成はテンプレートを少し編集いただくだけで変更可能です。
また、入力した管理者用グループ アドレスには、部署用のフォルダに対するオーナー権限が付与されます。そのため、以降の運用時には管理者用グループ アドレスに含まれる管理者が適宜ユーザーを追加することが可能です。もちろんこの権限も変更可能です。
事前準備
前編でご紹介したとおり、今回のサンプルでは Google Forms、Google App Script、GitHub を利用するため、それぞれのサービスを事前に準備します。
1. Google Forms の準備
いろいろと作成方法はあるかと思いますが、https://docs.google.com/forms へアクセスをいただいて新規作成いただくのが最も簡単かと思います。
今回は上述した環境を作成するため、Google Forms には以下の質問項目を作成します。(Google App Script のコードサンプルの都合上この順番で質問を作成ください)
- 部署名 (Short answer)
- サービス名 (Short answer)
- フォルダ管理者グループ アドレス (Short answer)
2. GitHub の準備
後述の手順では Config Controller と Google Forms の他に GitHub を利用します。そのため、事前準備として GitHub リポジトリ、および GitHub Actions の実行をトリガーする際に利用する GitHub Apps を作成ください。
GitHub Apps の作成手順は GitHub 社のドキュメントが参考になりますが、少し補足をします。
1) GitHub Apps の作成
基本的には以下のドキュメントの通りです。
https://docs.github.com/ja/developers/apps/building-github-apps/creating-a-github-app
ほとんどの設定はデフォルト値の通りにご設定いただいて問題ございませんが、一部不要な設定やチェックが必要な設定項目もございますので、以下に補足させていただきます。GitHub Apps 作成後に App ID が表示されるため、この ID をメモします。
- Homepage URL:任意の URL で問題ございません
- Webhook の設定:デフォルトでは Active ですが、無効化いただいて問題ございません
- Repository permissions の設定:Actions (Read and write)、Metadata (Read-only)、Pull request (Read and write) 、Workflows (Read and write) を付与します
2) GitHub Apps の秘密鍵の作成
以下のドキュメントに記載の手順で秘密鍵を作成します。
なお、この秘密鍵は Google App Script から GitHub Actions をトリガーするときに利用しますが、作成される秘密鍵のフォーマットが Google App Script での認証時に呼び出す Utilities.computeRsaSha256Signature 関数が期待するフォーマットと合致していません。
そのため、以下のコマンド (openssl コマンド) でダウンロードしたファイルのフォーマットを変更します。
openssl pkcs8 -topk8 -inform pem -in <ダウンロードしたファイル名>.pem -outform pem -nocrypt -out <任意の新しいファイル名>.pem
そして、以下のコマンドによって Utilities.computeRsaSha256Signature 関数が期待するフォーマットに変換します。
sed -i -z 's/\n/\\n/g' <ファイル名>.pem; sed -i 's/\\n$//' <ファイル名>.pem
3) GitHub Apps のインストール
以下のドキュメントに記載の手順で、今回利用する GitHub リポジトリに GitHub Apps をインストールします。
インストール後、Web ブラウザのアドレス バーの末尾に表示される番号 (Installation ID) をメモします。
構築手順
それでは、事前準備が完了したところで構築手順についてご紹介します。前編で記載したとおり、今回の仕組みは下記の Blueprint チュートリアルを基に実装しています。そのため、一部の手順はチュートリアルのドキュメントをポイントしながら記載しています。
https://cloud.google.com/anthos-config-management/docs/tutorials/landing-zone
また、Google App Script のサンプルなどは以下の GitHub リポジトリで公開しております。
https://github.com/yoshimasak/configcontroller-selfservice-sample
1. Config Controller のデプロイ
Blueprint チュートリアルのドキュメントの “始める前に”、“環境の準備”、”Config Congroller の設定” の章を実行します。
https://cloud.google.com/anthos-config-management/docs/tutorials/landing-zone#before-you-begin
https://cloud.google.com/anthos-config-management/docs/tutorials/landing-zone#setting_up
2. GitOps パイプラインの作成
基本的には下記手順に則っていますが、今回は GitHub を利用するために少し変更を加えます。
1) Google Cloud プロジェクトで Resource Manager サービスを有効化
Google Cloud CLI で以下のコマンドを実行します。
gcloud services enable cloudresourcemanager.googleapis.com \
cloudbuild.googleapis.com
2) Cloud Build の参照リポジトリとして GitHub リポジトリを登録
Cloud Console で Cloud Build を表示し、[トリガー] — [リポジトリの管理] — [リポジトリを接続] を押下します。そしてソースとして “GitHub (Cloud Build GitHub アプリ)“ を選択し、[続行] を押下して GitHub の認証情報を入力します。最後に利用するリポジトリを選択し、[接続] を押下します。もしリポジトリが表示されていない場合は [GITHUB のリポジトリを編集] を押下し、リポジトリに Cloud Build 用の GitHub Apps をインストールした上でリポジトリを選択します。
なお、リポジトリを登録するとオプションでトリガーの作成が可能ですが、トリガーは後の手順で作成するので今回は [完了] を押下してトリガーの作成はスキップします。
3) GitOps テンプレートのダウンロード
ローカル環境に GitHub リポジトリをクローンし、manifests ディレクトリをルート配下に作成した上で、GitOps テンプレートをダウンロードします。(ディレクトリ名は任意で問題ございませんが、manifests から変更した場合は適宜以降の手順でもディレクトリ名を変更ください)
git clone https://github.com/<GitHub ユーザー名>/<リポジトリ名>.git
cd <リポジトリ名>
mkdir manifests
kpt pkg get https://github.com/GoogleCloudPlatform/blueprints.git/catalog/gitops@gitops-blueprint-v0.5.0 ./manifests/gitops
4) setters.yaml の編集
kpt のレンダリングに利用する setters.yaml ファイルを 2 つ編集します。まず、manifests/gitops/setters.yaml ファイルを開き、以下の変数を編集します。
- project-id : Config Controller をデプロイしたプロジェクト ID
- project-number : Config Controller をデプロイしたプロジェクト番号
- cluster-name : Config Controller 名 (手順の通りに実施いただいた場合は config-controller-1 という名前となります)
続いて、manifests/gitops/configsync/setters.yaml を開き、以下の変数を編集します。
- cluster-name : Config Controller 名 (手順の通りに実施いただいた場合は config-controller-1 という名前となります)
- project-id : Config Controller をデプロイしたプロジェクト ID
5) Cloud Build パイプラインの編集
ダウンロードしたテンプレートは GitHub リポジトリではなく Source Repositories への Push を基に Cloud Build がトリガーされるよう実装されています。そのため、GitHub リポジトリへの Push を基に Cloud Build がトリガーされるよう manifests/gitops/hydration-trigger.yaml ファイルのコードを 2 箇所変更します。
変更箇所 ①
- 変更前 : SRC_DIR=”.”
- 変更後 : SRC_DIR=”./manifests/”
変更箇所 ②
https://github.com/GoogleCloudPlatform/blueprints/blob/main/catalog/gitops/hydration-trigger.yaml#L99-L102
- 変更前:
triggerTemplate:
branchName: ".*"
repoRef:
name: source-repo # kpt-set: ${source-repo}
- 変更後:
github:
owner: <GitHub ユーザー名>
name: <GitHub リポジトリ名>
push:
branch: main
includedFiles:
- "manifests/**"
6) GitOps テンプレートの適用
kpt のレンダリングによって Config Controller クラスターに適用する定義ファイルを生成し、クラスターに適用します。
kpt fn render manifests/gitops/
kubectl apply --wait -f manifests/gitops --recursive
7) デプロイ完了まで待機
以下のコマンドでデプロイ完了まで待機します。
kubectl wait --for=condition=READY -f \
manifests/gitops/source-repositories.yaml --timeout=5m
8) GitOps テンプレートを GitHub リポジトリに保存
Config Controller に適用した GitOps 用のリソースを GitHub リポジトリに保存します。
git add manifests/gitops
git commit -m "Add GitOps blueprint"
git push origin main
9) 成功の検証
Cloud Build の GUI から Build Trigger が実行されたこと、またエラーなく終わっていることを確認します。
kubectl get gcp -n config-control -o yaml \
| grep "^ name: \\|message"
以下のような出力になっていれば成功です。もし up to date と表示されないリソースがある場合、少し時間を空けて再度同じコマンドを実行ください。
name: source-repo-cicd-trigger
message: The resource is up to date
name: sync-config-controller-1
message: The resource is up to date
name: projects/<Project ID>/serviceAccounts/sync-config-controller-1@<Project ID>.iam.gserviceaccount.com
name: deployment-repo-cloudbuild-write
message: The resource is up to date
name: source-reader-sync-config-controller-1-<Project ID>
message: The resource is up to date
name: source-repo-cloudbuild-read
message: The resource is up to date
name: sync-config-controller-1
message: The resource is up to date
name: cloudbuild.googleapis.com
message: The resource is up to date
name: sourcerepo.googleapis.com
message: The resource is up to date
name: deployment-repo
message: The resource is up to date
name: source-repo
message: The resource is up to date
3. ランディングゾーンの初期化
基本的には下記手順に則っています。
1) ランディング ゾーン テンプレートのダウンロード
以下のコマンドを実行してテンプレートをダウンロードします。
kpt pkg get https://github.com/GoogleCloudPlatform/blueprints.git/catalog/landing-zone@main ./manifests/landing-zone
git add manifests/landing-zone/
git commit -m "Add landing zone"
2) setters.yaml の編集
manifests/landing-zone/setters.yaml ファイルを開き、以下の変数を編集します。
- org-id : 組織 ID
- billing-account-id : 請求アカウント ID
- group-org-admins : 組織管理者用のグループ
- group-billing-admins : 請求アカウント管理者用のグループ
- management-project-id : Config Controller をデプロイしたプロジェクト ID
3) ランディングゾーン テンプレートを GitHub リポジトリに保存
ランディングゾーン関連のファイルを GitHub リポジトリに保存します。
git diff
git commit -a -m "Configure landing zone blueprint"
git push origin main
4. GitHub Actions の実装
1) GitHub Actions の新規作成
GitHub Actions パイプラインは、GitHub リポジトリのルート配下に .github/workflows ディレクトリを作成し、そのディレクトリ内に yaml ファイルを作成することで定義可能です。そのため、ローカル環境にクローンした GitHub リポジトリのルートで以下のコマンドを実行し、GitHub Actions パイプラインを作成します。
mkdir -p .github/workflows
touch .github/workflows/create-environment.yaml
2) GitHub Actions パイプラインの実装
作成した create-environment.yaml ファイルに以下のファイル内容をコピーし、GitHub リポジトリに保存します。
git add .github/workflows
git commit -m “Create GitHub Actions pipeline”
git push origin main
5. Google App Script の実装
1) Google App Script プロジェクトの作成
事前準備として作成した Google Forms の画面右上のメニュー (縦に “・” が 3 つ並んだボタン) から [Script editor] をクリックすると、Google Forms と連携する Google App Script プロジェクトが作成できます。
2) Google App Script の実装
Google App Script の Code.gs に以下のコードをコピーして保存します。
https://github.com/yoshimasak/configcontroller-selfservice-sample/blob/main/src/Code.gs
3) Google App Script の変数の設定
Google App Script のコード内で変数 (Script Properties) を呼び出すため、Google App Script の画面左側の歯車マーク (Project Settings) をクリックして Script Propertires で以下のとおり変数を設定して保存します。
- appId : GitHub Apps の App ID
- installationId : GitHub Apps の Installation ID
- privateKey : フォーマット済みの GitHub Apps の秘密鍵文字列
- userName : GitHub ユーザー名
- repo : GitHub リポジトリ名
4) Google App Script の実行トリガーの設定
画面左側の時計マーク (Triggers) へ移り、[+ Add Trigger] メニューから以下のように設定します。この設定により、Google Forms で回答を Submit したことをトリガーとしてスクリプトが実行されるようになります。今回のサンプルでは、トリガー時に main 関数が実行されるよう設定します。(外部 URL (GitHub API) へリクエストを送信するため、認可を求められる場合があります)
実行手順
ここまでで環境構築は完了なので実際に実行します。実行とは言っても、Google Forms に以下の必要事項を入力するだけです。
- 部署名:組織配下に作成されるフォルダ名になります
- サービス名:部署用フォルダ配下に作成されるフォルダ名になります
- フォルダ管理者グループ アドレス:部署用フォルダのオーナー権限が付与されます
これらの情報を入力して Submit すると、自動で Google App Script や GitHub Actions の処理が実行されます。
GitHub Actions の処理は、Pull Request の作成までとなります。そのため、管理者は Pull Request をレビューし、リソースを作成しても問題なさそうな場合は main ブランチに変更をマージすることで Cloud Build がトリガーされ、最終的にリソースが作成されます。
環境の削除
Config Controller を削除する前に、Config Controller で管理されているリソースを削除する必要があります。削除する順番については下記ドキュメントをご参照ください。
https://cloud.google.com/anthos-config-management/docs/tutorials/landing-zone#clean-up
まとめ
長くなりましたが、今回作成したサンプルの構築手順は以上となります。前編で記載したとおり、例えばサンドボックス環境を一括で簡単に作りたい、実際の環境を払い出したいといったユースケースでご利用いただけるのではないかと思っています。テンプレートについては適宜増やしていこうとは思っていますので、少しでもみなさまのお役になりましたら幸いです!