kakakakakku blog

Weekly Tech Blog: Keep on Learning!

Terraform で ALB のアクセスログを設定するときに InvalidConfigurationRequest と出たら

Terraform で ALB (Application Load Balancer) を構築するときに「アクセスログ」を Amazon S3 に流す設定をすると,以下のように InvalidConfigurationRequest というエラーが出る場合がある⚡️エラーをよく読むと Please check S3bucket permission と書いてあって「バケットポリシー」に関係していそうだと予想はできても多少わかりにくく,どう解消するのかをまとめておく❗️

│ Error: failure configuring LB attributes: InvalidConfigurationRequest: Access Denied for bucket: kakakakakku-alb-logs. Please check S3bucket permission
│     status code: 400, request id: 96d74a1a-1331-48dc-990a-404e39e0cb3a

Terraform: NG 例 🙅‍♂️

まず,上記エラーが出てしまう Terraform の NG 例を載せておく.セキュリティグループやサブネットなどの値はサンプルとして固定値を設定している.

resource "aws_lb" "alb" {
  name               = "kakakakakku-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = ["sg-00000000000000000"]
  subnets            = ["subnet-00000000000000000", "subnet-00000000000000000", "subnet-00000000000000000"]

  access_logs {
    enabled = true
    bucket  = aws_s3_bucket.alb_logs.bucket
  }
}

resource "aws_s3_bucket" "alb_logs" {
  bucket = "kakakakakku-alb-logs"
}

よくある設定だし,ドキュメントの access_logs あたりに注釈でも入ってると良いのになぁ〜とは思ったりする💡

ELB (Elastic Load Balancing) サービスアカウントとは 🌍

エラーを解消する前に,ALB のアクセスログを Amazon S3 に流す場合は「ELB (Elastic Load Balancing) サービスアカウント」に対して Amazon S3 への権限を与える必要があるという仕様を以下のドキュメントを読んで理解しておく.さらにアカウントはリージョンごとに異なる点も要注意❗️

  • 米国東部 (バージニア北部): 127311923021
  • 米国西部 (オレゴン): 797873946194
  • アジアパシフィック (東京): 582318560864
  • アジアパシフィック (大阪): 383597477331
  • etc

docs.aws.amazon.com

そして「バケットポリシー」のサンプルもドキュメントに載っている👌

{
  "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/*"
    }
  ]
}

Terraform: OK 例 🙆‍♂️

次に Terraform の OK 例を載せておく😃

data "aws_caller_identity" "current" {}
data "aws_elb_service_account" "main" {}

resource "aws_lb" "alb" {
  name               = "kakakakakku-alb"
  internal           = false
  load_balancer_type = "application"
  security_groups    = ["sg-00000000000000000"]
  subnets            = ["subnet-00000000000000000", "subnet-00000000000000000", "subnet-00000000000000000"]

  access_logs {
    enabled = true
    bucket  = aws_s3_bucket.alb_logs.bucket
  }
}

resource "aws_s3_bucket" "alb_logs" {
  bucket = "kakakakakku-alb-logs"
}

resource "aws_s3_bucket_policy" "alb_logs_policy" {
  bucket = aws_s3_bucket.alb_logs.id
  policy = data.aws_iam_policy_document.alb_logs_policy_document.json
}

data "aws_iam_policy_document" "alb_logs_policy_document" {
  statement {
    effect = "Allow"
    principals {
      type        = "AWS"
      identifiers = [data.aws_elb_service_account.main.arn]
    }
    actions   = ["s3:PutObject"]
    resources = ["${aws_s3_bucket.alb_logs.arn}/AWSLogs/${data.aws_caller_identity.current.account_id}/*"]
  }
}

aws_s3_bucket_policy Resource と aws_iam_policy_document Data Source を追加して,Amazon S3 バケットにバケットポリシーを追加すれば InvalidConfigurationRequest エラーは解消できる.

ポイント1点目は principals.identifiers に設定している data.aws_elb_service_account.main.arn で,aws_elb_service_account Data Source を使って「ELB (Elastic Load Balancing) サービスアカウント」を取得している.例えば "東京リージョン" なら 383597477331 など固定値を設定することもできるけど,リージョンごとに異なる値を設定できるメリットがある❗️

ポイント2点目は resources に設定している data.aws_caller_identity.current.account_id で,aws_caller_identity Data Source を使って「自分自身のアカウント」を取得している.

terraform apply を実行すると

最終的に terraform apply を実行すると Apply complete! となり「バケットポリシー」は以下のように期待通り設定される❗️今回は "東京リージョン" で実行しているため,ちゃんと ELB (Elastic Load Balancing) サービスアカウント 582318560864 が設定されている✌

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::582318560864:root"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::kakakakakku-alb-logs/AWSLogs/000000000000/*"
        }
    ]
}