Azure Terraformで Azure SQL Databaseをすぐに構築する方法

更新内容：terraformの初期化手順を最新化

#Azure Terraformで、リソースはすぐできる。

[以前の投稿](https://qiita.com/KO_YAmajun/items/2e36b2023275b94e948c)でも記載した通り、Azure等のクラウド環境を活用すれば
素早い基盤構築が可能になりますが
Terraformを併用することで、より素早く・確実に構築が可能になります。

#構築デモ:事前準備

今回は、開発用PCでAzure PowerShell/Azure Terraform を実行する方式で進めます。
CloudShellの場合は、設定先が異なります。

認証方法は、AzureCLIを使用した認証を採用
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/azure_cli

### Powershell7～をインストールする（推奨）
Azure PowerShellをインストール。
https://github.com/PowerShell/PowerShell/releases

手順は下記を参照。
https://docs.microsoft.com/ja-jp/powershell/scripting/install/installing-powershell-core-on-windows

### Azure Cliをインストールする～ログイン
下記コマンドを実行。インストールとログインを行う
https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-windows?tabs=azure-powershell

```PowerShell:install.ps1
### インストール
Invoke-WebRequest -Uri https://aka.ms/installazurecliwindows -OutFile .\AzureCLI.msi; Start-Process msiexec.exe -Wait -ArgumentList '/I AzureCLI.msi /quiet'; rm .\AzureCLI.msi
```

```PowerShell:login.ps1
# CLI更新
az upgrade
# ログイン
az login
```
※ログイン後、TenantIdを確認しておくこと。

### 環境変数へのAzureテナント情報の登録

```PowerShell
# Azureポータルで確認できる サブスクリプション ID
[System.Environment]::SetEnvironmentVariable("ARM_SUBSCRIPTION_ID", "*****", "User");
# az login または az account show で確認できる TENANT_ID
[System.Environment]::SetEnvironmentVariable("ARM_TENANT_ID", "*****", "User");
```

###Terraformの準備

下記サイトからTerrafor.exeをダウンロードし、任意のフォルダに配置（今回は、C:\terraform）
https://www.terraform.io/downloads.html
配置したフォルダに環境変数/pathを通し、どのフォルダでもterraformコマンドを実行可能にしておく。

任意のフォルダで下記のPowershellを実行。
PowerShellが実行不可能であれば、代わりに手作業かbatを使用して環境変数を設定する。

```powershell:setup.ps1
# TerraFormのパスを通す。実際に配置しているパスを設定すること。
[System.Environment]::SetEnvironmentVariable("Path", "C:\terraform", "User");
```

###オプション：サービスプリンシパルを使用した認証の場合
クライアントシークレットを持つサービスプリンシパルを使用した認証の場合、
さらに下記も登録する。
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret

```powershell:setup.ps1
# Azure環境変数を設定。****は実際の値に置き換えてください。
# 作成したAzure ADのアプリケーション (クライアント) ID(ポータル_証明書とシークレットで確認)
[System.Environment]::SetEnvironmentVariable("ARM_CLIENT_ID", "****-****-****-****-****", "User");
# 作成したAzure ADのシークレット(ポータル_証明書とシークレット>クライアント シークレット)
[System.Environment]::SetEnvironmentVariable("ARM_CLIENT_SECRET", "********************", "User");
```

## Terraform Provider(azurerm)の初期化
下記tfファイルを配置して、terraform initを実行する
https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs

```HCL:provider.tf
terraform {
  # 本体のバージョン指定
  required_version = "~> 0.14"

  required_providers {
    # azurermのバージョン指定
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>2.43.0"
    }
  }
}

provider "azurerm" {
  # featuresは何も設定しない場合も、記入はしなければならない。
  features {}

  # 環境変数に埋め込まない場合、ここに記載する
  # ARM_SUBSCRIPTION_ID=*******
  # ARM_TENANT_ID=*******
}
```

#データベース構築デモ

今回は、下記3点をセットで構築します。
・resource_group
・sql_server ※Firewall_rule付き
・sql_database

##tfファイルの作成
まず、Azureで構築するリソースの情報を定義したtfファイルを作成します。

```shell:main.tf
# このファイルにインフラ構造を定義。
# 事前に環境変数に仕込んでいない場合はsubscription_id、client_id、client_secret、tenant_idを設定。


resource "azurerm_resource_group" "Examples" {
  name     = "${local.resource_group_name}"
  location = "${local.location}"
  
  tags = {
    environment = "${local.tags_environment_common}"
  }
}

resource "azurerm_sql_server" "Examples" {
  name                         = "${local.sql_server_name}"
  administrator_login          = "${local.sql_server_login}"
  administrator_login_password = "${local.sql_server_login_password}"
  version                      = "${local.sql_server_version}"
  resource_group_name          = "${azurerm_resource_group.Examples.name}"
  location                     = "${azurerm_resource_group.Examples.location}"
  
  tags = {
    environment = "${local.tags_environment_common}"
  }
}

resource "azurerm_sql_firewall_rule" "Examples" {
  name                = "${local.firewall_rule_name}"
  start_ip_address    = "${local.start_ip_address}"
  end_ip_address      = "${local.end_ip_address}"
  resource_group_name = "${azurerm_resource_group.Examples.name}"
  server_name         = "${azurerm_sql_server.Examples.name}"
}

resource "azurerm_sql_database" "Examples" {
  name                = "${local.sql_database_name}"
  edition             = "${local.sql_database_edition}"
  resource_group_name = "${azurerm_resource_group.Examples.name}"
  location            = "${azurerm_resource_group.Examples.location}"
  server_name         = "${azurerm_sql_server.Examples.name}"

  tags = {
    environment = "${local.tags_environment}"
  }
}
```

```shell:locals.tf
locals {
  # main.tfで定義した変数群を設定。
  # common  
  resource_group_name       = "Example"  
  location                  = "Japan East"
  tags_environment_common   = "common"
  # SQLServer_config
  sql_server_name           = "example-db"
  sql_server_login          = "Example"
  sql_server_login_password = "Example____!"
  sql_server_version        = "12.0"
  # SQLFirewall_config
  firewall_rule_name        = "Example"
  start_ip_address          = "192.168.10.10"
  end_ip_address            = "${local.start_ip_address}"
  # SQLDatabase_config
  sql_database_name         = "Example"
  sql_database_edition      = "Basic"
  tags_environment          = "production"
}
```

##リソースの作成

下記3ステップで実行可能です。

・tfファイルを配置している場所に移動
・terraform planで作成計画を確認
・terraform apply -auto-approve でリソースを作成　※planで確認済なのでapply時には確認しないようにしている。

```powershell:create.ps1
#terraformファイル(.tf)の格納フォルダパス
${TFFile_Path} = ''
cd ${TFFile_Path}

#リソースの作成をterraform apply -auto-approve で行う。確認はterraform planで行う。
terraform plan
#terraform apply -auto-approve 
```

##リソースの破棄
作成時同様の手順でOK。
plan -destroyで破棄計画を確認、次いでdestroyで破棄を実行できます。

```powershell:destroy.ps1
#terraformファイル(.tf)の格納フォルダパス
${TFFile_Path} = ''
cd ${TFFile_Path}

#リソースの破棄をterraform destroy -auto-approve で行う。
#確認はterraform plan -destroyで行う。
terraform plan -destroy
#terraform destroy -auto-approve 
```