TerraformでS3のバケットポリシーを書く方法

TerraformでS3のバケットポリシーを書く方法
目次

インフラのコード化を進める作業では、コード化のライブラリ作法に倣うため、ドキュメントを見ながら設定を書いていくことが多いです。

Terraform も例外ではないのですが、S3バケットのポリシー設定の所でふと気付いたので書いておきます。

Terraform公式のS3のバケットポリシーが…

Terraform公式の aws_s3_bucket_policy のリソースは policy の部分がヒアドキュメントで書かれています。

 1resource "aws_s3_bucket" "b" {
 2  bucket = "my_tf_test_bucket"
 3}
 4
 5resource "aws_s3_bucket_policy" "b" {
 6  bucket = "${aws_s3_bucket.b.id}"
 7  policy =<<POLICY
 8{
 9  "Version": "2012-10-17",
10  "Id": "MYBUCKETPOLICY",
11  "Statement": [
12    {
13      "Sid": "IPAllow",
14      "Effect": "Deny",
15      "Principal": "*",
16      "Action": "s3:*",
17      "Resource": "arn:aws:s3:::my_tf_test_bucket/*",
18      "Condition": {
19         "IpAddress": {"aws:SourceIp": "8.8.8.8/32"}
20      }
21    }
22  ]
23}
24POLICY
25}

だめではないのですが、折角コード化を進めているので、ここもキレイにしたいですよね。

IAMポリシードキュメントのデータソース(aws_iam_policy_document)を使う

結論から言うと、 aws_iam_policy_document のデータソースを使用することができます。

データソース名から 「IAMにしか適用できないのでは?」 と思うかもしれませんが、結局はポリシードキュメントなので使えます。

 1resource "aws_s3_bucket" "b" {
 2  bucket = "my_tf_test_bucket"
 3}
 4
 5resource "aws_s3_bucket_policy" "b" {
 6  bucket = "${aws_s3_bucket.b.id}"
 7  policy = "${aws_iam_policy_document.bucket_policy_document.json}"
 8}
 9
10data "aws_iam_policy_document" "bucket_policy_document" {
11
12    statement {
13        sid = "IPAllow"
14        effect = "Deny"
15        principals {
16            type = "*"
17            identifiers = ["*"]
18        }
19        actions = [
20            "s3:*"
21        ]
22        resources = [
23            "arn:aws:s3:::my_tf_test_bucket/*"
24        ]
25        condition {
26            test = "IpAddress"
27            variable = "aws:SourceIp"
28            values = [
29              "8.8.8.8/32"
30            ]
31        }
32    }
33}

ポイントは policy = "${aws_iam_policy_document.bucket_policy_document.json}" の所です。

データソースをJSON文字列にしてくれます。

AWS公式の IAM JSON ポリシーエレメント: 条件演算子 にもある通り、 IpAddress も条件演算子のひとつとして定義されているので、ちゃんと condition ブロックで使えます。

強いてクセを挙げるとしたら、

1"Principal": "*",

を表現するために

1principals {
2    type = "*"
3    identifiers = ["*"]
4}

と記述しないといけない所でしょうか。

まとめ

S3バケットのポリシードキュメントも aws_iam_policy_document を使えば、Terraformのコードとして管理できます。 HCLからポリシードキュメント(JSON)を生成するために、微妙に書き方が違う部分がありますが、それは普段通りTerraformの公式を読めばなんとかなるでしょう。 さらばヒアドキュメント!!

参考にさせていただいたサイト