理系学生日記

おまえはいつまで学生気分なのか

Terraform BackendのあるSubscriptionとは別のSubscriptionへリソースを構築する

SubScriptionによって環境分離を実現しようと考えています。つまり、Subscription1がQA環境、Subscription2がProd環境といった具合に。 このように各環境ごとにSubscriptionを分割し、それぞれをTerraformで管理しようとした場合、Terraform Backendをどの粒度で構築するかが1つの検討ポイントでした。 ここではTerraform Backend用に別Subscriptionを用意し、Staging環境用Subscriptionにリソースを作成することを試してみます。

Terraform Backendの構成

以下で実現できました。 backendブロックにはDelivery Subscription上で作成したtfstateの設定をそのまま記述します。 providerブロックでStaging SubscriptionのIDを明示的に指定しました。

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = ">= 2.60.0, < 3.0.0"
    }
  }

  backend "azurerm" {
    # Delivery Subscription上のResource Group等
    resource_group_name  = "rg-kiririmode-tfstate-stg"
    storage_account_name = "stkiririmodetfstatestg"
    container_name       = "tfstate"
    key                  = "terraform.tfstate"
  }
}

provider "azurerm" {
  features {}
  subscription_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" # StagingのSubscriptionID
}

これを実行すると、DeliveryではなくStaging Subscriptionに想定通りResourceGroupを構成できました。

$ terraform apply
Acquiring state lock. This may take a few moments...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # azurerm_resource_group.example will be created
  + resource "azurerm_resource_group" "example" {
      + id       = (known after apply)
      + location = "japaneast"
      + name     = "example"
    }

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.example: Creating...
azurerm_resource_group.example: Creation complete after 1s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/example]

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

今後の課題(tfstateのアクセス制限)

tfstateは、誰もが参照・更新できて良いリソースではありません。適切な人にしかアクセスできないように、アクセス制限をかけておく必要があります。

tfstateが配置されているのは先述のとおりAzure Blob Storageですが、Azure Storageへのアクセス承認方法は以下2種類が存在します。

  • Azure ADアカウントでの認証・認可
  • ストレージアカウントアクセスキーでの認証・認可

アクセスキーによる方法は、当該のアクセスキーを持つ人すべてに参照・更新が可能になってしまいます。Azureのドキュメントでも以下のとおりAzure ADでの承認が推奨されています。

BLOB およびキューのデータに対する要求を承認するには、共有キーではなく、可能であれば Azure Active Directory (Azure AD) を使用することをお勧めします。 Azure AD では、共有キーよりも優れたセキュリティと使いやすさが実現されます。

ストレージ アカウント アクセス キーを管理する

Terraform BackendをAzureで構成する場合は、このあたりのアクセス制限の設定を適切に行う必要がありそうです。