diff --git a/CHANGELOG.md b/CHANGELOG.md index 081e9eb..3057c0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,3 +42,7 @@ Provides standard and t26 S3 bucket construction. * v2.2.2 -- 20211104 - update documenation to include sample policy and policy document + +* v2.3.0 -- 20211117 + - allow kms_key_arn to be created externally + - prep submodule kms_key to be able to handle that diff --git a/common/README.md b/common/README.md index fa95728..41623d7 100644 --- a/common/README.md +++ b/common/README.md @@ -46,7 +46,8 @@ No modules. | [bucket\_policy\_document](#input\_bucket\_policy\_document) | IAM Policy document describing additiona policy to be attached to the bucket beyond the default | `string` | `""` | no | | [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 | | [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 | -| [kms\_key\_id](#input\_kms\_key\_id) | AWS KMS Key ID (one per bucket). This is currently ignored. | `string` | `""` | no | +| [kms\_key\_arn](#input\_kms\_key\_arn) | AWS KMS Key ARN, a key created external to this module call. | `string` | `null` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | AWS KMS Key ID (one per bucket). This is currently ignored (and deprecated). | `string` | `null` | no | | [kms\_policy\_document](#input\_kms\_policy\_document) | AWS KMS Key Policy Document JSON, merged with admin policy document | `string` | `""` | no | | [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 | | [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 | diff --git a/common/outputs.tf b/common/outputs.tf deleted file mode 100644 index 254a87e..0000000 --- a/common/outputs.tf +++ /dev/null @@ -1,30 +0,0 @@ -#--- -# bucket -#--- -output "s3_bucket_arn" { - description = "Created S3 Bucket ARN" - value = aws_s3_bucket.this.arn -} - -output "s3_bucket_id" { - description = "Created S3 Bucket ID" - value = aws_s3_bucket.this.id -} - -#--- -# key -#--- -output "kms_key_id" { - description = "Created KMS Key ID" - value = aws_kms_key.key.id -} - -output "kms_key_arn" { - description = "Created KMS Key ARN" - value = aws_kms_key.key.arn -} - -output "kms_key_alias" { - description = "Created KMS Key Alias name" - value = aws_kms_alias.key.name -} diff --git a/common/resources.tf b/common/resources.tf index 5a5c541..6496033 100644 --- a/common/resources.tf +++ b/common/resources.tf @@ -1,5 +1,4 @@ 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 @@ -12,13 +11,12 @@ locals { bucket_name = format("%s%s", local._prefixes["s3"], local.name) bucket_policy_document = length(var.bucket_policy_document) > 0 ? var.bucket_policy_document : data.aws_iam_policy_document.empty.json - # 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_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 + # 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" @@ -70,7 +68,8 @@ resource "aws_s3_bucket" "this" { server_side_encryption_configuration { rule { apply_server_side_encryption_by_default { - kms_master_key_id = aws_kms_key.key.arn + # kms_master_key_id = aws_kms_key.key.arn + kms_master_key_id = local.kms_key_arn sse_algorithm = "aws:kms" } } @@ -218,54 +217,3 @@ resource "aws_s3_bucket_object" "this_objects" { depends_on = [null_resource.policy_delay] } -#--- -# create a key and alias if not specified -# right now, this can't use an external key, it has to create one per bucket -#--- -resource "aws_kms_key" "key" { - description = "KMS CMK for S3 bucket ${local.name}" - enable_key_rotation = true - policy = data.aws_iam_policy_document.key_policy_combined.json - - tags = merge( - local.base_tags, - var.tags, - local.enforced_tags, - 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" "bucket_policy_combined" { - source_policy_documents = [ - data.aws_iam_policy_document.this.json, - local.bucket_policy_document - ] -} - -data "aws_iam_policy_document" "empty" {} diff --git a/common/variables.tf b/common/variables.tf deleted file mode 100644 index 689fd00..0000000 --- a/common/variables.tf +++ /dev/null @@ -1,86 +0,0 @@ -variable "bucket_name" { - description = "AWS Bucket Name. Standard prefix will be applied here, do not include here." - type = string -} - -variable "bucket_folders" { - description = "List of folders (keys) to create after creation of bucket. They will have object metadata provided based on metadata_tags and data_safeguard labels." - type = list(string) - default = [] -} - -variable "bucket_policy_document" { - description = "IAM Policy document describing additiona policy to be attached to the bucket beyond the default" - type = string - default = "" -} - -variable "kms_key_id" { - description = "AWS KMS Key ID (one per bucket). This is currently ignored." - type = string - 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) - default = {} -} - -variable "metadata_tags" { - description = "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." - type = map(string) - default = {} -} - -variable "access_log_bucket_prefix" { - description = "Access log bucket prefix, to which the bucket name will be appended to make the target_prefix" - type = string - default = "s3" -} - -variable "access_log_bucket" { - description = "Server Access Logging Bucket ID" - type = string - # default = null -} - -variable "allowed_cidr" { - description = "List of allowed source IPs (NOT from within the VPC). If empty, there will be no restrictions on source IP. If provided, you must also use allowed_endpoints for access within a VPC." - type = list(string) - default = [] -} - -variable "allowed_endpoints" { - description = "List of allowed VPC endpoint IDs. If used, it will enable access to the bucket from the specific VPC endpoints." - type = list(string) - default = [] -} - -variable "force_destroy" { - description = "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." - type = bool - default = false -} - -variable "require_explicit_encryption" { - description = "When enabled, adds bucket policy to Deny unencrypted uploads and incorrect encryption header. Should not normally be needed." - type = bool - default = false -} - -# TBD -# variable "kms_policy_read_arns" { } -# variable "kms_policy_write_arns" { } diff --git a/common/version.tf b/common/version.tf index 548c682..03d330b 100644 --- a/common/version.tf +++ b/common/version.tf @@ -1,3 +1,3 @@ locals { - _module_version = "2.2.2" + _module_version = "2.3.0" } diff --git a/kms_key/README.md b/kms_key/README.md new file mode 100644 index 0000000..3359374 --- /dev/null +++ b/kms_key/README.md @@ -0,0 +1,65 @@ +# About aws-s3 :: kms\_key + +This submodule allows you to create a KMS key for use with S3 buckets. + +# Usage + +```hcl +module "mykey" { + source = "git@github.e.it.census.gov:terraform-modules/aws-s3.git//kms_key" + key_name = "mykeyname" + + ## optional + # kms_admin_roles = [ aws_iam_role.cloud-admin.arn ] + # kms_policy_document = data.aws_iam_policy_document.mypolicy.json +} +``` + +## Requirements + +No requirements. + +## Providers + +| Name | Version | +|------|---------| +| [aws](#provider\_aws) | n/a | + +## Modules + +No modules. + +## Resources + +| Name | Type | +|------|------| +| [aws_kms_alias.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_alias) | resource | +| [aws_kms_key.key](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key) | 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.bucket_policy_combined](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | 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_region.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| [data\_safeguards](#input\_data\_safeguards) | Selected available safeguards which apply to the data in the bucket | `list(string)` | `[]` | no | +| [enable\_title26](#input\_enable\_title26) | Flag to enable bucket with Title 26 (FTI) settings | `bool` | `false` | no | +| [key\_name](#input\_key\_name) | KMS Key Name (alias). Standard prefix will be added. | `string` | n/a | yes | +| [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 | +| [kms\_key\_arn](#input\_kms\_key\_arn) | AWS KMS Key ARN, a key created external to this module call. | `string` | `null` | no | +| [kms\_key\_id](#input\_kms\_key\_id) | AWS KMS Key ID (one per bucket). This is currently ignored (and deprecated). | `string` | `null` | no | +| [kms\_policy\_document](#input\_kms\_policy\_document) | AWS KMS Key Policy Document JSON, merged with admin policy document | `string` | `""` | no | +| [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 | + +## Outputs + +| Name | Description | +|------|-------------| +| [kms\_key\_alias](#output\_kms\_key\_alias) | Created KMS Key Alias name | +| [kms\_key\_arn](#output\_kms\_key\_arn) | Created KMS Key ARN | +| [kms\_key\_id](#output\_kms\_key\_id) | Created KMS Key ID | diff --git a/kms_key/data.tf b/kms_key/data.tf new file mode 120000 index 0000000..995624d --- /dev/null +++ b/kms_key/data.tf @@ -0,0 +1 @@ +../common/data.tf \ No newline at end of file diff --git a/kms_key/defaults.tf b/kms_key/defaults.tf new file mode 120000 index 0000000..a5556ac --- /dev/null +++ b/kms_key/defaults.tf @@ -0,0 +1 @@ +../common/defaults.tf \ No newline at end of file diff --git a/kms_key/kms.tf b/kms_key/kms.tf new file mode 120000 index 0000000..b0b3f29 --- /dev/null +++ b/kms_key/kms.tf @@ -0,0 +1 @@ +../common/kms.tf \ No newline at end of file diff --git a/kms_key/main.tf b/kms_key/main.tf new file mode 100644 index 0000000..6f47c84 --- /dev/null +++ b/kms_key/main.tf @@ -0,0 +1,23 @@ +/* +* # About aws-s3 :: kms_key +* +* This submodule allows you to create a KMS key for use with S3 buckets. +* +* # Usage +* +* ```hcl +* module "mykey" { +* source = "git@github.e.it.census.gov:terraform-modules/aws-s3.git//kms_key" +* key_name = "mykeyname" +* +* ## optional +* # kms_admin_roles = [ aws_iam_role.cloud-admin.arn ] +* # kms_policy_document = data.aws_iam_policy_document.mypolicy.json +* } +* ``` +*/ + + +locals { + name = var.key_name +} diff --git a/kms_key/outputs.kms.tf b/kms_key/outputs.kms.tf new file mode 120000 index 0000000..74a8d7b --- /dev/null +++ b/kms_key/outputs.kms.tf @@ -0,0 +1 @@ +../common/outputs.kms.tf \ No newline at end of file diff --git a/kms_key/prefixes.tf b/kms_key/prefixes.tf new file mode 120000 index 0000000..7e265d5 --- /dev/null +++ b/kms_key/prefixes.tf @@ -0,0 +1 @@ +../common/prefixes.tf \ No newline at end of file diff --git a/kms_key/safeguard_variables.tf b/kms_key/safeguard_variables.tf new file mode 100644 index 0000000..a934cfc --- /dev/null +++ b/kms_key/safeguard_variables.tf @@ -0,0 +1,14 @@ +/* +* Valid values include: title13, title26, title42, pii, title5 +*/ +variable "data_safeguards" { + description = "Selected available safeguards which apply to the data in the bucket" + type = list(string) + default = [] +} + +variable "enable_title26" { + description = "Flag to enable bucket with Title 26 (FTI) settings" + type = bool + default = false +} diff --git a/kms_key/variables.common.tf b/kms_key/variables.common.tf new file mode 120000 index 0000000..7439ed8 --- /dev/null +++ b/kms_key/variables.common.tf @@ -0,0 +1 @@ +../common/variables.common.tf \ No newline at end of file diff --git a/kms_key/variables.kms.tf b/kms_key/variables.kms.tf new file mode 120000 index 0000000..08cab47 --- /dev/null +++ b/kms_key/variables.kms.tf @@ -0,0 +1 @@ +../common/variables.kms.tf \ No newline at end of file diff --git a/kms_key/variables.tf b/kms_key/variables.tf new file mode 100644 index 0000000..a076f54 --- /dev/null +++ b/kms_key/variables.tf @@ -0,0 +1,5 @@ +variable "key_name" { + description = "KMS Key Name (alias). Standard prefix will be added." + type = string +} + diff --git a/kms_key/version.tf b/kms_key/version.tf new file mode 120000 index 0000000..b83c5b7 --- /dev/null +++ b/kms_key/version.tf @@ -0,0 +1 @@ +../common/version.tf \ No newline at end of file diff --git a/standard/outputs.tf b/standard/outputs.tf deleted file mode 120000 index 93b0065..0000000 --- a/standard/outputs.tf +++ /dev/null @@ -1 +0,0 @@ -../common/outputs.tf \ No newline at end of file diff --git a/standard/variables.tf b/standard/variables.tf deleted file mode 120000 index 72202b3..0000000 --- a/standard/variables.tf +++ /dev/null @@ -1 +0,0 @@ -../common/variables.tf \ No newline at end of file diff --git a/title26/outputs.tf b/title26/outputs.tf deleted file mode 120000 index 93b0065..0000000 --- a/title26/outputs.tf +++ /dev/null @@ -1 +0,0 @@ -../common/outputs.tf \ No newline at end of file diff --git a/title26/variables.tf b/title26/variables.tf deleted file mode 120000 index 72202b3..0000000 --- a/title26/variables.tf +++ /dev/null @@ -1 +0,0 @@ -../common/variables.tf \ No newline at end of file