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の公式を読めばなんとかなるでしょう。
さらばヒアドキュメント!!