概要
「Infrastructure as Code」ということで、Terraform を用いて Azureを構成するときに、あらかじめ Azureに仕込んでおくべきことを記載しています。 おおまかな流れは以下となります。
- Terraform の構成ファイル「tfstate」の保存場所の作成(ローカルに保存する場合は不要)
- Terraform でAzure上に環境構築するためのサービスプリンシパルの作成
- 確認のため、Terraform でリソースグループを作成してみる
ローカル環境
- macOS Monterey 12.0.1
- Azure CLI 2.28.0
- terraform v1.0.11
前提条件
- Azure環境がすでに用意されていること(テナント/サブスクリプション)
- ローカル環境に「azure cli」がインストールされていること
- ローカル環境に「terraform」環境が構成されていること
準備
Terraform の構成ファイル 「tfstate」 の保存場所の作成 (ローカルに保存する場合は不要)
## ローカル環境変数の定義
export RG_TF_NAME=rg-ituru-tfstate
export SUBS_NAME=PSG2-01
export STORAGE_TF_ACCOUNT=iturutfstate
export STORAGE_TF_CONTAINER=tfstate
## 使用するテナントへのログイン
$ az login --tenant <tenant_id>
## 使用サブスクリプションの定義
$ az account set --subscription $SUBS_NAME
## teffarom tfstate 用のリソースグループ作成
$ az group create --name $RG_TF_NAME --location japaneast
## teffarom tfstate 用のストレージアカウントの作成
$ az storage account create --name $STORAGE_TF_ACCOUNT --resource-group $RG_TF_NAME -l japaneast --sku Standard_LRS --enable-hierarchical-namespace true
## teffarom tfstate ファイルを保存するコンテナの作成
$ az storage container create --name $STORAGE_TF_CONTAINER --account-name $STORAGE_TF_ACCOUNT
## teffarom tfstate 用のストレージアカウントの認証情報の取得
$ az storage account keys list --account-name $STORAGE_TF_ACCOUNT --subscription $SUBS_NAME --resource-group $RG_TF_NAME --output table
CreationTime KeyName Permissions Value
-------------------------------- --------- ------------- ----------------------------------------------------------------------------------------
2021-12-04T16:11:49.888094+00:00 key1 FULL pppppppppppppppppppppppppppp....ppppp
2021-12-04T16:11:49.888094+00:00 key2 FULL qqqqqqqqqqqqqqqqqqqqqqqqqqqq....qqqqq
## Terraform のためのローカル環境変数の定義
export ARM_ACCESS_KEY="<storage_account_key1>"
Teffarom でAzure上に環境構築するためのサービスプリンシパルの作成
## ローカル環境変数の定義
export SP_TF_NAME=sp_itutu_terraform
## サービスプリンシパルの有効期限を2年で作成します(ロール割当なしで)
$ az ad sp create-for-rbac --name $SP_TF_NAME --skip-assignment --years 2
{
"appId": "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx", --> AZURE_CLIENT_ID として terraform実行ローカル環境変数として登録
"displayName": "<ServicePrincial名>",
"name": "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx",
"password": "hogehogehogehogehogehogehogehogege", --> AZURE_CLIENT_SECRET として terraform実行ローカル環境変数として登録
"tenant": "zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz" --> AZURE_TENANT_ID として terraform実行ローカル環境変数として登録
}
## 必要なスコープに必要なロールを割り与えるための appId の取得
$ APP_ID=$(az ad sp list --display-name $SP_TF_NAME --query '[].{ID:appId}' --output tsv)
## 必要なスコープに必要なロールを割り与えるための サブスクリプションID の取得
$ SUBS_ID=$(az account show --query "id" --output tsv)
## 必要なスコープに必要なロールの割当て
## 今回はSubscription各種リソースを定義するので、スコープ:Subscription ロール:Contributor(共同作成者)とします
$ az role assignment create --assignee $APP_ID --scope /subscriptions/$SUBS_ID --role Contributor
Terraform でリソースグループを作成してみる
terraform 定義ファイルの作成
メイン定義ファイル
main.tf
# プロバイダーの定義
terraform {
required_providers {
azurerm = "~> 2.33"
}
# tfstate ファイルの保存先(ローカルに保存の場合、不要)
backend "azurerm" {
storage_account_name = "iturutfstate"
container_name = "tfstate"
key = "test01/terraform.tfstate"
}
}
# Azureプロバイダ
provider "azurerm" {
features {}
tenant_id = var.ARM_TENANT_ID
client_id = var.ARM_CLIENT_ID
client_secret = var.ARM_CLIENT_SECRET
}
# リソースグループ
resource "azurerm_resource_group" "this" {
name = var.resource_group_name
location = var.region
tags = var.tags_def
}
パラメータ定義ファイル
variables.tf
# 環境変数(Azureサービスプリンシパル)
variable ARM_TENANT_ID {}
variable ARM_CLIENT_ID {}
variable ARM_CLIENT_SECRET {}
# タグ情報
variable tags_def {
default = {
owner = "ituru"
period = "2022-03-31"
CostCenter = "psg2"
}
}
# 各種パラメータ
variable resource_group_name {}
variable region {}
パラメータ値定義ファイル
terraform.tfvars
# 環境変数の定義(Azureサービスプリンシパル)
ARM_TENANT_ID = "zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz"
ARM_CLIENT_ID = "xxxxxxxx-xxxx-4444-9922-xxxxxxxxxxxx"
ARM_CLIENT_SECRET = "hogehogehogehogehogehogehogehogege"
# パラメータ値の定義
resource_group_name = "rg_ituru_test" // リソースグループ名
region = "japaneast" // 利用リージョン
terraform の実行
## init
$ terraform init
Initializing the backend...
Successfully configured the backend "azurerm"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Reusing previous version of hashicorp/azurerm from the dependency lock file
- Using previously-installed hashicorp/azurerm v2.88.1
Terraform has been successfully initialized!
## plan
$ 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.this will be created
+ resource "azurerm_resource_group" "this" {
+ id = (known after apply)
+ location = "japaneast"
+ name = "rg-ituru-test"
+ tags = {
+ "CostCenter" = "psg2"
+ "owner" = "ituru"
+ "period" = "2022-03-31"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
## apply
$ 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_resource_group.this will be created
+ resource "azurerm_resource_group" "this" {
+ id = (known after apply)
+ location = "japaneast"
+ name = "rg-ituru-test"
+ tags = {
+ "CostCenter" = "psg2"
+ "owner" = "ituru"
+ "period" = "2022-03-31"
}
}
Plan: 1 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.
Enter a value: yes
azurerm_resource_group.this: Creating...
azurerm_resource_group.this: Creation complete after 0s [id=/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
terraform 実行後の確認
## 作成されたリソースグループの確認
$ az group show --name rg-ituru-test
{
"id": "/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test",
"location": "japaneast",
"managedBy": null,
"name": "rg-ituru-test",
"properties": {
"provisioningState": "Succeeded"
},
"tags": {
"CostCenter": "psg2",
"owner": "ituru",
"period": "2022-03-31"
},
"type": "Microsoft.Resources/resourceGroups"
}
## tfstateファイルの確認
## コンテナー内の BLOB を一覧表示する
$ az storage blob list --account-name $STORAGE_TF_ACCOUNT --container-name $STORAGE_TF_CONTAINER --output table
Name Blob Type Blob Tier Length Content Type Last Modified Snapshot
------------------------------ ----------- ----------- -------- ---------------- ------------------------- ----------
test01 BlockBlob Hot 2022-01-05T10:26:47+00:00
test01/terraform.tfstate BlockBlob Hot 1037 application/json 2022-01-05T10:38:36+00:00
ローカルの作業ディレクトの状況
$ tree -a
.
├── .terraform
│ ├── providers
│ │ └── registry.terraform.io
│ │ └── hashicorp
│ │ └── azurerm
│ │ └── 2.88.1
│ │ └── darwin_amd64
│ │ └── terraform-provider-azurerm_v2.88.1_x5
│ └── terraform.tfstate
├── .terraform.lock.hcl
├── main.tf
├── terraform.tfvars
└── variables.tf
terraform による作成したリソースの削除
$ terraform destroy
azurerm_resource_group.this: Refreshing state... [id=/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# azurerm_resource_group.this will be destroyed
- resource "azurerm_resource_group" "this" {
- id = "/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test" -> null
- location = "japaneast" -> null
- name = "rg-ituru-test" -> null
- tags = {
- "CostCenter" = "psg2"
- "owner" = "ituru"
- "period" = "2022-03-31"
} -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
azurerm_resource_group.this: Destroying... [id=/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test]
azurerm_resource_group.this: Still destroying... [id=/subscriptions/xxxxxxxx-1717-4343-9779-zzzzzzzzzzzz/resourceGroups/rg-ituru-test, 10s elapsed]
azurerm_resource_group.this: Destruction complete after 15s
Destroy complete! Resources: 1 destroyed.
$ az group show --name rg-ituru-test
(ResourceGroupNotFound) Resource group 'rg-ituru-test' could not be found.
$ az storage blob list --account-name $STORAGE_TF_ACCOUNT --container-name $STORAGE_TF_CONTAINER --output table
Name Blob Type Blob Tier Length Content Type Last Modified Snapshot
------------------------------ ----------- ----------- -------- ---------------- ------------------------- ----------
test01 BlockBlob Hot 2022-01-05T10:26:47+00:00
test01/terraform.tfstate BlockBlob Hot 156 application/json 2022-01-05T10:49:52+00:00
まとめ
これで、Terraform でAzure環境を構成できる準備が整いました。terraform の tfstateファイル は上記で作成したストレージアカウントのコンテナに保存されるようになります。