2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【GCP】Cloud Functions (python)をCloud Build でdeploy する

Last updated at Posted at 2022-01-16

はじめに

Cloud Functions を python で使ってみるための調査をしました。いまどき、サーバレスでなくてはね、ということで、老体に鞭を打ち、休日に作業しています。戦いの証をこちらに掲げています。

Quick Start から CDまで

まずはQuick Start

Quick start は、コンソールだけでdeploy するところまでできます。テストも楽にできるんだなーというのが、印象的です。

その後、gcloud による操作をここを読んでざっと理解しました。

これらをもとに、Cloudbuild でCI/CDできるように頑張りました。

作業内容

準備

準備します。Python3.9 にしているのは、使ってみたいからです。

$ virtualenv -p python3.9 venv
$ source ./venv/bin/activate
(venv) $ $ python -V

Python 3.9.5

ローカルで動かすために必要なものを入れます。

$ python -m pip install functions-framework
...
# python -m pip list
$ python -m pip list
Package                        Version
------------------------------ ---------
...
Flask                          2.0.2
functions-framework            3.0.0
google-api-core                2.4.0
google-auth                    2.3.3
grpc-google-iam-v1             0.12.3
grpcio                         1.43.0
...

という感じでした。

ローカルで動かす

関数 my_hello_http が実装してあるフォルダで、function-framework を実行します。
実装はサンプルにあるもののコピペです。

main.py
from flask import escape
import functions_framework

@functions_framework.http
def my_hello_http(request):
    request_json = request.get_json(silent=True)
    request_args = request.args

    if request_json and 'name' in request_json:
        name = request_json['name']
    elif request_args and 'name' in request_args:
        name = request_args['name']
    else:
        name = 'World'
    return 'Hello {}!'.format(escape(name))

これを functions-framework で実行します。

$ functions-framework --target my_hello_http --signature-type=http --port=8080 --debug
 * Serving Flask app 'hello_http' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://172.25.125.68:8080/ (Press CTRL+C to quit)
 * Restarting with watchdog (inotify)
 * Debugger is active!
 * Debugger PIN: 111-222-666

別のターミナルで接続してみる。

$ curl -H "accept: application/json" -H "Content-Type: application/json" -d '{"name": "baby."}' http://172.25.125.68:8080/my_hello_sample
Hello baby.!

動いた。よしよし。

手動で Deploy

deploy は gcloud functions deploy で行ける。覚えられるかな。

$ gcloud functions deploy my_hello_http --runtime python39 --trigger-http --allow-unauthenticated

Deploying function (may take a while - up to 2 minutes)...⠛
For Cloud Build Logs, visit: https://console.cloud.google.com/cloud-build/builds;region=us-central1/xxxxxxxxxxxxxxxxxxxxx?project=1234567890123
Deploying function (may take a while - up to 2 minutes)...done.
availableMemoryMb: 256
buildId: xxxxxxxxxxxxxxxxxxxxxxxxxxx
buildName: projects/1234567890123/locations/us-central1/builds/xxxxxxxxxxxxxxxxxxxxxxxxxxx
entryPoint: my_hello_http
httpsTrigger:
  securityLevel: SECURE_ALWAYS
  url: https://us-central1-myproject.cloudfunctions.net/my_hello_http
ingressSettings: ALLOW_ALL
labels:
  deployment-tool: cli-gcloud
name: projects/myproject/locations/us-central1/functions/my_hello_http
runtime: python39
serviceAccountEmail: ambmonitordev@appspot.gserviceaccount.com
sourceUploadUrl: https://storage.googleapis.com/gcf-upload-us-central1-yyyyyyyyyyyyyyyyyyy/zzzzzzzzzzzzzzzzzzzzzzzzzzz.zip
status: ACTIVE
timeout: 60s
updateTime: '2022-01-16T11:16:18.258Z'
versionId: '1'

内部ではどのように動いているのかな。build したり、storage の設定が出てきたり、entryPoint の文字が見えたり。
この情報は、以下でも表示できる。

$ gcloud functions describe my_hello_http

deploy しているserverless application を忘れたら、list する。

$ gcloud functions list
NAME           STATUS  TRIGGER       REGION
my_hello_http  ACTIVE  HTTP Trigger  us-central1

CloudBuild でDeploy

今のコマンドをcloudbuild.yaml に書いてみる。

steps:
- name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
  args:
  - gcloud
  - functions
  - deploy
  - my_hello_http
  - --region=asia-northeast1
  - --source=.
  - --trigger-http
  - --runtime=python39

とりあえずローカルで実行してみる。今、main.py と同じディレクトリで下記を実行することを想定していますが、そうでなければ"source=..."の値を書き換えてください。

$ gcloud builds submit --config cloudbuild.yml .

がエラーになってしまった。

- '@type': type.googleapis.com/google.rpc.ErrorInfo
  domain: googleapis.com
  metadata:
    consumer: projects/12345678901234
    service: cloudresourcemanager.googleapis.com
  reason: SERVICE_DISABLED
ERROR

と言われたので、Cloud Resouce Manager API を有効にしました。そうしたら成功はしたのですが、

Deploying function (may take a while - up to 2 minutes)...
WARNING: Setting IAM policy failed, try `gcloud alpha functions add-iam-policy-binding my_hello_http --region=asia-northeast1 --member=allUsers --role=roles/cloudfunctions.invoker`

と言われたので、素直にコマンドを叩いておきました。

$ gcloud alpha functions add-iam-policy-binding my_hello_http --region=asia-northeast1 --member=allUsers --role=roles/cloudfunctions.invoker
bindings:
- members:
  - allUsers
  role: roles/cloudfunctions.invoker
etag: BwXVssdV2mE=
version: 1

いよいよCloud Build にtrigger を作ります。いろいろエラーが出たのですが、

  • CloudBuild のサービスアカウントに CloudFunctions 開発者のロールが無効だった。これはコンソールのCloudBuild の設定から変更できます。
  • build trigger を実行するサービスアカウントの権限がLogging になかった。これはせってしない方が良かったのかもしれない。

で最後は無事にdeploy できました!! (^^)/

まとめ

GCPのサーバレスをpython で利用するために、Cloud Functions を python 使い方を調査し、動作確認をとった。

  • ローカルで動かすことも可能。(functions-)
  • CloudBuild から deploy 可能

いろいろ作っていくのか。location(region?) が違うと別のものとして扱われているようだった。

来週も生き延びれるかな。。。

メモ

  • 参考にさせていただきました。PubSubもさくっと動作確認されている。

  • ローカルに作ったパッケージを呼び出す。

  • google 様のサンプル: python-doc-samples/functions/ 以下に全部ある。

  • gcloud の使い方入門

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?