LoginSignup
0
0

Terraformを使ってWorkflowsとCloud Functionsをデプロイする

Posted at

データエンジニアをしています。
運用しているデータパイプラインの一部にGoogle CloudのWorkflowsとCloud Functionsを用いておりますが、デプロイの俊敏性・正確性に課題があります。(コピペ・手動デプロイをやめたいです)
Terraformを使用してこれらを解消できないか、検証をしたことを共有します。

想定読者

  • Terraform初心者
  • Terraformを業務に導入してみたいと考えている人
  • 既存のデプロイフローや手法に課題があると考えている人

試したことをかんたんに

  • WorkflowsとCloud Functionsをterraformでデプロイした
  • Cloud FunctionsはローカルのソースコードをZIP化してGCSにアップロードし、それをもとにCloudFunctionsをデプロイした
  • 外部ファイル(ローカルのソースコードのファイル)を読み込む形でWorkflowsのソースコードを指定した

試した環境・構成

  • Cloud Shell
ディレクトリ構成.txt
work
  └ archive
      └ cloudfuncitons
           └ test_function1
                └ main.zip
  └ cloudfunctions
       └ test_function1
            └ main.py 
  └ workflows
       └ test_workflows
             └ test_workflow.yml
  └ main.tf

archive
Cloud FunctionsをデプロイするためにZIP化したソースコードを格納するディレクトリ。
実運用ではCloud FunctionsだけでなくLambdaも使用予定なので、サービス名別・関数名別にディレクトリを作成している。

cloudfunctions
デプロイするCloud Functionsのソースコードを格納するディレクトリ。

workflows
デプロイするWorkflowsのソースコードを格納するディレクトリ。

main.tf
Cloud FunctionsやWorkflowsとそれに関連するリソースの構成情報を記載したtfファイル。

Cloud Functionsのソースコード

Hello Worldを出力するシンプルなコードです。

main.py
def hello_world(request):
    print('Hello World')
    return 'Hello from Cloud Functions!'

Workflowsのソースコード

Cloud Functionsを呼び出すシンプルなコードです。

test_workflows.yml
- invoke_test_function1:
      call: http.get
      args:
          url: "Cloud FuncitonsのURL"
          auth:
            type: OIDC
      result: response
- logResponse:
      call: sys.log
      args:
        text: ${response.body}
        severity: "INFO"

Terraformのソースコード

プロバイダの設定

main.tf
provider "google" {
  project = "プロジェクト名"
  region  = "asia-northeast1"
}

Cloud Functionsの構成情報

main.tf
# CloudFunctionsのソースコードを格納するGoogle Cloud Storageバケット
resource "google_storage_bucket" "cloud_functions_bucket" {
  name     = "バケット名"
  location = "asia-northeast1"
  # アクセスレベルを均一化
  uniform_bucket_level_access = true
  # 公開アクセスを「非公開」に
  public_access_prevention = "enforced"
}

# CloudFunctionsのソースコードをGCSのオブジェクトとしてアップロードする
resource "google_storage_bucket_object" "test_function1" {
  name   = data.archive_file.function_archive.output_path
  bucket = google_storage_bucket.cloud_functions_bucket.name
  source = data.archive_file.function_archive.output_path
}

# CloudFunctionsのローカルのソースコードをZIP化して、ローカルのarchiveディレクトリに格納する(このZIPファイルをGCSにアップロードする)
data "archive_file" "function_archive" {
  type        = "zip"
  source_dir  = "cloudfunctions/test_function1"
  output_path = "archive/cloudfunctions/test_function1/main.zip"
}

# CloudFunctionsの構成情報
resource "google_cloudfunctions_function" "test_function1" {
  name        = "test_function1"
  description = "An example Cloud Function"
  runtime     = "python310"

  # GCSにアップロードしたソースコードをもとにデプロイする
  source_archive_bucket        = google_storage_bucket_object.test_function1.bucket
  source_archive_object        = google_storage_bucket_object.test_function1.source
  available_memory_mb          = 128
  entry_point                  = "hello_world"
  trigger_http                 = true
  https_trigger_security_level = "SECURE_ALWAYS"
  timeout                      = 60
}

Workflowsの構成情報

main.tf
# Workflowsの構成情報
resource "google_workflows_workflow" "test_workflow" {
  name        = "test_workflow"
  description = "An example workflow"
  # ローカルのymlファイルをソースコードとしてデプロイする
  # ${path.module}はTerraformファイルがあるディレクトリを表します
  source_contents = file("${path.module}/workflows/test_workflows/test_workflow.yml")
  # TODO: 既存サービスアカウントもTerraformで扱えるようにimportしたい
  service_account = "既存のサービスアカウント"
}

ハマったポイント

結果としてterraform applyでのデプロイは成功したのですが、それまでにいくつかハマったポイントがあったので、記録しておきます。

Workflowsのソースコードを外部から読み込む

TerraformやGoogle Cloudのドキュメントを見ていると、Workflowsのソースコードはtfファイルに直書きしている例が多かったです。
しかし、これだと保守性も悪くなりそうですし、テキスト容量の制限(32KB)もあったので、外部ファイルを読み込むことができないか模索しました。

結果、Terraformのfile関数とpath.module変数を用い、下記のように外部ファイルを読み込むことができました。

file("${path.module}/workflows/test_workflows/test_workflow.yml")

参考1:google_workflows_workflow
参考2:Terraform を使用してワークフローを作成する

WorkflowsからCloud Functionsを呼び出すとき

これはTerraform関連の話ではないのですが、WorkflowsからCloud Functionsを呼び出すとき、403エラーが出でしまいました。
Workflowsには十分な権限を付与していたのですが、エラーとなってしまいました。

ドキュメントをみるとauthセクションを加えることで認証情報を付与してCloud Functionsを呼び出すことができるようでした。

Cloud Functions や Cloud Run にリクエストを送信するときは、OIDC を使用して認証します。

OIDC を使用して HTTP リクエストを行うには、URL を指定した後に、ワークフローの定義の args セクションに auth セクションを追加します。この例では、Cloud Functions を呼び出すために、リクエストが送信されます。

参考:ワークフローに認証情報を追加する

今後の展望

  • 既存のリソースをTerraformで管理できるようにする
    • すでに運用しているデータパイプラインをTerraformで扱えるようにする
  • Step FunctionsとLambdaもTerraformで管理できるようにする
    • すでに運用しているデータパイプラインはStep FuncitonsとLambdaも使用しているため
  • Githubとクラウド環境のソースコードおよび構成情報を一致させるために、CI/CDパイプラインとTerraformを連携させる
    • Github ActionsとTerraformを組み合わせてデプロイの俊敏性・正確性を上げる
0
0
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
0
0