Commit e74d1509 authored by Bryant Biggs's avatar Bryant Biggs Committed by GitHub

feat: Add bucket acl policy grants (#44)

parent 828cf67c
repos: repos:
- repo: git://github.com/antonbabenko/pre-commit-terraform - repo: git://github.com/antonbabenko/pre-commit-terraform
rev: v1.31.0 rev: v1.43.0
hooks: hooks:
- id: terraform_fmt - id: terraform_fmt
- id: terraform_docs - id: terraform_docs
- id: terraform_tflint
args:
- '--args=--only=terraform_deprecated_interpolation'
- '--args=--only=terraform_deprecated_index'
- '--args=--only=terraform_unused_declarations'
- '--args=--only=terraform_comment_syntax'
- '--args=--only=terraform_documented_outputs'
- '--args=--only=terraform_documented_variables'
- '--args=--only=terraform_typed_variables'
- '--args=--only=terraform_module_pinned_source'
- '--args=--only=terraform_naming_convention'
- '--args=--only=terraform_required_version'
- '--args=--only=terraform_required_providers'
- '--args=--only=terraform_standard_module_structure'
- '--args=--only=terraform_workspace_remote'
- repo: git://github.com/pre-commit/pre-commit-hooks - repo: git://github.com/pre-commit/pre-commit-hooks
rev: v3.1.0 rev: v3.2.0
hooks: hooks:
- id: check-merge-conflict - id: check-merge-conflict
...@@ -98,7 +98,7 @@ module "s3_bucket" { ...@@ -98,7 +98,7 @@ module "s3_bucket" {
| Name | Description | Type | Default | Required | | Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:| |------|-------------|------|---------|:--------:|
| acceleration\_status | (Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended. | `string` | `null` | no | | acceleration\_status | (Optional) Sets the accelerate configuration of an existing bucket. Can be Enabled or Suspended. | `string` | `null` | no |
| acl | (Optional) The canned ACL to apply. Defaults to 'private'. | `string` | `"private"` | no | | acl | (Optional) The canned ACL to apply. Defaults to 'private'. Conflicts with `grant` | `string` | `"private"` | no |
| attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | `bool` | `false` | no | | attach\_elb\_log\_delivery\_policy | Controls if S3 bucket should have ELB log delivery policy attached | `bool` | `false` | no |
| attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | `bool` | `false` | no | | attach\_policy | Controls if S3 bucket should have bucket policy attached (set to `true` to use value of `policy` as bucket policy) | `bool` | `false` | no |
| attach\_public\_policy | Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket) | `bool` | `true` | no | | attach\_public\_policy | Controls if a user defined public bucket policy will be attached (set to `false` to allow upstream to apply defaults to the bucket) | `bool` | `true` | no |
...@@ -109,6 +109,7 @@ module "s3_bucket" { ...@@ -109,6 +109,7 @@ module "s3_bucket" {
| cors\_rule | List of maps containing rules for Cross-Origin Resource Sharing. | `list(any)` | `[]` | no | | cors\_rule | List of maps containing rules for Cross-Origin Resource Sharing. | `list(any)` | `[]` | no |
| create\_bucket | Controls if S3 bucket should be created | `bool` | `true` | no | | create\_bucket | Controls if S3 bucket should be created | `bool` | `true` | no |
| force\_destroy | (Optional, Default:false ) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are not recoverable. | `bool` | `false` | no | | force\_destroy | (Optional, Default:false ) A boolean that indicates all objects should be deleted from the bucket so that the bucket can be destroyed without error. These objects are not recoverable. | `bool` | `false` | no |
| grant | An ACL policy grant. Conflicts with `acl` | `list(any)` | `[]` | no |
| ignore\_public\_acls | Whether Amazon S3 should ignore public ACLs for this bucket. | `bool` | `false` | no | | ignore\_public\_acls | Whether Amazon S3 should ignore public ACLs for this bucket. | `bool` | `false` | no |
| lifecycle\_rule | List of maps containing configuration of object lifecycle management. | `any` | `[]` | no | | lifecycle\_rule | List of maps containing configuration of object lifecycle management. | `any` | `[]` | no |
| logging | Map containing access bucket logging configuration. | `map(string)` | `{}` | no | | logging | Map containing access bucket logging configuration. | `map(string)` | `{}` | no |
......
...@@ -27,14 +27,18 @@ Note that this example may create resources which cost money. Run `terraform des ...@@ -27,14 +27,18 @@ Note that this example may create resources which cost money. Run `terraform des
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements ## Requirements
No requirements. | Name | Version |
|------|---------|
| terraform | >= 0.12.6, < 0.14 |
| aws | >= 3.0, < 4.0 |
| random | ~> 2 |
## Providers ## Providers
| Name | Version | | Name | Version |
|------|---------| |------|---------|
| aws | n/a | | aws | >= 3.0, < 4.0 |
| random | n/a | | random | ~> 2 |
## Inputs ## Inputs
......
...@@ -2,6 +2,8 @@ locals { ...@@ -2,6 +2,8 @@ locals {
bucket_name = "s3-bucket-${random_pet.this.id}" bucket_name = "s3-bucket-${random_pet.this.id}"
} }
data "aws_canonical_user_id" "current" {}
resource "random_pet" "this" { resource "random_pet" "this" {
length = 2 length = 2
} }
...@@ -55,6 +57,25 @@ module "log_bucket" { ...@@ -55,6 +57,25 @@ module "log_bucket" {
attach_elb_log_delivery_policy = true attach_elb_log_delivery_policy = true
} }
module "cloudfront_log_bucket" {
source = "../../"
bucket = "cloudfront-logs-${random_pet.this.id}"
acl = null # conflicts with default of `acl = "private"` so set to null to use grants
grant = [{
type = "CanonicalUser"
permissions = ["FULL_CONTROL"]
id = data.aws_canonical_user_id.current.id
}, {
type = "CanonicalUser"
permissions = ["FULL_CONTROL"]
id = "c4c1ede66af53448b93c283ce9448c4ba468c9432aa01d700d3878632f77d2d0"
# Ref. https://github.com/terraform-providers/terraform-provider-aws/issues/12512
# Ref. https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html
}]
force_destroy = true
}
module "s3_bucket" { module "s3_bucket" {
source = "../../" source = "../../"
...@@ -183,7 +204,7 @@ module "s3_bucket" { ...@@ -183,7 +204,7 @@ module "s3_bucket" {
} }
} }
// S3 bucket-level Public Access Block configuration # S3 bucket-level Public Access Block configuration
block_public_acls = true block_public_acls = true
block_public_policy = true block_public_policy = true
ignore_public_acls = true ignore_public_acls = true
......
terraform {
required_version = ">= 0.12.6, < 0.14"
required_providers {
aws = ">= 3.0, < 4.0"
random = "~> 2"
}
}
...@@ -17,15 +17,20 @@ Note that this example may create resources which cost money. Run `terraform des ...@@ -17,15 +17,20 @@ Note that this example may create resources which cost money. Run `terraform des
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements ## Requirements
No requirements. | Name | Version |
|------|---------|
| terraform | >= 0.12.6, < 0.14 |
| aws | >= 3.0, < 4.0 |
| null | ~> 2 |
| random | ~> 2 |
## Providers ## Providers
| Name | Version | | Name | Version |
|------|---------| |------|---------|
| aws | n/a | | aws | >= 3.0, < 4.0 |
| null | n/a | | null | ~> 2 |
| random | n/a | | random | ~> 2 |
## Inputs ## Inputs
......
...@@ -81,7 +81,7 @@ module "all_notifications" { ...@@ -81,7 +81,7 @@ module "all_notifications" {
bucket = module.s3_bucket.this_s3_bucket_id bucket = module.s3_bucket.this_s3_bucket_id
// Common error - Error putting S3 notification configuration: InvalidArgument: Configuration is ambiguously defined. Cannot have overlapping suffixes in two rules if the prefixes are overlapping for the same event type. # Common error - Error putting S3 notification configuration: InvalidArgument: Configuration is ambiguously defined. Cannot have overlapping suffixes in two rules if the prefixes are overlapping for the same event type.
lambda_notifications = { lambda_notifications = {
lambda1 = { lambda1 = {
...@@ -106,7 +106,7 @@ module "all_notifications" { ...@@ -106,7 +106,7 @@ module "all_notifications" {
filter_prefix = "prefix2/" filter_prefix = "prefix2/"
filter_suffix = ".txt" filter_suffix = ".txt"
// queue_id = aws_sqs_queue.this[0].id // optional # queue_id = aws_sqs_queue.this[0].id // optional
} }
sqs2 = { sqs2 = {
......
terraform {
required_version = ">= 0.12.6, < 0.14"
required_providers {
aws = ">= 3.0, < 4.0"
random = "~> 2"
null = "~> 2"
}
}
...@@ -19,15 +19,19 @@ Note that this example may create resources which cost money. Run `terraform des ...@@ -19,15 +19,19 @@ Note that this example may create resources which cost money. Run `terraform des
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements ## Requirements
No requirements. | Name | Version |
|------|---------|
| terraform | >= 0.12.6, < 0.14 |
| aws | >= 3.0, < 4.0 |
| random | ~> 2 |
## Providers ## Providers
| Name | Version | | Name | Version |
|------|---------| |------|---------|
| aws | n/a | | aws | >= 3.0, < 4.0 |
| aws.replica | n/a | | aws.replica | >= 3.0, < 4.0 |
| random | n/a | | random | ~> 2 |
## Inputs ## Inputs
......
terraform {
required_version = ">= 0.12.6, < 0.14"
required_providers {
aws = ">= 3.0, < 4.0"
random = "~> 2"
}
}
...@@ -50,6 +50,17 @@ resource "aws_s3_bucket" "this" { ...@@ -50,6 +50,17 @@ resource "aws_s3_bucket" "this" {
} }
} }
dynamic "grant" {
for_each = var.grant
content {
id = lookup(grant.value, "id", null)
type = grant.value.type
permissions = grant.value.permissions
uri = lookup(grant.value, "uri", null)
}
}
dynamic "lifecycle_rule" { dynamic "lifecycle_rule" {
for_each = var.lifecycle_rule for_each = var.lifecycle_rule
...@@ -254,8 +265,8 @@ data "aws_iam_policy_document" "elb_log_delivery" { ...@@ -254,8 +265,8 @@ data "aws_iam_policy_document" "elb_log_delivery" {
resource "aws_s3_bucket_public_access_block" "this" { resource "aws_s3_bucket_public_access_block" "this" {
count = var.create_bucket && var.attach_public_policy ? 1 : 0 count = var.create_bucket && var.attach_public_policy ? 1 : 0
// Chain resources (s3_bucket -> s3_bucket_policy -> s3_bucket_public_access_block) # Chain resources (s3_bucket -> s3_bucket_policy -> s3_bucket_public_access_block)
// to prevent "A conflicting conditional operation is currently in progress against this resource." # to prevent "A conflicting conditional operation is currently in progress against this resource."
bucket = (var.attach_elb_log_delivery_policy || var.attach_policy) ? aws_s3_bucket_policy.this[0].id : aws_s3_bucket.this[0].id bucket = (var.attach_elb_log_delivery_policy || var.attach_policy) ? aws_s3_bucket_policy.this[0].id : aws_s3_bucket.this[0].id
block_public_acls = var.block_public_acls block_public_acls = var.block_public_acls
......
...@@ -5,13 +5,17 @@ Creates S3 bucket notification resource with all supported types of deliveries: ...@@ -5,13 +5,17 @@ Creates S3 bucket notification resource with all supported types of deliveries:
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK --> <!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Requirements ## Requirements
No requirements. | Name | Version |
|------|---------|
| terraform | >= 0.12.6, < 0.14 |
| aws | >= 3.0, < 4.0 |
| random | ~> 2 |
## Providers ## Providers
| Name | Version | | Name | Version |
|------|---------| |------|---------|
| aws | n/a | | aws | >= 3.0, < 4.0 |
## Inputs ## Inputs
......
locals { locals {
bucket_arn = coalesce(var.bucket_arn, "arn:aws:s3:::${var.bucket}") bucket_arn = coalesce(var.bucket_arn, "arn:aws:s3:::${var.bucket}")
// Convert from "arn:aws:sqs:eu-west-1:835367859851:bold-starling-0" into "https://sqs.eu-west-1.amazonaws.com/835367859851/bold-starling-0" if queue_id was not specified # Convert from "arn:aws:sqs:eu-west-1:835367859851:bold-starling-0" into "https://sqs.eu-west-1.amazonaws.com/835367859851/bold-starling-0" if queue_id was not specified
// queue_url used in aws_sqs_queue_policy is not the same as arn which is used in all other places # queue_url used in aws_sqs_queue_policy is not the same as arn which is used in all other places
queue_ids = { for k, v in var.sqs_notifications : k => format("https://%s.%s.amazonaws.com/%s/%s", data.aws_arn.queue[k].service, data.aws_arn.queue[k].region, data.aws_arn.queue[k].account, data.aws_arn.queue[k].resource) if lookup(v, "queue_id", "") == "" } queue_ids = { for k, v in var.sqs_notifications : k => format("https://%s.%s.amazonaws.com/%s/%s", data.aws_arn.queue[k].service, data.aws_arn.queue[k].region, data.aws_arn.queue[k].account, data.aws_arn.queue[k].resource) if lookup(v, "queue_id", "") == "" }
} }
...@@ -54,7 +54,7 @@ resource "aws_s3_bucket_notification" "this" { ...@@ -54,7 +54,7 @@ resource "aws_s3_bucket_notification" "this" {
] ]
} }
// Lambda # Lambda
resource "aws_lambda_permission" "allow" { resource "aws_lambda_permission" "allow" {
for_each = var.lambda_notifications for_each = var.lambda_notifications
...@@ -66,7 +66,7 @@ resource "aws_lambda_permission" "allow" { ...@@ -66,7 +66,7 @@ resource "aws_lambda_permission" "allow" {
source_arn = local.bucket_arn source_arn = local.bucket_arn
} }
// SQS Queue # SQS Queue
data "aws_arn" "queue" { data "aws_arn" "queue" {
for_each = var.sqs_notifications for_each = var.sqs_notifications
...@@ -107,7 +107,7 @@ resource "aws_sqs_queue_policy" "allow" { ...@@ -107,7 +107,7 @@ resource "aws_sqs_queue_policy" "allow" {
policy = data.aws_iam_policy_document.sqs[each.key].json policy = data.aws_iam_policy_document.sqs[each.key].json
} }
// SNS Topic # SNS Topic
data "aws_iam_policy_document" "sns" { data "aws_iam_policy_document" "sns" {
for_each = var.sns_notifications for_each = var.sns_notifications
......
terraform {
required_version = ">= 0.12.6, < 0.14"
required_providers {
aws = ">= 3.0, < 4.0"
random = "~> 2"
}
}
...@@ -8,7 +8,6 @@ output "this_s3_bucket_arn" { ...@@ -8,7 +8,6 @@ output "this_s3_bucket_arn" {
value = element(concat(aws_s3_bucket.this.*.arn, list("")), 0) value = element(concat(aws_s3_bucket.this.*.arn, list("")), 0)
} }
output "this_s3_bucket_bucket_domain_name" { output "this_s3_bucket_bucket_domain_name" {
description = "The bucket domain name. Will be of format bucketname.s3.amazonaws.com." description = "The bucket domain name. Will be of format bucketname.s3.amazonaws.com."
value = element(concat(aws_s3_bucket.this.*.bucket_domain_name, list("")), 0) value = element(concat(aws_s3_bucket.this.*.bucket_domain_name, list("")), 0)
......
...@@ -35,7 +35,7 @@ variable "bucket_prefix" { ...@@ -35,7 +35,7 @@ variable "bucket_prefix" {
} }
variable "acl" { variable "acl" {
description = "(Optional) The canned ACL to apply. Defaults to 'private'." description = "(Optional) The canned ACL to apply. Defaults to 'private'. Conflicts with `grant`"
type = string type = string
default = "private" default = "private"
} }
...@@ -94,6 +94,12 @@ variable "logging" { ...@@ -94,6 +94,12 @@ variable "logging" {
default = {} default = {}
} }
variable "grant" {
description = "An ACL policy grant. Conflicts with `acl`"
type = list(any)
default = []
}
variable "lifecycle_rule" { variable "lifecycle_rule" {
description = "List of maps containing configuration of object lifecycle management." description = "List of maps containing configuration of object lifecycle management."
type = any type = any
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment