Terraform コトハジメ

# はじめに

Terraformを利用する前に準備しておくとよいことをまとめました。
環境はWindows10を前提としています。

# VSCodeをインストールしておく

今となっては当たり前かもしれませんが、まずは **「Visual Studio Code」** をインストールしましょう。
間違ってもサクラエディタとかでコーディングしないほうがよいです。(できますが、VSCodeでやったほうが圧倒的に効率的ですし便利です)

インストール方法はただインストーラーを実行するだけなので省略します。

# Terraformのインストール

早速terraform をインストールしてきましょう。

https://www.terraform.io/downloads

からWindows用Terraformをダウンロードします。
ダウンロードできたらzipを解凍し、exeを適当なところに配置しましょう。
ここでは仮に以下におきます。

```
C://terraform/
```

あとはパスを環境変数にセットすればOKです。

```
terraform version

Terraform v1.2.9
on windows_amd64
```

こんな感じに表示されればOK。

# tflintをインストールする

tflintを実行すると、構文やパラメータがルール違反していないか確認してくれます。便利ツール。

https://github.com/terraform-linters/tflint/releases

こちらからWindows版を探してダウンロードしましょう。
あとはTerraform.exeと同じディレクトリに入れときます。
この記事を書いた時点では、Windows版はv0.40.0が最新でした。

# VSCodeの拡張機能をインストールする

HashiCorpが提供している拡張機能をインストールしましょう。
これによってよりTerraformコードを書くのが簡単になります。

https://marketplace.visualstudio.com/items?itemName=HashiCorp.terraform

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626338/d8724a03-fa85-105f-907f-664116f57f60.png)


# 適当なディレクトリを作る

Terraformを利用する上でのディレクトリ構造は好みが分かれるところですが、一般的には以下のように構成しておけばよいと思います。

``` 
-- terraform
    -- env
        -- dev
            -- main.tf
            -- variables.tf
            …
        -- prod
            -- main.tf
            -- variables.tf
            …
    -- module
        -- service name(vnetなど)
            -- main.tf
            -- variables.tf
            -- output.tf
            …
        …
```

こうしておくと、各環境ごとにそれぞれ呼び出すモジュールの定義を入れることができます。
まぁここでは難しいことは考えず、そのまま作っておきましょう！

# 使ってみる

ではterraformを利用して適当にリソースを作ってみます。
私はAzureをよく利用するので、ここでのサンプルはAzure providerを利用して行います。
リソースグループを生成し、vNetを生成します。

参考はこちら。

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs

早速dev/main.tfに以下のサンプルコードを書いてみます。

```

terraform {
  #  tflintテストのためコメントアウト
  #  required_version = "1.2.9"
  backend "local" {}
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.23.0"
    }
  }
}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "resource_group" {
  name     = "rg_terraform-001"
  location = "japaneast"
}

resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-terraform-dv-001"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.resource_group.location
  resource_group_name = azurerm_resource_group.resource_group.name

}

```

ここでtflintをコマンドプロンプトから実行してみましょう。
```
tflint

1 issue(s) found:

Warning: terraform "required_version" attribute is required (terraform_required_version)

  on  line 0:
   (source code not available)

Reference: https://github.com/terraform-linters/tflint-ruleset-terraform/blob/v0.1.0/docs/rules/terraform_required_version.md

```

**「利用するTerraform Versionを指定しなさい！」** って怒られましたね。
動作確認ができたので、コメントアウトしたところを解除しておきます。

Azureでテストする場合は、ここでaz loginをしておきます。
そうすると認証情報などはTerraformには入力せずとも、az loginで利用したアカウント情報でTerraformを実行してくれます。


まずは

```
cd C://terraform/env/dev
terraform init
```

を実行し…

```
nitializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Using previously-installed hashicorp/azurerm v3.7.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

```

と応答が返ってきて初期化成功です。

次にTerraform planを実行しましょう。
これはdry runするコマンドです。

```
terraform plan
```

実行結果
```
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.resource_group will be created
  + resource "azurerm_resource_group" "resource_group" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "rg_terraform-001"
    }

  # azurerm_virtual_network.vnet will be created
  + resource "azurerm_virtual_network" "vnet" {
      + address_space       = [
          + "10.0.0.0/16",
        ]
      + dns_servers         = (known after apply)
      + guid                = (known after apply)
      + id                  = (known after apply)
      + location            = "japaneast"
      + name                = "vnet-terraform-dv-001"
      + resource_group_name = "rg_terraform-001"
      + subnet              = (known after apply)
    }

Plan: 2 to add, 0 to change, 0 to destroy.

```

はい、問題なくPlanが通ったので次はapplyしていきます。

```
terraform apply
```

```
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

azurerm_resource_group.resource_group: Creating...
azurerm_resource_group.resource_group: Creation complete after 0s [id=/subscriptions/                /resourceGroups/rg_terraform-001]
azurerm_virtual_network.vnet: Creating...
azurerm_virtual_network.vnet: Creation complete after 4s [id=/subscriptions/                /resourceGroups/rg_terraform-001/providers/Microsoft.Network/virtualNetworks/vnet-terraform-dv-001]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

```

はい、これでリソースグループとvNetが生成されました。簡単ですね！
コトハジメとしてはこんなもんですかね。

# おわりに

とりあえずまず第一歩を踏み出すための記事でした。
今後はTerraformを具体的にどう書いていくか？という記事を書く予定です！