Terraform tips’n’tricks: getting the latest Oracle Linux 7 image OCID programatically

As with all cloud providers you need to specify an operating system image when creating virtual machines using Terraform in Oracle Cloud Infrastructure (OCI). This can either be an Oracle supplied image, or a custom image you built. This post describes how to fetch the most recent Oracle-provided image for Oracle Linux 7 in Terraform. I am planning another post for Oracle Linux 8 in the future.

Terraform versions

When writing this post Terraform 0.14.5 was the latest and greatest release. The terraform init command downloaded release 4.10.0 of the OCI provider.

Supported Operating System Images

Part of the details you need to provide when starting a VM in OCI is the operating system image ID. Oracle calls their cloud identifiers “Oracle Cloud ID” or OCID for short. You can find all supported image OCIDs as part of the OCI documentation.

For instance, if you want to create an Oracle Linux 7 image, the latest “standard” image OCIDs at the time of writing could be found here. Now all you need to do is find the OCID corresponding to your region, suitable with the VM shape you want to run. My target region is eu-frankfurt-1 and I want to start an always-free VM, so I’ll have to pick this OCID for Oracle-Linux-7.9-2021.01.12-0:

ocid1.image.oc1.eu-frankfurt-1.aaaaaaaa5w2lrmsn6wpjn7fbqv55curiarwsryqhoj4dw5hsixrl37hrinja

I love the documentation page for reference, but it is not very practical. A new release of Oracle’s image requires me to update the VM configuration in Terraform. Wouldn’t it be nice if I could look the most recent version up programmatically?

Looking up the latest OCID for your Oracle Linux 7 image

This little code snippet shows how to fetch the OCID for the latest Oracle Linux 7.9 image for use with an always-free VM instance. I am running this in my cloud shell, if you want to run this locally you’d have to update the provider configuration accordingly.

provider "oci" {
        auth = "InstancePrincipal"
        region = var.oci_region
}

# this is the data source for Oracle Linux 7 images
data "oci_core_images" "ol7_latest" {
        compartment_id = var.compartment_ocid

        operating_system = "Oracle Linux"
        operating_system_version = "7.9"
        shape = "VM.Standard.E2.1.Micro"
}

# now let's print the OCID
output "latest_ol7_image" {
        value = data.oci_core_images.ol7_latest.images.0.id
} 

You’ll notice this code snippet doesn’t create anything, it merely fetches information and prints it. Terraform uses data sources for this purpose, returning the desired information. In the case of the oci_core_images data source Terraform will return the list of images matching the specification.

Once the usual terraform init has been run you can execute the code and print the image OCID:

$ terraform apply

[...]

Outputs:
latest_ol7_image = "ocid1.image.oc1.eu-frankfurt-1.aaaaaaaa5w2lrmsn6wpjn7fbqv55curiarwsryqhoj4dw5hsixrl37hrinja"

Nice! This way I get the same result but unlike with the hard-coded version I don’t need to worry about a later Oracle Linux 7.9 image.

I can easily reference the OCID in the oci_core_instance’s source_details.

resource "oci_core_instance" "some_instance" {
        # oci_ads is another data source looking up names of the ADs in my region
        availability_domain = data.oci_identity_availability_domains.oci_ads.availability_domains.1.name
        compartment_id = var.compartment_ocid
        shape = "VM.Standard.E2.1.Micro"

        source_details {
                source_id = data.oci_core_images.ol7_latest.images.0.id
                source_type = "image"

        }

} 

Pitfall

You can’t simply specify “7” as the operating_system_ attribute, when I tried that terraform complained:

 $ grep operating_system_version main.tf 
        operating_system_version = "7"
$ terraform plan

Error: Invalid index

  on main.tf line 24, in output "latest_ol7_image":
  24:         value = data.oci_core_images.ol7_latest.images.0.id
    |----------------
    | data.oci_core_images.ol7_latest.images is empty list of object

The given key does not identify an element in this collection value. 

So remember to specify the dot release for Oracle Linux 7 and update it when a new one comes out.