Azure環境でTerraformを使ってみる(1/2)

# はじめに
初めてTerraformを使ってみたい方かつAzureで試してみたい方向けにやり方をまとめました。
この内容を実行することでIT初級者でもTerraformを使ったInfrastracture As Code(IaC)を体験することができます。
（所要時間30分くらい）
今回は利便性を体験することが目的なのでコード自体の解説は別の機会があればと思います。


# 概要
Terraform実行用の環境として専用環境を準備することもできるのですが、今回は試してみることが目的なので簡易的に動かしたいと思います。
AzureではCloud Shellを使えばTerraformを動かせるので、ローカル環境のノートパッドで作成したコードをAzure上のCloud Shellへコピーして動作させます。



# 構成図
最終的な構成図です。
二つのサブネットを含むVNETと3枚のNWインターフェースを持つVMを1台作成します

![概要図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/42992302-390e-8461-7836-47f799d7ed92.png)

# 作業の流れ
1. ネットワークを作成するコードを準備
1. terraformの環境を準備
1. terraformを実行
1. VMを作成するコードを準備
1. terraformを実行



# 手順

## **1.ネットワークを作成するコードを準備**
1. 最初にネットワークを作成するコードを準備します
ローカルPCで作業してください
以下のコードを丸ごとコピーしてローカルPCのメモ帳などで作成し保存します
これがリソースグループ、VNET、サブネット、NSGなどを作成するコードです

```network.tf
# Azureプロバイダーを構成する
terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "~>3.0.2"
    }
  }
}

# 機能を定義する
# 削除する時に楽なようにリソースグループにリソースが残っていても削除できるように設定しています
provider "azurerm" {
  features {
    resource_group {
      prevent_deletion_if_contains_resources = false
    }
  }
}

# リソースグループを作成する
resource "azurerm_resource_group" "ec_group" {
    name     = "education_env"
    location = "Japan East"
}

# VNETを作成する
resource "azurerm_virtual_network" "ec_network" {
    name                = "EducationNetwork"
    address_space       = ["10.10.0.0/16"]
    location            = "Japan East"
    resource_group_name = "${azurerm_resource_group.ec_group.name}"
}

# VNETに含むサブネット1を作成する
resource "azurerm_subnet" "ec_FRsubnet" {
    name                 = "FrontSubnet"
    resource_group_name  = "${azurerm_resource_group.ec_group.name}"
    virtual_network_name = "${azurerm_virtual_network.ec_network.name}"
    address_prefixes     = ["10.10.1.0/24"]
}

# VNETに含むサブネット2を作成する
resource "azurerm_subnet" "ec_BKsubnet" {
    name                 = "BackSubnet"
    resource_group_name  = "${azurerm_resource_group.ec_group.name}"
    virtual_network_name = "${azurerm_virtual_network.ec_network.name}"
    address_prefixes     = ["10.10.100.0/24"]
}

# Linux用のNSGを作成する
resource "azurerm_network_security_group" "eclinux_nsg" {
    name                = "SSHNetworkSecurityGroup"
    location            = "Japan East"
    resource_group_name = "${azurerm_resource_group.ec_group.name}"
    
    security_rule {
        name                       = "SSH"
        priority                   = 1001
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "22"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
    }
}
```
## **2 Terraformの環境を準備**
1. Azure Portalにログインして右上のコンソールアイコンを選択しCloud Shellを起動
![00.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/882c39d3-49f0-d5d1-2af9-11a8fe76e4f9.png)


&ensp;2. 以下の画面が出る場合はBashをクリック
（PowerShellでもIaCは体験できますが、今回はTerraformがテーマなのでBashを選択します）
![cloudshell02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/bfca8094-e1ce-fca4-bb5b-f408dccdb80e.png)




&ensp;3.  初めて作成する場合は以下の画面になると思います。詳細設定の表示をクリック
![cloudshell03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/0285ec50-8dfc-65d4-8798-377074f396ae.png)






&ensp;4.  リソースグループ名、ストレージアカウント名、共有ファイル名を入力してストレージの作成をクリック
&ensp;**ストレージアカウント名はAzure内で一意である必要があるので誰とも重複しない名前にして下さい。**
&ensp;（他の人の命名と重複してはいけないこの制限はかなり不便だと思います）
&ensp;&ensp;リソースグループ名はnetwork.tfの中でeducation_envを使っているのでそれ以外の名前（以下のサンプルではeducation)にして下さい

参考URL：[ストレージ アカウントの概要](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-account-overview#:~:text=%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%20%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E5%90%8D%E3%81%AE%E9%95%B7,%E3%82%92%E6%8C%81%E3%81%A4%E3%81%93%E3%81%A8%E3%81%AF%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82)

![cloudshell05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/21308c69-70f9-1550-40c1-36f293a90310.png)


&ensp;5. これでAzure Cloud Shellが利用できるようになりました。以下の画面が出ていると思います。
```
Requesting a Cloud Shell.Succeeded. 
Connecting terminal...

Welcome to Azure Cloud Shell

Type "az" to use Azure CLI
Type "help" to learn about Cloud Shell

nosecape@Azure:~$ 
```
　　
## **3.terraformを実行**

1. lsを実行してデフォルトのファイル状況を確認する
```
nosecape@Azure:~$ ls
clouddrive
```
&ensp;2. ローカルに作成したnetwork.tfファイルをコンソールにドラック&ドロップする
&ensp;lsを実行してファイルがアップロードされたことを確認する
```
nosecape@Azure:~$ ls
clouddrive  network.tf
```
&ensp;3. 今回はIaCの体験なのでterraformのコマンドはおまじないだと思い以下のコマンドを実行する

&ensp;terraform initを実行する（初期化しています）

```
nosecape@Azure:~$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding hashicorp/azurerm versions matching "~> 3.0.2"...

          　　　　　　　　　　・
          　　　　　　　　　　・
　　　　　　　　　　 　　　　<省略>
          　　　　　　　　　　・
          　　　　　　　　　　・
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
nosecape@Azure:~$ 
```
&ensp;4. terraform planを実行します（リソースの確認を行っています）
```
nosecape@Azure:~$ 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_network_security_group.eclinux_nsg will be created
  + resource "azurerm_network_security_group" "eclinux_nsg" {
      + id                  = (known after apply)
      + location            = "japaneast"
      + name                = "SSHNetworkSecurityGroup"
      + resource_group_name = "education_env"
      + security_rule       = [
          + {
              + access                                     = "Allow"
              + description                                = ""
              + destination_address_prefix                 = "*"
    ![09.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/db1164ea-378d-d9a7-8011-fb984e529989.png)
      　　　　　　　　　　・
          　　　　　　　　　　・
　　　　　　　　　　 　　　　<省略>
          　　　　　　　　　　・
          　　　　　　　　　　・
  # azurerm_virtual_network.ec_network will be created
  + resource "azurerm_virtual_network" "ec_network" {
      + address_space       = [
          + "10.10.0.0/16",
        ]
      + dns_servers         = (known after apply)
      + guid                = (known after apply)
      + id                  = (known after apply)
      + location            = "japaneast"
      + name                = "EducationNetwork"
      + resource_group_name = "education_env"
      + subnet              = (known after apply)
    }

Plan: 6 to add, 0 to change, 0 to destroy.
```
&ensp;5. terraform applyを実行します（リソースの作成を行います）
```
nosecape@Azure:~$ terraform apply

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_network_security_group.eclinux_nsg will be created
  + resource "azurerm_network_security_group" "eclinux_nsg" {
      + id                  = (known after apply)
      + location            = "japaneast"
      + name                = "SSHNetworkSecurityGroup"
      + resource_group_name = "education_env"

          　　　　　　　　　　・
          　　　　　　　　　　・
　　　　　　　　　　 　　　　<省略>
          　　　　　　　　　　・
          　　　　　　　　　　・
  # azurerm_virtual_network.ec_network will be created
  + resource "azurerm_virtual_network" "ec_network" {
      + address_space       = [
          + "10.10.0.0/16",
        ]
      + dns_servers         = (known after apply)
      + guid                = (known after apply)
      + id                  = (known after apply)
      + location            = "japaneast"
      + name                = "EducationNetwork"
      + resource_group_name = "education_env"
      + subnet              = (known after apply)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
```
&ensp;6. Enter a value と出てくるのでyesと入力します
```
  Enter a value: yes

azurerm_resource_group.ec_group: Creating...
azurerm_resource_group.ec_group: Creation complete after 1s [id=/subscriptions/xxxxxxx]
azurerm_network_security_group.eclinux_nsg: Creating...
          　　　　　　　　　　・
          　　　　　　　　　　・
　　　　　　　　　　 　　　　<省略>
          　　　　　　　　　　・
          　　　　　　　　　　・
azurerm_subnet.ec_FRsubnet: Creation complete after 9s [id=/subscriptions/xxxxxx/FrontSubnet]

Apply complete! Resources: 6 added, 0 changed, 0 destroyed.
nosecape@Azure:~$ 
```
&ensp;これでリソースが出来上がりました。
&ensp;数分で出来ると思いますがAzure状態によっては時間がかかるようです。

&ensp;7. 確認していきましょう。
&ensp;リソースグループ「education_env」を作成しているので確認してみます
&ensp;VNETとNSGが作成されています
![09.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/1dbdb872-785f-a39d-3de8-1f5d9d53c521.png)

&ensp;8. VNETの中にサブネットもできています
![10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/f84de749-9052-68a2-71cf-1e49622b888f.png)

ここまでの手順で以下の構成までできました。続きは [こちら](https://qiita.com/hanazaki/items/80fab26339735d010557)
![概要図NW.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516565/c026da07-5ceb-9439-1e4c-ad7aa756fced.png)