【GCP & Terraform】【入門編③】Terraformモジュールの操作

# 前回
【GCP & Terraform】【入門編①】terraform使用でのGCP仮想マシン作成
https://qiita.com/SHA_AKA/items/86bf08e9cf35c3b7fd6f
【GCP & Terraform】【入門編②】Terraformの依存関係とVPCの構成
https://qiita.com/SHA_AKA/items/77125c7460e73a29de1b


# 今回の目標
1. Terraform モジュールとは
2. モジュールを使用して構成ファイルを作成
3. 実装結果


## 1. Terraform モジュールについて
Terraform でインフラの管理を続けると、段々構成が複雑になってきます。
下記の問題が発生する可能性が高いです。
・構成ファイルmain.tfの管理が難しくなる。
・1 つのリソースブロックを更新すると他のブロックに想定外の影響が及ぶ可能性があるため、構成の更新に伴うリスクが高くなる。
・開発環境と本番環境の管理が混乱になる。
・プロジェクト間またはチーム間の共同開発・運用・メンテナンスのコストが高くなる。

こちらの問題点を対応するため、モジュールが利用できます。
Terraform 構成ファイル.tfを 1 つのディレクトリ内に集めたものが、一つ以上のモジュールです。
例えば、Terraform モジュールのディレクトリが下記のようになります。
```
|--main.tf
|--variables.tf
|--modules
|  |--gcs-static-website-bucket
|  |  |--LICENSE
|  |  |--README.md
|  |  |--main.tf
|  |  |--outputs.tf
|  |  |--variables.tf
|  |--vm-instance
|  |  |--LICENSE
|  |  |--README.md
|  |  |--main.tf
|  |  |--outputs.tf
|  |  |--variables.tf
```

上記の例、ルードディレクトリの構成ファイルがmain.tf、二つのモジュールgcs-static-website-bucketとvm-instanceが存在しています。
それぞれのファイルについて：
<dt>LICENSE</dt> 
<dd>モジュールを配布する際のライセンスが記載される。モジュールを共有する際に、このLICENSEファイルによってモジュールの使用者に利用条件を知らせることができる。Terraform にはこのファイルを使用しないです。</dd>
<dt>README.md</dt>  
<dd> モジュールの使用方法を説明するためのMarkdown形式で記載されているドキュメントです。Terraform はこのファイルを使用しないです。</dd>
<dt>main.tf</dt>
 <dd>モジュールの構成の主要な部分が含まれるファイルです。その他の構成ファイルを作成し、プロジェクトに合うように構成ファイルを整理することもできる。</dd>
<dt>variables.tf</dt>
 <dd>モジュール用の変数定義が含まれるファイルです。他の人がこのモジュールを使用する際、各変数はモジュールブロック内の引数として構成される。Terraform ではすべての値を定義する必要があるため、デフォルト値を持たない変数はすべて必須の引数になる。デフォルト値がある変数は、モジュール引数として指定することもできます。</dd>
<dt>outputs.tf</dt>
 <dd>モジュールの出力の定義が含まれるファイルです。モジュールの出力を、モジュールで定義されたインフラストラクチャの各部分に関する情報を構成の他の部分に渡すために使用される</dd>

その他、terraform.tfstate、.terraformまたは.tfvarsのファイルもありますが、それらの説明今回は割愛させていただきます。


## 2. モジュールによりインフラを構築する
上記と同じ構造で、バケットおよびインスタンスの構成を実装しようと思います。
/gcs-static-website-bucket/variables.tfに下記の内容を追加します。
```
variable "name" {
  description = "作成するバケットの名前"
  type        = string
  default     = "一意のバケット名前"
}
variable "project_id" {
  description = "バケットを作成するプロジェクトの ID"
  type        = string
  default     = "projectid"
}
variable "location" {
  description = "バケットの場所"
  type        = string
  default     = "asia-northeast3"
}
variable "bucket_policy_only" {
  description = "バケットに対するバケット ポリシーのみのアクセスを有効にする"
  type        = bool
  default     = true
}
variable "versioning" {
  description = "true に設定すると、バージョニングがこのバケットで完全に有効になる"
  type        = bool
  default     = true
}
variable "force_destroy" {
  description = "バケットを削除する際、含まれているすべてのオブジェクトが削除されるかどうかがこのブール値オプションで決まる。false の場合、Terraform はオブジェクトが含まれているバケットを削除できない。"
  type        = bool
  default     = true
}
```
/gcs-static-website-bucket/main.tfに下記の内容を追加します。
```
resource "google_storage_bucket" "bucket" {
  name               = var.name
  project            = var.project_id
  location           = var.location
  force_destroy      = var.force_destroy
  versioning {
    enabled = var.versioning
  }
}
```

次に、/vm-instance/variables.tfに下記の内容を追加します。
```
variable "project_id" {
  description = "projectid"
  default     = "shadev2022"
}

variable "name" {
  description = "インスタンスの名前"
  default     = "instance1"
}

variable "machine_type" {
  description = "machine_type"
  default     = "n1-standard-1"
}

variable "zone" {
  description = "zone"
  default     = "asia-northeast1-c"
}

variable "image" {
  description = "image"
  default     = "debian-cloud/debian-9"
}
```
/vm-instance/main.tfに下記の内容を追加します。
```
resource "google_compute_instance" "instance" {
  project      = var.project_id
  name         = var.name
  machine_type = var.machine_type
  zone         = var.zone
  boot_disk {
    initialize_params {
      image = var.image
    }
  }
  network_interface {
    network = "default"
    access_config {
    }
  }
}
```
最後は、~/main.tfに下記の内容を追加します。
```
module "gcs-static-website-bucket" {
  source = "./modules/gcs-static-website-bucket"
  }

module "vm-instance" {
  source = "./modules/vm-instance"
  }
```
`` module "モジュールフォルダ名" ``によりモジュールを指定できます。
ここまで構成ファイルの作成が完了しました。

## 3. 実装結果
コマンド`` terraform init ``およびコマンド`` terraform apply ``で実行するします。
結果が下記のようになります。
```
module.gcs-static-website-bucket.google_storage_bucket.bucket: Creating...
module.vm-instance.google_compute_instance.instance: Creating...
module.gcs-static-website-bucket.google_storage_bucket.bucket: Creation complete after 1s [id=<projectid>]
module.vm-instance.google_compute_instance.instance: Still creating... [10s elapsed]
module.vm-instance.google_compute_instance.instance: Creation complete after 13s [id=projects/<projectid>/zones/asia-northeast1-c/instances/instance1]
```

# リソースの削除および次回
コマン`` terraform destroy ``を実行すると、今回構成したリソースをすべて削除されます。
次回ではTerraform Stateについて話をしたいと思います。