TerraformでCloud Composerを構築する

この記事は自身が実際に業務で使用した内容の復習 & 備忘録です。
理解不足の点や説明の誤りなどありましたら本ページ最下部のコメントでご指摘いただけると幸いです。

目的

Terraform で Google Cloud Platform (以下、GCP)の Cloud Composer を構築する。

前提

  • Terraformコマンドが利用できること
  • GCPを利用するための準備ができていること

今回はCloud Composer を構築するための Terraform の書き方・実行方法に重点を置いているため、上記については説明しません。また、Terraform の構文などについても説明していません。

Terraform を書く

以下のようにTerraform を書きます。

# terraform.tfvars
credentials = "credentials.json"
project = "GCPのプロジェクトID"
region = "asia-northeast1"
zone = "asia-northeast1-b"
# variables.tf
variable "credentials" { type = string }
variable "project" { type = string }
variable "region" { type = string }
variable "zone" { type = string }
# output.tf
output "composer_name" {
  description = "Name of composer environment"
  value       = google_composer_environment.composer.name
}

output "service_account" {
  description = "Service account used by composer"
  value       = google_composer_environment.composer.config[0].node_config[0].service_account
}
# main.tf
provider "google" {
  credentials = file(var.credentials)
  project     = var.project
  region      = var.region
  zone        = var.zone
}

resource "google_composer_environment" "composer" {
  name    = "test-composer"
  project = var.project
  region  = var.region
  labels  = {
    "composer": "test-composer"
  }

  config {
    node_count = 3

    node_config {
      zone            = "projects/${var.project}/zones/${var.zone}"
      machine_type    = "n1-standard-1"
      disk_size_gb    = 30
      network         = "projects/${var.project}/global/networks/default"
      service_account = "test-composer@${var.project}.iam.gserviceaccount.com"
      oauth_scopes    = [
        "https://www.googleapis.com/auth/cloud-platform",
      ]
    }

    software_config {
      airflow_config_overrides = {
        core-max_active_runs_per_dag = 1
      }
      image_version  = "composer-1.17.8-airflow-1.10.15"
      python_version = "3"
    }
  }
}

main.tf の記載内容の説明

provider

今回はGCPを使用するため、Googleを指定します。
{}の中に、自身のGCPプロジェクトの情報を記載します。

credentials
このtfファイルでリソースを作成するためのサービスアカウントの権限情報を指定します。
具体的には以下の通りです。

  • GCPのコンソール画面から[IAMと管理] –> [サービスアカウント] でTerraformで使用するサービスアカウントを作成または選択
  • そのサービスアカウントの [キー]タブ を表示して [鍵を追加] をクリックして [新しい鍵を作成] を選択
  • キーのタイプから「JSON」を選択して[作成]をクリックするとcredentials情報のJSONファイルがダウンロードされる
  • ダウンロードしたJSONファイルのパスをcredentialsに指定する

project
使用するGCPプロジェクトのIDを指定します。

region
使用するリージョンを指定します。

zone
リージョン内のゾーンを指定します。

provider の書き方の詳細につきましては 公式サイト をご覧ください。

resource

resource "リソースの種類" "tfファイル内で使用する名前" {} のように書きます。
作成するリソースを指定して、{}の中にリソースの情報を記載していきます。

今回はCloud Composerを作成するので、リソースの種類にはgoogle_composer_environmentを指定します。

"tfファイル内で使用する名前"は、output.tfvalueにしているように、リソースの情報を別の場所で参照するときに使用します。

{}の中には作成するcomposerの情報を記載していきます。
より詳細な書き方については、公式サイト をご参照ください。

name
ここで指定した名称でcomposerが作成されます。

config
composerを構成する各種情報を設定します。

config.node_config
KubernetesEngineクラスターに使用される情報を設定します。

config.node_config.service_account
composerで様々な処理を行う際に使用するサービスアカウントを指定します。「providerのcredentials」に指定したサービスアカウントとは用途が違うので要注意。

config.software_config.airflow_config_overrides
Airflowのパラメータを設定します。Airflowのパラメータについては、こちらの公式サイト をご参照ください。

config.software_config.image_version
利用するcomposerのイメージのバージョンを設定します。バージョンリストについては、こちらの公式ドキュメント をご参照ください。

ディレクトリ構成

ディレクトリ構成は次のようになります。

.
├── credentials.json
├── main.tf
├── output.tf
├── terraform.tfvars
└── variables.tf

Terraformを実行してComposerを作成する

Terraformコマンドを実行してComposerを作成します。

Terraformコマンドの実行

以下の順にコマンドを実行します。

terraform init
terraform plan
terraform apply

terraform applyコマンドを叩くと「Do you want to perform these actions?」と聞かれるので、yesを入力するとリソースの作成が開始されます。

Composer の環境が作成されるまで、だいぶ時間がかかります。
公式サイトには「約25分かかります。」と記載されていますが、今回は約17分かかりました。

完了すると、次のように表示されます。

google_composer_environment.composer: Creation complete after 17m9s [id=projects/{プロジェクトID}/locations/asia-northeast1/environments/test-composer]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Outputs:

composer_name = "test-composer"
service_account = "test-composer@{プロジェクトID}.iam.gserviceaccount.com"

補足

Outputs:以降の内容は、output.tfに記載した項目が表示されます。

output項目を記載してない場合は、Outputs:以降の内容は表示されません。

作成されたComposerを確認

GCPのコンソールからTerraformで定義した内容通りComposerが作成されたことを確認します。

下図の赤文字は Composer の設定に対応する main.tf に記載した項目名です。

composerの設定一覧
作成されたcomposerの確認

Composerを削除する

作成したcomposerをそのまま放置していると、かなりお金がかかります。

僕の場合、約2週間放置していたら2万5千円くらい課金されていました。(幸いプロジェクトを作成したばかりで$300相当の無料トライアルがあったため、実際に支払いはしなくて済んだの良かったですが…)

もし使用しないのであれば課金されないように削除しましょう。

削除するにはterraform destroyコマンドを実行します。「Do you really want to destroy all resources?」と聞かれるので、yesを入力すると削除が開始されます。

完了すると、次のように表示されます。

google_composer_environment.composer: Destruction complete after 4m12s

Destroy complete! Resources: 1 destroyed.

注意

課金されないようにするためには、Composerの環境だけでなく、Cloud StorageのバケットやCompute Engineの永続ディスクも削除する必要があります。詳しくは、公式サイトのこちらのページ をご覧ください。

terraform destroyコマンドでは、Cloud Storageのバケットは削除されなかったので、バケットは別途削除する必要があります。

発生したエラー

composerの作成を自身のGCPプロジェクトで再現しようした際に発生したエラーと、その対処方法を記載しておきます。

エラー内容

terraform applyを叩くと、以下のようなエラーが表示されました。

Error: Error waiting to create Environment: Error waiting for Creating Environment: Error code 3, message: CREATE operation failed. Errors in: [Web server]; Error messages:
        Failed to deploy the Airflow web server. This might be a temporary issue. You can retry the operation later.
If the issue persists, it might be caused by problems with permissions or network configuration. For more information, see https://cloud.google.com/composer/docs/troubleshooting-environment-creation.

An internal error occurred while processing task /app-engine-flex/flex_await_healthy/flex_await_healthy>2022-04-30T15:31:36.063Z14449.xa.1: Your deployment has failed to become healthy in the allotted time and therefore was rolled back. If you believe this was an error, try adjusting the 'app_start_timeout_sec' setting in the 'readiness_check' section.


  on main.tf line 9, in resource "google_composer_environment" "composer":
   9: resource "google_composer_environment" "composer" {

解決方法

以下の2つの対応を行ったところ、エラーが解消されました。

ファイアーウォールの設定

まず、エラー表示されているリンクを辿ったところ、こちらのページ にたどり着いたので、分からないなりにファイアーウォールを設定してみました。(無駄な設定があるかもしれません…)

種類下り
ターゲットすべてに適用
フィルタ0.0.0.0/0,
172.16.2.0/23,
172.31.254.0/24,
130.211.0.0/22,
35.191.0.0/16
プロトコル / ポートall

ゾーンの変更

ファイアーウォールを設定しただけ解決しなかったため、Cloud Loggingでエラーログを確認してみると、GKEで次のようなエラーが出ていました。

The zone 'projects/{プロジェクトID}/zones/asia-northeast1-a' does not have enough resources available to fulfill the request. Try a different zone, or try again later.

Google翻訳にかけてみると、「ゾーン’projects/{プロジェクトID}/zones/asia-northeast1-a’には、要求を満たすのに十分なリソースがありません。 別のゾーンを試すか、後でもう一度やり直してください。」と翻訳されたので、ゾーンをasia-northeast1-aからasia-northeast1-bに変更したらうまくいきました。

参考