この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは!この前ついにドラム式洗濯機を大人買いしてしまったつくぼし(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"
}
]
}
以下の公式ページに記載があります。
コード内容
main.tf
#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のコードを書いているつくぼしでした!