Skip to content

Commit

Permalink
feat: support custom os image import from COS into PowerVS workspace (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ludwig-mueller authored Oct 22, 2024
1 parent 7675867 commit 88db9c3
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": "go.sum|^.secrets.baseline$",
"lines": null
},
"generated_at": "2024-05-16T16:55:16Z",
"generated_at": "2024-10-22T07:26:22Z",
"plugins_used": [
{
"name": "AWSKeyDetector"
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ No modules.
| Name | Type |
|------|------|
| [ibm_pi_image.import_images](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/pi_image) | resource |
| [ibm_pi_image.pi_custom_image1](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/pi_image) | resource |
| [ibm_pi_image.pi_custom_image2](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/pi_image) | resource |
| [ibm_pi_image.pi_custom_image3](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/pi_image) | resource |
| [ibm_pi_key.ssh_key](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/pi_key) | resource |
| [ibm_pi_network.private_subnet_1](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/pi_network) | resource |
| [ibm_pi_network.private_subnet_2](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/pi_network) | resource |
Expand All @@ -109,6 +112,11 @@ No modules.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_pi_custom_image1"></a> [pi\_custom\_image1](#input\_pi\_custom\_image1) | Optional custom image to import from Cloud Object Storage into PowerVS workspace.<br/> image\_name: string, must be unique image name how the image will be named inside PowerVS workspace<br/> file\_name: string, full file name of the image inside COS bucket<br/> storage\_tier: string, storage tier which the image will be stored in after import. Must be one of the storage tiers supported in the PowerVS workspace region. Available tiers can be found using `ibmcloud pi storage-tiers`. Supported values are: "tier0", "tier1", "tier3", "tier5k"<br/> sap\_type: string, "Hana", "Netweaver". Set to null if it's not an SAP image. | <pre>object({<br/> image_name = string<br/> file_name = string<br/> storage_tier = string<br/> sap_type = string<br/> })</pre> | `null` | no |
| <a name="input_pi_custom_image2"></a> [pi\_custom\_image2](#input\_pi\_custom\_image2) | Optional custom image to import from Cloud Object Storage into PowerVS workspace.<br/> image\_name: string, must be unique image name how the image will be named inside PowerVS workspace<br/> file\_name: string, full file name of the image inside COS bucket<br/> storage\_tier: string, storage tier which the image will be stored in after import. Must be one of the storage tiers supported in the PowerVS workspace region. Available tiers can be found using `ibmcloud pi storage-tiers`. Supported values are: "tier0", "tier1", "tier3", "tier5k"<br/> sap\_type: string, "Hana", "Netweaver". Set to null if it's not an SAP image. | <pre>object({<br/> image_name = string<br/> file_name = string<br/> storage_tier = string<br/> sap_type = string<br/> })</pre> | `null` | no |
| <a name="input_pi_custom_image3"></a> [pi\_custom\_image3](#input\_pi\_custom\_image3) | Optional custom image to import from Cloud Object Storage into PowerVS workspace.<br/> image\_name: string, must be unique image name how the image will be named inside PowerVS workspace<br/> file\_name: string, full file name of the image inside COS bucket<br/> storage\_tier: string, storage tier which the image will be stored in after import. Must be one of the storage tiers supported in the PowerVS workspace region. Available tiers can be found using `ibmcloud pi storage-tiers`. Supported values are: "tier0", "tier1", "tier3", "tier5k"<br/> sap\_type: string, "Hana", "Netweaver". Set to null if it's not an SAP image. | <pre>object({<br/> image_name = string<br/> file_name = string<br/> storage_tier = string<br/> sap_type = string<br/> })</pre> | `null` | no |
| <a name="input_pi_custom_image_cos_configuration"></a> [pi\_custom\_image\_cos\_configuration](#input\_pi\_custom\_image\_cos\_configuration) | Cloud Object Storage bucket containing the custom PowerVS images. Images will be imported into the PowerVS Workspace.<br/> bucket\_name: string, name of the COS bucket<br/> bucket\_access: string, possible values: "public", "private" (private requires pi\_custom\_image\_cos\_service\_credentials)<br/> bucket\_region: string, COS bucket region | <pre>object({<br/> bucket_name = string<br/> bucket_access = string<br/> bucket_region = string<br/> })</pre> | `null` | no |
| <a name="input_pi_custom_image_cos_service_credentials"></a> [pi\_custom\_image\_cos\_service\_credentials](#input\_pi\_custom\_image\_cos\_service\_credentials) | Service credentials for the Cloud Object Storage bucket containing the custom PowerVS images. The bucket must have HMAC credentials enabled. Click [here](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-service-credentials) for a json example of a service credential. | `string` | `null` | no |
| <a name="input_pi_image_names"></a> [pi\_image\_names](#input\_pi\_image\_names) | List of images to be imported into cloud account from catalog images. Supported values can be found [here](https://github.com/terraform-ibm-modules/terraform-ibm-powervs-workspace/blob/main/docs/catalog_images_list.md) | `list(string)` | n/a | yes |
| <a name="input_pi_private_subnet_1"></a> [pi\_private\_subnet\_1](#input\_pi\_private\_subnet\_1) | IBM Cloud PowerVS first private subnet name and cidr which will be created. Set value to null to not create this subnet. | <pre>object({<br/> name = string<br/> cidr = string<br/> })</pre> | `null` | no |
| <a name="input_pi_private_subnet_2"></a> [pi\_private\_subnet\_2](#input\_pi\_private\_subnet\_2) | IBM Cloud PowerVS second private subnet name and cidr which will be created. Set value to null to not create this subnet. | <pre>object({<br/> name = string<br/> cidr = string<br/> })</pre> | `null` | no |
Expand Down
90 changes: 86 additions & 4 deletions pi_images.tf
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,95 @@ resource "ibm_pi_image" "import_images" {
}


#####################################################
# Import Custom Image from COS
#####################################################

locals {
pi_custom_image_cos_service_credentials = var.pi_custom_image_cos_configuration != null ? var.pi_custom_image_cos_configuration.bucket_access == "private" ? jsondecode(var.pi_custom_image_cos_service_credentials) : null : null
}

resource "ibm_pi_image" "pi_custom_image1" {
count = var.pi_custom_image1 != null ? 1 : 0

pi_image_name = var.pi_custom_image1.image_name
pi_cloud_instance_id = ibm_resource_instance.pi_workspace.guid
pi_image_bucket_name = var.pi_custom_image_cos_configuration.bucket_name
pi_image_bucket_access = var.pi_custom_image_cos_configuration.bucket_access
pi_image_bucket_region = var.pi_custom_image_cos_configuration.bucket_region
pi_image_bucket_file_name = var.pi_custom_image1.file_name
pi_image_storage_type = var.pi_custom_image1.storage_tier
pi_image_access_key = var.pi_custom_image_cos_configuration.bucket_access == "private" ? local.pi_custom_image_cos_service_credentials.cos_hmac_keys.access_key_id : null
pi_image_secret_key = var.pi_custom_image_cos_configuration.bucket_access == "private" ? local.pi_custom_image_cos_service_credentials.cos_hmac_keys.secret_access_key : null

dynamic "pi_image_import_details" {
# make pi_image_import_details optional
for_each = var.pi_custom_image1.sap_type != null ? [var.pi_custom_image1.sap_type] : []

content {
license_type = "byol"
product = var.pi_custom_image1.sap_type
vendor = "SAP"
}
}
}

resource "ibm_pi_image" "pi_custom_image2" {
count = var.pi_custom_image2 != null ? 1 : 0
depends_on = [ibm_pi_image.pi_custom_image1]

pi_image_name = var.pi_custom_image2.image_name
pi_cloud_instance_id = ibm_resource_instance.pi_workspace.guid
pi_image_bucket_name = var.pi_custom_image_cos_configuration.bucket_name
pi_image_bucket_access = var.pi_custom_image_cos_configuration.bucket_access
pi_image_bucket_region = var.pi_custom_image_cos_configuration.bucket_region
pi_image_bucket_file_name = var.pi_custom_image2.file_name
pi_image_storage_type = var.pi_custom_image2.storage_tier
pi_image_access_key = var.pi_custom_image_cos_configuration.bucket_access == "private" ? local.pi_custom_image_cos_service_credentials.cos_hmac_keys.access_key_id : null
pi_image_secret_key = var.pi_custom_image_cos_configuration.bucket_access == "private" ? local.pi_custom_image_cos_service_credentials.cos_hmac_keys.secret_access_key : null

dynamic "pi_image_import_details" {
# make pi_image_import_details optional
for_each = var.pi_custom_image2.sap_type != null ? [var.pi_custom_image2.sap_type] : []

content {
license_type = "byol"
product = var.pi_custom_image2.sap_type
vendor = "SAP"
}
}
}

resource "ibm_pi_image" "pi_custom_image3" {
count = var.pi_custom_image3 != null ? 1 : 0
depends_on = [ibm_pi_image.pi_custom_image1, ibm_pi_image.pi_custom_image2]

pi_image_name = var.pi_custom_image3.image_name
pi_cloud_instance_id = ibm_resource_instance.pi_workspace.guid
pi_image_bucket_name = var.pi_custom_image_cos_configuration.bucket_name
pi_image_bucket_access = var.pi_custom_image_cos_configuration.bucket_access
pi_image_bucket_region = var.pi_custom_image_cos_configuration.bucket_region
pi_image_bucket_file_name = var.pi_custom_image3.file_name
pi_image_storage_type = var.pi_custom_image3.storage_tier
pi_image_access_key = var.pi_custom_image_cos_configuration.bucket_access == "private" ? local.pi_custom_image_cos_service_credentials.cos_hmac_keys.access_key_id : null
pi_image_secret_key = var.pi_custom_image_cos_configuration.bucket_access == "private" ? local.pi_custom_image_cos_service_credentials.cos_hmac_keys.secret_access_key : null

dynamic "pi_image_import_details" {
# make pi_image_import_details optional
for_each = var.pi_custom_image3.sap_type != null ? [var.pi_custom_image3.sap_type] : []

content {
license_type = "byol"
product = var.pi_custom_image3.sap_type
vendor = "SAP"
}
}
}

################
# For output
################

locals {
pi_images = {
for image in ibm_pi_image.import_images :
image.pi_image_name => image.image_id
}
pi_images = merge({ for image in ibm_pi_image.import_images : image.pi_image_name => image.image_id }, { for image in ibm_pi_image.pi_custom_image1 : image.pi_image_name => image.image_id }, { for image in ibm_pi_image.pi_custom_image2 : image.pi_image_name => image.image_id }, { for image in ibm_pi_image.pi_custom_image3 : image.pi_image_name => image.image_id })
}
109 changes: 109 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,112 @@ variable "pi_tags" {
type = list(string)
default = null
}

variable "pi_custom_image1" {
description = <<EOF
Optional custom image to import from Cloud Object Storage into PowerVS workspace.
image_name: string, must be unique image name how the image will be named inside PowerVS workspace
file_name: string, full file name of the image inside COS bucket
storage_tier: string, storage tier which the image will be stored in after import. Must be one of the storage tiers supported in the PowerVS workspace region. Available tiers can be found using `ibmcloud pi storage-tiers`. Supported values are: "tier0", "tier1", "tier3", "tier5k"
sap_type: string, "Hana", "Netweaver". Set to null if it's not an SAP image.
EOF
type = object({
image_name = string
file_name = string
storage_tier = string
sap_type = string
})
validation {
condition = var.pi_custom_image1 != null ? var.pi_custom_image1.sap_type == null ? true : contains(["Hana", "Netweaver"], var.pi_custom_image1.sap_type) : true
error_message = "Unsupported sap_type in pi_custom_image1. Supported values: null, \"Hana\", \"Netweaver\"."
}
validation {
condition = var.pi_custom_image1 != null ? contains(["tier0", "tier1", "tier3", "tier5k"], var.pi_custom_image1.storage_tier) : true
error_message = "Invalid storage tier detected in pi_custom_image1. Supported values are: tier0, tier1, tier3, tier5k."
}
default = null
}

variable "pi_custom_image2" {
description = <<EOF
Optional custom image to import from Cloud Object Storage into PowerVS workspace.
image_name: string, must be unique image name how the image will be named inside PowerVS workspace
file_name: string, full file name of the image inside COS bucket
storage_tier: string, storage tier which the image will be stored in after import. Must be one of the storage tiers supported in the PowerVS workspace region. Available tiers can be found using `ibmcloud pi storage-tiers`. Supported values are: "tier0", "tier1", "tier3", "tier5k"
sap_type: string, "Hana", "Netweaver". Set to null if it's not an SAP image.
EOF
type = object({
image_name = string
file_name = string
storage_tier = string
sap_type = string
})
validation {
condition = var.pi_custom_image2 != null ? var.pi_custom_image2.sap_type == null ? true : contains(["Hana", "Netweaver"], var.pi_custom_image2.sap_type) : true
error_message = "Unsupported sap_type in pi_custom_image2. Supported values: null, \"Hana\", \"Netweaver\"."
}
validation {
condition = var.pi_custom_image2 != null ? contains(["tier0", "tier1", "tier3", "tier5k"], var.pi_custom_image2.storage_tier) : true
error_message = "Invalid storage tier detected in pi_custom_image2. Supported values are: tier0, tier1, tier3, tier5k."
}
default = null
}

variable "pi_custom_image3" {
description = <<EOF
Optional custom image to import from Cloud Object Storage into PowerVS workspace.
image_name: string, must be unique image name how the image will be named inside PowerVS workspace
file_name: string, full file name of the image inside COS bucket
storage_tier: string, storage tier which the image will be stored in after import. Must be one of the storage tiers supported in the PowerVS workspace region. Available tiers can be found using `ibmcloud pi storage-tiers`. Supported values are: "tier0", "tier1", "tier3", "tier5k"
sap_type: string, "Hana", "Netweaver". Set to null if it's not an SAP image.
EOF
type = object({
image_name = string
file_name = string
storage_tier = string
sap_type = string
})
validation {
condition = var.pi_custom_image3 != null ? var.pi_custom_image3.sap_type == null ? true : contains(["Hana", "Netweaver"], var.pi_custom_image3.sap_type) : true
error_message = "Unsupported sap_type in pi_custom_image3. Supported values: null, \"Hana\", \"Netweaver\"."
}
validation {
condition = var.pi_custom_image3 != null ? contains(["tier0", "tier1", "tier3", "tier5k"], var.pi_custom_image3.storage_tier) : true
error_message = "Invalid storage tier detected in pi_custom_image3. Supported values are: tier0, tier1, tier3, tier5k."
}
default = null
}

variable "pi_custom_image_cos_configuration" {
description = <<EOF
Cloud Object Storage bucket containing the custom PowerVS images. Images will be imported into the PowerVS Workspace.
bucket_name: string, name of the COS bucket
bucket_access: string, possible values: "public", "private" (private requires pi_custom_image_cos_service_credentials)
bucket_region: string, COS bucket region
EOF
type = object({
bucket_name = string
bucket_access = string
bucket_region = string
})
default = null
validation {
condition = var.pi_custom_image_cos_configuration != null ? contains(["public", "private"], var.pi_custom_image_cos_configuration.bucket_access) : true
error_message = "Invalid pi_custom_image_cos_configuration.bucket_access. Allowed values: [\"public\", \"private\"]."
}
validation {
condition = alltrue([var.pi_custom_image1 == null, var.pi_custom_image2 == null, var.pi_custom_image3 == null]) ? true : var.pi_custom_image_cos_configuration != null
error_message = "The import of custom images into PowerVS workspace requires a cos configuration. pi_custom_image_cos_configuration undefined."
}
}

variable "pi_custom_image_cos_service_credentials" {
description = "Service credentials for the Cloud Object Storage bucket containing the custom PowerVS images. The bucket must have HMAC credentials enabled. Click [here](https://cloud.ibm.com/docs/cloud-object-storage?topic=cloud-object-storage-service-credentials) for a json example of a service credential."
type = string
sensitive = true
default = null
validation {
condition = var.pi_custom_image_cos_configuration != null ? var.pi_custom_image_cos_configuration.bucket_access == "private" ? var.pi_custom_image_cos_service_credentials != null : true : true
error_message = "pi_custom_image_cos_service_credentials are required to access private COS buckets."
}
}

0 comments on commit 88db9c3

Please sign in to comment.