diff --git a/CHANGELOG.md b/CHANGELOG.md index 952af93..25c9792 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [6.9.0] - 2021-06-22 +### Added +- Added apiary_consumer_iamroles variable to grant cross account access to IAM roles. +- Added apiary_customer_condition variable to restrict access using S3 object tags. + ## [6.8.1] - 2021-06-17 ### Added - Add support for cross account access to s3 inventory. diff --git a/README.md b/README.md index 4b9d50e..6446636 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,10 @@ module "apiary" { } ] apiary_customer_accounts = ["aws_account_no_1", "aws_account_no_2"] + apiary_customer_condition = <` | no | | apiary_producer_iamroles | AWS IAM roles allowed write access to managed Apiary S3 buckets. | map | `` | no | | apiary_rds_additional_sg | Comma-separated string containing additional security groups to attach to RDS. | list | `` | no | | apiary_shared_schemas | Schema names which are accessible from read-only metastore, default is all schemas. | list | `` | no | diff --git a/s3.tf b/s3.tf index 0b56e74..036a61a 100644 --- a/s3.tf +++ b/s3.tf @@ -17,10 +17,12 @@ data "template_file" "bucket_policy" { vars = { #if apiary_shared_schemas is empty or contains current schema, allow customer accounts to access this bucket. customer_principal = (length(var.apiary_shared_schemas) == 0 || contains(var.apiary_shared_schemas, each.key)) && each.value["customer_accounts"] != "" ? join("\",\"", formatlist("arn:aws:iam::%s:root", split(",", each.value["customer_accounts"]))) : "" + customer_condition = var.apiary_customer_condition bucket_name = each.value["data_bucket"] encryption = each.value["encryption"] kms_key_arn = each.value["encryption"] == "aws:kms" ? aws_kms_key.apiary_kms[each.key].arn : "" + consumer_iamroles = join("\",\"", var.apiary_consumer_iamroles) producer_iamroles = replace(lookup(var.apiary_producer_iamroles, each.key, ""), ",", "\",\"") deny_iamroles = join("\",\"", var.apiary_deny_iamroles) client_roles = replace(lookup(each.value, "client_roles", ""), ",", "\",\"") diff --git a/templates/apiary-bucket-policy.json b/templates/apiary-bucket-policy.json index 20ea9e8..12e3708 100644 --- a/templates/apiary-bucket-policy.json +++ b/templates/apiary-bucket-policy.json @@ -4,20 +4,38 @@ "Statement": [ %{if customer_principal != ""} { - "Sid": "Apiary customer account permissions", + "Sid": "Apiary customer account bucket permissions", "Effect": "Allow", "Principal": { "AWS": [ "${customer_principal}" ] }, "Action": [ "s3:GetBucketLocation", - "s3:GetObject", - "s3:GetObjectAcl", "s3:GetBucketAcl", "s3:ListBucket" ], "Resource": [ - "arn:aws:s3:::${bucket_name}", + "arn:aws:s3:::${bucket_name}" + ] + }, +%{endif} +%{if customer_principal != ""} + { + "Sid": "Apiary customer account object permissions", + "Effect": "Allow", + "Principal": { + "AWS": [ "${customer_principal}" ] + }, +%{if customer_condition != ""} + "Condition": { + ${customer_condition} + }, +%{endif} + "Action": [ + "s3:GetObject", + "s3:GetObjectAcl" + ], + "Resource": [ "arn:aws:s3:::${bucket_name}/*" ] }, @@ -36,6 +54,26 @@ } }, %{endif} +%{if consumer_iamroles != ""} + { + "Sid": "Apiary consumer iamrole permissions", + "Effect": "Allow", + "Principal": { + "AWS": [ "${consumer_iamroles}" ] + }, + "Action": [ + "s3:GetBucketLocation", + "s3:GetObject", + "s3:GetObjectAcl", + "s3:GetBucketAcl", + "s3:ListBucket" + ], + "Resource": [ + "arn:aws:s3:::${bucket_name}", + "arn:aws:s3:::${bucket_name}/*" + ] + }, +%{endif} %{if producer_iamroles != ""} { "Sid": "Apiary producer iamrole permissions", diff --git a/variables.tf b/variables.tf index 58570fe..aaf19e8 100644 --- a/variables.tf +++ b/variables.tf @@ -132,6 +132,12 @@ variable "apiary_customer_accounts" { default = [] } +variable "apiary_customer_condition" { + description = "IAM policy condition applied to customer account s3 object access." + type = string + default = "" +} + variable "apiary_deny_iamroles" { description = "AWS IAM roles denied access to Apiary managed S3 buckets." type = list(string) @@ -144,6 +150,12 @@ variable "apiary_assume_roles" { default = [] } +variable "apiary_consumer_iamroles" { + description = "AWS IAM roles allowed read access to managed Apiary S3 buckets." + type = list(string) + default = [] +} + variable "apiary_producer_iamroles" { description = "AWS IAM roles allowed write access to managed Apiary S3 buckets." type = map(any)