Lapis Lazuli

technical blog for web developer

【Terraform】DataSourceの使いどころ

インフラのコード化に使われるTerraformですが、クラウド上のリソースを管理するresource以外にもdataという属性があります。
これはデータソースというもので、簡単に説明すると実際のクラウド上には存在しないけど、Terraform内で完結するように作られるリソースです。
つまりdataの名前どおり、データとして存在している概念的なリソースですね。

普段リソースを管理しているときは、あまり使うシーンはないと思います。resourceで定義したものをそのまま反映していくだけで構築されますからね。
ただ一部リソースに関しては、これを使った方がベターな場合があります。

IAMロール

IAMロールのリソースは、aws_iam_roleで定義します。
この中の必須属性にassume_role_policy というものがあり、これでロールのパーミッションを決めるのですが、記述方法はJSONとなっています。
もちろんそのまま書いてもいいのですが、HCLの中に素のJSONがあるのはかなり可読性が下がりますし、何より補完などが効かなくてあまりスマートなやり方ではありません。
なのでこの部分をdataを使って定義すると、JSONをHCLで構造化できるようになります。

data "aws_iam_policy_document" "ec2" {
  statement {
    actions = ["sts:AssumeRole"]
    principals {
      type        = "Service"
      identifiers = ["ec2.amazonaws.com"]
    }
  }
}

書き方は上記のようになります。これをJSONで書こうとすると、ドキュメントの通りになります。

registry.terraform.io

resource "aws_iam_role" "test_role" {
  name = "test_role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Effect": "Allow",
      "Sid": ""
    }
  ]
}
EOF

  tags = {
    tag-key = "tag-value"
  }
}

HCLの中にいきなりJSONなので面くらいますね。
私も最初はそのまま書いてたりしたのですが、データソースを知ってからはそちらを使うようにしています。
ぱっと見でも違いがわかって頂けたかと思います。

データソースはあくまでもTerraform内でリソースが存在するかのように扱います。
なのでソースが変更されると、実際のクラウドリソースを変更するのではなく、参照先のリソースに影響を及ぼします。
ここが一番の違いで、意識しないといけない部分でもあります。

今回はデータソースに関してでした。
今後もどんどん使っていって、あらゆるリソースのコード化を推進していきたいと思います。