Terraform で Cloud Functions をデプロイする
目次
- 1 概要
- 2 Terraform
- 3 エラー
- 3.1 ERROR: error fetching storage source: generic::unknown: retry budget exhausted (3 attempts): fetching gcs source: unpacking source from gcs: source fetch container exited with non-zero status: 9
- 3.2 Error: Error waiting for Creating CloudFunctions Function: Error code 3, message: Function failed on loading user code. This is likely due to a bug in the user code. Error message: File main.py that is expected to define function doesn’t exist
- 3.3 Error: Error waiting for Creating CloudFunctions Function: Error code 3, message: Function failed on loading user code. This is likely due to a bug in the user code. Error message: File main.py is expected to contain a function named helloGET
- 3.4 Error: Error applying IAM policy for cloudfunctions cloudfunction “projects/<PROJECT_ID>/locations/us-central1/functions/function-test”: Error setting IAM policy for cloudfunctions cloudfunction “projects/<PROJECT_ID>/locations/us-central1/functions/function-test”: googleapi: Error 403: Permission ‘cloudfunctions.functions.setIamPolicy’ denied on resource ‘projects/<PROJECT_ID>/locations/us-central1/functions/function-test’ (or resource may not exist).
- 4 参考
概要
やりたいこと
Terraform で CloudFunctions をデプロイしたい。
前回の GCP チュートリアルの続き。
CloudFunctions のデプロイ
GCP 版 AWS Lambda。デプロイ方法は以下を参考にした。
流れ。
- ローカルでプログラムファイルを作成・修正
- Terraform で zip 化
- Terraform で zip ファイルを GCS へアップロード
- CloudFunctions が GCS から zip を取得し解凍
Terraform
Terraform 準備
前回参照。
Python で Hellow World
CloudFunctions で動かすプログラムは Python を選択。基本の Hello World。
main.py という名前で作成しないといけない。
vi main.py
def hello_world(request): """Responds to any HTTP request. Args: request (flask.Request): HTTP request object. Returns: The response text or any set of values that can be turned into a Response object using `make_response <http://flask.pocoo.org/docs/1.0/api/#flask.Flask.make_response>`. """ request_json = request.get_json() if request.args and 'message' in request.args: return request.args.get('message') elif request_json and 'message' in request_json: return request_json['message'] else: return f'Hello World!'
Terraform で CloudFunctions
ランタイムは Python3.7 を指定する。
vi cloudfunctions.tf
data "archive_file" "function_archive" { type = "zip" source_dir = "code" # main.pyやrequirement.txtが入ってるdir output_path = "code/main.zip" # zipファイルの出力パス } resource "google_storage_bucket" "bucket" { name = "test-bucket-hello-world-test" } resource "google_storage_bucket_object" "archive" { name = "index.zip" bucket = google_storage_bucket.bucket.name source = data.archive_file.function_archive.output_path } resource "google_cloudfunctions_function" "function" { name = "function-test" description = "My function" runtime = "python37" available_memory_mb = 128 source_archive_bucket = google_storage_bucket.bucket.name source_archive_object = google_storage_bucket_object.archive.name trigger_http = true entry_point = "hello_world" } resource "google_cloudfunctions_function_iam_member" "invoker" { project = google_cloudfunctions_function.function.project region = google_cloudfunctions_function.function.region cloud_function = google_cloudfunctions_function.function.name role = "roles/cloudfunctions.invoker" member = "allUsers" }
デプロイ。
terraform apply
curl から呼び出せることを確認。
url https://us-central1-<PROJECT_ID>.cloudfunctions.net/function-test
エラー
ERROR: error fetching storage source: generic::unknown: retry budget exhausted (3 attempts): fetching gcs source: unpacking source from gcs: source fetch container exited with non-zero status: 9
ローカルの python ファイルを zip に圧縮しないで指定していた。
resource "google_storage_bucket_object" "archive" { name = "index.zip" bucket = google_storage_bucket.bucket.name source = "./slack_bot.py" }
python ファイルを zip で圧縮し、zip ファイルを指定するようにした。
resource "google_storage_bucket_object" "archive" { name = "index.zip" bucket = google_storage_bucket.bucket.name source = "./slack_bot.py.zip" }
Error: Error waiting for Creating CloudFunctions Function: Error code 3, message: Function failed on loading user code. This is likely due to a bug in the user code. Error message: File main.py that is expected to define function doesn’t exist
main.py という名前で python ファイルを作成しないといけなかった。
Error: Error waiting for Creating CloudFunctions Function: Error code 3, message: Function failed on loading user code. This is likely due to a bug in the user code. Error message: File main.py is expected to contain a function named helloGET
python のメソッド名が Terraform の endpoint と一致していない( helloGET というメソッドがない)
Terraform 側の endpoint 名を変更した。
resource "google_cloudfunctions_function" "function" { name = "function-test" description = "My function" runtime = "python37" available_memory_mb = 512 source_archive_bucket = google_storage_bucket.bucket.name source_archive_object = google_storage_bucket_object.archive.name trigger_http = true entry_point = "hello_http" }
Error: Error applying IAM policy for cloudfunctions cloudfunction “projects/<PROJECT_ID>/locations/us-central1/functions/function-test”: Error setting IAM policy for cloudfunctions cloudfunction “projects/<PROJECT_ID>/locations/us-central1/functions/function-test”: googleapi: Error 403: Permission ‘cloudfunctions.functions.setIamPolicy’ denied on resource ‘projects/<PROJECT_ID>/locations/us-central1/functions/function-test’ (or resource may not exist).
IAM Policy を CloudFunctions にセットできない。
パブリックアクセスを許可する設定部分。
resource "google_cloudfunctions_function_iam_member" "invoker" { project = google_cloudfunctions_function.function.project region = google_cloudfunctions_function.function.region cloud_function = google_cloudfunctions_function.function.name role = "roles/cloudfunctions.invoker" member = "allUsers" }
cloudfunctions.functions.setIamPolicy
権限がないためとのこと。
Terraform 用のサービスロールに Cloud Functions Admin を追加した。
ディスカッション
コメント一覧
まだ、コメントがありません