TerraformでAzureに2階層システムを構築する

## はじめに
Microsoft Azureに仮想マシンや仮想ネットワークなどを構築するにはAzureポータルを使うことができますが、クラウドの旨味を十分に活かすためにこれらを柔軟に繰り返し配備・破棄できることが開発効率化の重要なポイントとなるため、構築自動化にチャレンジします。
自動化にはAzure CLIやARMテンプレートが候補として挙がりますが、今後Azureだけでなく複数クラウドの構築自動化を見据え、Terraformを使って自動化をやってみました。

Azureの公式ドキュメントに紹介されている[解説ページ](https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/terraform-install-configure)と、Terraform開発元のHashicorp社が公開している[examplesテンプレート](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/examples/virtual-machines/bastion-box/README.md)がありますので、それらを参考・流用しつつ、以下の超小規模のシステムを自動構築してみました。

<img width="591" alt="スクリーンショット 2019-09-15 16.07.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133866/fe8633f1-6acc-0687-5046-3958f11f7d2b.png">

## 構築準備
本記事では任意のCentOS7の環境が準備された想定で以下の手順を記載します。

### terraformをインストールする

[terraform公式ドキュメント](https://www.terraform.io/downloads.html)からダウンロードURLを確認しwgetで取得します。
(2019/9/15現在ではterraform 0.12.8でした)

```
# wget https://releases.hashicorp.com/terraform/0.12.8/terraform_0.12.8_linux_amd64.zip -P /usr/local/bin
# cd /usr/local/bin
# unzip terraform_0.12.8_linux_amd64.zip
Archive:  terraform_0.12.8_linux_amd64.zip
  inflating: terraform
```

### terraformがインストールされたか確認する

```
# terraform --version
Terraform v0.12.8
```

### Azure CLIをインストールする
[公式のドキュメントを参照](https://docs.microsoft.com/ja-jp/cli/azure/install-azure-cli-yum?view=azure-cli-latest)してインストールします。

### Azureの認証情報を取得する
terraformからAzureの操作を行うために事前に認証情報を取得します。
具体的にはAzure CLIでAzureにログイン後、Azure Service Principalを作成します。

### Azureにloginする

```
# az login
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code XXXXXXX to authenticate.
```

### コマンドで出力されたURLにブラウザでアクセスする
要求されているコード`az login`で出力されたコードを入力します。上記だとXXXXXXXに相当します。

![スクリーンショット 2019-09-15 14.32.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133866/c3d9713a-5e58-3a64-fbc6-408299692222.png)

### ログイン後Service PrincipalをAzure CLIで発行する

```
# az account list -o table
Name           CloudName    SubscriptionId                        State    IsDefault
-------------  -----------  ------------------------------------  -------  -----------
Pay-As-You-Go  AzureCloud   @@@YOUR_SUBCSRIPTION_ID@@@            Enabled  True

# SUBSCRIPTION_ID="上記で取得したSubscriptionId"
# az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}"
Creating a role assignment under the scope of "/subscriptions/@@@YOUR_SUBCSRIPTION_ID@@@"
{
  "appId": "APP_ID",
  "displayName": "azure-cli-2019-09-15-05-41-36",
  "name": "http://azure-cli-2019-09-15-05-41-36",
  "password": "PASSWORD",
  "tenant": "TENANT_ID"
}
```

## terraformを使ってAzure上に構築する

### 認証情報を設定する

```
# export ARM_SUBSCRIPTION_ID=${SUBSCRIPTION_ID}
# export ARM_CLIENT_ID="<Service principal作成時に出力されたappId>"
# export ARM_CLIENT_SECRET="<Service principal作成時に出力されたpassword>"
# export ARM_TENANT_ID="<Service principal作成時に出力されたtenant>"
```

### terraform templateをgitで取得する
terraformを開発しているHashicorp社が[Example](https://github.com/terraform-providers/terraform-provider-azurerm/blob/master/examples/virtual-machines/bastion-box/README.md)を公開しているため、そちらからテンプレートを準備します。
が、、Examplesではdmz構成に1つのVMしか配備されないテンプレートのため、本記事ではExamplesを流用して拡張したテンプレートを使用します。

```
# cd ~
# git clone -b feature/dmzsecure https://github.com/kita-atsushi/terraform-provider-azurerm.git
# cd terraform-provider-azurerm/examples/virtual-machines/bastion-box
```

### terraform initを実行しAzure pluginをインストールする

```
# terraform init
```

### terraform applyでAzureに環境を構築する

```
# terraform apply -var 'location=japaneast' -var "prefix=sandbox20190915" -auto-approve

： (省略： 数分〜数十分かかります)

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

Outputs:

ssh_command = ssh testadmin@sandbox20190915-jumpserver.japaneast.cloudapp.azure.com
vm_fqdn = sandbox20190915-jumpserver.japaneast.cloudapp.azure.com
```

AzureポータルからもIaaSが構築されていることを確認できます。
![スクリーンショット 2019-09-15 15.52.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133866/9dbae163-7d38-6d33-e316-018f1d829883.png)

### 構築した仮想マシンにsshするための鍵を取得する
`terraform apply`後に出力されるOutputsより構築した仮想マシンにログインするためのsshコマンドが出力されますが、ssh鍵の指定が別途必要となります。ssh鍵は`terraform show`コマンドでテキストとして取得することができます。
ここでは以下のコマンドで鍵文字列を取得しファイルとして保存します(jqコマンド必要)。

```
# terraform show -json |jq -r '.values.root_module.resources[] | select(.address=="tls_private_key.jumpserver") | .values.private_key_pem' >id_rsa
# chmod 600 id_rsa
```

### 構築した仮想マシンにsshする

以下のコマンドでsshし構築したサーバにログインできます。

```
# ssh -i id_rsa testadmin@sandbox20190915-jumpserver.japaneast.cloudapp.azure.com

[testadmin@jump-server ~]$ hostname
jump-server
[testadmin@jump-server ~]$
```

以上