Terraform

Terraform Azure Blob バックエンド徹底ガイド: Azure での遠隔状態管理

2026-04-19
NicheeLab編集部

Terraform で複数人・複数環境を安全に運用するには、状態(tfstate)をリモートで一元管理し、並行実行を防ぐロックと堅牢な認証が欠かせません。本稿では Azure Blob Storage を用いる azurerm バックエンドの実務運用ポイントを、試験(Associate / Pro)で問われやすい観点とあわせて整理します。

公式仕様に基づき、作成コマンド、認証パターン、ワークスペース分離、ロック動作、CI/CD での落とし穴と対処を具体化します。

なぜ Azure Blob バックエンドか: 基本と要点

Terraform のバックエンドは状態ファイルの保存先とロック方式を決めます。Azure 環境なら azurerm バックエンドで Blob Storage に保存するのが定番です。Blob のリース機能を利用した排他ロックにより、apply の二重実行を防げます。

ストレージ側は既定でサーバー側暗号化が有効、Azure AD ベースの RBAC によるきめ細かなデータプレーン権限付与が可能です。Terraform 側は terraform init によってバックエンドと接続し、以後の plan/apply はリモート状態を参照・更新します。

  • ロック: Azure Blob のリースで排他制御。force-unlock で手動解除も可能。
  • 暗号化: サーバー側暗号化は既定で有効。必要に応じて CMK に切替可能(ストレージ設定側)。
  • 認証: Azure AD(サービスプリンシパル/Managed Identity/Azure CLI)、またはストレージ アクセスキーや SAS も選択可(推奨は Azure AD)。
バックエンドロック方式既定の暗号化主な認証
localなし(並行実行で破損リスク)なしローカル権限のみ
azurerm (Azure Blob)Blob Lease による排他サーバー側暗号化(Microsoft 管理キー)Azure AD(RBAC) / Managed Identity / サービスプリンシパル / (代替)アクセスキー・SAS
s3 (参考)DynamoDB テーブルでロック(任意)サーバー側暗号化(SSE-S3 既定)AWS IAM(ロール/ユーザー)

Azure Blob バックエンドの流れ(ロック含む)

Dev / CI Runnerterraform init / plan / applyAzure Storage AccountContainer: tfstate / Blob: *.tfstateacquire lease (Blob Lease) で排他ロック → 単一書込者・並行 apply を防止

最小構成の backend ブロック(認証は環境側で供給)

terraform {
  backend "azurerm" {
    resource_group_name  = "rg-tfstate"
    storage_account_name = "sttfstate1234"
    container_name       = "tfstate"
    key                  = "network/terraform.tfstate"
    # 認証情報は Azure AD / CLI / Managed Identity / SP の環境から取得
  }
}

事前準備: ストレージとコンテナの作成

状態保存用の専用ストレージアカウントを用意します。命名は小文字・数字で 3〜24 文字。Blob コンテナは環境ごとに分けるか、キーで論理分離します。パブリックアクセスは無効を推奨、バージョニングとソフトデリートを有効化すると復旧が容易です。

terraform init に先立ち、リソースグループ、ストレージ、コンテナを作成します。認証を Azure AD で行う場合、コンテナ作成は CLI の login 認証を使うと安全です。

  • ストレージ種別: StorageV2、冗長化は LRS/GRS など要件に応じ選択
  • 推奨設定: Blob バージョニング有効化、ソフトデリート保持日数の設定、パブリックアクセス禁止
  • 命名指針: コンテナ名は tfstate、キーは proj/env/ などのパスで分類

Azure CLI による作成例と推奨プロパティ設定

# 1) リソースグループ
az group create -n rg-tfstate -l japaneast

# 2) ストレージアカウント(パブリックアクセス無効)
az storage account create \
  -n sttfstate1234 \
  -g rg-tfstate \
  -l japaneast \
  --sku Standard_LRS \
  --kind StorageV2 \
  --allow-blob-public-access false

# 3) Blob バージョニングとソフトデリート(例: 30日)
az storage account blob-service-properties update \
  --account-name sttfstate1234 \
  --enable-versioning true
az storage blob service-properties delete-policy update \
  --account-name sttfstate1234 \
  --enable true --days-retained 30

# 4) コンテナ作成(Azure AD ログインを使用)
az storage container create \
  --name tfstate \
  --account-name sttfstate1234 \
  --auth-mode login

認証と権限: Azure AD/RBAC が基本

バックエンドの認証は Azure AD を推奨します。サービスプリンシパル、Managed Identity、ローカルの Azure CLI ログイン、ワークロード ID(OIDC) などが利用できます。ストレージ データプレーン権限として、少なくとも Storage Blob Data Contributor を付与します(コンテナ単位のスコープ最小化が望ましい)。

環境変数経由のサービスプリンシパル認証では ARM_CLIENT_ID/ARM_CLIENT_SECRET/ARM_TENANT_ID/ARM_SUBSCRIPTION_ID を設定します。ワークロード ID フェデレーション(GitHub Actions など)ではクライアントID/テナントID/サブスクリプションIDを設定し、OIDC トークンはログインアクションが提供するファイル/環境から取得されます。アクセスキーや SAS トークンも使えますが、運用上は鍵のローテーションや秘匿管理の複雑さから Azure AD 優先が無難です。

  • 必要ロール(例): Storage Blob Data Contributor(読み書き) + 読み取りのみ環境では Storage Blob Data Reader
  • 推奨: ストレージアカウントへのアカウントキー共有は避ける。RBAC と監査を活用
  • テナント/サブスクリプション跨ぎ: backend に tenant_id/subscription_id を明示可能

RBAC 付与と環境変数の例(SP 認証)

# サービスプリンシパル(appId)に Blob データ貢献者ロールを付与
az role assignment create \
  --assignee <APP_ID> \
  --role "Storage Blob Data Contributor" \
  --scope "/subscriptions/<SUB_ID>/resourceGroups/rg-tfstate/providers/Microsoft.Storage/storageAccounts/sttfstate1234"

# Terraform 用の環境変数(SP シークレット認証)
export ARM_CLIENT_ID=<APP_ID>
export ARM_CLIENT_SECRET=<CLIENT_SECRET>
export ARM_TENANT_ID=<TENANT_ID>
export ARM_SUBSCRIPTION_ID=<SUB_ID>
# (ワークロードID/OIDC の場合は認証アクションがトークンを供給。CLIENT_SECRET は不要)

バックエンド設定と状態分離: 環境ごとのキー/コンテナ

backend ブロックは静的で、変数補間は基本的に使えません。環境ごとに状態を分けるには、キー(key)を切り替えるか、コンテナを分けます。チーム運用では「プロジェクト/環境/コンポーネント.tfstate」の命名を徹底し、誤参照を防ぎます。

terraform init 時に -backend-config を渡して部分設定を埋めるパターンが実務的です。ワークスペース名をキーに反映する場合は、スクリプトで現在のワークスペースを取得し、init -reconfigure でキーを上書きします。

  • キー例: key = projectA/dev/network.tfstate
  • 推奨: 本番は専用コンテナ or 専用ストレージで境界を強める
  • backend の機微情報は -backend-config で外出し(リポジトリに直書きしない)

-backend-config とワークスペース連動の例

# 例) 各環境に応じて key を切替
RG=rg-tfstate
ST=sttfstate1234
CT=tfstate
WS=$(terraform workspace show)
KEY="projectA/${WS}/network.tfstate"

terraform init -reconfigure \
  -backend-config="resource_group_name=${RG}" \
  -backend-config="storage_account_name=${ST}" \
  -backend-config="container_name=${CT}" \
  -backend-config="key=${KEY}"

ロック・暗号化・復旧性: 実運用で効く設定

ロックは Blob のリースで実現され、並行 apply は拒否されます。プロセス異常終了でロックが残る場合、terraform force-unlock で解除します(ロックIDはエラーメッセージに表示)。

暗号化は既定で有効です。要件によりストレージ側で顧客管理キー(CMK)に切替可能です。状態のバージョニング/ソフトデリートを有効化しておくと、誤操作時のロールバックが容易です(旧バージョンを復元)。

  • ロック異常時: terraform force-unlock -force <LOCK_ID>
  • 推奨: Blob バージョニング + ソフトデリート + 変更フィードで監査強化
  • 注意: 状態の手編集は原則禁止。必要時はバックアップを取得してから

ロック解除とバージョニングの確認

# ロック解除(メッセージに表示された LOCK_ID を使用)
terraform force-unlock -force 01234567-89ab-cdef-0123-456789abcdef

# バージョニング有効化はセクション2参照。復元は Portal/CLI で対象 Blob の過去版を復元

CI/CD 組み込みとトラブル対処

CI では非対話実行(-input=false)と確実な認証供給が鍵です。バックエンドの再設定が入る場合は -reconfigure を明示します。状態は機密情報を含み得るため、Plan ファイルの保管やログ出力に注意します。

よくあるエラーと対処: 403(AuthorizationPermissionMismatch) は RBAC 不足、コンテナ未作成や名前誤り、テナント/サブスクリプション不一致、並行ジョブによるロック競合が代表例です。

  • 変更時は terraform init -reconfigure を徹底
  • 並行 apply を避けるためジョブを直列化、もしくは環境/キーを完全分離
  • 計画と適用で同一バックエンド/同一キーを参照しているか検証

GitHub Actions の例(OIDC + Azure AD)

name: tf-apply
on: [workflow_dispatch]
jobs:
  apply:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id:  ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
      - uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.6.6
      - name: Init backend
        run: |
          terraform init -reconfigure \
            -backend-config="resource_group_name=rg-tfstate" \
            -backend-config="storage_account_name=sttfstate1234" \
            -backend-config="container_name=tfstate" \
            -backend-config="key=projectA/prod/app.tfstate"
      - name: Plan
        run: terraform plan -input=false -out=plan.tfplan
      - name: Apply
        run: terraform apply -input=false -auto-approve plan.tfplan

問題で確認

Associate / Pro

問題 1

Terraform の azurerm バックエンドで状態の同時更新を防ぐ仕組みとして正しいものはどれか。

  1. Azure Blob のリース(Lease)を利用した排他ロック
  2. Azure Queue Storage のメッセージ可視性タイムアウト
  3. Azure Files のファイルロック(SMB)で代替
  4. Terraform Cloud のロックAPIを必ず組み合わせる必要がある

正解: A

azurerm バックエンドは Azure Blob のリース機能で排他ロックを実現します。Queue の可視性タイムアウトや SMB ロックは本件に不適、Terraform Cloud 連携も必須ではありません。

よくある質問

ストレージ アクセスキーではなく Azure AD で認証できますか?

可能です。サービスプリンシパル、Managed Identity、Azure CLI ログイン、ワークロード ID(OIDC) を利用できます。RBAC として少なくとも Storage Blob Data Contributor を付与してください。

環境ごとに状態を分けるベストプラクティスは?

本番は専用コンテナまたは専用ストレージで分離し、非本番はキー命名(project/env/component.tfstate)で分けるのが一般的です。backend は静的のため、init 時の -backend-config で key を切替えます。

ロックが解除されず apply できません。どうすれば?

他の実行が残っていないか確認し、必要なら terraform force-unlock -force <LOCK_ID> を実行してください。頻発する場合は CI 側の直列化、タイムアウト設定、ジョブの排他制御を見直します。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Terraform

Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける

Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...

Terraform

Terraform Authoring & Ops Pro: 上位資格の範囲と対策

上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...

Terraform

Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす

Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...

Terraform

Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義

Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...

Terraform

Terraform Data Source徹底理解:既存リソースの参照で壊さず足す

Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...

Terraformの記事一覧 (101件)
© 2026 NicheeLab All rights reserved.