Home > Mobile >  Error: error putting S3 bucket (s3-bucket-master-xxxxxx) logging: CrossLocationLoggingProhibitted: C
Error: error putting S3 bucket (s3-bucket-master-xxxxxx) logging: CrossLocationLoggingProhibitted: C

Time:07-13

I am creating two S3 buckets to keep logs, I want SRR Same Region Replication. Whilst I am not so much familiar with S3 service my code has worked except for the last stage of adding logging to make tfsec and checkov, compliant

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.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" {
  provider      = aws.apac
  bucket_prefix = "s3-bucket-master-"
}

resource "aws_s3_bucket_server_side_encryption_configuration" "s3_bucket_master_sse_config" {
  bucket   = aws_s3_bucket.s3_bucket_master.bucket
  provider = aws.apac
  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = aws_kms_key.kms_key.arn
      sse_algorithm     = "aws:kms"
    }
  }
}

resource "aws_s3_bucket_versioning" "s3_bucket_master_versioning" {
  provider = aws.apac

  bucket = aws_s3_bucket.s3_bucket_master.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_replication_configuration" "s3_bucket_master_replication" {
  provider = aws.apac
  # 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"
  provider = aws.apac
}

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" {
  provider                = alias.apac
  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" {
  provider = alias.apac
  bucket   = aws_s3_bucket.s3_bucket_master.id

  target_bucket = aws_s3_bucket.s3_bucket_slave.id
  target_prefix = "log/"
}

provider.tf

terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.22.0"
    }
    null = {
      source  = "hashicorp/null"
      version = "3.1.1"
    }
    alias = {
      source  = "hashicorp/aws"
      version = "4.22.0"
    }
  }
}
provider "null" {
  # Configuration options
}

# Configure AWS provider:

provider "aws" {
  region = "ap-southeast-2"
}

provider "aws" {
  alias  = "apac"
  region = "ap-southeast-1"
}

kms.tf

resource "aws_kms_key" "kms_key" {
  description             = "This key is used to encrypt bucket objects"
  deletion_window_in_days = 10
  enable_key_rotation     = true
}

Unfortunately, I am getting errors like the below:

╷
│ Warning: Duplicate required provider
│
│   on provider.tf line 4, in terraform:
│    4:     aws = {
│    5:       source  = "hashicorp/aws"
│    6:       version = "4.22.0"
│    7:     }
│
│ Provider hashicorp/aws with the local name "aws" was previously required as "alias". A provider can only be required once within required_providers.   
│
│ (and one more similar warning elsewhere)
╵
╷
│ Error: error putting S3 bucket (s3-bucket-master-20220712130829925900000001) logging: CrossLocationLoggingProhibitted: Cross S3 location logging not allowed.
│       status code: 403, request id: 85528RE6KMQJDMJM, host id: 3cpcDdHT3Wl442f7L/x3VLCp26wCghaIPTwKKhnWLOmsTW4cSI9f5pFROHr7q4fDLQJMyfNBZIA=
│
│   with aws_s3_bucket_logging.example,
│   on s3.tf line 166, in resource "aws_s3_bucket_logging" "example":
│  166: resource "aws_s3_bucket_logging" "example" {
│
╵

What help I am seeking from more experienced people is

  1. What part code do I need to delete to make SRR? thereby resolve the error.

  2. Any idea how to suppress the warning for alias?

Do note if I remote the section

    alias = {
      source  = "hashicorp/aws"
      version = "4.22.0"
    }

I get errors like the below for ** terraform init **

│ Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider hashicorp/alias: provider registry registry.terraform.io does not have a provider named 
│ registry.terraform.io/hashicorp/alias
│
│ All modules should specify their required_providers so that external consumers will get the correct providers when using a module. To see which        
│ modules are currently depending on hashicorp/alias, run the following command:
│     terraform providers
╵


terraform providers

Providers required by configuration:
.
├── provider[registry.terraform.io/hashicorp/aws] 4.22.0
├── provider[registry.terraform.io/hashicorp/null] 3.1.1
└── provider[registry.terraform.io/hashicorp/alias]

Providers required by state:

    provider[registry.terraform.io/hashicorp/aws]

CodePudding user response:

You don't need to define the aws twice in the required_providers block, it's enough to be defined only once:

terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.22.0"
    }
    null = {
      source  = "hashicorp/null"
      version = "3.1.1"
    }
  }
}

Then, you need to remove the .terraform directory prior to re-running terraform init to make sure you have a clean slate. Lastly, make sure if you want SRR and not CRR to use either the aliased or non-aliased provider, but not both.

So you are currently defining one of the buckets as:

resource "aws_s3_bucket" "s3_bucket_slave" {
  bucket_prefix = "s3-bucket-slave-"
}

And the second one as:

resource "aws_s3_bucket" "s3_bucket_master" {
  provider      = aws.apac # <---- note the aliased provider, hence a different region
  bucket_prefix = "s3-bucket-master-"
}

In order to fix that, either remove the aliased provider from the second bucket or add it to the first one. As you current configuration is using aws.apac in more places than it is not, I would suggest adding the aliased provider to the first bucket if the region is not important:

resource "aws_s3_bucket" "s3_bucket_slave" {
  provider      = aws.apac
  bucket_prefix = "s3-bucket-slave-"
}
  • Related