Skip to content

Commit 56ed5f5

Browse files
feat: add support to optionally create database users (using new users variable) and admin password (using new admin_pass variable). add new outputs hostname and port which will only output if users or service credentials are created. (#200)
1 parent b5fee87 commit 56ed5f5

File tree

11 files changed

+193
-16
lines changed

11 files changed

+193
-16
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,14 @@ To attach access management tags to resources in this module, you need the follo
7373
| [ibm_iam_authorization_policy.kms_policy](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/iam_authorization_policy) | resource |
7474
| [ibm_resource_key.service_credentials](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_key) | resource |
7575
| [ibm_resource_tag.postgresql_tag](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/resource_tag) | resource |
76+
| [ibm_database_connection.database_connection](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/data-sources/database_connection) | data source |
7677

7778
## Inputs
7879

7980
| Name | Description | Type | Default | Required |
8081
|------|-------------|------|---------|:--------:|
8182
| <a name="input_access_tags"></a> [access\_tags](#input\_access\_tags) | A list of access tags to apply to the PostgreSQL instance created by the module, see https://cloud.ibm.com/docs/account?topic=account-access-tags-tutorial for more details | `list(string)` | `[]` | no |
83+
| <a name="input_admin_pass"></a> [admin\_pass](#input\_admin\_pass) | The password for the database administrator. If the admin password is null then the admin user ID cannot be accessed. More users can be specified in a user block. The admin password must be in the range of 10-32 characters. | `string` | `null` | no |
8284
| <a name="input_auto_scaling"></a> [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. | <pre>object({<br> disk = object({<br> capacity_enabled = optional(bool, false)<br> free_space_less_than_percent = optional(number, 10)<br> io_above_percent = optional(number, 90)<br> io_enabled = optional(bool, false)<br> io_over_period = optional(string, "15m")<br> rate_increase_percent = optional(number, 10)<br> rate_limit_mb_per_member = optional(number, 3670016)<br> rate_period_seconds = optional(number, 900)<br> rate_units = optional(string, "mb")<br> })<br> memory = object({<br> io_above_percent = optional(number, 90)<br> io_enabled = optional(bool, false)<br> io_over_period = optional(string, "15m")<br> rate_increase_percent = optional(number, 10)<br> rate_limit_mb_per_member = optional(number, 114688)<br> rate_period_seconds = optional(number, 900)<br> rate_units = optional(string, "mb")<br> })<br> })</pre> | `null` | no |
8385
| <a name="input_backup_crn"></a> [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 |
8486
| <a name="input_backup_encryption_key_crn"></a> [backup\_encryption\_key\_crn](#input\_backup\_encryption\_key\_crn) | The CRN of a Key Protect key that you want to use for encrypting the disk that holds deployment backups. Only used if var.kms\_encryption\_enabled is set to true. BYOK for backups is available only in US regions us-south and us-east, and in eu-de. Only keys in the us-south and eu-de are durable to region failures. To ensure that your backups are available even if a region failure occurs, use a key from us-south or eu-de. Hyper Protect Crypto Services for IBM Cloud Databases backups is not currently supported. If no value is passed here, the value passed for the 'kms\_key\_crn' variable is used. And if a HPCS value is passed for var.kms\_key\_crn, the database backup encryption uses the default encryption keys. | `string` | `null` | no |
@@ -103,6 +105,7 @@ To attach access management tags to resources in this module, you need the follo
103105
| <a name="input_service_credential_names"></a> [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 |
104106
| <a name="input_service_endpoints"></a> [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 |
105107
| <a name="input_skip_iam_authorization_policy"></a> [skip\_iam\_authorization\_policy](#input\_skip\_iam\_authorization\_policy) | Set to true to skip the creation of an IAM authorization policy that permits all PostgreSQL database instances in the resource group to read the encryption key from the KMS instance. If set to false, pass in a value for the KMS instance in the existing\_kms\_instance\_guid variable. In addition, no policy is created if var.kms\_encryption\_enabled is set to false. | `bool` | `false` | no |
108+
| <a name="input_users"></a> [users](#input\_users) | A list of users that you want to create on the database. Multiple blocks are allowed. The user password must be in the range of 10-32 characters. Be warned that in most case using IAM service credentials (via the var.service\_credential\_names) is sufficient to control access to the Postgres instance. This blocks creates native postgres database users, more info on that can be found here https://cloud.ibm.com/docs/databases-for-postgresql?topic=databases-for-postgresql-user-management&interface=ui | <pre>list(object({<br> name = string<br> password = string # pragma: allowlist secret<br> type = string # "type" is required to generate the connection string for the outputs.<br> role = optional(string)<br> }))</pre> | `[]` | no |
106109

107110
## Outputs
108111

@@ -111,7 +114,9 @@ To attach access management tags to resources in this module, you need the follo
111114
| <a name="output_cbr_rule_ids"></a> [cbr\_rule\_ids](#output\_cbr\_rule\_ids) | CBR rule ids created to restrict Postgresql |
112115
| <a name="output_crn"></a> [crn](#output\_crn) | Postgresql instance crn |
113116
| <a name="output_guid"></a> [guid](#output\_guid) | Postgresql instance guid |
117+
| <a name="output_hostname"></a> [hostname](#output\_hostname) | Database hostname. Only contains value when var.service\_credential\_names or var.users are set. |
114118
| <a name="output_id"></a> [id](#output\_id) | Postgresql instance id |
119+
| <a name="output_port"></a> [port](#output\_port) | Database port. Only contains value when var.service\_credential\_names or var.users are set. |
115120
| <a name="output_service_credentials_json"></a> [service\_credentials\_json](#output\_service\_credentials\_json) | Service credentials json map |
116121
| <a name="output_service_credentials_object"></a> [service\_credentials\_object](#output\_service\_credentials\_object) | Service credentials object |
117122
| <a name="output_version"></a> [version](#output\_version) | Postgresql instance version |

examples/complete/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ module "postgresql_db" {
7272
name = "${var.prefix}-postgres"
7373
region = var.region
7474
pg_version = var.pg_version
75+
admin_pass = var.admin_pass
76+
users = var.users
7577
kms_encryption_enabled = true
7678
kms_key_crn = module.key_protect_all_inclusive.keys["icd-pg.${var.prefix}-pg"].crn
7779
existing_kms_instance_guid = module.key_protect_all_inclusive.key_protect_guid

examples/complete/outputs.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,13 @@ output "cbr_rule_ids" {
3232
description = "CBR rule ids created to restrict Postgresql"
3333
value = module.postgresql_db.cbr_rule_ids
3434
}
35+
36+
output "hostname" {
37+
description = "Postgresql instance hostname"
38+
value = module.postgresql_db.hostname
39+
}
40+
41+
output "port" {
42+
description = "Postgresql instance port"
43+
value = module.postgresql_db.port
44+
}

examples/complete/variables.tf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ variable "pg_version" {
4040
default = null
4141
}
4242

43+
variable "admin_pass" {
44+
type = string
45+
default = null
46+
sensitive = true
47+
description = "The password for the database administrator. If the admin password is null then the admin user ID cannot be accessed. More users can be specified in a user block. The admin password must be in the range of 10-32 characters."
48+
}
49+
50+
variable "users" {
51+
type = list(object({
52+
name = string
53+
password = string
54+
type = string
55+
role = optional(string)
56+
}))
57+
default = []
58+
sensitive = true
59+
description = "A list of users that you want to create on the database. Multiple blocks are allowed. The user password must be in the range of 10-32 characters."
60+
}
61+
4362
variable "service_credential_names" {
4463
description = "Map of name, role for service credentials that you want to create for the database"
4564
type = map(string)

examples/pitr/variables.tf

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,4 @@ variable "members" {
4949
type = number
5050
description = "Allocated number of members. Members must be same or higher than the source deployment PostgreSQL instance."
5151
default = 2
52-
# Validation is done in the Terraform plan phase by the IBM provider, so no need to add extra validation here.
5352
}

main.tf

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,24 @@ resource "ibm_database" "postgresql_db" {
5151
remote_leader_id = var.remote_leader_crn
5252
version = var.pg_version
5353
tags = var.resource_tags
54+
adminpassword = var.admin_pass
5455
service_endpoints = var.service_endpoints
5556
configuration = var.configuration != null ? jsonencode(var.configuration) : null
5657
key_protect_key = var.kms_key_crn
5758
backup_encryption_key_crn = local.backup_encryption_key_crn
5859
point_in_time_recovery_deployment_id = var.pitr_id
5960
point_in_time_recovery_time = var.pitr_time
6061

62+
dynamic "users" {
63+
for_each = nonsensitive(var.users != null ? var.users : [])
64+
content {
65+
name = users.value.name
66+
password = users.value.password
67+
type = users.value.type
68+
role = (users.value.role != "" ? users.value.role : null)
69+
}
70+
}
71+
6172
group {
6273
group_id = "member" # Only member type is allowed for postgresql
6374
memory {
@@ -185,6 +196,7 @@ locals {
185196
service_credentials_object = length(var.service_credential_names) > 0 ? {
186197
hostname = ibm_resource_key.service_credentials[keys(var.service_credential_names)[0]].credentials["connection.postgres.hosts.0.hostname"]
187198
certificate = ibm_resource_key.service_credentials[keys(var.service_credential_names)[0]].credentials["connection.postgres.certificate.certificate_base64"]
199+
port = ibm_resource_key.service_credentials[keys(var.service_credential_names)[0]].credentials["connection.postgres.hosts.0.port"]
188200
credentials = {
189201
for service_credential in ibm_resource_key.service_credentials :
190202
service_credential["name"] => {
@@ -194,3 +206,17 @@ locals {
194206
}
195207
} : null
196208
}
209+
210+
data "ibm_database_connection" "database_connection" {
211+
count = length(var.users) > 0 ? 1 : 0
212+
endpoint_type = var.service_endpoints
213+
deployment_id = ibm_database.postgresql_db.id
214+
user_id = var.users[0].name
215+
user_type = var.users[0].type
216+
}
217+
218+
locals {
219+
# Used for output only
220+
hostname = length(var.service_credential_names) > 0 ? ibm_resource_key.service_credentials[keys(var.service_credential_names)[0]].credentials["connection.postgres.hosts.0.hostname"] : length(var.users) > 0 ? flatten(data.ibm_database_connection.database_connection[0].postgres[0].hosts[0].hostname) : null
221+
port = length(var.service_credential_names) > 0 ? ibm_resource_key.service_credentials[keys(var.service_credential_names)[0]].credentials["connection.postgres.hosts.0.port"] : length(var.users) > 0 ? flatten(data.ibm_database_connection.database_connection[0].postgres[0].hosts[0].port) : null
222+
}

0 commit comments

Comments
 (0)