Auzreストレージ(Blobコンテナー)にterraform.tfstateを保管(初めてのAzureでTerraform(4))

初めてのTerraform第4回になります。

今回はマイクロソフト社のチュートリアルを参考にterraform.tfstateをストレージ(Blobコンテナー)に保管する設定をやってみました。

Terraformはterraform.tfstateと言うファイルで構成情報を管理しています。前回まではこのファイルをローカルに保管していましたが、これだと別ユーザーと構成情報の共有が出来ません。

別ユーザーがTerraformを使って更新した場合は、自身の構成情報は更新されず正しい構成情報が保管されていない状態になります。この状態で操作すると意図しないリソース更新が発生する可能性があります。

terraform.tfstateをAzure ストレージに保管する事で、他ユーザーとTerraformが管理する構成情報を共有する事が出来ます。

スポンサーリンク

ストレージアカウントを作成する

terraform.tfstateを保管する為のストレージアカウントを作成します。サンプルと同様にリソースグループの作成、ストレージアカウントの作成、Blobコンテナーを作成します。Azure CLI(Linux環境)で作成しています。

※今回は検証用なのでアクセス制限等は実施していません。実環境ではアクセス元のIP制限など十分にセキュリティにご留意ください。

ストレージアカウント作成
  • 作成条件
    • リソースグループ名は、terraformtest01とする
    • ストレージアカウント名は、tstate+ランダムの数字
    • Blobコンテナー名はtstateとする
    • ロケーションはeastus2(米国東部2)とする
    • echoコマンドでストレージアカウント名やアクセスキーを出力する。

Azure CLI(Linux環境で実行)

#!/bin/bash
RESOURCE_GROUP_NAME=terraformtest01
STORAGE_ACCOUNT_NAME=tstate$RANDOM
CONTAINER_NAME=tstate
# Create resource group
az group create –name $RESOURCE_GROUP_NAME –location eastus2
# Create storage account
az storage account create –resource-group $RESOURCE_GROUP_NAME –name $STORAGE_ACCOUNT_NAME –sku Standard_LRS –encryption-services blob
# 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
echo “storage_account_name: $STORAGE_ACCOUNT_NAME"
echo “container_name: $CONTAINER_NAME"
echo “access_key: $ACCOUNT_KEY

作成後にAzure Portalで確認してみます。リソースグループやストレージアカウント(コンテナー含む)が作成されている事が確認出来ます。

作成後メッセージ

storage_account_name: tstate9158
container_name: tstate
access_key: ji0/0qhk9xSphFHl(~中略~)N==

Azure Portalで確認した結果

terraform.tfstateをストレージアカウントに保存する

第2回で利用したファイルを参照しながら進めます。

main.tfファイルにBlobコンテナーの情報を記載する

main.tfにバックエンドの情報を記載します。今回はTerraformの方のチュートリアルを参考にaccess_keyを明示してアクセスしています。

※事前に認証を行っている環境だとAccess Keyを記載しなくても大丈夫そうです。今回は検証の都合上access_keyを直接記載していますが、本番運用時にはセキュリティ的に好ましくない気もするのでMIDを利用するなどにして下さい。

設定ファイルを編集
  • 作成条件
    • バックエンドに利用するストレージアカウントやBlobコンテナーは作成したものを利用。
    • Access Keyを利用してストレージアカウントへアクセス。
    • アクセスキーはストレージアカウント作成時に取得したものを利用。
    • 元々のmain.tfファイルにbackend “azurerm"{}(オレンジ部分)を追加。

【main.tf

terraform {
 required_providers {
  azurerm = {
  source = “hashicorp/azurerm"
  version = “=2.46.0"
  }
 }
 backend “azurerm" {
  resource_group_name = “terraformtest01"
  storage_account_name = “tstate9158"
  container_name = “tstate"
  key = “terraform.tfstate"
  access_key = “ji0/0qhk9xSphFHl(~中略~)N=="
 }
}

設定変更後にterraform initを実行する

ファイル設定変更後にterraform initを実行します。今回はすでにローカルにterraform.tfstateが存在する前提になります。

terraform init

バックエンドの情報を変更しましたので、再度terraform initを実行する必要があります。

PS C:\terraform> terraform init

Initializing the backend…

Error: Backend configuration changed

│ A change in the backend configuration has been detected, which may require migrating existing state.

│ If you wish to attempt automatic migration of the state, use “terraform init -migrate-state".
│ If you wish to store the current configuration with no changes to the state, use “terraform init -reconfigure"

エラーになります。これはローカルにterraform.tfstateが存在しておりその扱いを指定する必要があります。今回は別の場所に移行する形にしましたのでmigrate-stateをつけて再度実行します。オプションの詳細についてはこちらが参考になるかと思います。

terraform init -migrate-stateを実行してみます。

PS C:\terraform> terraform init -migrate-state

Initializing the backend…
Backend configuration changed!

Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.

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.46.0

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.

今度は成功した事が分かりました。

実際にAzure Portalでファイルを確認してみます。コンテナー内にterraform.tfstateファイルが生成されている事が分かります。

terraform applyを実行しterraform.tfstateロック状態を確認する

terraform applyを実行した際のロック状態を確認してみます。今回はterraform.tfstateを確認を目的にしていますのでapplyするアイテムは特に問いません。

terraform apply

terraform applyを実行してみます。メッセージを見ますと一番最初にstateがロックされている事が分かります。(plan時も同様にロックされています。)

PS C:\terraform> terraform apply

Acquiring state lock. This may take a few moments…

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:

apply中にファイルのステータスを確認するとロック状態になっている事が確認出来ます。

terraform.tfstateをapply前後で比較してみる

terraform apply前後のterraform.tfstateを確認し更新されている事を見てみます。

terraform.tfstateの比較

 terraform apply実行前

{
“version": 4,
“terraform_version": “1.0.1",
“serial": 0,
“lineage": “XXXXXXXXXXXXXXXXXXXXX",
“outputs": {},
“resources": []
}.

 terraform apply実行後

 “version": 4,
  “terraform_version": “1.0.1",
  “serial": 2,

  (~中略~

    {
      “mode": “managed",
      “type": “azurerm_linux_virtual_machine",
      “name": “VM-01",
      “provider": “provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      “instances": [

(~以下略~)【】

Azure ストレージにterraform.tfstate置いた場合でも更新されている事が分かりました。複数ユーザーで共有して作業出来る環境が出来る事が分かりました。