★ 初級

02. Resource Group

Resource Group は AWS には存在しない Azure 固有の概念。「論理的なリソースの箱」 として、ライフサイクル管理・課金タグ付け・RBAC スコープの中心になります。

Resource Group とは

Azure ではほぼ全リソースが必ず どこかの Resource Group に属する。Resource Group は:

基本宣言

resource "azurerm_resource_group" "main" {
  name     = "rg-myapp-prd"
  location = "Japan East"

  tags = {
    Project   = "myapp"
    Env       = "prd"
    Owner     = "platform-team"
    ManagedBy = "Terraform"
  }
}

# 他リソースから参照
resource "azurerm_storage_account" "data" {
  resource_group_name = azurerm_resource_group.main.name
  location            = azurerm_resource_group.main.location
  # ...
}

どう分けるか

RG を分けすぎても少なすぎてもダメ。実用的な分割パターン:

パターン適性
環境ごとrg-myapp-dev / rg-myapp-prd◎ 最も一般的
環境×サブシステムrg-myapp-prd-network / rg-myapp-prd-data○ 大規模で有用
共有 vs プロジェクトrg-shared-network + rg-app1○ ハブ&スポーク構成
全部 1 つrg-everything△ 検証用のみ

命名規則

Microsoft 公式の CAF naming convention を参考に。例: <type>-<app>-<env>-<region>-<instance>

rg-myapp-prd          # Resource Group
vnet-myapp-prd-jpe    # Virtual Network in Japan East
sa-myappprdjpe001     # Storage Account(- 不可、英数小文字のみ)
kv-myapp-prd-jpe      # Key Vault
vm-web-prd-jpe-001    # Virtual Machine
type 略称の例 rg Resource Group / vnet VNet / snet Subnet / nsg NSG / vm VM / sa Storage Account / kv Key Vault / asp App Service Plan / law Log Analytics Workspace

タグ戦略

Azure の タグは RG から自動継承されない(AWS Organizations の Tag Policy のような自動継承機能がない)。リソースごとに付ける必要があります。

locals {
  common_tags = {
    Project    = "myapp"
    Env        = "prd"
    Owner      = "platform-team"
    ManagedBy  = "Terraform"
    CostCenter = "1234"
  }
}

resource "azurerm_resource_group" "main" {
  name     = "rg-myapp-prd"
  location = "Japan East"
  tags     = local.common_tags
}

resource "azurerm_storage_account" "data" {
  # ...
  tags = local.common_tags
}

provider レベルでの default_tags 相当の機能が azurerm v3 以降にあります(features { ... } ではなく provider 引数として)。バージョンによって書き方が違うので公式を確認。

ロックで誤削除を防ぐ

本番 RG には Management Lock をかけて、Terraform 以外からも削除を防止できます。

resource "azurerm_management_lock" "prod_rg" {
  name       = "prod-rg-no-delete"
  scope      = azurerm_resource_group.main.id
  lock_level = "CanNotDelete"   # or "ReadOnly"
  notes      = "Production resources - Terraform managed"
}

# Terraform 側でも保護
resource "azurerm_resource_group" "main" {
  # ...
  lifecycle {
    prevent_destroy = true
  }
}