アライアンス事業部 エンジニアの村田です。
Cloud Console(GUI) や Cloud SDK(CLI)によってGoogle Cloud上にデプロイした既存リソースをコード化し、新しいプロジェクトに複製したいケースはありませんでしょうか? Google Cloud上の既存リソースを一括エクスポートでTerraform形式(HCL)にコード化するための機能がプレビューにて利用可能でしたので、本ブログにて試してみました。
※Google Cloud上の既存リソースをHCLに一括エクスポートできる機能はプレビューリリースのためテスト利用にお使いください。
※以下Google Cloudのチュートリアルを参考にしています。 https://cloud.google.com/docs/terraform/resource-management/export?hl=ja
検証環境
以下ローカル環境で検証しています。
OS : Ubuntu 22.04.2 LTS (GNU/Linux 5.15.90.1-microsoft-standard-WSL2 x86_64)
※Windows 11のWSL上に立てています。
ローカル環境で本検証を実行するにはgcloud CLI(Cloud SDK)のインストールと初期化が必要です。手順は以下をご参照ください。(Cloud Shellを利用する場合は以下手順は不要です。)
gcloud CLI をインストールする | Google Cloud CLI のドキュメント
準備
Google Cloud の Terraform一括エクスポートツールを利用するために、以下コマンドでConfig Connectorをインストールします。
gcloud components install config-connector
対象プロジェクトのGoogle Cloudリソースをエクスポートするために、Cloud Asset APIを有効化します。
gcloud services enable cloudasset.googleapis.com
Google Cloudのbetaバージョン機能やサービスを利用するためのgcloud betaコマンドをインストールします。
gcloud components install beta
Google Cloudプロジェクト全体のエクスポート
プロジェクトのリソース構成を出力するディレクトリを作成します。
mkdir OUTPUT_DIRECTORY
プロジェクト構成全体を Terraform HCL コードにエクスポートします。
gcloud beta resource-config bulk-export \
--path=OUTPUT_DIRECTORY \
--project=<Google CloudプロジェクトID> \
--resource-format=terraform
resource-config
Google Cloudリソースを宣言的に管理するためのコマンド。本コマンドを利用するために、前述のconfig-connectorのインストールが必要。
bulk-export
一括エクスポートのためのコマンド。
--path
エクスポート先ディレクトリ。
--project
エクスポート対象のプロジェクト。
--resource-format
エクスポートするコンフィグレーションのフォーマット。terraform
:Terraform HCL または krm
: KRM YAML のいずれかを指定可能。
指定したディレクトリ配下に詳細なリソースごと/インスタンスごとに、以下の構成で多数のtfファイルがエクスポートされました。(プロジェクトIDなどの情報はマスクしています)
$ tree
.
├── xxxxxxxx
│ └── Project
│ └── xxxxxxxx.tf
├── xxxxxxxx
│ └── Service
│ ├── artifactregistry-googleapis-com.tf
│ ├── autoscaling-googleapis-com.tf
│ ├── bigquery-googleapis-com.tf
│ ├── bigquerymigration-googleapis-com.tf
│ ├── bigquerystorage-googleapis-com.tf
│ ├── cloudapis-googleapis-com.tf
│ ├── cloudasset-googleapis-com.tf
│ ├── cloudbuild-googleapis-com.tf
│ ├── cloudtrace-googleapis-com.tf
│ ├── compute-googleapis-com.tf
│ ├── container-googleapis-com.tf
│ ├── containerfilesystem-googleapis-com.tf
│ ├── containerregistry-googleapis-com.tf
│ ├── datastore-googleapis-com.tf
│ ├── dns-googleapis-com.tf
│ ├── iam-googleapis-com.tf
│ ├── iamcredentials-googleapis-com.tf
│ ├── logging-googleapis-com.tf
│ ├── monitoring-googleapis-com.tf
│ ├── networkconnectivity-googleapis-com.tf
│ ├── osconfig-googleapis-com.tf
│ ├── oslogin-googleapis-com.tf
│ ├── pubsub-googleapis-com.tf
│ ├── run-googleapis-com.tf
│ ├── servicemanagement-googleapis-com.tf
│ ├── serviceusage-googleapis-com.tf
│ ├── sourcerepo-googleapis-com.tf
│ ├── sql-component-googleapis-com.tf
│ ├── storage-api-googleapis-com.tf
│ ├── storage-component-googleapis-com.tf
│ └── storage-googleapis-com.tf
├── xxxxxxxx
│ └── ComputeDisk
│ └── us-west1-a
│ └── flask-vm.tf
└── projects
└── xxxxxxxx
├── ComputeFirewall
│ ├── allow-ssh.tf
│ ├── default-allow-http.tf
│ ├── default-allow-https.tf
│ ├── default-allow-icmp.tf
│ ├── default-allow-internal.tf
│ ├── default-allow-rdp.tf
│ ├── default-allow-ssh.tf
│ └── flask-app-firewall.tf
├── ComputeInstance
│ └── us-west1-a
│ └── flask-vm.tf
├── ComputeNetwork
│ └── my-custom-mode-network.tf
├── ComputeResourcePolicy
│ └── us-central1
│ └── test-schedule.tf
├── ComputeSubnetwork
│ └── us-west1
│ └── my-custom-subnet.tf
├── IAMServiceAccount
│ ├── xxxxxxxx-compute.tf
│ ├── xxxxxxxx-sa.tf
│ ├── xxxxxxxx-sa.tf
│ └── terraform-account.tf
└── StorageBucket
└── US
├── export-xxxxxxxxxx.tf
└── xxxxxxxx-cloudbuild.tf
20 directories, 51 files
一部のtfファイルの中身を見てみます。(flask-vmというCompute Engineインスタンスを確認。プロジェクトIDや外部IPなどの情報はマスクしています)
$ cat projects/xxxxxxxx/ComputeInstance/us-west1-a/flask-vm.tf
resource "google_compute_instance" "flask_vm" {
boot_disk {
auto_delete = true
device_name = "persistent-disk-0"
initialize_params {
image = "https://www.googleapis.com/compute/beta/projects/debian-cloud/global/images/debian-11-bullseye-v20231010"
size = 10
type = "pd-standard"
}
mode = "READ_WRITE"
source = "https://www.googleapis.com/compute/v1/projects/xxxxxx/zones/us-west1-a/disks/flask-vm"
}
machine_type = "f1-micro"
metadata = {
startup-script = "sudo apt-get update; sudo apt-get install -yq build-essential python3-pip rsync; pip install flask"
}
name = "flask-vm"
network_interface {
access_config {
nat_ip = "xx.xxx.xx.xx"
network_tier = "PREMIUM"
}
network = "https://www.googleapis.com/compute/v1/projects/xxxxxx/global/networks/my-custom-mode-network"
network_ip = "10.0.1.2"
stack_type = "IPV4_ONLY"
subnetwork = "https://www.googleapis.com/compute/v1/projects/xxxxxx/regions/us-west1/subnetworks/my-custom-subnet"
subnetwork_project = "xxxxxx"
}
project = "xxxxxx"
scheduling {
automatic_restart = true
on_host_maintenance = "MIGRATE"
provisioning_model = "STANDARD"
}
shielded_instance_config {
enable_integrity_monitoring = true
enable_vtpm = true
}
tags = ["ssh"]
zone = "us-west1-a"
}
一部のGoogle Cloudリソースタイプのみエクスポート
--resource-types
でリソースタイプを指定することで、一部のリソースタイプのみをエクスポートすることができます。
gcloud beta resource-config bulk-export \
--resource-types=<リソースタイプ> \
--path=OUTPUT_DIRECTORY \
--project=<Google CloudプロジェクトID> \
--resource-format=terraform
指定可能なリソースタイプは以下コマンドを入力して確認できます。
$ gcloud beta resource-config list-resource-types
┌──────────────────────────────────────┬──────────────┬─────────┬──────┐
│ KRM KIND │ BULK EXPORT? │ EXPORT? │ IAM? │
├──────────────────────────────────────┼──────────────┼─────────┼──────┤
│ AccessContextManagerAccessLevel │ │ │ │
│ AccessContextManagerAccessPolicy │ │ │ x │
│ AccessContextManagerServicePerimeter │ │ │ │
│ ArtifactRegistryRepository │ x │ x │ x │
│ BigQueryDataset │ x │ x │ │
│ BigQueryJob │ │ x │ │
│ BigQueryTable │ x │ x │ x │
│ BigtableAppProfile │ x │ x │ │
│ BigtableGCPolicy │ │ │ │
│ BigtableInstance │ x │ x │ x │
│ BigtableTable │ x │ x │ x │
│ CloudBuildTrigger │ │ │ │
│ CloudIdentityGroup │ │ │ │
...
BULK EXPORT?
列にx
が記載してある行のKRM KIND
が指定可能なリソースタイプです。
ComputeInstance
とComputeNetwork
のみをOUTPUT_DIRECTORY_2
にエクスポートしてみます。
gcloud beta resource-config bulk-export \
--resource-types=ComputeInstance,ComputeNetwork \
--path=OUTPUT_DIRECTORY_2 \
--project=<Google CloudプロジェクトID> \
--resource-format=terraform
以下のようにエクスポートされました。(プロジェクトIDはマスクしています)
$ tree
.
└── projects
└── xxxxxxxxxx
├── ComputeInstance
│ └── us-west1-a
│ └── flask-vm.tf
└── ComputeNetwork
└── my-custom-mode-network.tf
5 directories, 2 files
[Tips]Cloud ConsoleからTerraformコードを確認する
Cloud Console の GUI画面からリソースのコードを確認する方法もあります。
Compute Enigineなど一部のリソースについては、リソース作成中の画面で[同等のコード]をクリックすることで画面右側に作成中のリソースについてコードをリアルタイム表示してくれます。
なお、Terraform(HCL)以外にもgcloudコマンド等によるコマンドラインでの設定、REST API(JSON)による設定も確認することもできます。
おわりに
今回、TerraformでGoogle Cloudを管理するための小ネタ的機能を試してみましたが、今後はTerraformによるGoogle Cloudのコード管理について様々な運用パターンでのベストプラクティスなど発信していきたいと思っています。