APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

TerraformでAzureのロールアサインをするときはlifecycleでignore_changesを指定しよう

f:id:thanaism:20210816155925p:plain

おばんです、コンテナソリューショングループの髙井です。

今日は、AzureのロールアサインをするときはTerraformのconfiguration driftに気を付けようという話をします。

configuration driftとは

Terraformでは、デプロイするたびにクラウド上にあるリソースの状態をstateファイルとして保存します。

ここで、誰かがIaCを経由せずに直接コマンドでリソースを書き換えてしまったりすると、実際のリソースとstateとの間にずれが生じてしまいます。これがconfiguration driftです。

Terraformに限らず、総じて意図しない設定値の変化をそう呼ぶことが多いかと思います。

変わってないのに変わっちゃうパターン

実際のリソースが気付かず変化しているのは、それはそれで困ったことではあるのですが、もっと困るのがクラウド上のリソースに変化がないのにterraform planをすると差分が出てしまう場合です。

たとえば、terraform applyをしてリソースをデプロイしたとします。その直後にterraform planをすれば、今あるTerraformファイルの通りに作ったばかりのリソースですから、差分は出ないはずです。

が、書き方によってはこれが出るケースがあるんですね。とくに、Azureロールのアサインなどで気を付けないと発生します。

azurerm_role_assignmentはユニークネームを作成する

Terraformの公式ページを見てみましょう。

変数の説明には、nameについて以下のように書いてあります。

(Optional) A unique UUID/GUID for this Role Assignment - one will be generated if not specified. Changing this forces a new resource to be created.

要するに「nameを指定しないとUUIDを勝手にふるよ」ということです。

すなわち、terraform applyをするたびに新しいUUIDが生成されるため、常に今あるロールアサインを削除して新しいロールアサインを行う挙動になってしまいます。

より具体的には、nameを省略していても以下のようなコードを書いているのと同じような状態だと考えればよいでしょう。

resource "azurerm_role_assignment" "my_role" {
  name = uuid()
  ...
}

uuidのページを見てみる

続いて、同じくTerraform公式ページuuidの項目を見てみましょう。

We do not recommend using the uuid function in resource configurations, but it can be used with care in conjunction with the ignore_changes lifecycle meta-argument.

公式も「uuidを設定値にするならignore_changesを併用しようね」と言ってくれています。

てなわけで、実際に利用する際は以下のように記述しましょう。

resource "azurerm_role_assignment" "my_role" {
  ...
  lifecycle {
    ignore_changes = [
      name
    ]
  }
}

こうすることにより、ロールアサインの強制的な再作成を防ぐことができます。

おわりに

configuration drift検知のために、定期的にterraform planを実行するなどの工夫をしているチームも多いかと思いますが、ロールアサインを適当に実装すると上記のような差分が発生してしまうため、ぜひお気を付けください(適当に書いた人)。

それではあなたのAzureライフが楽しくなるように、Stay Azure!