🛠️

Infrastructure Manager でより手軽に Terraform で IaC

2023/08/28に公開

先日 GA になった Infrastructure Manager が何者か気になったのでさっそく触ってみました!

Infrastructure Manager は IaC ツールである Terraform をより手軽に利用できるようなサービスとなっていました。Google Cloud には純正 IaC によるインフラ構築/管理サービスとして Deployment Manager がありますが、世の中的には Terraform を利用している方が多い印象ですね。

そういったところもあってか、より Google Cloud の世界で Terraform を扱えるラッパー的なマネージドサービスとして Infrastructure Manager が出てきたのかなと感じました。

イメージ図
(触ってみた感じをイメージ図にしてみました)

最速でこちらの記事が基本情報をまとめてくれているので、本記事では実際にコマンドをうってみた結果をまとめたいと思います。

Overview

Infrastructure Manager を活用した Iac 実践について検証

  • Terraform による IaC をローカルの環境構築なしに Infrastructure Manager で実現できました
  • gcloud alpha infra-manager コマンドTerraform で定義したリソースのプロビジョニングから deployment と呼ばれるスタックの確認やプロビジョニングされた resource の確認までは可能となっていました
  • これから IaC を実践しようとしている方にとっては gcloud コマンドベースで手軽に始められる点がよいなと思いました

所感

実際に触ってみて、メリットは上記で記載した点に加えて、ステートファイルの管理を考えなくていい点だと思いました。Terraform を利用するにあたって、ステートファイルの管理は少しハードルが高いところでもあるので、その点をよしなにやってくる点はよいなと。

また、こちらの terraform-google-modules にある各種リポジトリを参照することで手軽にリソース群をプロビジョニングできるところもよいところでしょうか。

今後も良さげなアップデートは期待できるのでウォッチし続けたいと思います!

キーワード

インフラのプロビジョニング

さっそくそれぞれのコマンドを試していきたいと思います!

コードの準備

用意するファイルは簡単に VPC と Subnet が定義された main.tf のみです。

main.tf
provider "google" {
  project = "sample-project"
  region  = "asia-northeast1"
}

terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
    }
  }
}

resource "google_compute_network" "sample_vpc" {
  name                    = "sample-network"
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "sample_subnet" {
  name                     = "sample-subnet"
  ip_cidr_range            = "192.168.0.0/20"
  region                   = "asia-northeast1"
  network                  = google_compute_network.sample_vpc.self_link
  private_ip_google_access = true
  log_config {
    flow_sampling = 1
  }
}

Deployment の作成:deployments apply

いよいよプロビジョニングしてみます。今回は tf ファイルを Cloud Storage で管理したいと思います。あらかじめ用意したバケットに上記のコードを転送します。

terminal
cloud storage cp main.tf gs://sample-storage/infra-manager

次にサービスアカウントを用意します。こちらのサービスアカウントは Cloud Build にアタッチされて権限を行使するようです。最低限のバインドするロールとしては roles/config.agent と Terraform で定義したリソースに合った権限のようです。

また、今回は Cloud Storage に格納した tf ファイルを取得するため Cloud Storage 周りの権限が必要かと思いましたが、 roles/config.agent に含まれていました。プロジェクトレベルでロールがバインドされていれば十分なようです。

下記のコマンドで Cloud Storage に格納した main.tf で定義したリソースをプロビジョニングできます。

terminal
gcloud alpha infra-manager deployments apply projects/sample-project/locations/us-central1/deployments/sample-deployment \
    --service-account projects/sample-project/serviceAccounts/sample-sa@sample-project.iam.gserviceaccount.com \
    --gcs-source gs://sample-storage/infra-manager

ポイント①

ポイントの 1 つ目は config.googleapis.com の対応リージョンは us-central1 / asia-east1 / europe-west1 という点です。 main.tf で生成されるスタックを deployment と呼ぶようで、この deployment は上記 3 つの中で指定したリージョンに生成されます。

ただ、実際のリソースは Terraform 内で指定したリージョン(今回は asia-northeast1)に生成されます。

ポイント②

ポイントの 2 つ目は Cloud Storage で管理している場合は --gcs-source でバケットとパスを指定することで、そのパスの tf ファイル群を読み込んでくれます。

記事冒頭で参考にさせていただいた記事では Git リポジトリを参照元としています。

ポイント③

ポイントの 3 つ目は Variable で変数を利用している場合は --input-values でコマンド実行時に値を渡すことができます。

試しに vpc_name を Variable で変数に置き換えてみます。 sample-vpc だったところを var.vpc_name に置き換え、 variable.tf を作成します。

main.tf
・・・

resource "google_compute_network" "sample_vpc" {
  name                    = var.vpc_name
  auto_create_subnetworks = false
}

resource "google_compute_subnetwork" "sample_subnet" {
  name                     = "sample-subnet"
  ip_cidr_range            = "192.168.0.0/20"
  region                   = "asia-northeast1"
  network                  = google_compute_network.sample_vpc.self_link
  private_ip_google_access = true
  log_config {
    flow_sampling = 1
  }
}
variable.tf
variable "vpc_name" {
}

こちらも Cloud Storage に転送します。

terminal
# Cloud Storage の main.tf と同様のパスに転送
gcloud storage cp main.tf variable.tf gs://sample-storage/infra-manager/

# --input-values で variable で設定した変数に対して値を渡す
gcloud alpha infra-manager deployments apply projects/sample-project/locations/us-central1/deployments/sample-deployment \
    --service-account projects/sample-project/serviceAccounts/sample-sa@sample-project.iam.gserviceaccount.com \
    --gcs-source gs://sample-storage/infra-manager
    --input-values="vpc_name=sample-network"

ポイント④

ポイントの 4 つ目はステートファイルの管理についてです。Terraform を利用するにあたってステートファイルの管理はついてまわります。こちらは Infrastructure Manager を利用すると gs://[PROJECT ID]-[Region]-blueprint-config というバケットに deploymentRevision 単位で作成されます。

下記は test という deployment の例です、ファイルの中身は厳密には teraform.tfstate ではないようですが、プロビジョニングされたリソースが記載されています。

log.json は Cloud Build での Terraform 関連にフォーカスされたログが吐き出させれているようです。

また、実行されたファイル群は別のディレクトリに格納されるようです。

このような感じでプロビジョニングができます!ローカルで Terraform の環境構築をしなくてさくっと IaC を実践できるのはいい感じです!

Deploymentの一覧:deployments list

deployment の一覧を確認したい場合には deployments list を実行します。

terminal
gcloud alpha infra-manager deployments list --project sample-project --location "us-central1"

NAME STATE LATEST_REVISION CREATE_TIME UPDATE_TIME
test ACTIVE r-12 2023-08-26T03:51:54.538592914Z 2023-08-26T08:04:00.865231992Z

Deploymentの詳細:deployments describe

deployment の詳細を確認したい場合には deployments describe を実行します。

terminal
 gcloud alpha infra-manager deployments describe projects/sample-project/locations/us-central1/deployments/test

createTime: '2023-08-26T03:51:54.538592914Z'
latestRevision: projects/sample-project/locations/us-central1/deployments/test/revisions/r-12
lockState: UNLOCKED
name: projects/sample-project/locations/us-central1/deployments/test
serviceAccount: projects/sample-project/serviceAccounts/sample-sa@sample-project.iam.gserviceaccount.com
state: ACTIVE
stateDetail: revision "projects/sample-project/locations/us-central1/deployments/test/revisions/r-12"
applied
terraformBlueprint:
gcsSource: gs://sample-storage/infra-manager
inputValues:
vpc_name:
inputValue: sample-network
updateTime: '2023-08-26T08:04:00.865231992Z'

Resourceの確認:resources list

deployment でプロビジョニングされている resource の一覧を確認したい場合には resources list を実行します。

terminal
gcloud alpha infra-manager resources list --revision=projects/sample-project/locations/us-central1/deployments/test/revisions/r-12

NAME STATE
compute-network-weq9yai7 RECONCILED
compute-subnetwork-kaviu171 RECONCILED

Resourceの詳細:resources describe

deployment でプロビジョニングされている resource の詳細を確認したい場合には resources describe を実行します。

terminal
gcloud alpha infra-manager resources describe projects/sample-project/locations/us-central1/deployments/test/revisions/r-12/resources/compute-network-weq9yai7

caiAssets:
compute.googleapis.com/Network:
fullResourceName: //compute.googleapis.com/projects/sample-project/global/networks/sample-network
intent: UNCHANGED
name: projects/sample-project/locations/us-central1/deployments/test/revisions/r-12/resources/compute-network-weq9yai7
state: RECONCILED
terraformInfo:
address: google_compute_network.sample_vpc
id: projects/sample-project/global/networks/sample-network
type: google_compute_network

明示的なロック:deployments lock

ステートファイルをローカルに落として Terraform のコマンドを適用したいといったユースケースで、ステートファイルが変更されて実行されると状態が変わってしまいややこしい状況になります。

そんな時は下記のコマンドで明示的にロックをかけて防ぐことができます。

terminal
 gcloud alpha infra-manager deployments lock test --project sample-project --location us-central1

こうすると test という deployment にロックがかかり deployments apply が実行できなくなります。

ERROR: Invalid resource state for "projects/sample-project/locations/us-central1/deployments/test": Deployment "projects/sample-project/locations/us-central1/deployments/test" is already locked

ロックの解除は下記のコマンドになります。

terminal
# ロック ID の取得
LOCK_ID=$(gcloud alpha infra-manager deployments export-lock test --project sample-test --location us-central1 --format="get(lockId)")

# ロックの解除
gcloud alpha infra-manager deployments unlock test --project sample-project --location us-central1 --lock-id ${LOCK_ID}

と思いましたが、下記のエラーが出て unlock することができませんでした。冒頭の記事でも対策込みで記述されていますので、ご参照ください。非常に助かりました。

ERROR: (gcloud.alpha.infra-manager.deployments.unlock) INVALID_ARGUMENT: Invalid JSON payload received. Unknown name "disableValidateAndUpdate": Cannot find field.

  • '@type': type.googleapis.com/google.rpc.BadRequest
    fieldViolations:
  • description: 'Invalid JSON payload received. Unknown name >"disableValidateAndUpdate":
    Cannot find field.'

Deployment の削除:deployments delete

deployment を削除したい場合には deployments delete を実行します。

上記でロックを解除できたのでコマンドが実行可能となりました。

terminal
# deployment の削除
gcloud alpha infra-manager deployments delete  projects/sample-project/locations/us-central1/deployments/test

# deployment の確認
gcloud alpha infra-manager deployments list --project sample-project --location "us-central1"

Listed 0 items.

これで一通り基本的なコマンドを試すことができました!

まとめ

Infrastructure Manager を簡単な tf ファイルベースに触ってみました。コマンドは直感的でわかりやすく、これから IaC を試したい人には使いやすいサービスと感じました。

本記事で紹介したコマンドの一覧

  • gcloud alpha infra-manager
    • deployments
      • apply:プロビジョニング
      • list:deployment の一覧表示
      • describe:deployment の詳細表示
      • lock:deployment の明示的なロック
      • export-lock:deployment のロック ID の取得
      • unlock:deployment の明示的なロック解除
      • delete:deplyment の削除
    • resources
      • list:deployment の resource の一覧表示
      • describe:deployment の resource の詳細表示

参考記事

  • Google Cloud のマネージド Terraform、 Infrastructure Manager 登場!(zennブログ)

さいごに

AWS と Google Cloud で構築したデータ基盤の開発・運用に携わっているデータエンジニアです。5 年くらい携わっていて、この業務がきっかけで Google Cloud が好きになりました。

現在は React のフロントエンジニアとして修行中です。

X では Google Cloud 関連の情報を発信をしています。

https://twitter.com/pHaya72

Discussion