AzureをTerraformで弄りはじめる

11 min読了の目安(約10700字TECH技術記事

published_at: 2020-03-14 19:28

これは自身の記事を、サービス終了に伴い Qrunch から移行したものです


Azure何もわかってなかったけど、↓を見かけて触ってみようと思ってやってみたのでその過程を共有したいと思います。

過程

0. サインアップ

以前、https://portal.azure.com/ からしてあったのでよく覚えてません。すみません。

1. ドキュメントを探し、Azure Cloud Shell にたどり着く

「Azure Terraform」で検索したら、Azure 上の Terraform のドキュメント - チュートリアル、サンプル、リファレンス、リソース | Microsoft Docs を見つけました。 そして勘でチュートリアルに進んでみました。

Terraform のインストールと構成 を読み進めてたら Azure Cloud Shell (以降、「Cloud Shell」)を使うことに。どうやらこれがAzureの登龍門みたい。
ポータルの検索バーで探そうとしてもなくて???になったけど、それっぽいやつがありました。

AzureCloudShell_Entry.png (17.9 kB)

2. Cloud Shell を使えるように

ストレージアカウントを作ってね!となったのではいはいとやってたのですが、Azureセンスが足りなくて、だいぶおこられました。

その様子

storage-account-create-failing.png (58.2 kB)

最終的には Cloud Shell に到達。けっこう嬉しい。

はじめての Cloud Shell

my-first-cli.png (63.2 kB)

その次の、Terraform のインストールは済んでるので先に進む。

3. アクセスキーなどの取得

Terraform から Azure にアクセスするための設定 のところ。
AWSでもGCPでもクレデンシャルの設定が必要だった局面。
Cloud Shell でコマンドを実行して必要なクレデンシャルを準備した。

クレデンシャル作成状況(一部非表示)

get-credencial.png (101.4 kB)

4. terraform init, plan

アクセスするための情報が揃ったので、init してみる

準備したファイル3つ(一部非表示)
  • provider.tf

        
    provider "azurerm" {
     # version = "~> 2.1"
    
      subscription_id = var.subscription_id
      client_id       = var.client_id
      client_secret   = var.client_secret
      tenant_id       = var.tenant_id
    }    
    
  • variables.tf

    
    variable subscription_id {}
    variable client_id {}
    variable client_secret {}
    variable tenant_id {}    
    
  • terraform.tfvars (ソース管理対象外)

        
    subscription_id = "XXXXXXXXXXXXXXXX"      # <- サブスクリプションID
    client_id       = "XXXXXXXXXXXXXXXX"      # <- appId
    client_secret   = "XXXXXXXXXXXXXXXX"      # <- password
    tenant_id       = "XXXXXXXXXXXXXXXX"      # <- tenant
    
init 時のコンソール出力

❯ terraform init

Initializing the backend...

Initializing provider plugins...
- Checking for available provider plugins...
- Downloading plugin for provider "azurerm" (hashicorp/azurerm) 2.1.0...

The following providers do not have any version constraints in configuration,
so the latest version was installed.

To prevent automatic upgrades to new major versions that may contain breaking
changes, it is recommended to add version = "..." constraints to the
corresponding provider blocks in configuration, with the constraint strings
suggested below.

* provider.azurerm: version = "~> 2.1"

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.    
provider のバージョンを入れて、plan

((準備したファイル3つ) のところの provider.tf でコメントアウトしてたのを外した)


❯ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.    

5. バックエンドストレージ準備

状態はAzureのストレージに置こうと思い、
「Terraform azure backend」で検索して チュートリアル:Terraform 状態を Azure Storage に格納する を見つけた

ストレージ整備

ストレージ アカウントの構成 のセクションにあったスクリプトをそのまま実行したらなんだか米国東部にできちゃってて、いやー遠すぎだなーと思い削除。
スクリプトを見直すなどしてると、コンテナだけ作ればいいんだなと思いそうした。
-> (追記) 管理するリソース群とバックエンドストレージは別のリソースグループにしたほうがよさそう。次のリソースを作ろうと仕込んでいたときに間違った import を行ってしまって、tfstate がぜーんぶふっとんで最初からやり直しになりました。最初だからよかったんですが。。

スクリプトとコンソール出力・ポータルで確認(一部非表示)

#!/bin/bash

#RESOURCE_GROUP_NAME=tfstate
#STORAGE_ACCOUNT_NAME=tfstate$RANDOM
#CONTAINER_NAME=tfstate
#
## Create resource group
#az group create \
#    --name $RESOURCE_GROUP_NAME \
#    --location japaneast
#
## Create storage account
#az storage account create \
#    --resource-group $RESOURCE_GROUP_NAME \
#    --name $STORAGE_ACCOUNT_NAME \
#    --sku Standard_LRS \
#    --encryption-services blob


RESOURCE_GROUP_NAME=(いつの間にか作成していたリソースグループ : 2.でちらっと出てくる)
STORAGE_ACCOUNT_NAME=(2.で作成したストレージアカウント)
CONTAINER_NAME=tfstate
    
# Get storage account key
ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query [0].value -o tsv)

# Create blob container
az storage container create \
    --name $CONTAINER_NAME \
    --account-name $STORAGE_ACCOUNT_NAME \
    --account-key $ACCOUNT_KEY

# output
echo "storage_account_name: $STORAGE_ACCOUNT_NAME"
echo "container_name: $CONTAINER_NAME"
echo "access_key: $ACCOUNT_KEY" 

sogaoh@Azure:~$ vi createContainer.sh
sogaoh@Azure:~$ bash createContainer.sh
{
  "created": true
}
storage_account_name: XXXXXXXX
container_name: tfstate
access_key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
sogaoh@Azure:~$     

container-created.png (61.8 kB)

再度 terraform init ...

backend.tf をガイドに従ってととのえ、さあいってみようとやってみたんですが・・・

CLI をインストールしてログインせよと・・・
  • backend.tf

terraform {
  backend "azurerm" {
    resource_group_name   = "(いつの間にか作成していたリソースグループ : 2.でちらっと出てくる)"
    storage_account_name  = "(2.で作成したストレージアカウント)"
    container_name        = "tfstate"
    key                   = "terraform.tfstate"
  }
}    

❯ terraform init

Initializing the backend...

Error: Error building ARM Config: Azure CLI Authorization Profile was not found. Please ensure the Azure CLI is installed and then log-in with `az login`.
    

6. CLI をインストールしてリトライ

Azure CLI のインストール から macOSへのインストール へ進み、Azure CLI (azコマンド) をインストールした。

brew install azure-cli -> バージョン確認(だいぶ省略)
    
❯ brew update && brew install azure-cli
Updated 5 taps ...
・・・
==> azure-cli
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d

~ 4m 13s
❯    

❯ az --version
azure-cli                          2.2.0

command-modules-nspkg              2.0.3
core                               2.2.0
nspkg                              3.0.4
telemetry                          1.0.4

Python location '/usr/local/Cellar/azure-cli/2.2.0_1/libexec/bin/python'
Extensions directory '/Users/sogaoh/.azure/cliextensions'

Python (Darwin) 3.8.2 (default, Mar 11 2020, 00:29:50)
[Clang 11.0.0 (clang-1100.0.33.17)]

Legal docs and information: aka.ms/AzureCliLegal



Your CLI is up-to-date.

Please let us know how we are doing: https://aka.ms/clihats

~ 10s
❯    
az login

自動で起動されたブラウザでなんだかエラーっぽいのが出てて焦ったけど成功してた

    
❯ az login
You have logged in. Now let us find all the subscriptions to which you have access...
[
  {
    "cloudName": "AzureCloud",
    "homeTenantId": "XXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "id": "XXXXXXXXXXXXXXXXXXXX",
    "isDefault": true,
    "managedByTenants": [],
    "name": "従量課金",
    "state": "Enabled",
    "tenantId": "XXXXXXXXXXXXXXXXXXXX",
    "user": {
      "name": "************************",
      "type": "user"
    }
  }
]

~ 18s    

ガイド Azure CLI を使用してサインインする を確認してたらレスポンスが出てた、という感じ。

terraform apply まで実行できた

❯ cd ${PATH_TO_TFs_DIRECTORY}

${PATH_TO_TFs_DIRECTORY}
❯ terraform init

Initializing the backend...

Successfully configured the backend "azurerm"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...

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.

${PATH_TO_TFs_DIRECTORY} 6s
❯ terraform plan
Acquiring state lock. This may take a few moments...
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------

No changes. Infrastructure is up-to-date.

This means that Terraform did not detect any differences between your
configuration and real physical resources that exist. As a result, no
actions need to be performed.

${PATH_TO_TFs_DIRECTORY} 6s
❯ terraform apply

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

❯    
  • ストレージに terraform.tfstateが作成されていることを確認(中身はガラガラ)
    terraform-applied.png (93.1 kB)

さいごに

最後まで見ていただきありがとうございます。
ここから先はAWSやGCPでTerraform使っていたのと要領として大差ないであろうと思うので、たまーにいろいろやっていきたいと思います。
この記事がAzureでIaCをしようとしている方の手がかりになれば幸いです。