Fly, Penguin!

I blog so I don't forget.

Managing S3 bucket permissions with terraform

1 minute read #cloud: aws #s3 #terraform

This is what I did today, and I found it useful. And yes, sometimes I over-engineer a bit.

  # IN FILE: locals_constants.tf

  iam_s3_perms_list = ["s3:List*",]
  iam_s3_perms_read = ["s3:List*", "s3:Get*",]
  iam_s3_perms_write = ["s3:List*", "s3:Get*", "s3:PutObject",]

  s3_permissions_rw = distinct(concat(
    local.iam_s3_perms_list,
    local.iam_s3_perms_read,
    local.iam_s3_perms_write,
  ))

  s3_permissions_ro = distinct(concat(
    local.iam_s3_perms_list,
    local.iam_s3_perms_read,
  ))


# IN FILE: locals.tf

team_dev_bucket_configs = {
  "ReadWrite" = {
    actions = local.s3_permissions_rw
    buckets = [
      "yo-corp-yoman-dev",
      "yo-corp-yoman-test",
      "yo-corp-playground",
    ]
  }
  "ReadOnly" = {
    actions = local.s3_permissions_ro
    buckets = [
      "yo-corp-yoman-prod",
      "yo-corp-yoman-archive",
    ]
  }
}


# IN FILE: permissions.tf

# so this policy is now assigned to a group with every dev team member.
# easy. :)
resource "aws_iam_policy" "s3_team_dev_bucket_permissions" {
  name        = "s3-team-dev-bucket-permissions"
  description = "Dev team S3 bucket permissions"
  policy      = data.aws_iam_policy_document.s3_team_dev_bucket_permissions_document.json
}

data "aws_iam_policy_document" "s3_team_dev_bucket_permissions_document" {
  dynamic "statement" {
    for_each = local.team_dev_bucket_configs
    content {
      sid     = "TeamDevBuckets${statement.key}"
      effect  = "Allow"
      actions = statement.value["actions"]
      resources = flatten(
        [
          for bucket in statement.value["buckets"] :
          [
            "arn:aws:s3:::${bucket}", "arn:aws:s3:::${bucket}/*"
          ]
        ]
      )
    }
  }
}