[Terraform] [Cloud Functions] 環境変数をyamlファイルから読み込みたい

2022.09.12

データアナリティクス事業部でGoogle Cloudのデータエンジニアをしています。はんざわです。

Cloud FunctionsをTerraformで構築する際に環境変数をyamlファイルから読み込みたいケースがありました。 gcloudコマンドだと以下のコマンドでデプロイすることができます。

gcloud functions deploy cloud_functions_test \
  --region us-central1 \
  --entry-point main \
  --runtime python39 \
  --env-vars-file env.yaml \
  --trigger-http

上のコマンドをTerraformでも再現します。

環境

Google Cloud Shell

terraform:v1.2.7

構成図

cloud_functions_test/
├── functions
│   ├── env.yaml
│   └── main.py
└── terraform
    ├── environments
    │   └── test1
    │       ├── main.tf
    │       └── terraform.tfvars
    └── modules
        ├── cloud_functions
        │   ├── main.tf
        │   └── variables.tf
        └── cloud_storage
            ├── main.tf
            ├── output.tf
            └── variables.tf

7 directories, 9 files

公式ドキュメント

以下のリソースは公式ドキュメントから引用してきました。

resource "google_cloudfunctions_function" "function" {
  name        = "function-test"
  description = "My function"
  runtime     = "nodejs16"

  available_memory_mb          = 128
  source_archive_bucket        = google_storage_bucket.bucket.name
  source_archive_object        = google_storage_bucket_object.archive.name
  trigger_http                 = true
  https_trigger_security_level = "SECURE_ALWAYS"
  timeout                      = 60
  entry_point                  = "helloGET"
  labels = {
    my-label = "my-label-value"
  }

  environment_variables = {
    MY_ENV_VAR = "my-env-var-value"
  }
}

environment_variablesの部分でkey value形式で変数を定義しています。

結論

結論は単純でenvironment_variables = yamldecode(file("ファイルpath"))で変数として与えることが可能です。

検証用に以下のようなモジュールファイルを作成し、呼び出してみました。

## modules/cloud_functions/main.tf

data "archive_file" "zip_file" {
  type        = "zip"
  source_dir  = var.script_dir
  output_path = var.zip_file_path
  excludes    = ["env.yaml"]
}

resource "google_storage_bucket_object" "upload_file" {
  name   = var.zip_name
  bucket = var.bucket_name
  source = data.archive_file.zip_file.output_path
}

resource "google_cloudfunctions_function" "functions" {
  name    = var.gcf_name
  runtime = "python39"

  available_memory_mb   = var.memory
  source_archive_bucket = google_storage_bucket_object.upload_file.bucket
  source_archive_object = google_storage_bucket_object.upload_file.name
  trigger_http          = true
  timeout               = var.timeout
  entry_point           = "main"
  region                = var.region

  environment_variables = yamldecode(file("../../../functions/env.yaml"))
}

resource "google_cloudfunctions_function_iam_member" "invoker" {
  project        = google_cloudfunctions_function.functions.project
  region         = google_cloudfunctions_function.functions.region
  cloud_function = google_cloudfunctions_function.functions.name

  role   = "roles/cloudfunctions.invoker"
  member = "allUsers"
}
## functions/env.yaml
hoge: "hello"
fuga: "world"

まとめ

Cloud Fcuntionsを複数個構築するような場合、こうすることで環境毎に環境変数ファイルを参照することができ、管理が楽になると思います。