Aws application load balancer cannot enable access logs via terraform only via console even after applying policies

I have an application load balancer and I’m trying to enable logging, terraform code below:


resource "aws_s3_bucket" "lb-logs" {
  bucket = "yeo-messaging-${var.environment}-lb-logs"
}

resource "aws_s3_bucket_acl" "lb-logs-acl" {
  bucket = aws_s3_bucket.lb-logs.id
  acl    = "private"
}


resource "aws_lb" "main" {
  name                       = "main"
  internal                   = false
  load_balancer_type         = "application"
  security_groups            = [aws_security_group.public.id]
  enable_deletion_protection = false
  subnets                    = [aws_subnet.public.id, aws_subnet.public-backup.id]

  access_logs {
    bucket  = aws_s3_bucket.lb-logs.bucket
    prefix  = "main-lb"
    enabled = true
  }
}

unfortunately I can’t apply this due to:

Error: failure configuring LB attributes: InvalidConfigurationRequest: Access Denied for bucket: xxx-lb-logs. Please check S3bucket permission
│       status code: 400, request id: xx

I’ve seen a few SO threads and documentation but unfortunately it all applies to the classic load balancer, particularly the ‘data’ that allows you to get the service account of the laod balancer.

I have found some policy info on how to apply the right permissions to a SA but I can’t seem to find how to apply the service account to the LB itself.

Example:

data "aws_iam_policy_document" "allow-lb" {
  statement {
    principals {
      type        = "AWS"
      identifiers = [data.aws_elb_service_account.main.arn]
    }

    actions = [
      "s3:GetObject",
      "s3:ListBucket",
      "s3:PutObject"
    ]

    resources = [
      aws_s3_bucket.lb-logs.arn,
      "${aws_s3_bucket.lb-logs.arn}/*",
    ]
  }
}


resource "aws_s3_bucket_policy" "allow-lb" {
  bucket = aws_s3_bucket.lb-logs.id
  policy = data.aws_iam_policy_document.allow-lb.json
}

But this is all moot because data.aws_elb_service_account.main.arn is only for classic LB.


EDIT:

Full code with attempt from answer below:


resource "aws_s3_bucket" "lb-logs" {
  bucket = "yeo-messaging-${var.environment}-lb-logs"
}

resource "aws_s3_bucket_acl" "lb-logs-acl" {
  bucket = aws_s3_bucket.lb-logs.id
  acl    = "private"
}

data "aws_iam_policy_document" "allow-lb" {
  statement {
    principals {
      type        = "Service"
      identifiers = ["logdelivery.elb.amazonaws.com"]
    }

    actions = [
      "s3:PutObject"
    ]

    resources = [
      "${aws_s3_bucket.lb-logs.arn}/*"
    ]

    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"

      values = [
        "bucket-owner-full-control"
      ]
    }
  }
}

resource "aws_s3_bucket_policy" "allow-lb" {
  bucket = aws_s3_bucket.lb-logs.id
  policy = data.aws_iam_policy_document.allow-lb.json
}


resource "aws_lb" "main" {
  name                       = "main"
  internal                   = false
  load_balancer_type         = "application"
  security_groups            = [aws_security_group.public.id]
  enable_deletion_protection = false
  subnets                    = [aws_subnet.public.id, aws_subnet.public-backup.id]

  access_logs {
    bucket  = aws_s3_bucket.lb-logs.bucket
    prefix  = "main-lb"
    enabled = true
  }
}
1 Like

@sebastiangug hello,
I’m experiencing exactly the same issue.
Could you please tell, have you figured how to config LB with S3 bucket?

Edited

this helped me. The problem was in prefix declared in aws_lb access_logs.

Please share your code and the error you’re getting. Or is it already fixed?

@macmiranda yes, the link from above helped me to resolve my issue, thank you :slight_smile: