Skip to content

Commit

Permalink
fix: include unofficial extensions<br>- NOTE: No upgrade path support…
Browse files Browse the repository at this point in the history
…ed from previous versions (#56)
  • Loading branch information
shemau authored Nov 21, 2024
1 parent ece4c94 commit 8c273b1
Show file tree
Hide file tree
Showing 32 changed files with 910 additions and 24 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ crash.log

# Ignore files for local testing
test.tf
bootstrap_api_key.txt

# Ignore override files as they are usually used to override resources locally and so
# are not checked in
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ are incomplete, may not be in final form and may generate unpredicatable failure
* [terraform-ibm-mq-cloud](#terraform-ibm-mq-cloud)
* [Submodules](./modules)
* [application](./modules/application)
* [experimental-api-key](./modules/experimental-api-key)
* [experimental-certificate](./modules/experimental-certificate)
* [experimental-connection](./modules/experimental-connection)
* [keystore-certificate](./modules/keystore-certificate)
* [mq-instance](./modules/mq-instance)
* [queue-manager](./modules/queue-manager)
Expand Down Expand Up @@ -83,7 +86,7 @@ module "mq_on_cloud" {
queue_manager_display_name = "queue-manager"
queue_manager_name = "qm"
queue_manager_size = "xsmall"
queue_manager_version = "9.4.0_1"
queue_manager_version = "9.4.0_3"
applications = {
"application" = {
Expand Down Expand Up @@ -169,9 +172,9 @@ No resources.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_applications"></a> [applications](#input\_applications) | A map of IBM MQ on Cloud applications to be created. | <pre>map(object({<br> name = string<br> }))</pre> | `{}` | no |
| <a name="input_applications"></a> [applications](#input\_applications) | A map of IBM MQ on Cloud applications to be created. | <pre>map(object({<br/> name = string<br/> }))</pre> | `{}` | no |
| <a name="input_existing_mq_capacity_crn"></a> [existing\_mq\_capacity\_crn](#input\_existing\_mq\_capacity\_crn) | The CRN of an existing capacity service instance, if not specifed, a new capacity plan will be created | `string` | `null` | no |
| <a name="input_keystore_certificates"></a> [keystore\_certificates](#input\_keystore\_certificates) | A map of IBM MQ on Cloud keystore certificates to be created. | <pre>map(object({<br> certificate = string<br> label = string<br> }))</pre> | `{}` | no |
| <a name="input_keystore_certificates"></a> [keystore\_certificates](#input\_keystore\_certificates) | A map of IBM MQ on Cloud keystore certificates to be created. | <pre>map(object({<br/> certificate = string<br/> label = string<br/> }))</pre> | `{}` | no |
| <a name="input_name"></a> [name](#input\_name) | The name to give the MQ on Cloud instance. | `string` | n/a | yes |
| <a name="input_queue_manager_display_name"></a> [queue\_manager\_display\_name](#input\_queue\_manager\_display\_name) | A displayable name for the queue manager. | `string` | n/a | yes |
| <a name="input_queue_manager_location"></a> [queue\_manager\_location](#input\_queue\_manager\_location) | The location in which the queue manager will be deployed. Defaults to using the first location in the created service instance | `string` | `null` | no |
Expand All @@ -181,8 +184,8 @@ No resources.
| <a name="input_region"></a> [region](#input\_region) | The region to provision the MQ on Cloud instance to. | `string` | n/a | yes |
| <a name="input_resource_group_id"></a> [resource\_group\_id](#input\_resource\_group\_id) | The ID of the resource group to provision the MQ on Cloud instance to. | `string` | n/a | yes |
| <a name="input_tags"></a> [tags](#input\_tags) | The list of resource tags that you want to associate with your MQ on Cloud instance. | `list(string)` | `[]` | no |
| <a name="input_truststore_certificates"></a> [truststore\_certificates](#input\_truststore\_certificates) | A map of IBM MQ on Cloud truststore certificates to be created. | <pre>map(object({<br> certificate = string<br> label = string<br> }))</pre> | `{}` | no |
| <a name="input_users"></a> [users](#input\_users) | A map of IBM MQ on Cloud users to be created. | <pre>map(object({<br> email = string<br> name = string<br> }))</pre> | `{}` | no |
| <a name="input_truststore_certificates"></a> [truststore\_certificates](#input\_truststore\_certificates) | A map of IBM MQ on Cloud truststore certificates to be created. | <pre>map(object({<br/> certificate = string<br/> label = string<br/> }))</pre> | `{}` | no |
| <a name="input_users"></a> [users](#input\_users) | A map of IBM MQ on Cloud users to be created. | <pre>map(object({<br/> email = string<br/> name = string<br/> }))</pre> | `{}` | no |

### Outputs

Expand Down
2 changes: 1 addition & 1 deletion examples/advanced/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module "mq_on_cloud" {
queue_manager_display_name = "${var.prefix}-qm-display"
queue_manager_name = "${local.prefix}_qm"
queue_manager_size = "xsmall"
queue_manager_version = "9.4.0_1"
queue_manager_version = "9.4.0_3"

applications = {
"app-${local.prefix}" = {
Expand Down
2 changes: 1 addition & 1 deletion examples/basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module "mq_on_cloud" {
queue_manager_display_name = "${var.prefix}-qm-display"
queue_manager_name = "${local.prefix}_qm"
queue_manager_size = "xsmall"
queue_manager_version = "9.4.0_1"
queue_manager_version = "9.4.0_3"

applications = {
"app-${local.prefix}" = {
Expand Down
27 changes: 27 additions & 0 deletions ibm_catalog.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
"required": true,
"default_value": "us-east"
},
{
"key": "resource_tags"
},
{
"key": "prefix"
},
Expand Down Expand Up @@ -107,6 +110,30 @@
},
{
"key": "existing_queue_manager_name"
},
{
"key": "application_name"
},
{
"key": "existing_application_name"
},
{
"key": "user_name"
},
{
"key": "existing_user_name"
},
{
"key": "user_email"
},
{
"key": "existing_secrets_manager_crn"
},
{
"key": "existing_secret_group_id"
},
{
"key": "secret_group_name"
}
],
"architecture": {
Expand Down
2 changes: 1 addition & 1 deletion main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module "mqcloud_instance" {
name = var.name
region = var.region
resource_group_id = var.resource_group_id
existing_mq_capacity_crn = local.capacity_crn
existing_mq_capacity_crn = var.existing_mq_capacity_crn
tags = var.tags
}

Expand Down
56 changes: 56 additions & 0 deletions modules/experimental-api-key/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# MQ on Cloud API Key

This is an experimental module to extend the [application module](../application). This module uses the application create_api_key_uri to return an application user name and password.

[Learn more](https://cloud.ibm.com/docs/mqcloud?topic=mqcloud-users_and_apps)

This module is problematic in some environments. A temporary step during the provisioning of the key writes to a file. This file has to be retained from one terraform command to another. This means pipeline environments, such as IBM Cloud schematics, which use a clean environment for each run will fail after the first apply.

### Usage

```hcl
module "application_api_key" {
source = "terraform-ibm-modules/mq-cloud/ibm//modules/experimental-api-key"
version = "X.X.X" # Replace "X.X.X" with a release version to lock into a specific release
ibmcloud_api_key = "IBM Cloud Api Key" # pragma: allowlist secret
key_name = "my-application-key"
href = module.<application>.href
}
```

<!-- The following content is automatically populated by the pre-commit hook -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
### Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_local"></a> [local](#requirement\_local) | >= 2.5.2 |

### Modules

No modules.

### Resources

| Name | Type |
|------|------|
| [terraform_data.bootstrap_api_key](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource |
| [local_sensitive_file.bootstrap_api_key](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/sensitive_file) | data source |

### Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_href"></a> [href](#input\_href) | The application href | `string` | n/a | yes |
| <a name="input_ibmcloud_api_key"></a> [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources. | `string` | n/a | yes |
| <a name="input_key_name"></a> [key\_name](#input\_key\_name) | The name to give to the api key | `string` | n/a | yes |

### Outputs

| Name | Description |
|------|-------------|
| <a name="output_api_key"></a> [api\_key](#output\_api\_key) | MQ on Cloud application API key (sensitive) |
| <a name="output_api_key_id"></a> [api\_key\_id](#output\_api\_key\_id) | MQ on Cloud application API key id |
| <a name="output_api_key_name"></a> [api\_key\_name](#output\_api\_key\_name) | MQ on Cloud application API key name |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
15 changes: 15 additions & 0 deletions modules/experimental-api-key/curlly.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

# Exit if any of the intermediate steps fail
set -e

APIKEY=${1}
KEYNAME=${2}
HREF=${3}

BEARER=$(curl -X POST "https://iam.cloud.ibm.com/identity/token" --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json' --data-urlencode 'grant_type=urn:ibm:params:oauth:grant-type:apikey' --data-urlencode 'apikey='"${APIKEY}" 2>/dev/null | jq .access_token | sed 's/^"//' | sed 's/"$//') # pragma: allowlist secret

# shellcheck disable=SC2086
KEY=$(curl -X POST --location --header "Authorization: Bearer ${BEARER}" --header "Accept: application/json" --header "Content-Type: application/json" --data '{ "name": "'${KEYNAME}'" }' "${HREF}" 2>/dev/null)

echo "${KEY}"
33 changes: 33 additions & 0 deletions modules/experimental-api-key/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
##############################################################################
# terraform-ibm-mq-cloud
#
# Create an MQ on Cloud application api key
##############################################################################

locals {
api_key_href = "${var.href}/api_key"
}

# terraform_data is as a do-nothing container for arbitrary actions taken by a provisioner.
# Redirect standard output to a file
resource "terraform_data" "bootstrap_api_key" {
triggers_replace = []

provisioner "local-exec" {
command = "../../modules/experimental-api-key/curlly.sh \"${var.ibmcloud_api_key}\" \"${var.key_name}\" \"${local.api_key_href}\" > bootstrap_api_key.txt"
}
}

# Sensitively read output
data "local_sensitive_file" "bootstrap_api_key" {
filename = "bootstrap_api_key.txt"

depends_on = [resource.terraform_data.bootstrap_api_key]
}

# Find values in JSON, retaining sensitive on api_key
locals {
api_key = regexall("(.*api_key\":\")([0-9a-zA-Z_]*)", data.local_sensitive_file.bootstrap_api_key.content)[0][1]
api_key_id = nonsensitive(regexall("(.*api_key_id\":\")([0-9a-fApiKey-]*)", data.local_sensitive_file.bootstrap_api_key.content)[0][1])
api_key_name = nonsensitive(regexall("(.*api_key_name\":\")([0-9a-zA-Z-_]*)", data.local_sensitive_file.bootstrap_api_key.content)[0][1])
}
19 changes: 19 additions & 0 deletions modules/experimental-api-key/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
########################################################################################################################
# Outputs
########################################################################################################################

output "api_key_name" {
description = "MQ on Cloud application API key name"
value = local.api_key_name
}

output "api_key_id" {
description = "MQ on Cloud application API key id"
value = local.api_key_id
}

output "api_key" {
description = "MQ on Cloud application API key (sensitive)"
value = local.api_key
sensitive = true
}
29 changes: 29 additions & 0 deletions modules/experimental-api-key/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
########################################################################################################################
# Input Variables
########################################################################################################################

variable "ibmcloud_api_key" {
type = string
description = "The IBM Cloud API key to deploy resources."
sensitive = true
}

variable "href" {
description = "The application href"
type = string
}

variable "key_name" {
description = "The name to give to the api key"
type = string

# This is the same as API call validation to catch the error at terraform plan
validation {
condition = alltrue([
can(length(var.key_name) >= 1),
can(length(var.key_name) <= 12),
can(regex("^[a-z][-a-z0-9]*$", var.key_name))
])
error_message = "key_name ${var.key_name} should match regex ^[a-z][-a-z0-9]*$ and be 12 or less characters"
}
}
10 changes: 10 additions & 0 deletions modules/experimental-api-key/version.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
terraform {
required_version = ">= 1.3.0"
required_providers {
# Use "greater than or equal to" range in modules
local = {
source = "hashicorp/local"
version = ">= 2.5.2"
}
}
}
59 changes: 59 additions & 0 deletions modules/experimental-certificate/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# MQ on Cloud trust store certificate download

The trust store is used to trust certificates from MQ clients and other queue managers that connect to the queue manager.

[Learn more](https://cloud.ibm.com/docs/mqcloud?topic=mqcloud-mqoc_qm_certs#cert_policy_mqoc_qm_certs)

This module downloads the provided certificates certificate file.

### Usage

```hcl
# Source a certificate
data "ibm_mqcloud_truststore_certificate" "certificate" {
label = "LetsEncryptIssuingCA"
queue_manager_id = local.queue_manager_id
service_instance_guid = local.override_guid
}
# Download the certificate from the certificates href
module "experimental_certificate" {
source = "terraform-ibm-modules/mq-cloud/ibm//modules/experimental-certificate"
version = "X.X.X" # Replace "X.X.X" with a release version to lock into a specific release
ibmcloud_api_key = "IBM Cloud Api Key" # pragma: allowlist secret
href = data.ibm_mqcloud_truststore_certificate.certificate.trust_store[0].href
}
```

<!-- The following content is automatically populated by the pre-commit hook -->
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
### Requirements

| Name | Version |
|------|---------|
| <a name="requirement_terraform"></a> [terraform](#requirement\_terraform) | >= 1.3.0 |
| <a name="requirement_external"></a> [external](#requirement\_external) | >= 2.3.4 |

### Modules

No modules.

### Resources

| Name | Type |
|------|------|
| [external_external.certificate](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external) | data source |

### Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_href"></a> [href](#input\_href) | The truststore certificates href | `string` | n/a | yes |
| <a name="input_ibmcloud_api_key"></a> [ibmcloud\_api\_key](#input\_ibmcloud\_api\_key) | The IBM Cloud API key to deploy resources | `string` | n/a | yes |

### Outputs

| Name | Description |
|------|-------------|
| <a name="output_certificate"></a> [certificate](#output\_certificate) | name |
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
15 changes: 15 additions & 0 deletions modules/experimental-certificate/curlly.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

# Exit if any of the intermediate steps fail
set -e

eval "$(jq -r '@sh "APIKEY=\(.apikey) HREF=\(.href)"')"

BEARER=$(curl -X POST "https://iam.cloud.ibm.com/identity/token" --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json' --data-urlencode 'grant_type=urn:ibm:params:oauth:grant-type:apikey' --data-urlencode 'apikey='"${APIKEY}" 2>/dev/null | jq .access_token | sed 's/^"//' | sed 's/"$//') # pragma: allowlist secret

# echo $BEARER

CERT_STREAM=$(curl -X GET --location --header "Authorization: Bearer ${BEARER}" --header "Accept: application/octet-stream" "${HREF}" 2>/dev/null)

# shellcheck disable=SC2086
echo '{"certificate":"'${CERT_STREAM}'"}'
19 changes: 19 additions & 0 deletions modules/experimental-certificate/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
##############################################################################
# terraform-ibm-mq-cloud
#
# Create an MQ on Cloud truststore certificate
##############################################################################

locals {
certificate_href = "${var.href}/download"
}

data "external" "certificate" {
program = [
"sh", "../../modules/experimental-certificate/curlly.sh"
]
query = {
apikey = var.ibmcloud_api_key
href = local.certificate_href
}
}
9 changes: 9 additions & 0 deletions modules/experimental-certificate/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
########################################################################################################################
# Outputs
########################################################################################################################

output "certificate" {
description = "name"
value = data.external.certificate.result.certificate
sensitive = true
}
Loading

0 comments on commit 8c273b1

Please sign in to comment.