Terraform 状態を Azure Storage に格納する

Terraform を使用すると、クラウド インフラストラクチャの定義、プレビュー、およびデプロイを行うことができます。 Terraform を使用する際は、HCL 構文を使って構成ファイルを作成します。 HCL 構文では、Azure などのクラウド プロバイダーと、クラウド インフラストラクチャを構成する要素を指定できます。 構成ファイルを作成したら、"実行プラン" を作成します。これにより、インフラストラクチャの変更をデプロイ前にプレビューすることができます。 変更を確認したら、実行プランを適用してインフラストラクチャをデプロイします。

Terraform 状態は、Terraform 構成を使用してデプロイされたリソースを調整するために使用されます。 "状態" を使用すると、追加、更新、または削除する Azure リソースが Terraform によって把握されます。

既定では Terraform 状態はローカルに格納されますが、これは次の理由から理想的ではありません。

  • ローカルの状態は、チーム環境または共同作業環境ではあまり実用的でない。
  • Terraform 状態に機密情報が含まれる可能性がある。
  • 状態をローカルに格納すると、不注意で削除される可能性が高くなる。

この記事では、次のことについて説明します。

  • Azure のストレージ アカウントの作成
  • Azure Storage の使用によるリモートの Terraform 状態の保存
  • 状態のロックについて
  • "保存時の暗号化" について

1. 環境を構成する

  • Azure サブスクリプション:Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。

2. リモート状態ストレージ アカウントを構成する

Azure Storage をバックエンドとして使用する前に、ストレージ アカウントを作成する必要があります。

次のコマンドまたは構成を実行して、Azure ストレージ アカウントとコンテナーを作成します。

#!/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 eastus

# Create storage account
az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob

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

重要なポイント:

  • Azure ストレージ アカウントには、グローバルに一意の名前を指定する必要があります。 ストレージ アカウント名のトラブルシューティングの詳細については、「ストレージ アカウント名のエラーの解決」を参照してください。
  • Terraform 状態はプレーン テキストで格納され、シークレットを含む場合があります。 状態が誤ってセキュリティで保護されている場合、システムへの不正アクセスとデータ損失が発生する可能性があります。
  • この例では、Terraform はアクセス キーを使用して Azure ストレージ アカウントに対して認証を行います。 運用環境のデプロイでは、azurerm バックエンドでサポートされている使用可能な認証オプションを評価し、ユース ケースに最も安全なオプションを使用することをお勧めします。
  • この例では、この Azure ストレージ アカウントへのパブリック ネットワーク アクセスが許可されています。 運用環境のデプロイでは、ストレージ ファイアウォール、サービス エンドポイント、またはプライベート エンドポイントを使用して、このストレージ アカウントへのアクセスを制限することをお勧めします

3. Terraform バックエンド状態を構成する

バックエンド状態を構成するには、Azure ストレージに関する次の情報が必要です。

  • storage_account_name: Azure ストレージ アカウントの名前。
  • container_name: BLOB コンテナーの名前。
  • key: 作成される状態ストア ファイルの名前。
  • access_key: ストレージ アクセス キー。

これらの各値は、Terraform 構成ファイルまたはコマンド ラインで指定できます。 access_key 値には環境変数を使用することをお勧めします。 環境変数を使用することで、キーがディスクに書き込まれるのを防ぐことができます。

次のコマンドを実行してストレージ アクセス キーを取得し、環境変数として格納します。

ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
export ARM_ACCESS_KEY=$ACCOUNT_KEY

重要なポイント:

  • Azure ストレージ アカウントのアクセス キーをさらに保護するには、これを Azure Key Vault に格納します。 環境変数は、次のようなコマンドを使用して設定できます。 Azure Key Vault の詳細については、Azure Key Vault のドキュメントを参照してください。

    export ARM_ACCESS_KEY=$(az keyvault secret show --name terraform-backend-key --vault-name myKeyVault --query value -o tsv)
    

backend 構成ブロックを使用して Terraform 構成を作成します。

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>3.0"
    }
  }
  backend "azurerm" {
      resource_group_name  = "tfstate"
      storage_account_name = "<storage_account_name>"
      container_name       = "tfstate"
      key                  = "terraform.tfstate"
  }

}

provider "azurerm" {
  features {}
}

resource "azurerm_resource_group" "state-demo-secure" {
  name     = "state-demo"
  location = "eastus"
}

<storage_account_name> は、実際の Azure Storage アカウントの名前に置き換えてください。

次のコマンドを実行して、構成を初期化します。

terraform init

次のコマンドを実行して、構成を実行します。

terraform apply

これで、Azure Storage BLOB で状態ファイルを見つけることができます。

4. 状態のロックについて

Azure Storage BLOB は、状態を書き込む操作の前に自動的にロックされます。 このパターンによって、破損を引き起こす可能性がある、同時状態操作が防止されます。

詳細については、Terraform ドキュメントの「状態のロック」を参照してください。

Azure portal または他の Azure 管理ツールを使用して BLOB を調べると、ロックを確認できます。

Azure blob with lock

5. 保存時の暗号化について

Azure BLOB の格納データは、永続化される前に暗号化されます。 必要に応じて、Terraform はバックエンドから状態を取得し、ローカル メモリに格納します。 このパターンを使用した場合、状態はローカル ディスクに書き込まれません。

Azure Storage 暗号化の詳細については、保存データに対する Azure Storage Service Encryption に関するページをご覧ください。

Azure での Terraform のトラブルシューティング

Azure で Terraform を使用する場合の一般的な問題のトラブルシューティング

次のステップ