Terraformの環境別の書き方

Terraformを用いて開発環境や本番環境などの環境毎の記載方法について、フォルダ構成等の記事になります。Google Cloud Platform(GCP)を対象としております。

# Terraformとは
HashiCorp社により提供している、クラウド等のインフラ構築や様々な設定をコード化、自動化するためのツールです。インフラ設定の管理を容易にすることが出来ます。
[Terraform](https://www.terraform.io/)


# 環境構築
### 準備するもの
- システムを構築するクラウドサービスのプロジェクト（今回はGCP）
- クラウドサービスのアカウント
- 端末（MacBookPro等のShellが実行出来るもの）

### GoogleCloudSDKのインストールと認証
対象のクラウドサービスがGCPなので、GoogleCloudSDKのインストールと認証を行います。
※今回はTerraformの記事なので省略させて頂きます。

[macOS 用のクイックスタート](https://cloud.google.com/sdk/docs/quickstart-macos)


### Terraformのインストール
Terraformは、Versionによって記述の仕方が変わる事があるため管理が出来るように、tfenvを使用してインストールしていきます。
以下の手順をターミナルで実行していきます。
##### tfenvをインストール

```bash
$ brew install tfenv
```

##### terraformの0.13.2をインストール

```
$ tfenv install 0.13.2
[INFO] Installing Terraform v0.13.2
[INFO] Downloading release tarball from https://releases.hashicorp.com/terraform/0.13.2/terraform_0.13.2_darwin_amd64.zip
######################################################################### 100.0%
[INFO] Downloading SHA hash file from https://releases.hashicorp.com/terraform/0.13.2/terraform_0.13.2_SHA256SUMS
tfenv: tfenv-install: [WARN] No keybase install found, skipping OpenPGP signature verification
Archive:  tfenv_download.rIO5YW/terraform_0.13.2_darwin_amd64.zip
  inflating: /usr/local/Cellar/tfenv/1.0.2/versions/0.13.2/terraform  
[INFO] Installation of terraform v0.13.2 successful
[INFO] Switching to v0.13.2
[INFO] Switching completed
```
 
##### versionの確認

```
$ terraform -version
Terraform v0.13.2
```

# Terraformのファイル作成
### フォルダ構成
書き分けは以下になります。
環境ごとの設定：env1、env2
共通部分の設定：modules

```
.
├── env1
│   ├── main.tf
│   └── variables.tf
├── env2
│   ├── main.tf
│   └── variables.tf
└── modules
    ├── config.tf
    └── storage.tf
```

### ファイルの説明
##### 環境ごとの設定
providerに、環境構築先のプロジェクト設定を記述します。
moduleに、共通部分に渡す変数を記述します。

```main.tf
provider "google" {
  project = var.project
  region  = var.region
}

module "env1" {
  source = "./../modules"

  ## variables
  region  = var.region
  storage = var.storage
}
```

```variables.tf
# project
variable "project" {
  default = "{プロジェクト名}"
}

variable "region" {
  default = "asia-northeast1"
}

# storage
variable "storage" {
  default = "{bucket名}"
}
```

##### 共通部分の設定
terraformのVersionを0.13以上に制限します。

```config.tf
terraform {
  required_version = ">= 0.13"
}
```
bucket名とリージョン、ローケーションタイプを記述します。

```storage.tf
# variables
variable "storage" {}
variable "region" {}

resource "google_storage_bucket" "sample" {
  name          = var.storage
  location      = var.region
  storage_class = "REGIONAL"
}
```

### 実行方法
環境の構築をする際は、構築先の設定ファイルがあるフォルダに移動して実行します。
env1に構築をする場合は、env1ディレクトリに移動します。

```
$ cd env1
```
状態を管理するstateファイル作成のため、初期化を行います。
env1ディレクトリにterraformのディレクトリが作成されます。

```
$ terraform init
```
terraformの記述が正しいかチェックを行います。

```
$ terraform plan
```
terraformで環境の構築を行います。

```
$ terraform apply
```

# 複数人で同じプロジェクトを使用する場合
stateファイルをGCSに保存する事で同じファイルを使う事が出来ます。
main.tfに以下を追加する事で、保存先を指定します。

```
terraform {
  backend "gcs" {
    bucket = {保存先のbucket名}
  }
}
```

# 所感
Terraformを使いコード化する事で、手作業が減らせる事と設定の管理が容易にする事が出来ます。今回は、変数が使用するサービスの設定だけなので暗号化はしていないですが、認証情報などの場合はCloud KMSなど使用する事で容易に暗号化する事が出来ます。
Terraformでコード化する時の注意点として、クラウドサービスの中には1度設定すると変更出来ないものや削除出来ないものもあるので、構築する際は対象となるものがTerraformで扱いやすいかを調べる必要があります。