Terraformで構築したCloud SQLインスタンスを停止した時に検出される差分の対処方法

## 背景

Terraform でCloud SQLのインスタンスを構築しました。

```terraform
resource "google_sql_database" "database" {
  name     = "my-database"
  instance = google_sql_database_instance.main.name
}

resource "google_sql_database_instance" "main" {
  name             = "main-instance"
  database_version = "POSTGRES_14"
  region           = "us-central1"

  settings {
    tier = "db-f1-micro"
  }
}
```

諸事情により構築したインスタンスを手動により「停止」を行いました。その後Terraform Planを実行すると以下の差分が発生しました。

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

Terraform will perform the following actions:

  # google_sql_database.database will be created
  + resource "google_sql_database" "database" {
      + charset   = (known after apply)
      + collation = (known after apply)
      + id        = (known after apply)
      + instance  = "main-instance"
      + name      = "my-database"
      + project   = (known after apply)
      + self_link = (known after apply)
    }

  # google_sql_database_instance.main will be updated in-place
  ~ resource "google_sql_database_instance" "main" {
        id                            = "main-instance"
        name                          = "main-instance"
        # (11 unchanged attributes hidden)

      ~ settings {
          ~ activation_policy     = "NEVER" -> "ALWAYS"
            # (9 unchanged attributes hidden)



            # (3 unchanged blocks hidden)
        }
    }

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

Terraformの運用上、この差分が発生したままでは困るのでどうにかして差分を無くしたいです。どうしたらこの差分を無くせるだろうか？

## なぜこの差分が発生するのか

### 1. Cloud SQL を停止するとデータベースが非表示となり存在しない状態となる

インスタンスが起動中は以下のようにデータベースが存在しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29755/0fb6c1d5-5258-af19-53fc-1b3f7e042a93.png)

しかしインスタンスを停止するとデータベースが非表示となります。データベースは存在しないのと同じ状態のようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29755/eeaf3bdb-5e7c-e1af-45f4-d2d93bde4612.png)


そのため、以下の実装によりデータベースを作成する差分が発生していました。

```terraform
resource "google_sql_database" "database" {
  name     = "my-database"
  instance = google_sql_database_instance.main.name
}
```

### 2. インスタンスの起動状態(アクティベーションポリシー）が変わっていた


インスタンスの起動状態は、「アクティベーション ポリシー」設定で管理されています。起動または停止に応じて変わります。今回インスタンスを停止したことによりアクティベーションポリシーが `ALWAYS` から `NEVER` に変わったことで以下の差分が発生していました。

```terraform
  # google_sql_database_instance.main will be updated in-place
  ~ resource "google_sql_database_instance" "main" {
        id                            = "main-instance"
        name                          = "main-instance"
        # (11 unchanged attributes hidden)

      ~ settings {
          ~ activation_policy     = "NEVER" -> "ALWAYS"
```

## 解消方法

以下の２点を調整することで差分は無くせます

1. データベース作成の実装を削除（またはコメントアウト)
2. インスタンスの状態に沿ってアクティベーションポリシーを設定

```terraform
# resource "google_sql_database" "database" {
#   name     = "my-database"
#   instance = google_sql_database_instance.main.name
# }

resource "google_sql_database_instance" "main" {
  name             = "main-instance"
  database_version = "POSTGRES_14"
  region           = "us-central1"

  settings {
    tier = "db-f1-micro"
    activation_policy = "NEVER"
  }
}
```

この実装状態で Terraform Planを実行すると

```terraform
No changes. Your infrastructure matches the configuration.
```

と差分なしの状態となりました :tada: 

## まとめ

そもそも Terraform 管理下の状態で手動操作を実施するのが良くないというのはあります。ただ諸事情でどうしても先に手動で操作したい場合には、後追いでTerraform調整することは稀にあることです。

今回の修正について、冷静に考えれば現状起きている状態の通りに修正しただけです。これが発生した時は気づきませんでしたが、GCPコンソール上で差分が発生した箇所がどうなっているのか見比べればすぐにわかりそうな内容でした。

今回の学びとしては差分が発生したら、「なぜその差分が発生しているのか」を把握することが大切だと思いました。

## 参考
* [アクティベーション ポリシー](https://cloud.google.com/sql/docs/mysql/instance-settings?hl=ja)
* [google\_sql\_database\_instance \| Resources \| hashicorp/google \| Terraform Registry](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance)