Skip to content

Commit a125a76

Browse files
committed
Add support for TDE key rotation
1 parent 6c137e1 commit a125a76

23 files changed

+472
-68
lines changed

docs/resources/service.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,9 @@ Required:
162162

163163
- `enabled` (Boolean) If true, TDE is enabled for the service.
164164

165-
Optional:
165+
Read-Only:
166166

167-
- `key_id` (String) ID of the Encryption key to use for data encryption. Must be an ARN for AWS services or a Key Resource Path for GCP services.
167+
- `role_id` (String) ID of Role to be used for granting access to the Encryption Key. This is an ARN for AWS services and a Service Account Identifier for GCP.
168168

169169

170170
<a id="nestedatt--private_endpoint_config"></a>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "clickhouse_service_transparent_data_encryption_key_association Resource - clickhouse"
4+
subcategory: ""
5+
description: |-
6+
You can use the clickhouse_service resource to deploy ClickHouse cloud instances on supported cloud providers.
7+
Known limitations:
8+
If you create a service with warehouse_id set and then remove warehouse_id attribute completely, the provider won't detect the change. If you want to make a secondary service become primary, remove the warehouse_id and taint it before applying.If you create a service with readonly flag set to true and then remove readonly flag completely, the provider won't detect the change. If you want to make a secondary service read write, explicitly set the readonly flag to false.
9+
---
10+
11+
# clickhouse_service_transparent_data_encryption_key_association (Resource)
12+
13+
You can use the *clickhouse_service* resource to deploy ClickHouse cloud instances on supported cloud providers.
14+
15+
Known limitations:
16+
17+
- If you create a service with `warehouse_id` set and then remove `warehouse_id` attribute completely, the provider won't detect the change. If you want to make a secondary service become primary, remove the `warehouse_id` and taint it before applying.
18+
- If you create a service with `readonly` flag set to true and then remove `readonly` flag completely, the provider won't detect the change. If you want to make a secondary service read write, explicitly set the `readonly` flag to false.
19+
20+
## Example Usage
21+
22+
```terraform
23+
resource "clickhouse_service" "service" {
24+
...
25+
}
26+
27+
resource "aws_kms_key" "enc" {
28+
...
29+
}
30+
31+
resource "clickhouse_service_transparent_data_encryption_key_association" "service_key_association" {
32+
service_id = clickhouse_service.service.id
33+
key_id = aws_kms_key.enc.arn
34+
}
35+
```
36+
37+
<!-- schema generated by tfplugindocs -->
38+
## Schema
39+
40+
### Required
41+
42+
- `key_id` (String) ID of the Encryption key to use for data encryption. Must be an ARN for AWS services or a Key Resource Path for GCP services.
43+
- `service_id` (String) ClickHouse Service ID
44+
45+
## Import
46+
47+
Import is supported using the following syntax:
48+
49+
```shell
50+
# Endpoint Attachments can be imported by specifying the clickhouse service UUID
51+
terraform import clickhouse_service_transparent_data_encryption_key_association.example xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
52+
```
File renamed without changes.

examples/full/tde/aws/aws.tf

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
variable "aws_key" {
2+
type = string
3+
}
4+
5+
variable "aws_secret" {
6+
type = string
7+
}
8+
9+
variable "aws_session_token" {
10+
type = string
11+
default = ""
12+
}
13+
14+
locals {
15+
tags = {
16+
Name = var.service_name
17+
}
18+
}
19+
20+
provider "aws" {
21+
region = var.region
22+
access_key = var.aws_key
23+
secret_key = var.aws_secret
24+
token = var.aws_session_token
25+
}
26+
27+
data "aws_caller_identity" "current" {}
28+
29+
data "aws_iam_policy_document" "policy" {
30+
# Allow root user on the account all access.
31+
statement {
32+
sid = "AllowRoot"
33+
34+
actions = ["kms:*"]
35+
resources = ["*"]
36+
principals {
37+
type = "AWS"
38+
identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
39+
}
40+
}
41+
42+
# Allow user that runs terraform to manage the KMS key.
43+
statement {
44+
sid = "AllowAdmins"
45+
actions = [
46+
"kms:Create*",
47+
"kms:Describe*",
48+
"kms:Enable*",
49+
"kms:List*",
50+
"kms:Put*",
51+
"kms:Update*",
52+
"kms:Revoke*",
53+
"kms:Disable*",
54+
"kms:Get*",
55+
"kms:Delete*",
56+
"kms:TagResource",
57+
"kms:UntagResource",
58+
"kms:ScheduleKeyDeletion",
59+
"kms:CancelKeyDeletion",
60+
"kms:RotateKeyOnDemand",
61+
"kms:Encrypt",
62+
"kms:Decrypt",
63+
"kms:ReEncrypt*",
64+
"kms:DescribeKey",
65+
"kms:CreateGrant",
66+
"kms:ListGrants",
67+
"kms:RevokeGrant"
68+
]
69+
resources = ["*"]
70+
71+
principals {
72+
type = "AWS"
73+
identifiers = [data.aws_caller_identity.current.arn]
74+
}
75+
}
76+
77+
# Allow clickhouse's accounts to access the KMS key.
78+
statement {
79+
sid = "AllowClickHouse"
80+
actions = [
81+
"kms:Encrypt",
82+
"kms:Decrypt",
83+
"kms:ReEncrypt*",
84+
"kms:DescribeKey",
85+
]
86+
resources = ["*"]
87+
88+
principals {
89+
type = "AWS"
90+
identifiers = [clickhouse_service.service.transparent_data_encryption.role_id]
91+
}
92+
}
93+
}
94+
95+
resource "aws_kms_key" "enc" {
96+
customer_master_key_spec = "SYMMETRIC_DEFAULT"
97+
deletion_window_in_days = 7
98+
description = var.service_name
99+
enable_key_rotation = false
100+
is_enabled = true
101+
key_usage = "ENCRYPT_DECRYPT"
102+
multi_region = false
103+
104+
policy = data.aws_iam_policy_document.policy.json
105+
106+
tags = local.tags
107+
}

examples/tde/aws/main.tf renamed to examples/full/tde/aws/main.tf

+5-1
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,14 @@ resource "clickhouse_service" "service" {
5959

6060
transparent_data_encryption = {
6161
enabled = true
62-
key_id = "arn:aws:kms:us-east-2:XXXXXXXX:key/12345-6789-abcd-ef01-23456789abcde"
6362
}
6463
}
6564

65+
resource "clickhouse_service_transparent_data_encryption_key_association" "service_key_association" {
66+
service_id = clickhouse_service.service.id
67+
key_id = aws_kms_key.enc.arn
68+
}
69+
6670
output "service_endpoints" {
6771
value = clickhouse_service.service.endpoints
6872
}
File renamed without changes.

examples/tde/gcp/variables.tfvars.sample renamed to examples/full/tde/aws/variables.tfvars.sample

+5
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,8 @@
22
organization_id = "aee076c1-3f83-4637-95b1-ad5a0a825b71"
33
token_key = "avhj1U5QCdWAE9CA9"
44
token_secret = "4b1dROiHQEuSXJHlV8zHFd0S7WQj7CGxz5kGJeJnca"
5+
6+
# AWS
7+
aws_key = "key"
8+
aws_secret = "secret"
9+
aws_region = "us-west-2"
File renamed without changes.

examples/tde/gcp/main.tf renamed to examples/full/tde/gcp/main.tf

-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ resource "clickhouse_service" "service" {
7373

7474
transparent_data_encryption = {
7575
enabled = true
76-
key_id = "arn:aws:kms:us-east-2:XXXXXXXX:key/12345-6789-abcd-ef01-23456789abcde"
7776
}
7877
}
7978

File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Endpoint Attachments can be imported by specifying the clickhouse service UUID
2+
terraform import clickhouse_service_transparent_data_encryption_key_association.example xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
resource "clickhouse_service" "service" {
2+
...
3+
}
4+
5+
resource "aws_kms_key" "enc" {
6+
...
7+
}
8+
9+
resource "clickhouse_service_transparent_data_encryption_key_association" "service_key_association" {
10+
service_id = clickhouse_service.service.id
11+
key_id = aws_kms_key.enc.arn
12+
}

pkg/internal/api/models.go

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type Service struct {
6464
EncryptionAssumedRoleIdentifier string `json:"encryptionAssumedRoleIdentifier,omitempty"`
6565
HasTransparentDataEncryption bool `json:"hasTransparentDataEncryption,omitempty"`
6666
TransparentEncryptionDataKeyID string `json:"transparentDataEncryptionKeyId,omitempty"`
67+
EncryptionRoleID string `json:"encryptionRoleId,omitempty"`
6768
BackupConfiguration *BackupConfiguration `json:"backupConfiguration,omitempty"`
6869
ReleaseChannel string `json:"releaseChannel,omitempty"`
6970
QueryAPIEndpoints *ServiceQueryEndpoint `json:"-"`
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
You can use the *clickhouse_service_transparent_data_encryption_key_association* resource to associate your own Encryption Key with a Clickhouse Service with the Transparent Data Encryption (TDE) feature enabled.
2+
Please note that this feature requires an organization with the `Enterprise` plan.

pkg/resource/models/service_resource.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -135,22 +135,22 @@ func (e OptionalEndpoint) ObjectValue() basetypes.ObjectValue {
135135

136136
type TransparentEncryptionData struct {
137137
Enabled types.Bool `tfsdk:"enabled"`
138-
KeyID types.String `tfsdk:"key_id"`
138+
RoleID types.String `tfsdk:"role_id"`
139139
}
140140

141141
func (t TransparentEncryptionData) ObjectType() types.ObjectType {
142142
return types.ObjectType{
143143
AttrTypes: map[string]attr.Type{
144144
"enabled": types.BoolType,
145-
"key_id": types.StringType,
145+
"role_id": types.StringType,
146146
},
147147
}
148148
}
149149

150150
func (t TransparentEncryptionData) ObjectValue() basetypes.ObjectValue {
151151
return types.ObjectValueMust(t.ObjectType().AttrTypes, map[string]attr.Value{
152152
"enabled": t.Enabled,
153-
"key_id": t.KeyID,
153+
"role_id": t.RoleID,
154154
})
155155
}
156156

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package models
2+
3+
import (
4+
"github.com/hashicorp/terraform-plugin-framework/types"
5+
)
6+
7+
type ServiceTransparentDataEncryptionKeyAssociation struct {
8+
ServiceID types.String `tfsdk:"service_id"`
9+
KeyID types.String `tfsdk:"key_id"`
10+
}

pkg/resource/register_debug.go

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ func GetResourceFactories() []func() upstreamresource.Resource {
1111
NewServiceResource,
1212
NewPrivateEndpointRegistrationResource,
1313
NewServicePrivateEndpointsAttachmentResource,
14+
NewServiceTransparentDataEncryptionKeyAssociationResource,
1415
NewDatabaseResource,
1516
NewClickPipeResource,
1617
NewClickPipeReversePrivateEndpointResource,

pkg/resource/register_stable.go

+1
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ func GetResourceFactories() []func() upstreamresource.Resource {
1111
NewServiceResource,
1212
NewPrivateEndpointRegistrationResource,
1313
NewServicePrivateEndpointsAttachmentResource,
14+
NewServiceTransparentDataEncryptionKeyAssociationResource,
1415
}
1516
}

0 commit comments

Comments
 (0)