OCI Instance using Marketplace image with Terraform

When spinning up a compute instance in OCI using Terraform, it is relatively easy to fetch the latest OS image you need and attach it to your compute resource. But when you want to use a pre-defined partner image it gets more complicated. You need to accept the agreements and make sure you have the latest version. In this article I walk you through fetching the image ID, accepting the agreement, and spinning up the instance.

In this example we will use the EBS Cloud Manager image provided by the Oracle EBS team in the marketplace of OCI.

Fetching the listing data

First we fetch everything we need to accept the agreement for the specific image and subscribe to it afterwards.

# Get the listing id out of the data source
data "oci_core_app_catalog_listings" "ebs_cloud_manager" {
  display_name = "Oracle E-Business Suite Cloud Manager"
}

# Get the versions available for the listing
data "oci_core_app_catalog_listing_resource_versions" "ebs_versions" {
  listing_id = data.oci_core_app_catalog_listing.ebs_cloud_manager.listing_id
}

# Save the latest version to a local
locals {
  # Get the latest version - it's the FIRST one in the list (index 0)
  latest_version = data.oci_core_app_catalog_listing_resource_versions.ebs_versions.app_catalog_listing_resource_versions[0].listing_resource_version
}

data "oci_core_app_catalog_listing_resource_version" "ebs_version" {
  listing_id       = data.oci_core_app_catalog_listing.ebs_cloud_manager.listing_id
  resource_version = local.latest_version
}

Accepting the agreements

Now we have all the details fetched in data sources about the image or application listing we will use, we can proceed with the agreements. To accept all the agreements we use resource blocks, as these translate to API calls under the hood.

# Accept the license agreement
resource "oci_core_app_catalog_listing_resource_version_agreement" "ebs_agreement" {
  listing_id               = data.oci_core_app_catalog_listing_resource_version.ebs_version.listing_id
  listing_resource_version = data.oci_core_app_catalog_listing_resource_version.ebs_version.listing_resource_version
}

# When you accept this, you receive attributes we will use in the next resource block.
# Now we will subscribe to the image.
resource "oci_core_app_catalog_subscription" "ebs_subscription" {
  compartment_id           = var.tenancy_ocid
  listing_id               = oci_core_app_catalog_listing_resource_version_agreement.ebs_agreement.listing_id
  listing_resource_version = oci_core_app_catalog_listing_resource_version_agreement.ebs_agreement.listing_resource_version
  oracle_terms_of_use_link = oci_core_app_catalog_listing_resource_version_agreement.ebs_agreement.oracle_terms_of_use_link
  signature                = oci_core_app_catalog_listing_resource_version_agreement.ebs_agreement.signature
  time_retrieved           = oci_core_app_catalog_listing_resource_version_agreement.ebs_agreement.time_retrieved
}

Using the image in your compute resource

Now that the subscription is ready, you can reference it as the image source in your compute resource via the listing_resource_id attribute:

resource "oci_core_instance" "compute" {
  display_name        = var.name
  availability_domain = var.availability_domain
  compartment_id      = var.compartment
  shape               = var.shape

  shape_config {
    ocpus         = var.ocpu
    memory_in_gbs = var.memory
  }

  source_details {
    source_type             = "image"
    source_id               = oci_core_app_catalog_subscription.ebs_subscription.listing_resource_id
    boot_volume_size_in_gbs = var.bootvolsize
  }
}

Make sure that you do this for every marketplace image you would like to use, because every image has a license agreement and needs to be subscribed to. This is all you need to use a marketplace image in Terraform. See you next time!