Terraformで循環参照のエラーが出た時
これは、リソースを変数で参照して整合性?を保とうとしたときに良くなる。
variable "env" { type = "string" default = "dev" } variable "service" { type = "string" default = "foo" } resource "aws_cloudfront_origin_access_identity" "origin_access" { comment = "access-identity-${var.env}-${var.service}.s3.amazonaws.com" } data "template_file" "s3_policy" { template = "${file("s3-bucket-policy.json")}" vars { bucket_name = "${var.env}-${var.service}" origin_access_identity = "${aws_cloudfront_origin_access_identity.origin_access.id}" } } resource "aws_s3_bucket" "foo" { bucket = "${var.env}-${var.service}" acl = "private" policy = "${data.template_file.s3_policy.rendered}" tags { Name = "${var.env}-${var.service}" Environment = "${var.env}" ServiceName = "${var.service}" } }
となっている場合、循環参照が発生する。
❯ terraform plan Error configuring: 1 error(s) occurred: * Cycle: data.template_file.s3_policy, aws_s3_bucket.foo, aws_cloudfront_origin_access_identity.origin_access
もう、わけわかんないし辛い気持ちになるけど、Terraformには便利な機能がある。
依存グラフの出力である。
terraform graph -draw-cycles | dot -Tpng > graph.png
-draw-cycles
をつけると赤くなるので、分かりやすい。
後は、その依存関係を解決していけば良いだけ。
今回のケースは、aws_cloudfront_origin_access_identity
でバケット名を参照しているが、バケット名は"${var.env}-${var.service}"
で置き換え可能なため、
resource "aws_cloudfront_origin_access_identity" "origin_access" { comment = "access-identity-${var.env}-${var.service}.s3.amazonaws.com" }
とすると直る。