ALBのアクセスログ用S3バケットポリシーをTerraformで書いてみた
こんにちは!この前ついにドラム式洗濯機を大人買いしてしまったつくぼし(tsukuboshi0755)です!
ALBにアクセスログを設定したい場合、ALBがS3にアクセスできるようにバケットポリシーを書き換える必要があります。
この書き換えをTerraformで実施する場合、各々の環境毎にバケットポリシー用のjsonファイルを用意しても良いのですが、どの環境でも使用できる汎用的なバケットポリシーをtfファイルで作成してみました。
環境
$ terraform -v Terraform v1.1.7 on darwin_arm64
対象バケットポリシー
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::elb-account-id:root" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::bucket-name/prefix/AWSLogs/your-aws-account-id/*" }, { "Effect": "Allow", "Principal": { "Service": "delivery.logs.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::bucket-name/prefix/AWSLogs/your-aws-account-id/*", "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control" } } }, { "Effect": "Allow", "Principal": { "Service": "delivery.logs.amazonaws.com" }, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::bucket-name" } ] }
以下の公式ページに記載があります。
コード内容
#ELBアカウントIDの取得 data "aws_elb_service_account" "tf_elb_service_account" {} #AWSアカウントIDの取得 data "aws_caller_identity" "tf_caller_identity" {} #ALBログ用プレフィックスの設定 variable "alb_log_prefix" { default = "xxxxxxxxxxxxxxxxxxxx" #任意の名前 } #ALBログ用バケット名の設定 variable "bucket_name_alb_log" { default = "xxxxxxxxxxxxxxxxxxxx" #任意の名前 } #ALBログ用バケットの作成 resource "aws_s3_bucket" "tf_bucket_alb_log" { bucket = "${var.bucket_name_alb_log}-${data.aws_caller_identity.tf_caller_identity.account_id}" } #ALBログ用バケットポリシーの作成 data "aws_iam_policy_document" "tf_iam_policy_document_alb_log" { statement { effect = "Allow" principals { type = "AWS" identifiers = ["arn:aws:iam::${data.aws_elb_service_account.tf_elb_service_account.id}:root"] } actions = ["s3:PutObject"] resources = ["arn:aws:s3:::${aws_s3_bucket.tf_bucket_alb_log.bucket}/${var.alb_log_prefix}/AWSLogs/${data.aws_caller_identity.tf_caller_identity.account_id}/*"] } statement { effect = "Allow" principals { type = "Service" identifiers = ["delivery.logs.amazonaws.com"] } actions = ["s3:PutObject"] resources = ["arn:aws:s3:::${aws_s3_bucket.tf_bucket_alb_log.bucket}/${var.alb_log_prefix}/AWSLogs/${data.aws_caller_identity.tf_caller_identity.account_id}/*"] condition { test = "StringEquals" variable = "s3:x-amz-acl" values = ["bucket-owner-full-control"] } } statement { effect = "Allow" principals { type = "Service" identifiers = ["delivery.logs.amazonaws.com"] } actions = ["s3:GetBucketAcl"] resources = ["arn:aws:s3:::${aws_s3_bucket.tf_bucket_alb_log.bucket}"] } } #バケットポリシーの書き換え resource "aws_s3_bucket_policy" "tf_bucket_policy_alb_log" { bucket = aws_s3_bucket.tf_bucket_alb_log.id policy = data.aws_iam_policy_document.tf_iam_policy_document_alb_log.json }
解説
ELBアカウントID
公式バケットポリシーのelb-account-id
に該当する、リージョンに応じたELBのアカウントIDです。
Terraformではaws_elb_service_account
というData Sourceを用いて、ELBアカウントIDをリージョン毎に動的に取得可能です!
原則AWS Provider設定のregionに指定している値に応じて、対応するELBアカウントIDを取得できます。
(例:ap-northeast-1→ELBアカウントID"582318560864"を取得)
AWSアカウントID
公式バケットポリシーのyour-aws-account-id
に該当する、自身のAWSアカウントIDです。
Terraformではaws_caller_identity
というData Sourceを用いて、AWSアカウントIDも取得可能です。
プレフィックス
公式バケットポリシーのprefix
に該当する、ALBログ用バケットの階層です。
今回はInput Variablesを用いて、任意の値を指定できるようにしました。
バケット名
公式バケットポリシーのbucket-name
に該当する、ALBログ用バケットの名前です。
こちらもプレフィックスと同じく、Input Variablesで任意の値を指定できるようにしてます。
今回はInput VariablesにAWSアカウントIDを追記する事で、一意なバケット名を作成しやすくしました!
終わりに
terraformでバケットポリシーのようなjson形式の情報が必要な場合、tfファイルに組み込む事でID情報等を動的に取得できるのでオススメです!
他の環境にも流用できて便利なので、皆さんもTerraformでjsonを使用する場合はtfファイルに組み込めないか検討してみてはいかがでしょうか?
ちなみに俺はCloudFormationでバケットポリシー書きたいんだ!という人は、以下の記事も参照してみて下さい!
以上、最近ひたすらTerraformのコードを書いているつくぼしでした!