Cloud RunとGitHub Actionsでコンテナアプリケーションのデプロイを自動化する

公開:2020/12/20
更新:2021/01/16
6 min読了の目安(約5800字TECH技術記事

この投稿は CA21 Advent Calendar 2020 の 20日目の記事です

ソースコードから直接Cloud Runにビルド&デプロイする方法

gcloud beta run deploy --source=[DIRECTORY]

には本記事では対応していません。
こちらの詳細はGoogle Cloudの公式ブログで解説されています。
https://cloud.google.com/blog/products/serverless/build-and-deploy-an-app-to-cloud-run-with-a-single-command

こんにちは、@konnyaku256です。
みなさん、コンテナ使ってますか?
私はよく使っています。最近の開発ではDockerコンテナを採用するのがほとんどです。
そんな、コンテナはサーバレスやCI/CDといった環境との相性も抜群に良いです。
この記事では、私の大好きなCloud RunとGitHub Actionsを使ってコンテナアプリケーションのデプロイをお手軽に自動化する方法を紹介します。

Cloud Run

Cloud Run is a managed compute platform that enables you to run stateless containers that are invocable via web requests or Pub/Sub events. Cloud Run is serverless: it abstracts away all infrastructure management, so you can focus on what matters most — building great applications. It is built from Knative. Learn more about the Cloud Run platforms

Cloud RunとはGCPのマネージドなコンテナ実行環境です。
次のような特徴があります。

  • WebリクエストまたはPub/Subイベントによる呼び出しに対応
  • コンテナはステートレス(状態を持たない)
  • 内部的にはKubernetesでサーバレスを実現するKnativeの上に構築されている
  • デフォルトでHTTPSに対応しており、https://xxxxxxxx.a.run.app/ のようなURLで公開できる
  • ランタイムが起動している間のみ課金が発生する従量課金制

最近だと、gRPCのserver streamingがサポートされるなどGoogleもかなり力を入れてくれているのがわかります。

GitHub Actions

GitHub ActionsとはGitHubのCI/CD環境です。
Gitリポジトリの .github/workflows/*.yml に専用の設定ファイルを設置することでビルド、テスト、デプロイといったワークフローを自動化することができます。

GitHub Marketplace上で独自のActionsを公開できる仕組みもあります。

対象とするコンテナアプリケーションの仕様

  • あるポート番号が開放されているDockerコンテナ(このポート番号をデプロイ時に指定する必要があります)
  • コンテナ内で上記のポート番号へのHTTPリクエストに応答するサーバサイドアプリケーションが起動すること

想定するユースケース

上記のようなアプリケーション開発で「mainブランチにpushされたらGitHub Actionsを経由してCloud Runにデプロイすること」を目指します。

Cloud Runではもちろんコンソールからもデプロイ可能ですが、今回はできるだけCI/CDワークフローからデプロイできるように設定してみます。

事前準備

GCP 側

  1. Cloud Run APIを有効にする
    • プロジェクトでCloud Runを使用するにはAPIの有効化が必要です。
  2. GitHub Actions用に権限を付与したサービスアカウントを設定する
    1. サービスアカウントを作成する
    2. サービスアカウントキーを発行する
    3. Cloud Run(とContainer Registry)へのデプロイに必要な権限をもたせる

デプロイに必要な権限の最小構成

Cloud Run 管理者

run.services.create
run.services.get
run.services.getIamPolicy
run.services.setIamPolicy
run.services.update

Cloud Run サービスエージェント

iam.serviceAccounts.actAs
storage.objects.get
storage.objects.list

ストレージ管理者(Container Registryへのpushに必要)

storage.buckets.get
storage.objects.create
storage.objects.delete
storage.objects.get
storage.objects.list

GitHub 側

  1. GitHubのSecretsにGCPプロジェクトの情報を設定する
    • GitHubのEncrypted secretsでリポジトリに環境変数を設定できます。
    • ここで設定した変数は後でGitHub Actionsから参照します。

設定するSecrets

GCP_PROJECT_ID
GCP_REGION
GCP_SA_KEY
PORT
SERVICE_NAME

デプロイワークフローを設定する

あとは次のようなワークフローを設定すると、mainブランチにpushされたときCloud Runへ自動デプロイされるようになります。

deploy.yml
name: Deploy

on: 
  push:
    branches:
      - main

env:
  SERVICE_NAME: ${{ secrets.SERVICE_NAME }}
  PORT: ${{ secrets.PORT }}
  GCP_PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
  GCP_REGION: ${{ secrets.GCP_REGION }}
  IMAGE: asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/${{ secrets.SERVICE_NAME }}:${{ github.sha }}

jobs:
  deploy-to-cloud-run:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout the repository
        uses: actions/checkout@v2

      - name: Setup gcloud
        uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
        with:
          version: 'latest'
          project_id: ${{ secrets.GCP_PROJECT_ID }}
          service_account_key: ${{ secrets.GCP_SA_KEY }}
          export_default_credentials: true

      - name: Configure docker to use the gcloud cli
        run: gcloud auth configure-docker --quiet

      - name: Build a docker image
        run: docker build -t $IMAGE .

      - name: Push the docker image to Container Registry
        run: docker push $IMAGE

      - name: Deploy to Cloud Run
        run: |
            gcloud run deploy $SERVICE_NAME \
              --image $IMAGE \
              --port $PORT \
              --project $GCP_PROJECT_ID \
              --region $GCP_REGION \
              --platform=managed \
              --allow-unauthenticated \
              --quiet

GitHub Secrets

GitHubのEncrypted secretsで設定した環境変数は ${{ secrets.SERVICE_NAME }} のようにしてGitHub Actionsから参照できるため、プロジェクトの秘匿情報を扱うのに便利です。

setup-gcloud

GCP公式のActions、setup-gcloudを使ってgcloud CLIの設定をしています。
GCPの project_idservice_account_key を設定するだけでGitHub Actions環境からgcloudコマンドを実行できるようになります。

gcloud auth configure-docker

Container Registryの認証情報をDockerで使用するように設定しています。
これによって docker push $IMAGE でContainer Registryに向けてイメージをpushすることができます。

Cloud Runにデプロイする

gcloud run deploy コマンドでCloud Runにデプロイできます。
Cloud Runへのリクエストは通常、コンテナの8080番に転送されるように設定されています--port $PORT のようにして任意のポート番号を設定することもできます。
また、デフォルトで未認証のアクセスが無効になっているので、全てのアクセスを許可したい場合は --allow-unauthenticated オプションを使って有効にする必要があります。
その他のオプションの解説は公式のリファレンスに譲ります。

まとめ

Cloud RunとGitHub Actionsを使うことでコンテナアプリケーションのデプロイをお手軽に自動化することができました。
アプリケーションの開発に集中したい方には、ぜひともおすすめしたい方法です。
みなさんの開発ライフがより豊かになれば嬉しいです。

PR

内定先のCyberAgentでは22卒のエンジニア採用を行っています!

https://www.cyberagent.co.jp/careers/news/detail/id=25511