組織用のGCPアカウントを作ってTerraformで管理を始めました

# はじめに
そろそろ弊社でもしっかりGCPを利用していこうと考え、組織用のGCPアカウントを作成しました。
またガバナンスを効かせるため、組織、フォルダ、プロジェクトの管理をTerraformで一元管理していく方針をたてました。
その際に、どういった点を検討すべきなのか、どう判断したかを書いています。

# GCPの組織を何で管理するか？
[公式ドキュメント](https://cloud.google.com/docs/enterprise/setup-checklist)を確認します。ドキュメントが素晴らしい。

**Cloud Identity と組織**を確認すると、いくつか選択肢が記載されています。
弊社は現時点でGoogle Workspaceを利用していないので、 **Google Identity Free Edition**を利用します。
すでにGoogleWorkspaceを利用されている方は、Workspace上でGoogle Identityを有効にするようです。
**Free Edition**ではデフォルトで50ユーザーライセンスが提供されています。（2022/12現在）

# GCP用の組織をGoogle Identityで作成する
公式チェックリストにある、**「最初のCloud Identityアカウントと特権管理者ユーザー名を作成します。」** をクリックして作成に進みます。
![GoogleIdentityアカウント作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/dcc94851-0886-bfb5-c427-d0d9f3afbcd0.png)

## Cloud Identityの作成
では、実際に作成していきます。

1. 組織情報を入力して[次へ]をクリックします。
![組織情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/dc27974f-37a2-e6bf-650b-262a257de5fd.png)
1. 特権管理者ユーザーの情報を入力[次へ]をクリックします。
![管理者情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/bac2a5a2-6eb9-9e97-0d63-62b8a0d358dd.png)
1. 組織で利用するドメイン情報を入力して、[次へ]をクリックします。  
![ドメイン情報.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/0529f45a-008d-35e3-1b99-15347a87511b.png)
1. 入力したドメイン情報に誤りがないか確認して、[次へ]をクリックします。
![ドメイン確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/0009ff80-ac93-5873-cf77-caf14c31bbb3.png)
1. お知らせを受け取るか選択して、[次へ]をクリックします。
![お知らせ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/09a9a4a6-0025-2c52-89e5-e31e2ebc940a.png)
1. 特権管理者ユーザーのアカウント情報を入力して、[同意して続行]をクリックします。
![ログイン情報入力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/42c068a2-e9f0-6405-7531-0c1850b333bc.png)
1. 組織が作成されました。
![作成完了.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/0f31ba07-7c79-be28-36af-d20999555d37.png)

## 組織ドメインの保護
指定の**TXTレコード**、もしくはCNAMEを登録することで、ドメインの所有権を確認し、他のユーザーに不正に利用されないようにします。（ドメインを保護しないと組織は利用できません）
弊社の場合、ドメインは親会社で管理しているため、設定までリードタイムが必要でした。

**注意** ドメイン保護については設定から**14日以内**での設定が必要です。最悪の場合アカウントが削除される可能性があるとのことなので、早めに対応しましょう。

TXTドメインの設定が反映されると、ドメイン保護が完了し、利用可能になりました。
これで作成した組織でGCPが利用可能になります。
![ドメイン保護完了.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/0730a6bd-3a6a-4507-7b92-8db982b1cdcb.png)


# GCP上の組織とフォルダについて
弊社では今後サービス提供、社内利用それぞれが干渉しないようにする必要があるため、Googleの[公式ページ](https://cloud.google.com/resource-manager/docs/creating-managing-folders?hl=ja)を参考にフォルダ構成、プロジェクト構成で設計をしました。
これをもとに、Terraformでフォルダを作成していきます。
![設計.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/8b5b3306-65f1-9193-471a-559c07e4f550.png)

# Terraformでフォルダを管理する
今後、AWS、Azure、など他のクラウドも同様のレベルで管理をしていきたいという方針を持っているため、Terraformでの管理を進めていこうと考えています。

## 事前設定
1. Terraform State管理用のフォルダとプロジェクトの作成
    - GCS(Google Cloud Storage)でTerraformのstateを管理するため、まず手動でstate管理用のフォルダ、プロジェクトを作成します
    - GCSのメニューからバケットを作成します
1. サービスアカウントの設定
    - GCSへの操作権限を付与する
    - フォルダ、プロジェクトの作成権限を付与する

## ローカル環境設定
CI/CD環境は今後整備をすすめるため、まずはローカルからデプロイできる状況を作ります。
設定手順は[公式の手順](https://cloud.google.com/sdk/docs/install?hl=ja)を参考に進めています。（MacOSを前提としています。）

1. gcloud CLIのインストール
    ```shell
    cd /usr/local/bin
    curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-410.0.0-darwin-arm.tar.gz
    tar xvzf google-cloud-cli-410.0.0-darwin-arm.tar.gz
    ./google-cloud-sdk/install.sh
    ```
    ※対話モードでの設定は、全てデフォルトにしています。
    ※バージョンは公式手順から最新のパッケージのURLを確認してください。

1. gcloudの初期設定
    ```shell
    ./google-cloud-sdk/bin/gcloud init
    ```
    - ここでgoogle chromeが立ち上がり、該当のgoogleアカウントでログインを行い、アクセス許可を行う
    - **Pick cloud project to use:** と表示されるので、デフォルトのプロジェクトIDを選択して終了する。

1. gcpへのログイン
    ```shell
    gcloud auth application-default login
    ```

## Terraformコード作成
1. Terraformの[Standard Module Structure](https://developer.hashicorp.com/terraform/language/modules/develop/structure)を参考に簡単なモジュールを作成していきます。
    ```shell:フォルダ構成
        .
        ├── envs
        │   ├── backend.tf
        │   ├── main.tf
        │   ├── outputs.tf
        │   ├── providers.tf
        │   └── variables.tf
        └── modules
            └── folders
                ├── README.md
                ├── main.tf
                ├── outputs.tf
                └── variables.tf
    ```
    
    ```terraform:modules/folders/main.tf
    resource "google_folder" "folders" {
      count        = length(var.names)
      display_name = var.names[count.index]
      parent       = var.org_name
    }
    ```    

    ```terraform:envs/providers.tf
    provider "google" {
      project = "project_id"
      region  = "asia-northeast1"
    }
    ```

    ```terraform:envs/backend.tf
    terraform {
      backend "gcs" {
        bucket = "bucket_name"
      }
    }
    ```

    ```terraform:envs/main.tf
    data "google_organization" "org" {
      domain = "domain.com"
    }
    
    locals {
      names = [
        "Corporation", //会社内利用
        "Services"     //サービス提供用
      ]
    }
    
    module "folders" {
      source   = "../../modules/folders"
      names    = local.names
      org_name = data.google_organization.org.name
    }
    
    ```    


1. Terraformコマンドを実行してデプロイ
    ```shell
    cd envs
    terraform init  //　初期化
    terraform plan  // plan
    terraform apply // デプロイ
    ```
1. GCPのコンソールを確認すると、無事作成されました！
![フォルダ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129073/70537579-cb3a-7a93-a6ae-8d1a6d767b79.png)


# まとめ
- CloudIdentityを利用する場合には、ドメインへのTXTレコード反映のリードタイムを事前に確認しておくと安心です。
- 環境が整いつつあるので、今後弊社において、GCPの利用実績がどんどん増えていくと思います。