Terraformでテンプレートを使ってポリシーを定義する

Terraformにはテンプレート機能がある。よく使われるのは、ポリシーの設定などで、ヒアドキュメントで記述されるようなものを、別ファイルに記述し変数を与えて埋めていく。

ポリシーを定義する

例えば、ユーザやグループにポリシーを設定するために、まずポリシーを定義する。 ここで、 bucket_name は変数になっている。ポリシーの意味は ${bucket_name} 以下にあるオブジェクトに対しての操作を全て許可するというもの。リソースの最後に /* をつけないとバケットの操作1になってしまうので注意。 これを、 s3_bucket_policy.tpl.json というファイルに保存しておこう。拡張子を json とかにしておいたほうがシンタックスハイライトの恩恵が受けられる(と個人的には思う)。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "*",
      "Resource": [
        "arn:aws:s3:::${bucket_name}/*",
      ]
    }
  ]
}

IAM Policy リソースの定義

次に、リソースを定義しよう。 今までは policy<<EOF ... EOF などを書いてポリシーを埋め込んでいたと思う。 ココも変数にする。

resource "aws_iam_policy" "developer" {
    name = "developer_policy"
    path = "/developer"
    description = "Developer IAM policy"
    policy = "${data.template_file.foo.rendered}"
}

Template データの定義

最後にテンプレートの定義をしていこう。datatemplate_fileを定義する。 template には最初で作成したファイルを指定する。fileメソッドを使うとファイルを引っ張って来ることができ、引数にはパス、ファイル名を与えよう。最初に作成したファイル名はs3_bucket_policy.tpl.jsonなので、それを指定する。

テンプレート内にbukcet_nameという変数があったが、それをここで埋める。 varsのマップを記述すると、そのままテンプレートに渡され、埋められる。

data "template_file" "foo" {
  template = "${file("s3_bucket_policy.tpl.json")}"

  vars {
    bucket_name = "bar"
  }
}

bukcet_name をTerraformで作成したバケットにしたい場合は、varsに変数を与えればいい。

resource "aws_s3_bucket" "bar" {
  bucket = "dev-var-bucket"
  acl    = "private"
}

data "template_file" "foo" {
  template = "${file("s3_bucket_policy.tpl.json")}"

  vars {
    bucket_name = "${aws_s3_bucket.bar.bucket}"
  }
}

Appendix

AWS_IAM_POLICY_DOCUMENT resource

AWS IAMポリシーの作成はHCLで記述できることを @mia_0032 さんから教えていただきました。 Terraform version 0.7.0 から aws_iam_policy_document リソースが入っていた(CHANGELOG)。

New Data Source: aws_iam_policy_document (#6881)

これのメリットをちょっと考えてみると次のような感じだと思う。

  • HCLのシンタックスハイライトを使ってポリシーを書ける
  • plan 実行時にある程度の構文チェックができる
  • 書くものが減りすこしスッキリする(テンプレートの方式だと、 json ファイル、 data ソース、 aws_iam_policy リソースを用意しないといけない)

結構、多くのメリットがありそう。

ぼくがポリシーを書くときは、AWSコンソールで直接ポリシーを作成して、検証しながらJSONを組み立てていく。整ったところで、JSONをコピーし、変数になる部分の記述を変換してテンプレートを仕上げている。

JSONのポリシーをHCLに変換してくれる何かがほしい。 ちょっと調べてみた感じだとありそう(kvz/json2hcl)。

References