Skip to content

Commit

Permalink
Feature/s3 tag policies (#193)
Browse files Browse the repository at this point in the history
* apiary customer policy condition

* seperate bucket and object policies

* fix

* fix

* update changelog

* update readme

* fix

Co-authored-by: Raj Poluri <[email protected]>
  • Loading branch information
rpoluri and Raj Poluri authored Jun 22, 2021
1 parent 68da907 commit 7db672e
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 4 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ module "apiary" {
}
]
apiary_customer_accounts = ["aws_account_no_1", "aws_account_no_2"]
apiary_customer_condition = <<EOF
"ForAnyValue:StringEquals": {"s3:ExistingObjectTag/security": [ "public"] } ,
"StringLike": {"s3:ExistingObjectTag/type": "image*" }
EOF
ingress_cidr = ["10.0.0.0/8"]
apiary_assume_roles = [
{
Expand Down
2 changes: 2 additions & 0 deletions VARIABLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
|------|-------------|:----:|:-----:|:-----:|
| apiary_assume_roles | List of maps - each map describes an IAM role that can be assumed in this account to write data into the configured list of schemas. See section [`apiary_assume_roles`](#apiary_assume_roles) for more info. | list(map) | - | no |
| apiary_customer_accounts | AWS account IDs for clients of this Metastore. | list | - | no |
| apiary_customer_condition | IAM policy condition applied to customer account s3 access. | string | `` | no |
| apiary_database_name | Database name to create in RDS for Apiary. | string | `apiary` | no |
| apiary_deny_roles | AWS IAM roles denied access to Apiary managed S3 buckets. | list | - | yes |
| apiary_domain_name | Apiary domain name for Route 53. | string | `` | no |
| apiary_log_bucket | Bucket for Apiary logs. | string | - | yes |
| apiary_log_prefix | Prefix for Apiary logs. | string | `` | no |
| apiary_managed_schemas | List of maps - each map entry describes an Apiary schema, along with S3 storage properties for the schema. See section [`apiary_managed_schemas`](#apiary_managed_schemas) for more info. | list(map) | - | no |
| apiary_consumer_iamroles | AWS IAM roles allowed read access to managed Apiary S3 buckets. | map | `<list>` | no |
| apiary_producer_iamroles | AWS IAM roles allowed write access to managed Apiary S3 buckets. | map | `<map>` | no |
| apiary_rds_additional_sg | Comma-separated string containing additional security groups to attach to RDS. | list | `<list>` | no |
| apiary_shared_schemas | Schema names which are accessible from read-only metastore, default is all schemas. | list | `<list>` | no |
Expand Down
2 changes: 2 additions & 0 deletions s3.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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", ""), ",", "\",\"")
Expand Down
46 changes: 42 additions & 4 deletions templates/apiary-bucket-policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -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}/*"
]
},
Expand All @@ -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",
Expand Down
12 changes: 12 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down

0 comments on commit 7db672e

Please sign in to comment.