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 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.
  9. You must specify the minimum and maximum supported Terraform versions on which you have tested your stack.

    • Specify the minimum required Terraform version in the format: ~> <major_version>.<minor_version>.<patch_version>.

      Where, the patch_version is always set to 0. When a stack is launched, Resource Manager checks the <major_version>.<minor_version> that you have defined in your code and uses the most recent patch version available. That's why you must use the ~> sign instead of the => sign while specifying the minimum required Terraform version.

      For example, ~> 0.14.0 indicates the supported Terraform versions are 0.14.0 or later.

    • Specify the maximum required Terraform version in the format: < <major_version>.<minor_version>.

      For example, < 0.15 indicates that the supported Terraform versions are earlier than 0.15.

    The following example shows how to specify the minimum and maximum supported Terraform versions when you have tested your stack only on Terraform 0.14.

    terraform 
    { required_version = "~> 0.14.0, < 0.15" }

For more information about Terraform, including the Oracle Cloud Infrastructure provider, instance principal authentication, and the remote exec provisioner, see the Terraform documentation for Provider Configuration. For information about supported versions of Terraform, see Getting Started with the Terraform Providerin Oracle Cloud Infrastructure Documentation.

Coding Guidelines for Terraform Configurations

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.