まーぽんって誰がつけたの?

iOS→Scala→インフラなおじさん技術メモ

Terraformで変数を組み合わせることができるlocal valuesというのが使えるようになってた

Local Valuesがない世界😢

例えば、S3のバケットの名前をnameenvっていう変数を使って"${var.name}-${var.env}"ってしたいとする。

resource "aws_s3_bucket" "b" {
  bucket = "${var.name}-${var.env}"
}

んで、例えば、このbucketの名前を他で使いたいときは、"${aws_s3_bucket.b.id}"ってやればいいんだけど、たまに循環参照が起きて使えないことがある。

例: s3_bucketのpolicyを指定したい -> policyにはs3_bucketから名前をいれたい みたいな場合。鶏が先か卵が先かみたいな感じになっちゃう。🐔

resource "aws_s3_bucket" "b" {
  bucket = "${var.name}-${var.env}"
  policy = "${data.aws_iam_policy_document.s3_policy_cf_bucket.json}"
}

# ↑を作るには↓が必要で、↓を作るには↑が必要

data "aws_iam_policy_document" "p" {
  statement {
    actions   = ["s3:GetObject"]
    resources = ["arn:aws:s3:::${aws_s3_bucket.b.id}/*"]

    principals {
      type        = "AWS"
      identifiers = ["${aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn}"]
    }
  }
}

そういうときは、この"${var.name}-${var.env}"をそこかしこで書かないといけない。これがbucket名を表してるってちょっとわかりにくいので一つのvariableにまとめたいと人は思います。が、variableはそれができないのです!!

# これはできない!!variableはinterpolationをサポートしてない
variable "bucket_name" {
  default = "${var.name}-${var.env}"
}

Local Valuesがある世界💯

www.terraform.io

Local Valuesは簡単にいうと色々組み合わせて好きな名前で値を定義しておけるものです。 こういうsyntaxで値を定義できます。

locals {
  bucket_name = "${var.name}-${var.env}"
}

使うときはこんな感じで、${local.bucket_name}とできる。

resource "aws_s3_bucket" "b" {
  bucket = "${local.bucket_name}"
  policy = "${data.aws_iam_policy_document.s3_policy_cf_bucket.json}"
}

data "aws_iam_policy_document" "s3_policy_cf_bucket" {
  statement {
    actions   = ["s3:GetObject"]
    resources = ["arn:aws:s3:::${local.bucket_name}/*"]

    principals {
      type        = "AWS"
      identifiers = ["${aws_cloudfront_origin_access_identity.origin_access_identity.iam_arn}"]
    }
  }
}