Skip to content

Commit 541232b

Browse files
authored
feat: S3 table and table bucket CMK encryption support (#327)
1 parent 1fc4233 commit 541232b

File tree

9 files changed

+78
-10
lines changed

9 files changed

+78
-10
lines changed

examples/table-bucket/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,21 @@ Note that this example may create resources which cost money. Run `terraform des
2020
| Name | Version |
2121
|------|---------|
2222
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
23-
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.83 |
23+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.98 |
2424
| <a name="requirement_random"></a> [random](#requirement\_random) | >= 2.0 |
2525

2626
## Providers
2727

2828
| Name | Version |
2929
|------|---------|
30-
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.83 |
30+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.98 |
3131
| <a name="provider_random"></a> [random](#provider\_random) | >= 2.0 |
3232

3333
## Modules
3434

3535
| Name | Source | Version |
3636
|------|--------|---------|
37+
| <a name="module_kms"></a> [kms](#module\_kms) | terraform-aws-modules/kms/aws | ~> 2.0 |
3738
| <a name="module_table_bucket"></a> [table\_bucket](#module\_table\_bucket) | ../../modules/table-bucket | n/a |
3839

3940
## Resources
@@ -43,6 +44,7 @@ Note that this example may create resources which cost money. Run `terraform des
4344
| [aws_s3tables_namespace.namespace](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3tables_namespace) | resource |
4445
| [random_pet.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/pet) | resource |
4546
| [aws_caller_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
47+
| [aws_region.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/region) | data source |
4648

4749
## Inputs
4850

examples/table-bucket/main.tf

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,18 @@ locals {
1313

1414
data "aws_caller_identity" "this" {}
1515

16+
data "aws_region" "this" {}
17+
1618
module "table_bucket" {
1719
source = "../../modules/table-bucket"
1820

1921
table_bucket_name = local.bucket_name
2022

23+
encryption_configuration = {
24+
kms_key_arn = module.kms.key_arn
25+
sse_algorithm = "aws:kms"
26+
}
27+
2128
maintenance_configuration = {
2229
iceberg_unreferenced_file_removal = {
2330
status = "enabled"
@@ -49,6 +56,11 @@ module "table_bucket" {
4956
format = "ICEBERG"
5057
namespace = aws_s3tables_namespace.namespace.namespace
5158

59+
encryption_configuration = {
60+
kms_key_arn = module.kms.key_arn
61+
sse_algorithm = "aws:kms"
62+
}
63+
5264
maintenance_configuration = {
5365
iceberg_compaction = {
5466
status = "enabled"
@@ -103,3 +115,47 @@ resource "aws_s3tables_namespace" "namespace" {
103115
namespace = "example_namespace"
104116
table_bucket_arn = module.table_bucket.s3_table_bucket_arn
105117
}
118+
119+
module "kms" {
120+
source = "terraform-aws-modules/kms/aws"
121+
version = "~> 2.0"
122+
123+
description = "Key example for s3 table buckets"
124+
deletion_window_in_days = 7
125+
126+
# https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-tables-kms-permissions.html
127+
key_statements = [
128+
{
129+
sid = "s3TablesMaintenancePolicy"
130+
actions = [
131+
"kms:GenerateDataKey",
132+
"kms:Decrypt"
133+
]
134+
resources = ["*"]
135+
136+
principals = [
137+
{
138+
type = "Service"
139+
identifiers = ["maintenance.s3tables.amazonaws.com"]
140+
}
141+
]
142+
143+
conditions = [
144+
{
145+
test = "StringEquals"
146+
variable = "aws:SourceAccount"
147+
values = [
148+
data.aws_caller_identity.this.id,
149+
]
150+
},
151+
{
152+
test = "StringLike"
153+
variable = "kms:EncryptionContext:aws:s3:arn"
154+
values = [
155+
"arn:aws:s3tables:${data.aws_region.this.name}:${data.aws_caller_identity.this.account_id}:bucket/${local.bucket_name}/table/*"
156+
]
157+
}
158+
]
159+
}
160+
]
161+
}

examples/table-bucket/versions.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ terraform {
44
required_providers {
55
aws = {
66
source = "hashicorp/aws"
7-
version = ">= 5.83"
7+
version = ">= 5.98"
88
}
99
random = {
1010
source = "hashicorp/random"

modules/table-bucket/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ Creates S3 Table Bucket and Tables with various configurations.
88
| Name | Version |
99
|------|---------|
1010
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.0 |
11-
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.83 |
11+
| <a name="requirement_aws"></a> [aws](#requirement\_aws) | >= 5.98 |
1212

1313
## Providers
1414

1515
| Name | Version |
1616
|------|---------|
17-
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.83 |
17+
| <a name="provider_aws"></a> [aws](#provider\_aws) | >= 5.98 |
1818

1919
## Modules
2020

@@ -37,7 +37,8 @@ No modules.
3737
|------|-------------|------|---------|:--------:|
3838
| <a name="input_create"></a> [create](#input\_create) | Whether to create s3 table resources | `bool` | `true` | no |
3939
| <a name="input_create_table_bucket_policy"></a> [create\_table\_bucket\_policy](#input\_create\_table\_bucket\_policy) | Whether to create s3 table bucket policy | `bool` | `false` | no |
40-
| <a name="input_maintenance_configuration"></a> [maintenance\_configuration](#input\_maintenance\_configuration) | Map of table bucket maintenance configurations | `any` | `{}` | no |
40+
| <a name="input_encryption_configuration"></a> [encryption\_configuration](#input\_encryption\_configuration) | Map of encryption configurations | `any` | `null` | no |
41+
| <a name="input_maintenance_configuration"></a> [maintenance\_configuration](#input\_maintenance\_configuration) | Map of table bucket maintenance configurations | `any` | `null` | no |
4142
| <a name="input_table_bucket_name"></a> [table\_bucket\_name](#input\_table\_bucket\_name) | Name of the table bucket. Must be between 3 and 63 characters in length. Can consist of lowercase letters, numbers, and hyphens, and must begin and end with a lowercase letter or number | `string` | `null` | no |
4243
| <a name="input_table_bucket_override_policy_documents"></a> [table\_bucket\_override\_policy\_documents](#input\_table\_bucket\_override\_policy\_documents) | List of IAM policy documents that are merged together into the exported document. In merging, statements with non-blank `sid`s will override statements with the same `sid` | `list(string)` | `[]` | no |
4344
| <a name="input_table_bucket_policy"></a> [table\_bucket\_policy](#input\_table\_bucket\_policy) | Amazon Web Services resource-based policy document in JSON format | `string` | `null` | no |

modules/table-bucket/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ resource "aws_s3tables_table_bucket" "this" {
22
count = var.create ? 1 : 0
33

44
name = var.table_bucket_name
5+
encryption_configuration = var.encryption_configuration
56
maintenance_configuration = var.maintenance_configuration
67
}
78

@@ -67,6 +68,7 @@ resource "aws_s3tables_table" "this" {
6768
name = try(each.value.table_name, each.key)
6869
namespace = each.value.namespace
6970
table_bucket_arn = aws_s3tables_table_bucket.this[0].arn
71+
encryption_configuration = try(each.value.encryption_configuration, null)
7072
maintenance_configuration = try(each.value.maintenance_configuration, null)
7173
}
7274

modules/table-bucket/variables.tf

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,16 @@ variable "table_bucket_name" {
1010
default = null
1111
}
1212

13+
variable "encryption_configuration" {
14+
description = "Map of encryption configurations"
15+
type = any
16+
default = null
17+
}
18+
1319
variable "maintenance_configuration" {
1420
description = "Map of table bucket maintenance configurations"
1521
type = any
16-
default = {}
22+
default = null
1723
}
1824

1925
variable "create_table_bucket_policy" {

modules/table-bucket/versions.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ terraform {
44
required_providers {
55
aws = {
66
source = "hashicorp/aws"
7-
version = ">= 5.83"
7+
version = ">= 5.98"
88
}
99
}
1010
}

wrappers/table-bucket/main.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ module "wrapper" {
55

66
create = try(each.value.create, var.defaults.create, true)
77
create_table_bucket_policy = try(each.value.create_table_bucket_policy, var.defaults.create_table_bucket_policy, false)
8-
maintenance_configuration = try(each.value.maintenance_configuration, var.defaults.maintenance_configuration, {})
8+
encryption_configuration = try(each.value.encryption_configuration, var.defaults.encryption_configuration, null)
9+
maintenance_configuration = try(each.value.maintenance_configuration, var.defaults.maintenance_configuration, null)
910
table_bucket_name = try(each.value.table_bucket_name, var.defaults.table_bucket_name, null)
1011
table_bucket_override_policy_documents = try(each.value.table_bucket_override_policy_documents, var.defaults.table_bucket_override_policy_documents, [])
1112
table_bucket_policy = try(each.value.table_bucket_policy, var.defaults.table_bucket_policy, null)

wrappers/table-bucket/versions.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ terraform {
44
required_providers {
55
aws = {
66
source = "hashicorp/aws"
7-
version = ">= 5.83"
7+
version = ">= 5.98"
88
}
99
}
1010
}

0 commit comments

Comments
 (0)