TerraformでAzureリソース構築後にAzure Potal上から変更を加えた場合の動作

TerraformでAzureリソース構築後、リソースの状態は状態格納ファイル(terraform.tfstate)に格納されます。要件が変更となり、Azure Portal上からリソース変更した場合の動作について簡単に解説します。

結論から述べると、Azure Portalからリソースを変更した後にTerraformを再度実行すると、Azure Portalから変更した設定は消されてしまいます。

そのため、Azure PortalからTerraformで作成したリソースの設定を変更した後は、Terraformの定義ファイルに追記し terraform apply コマンドを実行し、クラウドリソースとして展開する必要があります。

今回は以上の手順を紹介します。例としてリソースグループを使用します。

※ 他の手段に、terraform importがありますが、今回は使用しません。

前提

本記事では、下記の前提を満たしている事を想定しています。

  • Terraformをインストール済であること
  • Terraformでリソースを作成済みであること

定義ファイル記載例

リソース作成に使用した定義ファイルを定義ファイル記載例に示します。

※本記事では以下リソースグループを作成しています。

  • リソースグループ名:test-rg01
  • リージョン:東日本

main.tf

プロバイダー情報、作成先サブスクリプション、状態格納用ストレージを記載します。

provider "azurerm" {
  features {}
  subscription_id = var.subscription_id
  tenant_id       = var.tenant_id
}

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
    }
  }

variables.tf

定義ファイル内で使用するリソース名、変数を指定します。

#-------------------------------
# 基本変数定義
#-------------------------------

# サブスクリプション
variable "subscription_id" {}

# テナントID
variable "tenant_id" {}

#-------------------------------
# Resource Group
#-------------------------------

# Resource Group Name01

variable "rg_name01" {
  default = "test-rg01"
}

rg.tf

Microsoft Entraアプリケーションオブジェクト、サービスプリンシパルオブジェクトを定義します。

#-------------------------------
# Resource Group
#-------------------------------

#Resource Group01
resource "azurerm_resource_group" "rg01" {
  name     = var.rg_name01
  location = "Japan East"
}

リソースの確認

状態格納ファイル(terraform.tfstate)とAzure Portalを確認し、リソースが作成されていることを確認します。

状態格納ファイル(terraform.tfstate)
{
  "version": 4,
  "terraform_version": "1.11.0",
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  "resources": [
    {
      "mode": "managed",
      "type": "azurerm_resource_group",
      "name": "rg01",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "/subscriptions/xxxxxxxxxx/resourceGroups/test-rg01",
            "location": "japaneast",
            "managed_by": "",
            "name": "test-rg01",
            "tags": null,
            "timeouts": null
          },
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  "check_results": null
}
Azure Portal

リソースグループ作成後

Azure Portalからリソースの変更

Azure Portalからリソースグループに対して、以下のタグを付与します。

terraform:test

タグ付け

Terraform実行

Azure Portal上でタグが付与された状態でterraform planで実行後の状態を確認します。定義ファイルに変更は加えません。

すると以下のように、リソースグループに付与したタグは、状態格納ファイル(terraform.tfstate)には記載がないため、削除する動作となってしまいます。

azurerm_resource_group.rg01: Refreshing state... [id=/subscriptions/xxxxxxxxx/resourceGroups/test-rg01]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  ~ update in-place

Terraform will perform the following actions:

  # azurerm_resource_group.rg01 will be updated in-place
  ~ resource "azurerm_resource_group" "rg01" {
        id         = "/subscriptions/xxxxxxxxxxxxxxxx/resourceGroups/test-rg01"
        name       = "test-rg01"
      ~ tags       = {
          - "terraform" = "test" -> null
        }
        # (2 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

定義ファイル修正

Terraform上では削除されてしまう動作になるため、terraform planから確認した情報を元に、定義ファイルを以下のように修正し実行してみます。

rg.tf

#-------------------------------
# Resource Group
#-------------------------------

#Resource Group01
resource "azurerm_resource_group" "rg01" {
  name     = var.rg_name01
  location = "Japan East"
  tags = {
    "terraform" = "test"
  }
}

terraform planで実行後の状態を確認すると、No changes. Your infrastructure matches the configuration.という出力結果となり、状態格納ファイル(terraform.tfstate)に変更が加わらないことが分かります。

terraform plan
azurerm_resource_group.rg01: Refreshing state... [id=/subscriptions/xxxxxxxx/resourceGroups/test-rg01]

No changes. Your infrastructure matches the configuration.

ですが、terraform applyを使用すると、No changesの表記は変わりませんが、状態格納ファイル(terraform.tfstate)が更新されていることが分かります。

terraform apply
azurerm_resource_group.rg01: Refreshing state... [id=/subscriptions/xxxxxxxx/resourceGroups/test-rg01]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

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

状態格納ファイル(terraform.tfstate)

{
  "version": 4,
  "terraform_version": "1.11.0",
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  "resources": [
    {
      "mode": "managed",
      "type": "azurerm_resource_group",
      "name": "rg01",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "/subscriptions/xxxxxxxx/resourceGroups/test-rg01",
            "location": "japaneast",
            "managed_by": "",
            "name": "test-rg01",
            "tags": {
              "terraform": "test"
            },
            "timeouts": null
          },
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  "check_results": null
}

定義ファイルに変更を加えず、状態格納ファイル(terraform.tfstate)のみの更新の場合は、terraform refreshを実行することで変更になります。

最後に

最後まで閲覧ありがとうございます。

この記事を見て、Terraformでリソース操作することに興味を持っていただけたり、参考になったりすれば幸いです。

執筆担当者プロフィール
佐藤 宏樹

佐藤 宏樹(日本ビジネスシステムズ株式会社)

クラウドソリューション事業本部に所属しています。主にMicrosoft Azureに携わっています。バイク乗りです。

担当記事一覧