-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds a new CMEK resource, which primarily manages the configuration of customer-managed encryption keys (CMEK). CMEK is enabled for a cluster when the resource is created, and keys can be rotated by updating their specs. Due to circular dependencies (new regions depend on CMEK config, which depends on role policy, which depends on cluster), new regions must be managed by the CMEK resource. That means the cluster resource and CMEK resource need to keep track of which regions they "own" and reconcile that with updates and the actual state of the cluster. That's the bulk of the complexity here. Destroying a CMEK resource is a no-op, since CMEK cannot be disabled. That means that a user could be left with "floating" regions. I need to figure out a way to block targeted destroy operations on CMEK resources while allowing them to be removed from state when the parent cluster is destroyed. We could attempt to remove additional regions on destroy, but that would take significantly longer. Happy to do a walkthrough and discuss tradeoffs at a watercooler.
- Loading branch information
1 parent
5e55c84
commit 3d6a9d5
Showing
13 changed files
with
1,279 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
--- | ||
# generated by https://github.com/hashicorp/terraform-plugin-docs | ||
page_title: "cockroach_cmek Resource - terraform-provider-cockroach" | ||
subcategory: "" | ||
description: |- | ||
Customer-managed encryption keys (CMEK) resource for a single cluster | ||
--- | ||
|
||
# cockroach_cmek (Resource) | ||
|
||
Customer-managed encryption keys (CMEK) resource for a single cluster | ||
|
||
|
||
|
||
<!-- schema generated by tfplugindocs --> | ||
## Schema | ||
|
||
### Required | ||
|
||
- `id` (String) Cluster ID | ||
- `regions` (Attributes List) (see [below for nested schema](#nestedatt--regions)) | ||
|
||
### Optional | ||
|
||
- `additional_regions` (Attributes List) Once CMEK is enabled for a cluster, no new regions can be added to the cluster resource, since they need encryption key info stored in the CMEK resource. New regions can be added and maintained here instead. (see [below for nested schema](#nestedatt--additional_regions)) | ||
|
||
### Read-Only | ||
|
||
- `status` (String) Aggregated status of the cluster's encryption key(s) | ||
|
||
<a id="nestedatt--regions"></a> | ||
### Nested Schema for `regions` | ||
|
||
Required: | ||
|
||
- `key` (Attributes) (see [below for nested schema](#nestedatt--regions--key)) | ||
- `region` (String) | ||
|
||
Read-Only: | ||
|
||
- `status` (String) | ||
|
||
<a id="nestedatt--regions--key"></a> | ||
### Nested Schema for `regions.key` | ||
|
||
Required: | ||
|
||
- `auth_principal` (String) | ||
- `type` (String) Current allowed values are 'AWS_KMS' and 'GCP_CLOUD_KMS' | ||
- `uri` (String) | ||
|
||
Read-Only: | ||
|
||
- `created_at` (String) | ||
- `status` (String) | ||
- `updated_at` (String) | ||
- `user_message` (String) | ||
|
||
|
||
|
||
<a id="nestedatt--additional_regions"></a> | ||
### Nested Schema for `additional_regions` | ||
|
||
Required: | ||
|
||
- `name` (String) | ||
|
||
Optional: | ||
|
||
- `node_count` (Number) | ||
|
||
Read-Only: | ||
|
||
- `sql_dns` (String) | ||
- `ui_dns` (String) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
# Your Organization ID can be found at https://cockroachlabs.cloud/information | ||
variable "org_id" { | ||
type = string | ||
nullable = false | ||
} | ||
|
||
# Required to assign yourself permission to update the key. | ||
variable "iam_user" { | ||
type = string | ||
nullable = false | ||
} | ||
|
||
variable "cluster_name" { | ||
type = string | ||
nullable = false | ||
} | ||
|
||
variable "aws_region" { | ||
type = string | ||
nullable = false | ||
default = "us-west2" | ||
} | ||
|
||
variable "additional_regions" { | ||
type = list(string) | ||
nullable = false | ||
} | ||
|
||
variable "cluster_node_count" { | ||
type = number | ||
nullable = false | ||
default = 3 | ||
} | ||
|
||
variable "storage_gib" { | ||
type = number | ||
nullable = false | ||
default = 15 | ||
} | ||
|
||
variable "machine_type" { | ||
type = string | ||
nullable = false | ||
default = "m5.large" | ||
} | ||
|
||
terraform { | ||
required_providers { | ||
cockroach = { | ||
source = "cockroachdb/cockroach" | ||
} | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = "~> 4.0" | ||
} | ||
} | ||
} | ||
provider "cockroach" { | ||
# export COCKROACH_API_KEY with the cockroach cloud API Key | ||
} | ||
|
||
provider "aws" { | ||
# See https://registry.terraform.io/providers/hashicorp/aws/latest/docs | ||
# for configuration steps. | ||
|
||
# Please don't use a variable for region in production! The AWS provider won't | ||
# be able to find any resources if this value changes and you'll get | ||
# into a weird state. Be sure to run `terraform destroy` before changing | ||
# this value. | ||
region = var.aws_region | ||
} | ||
|
||
resource "cockroach_cluster" "example" { | ||
name = var.cluster_name | ||
cloud_provider = "AWS" | ||
dedicated = { | ||
storage_gib = var.storage_gib | ||
machine_type = var.machine_type | ||
private_network_visibility = true | ||
} | ||
regions = [{ | ||
name = var.aws_region, | ||
node_count = var.cluster_node_count | ||
} | ||
] | ||
} | ||
|
||
resource "aws_iam_role" "example" { | ||
name = "cmek_test_role" | ||
|
||
assume_role_policy = jsonencode({ | ||
"Version" : "2012-10-17", | ||
"Statement" : [ | ||
{ | ||
"Effect" : "Allow", | ||
"Action" : "sts:AssumeRole", | ||
"Principal" : { | ||
"AWS" : cockroach_cluster.example.account_id | ||
}, | ||
"Condition" : { | ||
"StringEquals" : { | ||
"sts:ExternalId" : var.org_id | ||
} | ||
} | ||
} | ||
] | ||
}) | ||
} | ||
|
||
data "aws_iam_user" "example" { | ||
user_name = var.iam_user | ||
} | ||
|
||
resource "aws_kms_key" "example" { | ||
policy = jsonencode({ | ||
"Version" : "2012-10-17", | ||
"Statement" : [ | ||
{ | ||
"Effect" : "Allow", | ||
"Action" : "kms:*", | ||
"Principal" : { | ||
"AWS" : [ | ||
aws_iam_role.example.arn, | ||
data.aws_iam_user.example.arn | ||
] | ||
}, | ||
"Resource" : "*" | ||
} | ||
] | ||
}) | ||
multi_region = true | ||
} | ||
|
||
resource "cockroach_cmek" "example" { | ||
id = cockroach_cluster.example.id | ||
regions = /*concat(*/[ | ||
{ | ||
region : var.aws_region | ||
key : { | ||
auth_principal : aws_iam_role.example.arn | ||
type : "AWS_KMS" | ||
uri : aws_kms_key.example.arn | ||
} | ||
} | ||
]#, | ||
# | ||
# Additional regions can be added after CMEK is enabled by updating | ||
# the `region` attribute and adding their name and node count to | ||
# `additional_regions`. These regions will be managed separately from | ||
# the parent cluster, but will otherwise behave the same. Cluster data | ||
# sources will always show the entire list of regions, regardless of | ||
# whether they're managed by the cluster or CMEK resource. | ||
# | ||
# These should be concatenated with the current region(s). | ||
#[for r in var.additional_regions : { | ||
# region: r, | ||
# key: { | ||
# auth_principal: aws_iam_role.example.arn | ||
# type: "AWS_KMS" | ||
# uri: aws_kms_key.example.arn | ||
# } | ||
#}]) | ||
|
||
#additional_regions = [for r in var.additional_regions : | ||
# { | ||
# name = r | ||
# node_count = var.cluster_node_count | ||
# } | ||
#] | ||
} |
Oops, something went wrong.