0
votes

I am learning how to automate infrastructure with terraform. Currently I have an application load balancer and I am looking to send logs from this into an S3 bucket. I have a json file created that specifies the policy but when I try to apply the terraform code, I am being presented with the following error:

error when applying Terraform code

I've checked my AWS Account number, checked the permissions of the user I am logged in, and cannot figure out why this is happening. Below is the also the code for my policy along with the creation of the S3 buckets. Any advice would appreciated.

Policy

{
"Version": "2012-10-17",
"Id": "javahome-alb-policy",
"Statement": [
    {
        "Sid": "root-access",
        "Effect": "Allow",
        "Principle": {
            "Service": "arn:aws:iam::aws-account-id:root"
        },
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::${access_logs_bucket}/AWSLogs/aws-account-id/*"
    },
    {
        "Sid": "log-delivery",
        "Effect": "Allow",
        "Principle": {
            "Service": "delivery.logs.amazonaws.com"
        },
        "Action": "s3:PutObject",
        "Resource": "arn:aws:s3:::${access_logs_bucket}/AWSLogs/aws-account-id/*",
        "Condition": {
            "StringEquals": {
                "s3:x-amz-acl": "bucket-owner-full-control"
            }
        }
    },
    {
        "Sid": "log-delivery-access-check",
        "Effect": "Allow",
        "Principle": {
            "Service": "delivery.logs.amazonaws.com"
        },
        "Action": "s3:GetBucketAcl",
        "Resource": "arn:aws:s3:::${access_logs_bucket}"
    }
]

}

S3 Bucket

resource "aws_s3_bucket" "alb_access_logs" {


bucket = var.alb_s3_logs
  policy = data.template_file.javahome.rendered
  acl    = "private"
  region = var.region
  tags = {
    Name        = "jalb-access-logs"
    Environment = terraform.workspace
  }
}

Application Load Balancer

resource "aws_lb_target_group" "javahome" {


name     = var.lb_tg_name
  port     = var.http_port
  protocol = "HTTP"
  vpc_id   = aws_vpc.my_app.id
}

resource "aws_lb_target_group_attachment" "javahome" {
  count            = var.web_ec2_count
  target_group_arn = aws_lb_target_group.javahome.arn
  target_id        = aws_instance.web.*.id[count.index]
  port             = var.http_port
}
resource "aws_lb" "javahome" {
  name               = var.alb_name
  internal           = false
  load_balancer_type = var.lb_type
  security_groups    = [aws_security_group.elb_sg.id]
  subnets            = local.pub_sub_ids

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

  tags = {
    Environment = terraform.workspace
  }
}

resource "aws_lb_listener" "listener" {
  load_balancer_arn = aws_lb.javahome.arn
  port              = var.http_port
  protocol          = "HTTP"

  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.javahome.arn
  }
}

data "template_file" "javahome" {
  template = file("scripts/iam/alb-s3-access-logs.json")
  vars = {
    access_logs_bucket = var.alb_s3_logs
  }
}
1

1 Answers

0
votes

The main problem here is the misspelled Principle, the right syntax is Principal. Also, check the documentation for the source of logs, which is an AWS account directly managed by AWS.

Here an example from AWS Docs:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::aws-account-id:root"
      },
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::bucket-name/prefix/*"
    }
  ]
}

https://docs.aws.amazon.com/en_us/elasticloadbalancing/latest/application/load-balancer-access-logs.html

Enable Access Logging

When you enable access logging for your load balancer, you must specify the name of the S3 bucket where the load balancer will store the logs. The bucket must be in the same Region as your load balancer, and must have a bucket policy that grants Elastic Load Balancing permission to write the access logs to the bucket. The bucket can be owned by a different account than the account that owns the load balancer.

P.S. posting account ID is not a good practice.