🚀

GitHub ActionsでCloud Functionsを自動デプロイする

2020/12/19に公開1

GitHub Actionsを使い、masterにプッシュされたコードをCloud Functionsに自動デプロイするワークフローの構築メモです。

今回組んだワークフロー

yamlファイルの記述

name: Deploy Cloud Funcstions

on:
  workflow_dispatch:
  push:
    branches: [ master ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
        
    - name: Set up Cloud SDK
      uses: google-github-actions/setup-gcloud@master
      with:
        project_id: my-project-id
        service_account_email: my-ci-account@my-project-id.iam.gserviceaccount.com
        service_account_key: ${{ secrets.GCP_SA_KEY }}
        export_default_credentials: true

    - name: Deploy Functions
      run: sh app/deploy/deploy.sh

my-ci-account my-project-id あたりは自分の情報に置き換えてください。(以下に詳しく説明します)

解説

トリガー

on:
  workflow_dispatch:
  push:
    branches: [ master ]

masterブランチにプッシュされたとき、または手動(workflow_dispatch)でワークフローを実行する設定です。

チェックアウト

- uses: actions/checkout@v2

リポジトリをチェックアウト。
チェックアウトなどの基本的な処理はActionsが提供してくれています。(ここにリンク)

Cloud SDKのセットアップ

 - name: Set up Cloud SDK
      uses: google-github-actions/setup-gcloud@master
      with:
        project_id: my-project-id
        service_account_email: my-ci-account@my-project-id.iam.gserviceaccount.com
        service_account_key: ${{ secrets.GCP_SA_KEY }}
        export_default_credentials: true

GCPへの認証です。
Googleが提供している setup-gcloud を使って、READMEに従って設定していきます。

以下の情報が必要なので、準備していきます。

  • プロジェクトID
  • サービスアカウントの情報(メールアドレスと鍵)

サービスアカウントというのはGCPのIAMで作成できるアカウントで、通常のアカウントとは違ってCIなどのマシン上で使われるアカウントです。

ひとつずつ準備していきます。

プロジェクトIDの確認

gcloud projects list

で自分のプロジェクトの一覧が出力されます。該当のプロジェクトIDをチェックします。

サービスアカウントの作成

gcloud iam service-accounts create my-ci-account \
--description="GitHubAction" \
--display-name="My CI ACCOUNT"

公式ドキュメントはこちら

サービスアカウントに権限を付与

作成したサービスアカウントに権限を紐付けます。

1.Cloud Functsionsの権限

gcloud projects add-iam-policy-binding my-project-id \
--member="serviceAccount:my-ci-account@my-project-id.iam.gserviceaccount.com" \
--role="roles/cloudfunctions.developer"

2.appspotのアカウントとサービスアカウントの権限

gcloud iam service-accounts add-iam-policy-binding \
my-project-id@appspot.gserviceaccount.com \
--member='serviceAccount:my-ci-account@my-project-id.iam.gserviceaccount.com' \
--role=roles/iam.serviceAccountUser

サービスアカウントの鍵情報を出力

続いて、認証のための鍵情報を出力します。

gcloud iam service-accounts keys create ~/key.json --iam-account my-ci-account@my-project-id.iam.gserviceaccount.com

公式ドキュメントはこちら

出力した鍵情報をGitHubのSecretsに登録

出力されたJSONデータをGitHubのSecretsに登録します。
今回は GCP_SA_KEY のキー名で登録しました。

デプロイ

- name: Deploy Functions
  run: sh app/deploy/deploy.sh

Cloud Functionにデプロイします。
run に続けてデプロイのコマンドを直で書くこともできますが、今回は複数デプロイが必要なのでシェルスクリプトにまとめました。

シェルスクリプトの中身はこちら:

gcloud functions deploy FUNCTION_NAME_1 \
--runtime python38 \
--timeout 540 \
--source app \
--trigger-topic TOPIC_NAME_1 \

gcloud functions deploy FUNCTION_NAME_2 \
--runtime python38 \
--timeout 540 \
--source app \
--trigger-topic TOPIC_NAME_2 \

gcloud functions deploy FUNCTION_NAME_3 \
--runtime python38 \
--timeout 540 \
--source app \
--trigger-topic TOPIC_NAME_3 \

また、Googleが公式に提供している google-github-actionsを利用することもできます。
その場合は以下のREADMEを参考に設定します。
https://github.com/google-github-actions/deploy-cloud-functions

以上の設定でワークフロー構築は完了です。

ダッシュボード上での表示


GitHub Actionsの見た目

GitHubのActionsタブを開くとワークフローの画面が開きます。
ビルド履歴やエラーが起きた際のログはここで確認できます。


手動実行は「Run Workflow」から

workflow_dispatchをトリガーに追加していたので手動でここから実行できるようになっています。

まとめ

GitHub Actionsを利用して、自動デプロイの仕組みを作りました。
GCPに慣れていないため権限まわりに少し時間がかかりましたが、提供されているactionも揃っておりスムーズに構築ができました。

これから設定される方のお役に立てれば幸いです。

Discussion

kangetsu_121kangetsu_121

2年前の記事で恐縮ですが、参照する方もいらっしゃると思うのでコメントさせていただきます。

出力されたJSONデータをGitHubのSecretsに登録します。

こちらですが、GitHub 公式では JSON を含む構造化データを secrets に登録することは、secrets の削除がうまくいかない可能性があるため非推奨とのことです。

https://docs.github.com/ja/actions/security-guides/encrypted-secrets

GitHub がログのシークレットを確実に削除するよう、シークレットの値として構造化データを使用しないでください。 たとえば、JSONやエンコードされたGit blobを含むシークレットは作成しないでください。

代案として、Base64 でエンコードして screts に登録し、参照時に Base64 デコードして利用する方法があるようです。
https://docs.github.com/ja/actions/security-guides/encrypted-secrets#storing-base64-binary-blobs-as-secrets

Base64 エンコードを使用して、小さなバイナリ BLOB をシークレットとして格納できます。 その後、ワークフロー内のシークレットを参照し、ランナーで使用するためにデコードできます。

(ドキュメント中にあるように、Base64 は暗号化ではないので、もちろん Base64 エンコードして登録した secrets も内容が露出することは避けた方が良いです)