Terraformを用いたインフラのコード化

# はじめに
こんにちは！株式会社80&Companyの技術広報です。
弊社の開発部署では毎週火曜日の朝9:30から社内勉強会を行なっています。

今回の記事はSRE業務を行なっているエンジニアが社内勉強会で「**Terraform**を用いたインフラのコード化」について発表したものを紹介します。
SREを簡単に説明すると、Google社が提唱・実践した概念で、「サイト・リライアビリティ・エンジニア（**Site Reliability Engineer**）」の略称です。
サービスやプロダクトの信頼性の向上を図り、エンジニアが開発と運用の両方に携わることによって自動化・効率化し、企業の課題を解決する役割と言われています。

SREエンジニアが発表した**Terraform**を用いたインフラのコード化について、興味のある方は参考にしてみて下さい♪

# 読者の対象
* **Terraform**に興味がある方
* **Terraform**の導入を検討している方

# Terraformとは？ざっくり概要
**Terraform**は **IaC(Infrastructure as Code)** を実現するツールです。 
**IaC(Infrastructure as Code)** とは、直訳すると「コードとしてのインフラ」という意味です。

サーバーやネットワークといったインフラの構成をプログラムのコードで書いて、書いたコードを元にインフラを構築します。
これまで、手動で行なっていたインフラの初期プロビジョニング、更新、削除などの作業をいずれもコードにより宣言し、実行することができます。


# Terraformの機能イメージ
インフラの構成をコードで宣言する仕組みがあります。
下記の画像が全体のイメージ画像です。`.state` `.tfvars` `.tf`といった拡張子のファイルが**Terraform**用のファイルです。
このファイルでコードを書き、**Terraform**のSDKを介して、**Terraform**がAWS、GCPのAPIを叩きます。

![スクリーンショット 2023-02-09 11.37.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3059557/5b4bd69c-69bc-6eb1-e846-afa70e6a75c9.png)


## 基本ファイル
**Terraform**用のファイルで紹介した`.tfvars` `.tf`といった拡張子のファイル記述を一部記載し、紹介します。

* main.tf
    * AWSプロバイダー情報(IAM情報・リージョン)を記載
```main.tf
provider "aws"{
    version = "~>2.0"
    region = "${var.provider_region}"
    profile = "s3-demo"
}

variable "provider_region" {}
```
* env.tfvars
    * .envのようなイメージで環境ごとに異なる値を設定
    * 上記`main.tf`の`region = "${var.provider_region}"`の`provider_region`の値を定数に与える
```env.tfvars
provider_region = "ap-northeast-1"
```
* s3.tf
    * リソース情報を記載するファイル。今回はAWS S3を作成する
```s3.tf
resource "aws_s3_bucket" "main"{
    bucket = "study_demo"
}
```
## コマンド紹介
### 基本的なコマンド
**Terraform**を扱うにあたり、適切なコマンドを打ちリソースを作成/修正/削除する必要があります。
その際に、代表的なコマンドを4つ紹介します。
#### terraform init
ワークスペースを初期化するコマンドです。
**Terraform** を実行するためには、1番初めに**terraform init**でワークスペースを初期化します。
**terraform init** を実行すると、`.tf`ファイルで利用しているプラグインのダウンロード処理が走ります。
#### terraform plan
今後の**Terraform**実行計画を確認することができるコマンドです。
`.tf` ファイルに記載された情報を元に、どのようなリソースが作成/修正/削除されるかを参照することが可能です。
#### terraform apply
ファイルを元にリソースを作成/修正/削除するコマンドです。
#### terraform destroy
これまでに作成されたインフラの削除を行うコマンドです。
このコマンドを実行するときは、最大限注意を払う必要があります。

### その他のコマンド
上記では紹介されていない、その他のコマンドについて紹介します。
#### terraform show
`terraform.state` ファイルを元にして、現在のリソースの状態を参照します。

#### terraform console
関数や記述の確認などを行うことができ、デバックに用いることができます。

#### terraform validate
コマンドを入力して、構成が有効かどうかを確認します。

#### terraform fmt
**Terraform** 構成を標準スタイルに再フォーマットします。

#### terraform import
**Terraform**以外の手段で既に作成したリソースをインポートし、取り込みます。

#### terraform force-unlock
定義された構成の状態を手動でロック解除します。
インフラストラクチャが変更されることはありません。

#### terraform get
ルートモジュールに記載されているモジュールをダウンロードして更新します。

#### terraform graph
構成、実行計画の視覚的表現(グラフ)を生成するために使用します。

#### terraform output
状態ファイルから出力変数の値を抽出するために使用します。

#### terraform providers 
各要件が検出された場所を理解するのに役立つように、現在の作業ディレクトリ内の構成のプロバイダー要件に関する情報を表示します。

#### terraform refresh
**Terraform**が状態ファイルを通じて認識している状態と実際のインフラストラクチャとを整合させるために使用します。

#### terraform taint
特定のオブジェクトが劣化または損傷したことを**Terraform**に通知します。

#### terraform untaint
特定のオブジェクトが劣化または損傷したことを**Terraform**に通知します。

#### terraform version
**Terraform**のバージョンを出力します

#### terraform workspace
ワークスペースを用いるために使用されます。


# Terraformを導入することのメリット
* バージョン管理ができる
  * Gitなどでバージョン管理することでインフラのデプロイと変更を追跡することができるようになる
  * 履歴から以前のインフラ構成に戻すことも可能である
* インフラ構成の複製や使い回しができる
  * コード化されているため同等の環境を簡単に作成できる
  * ステージング/本番環境など、（ほぼ）同一の環境を再現する際に便利
* 複数のクラウドプロバイダーとの同時作業
    * **Terraform**は AWS、Microsoft Azure、Kubernetesなどマルチプラットフォームに対応しているため、サービスとの連携により、マルチプラットフォームでリソースを同時に管理することができ、便利な状況を作ることができる

# Terraformを導入することのデメリット
* 学習コストがかかる
    * **Terraform**は、**Terraform**独自のコードで書く必要があるが、最近はGoやPythonなどのユーザーが普段使用しているコードでも同じ様なことができる仕組みがあるため、**Terraform**だけのために勉強する必要が出てくる


# 追記
今回は**Terraform**の概要と基本のコードを紹介しましたが、コードのより高いメンテナンス性や、複数人での開発が必要になってきた場合、**Terraform**コードのアーキテクチャと**Terraform**実行差分の管理要件も考える必要があります。


# 最後に
今回は、弊社社内勉強会で発表された「**Terraform**を用いたインフラのコード化」について扱いました。
今後も継続的に80&Companyでの社内勉強会の取り組みを発信していきます！
[Qiita Organization](https://qiita.com/organizations/80andco)や[Twitter](https://twitter.com/80andcoDev)公式アカウントのフォローもよろしくお願いいたします！
最後まで読んでいただきありがとうございます！


# 参考文献
https://rabiloo.com/ja/blog/infrastructure-terraform

https://developer.hashicorp.com/terraform