Bootstrap FreeKB - Amazon Web Services (AWS) - Update S3 Bucket Access Control Lists (ACLs) using Terraform
Amazon Web Services (AWS) - Update S3 Bucket Access Control Lists (ACLs) using Terraform


This assumes you have setup Terraform with the Amazon Web Services (AWS) provider. If not, check out my article Amazon Web Services (AWS) Getting Started with Terraform.

An S3 Bucket is similar to an NFS share in that it is a mountable storage volume (using s3fs fuse). However, one thing that is really cool is that you can interact with an S3 Bucket without having to mount the S3 Bucket on your system. For example, you could use boto to do things like upload and download files in the S3 Bucket.

By default, an S3 Bucket will be set with Access Control Lists (ACLs) disabled so that only the owner of the S3 Bucket can view and create objects in the bucket. The aws_s3_bucket_acl resource module can be used to enable Access Control Lists (ACLs) and to set Access Controls, such as giving the Log Delivery group permission to create (write) objects in the S3 Bucket.

Let's say you have the following files on your Terraform server.

├── required_providers.tf
├── s3_buckets (directory)
│   ├── buckets.tf
│   ├── provider.tf

 

required_providers.tf will almost always have this.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
    }
  }
}

 

Let's say provider.tf in the network_load_balancer directory has the following. In this example, the "default" profile in /home/username/.aws/config and /home/username/.aws/credentials is being used. This assumes you have setup Terraform as described in Amazon Web Services (AWS) - Getting Started with Terraform.

provider "aws" {
  alias   = "default"
  profile = "default"
  region  = "default"
}

 

And buckets.tf could have the following. By default, S3 Buckets are created in the us-east-1 (N. Virginia) region. In this example, an S3 Bucket named my_bucket_kdjmnzkdjemz will be created and the Access Control Lists (ACLs) will be enabled allowing Log Delivery group to create (write) objects in the S3 Bucket.

  • acl log-delivery-write will grant the S3 log delivery group Write permission for Objects, Read permission for Bucket ACL
  • acl public-read will grant the Everyone (public access) group List permission for Objects, Read permission for Bucket ACL
resource "aws_s3_bucket" "my_bucket_kdjmnzkdjemz" {
  bucket = "my-bucket-kdjmnzkdjemz"

  tags = {
    Name        = "my_bucket_kdjmnzkdjemz"
    Environment = "staging"
  }
}

resource "aws_s3_bucket_acl" "bucket_acl" {
  bucket = aws_s3_bucket.my_bucket_kdjmnzkdjemz.id
  acl    = "log-delivery-write"
}

 

Or, you can use access_control_policy instead of acl if you need to set certain permission. In this example, the S3 log delivery group will be granted only Read permission for Bucket ACL. The following permissions can be used:

  • FULL_CONTROL
  • READ
  • READ_ACP
  • WRITE
  • WRITE_ACP
resource "aws_s3_bucket" "my_bucket_kdjmnzkdjemz" {
  bucket = "my-bucket-kdjmnzkdjemz"

  tags = {
    Name        = "my_bucket_kdjmnzkdjemz"
    Environment = "staging"
  }
}

data "aws_canonical_user_id" "current" {}

resource "aws_s3_bucket_acl" "bucket_acl" {
  bucket = aws_s3_bucket.my_bucket_kdjmnzkdjemz.id
  access_control_policy {

    grant {
      grantee {
        id   = data.aws_canonical_user_id.current.id
        type = "CanonicalUser"
      }
      permission = "FULL_CONTROL"
    }

    grant {
      grantee {
        type = "Group"
        uri  = "http://acs.amazonaws.com/groups/s3/LogDelivery"
      }
      permission = "READ_ACP"
    }

    owner {
      id = data.aws_canonical_user_id.current.id
    }

  }
}

 

Often, you only want to set Access Control Lists after setting the S3 Bucket Owner (probably BucketOwnerPreferred) and allowing S3 Bucket Public Access, thus you could include depends_on to ensure the S3 Bucket Owner and S3 Bucket Public Access have been set.

resource "aws_s3_bucket" "my_bucket_kdjmnzkdjemz" {
  bucket = "my-bucket-kdjmnzkdjemz"

  tags = {
    Name        = "my_bucket_kdjmnzkdjemz"
    Environment = "staging"
  }
}

resource "aws_s3_bucket_ownership_controls" "bucket_ownership" {
  bucket = aws_s3_bucket.my_bucket_kdjmnzkdjemz.id
  rule {
    object_ownership = "BucketOwnerPreferred"
  }
}

resource "aws_s3_bucket_public_access_block" "public-access-block" {
  bucket = aws_s3_bucket.my_bucket_kdjmnzkdjemz.id

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

resource "aws_s3_bucket_acl" "bucket_acl" {
  depends_on = [
    aws_s3_bucket_ownership_controls.bucket_ownership_controls,
    aws_s3_bucket_public_access_block.public-access-block,
  ]

  bucket = aws_s3_bucket.my_bucket_kdjmnzkdjemz.id
  acl    = "log-delivery-write"
}

 

You may need to issue or reissue the terraform init command.

terraform init

 

The terraform plan command can be used to see what Terraform will try to do.

terraform plan

 

And the terraform apply command can be used to create the S3 Bucket and set the S3 Bucket Access Control Lists.

terraform apply



Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 48885a in the box below so that we can be sure you are a human.