terraform planで意図せず差分が検出される件と向き合ってみた
はじめに
良く terraform
を利用するのですが、定義変更がない状態でplan
を実行した際差分が検出される(ことがある)事象に悩まされていました。遭遇頻度がそこまで高くなかったために、しばらく放置していたのですがterraformもCI/CDをまわしたい欲に駆られてしっかりと向き合ってみました。
どんな事象が起きるのか
たとえば、Datadogと連携するためのiAM Roleを以下のように定義してみます。
resource "aws_iam_role" "dd" { name = "dd" description = "dd" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "123451234512" }, "Action": "sts:AssumeRole" } ] } EOF }
おもむろにapply
します。
$ terraform apply <snip> Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
無事にIAM Roleが作成されました。それでは、定義を変更せずにplan
を実行してみます。
$ terraform plan <snip> ~ aws_iam_role.dd assume_role_policy: "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Sid\":\"\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::123451234512:root\"},\"Action\":\"sts:AssumeRole\"}]}" => "{\n \"Version\": \"2012-10-17\",\n \"Statement\": [\n {\n \"Sid\": \"\",\n \"Effect\": \"Allow\",\n \"Principal\": {\n \"AWS\": \"123451234512\"\n },\n \"Action\": \"sts:AssumeRole\"\n }\n ]\n}\n"
定義の変更が無いにも関わらず、差分が検出されてしまいます。
向き合い方
それではこの差分と向き合ってみましょう。今回はterraform-landscapeを利用してplan
の可読性を高めています。
使い方は簡単でplan
の結果をパイプでlandscape
に渡してあげるだけです。それでは実行してみます。
$ terraform plan | landscape <snip> ~ aws_iam_role.dd assume_role_policy: "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "AWS": "arn:aws:iam::123451234512:root" + "AWS": "123451234512" }, "Sid": "" } ], "Version": "2012-10-17"
Principalの値に差分が見られますね。123451234512
として定義しましたが、tfstateファイルではarn:aws:iam::123451234512:root
と記録されているようです。
一方plan
で表示された設定は表記方法が異なるだけで、設定としては問題がなさそうです。そのためこのままapply
しても問題はなさそう。ですがこれでは都度差分を確認することとなり、精神的にも消耗しますし、最悪plan
をしっかりと確認しない文化が作られる可能性があります。
このようなケースで差分として検出されないために、定義ファイルを少しだけ修正してみます。
resource "aws_iam_role" "dd" { name = "dd" description = "dd" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123451234512:root" }, "Action": "sts:AssumeRole" } ] } EOF } `
Principalの定義をtfstateファイルに合わせ修正しています。この状態でplan
を実行して差分が検出されないことを確認してみます。
$ terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. aws_iam_role.dd: Refreshing state... (ID: dd) ------------------------------------------------------------------------ No changes. Infrastructure is up-to-date. This means that Terraform did not detect any differences between your configuration and real physical resources that exist. As a result, no actions need to be performed.
無事に差分が検出されなくなりました。
terreformでは定義ファイルの通りにtfstateファイルへと記録されないこともあるようですね。そのため、定義ファイルで変更が無い場合でもplan
の際に差分として検出されることがあります。このような差分はplan
のノイズになるので排除したいところです。
この辺りはplan
にヒントが多く表示されていると思われますので、やはりplan
は大事です。また、plan
の差分としてJSONが表示されるとかなり視認性が低くツラかったのですが、terraform-landscapeの力を借りることでかなり視認性が高くなりました。
この調子で意図しない差分はどんどん排除したいと思います。