Skip to content

Instantly share code, notes, and snippets.

@cjbischoff
Created June 3, 2019 16:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cjbischoff/66941041b43946a00e92286714b0b460 to your computer and use it in GitHub Desktop.
Save cjbischoff/66941041b43946a00e92286714b0b460 to your computer and use it in GitHub Desktop.
variable "bucket_name" {}
variable "name" {}
variable "s3logs_bucket_name" {}
variable "database_kms_key_arn" {}
variable "read_only_roles" {
type = "list"
default = []
}
resource "aws_s3_bucket" "main" {
acl = "private"
bucket = "${var.bucket_name}"
lifecycle_rule {
abort_incomplete_multipart_upload_days = 14
enabled = true
id = "MI-14day-expire"
prefix = ""
expiration {
days = 14
}
}
logging {
target_bucket = "${var.s3logs_bucket_name}"
target_prefix = "${var.name}/${var.bucket_name}/"
}
tags {
Name = "${var.name}"
}
versioning {
enabled = true
}
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = "${var.database_kms_key_arn}"
sse_algorithm = "aws:kms"
}
}
}
}
resource "aws_s3_bucket_policy" "main" {
bucket = "${aws_s3_bucket.main.id}"
# Concat if/else trick on `data` from:
# https://blog.gruntwork.io/terraform-tips-tricks-loops-if-statements-and-gotchas-f739bbae55f9#79f9
policy = "${element(concat(data.aws_iam_policy_document.main_bucket_with_read.*.json,
data.aws_iam_policy_document.main_bucket_without_read.*.json), 0)}"
}
# TODO: Consider refactoring this if we use tf version >= 0.12. `count` may have been added within fields in > 0.12.
data aws_iam_policy_document "main_bucket_with_read" {
count = "${length(var.read_only_roles) > 0 ? 1 : 0}"
statement {
sid = "DenyS3InsecureTransport"
actions = ["s3:*"]
condition {
test = "Bool"
variable = "aws:SecureTransport"
values = ["false"]
}
effect = "Deny"
principals {
type = "*"
identifiers = ["*"]
}
resources = ["${aws_s3_bucket.main.arn}/*"]
}
# Allow an external role to read from the S3.
statement {
sid = "AllowS3ReadOnlyRoles"
actions = [
"s3:GetObject",
]
principals {
type = "AWS"
identifiers = ["${var.read_only_roles}"]
}
resources = ["${aws_s3_bucket.main.arn}/*"]
}
}
data aws_iam_policy_document "main_bucket_without_read" {
count = "${length(var.read_only_roles) <= 0 ? 1 : 0}"
statement {
sid = "DenyS3InsecureTransport"
actions = ["s3:*"]
condition {
test = "Bool"
variable = "aws:SecureTransport"
values = ["false"]
}
effect = "Deny"
principals {
type = "*"
identifiers = ["*"]
}
resources = ["${aws_s3_bucket.main.arn}/*"]
}
}
resource "aws_kms_grant" "external_decrypt_grant" {
count = "${length(var.read_only_roles)}"
name = "${var.name}-external-decrypt-grant-${count.index}"
key_id = "${var.database_kms_key_arn}"
grantee_principal = "${element(var.read_only_roles, count.index)}"
operations = ["Decrypt"]
}
output "bucket_arn" {
value = "${aws_s3_bucket.main.arn}"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment