超簡単。GCPのサーバーレス環境Cloud RunにGoアプリを自動デプロイ!
GCPのCloud Runとは
GCPで用意されているコンテナ化されたアプリケーションを実行できるフルマネジドなサーバレス実行環境です。
公式ドキュメント
今回はCloud Runを触ったことがない人向けに、Cloud Buildを使った自動化も交え、簡単にデプロイ方法をご紹介できればと思います。
Cloud Buildを利用して自動デプロイを構築することで、Githubの特定ブランチにソースがmergeされたタイミング等で、任意の環境にアプリケーションがデプロイされ、デプロイの手間を省くことができます。さらにCloud Buildのステップ内に自動テストを用意すれば、テストが通ったコードのみがデプロイされることになり、コードの品質担保が可能となります。
今回の構成図
こちらが今回の構成図です。
アプリケーションの準備
Cloud RunにデプロイするApplicationを準備します。
今回はgcloudコマンドを実行するアプリケーションを用意してみました。
Golang経由でコマンドを実行する方法については、こちらを参考にさせて頂きました。
Cloud Runでは、HTTPを介して処理を実行する為、下記のようにHttpRequestを処理するHandlerを用意する必要があります。
func getGcloudConfigListHandler(w http.ResponseWriter, r *http.Request) {
out, err := exec.Command("gcloud", "config", "list").Output()
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Fprint(w, string(out))
return
}
Cloud Build によるデプロイ
デプロイに関しては、ローカルからコマンドを実行してもよいですが、今回は初めにご案内したメリットを踏まえ、デプロイ運用を自動化することを意識して、Cloud Buildを利用したいと思います。
前提
以下の設定が必要になります。
API有効化
- Cloud Run API有効化
- Cloud Resource Manager API 有効化
これらは通常デフォルトでは有効になっていないため、APIライブラリから有効化する必要があります。
権限設定
Cloud Buildサービスアカウント({プロジェクト番号}@cloudbuild.gserviceaccount.com)に下記権限
- Cloud Run 管理者
- Cloud Run サービス エージェント
- ストレージ オブジェクト閲覧者
Cloud Runへのデプロイとビルドステップで利用するコンテナイメージの読み取りに上記権限が必要となる為、IAMと管理より設定します。
デプロイの構成
下記はCloud Buildで利用する設定ファイルのcloudbuild.yamlとステップ内で利用するDockerfileです。
cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
id: 'build-docker-image'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/${_SERVICE_NAME}', '.']
- name: 'gcr.io/cloud-builders/docker'
id: 'push-docker-image'
args: ['push', 'gcr.io/$PROJECT_ID/${_SERVICE_NAME}']
- name: 'gcr.io/cloud-builders/gcloud'
id: 'deploy-cloud-run'
args: ['beta', 'run', 'deploy', '${_SERVICE_NAME}', '--image', 'gcr.io/$PROJECT_ID/${_SERVICE_NAME}', '--region', '${_REGION}']
- name: 'gcr.io/cloud-builders/gcloud'
# 便宜上誰でもEndpointを実行できるようにしているが、実際は権限設定を行う
id: 'apply-member-role-cloud-run'
args: ['beta', 'run', 'services', 'add-iam-policy-binding', '${_SERVICE_NAME}', '--region', '${_REGION}', '--member', 'allUsers', '--role', 'roles/run.invoker']
substitutions:
_REGION: us-central1
_SERVICE_NAME: gcloud-exec-example
images:
- gcr.io/$PROJECT_ID/${_SERVICE_NAME}
Dockerfile
FROM golang:1.11.10-alpine3.9 as builder
WORKDIR /go/src/app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -v -o main
FROM gcr.io/cloud-builders/gcloud:latest
WORKDIR /usr/local/bin/
COPY --from=builder /go/src/app/main /main
ENTRYPOINT ["/main"]
上記の手順(cloudbuild.yaml)の内容について
- Goの実行ファイルを作成して、Cloud Buildで利用可能なgcloudコンテナに閉じ込めてビルド
- 1でビルドしたDockerImageをContainerRegistoryにプッシュ
- 2で保管したDockerImageをCloud Runへデプロイ
トリガーの作成
Cloud Buildでは何を起点としてビルドを実行するのかを定義するトリガーというものがあります。
トリガーのイベントとして指定できるのは現在「特定のGitブランチへのpush / タグのpush」のみです。
今回は「masterへのpush」をイベントとして、ビルドを実行するトリガーを作成します。
トリガー作成手順
GCPコンソールからCloud Buildを選択し、トリガーを作成をクリックします。
ソースの連携元としてGithubを選択します。
該当するリポジトリを選択します。
リポジトリのルートから見たcloudbuild.yamlの場所とトリガーのイベントを設定します
トリガーを作成するとCloud Buildのトリガー一覧に表示されます。
トリガーの実行は該当イベントとなるmasterへのpushでもできる他、一覧の「トリガーを実行」からも手軽に実行できます。
今回はこちらを使用してトリガーを実行します。
トリガー実行後、ビルドが成功したことを確認します。
以上がCloud Buildでのデプロイ手順です。
Cloud Buildについてもっと詳しく知りたい方という方はこちらの記事もご一緒にどうぞ!
Cloud Runのサービス確認
GCPコンソールのCloud Run UIにて、サービスがデプロイされていることを確認します。
実際にサービスにアクセスするにはサービスのURLを確認します。
今回用意したエンドポイントを確認する為にサービスURL/getGcloudConfigList
にブラウザでアクセスしてみます。下記が表示され、サービスが想定通り動いていることが確認できました。
まとめ
いかがでしたでしょうか。
以上、簡単なGoアプリをCloud Buildを用いて、Cloud Runに自動デプロイする手順をお届けいたしました。
デプロイの自動化で運用の手間を削減することはもちろん、テストを挟めばコードの品質を高めることもできます。
是非一度お試し下さい。
ソースコードは 弊社のGitHubに置いてありますので、ご参考にして頂ければ幸いです。
ご意見・ご感想お待ちしております。