s3.tf
resource "aws_iam_role" "iam_role_replication" {
name = "tf-iam-role-replication-12345"
assume_role_policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
POLICY
}
resource "aws_iam_policy" "iam_policy_replication" {
name = "tf-iam-role-policy-replication-12345"
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:GetReplicationConfiguration",
"s3:ListBucket"
],
"Effect": "Allow",
"Resource": [
"${aws_s3_bucket.s3_bucket_master.arn}"
]
},
{
"Action": [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging"
],
"Effect": "Allow",
"Resource": [
"${aws_s3_bucket.s3_bucket_master.arn}/*"
]
},
{
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags"
],
"Effect": "Allow",
"Resource": "${aws_s3_bucket.s3_bucket_slave.arn}/*"
}
]
}
POLICY
}
resource "aws_iam_role_policy_attachment" "replication" {
role = aws_iam_role.iam_role_replication.name
policy_arn = aws_iam_policy.iam_policy_replication.arn
}
resource "aws_s3_bucket" "s3_bucket_slave" {
bucket_prefix = "s3-bucket-slave-"
}
resource "aws_s3_bucket_server_side_encryption_configuration" "s3_bucket_slave_sse_config" {
bucket = aws_s3_bucket.s3_bucket_slave.bucket
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.s3_kms_key.arn
sse_algorithm = "aws:kms"
}
}
}
resource "aws_s3_bucket_versioning" "s3_bucket_slave_versioning" {
bucket = aws_s3_bucket.s3_bucket_slave.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket" "s3_bucket_master" {
bucket_prefix = "s3-bucket-master-"
}
resource "aws_s3_bucket_policy" "s3_bucket_master_alb_put_policy" {
bucket = aws_s3_bucket.s3_bucket_master.id
policy = <<POLICY
{
"Id": "Policy",
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "${aws_s3_bucket.s3_bucket_master.arn}/access-logs-bucket/*",
"Principal": {
"AWS": [
"${data.aws_elb_service_account.main.arn}"
]
}
}
]
}
POLICY
}
resource "aws_s3_bucket_server_side_encryption_configuration" "s3_bucket_master_sse_config" {
bucket = aws_s3_bucket.s3_bucket_master.bucket
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.s3_kms_key.arn
sse_algorithm = "aws:kms"
}
}
}
resource "aws_s3_bucket_versioning" "s3_bucket_master_versioning" {
bucket = aws_s3_bucket.s3_bucket_master.id
versioning_configuration {
status = "Enabled"
}
}
resource "aws_s3_bucket_replication_configuration" "s3_bucket_master_replication" {
# Must have bucket versioning enabled first
depends_on = [aws_s3_bucket_versioning.s3_bucket_master_versioning]
role = aws_iam_role.iam_role_replication.arn
bucket = aws_s3_bucket.s3_bucket_master.id
rule {
id = "foobar"
delete_marker_replication {
status = "Disabled"
}
filter {
prefix = "foo"
}
status = "Enabled"
destination {
bucket = aws_s3_bucket.s3_bucket_slave.arn
storage_class = "STANDARD"
}
}
}
resource "aws_s3_bucket_acl" "s3_bucket_master_acl" {
bucket = aws_s3_bucket.s3_bucket_master.id
acl = "private"
}
resource "aws_s3_bucket_acl" "s3_bucket_slave_acl" {
bucket = aws_s3_bucket.s3_bucket_slave.id
acl = "log-delivery-write"
}
resource "aws_s3_bucket_public_access_block" "s3_bucket_master_public_access" {
bucket = aws_s3_bucket.s3_bucket_master.id
restrict_public_buckets = true
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
}
resource "aws_s3_bucket_public_access_block" "s3_bucket_slave_public_access" {
bucket = aws_s3_bucket.s3_bucket_slave.id
restrict_public_buckets = true
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
}
resource "aws_s3_bucket_logging" "example" {
bucket = aws_s3_bucket.s3_bucket_master.id
target_bucket = aws_s3_bucket.s3_bucket_slave.id
target_prefix = "log/"
}
alb.tf
####################################################
# Target Group Creation
####################################################
resource "aws_lb_target_group" "lb_tg" {
name = "alb-target-group"
port = 80
target_type = "instance"
protocol = "HTTP"
vpc_id = aws_vpc.vpc.id
}
####################################################
# Target Group Attachment with Instance
####################################################
resource "aws_alb_target_group_attachment" "tg_attachment" {
count = length(aws_instance.instance.*.id) == 3 ? 3 : 0
target_group_arn = aws_lb_target_group.lb_tg.arn
target_id = element(aws_instance.instance.*.id, count.index)
}
####################################################
# Application Load balancer
####################################################
resource "aws_lb" "lb" {
name = "alb"
internal = true
load_balancer_type = "application"
security_groups = [aws_security_group.sg.id, ]
subnets = aws_subnet.public_subnet.*.id
drop_invalid_header_fields = true
access_logs {
bucket = aws_s3_bucket.s3_bucket_master.bucket
prefix = "access-logs-bucket"
enabled = true
}
enable_deletion_protection = true
}
####################################################
# Listner
####################################################
resource "aws_lb_listener" "front_end" {
load_balancer_arn = aws_lb.lb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "redirect"
redirect {
port = "443"
protocol = "HTTPS"
status_code = "HTTP_301"
}
}
}
####################################################
# Listener Rule
####################################################
resource "aws_lb_listener_rule" "static" {
listener_arn = aws_lb_listener.front_end.arn
priority = 100
action {
type = "forward"
target_group_arn = aws_lb_target_group.lb_tg.arn
}
condition {
path_pattern {
values = ["/var/www/html/index.html"]
}
}
}
data.tf
# Get user
data "aws_caller_identity" "current" {}
# Get Account
data "aws_elb_service_account" "main" {}
Unfortunately, I am getting errors like the below:
╷
│ Error: failure configuring LB attributes: InvalidConfigurationRequest: Access Denied for bucket: s3-bucket-master-20220713230235453200000002. Please check S3bucket permission
│ status code: 400, request id: 17cb8a1b-d914-4fe5-b6cd-5db02f335cc4
│
│ with aws_lb.lb,
│ on alb.tf line 27, in resource "aws_lb" "lb":
│ 27: resource "aws_lb" "lb" {
│
╵
I followed the article from Terraform ELB S3 Permissions Issue
I am struggling to understand what exactly is the issue!?
P.S Edit 1: Amended the S3 Resource Name as per recommendation but I am still getting the error of access denied.
CodePudding user response:
It seems you have just copy/pasted the example from the documentation [1]:
resource "aws_s3_bucket" "s3_bucket_master" {
bucket_prefix = "s3-bucket-master-"
}
resource "aws_s3_bucket_policy" "s3_bucket_master_alb_put_policy" {
bucket = aws_s3_bucket.s3_bucket_master.id
policy = <<POLICY
{
"Id": "Policy",
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:PutObject"
],
"Effect": "Allow",
"Resource": "arn:aws:s3:::my-elb-tf-test-bucket/AWSLogs/*",
"Principal": {
"AWS": [
"${data.aws_elb_service_account.main.arn}"
]
}
}
]
}
POLICY
}
If you look at the ARN it is for a bucket that does not exist:
"arn:aws:s3:::my-elb-tf-test-bucket/AWSLogs/*"
You want the ARN of the master bucket if I am reading this right. So you would use the following ARN and the prefix defined in the prefix
argument of the access_logs
block in the aws_lb
resource:
"${aws_s3_bucket.s3_bucket_master.arn}/access-logs-bucket/AWSLogs/${data.aws_caller_identity.current.id}/*"
EDIT: The prefix has to be there along with the AWSLogs
and the AWS account ID as per [2].
[2] https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-access-logs.html
CodePudding user response:
The following line needs further correction:
Incorrect:
"Resource": "${aws_s3_bucket.s3_bucket_master.arn}/access-logs-bucket/*",
Correct:
"Resource": "${aws_s3_bucket.s3_bucket_master.arn}/access-logs-bucket/AWSLogs/${data.aws_caller_identity.current.account_id}/*",
I think the .current.account_id
on the aws_caller_identity
was not considered in previous answer.