Skip to content

Commit

Permalink
Merge pull request #27 from terraform-modules/add-kms-policy
Browse files Browse the repository at this point in the history
v2.1.0: add kms admin roles, key policy and allow them to be passed in
  • Loading branch information
badra001 committed May 11, 2021
2 parents 1432e2e + 3271d5f commit 50bb6a1
Show file tree
Hide file tree
Showing 12 changed files with 151 additions and 3 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,6 @@
* v2.0.1 -- 20210325
- make bucket policies denying missing encryption header optional
- add variable: `require_explicit_encryption` default = false

* v2.1.0 -- 20210511
- add kms_policy to be used for custom kms key policy and kms_admin_roles
8 changes: 8 additions & 0 deletions common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,13 @@ No modules.
| [aws_s3_bucket_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
| [aws_s3_bucket_public_access_block.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [null_resource.policy_delay](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.empty](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.key_admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.key_policy_combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |

## Inputs

Expand All @@ -37,7 +43,9 @@ No modules.
| <a name="input_bucket_folders"></a> [bucket\_folders](#input\_bucket\_folders) | List of folders (keys) to create after creation of bucket. They will have object metadata provided based on metadata\_tags and data\_safeguard labels. | `list(string)` | `[]` | no |
| <a name="input_bucket_name"></a> [bucket\_name](#input\_bucket\_name) | AWS Bucket Name. Standard prefix will be applied here, do not include here. | `string` | n/a | yes |
| <a name="input_force_destroy"></a> [force\_destroy](#input\_force\_destroy) | Sets force\_destroy to allow the bucket and contents to be deleted. The deletion may take a very long time based on the number of objects. You normally want to update this to true, apply, and then destroy the resource. | `bool` | `false` | no |
| <a name="input_kms_admin_roles"></a> [kms\_admin\_roles](#input\_kms\_admin\_roles) | AWS KMS Key administrative role(s) which have full access to the key. The root user is included by default. | `list(string)` | `[]` | no |
| <a name="input_kms_key_id"></a> [kms\_key\_id](#input\_kms\_key\_id) | AWS KMS Key ID (one per bucket). This is currently ignored. | `string` | `""` | no |
| <a name="input_kms_policy_document"></a> [kms\_policy\_document](#input\_kms\_policy\_document) | AWS KMS Key Policy Document JSON, merged with admin policy document | `string` | `""` | no |
| <a name="input_metadata_tags"></a> [metadata\_tags](#input\_metadata\_tags) | AWS S3 Custom metadata (prefix x-amzn-meta- automatically included, not needed here). If data\_safeguard labels are applied, they will be incorporated on any bucket objects created. | `map(string)` | `{}` | no |
| <a name="input_require_explicit_encryption"></a> [require\_explicit\_encryption](#input\_require\_explicit\_encryption) | When enabled, adds bucket policy to Deny unencrypted uploads and incorrect encryption header. Should not normally be needed. | `bool` | `false` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no |
Expand Down
7 changes: 7 additions & 0 deletions common/data.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
data "aws_caller_identity" "current" {}

data "aws_arn" "current" {
arn = data.aws_caller_identity.current.arn
}

data "aws_region" "current" {}
40 changes: 38 additions & 2 deletions common/resources.tf
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
locals {

account_id = data.aws_caller_identity.current.account_id
current_user_arn = data.aws_caller_identity.current.arn
partition = data.aws_arn.current.partition
region = data.aws_region.current.name
}

locals {
base_name = var.bucket_name
name = replace(var.bucket_name, local._prefixes["s3"], "")
bucket_name = format("%s%s", local._prefixes["s3"], local.name)

# kms_key_arn_exists = var.kms_key_arn != "" && var.kms_key_arn != null
kms_key_arn = aws_kms_key.key.arn
kms_key_name = format("%s%s", local._prefixes["kms"], local.name)

kms_admin_root = [format("arn:%v:iam::%v:root", local.partition, local.account_id)]
kms_admin_roles = compact(concat(local.kms_admin_root, var.kms_admin_roles))
kms_policy_document = length(var.kms_policy_document) > 0 ? var.kms_policy_document : data.aws_iam_policy_document.empty.json

condition_allowed_cidr = {
"test" : "NotIpAddress"
"variable" : "aws:sourceIp"
Expand Down Expand Up @@ -210,17 +223,40 @@ resource "aws_s3_bucket_object" "this_objects" {
resource "aws_kms_key" "key" {
description = "KMS CMK for S3 bucket ${local.name}"
enable_key_rotation = true
# policy = data.aws_iam_policy_document.key.json
policy = data.aws_iam_policy_document.key_policy_combined.json

tags = merge(
local.base_tags,
var.tags,
local.enforced_tags,
map("Name", local.bucket_name)
map("Name", local.kms_key_name)
)
}

resource "aws_kms_alias" "key" {
name = "alias/${local.kms_key_name}"
target_key_id = aws_kms_key.key.key_id
}

# auto includes root
data "aws_iam_policy_document" "key_admin" {
statement {
sid = "BuiltinKMSAdminRoles"
effect = "Allow"
actions = ["kms:*"]
resources = ["*"]
principals {
type = "AWS"
identifiers = local.kms_admin_roles
}
}
}

data "aws_iam_policy_document" "key_policy_combined" {
source_policy_documents = [
data.aws_iam_policy_document.key_admin.json,
local.kms_policy_document
]
}

data "aws_iam_policy_document" "empty" {}
16 changes: 16 additions & 0 deletions common/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ variable "kms_key_id" {
default = ""
}

variable "kms_policy_document" {
description = "AWS KMS Key Policy Document JSON, merged with admin policy document"
type = string
default = ""
}

variable "kms_admin_roles" {
description = "AWS KMS Key administrative role(s) which have full access to the key. The root user is included by default."
type = list(string)
default = []
}

variable "tags" {
description = "AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data_safeguard field for such things."
type = map(string)
Expand Down Expand Up @@ -62,3 +74,7 @@ variable "require_explicit_encryption" {
type = bool
default = false
}

# TBD
# variable "kms_policy_read_arns" { }
# variable "kms_policy_write_arns" { }
2 changes: 1 addition & 1 deletion common/version.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
locals {
_module_version = "2.0.1"
_module_version = "2.1.0"
}
23 changes: 23 additions & 0 deletions standard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,26 @@ module "mybucket" {
bucket_name = "mynormalbucket"
access_log_bucket = "mylogbucket"
kms_admin_roles = [ aws_iam_role.cloud-admin.arn ]
## optional
# kms_policy_document = data.aws_iam_policy_document.mypolicy.json
}
data "aws_iam_policy_document" "mypolicy" {
statement { }
}
```

This automaticaly creates an AWS KMS key used just for this bucket.

It will set a key usage/management policy by default with the `root` account, along with any other
roles in the variable `kms_admin_roles` list. This is **full** access to the KMS key.

If `kms_policy_document` is provided it needs to be a valid IAM policy as would apply to key usage,
such as read access (decrypt) or write access (encrypt, re-encrypt). A later enhancement may be
to provide variables granting read and write access to the key.

## Requirements

No requirements.
Expand All @@ -45,7 +60,13 @@ No modules.
| [aws_s3_bucket_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
| [aws_s3_bucket_public_access_block.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [null_resource.policy_delay](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.empty](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.key_admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.key_policy_combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |

## Inputs

Expand All @@ -60,7 +81,9 @@ No modules.
| <a name="input_data_safeguards"></a> [data\_safeguards](#input\_data\_safeguards) | Selected available safeguards which apply to the data in the bucket | `list(string)` | `[]` | no |
| <a name="input_enable_title26"></a> [enable\_title26](#input\_enable\_title26) | Flag to enable bucket with Title 26 (FTI) settings | `bool` | `false` | no |
| <a name="input_force_destroy"></a> [force\_destroy](#input\_force\_destroy) | Sets force\_destroy to allow the bucket and contents to be deleted. The deletion may take a very long time based on the number of objects. You normally want to update this to true, apply, and then destroy the resource. | `bool` | `false` | no |
| <a name="input_kms_admin_roles"></a> [kms\_admin\_roles](#input\_kms\_admin\_roles) | AWS KMS Key administrative role(s) which have full access to the key. The root user is included by default. | `list(string)` | `[]` | no |
| <a name="input_kms_key_id"></a> [kms\_key\_id](#input\_kms\_key\_id) | AWS KMS Key ID (one per bucket). This is currently ignored. | `string` | `""` | no |
| <a name="input_kms_policy_document"></a> [kms\_policy\_document](#input\_kms\_policy\_document) | AWS KMS Key Policy Document JSON, merged with admin policy document | `string` | `""` | no |
| <a name="input_metadata_tags"></a> [metadata\_tags](#input\_metadata\_tags) | AWS S3 Custom metadata (prefix x-amzn-meta- automatically included, not needed here). If data\_safeguard labels are applied, they will be incorporated on any bucket objects created. | `map(string)` | `{}` | no |
| <a name="input_require_explicit_encryption"></a> [require\_explicit\_encryption](#input\_require\_explicit\_encryption) | When enabled, adds bucket policy to Deny unencrypted uploads and incorrect encryption header. Should not normally be needed. | `bool` | `false` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no |
Expand Down
1 change: 1 addition & 0 deletions standard/data.tf
15 changes: 15 additions & 0 deletions standard/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,25 @@
*
* bucket_name = "mynormalbucket"
* access_log_bucket = "mylogbucket"
* kms_admin_roles = [ aws_iam_role.cloud-admin.arn ]
*
* ## optional
* # kms_policy_document = data.aws_iam_policy_document.mypolicy.json
* }
*
* data "aws_iam_policy_document" "mypolicy" {
* statement { }
* }
* ```
*
* This automaticaly creates an AWS KMS key used just for this bucket.
*
* It will set a key usage/management policy by default with the `root` account, along with any other
* roles in the variable `kms_admin_roles` list. This is **full** access to the KMS key.
*
* If `kms_policy_document` is provided it needs to be a valid IAM policy as would apply to key usage,
* such as read access (decrypt) or write access (encrypt, re-encrypt). A later enhancement may be
* to provide variables granting read and write access to the key.
*/

locals {
Expand Down
23 changes: 23 additions & 0 deletions title26/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ module "mybucket" {
bucket_name = "myt26bucket"
access_log_bucket = "mylogbucket"
# enable_title26 = true
kms_admin_roles = [ aws_iam_role.cloud-admin.arn ]
## optional
# kms_policy_document = data.aws_iam_policy_document.mypolicy.json
}
data "aws_iam_policy_document" "mypolicy" {
statement { }
}
```

Expand All @@ -24,6 +32,13 @@ to make a comma separated list.

This automaticaly creates an AWS KMS key used just for this bucket.

It will set a key usage/management policy by default with the `root` account, along with any other
roles in the variable `kms_admin_roles` list. This is **full** access to the KMS key.

If `kms_policy_document` is provided it needs to be a valid IAM policy as would apply to key usage,
such as read access (decrypt) or write access (encrypt, re-encrypt). A later enhancement may be
to provide variables granting read and write access to the key.

## Requirements

No requirements.
Expand All @@ -50,7 +65,13 @@ No modules.
| [aws_s3_bucket_policy.policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_policy) | resource |
| [aws_s3_bucket_public_access_block.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
| [null_resource.policy_delay](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
| [aws_arn.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/arn) | data source |
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
| [aws_iam_policy_document.empty](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.key_admin](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.key_policy_combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_iam_policy_document.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |

## Inputs

Expand All @@ -65,7 +86,9 @@ No modules.
| <a name="input_data_safeguards"></a> [data\_safeguards](#input\_data\_safeguards) | Selected available safeguards which apply to the data in the bucket | `list(string)` | <pre>[<br> "title26"<br>]</pre> | no |
| <a name="input_enable_title26"></a> [enable\_title26](#input\_enable\_title26) | Flag to enable bucket with Title 26 (FTI) settings | `bool` | `true` | no |
| <a name="input_force_destroy"></a> [force\_destroy](#input\_force\_destroy) | Sets force\_destroy to allow the bucket and contents to be deleted. The deletion may take a very long time based on the number of objects. You normally want to update this to true, apply, and then destroy the resource. | `bool` | `false` | no |
| <a name="input_kms_admin_roles"></a> [kms\_admin\_roles](#input\_kms\_admin\_roles) | AWS KMS Key administrative role(s) which have full access to the key. The root user is included by default. | `list(string)` | `[]` | no |
| <a name="input_kms_key_id"></a> [kms\_key\_id](#input\_kms\_key\_id) | AWS KMS Key ID (one per bucket). This is currently ignored. | `string` | `""` | no |
| <a name="input_kms_policy_document"></a> [kms\_policy\_document](#input\_kms\_policy\_document) | AWS KMS Key Policy Document JSON, merged with admin policy document | `string` | `""` | no |
| <a name="input_metadata_tags"></a> [metadata\_tags](#input\_metadata\_tags) | AWS S3 Custom metadata (prefix x-amzn-meta- automatically included, not needed here). If data\_safeguard labels are applied, they will be incorporated on any bucket objects created. | `map(string)` | `{}` | no |
| <a name="input_require_explicit_encryption"></a> [require\_explicit\_encryption](#input\_require\_explicit\_encryption) | When enabled, adds bucket policy to Deny unencrypted uploads and incorrect encryption header. Should not normally be needed. | `bool` | `false` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | AWS Tags to apply to appropriate resources (S3, KMS). Do not include safeguard tags here, use the data\_safeguard field for such things. | `map(string)` | `{}` | no |
Expand Down
1 change: 1 addition & 0 deletions title26/data.tf
15 changes: 15 additions & 0 deletions title26/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@
* bucket_name = "myt26bucket"
* access_log_bucket = "mylogbucket"
* # enable_title26 = true
* kms_admin_roles = [ aws_iam_role.cloud-admin.arn ]
*
* ## optional
* # kms_policy_document = data.aws_iam_policy_document.mypolicy.json
* }
*
* data "aws_iam_policy_document" "mypolicy" {
* statement { }
* }
* ```
*
Expand All @@ -24,6 +32,13 @@
* to make a comma separated list.
*
* This automaticaly creates an AWS KMS key used just for this bucket.
*
* It will set a key usage/management policy by default with the `root` account, along with any other
* roles in the variable `kms_admin_roles` list. This is **full** access to the KMS key.
*
* If `kms_policy_document` is provided it needs to be a valid IAM policy as would apply to key usage,
* such as read access (decrypt) or write access (encrypt, re-encrypt). A later enhancement may be
* to provide variables granting read and write access to the key.
*/

locals {
Expand Down

0 comments on commit 50bb6a1

Please sign in to comment.