これは、リソースを変数で参照して整合性?を保とうとしたときに良くなる。
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"
}
とすると直る。