diff --git a/README.md b/README.md index 40be36d9..cc8ead64 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ To attach access management tags to resources in this module, you need the follo | [auto\_scaling](#input\_auto\_scaling) | Optional rules to allow the database to increase resources in response to usage. Only a single autoscaling block is allowed. Make sure you understand the effects of autoscaling, especially for production environments. See https://ibm.biz/autoscaling-considerations in the IBM Cloud Docs. |
object({
disk = object({
capacity_enabled = optional(bool, false)
free_space_less_than_percent = optional(number, 10)
io_above_percent = optional(number, 90)
io_enabled = optional(bool, false)
io_over_period = optional(string, "15m")
rate_increase_percent = optional(number, 10)
rate_limit_mb_per_member = optional(number, 3670016)
rate_period_seconds = optional(number, 900)
rate_units = optional(string, "mb")
})
memory = object({
io_above_percent = optional(number, 90)
io_enabled = optional(bool, false)
io_over_period = optional(string, "15m")
rate_increase_percent = optional(number, 10)
rate_limit_mb_per_member = optional(number, 114688)
rate_period_seconds = optional(number, 900)
rate_units = optional(string, "mb")
})
}) | `null` | no |
| [backup\_crn](#input\_backup\_crn) | 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. | `string` | `null` | no |
| [backup\_encryption\_key\_crn](#input\_backup\_encryption\_key\_crn) | The CRN of a Key Protect or Hyper Protect Crypto Services encryption key that you want to use for encrypting the disk that holds deployment backups. Applies only if `use_ibm_owned_encryption_key` is false and `use_same_kms_key_for_backups` is false. If no value is passed, and `use_same_kms_key_for_backups` is true, the value of `kms_key_crn` is used. Alternatively set `use_default_backup_encryption_key` to true to use the IBM Cloud Databases default encryption. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups). | `string` | `null` | no |
-| [cbr\_rules](#input\_cbr\_rules) | (Optional, list) List of CBR rules to create | list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
})) | `[]` | no |
+| [cbr\_rules](#input\_cbr\_rules) | (Optional, list) List of CBR rules to create | list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
tags = optional(list(object({
name = string
value = string
})))
})) | `[]` | no |
| [configuration](#input\_configuration) | Database configuration parameters, see https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-changing-configuration&interface=api for more details. | object({
shared_buffers = optional(number)
max_connections = optional(number)
# below field gives error when sent to provider
# tracking issue: https://github.com/IBM-Cloud/terraform-provider-ibm/issues/5403
# max_locks_per_transaction = optional(number)
max_prepared_transactions = optional(number)
synchronous_commit = optional(string)
effective_io_concurrency = optional(number)
deadlock_timeout = optional(number)
log_connections = optional(string)
log_disconnections = optional(string)
log_min_duration_statement = optional(number)
tcp_keepalives_idle = optional(number)
tcp_keepalives_interval = optional(number)
tcp_keepalives_count = optional(number)
archive_timeout = optional(number)
wal_level = optional(string)
max_replication_slots = optional(number)
max_wal_senders = optional(number)
}) | `null` | no |
| [kms\_key\_crn](#input\_kms\_key\_crn) | The CRN of a Key Protect or Hyper Protect Crypto Services encryption key to encrypt your data. Applies only if `use_ibm_owned_encryption_key` is false. By default this key is used for both deployment data and backups, but this behaviour can be altered using the `use_same_kms_key_for_backups` and `backup_encryption_key_crn` inputs. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups). | `string` | `null` | no |
| [member\_cpu\_count](#input\_member\_cpu\_count) | Allocated dedicated CPU per member. For shared CPU, set to 0. [Learn more](https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-resources-scaling). Ignored during restore and point in time recovery operations | `number` | `0` | no |
@@ -113,10 +113,10 @@ To attach access management tags to resources in this module, you need the follo
| [region](#input\_region) | The region where you want to deploy your instance. | `string` | `"us-south"` | no |
| [remote\_leader\_crn](#input\_remote\_leader\_crn) | A CRN of the leader database to make the replica(read-only) deployment. The leader database is created by a database deployment with the same service ID. A read-only replica is set up to replicate all of your data from the leader deployment to the replica deployment by using asynchronous replication. For more information, see https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-read-only-replicas | `string` | `null` | no |
| [resource\_group\_id](#input\_resource\_group\_id) | The resource group ID where the PostgreSQL instance will be created. | `string` | n/a | yes |
-| [resource\_tags](#input\_resource\_tags) | Optional list of tags to be added to the PostgreSQL instance. | `list(string)` | `[]` | no |
| [service\_credential\_names](#input\_service\_credential\_names) | Map of name, role for service credentials that you want to create for the database | `map(string)` | `{}` | no |
| [service\_endpoints](#input\_service\_endpoints) | Specify whether you want to enable the public, private, or both service endpoints. Supported values are 'public', 'private', or 'public-and-private'. | `string` | `"private"` | no |
| [skip\_iam\_authorization\_policy](#input\_skip\_iam\_authorization\_policy) | Set to true to skip the creation of IAM authorization policies that permits all Databases for PostgreSQL instances in the given resource group 'Reader' access to the Key Protect or Hyper Protect Crypto Services key that was provided in the `kms_key_crn` and `backup_encryption_key_crn` inputs. This policy is required in order to enable KMS encryption, so only skip creation if there is one already present in your account. No policy is created if `use_ibm_owned_encryption_key` is true. | `bool` | `false` | no |
+| [tags](#input\_tags) | Optional list of tags to be added to the PostgreSQL instance. | `list(string)` | `[]` | no |
| [use\_default\_backup\_encryption\_key](#input\_use\_default\_backup\_encryption\_key) | When `use_ibm_owned_encryption_key` is set to false, backups will be encrypted with either the key specified in `kms_key_crn`, or in `backup_encryption_key_crn` if a value is passed. If you do not want to use your own key for backups encryption, you can set this to `true` to use the IBM Cloud Databases default encryption for backups. Alternatively set `use_ibm_owned_encryption_key` to true to use the default encryption for both backups and deployment data. | `bool` | `false` | no |
| [use\_ibm\_owned\_encryption\_key](#input\_use\_ibm\_owned\_encryption\_key) | IBM Cloud Databases will secure your deployment's data at rest automatically with an encryption key that IBM hold. Alternatively, you may select your own Key Management System instance and encryption key (Key Protect or Hyper Protect Crypto Services) by setting this to false. If setting to false, a value must be passed for the `kms_key_crn` input. | `bool` | `true` | no |
| [use\_same\_kms\_key\_for\_backups](#input\_use\_same\_kms\_key\_for\_backups) | Set this to false if you wan't to use a different key that you own to encrypt backups. When set to false, a value is required for the `backup_encryption_key_crn` input. Alternatiely set `use_default_backup_encryption_key` to true to use the IBM Cloud Databases default encryption. Applies only if `use_ibm_owned_encryption_key` is false. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups). | `bool` | `true` | no |
diff --git a/examples/backup/main.tf b/examples/backup/main.tf
index 623ccd67..2bc8be7e 100644
--- a/examples/backup/main.tf
+++ b/examples/backup/main.tf
@@ -17,7 +17,7 @@ module "postgresql_db" {
name = "${var.prefix}-postgres"
pg_version = var.pg_version
region = var.region
- resource_tags = var.resource_tags
+ tags = var.resource_tags
access_tags = var.access_tags
member_host_flavor = "multitenant"
}
@@ -28,13 +28,13 @@ data "ibm_database_backups" "backup_database" {
}
# New postgresql instance pointing to the backup instance
-module "restored_postgresql_db" {
+module "restored_icd_postgresql" {
source = "../.."
resource_group_id = module.resource_group.resource_group_id
name = "${var.prefix}-postgres-restored"
pg_version = var.pg_version
region = var.region
- resource_tags = var.resource_tags
+ tags = var.resource_tags
access_tags = var.access_tags
member_host_flavor = "multitenant"
backup_crn = var.postgresql_db_backup_crn == null ? data.ibm_database_backups.backup_database[0].backups[0].backup_id : var.postgresql_db_backup_crn
diff --git a/examples/backup/outputs.tf b/examples/backup/outputs.tf
index 86a00aef..40c833fc 100644
--- a/examples/backup/outputs.tf
+++ b/examples/backup/outputs.tf
@@ -1,17 +1,12 @@
##############################################################################
# Outputs
##############################################################################
-output "id" {
- description = "Postgresql instance id"
- value = var.postgresql_db_backup_crn == null ? module.postgresql_db[0].id : null
-}
-
-output "restored_postgresql_db_id" {
+output "restored_icd_postgresql_id" {
description = "Restored Postgresql instance id"
- value = module.restored_postgresql_db.id
+ value = module.restored_icd_postgresql.id
}
-output "restored_postgresql_db_version" {
+output "restored_icd_postgresql_version" {
description = "Restored Postgresql instance version"
- value = module.restored_postgresql_db.version
+ value = module.restored_icd_postgresql.version
}
diff --git a/examples/basic/main.tf b/examples/basic/main.tf
index 4605ce5b..ec6970c7 100644
--- a/examples/basic/main.tf
+++ b/examples/basic/main.tf
@@ -11,18 +11,25 @@ module "resource_group" {
}
##############################################################################
-# ICD postgresql database
+# Postgresql
##############################################################################
-module "postgresql_db" {
+module "database" {
source = "../.."
resource_group_id = module.resource_group.resource_group_id
- name = "${var.prefix}-postgres"
+ name = "${var.prefix}-data-store"
pg_version = var.pg_version
region = var.region
- resource_tags = var.resource_tags
+ tags = var.resource_tags
access_tags = var.access_tags
+ service_endpoints = var.service_endpoints
member_host_flavor = var.member_host_flavor
+ service_credential_names = {
+ "postgresql_admin" : "Administrator",
+ "postgresql_operator" : "Operator",
+ "postgresql_viewer" : "Viewer",
+ "postgresql_editor" : "Editor",
+ }
}
# On destroy, we are seeing that even though the replica has been returned as
@@ -34,7 +41,7 @@ module "postgresql_db" {
# adding a time sleep here.
resource "time_sleep" "wait_time" {
- depends_on = [module.postgresql_db]
+ depends_on = [module.database]
destroy_duration = "5m"
}
@@ -49,10 +56,10 @@ module "read_only_replica_postgresql_db" {
resource_group_id = module.resource_group.resource_group_id
name = "${var.prefix}-read-only-replica-${count.index}"
region = var.region
- resource_tags = var.resource_tags
+ tags = var.resource_tags
access_tags = var.access_tags
pg_version = var.pg_version
- remote_leader_crn = module.postgresql_db.crn
+ remote_leader_crn = module.database.crn
member_host_flavor = "multitenant"
member_memory_mb = 4096 # Must be an increment of 384 megabytes. The minimum size of a read-only replica is 2 GB RAM, new hosting model minimum is 4 GB RAM.
member_disk_mb = 5120 # Must be an increment of 512 megabytes. The minimum size of a read-only replica is 5 GB of disk
diff --git a/examples/basic/outputs.tf b/examples/basic/outputs.tf
index 9e43df1a..205652cd 100644
--- a/examples/basic/outputs.tf
+++ b/examples/basic/outputs.tf
@@ -3,31 +3,36 @@
##############################################################################
output "id" {
description = "Postgresql instance id"
- value = module.postgresql_db.id
+ value = module.database.id
}
output "version" {
description = "Postgresql instance version"
- value = module.postgresql_db.version
+ value = module.database.version
}
output "adminuser" {
description = "Database admin user name"
- value = module.postgresql_db.adminuser
+ value = module.database.adminuser
}
output "hostname" {
description = "Database connection hostname"
- value = module.postgresql_db.hostname
+ value = module.database.hostname
}
output "port" {
description = "Database connection port"
- value = module.postgresql_db.port
+ value = module.database.port
}
output "certificate_base64" {
description = "Database connection certificate"
- value = module.postgresql_db.certificate_base64
+ value = module.database.certificate_base64
sensitive = true
}
+
+output "postgresql_crn" {
+ description = "Postgresql CRN"
+ value = module.database.crn
+}
diff --git a/examples/basic/variables.tf b/examples/basic/variables.tf
index 5b215690..7029af4b 100644
--- a/examples/basic/variables.tf
+++ b/examples/basic/variables.tf
@@ -56,3 +56,14 @@ variable "member_host_flavor" {
description = "Allocated host flavor per member. For more information, see https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/database#host_flavor"
default = null
}
+
+variable "service_endpoints" {
+ type = string
+ description = "The type of endpoint of the database instance. Possible values: `public`, `private`, `public-and-private`."
+ default = "public"
+
+ validation {
+ condition = can(regex("public|public-and-private|private", var.service_endpoints))
+ error_message = "Valid values for service_endpoints are 'public', 'public-and-private', and 'private'"
+ }
+}
diff --git a/examples/complete/main.tf b/examples/complete/main.tf
index e90f8108..e6fbbcbc 100644
--- a/examples/complete/main.tf
+++ b/examples/complete/main.tf
@@ -30,7 +30,7 @@ module "key_protect_all_inclusive" {
resource_tags = var.resource_tags
keys = [
{
- key_ring_name = "icd-pg"
+ key_ring_name = "icd"
keys = [
{
key_name = local.data_key_name
@@ -101,7 +101,7 @@ module "cbr_zone" {
# Postgres Instance
##############################################################################
-module "postgresql_db" {
+module "icd_postgresql" {
source = "../../"
resource_group_id = module.resource_group.resource_group_id
name = "${var.prefix}-postgres"
@@ -112,9 +112,9 @@ module "postgresql_db" {
# Example of how to use different KMS keys for data and backups
use_ibm_owned_encryption_key = false
use_same_kms_key_for_backups = false
- kms_key_crn = module.key_protect_all_inclusive.keys["icd-pg.${local.data_key_name}"].crn
- backup_encryption_key_crn = module.key_protect_all_inclusive.keys["icd-pg.${local.backups_key_name}"].crn
- resource_tags = var.resource_tags
+ kms_key_crn = module.key_protect_all_inclusive.keys["icd.${local.data_key_name}"].crn
+ backup_encryption_key_crn = module.key_protect_all_inclusive.keys["icd.${local.backups_key_name}"].crn
+ tags = var.resource_tags
service_credential_names = {
"postgressql_admin" : "Administrator",
"postgressql_operator" : "Operator",
@@ -164,7 +164,7 @@ module "postgresql_db" {
# VPE provisioning should wait for the database provisioning
resource "time_sleep" "wait_120_seconds" {
- depends_on = [module.postgresql_db]
+ depends_on = [module.icd_postgresql]
create_duration = "120s"
}
@@ -179,7 +179,7 @@ module "vpe" {
cloud_service_by_crn = [
{
service_name = "${var.prefix}-postgres"
- crn = module.postgresql_db.crn
+ crn = module.icd_postgresql.crn
},
]
vpc_id = module.vpc.vpc_id
diff --git a/examples/complete/outputs.tf b/examples/complete/outputs.tf
index 3383a7e2..13aaa786 100644
--- a/examples/complete/outputs.tf
+++ b/examples/complete/outputs.tf
@@ -3,42 +3,42 @@
##############################################################################
output "id" {
description = "Postgresql instance id"
- value = module.postgresql_db.id
+ value = module.icd_postgresql.id
}
output "guid" {
description = "Postgresql instance guid"
- value = module.postgresql_db.guid
+ value = module.icd_postgresql.guid
}
output "version" {
description = "Postgresql instance version"
- value = module.postgresql_db.version
+ value = module.icd_postgresql.version
}
output "service_credentials_json" {
description = "Service credentials json map"
- value = module.postgresql_db.service_credentials_json
+ value = module.icd_postgresql.service_credentials_json
sensitive = true
}
output "service_credentials_object" {
description = "Service credentials object"
- value = module.postgresql_db.service_credentials_object
+ value = module.icd_postgresql.service_credentials_object
sensitive = true
}
output "cbr_rule_ids" {
description = "CBR rule ids created to restrict Postgresql"
- value = module.postgresql_db.cbr_rule_ids
+ value = module.icd_postgresql.cbr_rule_ids
}
output "hostname" {
description = "Postgresql instance hostname"
- value = module.postgresql_db.hostname
+ value = module.icd_postgresql.hostname
}
output "port" {
description = "Postgresql instance port"
- value = module.postgresql_db.port
+ value = module.icd_postgresql.port
}
diff --git a/examples/fscloud/main.tf b/examples/fscloud/main.tf
index c6621364..e764eacc 100644
--- a/examples/fscloud/main.tf
+++ b/examples/fscloud/main.tf
@@ -62,7 +62,7 @@ module "postgresql_db" {
kms_key_crn = var.kms_key_crn
backup_encryption_key_crn = var.backup_encryption_key_crn
backup_crn = var.backup_crn
- resource_tags = var.resource_tags
+ tags = var.resource_tags
service_credential_names = {
"postgressql_admin" : "Administrator",
"postgressql_operator" : "Operator",
diff --git a/examples/pitr/main.tf b/examples/pitr/main.tf
index e2e91df5..8b498abe 100644
--- a/examples/pitr/main.tf
+++ b/examples/pitr/main.tf
@@ -16,7 +16,7 @@ module "postgresql_db_pitr" {
resource_group_id = module.resource_group.resource_group_id
name = "${var.prefix}-postgres-pitr"
region = var.region
- resource_tags = var.resource_tags
+ tags = var.resource_tags
access_tags = var.access_tags
member_memory_mb = 4096
member_disk_mb = 5120
diff --git a/ibm_catalog.json b/ibm_catalog.json
index e95d17be..88339275 100644
--- a/ibm_catalog.json
+++ b/ibm_catalog.json
@@ -303,6 +303,9 @@
},
{
"key": "remote_leader_crn"
+ },
+ {
+ "key": "existing_postgresql_instance_crn"
}
]
}
diff --git a/main.tf b/main.tf
index 1c371d39..67d5b190 100644
--- a/main.tf
+++ b/main.tf
@@ -187,7 +187,7 @@ resource "ibm_database" "postgresql_db" {
backup_id = var.backup_crn
remote_leader_id = var.remote_leader_crn
version = var.pg_version
- tags = var.resource_tags
+ tags = var.tags
adminpassword = var.admin_pass
service_endpoints = var.service_endpoints
# remove elements with null values: see https://github.com/terraform-ibm-modules/terraform-ibm-icd-postgresql/issues/273
diff --git a/modules/fscloud/README.md b/modules/fscloud/README.md
index 2a2c2b76..f39e4195 100644
--- a/modules/fscloud/README.md
+++ b/modules/fscloud/README.md
@@ -35,7 +35,7 @@ No resources.
| [auto\_scaling](#input\_auto\_scaling) | Optional rules to allow the database to increase resources in response to usage. Only a single autoscaling block is allowed. Make sure you understand the effects of autoscaling, especially for production environments. See https://ibm.biz/autoscaling-considerations in the IBM Cloud Docs. | object({
disk = object({
capacity_enabled = optional(bool, false)
free_space_less_than_percent = optional(number, 10)
io_above_percent = optional(number, 90)
io_enabled = optional(bool, false)
io_over_period = optional(string, "15m")
rate_increase_percent = optional(number, 10)
rate_limit_mb_per_member = optional(number, 3670016)
rate_period_seconds = optional(number, 900)
rate_units = optional(string, "mb")
})
memory = object({
io_above_percent = optional(number, 90)
io_enabled = optional(bool, false)
io_over_period = optional(string, "15m")
rate_increase_percent = optional(number, 10)
rate_limit_mb_per_member = optional(number, 114688)
rate_period_seconds = optional(number, 900)
rate_units = optional(string, "mb")
})
}) | `null` | no |
| [backup\_crn](#input\_backup\_crn) | 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. | `string` | `null` | no |
| [backup\_encryption\_key\_crn](#input\_backup\_encryption\_key\_crn) | The CRN of a Key Protect or Hyper Protect Crypto Services encryption key that you want to use for encrypting the disk that holds deployment backups. Applies only if `use_ibm_owned_encryption_key` is false and `use_same_kms_key_for_backups` is false. If no value is passed, and `use_same_kms_key_for_backups` is true, the value of `kms_key_crn` is used. Alternatively set `use_default_backup_encryption_key` to true to use the IBM Cloud Databases default encryption. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups). | `string` | `null` | no |
-| [cbr\_rules](#input\_cbr\_rules) | (Optional, list) List of CBR rules to create | list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
})) | `[]` | no |
+| [cbr\_rules](#input\_cbr\_rules) | (Optional, list) List of CBR rules to create | list(object({
description = string
account_id = string
rule_contexts = list(object({
attributes = optional(list(object({
name = string
value = string
}))) }))
enforcement_mode = string
tags = optional(list(object({
name = string
value = string
})))
operations = optional(list(object({
api_types = list(object({
api_type_id = string
}))
})))
})) | `[]` | no |
| [configuration](#input\_configuration) | Database configuration parameters, see https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-changing-configuration&interface=api for more details. | object({
shared_buffers = optional(number)
max_connections = optional(number)
# below field gives error when sent to provider
# tracking issue: https://github.com/IBM-Cloud/terraform-provider-ibm/issues/5403
# max_locks_per_transaction = optional(number)
max_prepared_transactions = optional(number)
synchronous_commit = optional(string)
effective_io_concurrency = optional(number)
deadlock_timeout = optional(number)
log_connections = optional(string)
log_disconnections = optional(string)
log_min_duration_statement = optional(number)
tcp_keepalives_idle = optional(number)
tcp_keepalives_interval = optional(number)
tcp_keepalives_count = optional(number)
archive_timeout = optional(number)
wal_level = optional(string)
max_replication_slots = optional(number)
max_wal_senders = optional(number)
}) | `null` | no |
| [kms\_key\_crn](#input\_kms\_key\_crn) | The CRN of a Key Protect or Hyper Protect Crypto Services encryption key to encrypt your data. Applies only if `use_ibm_owned_encryption_key` is false. By default this key is used for both deployment data and backups, but this behaviour can be altered using the `use_same_kms_key_for_backups` and `backup_encryption_key_crn` inputs. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups). | `string` | `null` | no |
| [member\_cpu\_count](#input\_member\_cpu\_count) | Allocated dedicated CPU per member. For shared CPU, set to 0. [Learn more](https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-resources-scaling) | `number` | `3` | no |
@@ -48,9 +48,9 @@ No resources.
| [region](#input\_region) | The region where you want to deploy your instance. Must be the same region as the Hyper Protect Crypto Services instance. | `string` | `"us-south"` | no |
| [remote\_leader\_crn](#input\_remote\_leader\_crn) | A CRN of the leader database to make the replica(read-only) deployment. The leader database is created by a database deployment with the same service ID. A read-only replica is set up to replicate all of your data from the leader deployment to the replica deployment by using asynchronous replication. For more information, see https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-read-only-replicas | `string` | `null` | no |
| [resource\_group\_id](#input\_resource\_group\_id) | The resource group ID where the PostgreSQL instance will be created. | `string` | n/a | yes |
-| [resource\_tags](#input\_resource\_tags) | Optional list of tags to be added to the PostgreSQL instance. | `list(string)` | `[]` | no |
| [service\_credential\_names](#input\_service\_credential\_names) | Map of name, role for service credentials that you want to create for the database | `map(string)` | `{}` | no |
| [skip\_iam\_authorization\_policy](#input\_skip\_iam\_authorization\_policy) | Set to true to skip the creation of IAM authorization policies that permits all Databases for PostgreSQL instances in the given resource group 'Reader' access to the Key Protect or Hyper Protect Crypto Services key that was provided in the `kms_key_crn` and `backup_encryption_key_crn` inputs. This policy is required in order to enable KMS encryption, so only skip creation if there is one already present in your account. No policy is created if `use_ibm_owned_encryption_key` is true. | `bool` | `false` | no |
+| [tags](#input\_tags) | Optional list of tags to be added to the PostgreSQL instance. | `list(string)` | `[]` | no |
| [use\_default\_backup\_encryption\_key](#input\_use\_default\_backup\_encryption\_key) | When `use_ibm_owned_encryption_key` is set to false, backups will be encrypted with either the key specified in `kms_key_crn`, or in `backup_encryption_key_crn` if a value is passed. If you do not want to use your own key for backups encryption, you can set this to `true` to use the IBM Cloud Databases default encryption for backups. Alternatively set `use_ibm_owned_encryption_key` to true to use the default encryption for both backups and deployment data. | `bool` | `false` | no |
| [use\_ibm\_owned\_encryption\_key](#input\_use\_ibm\_owned\_encryption\_key) | Set to true to use the default IBM Cloud® Databases randomly generated keys for disk and backups encryption. To control the encryption keys, use the `kms_key_crn` and `backup_encryption_key_crn` inputs. | `string` | `false` | no |
| [use\_same\_kms\_key\_for\_backups](#input\_use\_same\_kms\_key\_for\_backups) | Set this to false if you wan't to use a different key that you own to encrypt backups. When set to false, a value is required for the `backup_encryption_key_crn` input. Alternatiely set `use_default_backup_encryption_key` to true to use the IBM Cloud Databases default encryption. Applies only if `use_ibm_owned_encryption_key` is false. Bare in mind that backups encryption is only available in certain regions. See [Bring your own key for backups](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-key-protect&interface=ui#key-byok) and [Using the HPCS Key for Backup encryption](https://cloud.ibm.com/docs/cloud-databases?topic=cloud-databases-hpcs#use-hpcs-backups). | `bool` | `true` | no |
diff --git a/modules/fscloud/main.tf b/modules/fscloud/main.tf
index 2b33446c..15403a85 100644
--- a/modules/fscloud/main.tf
+++ b/modules/fscloud/main.tf
@@ -13,7 +13,7 @@ module "postgresql_db" {
kms_key_crn = var.kms_key_crn
backup_crn = var.backup_crn
backup_encryption_key_crn = var.backup_encryption_key_crn
- resource_tags = var.resource_tags
+ tags = var.tags
access_tags = var.access_tags
cbr_rules = var.cbr_rules
configuration = var.configuration
diff --git a/modules/fscloud/variables.tf b/modules/fscloud/variables.tf
index c2f040c3..14ed0a4d 100644
--- a/modules/fscloud/variables.tf
+++ b/modules/fscloud/variables.tf
@@ -83,7 +83,7 @@ variable "service_credential_names" {
default = {}
}
-variable "resource_tags" {
+variable "tags" {
type = list(string)
description = "Optional list of tags to be added to the PostgreSQL instance."
default = []
@@ -214,6 +214,15 @@ variable "cbr_rules" {
value = string
}))) }))
enforcement_mode = string
+ tags = optional(list(object({
+ name = string
+ value = string
+ })))
+ operations = optional(list(object({
+ api_types = list(object({
+ api_type_id = string
+ }))
+ })))
}))
description = "(Optional, list) List of CBR rules to create"
default = []
diff --git a/solutions/standard/main.tf b/solutions/standard/main.tf
index 27b9d597..3b03e463 100644
--- a/solutions/standard/main.tf
+++ b/solutions/standard/main.tf
@@ -18,9 +18,9 @@ module "resource_group" {
locals {
# tflint-ignore: terraform_unused_declarations
- validate_kms_1 = var.use_ibm_owned_encryption_key && (var.existing_kms_instance_crn != null || var.existing_kms_key_crn != null || var.existing_backup_kms_key_crn != null) ? tobool("When setting values for 'existing_kms_instance_crn', 'existing_kms_key_crn' or 'existing_backup_kms_key_crn', the 'use_ibm_owned_encryption_key' input must be set to false.") : true
+ validate_kms_1 = var.existing_postgresql_instance_crn != null ? true : var.use_ibm_owned_encryption_key && (var.existing_kms_instance_crn != null || var.existing_kms_key_crn != null || var.existing_backup_kms_key_crn != null) ? tobool("When setting values for 'existing_kms_instance_crn', 'existing_kms_key_crn' or 'existing_backup_kms_key_crn', the 'use_ibm_owned_encryption_key' input must be set to false.") : true
# tflint-ignore: terraform_unused_declarations
- validate_kms_2 = !var.use_ibm_owned_encryption_key && (var.existing_kms_instance_crn == null && var.existing_kms_key_crn == null) ? tobool("When 'use_ibm_owned_encryption_key' is false, a value is required for either 'existing_kms_instance_crn' (to create a new key), or 'existing_kms_key_crn' to use an existing key.") : true
+ validate_kms_2 = var.existing_postgresql_instance_crn != null ? true : !var.use_ibm_owned_encryption_key && (var.existing_kms_instance_crn == null && var.existing_kms_key_crn == null) ? tobool("When 'use_ibm_owned_encryption_key' is false, a value is required for either 'existing_kms_instance_crn' (to create a new key), or 'existing_kms_key_crn' to use an existing key.") : true
}
#######################################################################################################################
@@ -28,7 +28,7 @@ locals {
#######################################################################################################################
locals {
- create_new_kms_key = !var.use_ibm_owned_encryption_key && var.existing_kms_key_crn == null ? true : false # no need to create any KMS resources if passing an existing key, or using IBM owned keys
+ create_new_kms_key = var.existing_postgresql_instance_crn == null && !var.use_ibm_owned_encryption_key && var.existing_kms_key_crn == null ? true : false # no need to create any KMS resources if passing an existing key, or using IBM owned keys
postgres_key_name = (var.prefix != null && var.prefix != "") ? "${var.prefix}-${var.key_name}" : var.key_name
postgres_key_ring_name = (var.prefix != null && var.prefix != "") ? "${var.prefix}-${var.key_ring_name}" : var.key_ring_name
}
@@ -99,16 +99,16 @@ data "ibm_iam_account_settings" "iam_account_settings" {
locals {
account_id = data.ibm_iam_account_settings.iam_account_settings.account_id
- create_cross_account_kms_auth_policy = !var.skip_pg_kms_auth_policy && var.ibmcloud_kms_api_key != null && !var.use_ibm_owned_encryption_key
- create_cross_account_backup_kms_auth_policy = !var.skip_pg_kms_auth_policy && var.ibmcloud_kms_api_key != null && !var.use_ibm_owned_encryption_key && var.existing_backup_kms_key_crn != null
+ create_cross_account_kms_auth_policy = var.existing_postgresql_instance_crn == null && !var.skip_pg_kms_auth_policy && var.ibmcloud_kms_api_key != null && !var.use_ibm_owned_encryption_key
+ create_cross_account_backup_kms_auth_policy = var.existing_postgresql_instance_crn == null && !var.skip_pg_kms_auth_policy && var.ibmcloud_kms_api_key != null && !var.use_ibm_owned_encryption_key && var.existing_backup_kms_key_crn != null
# If KMS encryption enabled (and existing ES instance is not being passed), parse details from the existing key if being passed, otherwise get it from the key that the DA creates
- kms_account_id = var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].account_id : module.kms_instance_crn_parser[0].account_id
- kms_service = var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_name : module.kms_instance_crn_parser[0].service_name
- kms_instance_guid = var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_instance : module.kms_instance_crn_parser[0].service_instance
- kms_key_crn = var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? var.existing_kms_key_crn : module.kms[0].keys[format("%s.%s", local.postgres_key_ring_name, local.postgres_key_name)].crn
- kms_key_id = var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].resource : module.kms[0].keys[format("%s.%s", local.postgres_key_ring_name, local.postgres_key_name)].key_id
- kms_region = var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].region : module.kms_instance_crn_parser[0].region
+ kms_account_id = var.existing_postgresql_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].account_id : module.kms_instance_crn_parser[0].account_id
+ kms_service = var.existing_postgresql_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_name : module.kms_instance_crn_parser[0].service_name
+ kms_instance_guid = var.existing_postgresql_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].service_instance : module.kms_instance_crn_parser[0].service_instance
+ kms_key_crn = var.existing_postgresql_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? var.existing_kms_key_crn : module.kms[0].keys[format("%s.%s", local.postgres_key_ring_name, local.postgres_key_name)].crn
+ kms_key_id = var.existing_postgresql_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].resource : module.kms[0].keys[format("%s.%s", local.postgres_key_ring_name, local.postgres_key_name)].key_id
+ kms_region = var.existing_postgresql_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_kms_key_crn != null ? module.kms_key_crn_parser[0].region : module.kms_instance_crn_parser[0].region
# If creating KMS cross account policy for backups, parse backup key details from passed in key CRN
backup_kms_account_id = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].account_id : local.kms_account_id
@@ -116,7 +116,7 @@ locals {
backup_kms_instance_guid = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].service_instance : local.kms_instance_guid
backup_kms_key_id = local.create_cross_account_backup_kms_auth_policy ? module.kms_backup_key_crn_parser[0].resource : local.kms_key_id
- backup_kms_key_crn = var.use_ibm_owned_encryption_key ? null : var.existing_backup_kms_key_crn
+ backup_kms_key_crn = var.existing_postgresql_instance_crn != null || var.use_ibm_owned_encryption_key ? null : var.existing_backup_kms_key_crn
# Always use same key for backups unless user explicially passed a value for 'existing_backup_kms_key_crn'
use_same_kms_key_for_backups = var.existing_backup_kms_key_crn == null ? true : false
}
@@ -234,6 +234,7 @@ locals {
# if - replace first char with J
# elseif _ replace first char with K
# else use asis
+ # admin password to use
admin_pass = var.admin_pass == null ? (startswith(random_password.admin_password[0].result, "-") ? "J${substr(random_password.admin_password[0].result, 1, -1)}" : startswith(random_password.admin_password[0].result, "_") ? "K${substr(random_password.admin_password[0].result, 1, -1)}" : random_password.admin_password[0].result) : var.admin_pass
}
@@ -241,8 +242,51 @@ locals {
# Postgresql
#######################################################################################################################
+# Look up existing instance details if user passes one
+module "postgresql_instance_crn_parser" {
+ count = var.existing_postgresql_instance_crn != null ? 1 : 0
+ source = "terraform-ibm-modules/common-utilities/ibm//modules/crn-parser"
+ version = "1.1.0"
+ crn = var.existing_postgresql_instance_crn
+}
+
+# Existing instance local vars
+locals {
+ existing_postgresql_guid = var.existing_postgresql_instance_crn != null ? module.postgresql_instance_crn_parser[0].service_instance : null
+ existing_postgresql_region = var.existing_postgresql_instance_crn != null ? module.postgresql_instance_crn_parser[0].region : null
+
+ # Validate the region input matches region detected in existing instance CRN (approach based on https://github.com/hashicorp/terraform/issues/25609#issuecomment-1057614400)
+ # tflint-ignore: terraform_unused_declarations
+ validate_existing_instance_region = var.existing_postgresql_instance_crn != null && var.region != local.existing_postgresql_region ? tobool("The region detected in the 'existing_postgresql_instance_crn' value must match the value of the 'region' input variable when passing an existing instance.") : true
+}
+
+# Do a data lookup on the resource GUID to get more info that is needed for the 'ibm_database' data lookup below
+data "ibm_resource_instance" "existing_instance_resource" {
+ count = var.existing_postgresql_instance_crn != null ? 1 : 0
+ identifier = local.existing_postgresql_guid
+}
+
+# Lookup details of existing instance
+data "ibm_database" "existing_db_instance" {
+ count = var.existing_postgresql_instance_crn != null ? 1 : 0
+ name = data.ibm_resource_instance.existing_instance_resource[0].name
+ resource_group_id = data.ibm_resource_instance.existing_instance_resource[0].resource_group_id
+ location = var.region
+ service = "databases-for-postgresql"
+}
+
+# Lookup existing instance connection details
+data "ibm_database_connection" "existing_connection" {
+ count = var.existing_postgresql_instance_crn != null ? 1 : 0
+ endpoint_type = "private"
+ deployment_id = data.ibm_database.existing_db_instance[0].id
+ user_id = data.ibm_database.existing_db_instance[0].adminuser
+ user_type = "database"
+}
+
# Create new instance
module "postgresql_db" {
+ count = var.existing_postgresql_instance_crn != null ? 0 : 1
source = "../../modules/fscloud"
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
@@ -257,7 +301,7 @@ module "postgresql_db" {
use_same_kms_key_for_backups = local.use_same_kms_key_for_backups
use_default_backup_encryption_key = var.use_default_backup_encryption_key
access_tags = var.access_tags
- resource_tags = var.resource_tags
+ tags = var.resource_tags
admin_pass = local.admin_pass
users = var.users
members = var.members
@@ -270,3 +314,12 @@ module "postgresql_db" {
service_credential_names = var.service_credential_names
backup_crn = var.backup_crn
}
+
+locals {
+ postgresql_guid = var.existing_postgresql_instance_crn != null ? data.ibm_database.existing_db_instance[0].guid : module.postgresql_db[0].guid
+ postgresql_id = var.existing_postgresql_instance_crn != null ? data.ibm_database.existing_db_instance[0].id : module.postgresql_db[0].id
+ postgresql_version = var.existing_postgresql_instance_crn != null ? data.ibm_database.existing_db_instance[0].version : module.postgresql_db[0].version
+ postgresql_crn = var.existing_postgresql_instance_crn != null ? var.existing_postgresql_instance_crn : module.postgresql_db[0].crn
+ postgresql_hostname = var.existing_postgresql_instance_crn != null ? data.ibm_database_connection.existing_connection[0].postgres[0].hosts[0].hostname : module.postgresql_db[0].hostname
+ postgresql_port = var.existing_postgresql_instance_crn != null ? data.ibm_database_connection.existing_connection[0].postgres[0].hosts[0].port : module.postgresql_db[0].port
+}
diff --git a/solutions/standard/moved.tf b/solutions/standard/moved.tf
new file mode 100644
index 00000000..4b9aafc0
--- /dev/null
+++ b/solutions/standard/moved.tf
@@ -0,0 +1,4 @@
+moved {
+ from = module.postgresql_db
+ to = module.postgresql_db[0]
+}
diff --git a/solutions/standard/outputs.tf b/solutions/standard/outputs.tf
index 691f3fe6..a0f14cbd 100644
--- a/solutions/standard/outputs.tf
+++ b/solutions/standard/outputs.tf
@@ -4,47 +4,42 @@
output "id" {
description = "PostgreSQL instance id"
- value = module.postgresql_db.id
+ value = local.postgresql_id
}
output "guid" {
description = "PostgreSQL instance guid"
- value = module.postgresql_db.guid
+ value = local.postgresql_guid
}
output "version" {
description = "PostgreSQL instance version"
- value = module.postgresql_db.version
+ value = local.postgresql_version
}
output "crn" {
description = "PostgreSQL instance crn"
- value = module.postgresql_db.crn
-}
-
-output "cbr_rule_ids" {
- description = "CBR rule ids created to restrict PostgreSQL"
- value = module.postgresql_db.cbr_rule_ids
+ value = local.postgresql_crn
}
output "service_credentials_json" {
description = "Service credentials json map"
- value = module.postgresql_db.service_credentials_json
+ value = var.existing_postgresql_instance_crn != null ? null : module.postgresql_db[0].service_credentials_json
sensitive = true
}
output "service_credentials_object" {
description = "Service credentials object"
- value = module.postgresql_db.service_credentials_object
+ value = var.existing_postgresql_instance_crn != null ? null : module.postgresql_db[0].service_credentials_json
sensitive = true
}
output "hostname" {
description = "PostgreSQL instance hostname"
- value = module.postgresql_db.hostname
+ value = local.postgresql_hostname
}
output "port" {
description = "PostgreSQL instance port"
- value = module.postgresql_db.port
+ value = local.postgresql_port
}
diff --git a/solutions/standard/variables.tf b/solutions/standard/variables.tf
index e8c86508..47546f27 100644
--- a/solutions/standard/variables.tf
+++ b/solutions/standard/variables.tf
@@ -66,6 +66,12 @@ variable "remote_leader_crn" {
default = null
}
+variable "existing_postgresql_instance_crn" {
+ type = string
+ default = null
+ description = "The CRN of an existing Databases for Postgresql instance. If no value is specified, a new instance is created."
+}
+
##############################################################################
# ICD hosting model properties
##############################################################################
diff --git a/tests/other_test.go b/tests/other_test.go
index 2fdbc8d0..b5e54140 100644
--- a/tests/other_test.go
+++ b/tests/other_test.go
@@ -5,7 +5,6 @@ import (
"fmt"
"testing"
- "github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
"github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testhelper"
)
@@ -53,26 +52,6 @@ func TestRunPointInTimeRecoveryDBExample(t *testing.T) {
assert.NotNil(t, output, "Expected some output")
}
-func TestRunBasicExample(t *testing.T) {
- t.Parallel()
-
- options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{
- Testing: t,
- TerraformDir: "examples/basic",
- Prefix: "postgres",
- BestRegionYAMLPath: regionSelectionPath,
- ResourceGroup: resourceGroup,
- TerraformVars: map[string]interface{}{
- "pg_version": "13",
- },
- CloudInfoService: sharedInfoSvc,
- })
-
- output, err := options.RunTestConsistency()
- assert.Nil(t, err, "This should not have errored")
- assert.NotNil(t, output, "Expected some output")
-}
-
func testPlanICDVersions(t *testing.T, version string) {
t.Parallel()
@@ -138,38 +117,3 @@ func TestRunBasicExampleWithFlavorMultitenant(t *testing.T) {
assert.Nil(t, err, "This should not have errored")
assert.NotNil(t, output, "Expected some output")
}
-
-func TestRunFSCloudExample(t *testing.T) {
- t.Parallel()
-
- options := testhelper.TestOptionsDefaultWithVars(&testhelper.TestOptions{
- Testing: t,
- TerraformDir: "examples/fscloud",
- Prefix: "postgres-fscloud",
- Region: "us-south", // For FSCloud locking into us-south since that is where the HPCS permanent instance is
- /*
- Comment out the 'ResourceGroup' input to force this tests to create a unique resource group to ensure tests do
- not clash. This is due to the fact that an auth policy may already exist in this resource group since we are
- re-using a permanent HPCS instance. By using a new resource group, the auth policy will not already exist
- since this module scopes auth policies by resource group.
- */
- //ResourceGroup: resourceGroup,
- TerraformVars: map[string]interface{}{
- "access_tags": permanentResources["accessTags"],
- "kms_key_crn": permanentResources["hpcs_south_root_key_crn"],
- "pg_version": "16", // Always lock this test into the latest supported Postgres version
- },
- CloudInfoService: sharedInfoSvc,
- })
- options.SkipTestTearDown = true
- output, err := options.RunTestConsistency()
- assert.Nil(t, err, "This should not have errored")
- assert.NotNil(t, output, "Expected some output")
-
- // check if outputs exist
- outputs := terraform.OutputAll(options.Testing, options.TerraformOptions)
- expectedOutputs := []string{"port", "hostname"}
- _, outputErr := testhelper.ValidateTerraformOutputs(outputs, expectedOutputs...)
- assert.NoErrorf(t, outputErr, "Some outputs not found or nil")
- options.TestTearDown()
-}
diff --git a/tests/pr_test.go b/tests/pr_test.go
index de4bca32..ee6dde0e 100644
--- a/tests/pr_test.go
+++ b/tests/pr_test.go
@@ -5,14 +5,15 @@ import (
"crypto/rand"
"encoding/base64"
"fmt"
- "io/fs"
"log"
+ "math/big"
"os"
- "path/filepath"
"strings"
"testing"
+ "github.com/gruntwork-io/terratest/modules/files"
"github.com/gruntwork-io/terratest/modules/logger"
+ "github.com/gruntwork-io/terratest/modules/random"
"github.com/gruntwork-io/terratest/modules/terraform"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -22,6 +23,10 @@ import (
"github.com/terraform-ibm-modules/ibmcloud-terratest-wrapper/testschematic"
)
+const standardSolutionTerraformDir = "solutions/standard"
+const fscloudExampleTerraformDir = "examples/fscloud"
+const latestVersion = "16"
+
// Use existing resource group
const resourceGroup = "geretain-test-postgres"
@@ -33,9 +38,11 @@ const yamlLocation = "../common-dev-assets/common-go-assets/common-permanent-res
var permanentResources map[string]interface{}
-const standardSolutionTerraformDir = "solutions/standard"
-
var sharedInfoSvc *cloudinfo.CloudInfoService
+var validICDRegions = []string{
+ "eu-de",
+ "us-south",
+}
// TestMain will be run before any parallel tests, used to read data from yaml for use with tests
func TestMain(m *testing.M) {
@@ -50,80 +57,21 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
-type tarIncludePatterns struct {
- excludeDirs []string
-
- includeFiletypes []string
-
- includeDirs []string
-}
-
-func getTarIncludePatternsRecursively(dir string, dirsToExclude []string, fileTypesToInclude []string) ([]string, error) {
- r := tarIncludePatterns{dirsToExclude, fileTypesToInclude, nil}
- err := filepath.WalkDir(dir, func(path string, entry fs.DirEntry, err error) error {
- return walk(&r, path, entry, err)
- })
- if err != nil {
- fmt.Println("error")
- return r.includeDirs, err
- }
- return r.includeDirs, nil
-}
-
-func walk(r *tarIncludePatterns, s string, d fs.DirEntry, err error) error {
- if err != nil {
- return err
- }
- if d.IsDir() {
- for _, excludeDir := range r.excludeDirs {
- if strings.Contains(s, excludeDir) {
- return nil
- }
- }
- if s == ".." {
- r.includeDirs = append(r.includeDirs, "*.tf")
- return nil
- }
- for _, includeFiletype := range r.includeFiletypes {
- r.includeDirs = append(r.includeDirs, strings.ReplaceAll(s+"/*"+includeFiletype, "../", ""))
- }
- }
- return nil
-}
-
func TestRunStandardSolutionSchematics(t *testing.T) {
t.Parallel()
- excludeDirs := []string{
- ".terraform",
- ".docs",
- ".github",
- ".git",
- ".idea",
- "common-dev-assets",
- "examples",
- "tests",
- "reference-architectures",
- }
- includeFiletypes := []string{
- ".tf",
- ".yaml",
- ".py",
- ".tpl",
- ".sh",
- }
-
- tarIncludePatterns, recurseErr := getTarIncludePatternsRecursively("..", excludeDirs, includeFiletypes)
-
- // if error producing tar patterns (very unexpected) fail test immediately
- require.NoError(t, recurseErr, "Schematic Test had unexpected error traversing directory tree")
- prefix := "postgres-st-da"
options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{
- Testing: t,
- TarIncludePatterns: tarIncludePatterns,
+ Testing: t,
+ TarIncludePatterns: []string{
+ "*.tf",
+ fmt.Sprintf("%s/*.tf", standardSolutionTerraformDir),
+ fmt.Sprintf("%s/*.tf", fscloudExampleTerraformDir),
+ fmt.Sprintf("%s/*.tf", "modules/fscloud"),
+ fmt.Sprintf("%s/*.sh", "scripts"),
+ },
TemplateFolder: standardSolutionTerraformDir,
BestRegionYAMLPath: regionSelectionPath,
- Prefix: prefix,
+ Prefix: "postgresql-st-da",
ResourceGroup: resourceGroup,
DeleteWorkspaceOnFail: false,
WaitJobCompleteMinutes: 60,
@@ -147,14 +95,16 @@ func TestRunStandardUpgradeSolution(t *testing.T) {
t.Parallel()
options := testhelper.TestOptionsDefault(&testhelper.TestOptions{
- Testing: t,
- TerraformDir: standardSolutionTerraformDir,
- Region: "us-south",
- Prefix: "postgres-st-da-upg",
- ResourceGroup: resourceGroup,
+ Testing: t,
+ TerraformDir: standardSolutionTerraformDir,
+ Region: "us-south",
+ Prefix: "postgres-st-da-upg",
+ ResourceGroup: resourceGroup,
+ CheckApplyResultForUpgrade: true,
})
options.TerraformVars = map[string]interface{}{
+ "access_tags": permanentResources["accessTags"],
"existing_kms_instance_crn": permanentResources["hpcs_south_crn"],
"kms_endpoint_type": "public",
"provider_visibility": "public",
@@ -183,6 +133,7 @@ func TestPlanValidation(t *testing.T) {
"prefix": options.Prefix,
"region": "us-south",
"kms_endpoint_type": "public",
+ "pg_version": "16",
"provider_visibility": "public",
"resource_group_name": "validate-plan",
}
@@ -237,3 +188,83 @@ func GetRandomAdminPassword(t *testing.T) string {
return randomPass
}
+
+func TestRunExistingInstance(t *testing.T) {
+ t.Parallel()
+ prefix := fmt.Sprintf("postgresql-t-%s", strings.ToLower(random.UniqueId()))
+ realTerraformDir := ".."
+ tempTerraformDir, _ := files.CopyTerraformFolderToTemp(realTerraformDir, fmt.Sprintf(prefix+"-%s", strings.ToLower(random.UniqueId())))
+ rand, err := rand.Int(rand.Reader, big.NewInt(int64(len(validICDRegions))))
+ if err != nil {
+ fmt.Println("Error generating random number:", err)
+ return
+ }
+ region := validICDRegions[rand.Int64()]
+
+ // Verify ibmcloud_api_key variable is set
+ checkVariable := "TF_VAR_ibmcloud_api_key"
+ val, present := os.LookupEnv(checkVariable)
+ require.True(t, present, checkVariable+" environment variable not set")
+ require.NotEqual(t, "", val, checkVariable+" environment variable is empty")
+
+ logger.Log(t, "Tempdir: ", tempTerraformDir)
+ existingTerraformOptions := terraform.WithDefaultRetryableErrors(t, &terraform.Options{
+ TerraformDir: tempTerraformDir + "/examples/basic",
+ Vars: map[string]interface{}{
+ "prefix": prefix,
+ "region": region,
+ "pg_version": latestVersion,
+ "service_endpoints": "public-and-private",
+ },
+ // Set Upgrade to true to ensure latest version of providers and modules are used by terratest.
+ // This is the same as setting the -upgrade=true flag with terraform.
+ Upgrade: true,
+ })
+
+ terraform.WorkspaceSelectOrNew(t, existingTerraformOptions, prefix)
+ _, existErr := terraform.InitAndApplyE(t, existingTerraformOptions)
+ if existErr != nil {
+ assert.True(t, existErr == nil, "Init and Apply of temp existing resource failed")
+ } else {
+ logger.Log(t, " existing_postgresql_instance_crn: ", terraform.Output(t, existingTerraformOptions, "postgresql_crn"))
+ options := testschematic.TestSchematicOptionsDefault(&testschematic.TestSchematicOptions{
+ Testing: t,
+ TarIncludePatterns: []string{
+ "*.tf",
+ fmt.Sprintf("%s/*.tf", standardSolutionTerraformDir),
+ fmt.Sprintf("%s/*.tf", fscloudExampleTerraformDir),
+ fmt.Sprintf("%s/*.tf", "modules/fscloud"),
+ fmt.Sprintf("%s/*.sh", "scripts"),
+ },
+ TemplateFolder: standardSolutionTerraformDir,
+ BestRegionYAMLPath: regionSelectionPath,
+ Prefix: "postgresql-da",
+ ResourceGroup: resourceGroup,
+ DeleteWorkspaceOnFail: false,
+ WaitJobCompleteMinutes: 60,
+ })
+
+ options.TerraformVars = []testschematic.TestSchematicTerraformVar{
+ {Name: "ibmcloud_api_key", Value: options.RequiredEnvironmentVars["TF_VAR_ibmcloud_api_key"], DataType: "string", Secure: true},
+ {Name: "existing_postgresql_instance_crn", Value: terraform.Output(t, existingTerraformOptions, "postgresql_crn"), DataType: "string"},
+ {Name: "resource_group_name", Value: fmt.Sprintf("%s-resource-group", prefix), DataType: "string"},
+ {Name: "region", Value: region, DataType: "string"},
+ {Name: "use_existing_resource_group", Value: true, DataType: "bool"},
+ {Name: "provider_visibility", Value: "public", DataType: "string"},
+ }
+ err := options.RunSchematicTest()
+ assert.Nil(t, err, "This should not have errored")
+
+ }
+ envVal, _ := os.LookupEnv("DO_NOT_DESTROY_ON_FAILURE")
+ // Destroy the temporary existing resources if required
+ if t.Failed() && strings.ToLower(envVal) == "true" {
+ fmt.Println("Terratest failed. Debug the test and delete resources manually.")
+ } else {
+ logger.Log(t, "START: Destroy (existing resources)")
+ terraform.Destroy(t, existingTerraformOptions)
+ terraform.WorkspaceDelete(t, existingTerraformOptions, prefix)
+ logger.Log(t, "END: Destroy (existing resources)")
+ }
+
+}
diff --git a/variables.tf b/variables.tf
index b0f4096b..355cba0f 100644
--- a/variables.tf
+++ b/variables.tf
@@ -122,7 +122,7 @@ variable "service_endpoints" {
}
}
-variable "resource_tags" {
+variable "tags" {
type = list(string)
description = "Optional list of tags to be added to the PostgreSQL instance."
default = []
@@ -322,6 +322,10 @@ variable "cbr_rules" {
value = string
}))) }))
enforcement_mode = string
+ tags = optional(list(object({
+ name = string
+ value = string
+ })))
}))
description = "(Optional, list) List of CBR rules to create"
default = []