Guidelines for Stacks

Oracle recommends that you adopt general Terraform best practices for building your Terraform template. However, there are specific Marketplace stack standards to follow in order to publish a stack.

Mandatory Guidelines

The following are mandatory guidelines for stacks listed in Oracle Cloud Infrastructure Marketplace. Each guideline MUST be followed. Before being published, each stack artifact is validated against each of these guidelines.
  1. Stack artifact MUST be a zip file including the Terraform configuration file(s) and a Schema file.
    • Zip MUST include at least one configuration file (.tf) in the root folder.
    • Zip MUST include the Schema file (.yaml) in the root folder.
    • Zip MUST NOT include a Terraform state file in the zip file. State files are managed by Oracle Resource Manager (ORM). When customers launch a stack, ORM creates and manages the resources and the state file become available for download only.
    • Zip MUST NOT include Terraform runtime configuration folder (.terraform).
  2. Terraform configuration MUST ONLY use instance image(s) that are Approved or Published (Public or Private) Marketplace Image(s). It MUST have a Marketplace subscription to each of these image(s). It MUST have hard-coded reference(s) to these Marketplace Image(s). See Sample Terraform configuration for a Marketplace image subscription and usage below for more details.
  3. Binaries MUST NOT be downloaded from external repositories. All binaries and dependencies MUST be baked into the published Marketplace Image.
  4. The Terraform remote exec provisioner MUST ONLY be run within the Oracle Cloud Infrastructure domain. It MUST NOT download files on a remote server.
  5. Third-party code or binaries MUST NOT be downloaded using cloud-init.
    1. cloud-init is a commonly used startup configuration utility for cloud compute instances. It accepts configuration via user-data mechanisms specified as part of the metadata definition on oci_core_instance resource.
    2. There are multiple user-data formats supported by cloud-init. See https://cloudinit.readthedocs.io/en/latest/topics/format.html.
    3. Regardless of the user-data format, cloud-init MUST NOT be used for downloading any third-party code or binary. All binaries required during the instance launch process (bootstrap), if not available within the image, should be downloaded by a process (script) baked as part of the image distribution, not injected via cloud-init (for example, leveraging wget).
    4. However, you may have a cloud-init template set up for customers to use in some particular scenarios, for example, to import a license key file, or to import a configuration file. In that case, you should provide a variable in the Terraform template code to enable customers to enter some data into the cloud-init building block, for example, leveraging Terraform template_file data source.
  6. The Terraform provider MUST be Oracle Cloud Infrastructure. Other cloud providers or third-party application providers are not supported.
  7. If a Terraform module is used, it MUST be loaded from local relative paths. It cannot be loaded from a remote repository.
  8. The Terraform configuration MUST use instance principal authentication.

For more information about Terraform, including the Oracle Cloud Infrastructure provider, instance principal authentication, and the remote exec provisioner, see the Terraform documentation: https://www.terraform.io/docs/providers/index.html.

Recommended Guidelines

The following guidelines are RECOMMENDED for stacks listed in Oracle Cloud Infrastructure Marketplace. Each guideline is considered a best practice that SHOULD be followed if possible.
  • Stack artifact SHOULD enable customers to either create all the infrastructure resources or point to existing ones (network, storage, and so on).
  • Naming conventions and formatting SHOULD be followed:
    • Casing - Use lower_snake_case for all naming. This applies to variable names, resource names, module names, file names, display names, and so on.
    • Specifying Resource Type - Do not include the resource or data source type in the name. In Terraform, resources and data sources are always referenced by <type>.<name>. As such, there is no need to include the type in the name itself.
    • ID vs OCID - In Oracle Cloud Infrastructure, id generally refers to a field that takes an OCID. As such, variables SHOULD use id when referring to OCID values, instead of using ocid.
    • Variable Names - Variable names for Oracle Cloud Infrastructure resources SHOULD typically use the same name as used for the Terraform resource.
    • Display Names - Display names for Oracle Cloud Infrastructure resources SHOULD typically use the same name as used for the Terraform resource.
    • Naming module variables and outputs - When using a module, the naming of the input (variables) and the outputs SHOULD be exposed to the caller.
    • terraform fmt SHOULD be applied to all Terraform before checking it in.

Sample Terraform configuration for a Marketplace image subscription and usage

The following is sample Terraform configuration to create a Marketplace image subscription and use the image as part of the stack definition.

# Local variables pointing to the Marketplace catalog resource
# Eg. Modify accordingly to your Application/Listing
locals {
  mp_listing_id               = "${var.mp_listing_id}"
  mp_listing_resource_id      = "${var.mp_listing_resource_id}"
  mp_listing_resource_version = "${var.mp_listing_resource_version}"
}
 
 
# Get Image Agreement
resource "oci_core_app_catalog_listing_resource_version_agreement" "mp_image_agreement" {
  count = "${var.use_marketplace_image ? 1 : 0}"
 
  listing_id               = "${local.mp_listing_id}"
  listing_resource_version = "${local.mp_listing_resource_version}"
}
 
# Accept Terms and Subscribe to the image, placing the image in a particular compartment
resource "oci_core_app_catalog_subscription" "mp_image_subscription" {
  count                    = "${var.use_marketplace_image ? 1 : 0}"
  compartment_id           = "${var.compartment_ocid}"
  eula_link                = "${oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement.eula_link}"
  listing_id               = "${oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement.listing_id}"
  listing_resource_version = "${oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement.listing_resource_version}"
  oracle_terms_of_use_link = "${oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement.oracle_terms_of_use_link}"
  signature                = "${oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement.signature}"
  time_retrieved           = "${oci_core_app_catalog_listing_resource_version_agreement.mp_image_agreement.time_retrieved}"
 
  timeouts {
    create = "20m"
  }
}
 
# Gets the partner image subscription
data "oci_core_app_catalog_subscriptions" "mp_image_subscription" {
  #Required
  compartment_id = "${var.compartment_ocid}"
 
  #Optional
  listing_id = "${local.mp_listing_id}"
 
  filter {
    name   = "listing_resource_version"
    values = ["${local.mp_listing_resource_version}"]
}
 
 
# Reference the Marketplace Image
resource "oci_core_instance" "instance" {
  // availability_domain = "${data.oci_identity_availability_domain.ad.name}"
  //...
 
  source_details {
    source_type = "image"
    source_id   = "${var.use_marketplace_image ? local.mp_listing_resource_id : var.custom_image_id}"
  }
 
  timeouts {
    create = "60m"
  }
}