Terraform入門 その1 リソース作成まで

# 1.Terraformとは
IaCの一種で、Codeでインフラを管理するものです。
AWSのCloud Formationも同様で、コードでインフラ管理するものですが、Terraformは、さまざまなサービスをプロバイダーとして管理できるため、技術要件だったりで別のクラウドサービスの環境をする場合でも、自社内でTerraformで一括管理できていれば、融通がかなりききます。

## メリット
コードで管理することで以下のメリットがあります。
### 開発／本番　などの環境下で同じ環境を構築したい時
### インフラの構成を明確に残しておきたい
### 人的ミスを限りなく無くせる

## デメリット
前述のCloud Formationは、JSON/YAMLで記述する一方で
HCPという独自のコードのため、多少初期学習コストがかかることが挙げられます。

# 環境構築
私はM2 Macのため、以下のサイトを参考にして構築しました。
brewでインストールしています。とても簡単です

https://zenn.dev/take_tech/articles/32188cd3607721

# ハンズオン
最初のハンズオンは以下のYoutubeをお勧めします。

https://www.youtube.com/watch?v=iR1MDGE2aL8

理由としては、のちにTerraformを勉強してくると、
```.tfvars```ファイル
```.versions```ファイル
```.variables```ファイル

という便利な設定ファイルを扱うのですが、これを先にやるよりかは
```main.tf```ファイルという主な開発を記述するファイルにべた書きで最初は書いた方がいいので、一旦は上記のリンクのハンズオンをお勧めします。

# Terraformの流れ

まずは、開発を行うディレクトリを作成し、移動してメインのファイルを作成しましょう。
```
mkdir workspace
cd workspace
touch main.tf
```
作成した```main.tf```に以下のように記述しましょう。

```tf
# main.tf
provider "aws" {
  region = "us-east-1"
}
```
この１つの塊を「ブロック」と呼びます。
上の例だと、プロバイダーはどこかをTerraformに教えています。


この次に、```terraform init```を実行し、初期化を行います。
そうすると、```main.tf```配下に１のフォルダと１つのファイルが生成されていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/81eeace6-ccaa-4fb3-8b13-daa2c2bc123e.png)

```.terraform```配下の```providers```フォルダの中身を辿っていくと、AWSプロバイダーの情報が記載されています。
この情報を元に、TerraformとAWSがAPIで連携し、サービスを構築していく流れになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/3eee4ba1-e6e3-448a-a969-250f34527f7d.png)

バージョンが記載されているので、お察しすると、このバージョン管理も非常に重要です。
```versions.tf```ファイルを設定してあげることで、バージョンを固定してあげることができます。
また、開発するリージョンなども固定したいので、```main.tf```で記載したリージョンも一緒に記載してあげましょう。
これでチーム開発でメンバーが同一AWSプロバイダーのバージョンを扱うことができるようになります。
```tf
# versions.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.98.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

```

実際に、```main.tf```を完全に空にした状態で、```versions.tf```だけを記述して
他のフォルダやファイルを削除してみて再度```terraform init```すると、正常に初期化でき、プロバイダーのフォルダも生成されます。

```.terraform.lock.hcl```フォルダを見てみると、設定したバージョンが記載されていると思います。
```hashes```という変数には、ハッシュ値が記載されています。
これは、Terraformで開発した内容を他と共有する際に、全く同じの状態かを確認できるようにするためのものです。これで、開発環境の一貫性が保たれているといった流れになります。


次に、実際にAWSでVPCの構築とその中で、サブネットの構築もしていきます。このような設定は、
```main.tf```に記載していきます。

```tf
# main.tf
resource "aws_vpc" "terra_vpc" {
  cidr_block = "10.0.0.0/16"
  tags = {
    Name = "aws_vpc_handson"
  }
}

resource "aws_subnet" "terra_subnet" {
  vpc_id = aws_vpc.terra_vpc.id

  cidr_block = "10.0.0.0/24"
  tags = {
    Name = "aws_subnet_name"
  }
}
```

これは、resourceブロックと言います。
```"aws_vpc"```といったresourceの次に記載するものは、あらかじめTerraformで決まったお作法であり、awsでvpcを構築したい場合は必ずこのように記載します。
別名をつけることもできます。その際はスペースを入れて記載してあげることで、ファイル内で別名で管理することができます。

サブネットを構築する際は、VPCのIDというものが必要です。
Terraformはとても便利で、上記のように記載してあげることで、idを特定することができます。

こちらを記述できたら、
```terraform plan``` と実行
terraform planで以下のようにVPCとサブネットを作成するので、2 to addとなってます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/b96fe795-9f02-424b-b98e-24d29bca535d.png)

planの内容が問題なければ、```terraform apply```をすることで、リソースが生成されます。

その後に```terraform.tfstate```というファイルが作られていると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/00a313a2-508b-41fa-9a52-4033c8e33b8d.png)

中身をみると、main.tfで記載した設定情報が記載されています。
これを元に、```.terraform.lock.hcl```ファイル内のハッシュ値が生成されています。

リソースの削除はとても簡単です。記述したmain.tfファイルをコメントアウトして、
```plan```コマンドを実行するだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/2a7c9428-c050-44ba-b73f-0564dc1a31c4.png)

そうすると、次は、2 destroyとなります。２つのリソースが削除されると言っていますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/ce4b700d-9e27-4a67-bc0e-414aa9810e86.png)

問題ないので、```apply```コマンドを適用します。
これで削除するともできました。

# まとめ

次の記事では、```main.tf```ファイルで、直接CIDRなどを記載しましたが、この値が不変だったり、よく使われる値であれば、```terraform.tfvars```を使ってあげることで、変数として扱うこともできます。

次はもっとTerraformをふかぼれればと思います。