Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b2ff6cd
feat: add support to use a different KMS key for backup encryption
Nov 14, 2024
c02ed29
feat: add support to use a different KMS key for backup encryption
Nov 14, 2024
85306bd
feat: add support to use a different KMS key for backup encryption
Nov 14, 2024
e9c00fa
feat: add support to use a different KMS key for backup encryption
Nov 14, 2024
effe3f9
fix: hardcode region
Nov 15, 2024
c99610e
fix: hardcode region
Nov 15, 2024
27c3fe8
fix: hardcode region
Nov 15, 2024
292f5cd
Merge branch 'main' into backup-encryption
jor2 Nov 17, 2024
a323994
fix: add policy
Nov 18, 2024
86d464e
fix: add policy
Nov 18, 2024
047f79a
fix: add policy
Nov 18, 2024
943ac34
fix: add policy
Nov 18, 2024
3a89deb
fix: add policy
Nov 18, 2024
b79e8ea
fix: add policy
Nov 18, 2024
37f0e96
fix: add policy
Nov 18, 2024
5cbed2b
fix: add policy
Nov 18, 2024
1365c25
fix: add policy
Nov 18, 2024
8bae00b
fix: add policy
Nov 18, 2024
89e82d9
fix: add policy sleep
Nov 18, 2024
bed3396
fix: id instead of crn
Nov 18, 2024
a036083
Merge branch 'main' into backup-encryption
jor2 Nov 19, 2024
9df97ea
fix: update for tests
Nov 19, 2024
cc7988c
Merge branch 'backup-encryption' of github.com:terraform-ibm-modules/…
Nov 19, 2024
613facc
fix: id instead of crn
Nov 19, 2024
592308e
fix: cra
Nov 20, 2024
d717b1d
Merge branch 'main' into backup-encryption
jor2 Nov 20, 2024
84cf169
Merge branch 'main' into backup-encryption
jor2 Nov 25, 2024
babec55
Merge branch 'main' into backup-encryption
jor2 Nov 27, 2024
c1b863a
Merge branch 'main' into backup-encryption
jor2 Dec 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions ibm_catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@
{
"title": "Attaches access tags",
"description": "Attaches access tags to the Elasticsearch instance."
},
{
"title": "Supports backup restoration",
"description": "Provides database restoration using a backup created by a deployment with the same service ID."
}
],
"flavors": [
Expand Down Expand Up @@ -274,6 +278,15 @@
{
"key": "auto_scaling"
},
{
"key": "backup_crn"
},
{
"key": "existing_backup_kms_key_crn"
},
{
"key": "existing_backup_kms_instance_crn"
},
{
"key": "enable_elser_model"
},
Expand Down
76 changes: 74 additions & 2 deletions solutions/standard/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -122,23 +122,95 @@ module "kms" {
]
}

#######################################################################################################################
# KMS backup encryption key for Elasticsearch
#######################################################################################################################

locals {
existing_backup_kms_instance_guid = var.existing_backup_kms_instance_crn != null ? module.backup_kms_instance_crn_parser[0].service_instance : null
existing_backup_kms_instance_region = var.existing_backup_kms_instance_crn != null ? module.backup_kms_instance_crn_parser[0].region : null

backup_key_name = var.prefix != null ? "${var.prefix}-backup-encryption-${var.elasticsearch_key_name}" : "backup-encryption-${var.elasticsearch_key_name}"
backup_key_ring_name = var.prefix != null ? "${var.prefix}-backup-encryption-${var.elasticsearch_key_ring_name}" : "backup-encryption-${var.elasticsearch_key_ring_name}"
backup_kms_key_crn = var.existing_backup_kms_key_crn != null ? var.existing_backup_kms_key_crn : var.existing_backup_kms_instance_crn != null ? module.backup_kms[0].keys[format("%s.%s", local.backup_key_ring_name, local.backup_key_name)].crn : null
backup_kms_service_name = var.existing_backup_kms_instance_crn != null ? module.backup_kms_instance_crn_parser[0].service_name : null
}

# If existing KMS intance CRN passed, parse details from it
module "backup_kms_instance_crn_parser" {
count = var.existing_backup_kms_instance_crn != null ? 1 : 0
source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
version = "1.1.0"
crn = var.existing_backup_kms_instance_crn
}

resource "ibm_iam_authorization_policy" "backup_kms_policy" {
count = local.existing_backup_kms_instance_guid == local.existing_kms_instance_guid ? 0 : var.existing_backup_kms_key_crn != null ? 0 : var.existing_backup_kms_instance_crn != null ? !var.skip_iam_authorization_policy ? 1 : 0 : 0
provider = ibm.kms
source_service_account = local.create_cross_account_auth_policy ? data.ibm_iam_account_settings.iam_account_settings[0].account_id : null
source_service_name = "databases-for-elasticsearch"
source_resource_group_id = module.resource_group.resource_group_id
target_service_name = local.backup_kms_service_name
target_resource_instance_id = local.existing_backup_kms_instance_guid
roles = ["Reader"]
description = "Allow all Elasticsearch instances in the resource group ${module.resource_group.resource_group_id} to read from the ${local.backup_kms_service_name} instance GUID ${local.existing_backup_kms_instance_guid}"
}

# workaround for https://github.com/IBM-Cloud/terraform-provider-ibm/issues/4478
resource "time_sleep" "wait_for_backup_kms_authorization_policy" {
depends_on = [ibm_iam_authorization_policy.backup_kms_policy]
create_duration = "30s"
}

module "backup_kms" {
providers = {
ibm = ibm.kms
}
count = var.use_ibm_owned_encryption_key ? 0 : var.existing_backup_kms_key_crn != null ? 0 : var.existing_backup_kms_instance_crn != null ? 1 : 0
source = "terraform-ibm-modules/kms-all-inclusive/ibm"
version = "4.15.13"
create_key_protect_instance = false
region = local.existing_backup_kms_instance_region
existing_kms_instance_crn = var.existing_backup_kms_instance_crn
key_ring_endpoint_type = var.kms_endpoint_type
key_endpoint_type = var.kms_endpoint_type
keys = [
{
key_ring_name = local.backup_key_ring_name
existing_key_ring = false
force_delete_key_ring = true
keys = [
{
key_name = local.backup_key_name
standard_key = false
rotation_interval_month = 3
dual_auth_delete_enabled = false
force_delete = true
}
]
}
]
}

#######################################################################################################################
# Elasticsearch
#######################################################################################################################

module "elasticsearch" {
count = local.use_existing_db_instance ? 0 : 1
source = "../../modules/fscloud"
depends_on = [time_sleep.wait_for_authorization_policy]
depends_on = [time_sleep.wait_for_authorization_policy, time_sleep.wait_for_backup_kms_authorization_policy]
resource_group_id = module.resource_group.resource_group_id
name = var.prefix != null ? "${var.prefix}-${var.name}" : var.name
region = var.region
plan = var.plan
skip_iam_authorization_policy = var.skip_iam_authorization_policy || local.create_cross_account_auth_policy
skip_iam_authorization_policy = var.skip_iam_authorization_policy || local.create_cross_account_auth_policy ? true : var.skip_iam_authorization_policy
elasticsearch_version = var.elasticsearch_version
existing_kms_instance_guid = local.existing_kms_instance_guid
use_ibm_owned_encryption_key = var.use_ibm_owned_encryption_key
kms_key_crn = local.kms_key_crn
backup_encryption_key_crn = local.backup_kms_key_crn
backup_crn = var.backup_crn
access_tags = var.access_tags
tags = var.tags
admin_pass = local.admin_pass
Expand Down
25 changes: 23 additions & 2 deletions solutions/standard/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ variable "elasticsearch_version" {
default = null
}

variable "backup_crn" {
type = string
description = "The CRN of a backup resource to restore from. The backup is created by a database deployment with the same service ID. The backup is loaded after provisioning and the new deployment starts up that uses that data. A backup CRN is in the format crn:v1:<…>:backup:. If omitted, the database is provisioned empty."
default = null
}

variable "region" {
type = string
description = "The region where you want to deploy your instance."
Expand Down Expand Up @@ -208,7 +214,7 @@ variable "auto_scaling" {

variable "existing_kms_key_crn" {
type = string
description = "The CRN of a Hyper Protect Crypto Services or Key Protect root key to use for disk encryption. If not specified, a root key is created in the KMS instance."
description = "The CRN of an Hyper Protect Crypto Services or Key Protect encryption key that you want to use to use for both disk and backup encryption. If no value is passed, a new key ring and key will be created in the instance provided in the `existing_kms_instance_crn` input. Backup encryption is only supported is some regions ([learn more](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok)), so if you need to use a key from a different region for backup encryption, use the `existing_backup_kms_key_crn` input."
default = null
}

Expand All @@ -230,7 +236,7 @@ variable "kms_endpoint_type" {

variable "existing_kms_instance_crn" {
type = string
description = "The CRN of a Hyper Protect Crypto Services or Key Protect instance in the same account as the Databases for Elasticsearch instance. This value is used to create an authorization policy if `skip_iam_authorization_policy` is false. If not specified, a root key is created."
description = "The CRN of an Hyper Protect Crypto Services or Key Protect instance that you want to use for both disk and backup encryption. Backup encryption is only supported is some regions ([learn more](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok)), so if you need to use a different instance for backup encryption from a supported region, use the `existing_backup_kms_instance_crn` input."
default = null
}

Expand Down Expand Up @@ -354,3 +360,18 @@ variable "elasticsearch_full_version" {
type = string
default = null
}

##############################################################
# Backup Encryption
##############################################################
variable "existing_backup_kms_key_crn" {
type = string
description = "The CRN of an Hyper Protect Crypto Services or Key Protect encryption key that you want to use to encrypt database backups. If no value is passed, the value of `existing_kms_key_crn` is used. If no value is passed for that, a new key will be created in the provided KMS instance and used for both disk encryption, and backup encryption."
default = null
}

variable "existing_backup_kms_instance_crn" {
description = "The CRN of an Hyper Protect Crypto Services or Key Protect instance that you want to use to encrypt database backups. If no value is passed, the value of the `existing_kms_instance_crn` input will be used, however backup encryption is only supported in certain regions so you need to ensure the KMS for backup is coming from one of the supported regions. [Learn more](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok)"
type = string
default = null
}
1 change: 1 addition & 0 deletions tests/pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ func TestRunStandardSolutionSchematics(t *testing.T) {
{Name: "enable_kibana_dashboard", Value: true, DataType: "bool"},
{Name: "provider_visibility", Value: "private", DataType: "string"},
{Name: "prefix", Value: options.Prefix, DataType: "string"},
{Name: "existing_backup_kms_key_crn", Value: permanentResources["hpcs_south_root_key_crn"], DataType: "string"},
}
err := options.RunSchematicTest()
assert.Nil(t, err, "This should not have errored")
Expand Down