Infrastructure Manager で Google Cloud プロジェクトを作成する

# Infrastructure Manager で Google Cloud プロジェクトを作成する
## はじめに
2023/9 に Terraform を Google Cloud マネージドサービスで動かせる Infrastructure Manager がリリースされました！

https://cloud.google.com/blog/ja/products/management-tools/introducing-infrastructure-manager-powered-by-terraform

以前 Terraform Cloud で Google Cloud プロジェクトを作成する記事を書きましたが、同じことを Infrastructure Manager でやってみました。

https://qiita.com/ysmmb12/items/8d2283878a4eb427b976

## 構築手順
公式ドキュメントのクイックスタートをもとに構築しました。

https://cloud.google.com/infrastructure-manager/docs/deploy-vpc-with-terraform

検証の要件は以下のようにしました：
 - Terraform テンプレートは CloudStorage に置く
 - 作成するのは Google Cloud プロジェクトのみ、請求先アカウントの紐づけはしない

### API の有効化
コマンドかコンソールから Infrastructure Manager API を有効化します。

https://cloud.google.com/infrastructure-manager/docs/enable-service

### サービスアカウントの設定
Infrastructure Manager で使うサービスアカウントを用意します。
そしてそのアカウントに Cloud Infrastructure Manager エージェント ロール（`roles/config.agent`）と、Terraform テンプレートで指定したリソースの作成に必要なロール（今回は `roles/resourcemanager.projectCreator`）を付与します。
 `roles/resourcemanager.projectCreator` の付与方法は前回の記事に書いています。

https://qiita.com/ysmmb12/items/8d2283878a4eb427b976#google-cloud-%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E6%BA%96%E5%82%99

### CloudStorage バケットの準備
Terraform テンプレートを配置する CloudStorage バケットを用意します。
テンプレートファイルのバージョニングをするように、オブジェクトのバージョニングを有効にしてバケットを作成します。

### Terraform テンプレートの準備
テンプレートのサンプルが公開されているので、こちらを参考にしました。

https://github.com/terraform-google-modules/terraform-google-network/tree/master/examples/simple_project

前回のテンプレートファイルより3ファイルを作成しました。
前回から変わった点は、
 - Terraform Cloud ワークスペースの指定の削除
 - 認証情報の指定の削除
 - 変数宣言とデフォルト値の設定を variable.tf 内で実施

``` main.tf
resource "google_project" "new_project" {
  name       = "<Project Name>"
  project_id = "<Priject ID>"
  org_id     = var.org_id
}
```

``` version.tf
terraform {
  required_providers {
    google = {
      source = "hashicorp/google"
      version = "4.51.0"
    }
  }
}
```

``` variable.tf
variable "org_id" {
  type      = string
  default   = "<Organization ID>"
}
```

前述で作ったバケットに任意のフォルダ（今回は `src` フォルダ）を作り、そこにこの3ファイルを配置します。

### Infrastructure Manager の実行
Cloud Shell より以下コマンドを実行します。

```
gcloud infra-manager deployments apply projects/<Project Name>/locations/asia-east1/deployments/my-depolyment \
    --service-account projects/<Project Name>/serviceAccounts/<Service Account Name> \
    --gcs-source gs://<Bucket>/src
```

記事作成時点でコマンドに指定できるリージョンは `asia-east1`, `europe-west1`, `us-central1` の3つのみです。
なので今回は `asia-east1` を指定しました。

https://cloud.google.com/infrastructure-manager/docs/locations

### デプロイ後の状態を確認する
デプロイ実行のステータスや作成されたリソースを見るにはコマンドを実行します。
ちなみに Infrastructure Manager のメタデータは `gs://PROJECT_ID-LOCATION-blueprint-config` というバケットに配置されるとのことですが、デプロイ実行ユーザーでもアクセス権限がなく、どういうファイルがあるのかは確認できませんでした。

https://cloud.google.com/infrastructure-manager/docs/deployments-revisions

#### デプロイ実行のステータスの確認
コマンド
``` 
gcloud infra-manager deployments describe projects/<Project Name>/locations/asia-east1/deployments/my-depolyment
```

結果
```
createTime: '2023-12-04T06:07:43.895650003Z'
latestRevision: projects/<Project Name>locations/asia-east1/deployments/my-depolyment/revisions/r-0
lockState: UNLOCKED
name: projects/<Project Name>/locations/asia-east1/deployments/my-depolyment
serviceAccount: projects/<Project Name>/serviceAccounts/<Service Account Name>
state: ACTIVE
stateDetail: revision "projects/<Project Name>/locations/asia-east1/deployments/my-depolyment/revisions/r-0"
  applied
terraformBlueprint:
  gcsSource: gs://<Bucket>/src
updateTime: '2023-12-04T06:08:45.675848249Z'
```

### 作成したリソースの確認
コマンド
```
gcloud infra-manager resources list --revision=projects/<Project Name>/locations/asia-east1/deployments/my-depolyment/revisions/r-0
```

結果
```
NAME: project-<任意の文字列>
STATE: RECONCILED
```

結果の `NAME` は Terraform テンプレートで指定した名前とは違う文字列でした。
試しに Infrastructure Manager で BigQuery データセットを作成し `NAME` を確認すると Terraform テンプレートで指定した名前ではなく `bigquery-dataset-<任意の文字列>` となっていました。
なのでここに表示されるのは内部で管理するための名前と思われます。


## Terraform Cloud と比べてみて（感想）
個人開発・単発 or 短期運用なら Infrastructure Manager、チーム開発・長期運用なら Terraform Cloud がよさそう、というのが感想です。

### Infrastructure Manager のほうが良いと思った点
#### サービスアカウントの鍵管理が不要になる！
前回の記事ではサービスアカウントの鍵を発行して Terraform テンプレートや変数に使っていますが、Infrastructure Manager であればサービスアカウントに必要なロールを付与すればOKです。
情報漏洩のリスクや鍵のローテーション云々を気にしなくてよいというメリットがあります。

#### Google Cloud 専用なので、テンプレートや連携などがシンプルになる
Infrastructure Manager は Google Cloud の中で閉じているので、テンプレートがプロバイダー中心のシンプルなものになります。
また、個人的に負荷が高いサービス間の連携設定が不要になるため、使い始めてからデプロイ完了までがスムーズでした。

### Terraform Cloud が良いと思った点
#### Github のプライベートリポジトリが使える
Infrastructure Manager のテンプレート配置先が、CloudStorage、Github のパブリックリポジトリ、ローカルマシンの3種類が用意されています。
わたしの場合、チームでテンプレートの管理をしたいので Github を使いたいのですが、会社のデータを含むテンプレートファイルをパブリックリポジトリで扱うことはできません。
なので Github のプライベートリポジトリを使える Terraform Cloud のほうがわたしのユースケースに合っていました。

#### 変数の管理が秘匿状態でできる
プロジェクト作成のプロバイダーは組織IDを指定しますが、IDをそのままテンプレートファイルに記載したままになるのがセキュリティ観点で気になるため、Terraform Cloud のように簡単に見えない状態で保持したいです。
（秘匿したい情報を Terraform に置く是非もあるかと思いますが）



以上です。どなたかの参考になれば幸いです。