Cloud Functions のデプロイまとめ
最近超小規模の案件があり、先方の運用費も含めてとにかく低予算で収めたいという要望と機能・非機能の要件も満たしていたので Cloud Functions + Cloud Firestore で開発を行いました。今回は一桁程度の関数しか作成しなかったのですが、大規模になった時を見越して Cloud Functions のデプロイについて調査・検証しましたのでまとめてみたいと思います。
デプロイ方法の概要
Deploying Cloud Functions | Cloud Functions Documentation
- GCP コンソールを使う
- gcloud コマンドを使う
- Cloud Functions API を使う
方法としては上記の 3 つあり、どの方法を使ったとしても以下の 3 つのステップで行います。
- ソースコードのアップロード
- ソースコードからコンテナイメージのビルド
- コンテナイメージのデプロイ
これらを踏まえて自身で CI&CD を構築する場合に各方法でどうすれば良さそうかを説明します。GCP コンソールは Cloud Functions をお試しで利用する際ぐらいしか利用しないと思いますので触れません。
gcloud コマンドを使う
gcloud functions deploy | Cloud SDK Documentation | Google Cloud
gcloud functions deploy Hello \
--entry-point=HelloWorld \
--region=asia-northeast1 \
--runtime=go113 \
--memory=256MB \
--security-level=secure-always \
--env-vars-file=env.yaml \
--trigger-http \
--allow-unauthenticated
各オプションの説明は公式に委ねて省略しますが、よく使うオプションを並べるとこんな感じですね。このコマンドを実行するとカレントディレクトリにあるものが GCS にアップロードされビルド&デプロイが行われます。
gcloud topic gcloudignore | Cloud SDK Documentation | Google Cloud
GCS にアップロードされたくないファイルがある時は .gcloudignore
というファイルを作成して下さい。構文は .gitignore と同じです。
gcloud functions deploy
のリファレンスを見て頂いてもわかりますが、1 コマンド: 1 関数のデプロイになっており、実行する度にソースコードのアップロードが行われますので、これを避けたい場合についても紹介しておきます。
Uploads and downloads | Cloud Storage | Google Cloud
gcloud functions deploy
には --source
というオプションがあり、GCS にある zip ファイルを指定する事が出来ます(一応 Cloud Source Repository も指定可)。手動で zip ファイル化したものを gsutil
を使ってアップロードして --source
で指定すれば都度アップロードを防ぐ事ができます。
Cloud Functions API を使う
Deploying from the Google Cloud Functions API
公式ドキュメントにも紹介されている通り、以下の順で API を叩きます。
-
projects.locations.functions.generateUploadUrl を叩いて
uploadUrl
を生成する - 生成された
uploadUrl
にソースコードを固めた zip ファイルをアップロードする -
projects.locations.functions.create の
sourceUploadUrl
にuploadUrl
を指定して叩く
generateUploadUrl で生成される URL は都度ユニークなものが生成されるので、並列に走ったジョブによって上書きされる心配はありません。が、デプロイ先が同じだと結局問題になるので並列実行させない方がいいです。
Resumable uploads | Cloud Storage | Google Cloud
アップロードは curl
等でも行えますが、API を叩く一連の流れや最後に叩く create のリクエストボディの JSON の作りやすさなどから、クライアントライブラリの用意された言語等で実装する方がやりやすいと思います。
アップロードしたソースコードを使いまわして複数の関数をデプロイしたい場合は、create API の sourceUploadUrl
に共通のものを使いつつ、 name
のパラメータだけ変えれば実現できます。
GitHub Actions
Cloud Functions Deploy - GitHub Marketplace
on:
push:
branches:
- main
concurrency: gcf-deploy
jobs:
build-and-deploy:
name: Deploy Functions
runs-on: ubuntu-20.04
strategy:
matrix:
functions: [Hello, Echo]
steps:
- uses: actions/checkout@v2
- name: auth
uses: google-github-actions/auth@v0.4.0
with:
credentials_json: ${{ secrets.GCP_CREDENTIALS }}
- name: deploy
uses: google-github-actions/deploy-cloud-functions@v0.6.0
with:
name: ${{ matrix.functions }}
runtime: go113
GitHub Actions を使ってデプロイしたい場合は Google 公式の Action があります。 Cloud Functions 開発者
の権限を持ったサービスアカウントを作成し、発行したサービスアカウントキーの JSON ファイルの内容を Github の Secrets に保存して上記のような設定を書けば動きます。(例だと GCP_CREDENTIALS に保存している)
上記の例だと Hello と Echo という関数が並列にビルド&デプロイされます。Action の実装は設定された内容の関数を Cloud Functions API で説明した手順を TypeScript で 1 つずつデプロイする形式になっており、複数の関数をデプロイしたい場合は strategy.matrix を使う必要があります。
もしソースコードのアップロードを 1 度のみにしたいのであれば、前述の gcloud もしくは Cloud Functions API で説明した方法を自前で実装する必要があります。
Discussion