Automate Application Deployment Across Availability Domains on Oracle Cloud Infrastructure with Terraform

Changbin Gong
Principal Product Manager and Cloud Advisor

The goal of this blog post is to provide some tips on how to automate application deployment across multiple availability domains on Oracle Cloud Infrastructure by using Terraform. 

Oracle Cloud Infrastructure regions contain multiple availability domains. These availability domains are isolated from each other, fault tolerant, and unlikely to fail simultaneously or be impacted by the failure of another availability domain. To ensure high availability and to protect against resource failure, we recommend deploying your application across multiple availability domains. 

To illustrate how to automate this deployment with Terraform, I am using a sample cluster application that consists of bastion, public agent, master, and worker nodes. These nodes need to be deployed across multiple availability domains to ensure high availability. The bastion and public agent nodes are deployed in public subnets, and the master and worker nodes are deployed in private subnets.

Create Subnets in Each Availability Domain

To accomplish high availability and redundancy for this cluster deployment, you need to create three subnets (bastion, public, and private) in each availability domain, and then deploy corresponding cluster nodes into these subnets. In Terraform, you can use the count variable to create these subnets in each availability domain rather than creating each of them individually. The tip here is to use count.index to refer to each of the availability domains when creating these subnets.

For example, the following code creates three private subnets in each availability domain.

data "oci_identity_availability_domains" "ADs" {

  compartment_id = "${var.tenancy_ocid}"


resource "oci_core_subnet" "private" {

  count = "3"

  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[count.index],"name")}"

  cidr_block = "${var.sampleapp_cidr[count.index]}"

  display_name = "private_ad${count.index}"

  compartment_id = "${var.compartment_ocid}"

  vcn_id = "${oci_core_virtual_network.sampleapp_vcn.id}"

  route_table_id = "${oci_core_route_table.sampleapp.id}"

  security_list_ids = ["${oci_core_security_list.PrivateSubnet.id}"]

  dhcp_options_id = "${oci_core_virtual_network.sampleapp_vcn.default_dhcp_options_id}"

  dns_label = "private${count.index}"



Deploy Cluster Nodes Across Availability Domains

With the same approach, you can provision and deploy each of the cluster nodes into a corresponding availability domain. The trick here is to use the count variable and the mod operator % so that you can easily distribute these nodes into different availability domains.

For example, you can use count.index%3 to determine which availability domain to deploy and to get the subnet_id from the list of subnets created in the preceding section. The following example code illustrates how to create the number of worker nodes specified by the user and then deploy them across different availability domains.

resource "oci_core_instance" "WorkerNode" {

  count = "${var.worker_node_count}"

  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[count.index%3],"name")}"

  compartment_id      = "${var.compartment_ocid}"

  display_name        = "Worker ${format("%01d", count.index+1)}"

  hostname_label      = "Worker-${format("%01d", count.index+1)}"

  shape               = "${var.WorkerInstanceShape}"

  subnet_id           = "${oci_core_subnet.private.*.id[count.index%3]}"


  source_details {

    source_type = "image"

    source_id = "${var.image_ocid}"

    boot_volume_size_in_gbs = "${var.boot_volume_size}"



  metadata {

    ssh_authorized_keys = "${var.ssh_public_key}"



  timeouts {

    create = "30m"



Attach Block Volumes to Cluster Nodes

When creating and attaching block volumes to cluster nodes that are distributed across availability domains, you can use the similar approach to perform the mod (%) operation based on the count variable.

For example, the following code illustrates creating block volumes and attaching them to corresponding master nodes in each availability domain.  

resource "oci_core_volume" "MasterVolume" {


  availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[count.index%3],"name")}"

  compartment_id = "${var.compartment_ocid}"

  display_name = "Master ${format("%01d", count.index+1)} Volume"

  size_in_gbs = "${var.blocksize_in_gbs}"



resource "oci_core_volume_attachment" "MasterAttachment" {


  attachment_type = "iscsi"

  compartment_id = "${var.compartment_ocid}"

  instance_id = "${oci_core_instance.MasterNode.*.id[count.index]}"

  volume_id = "${oci_core_volume.MasterVolume.*.id[count.index]}"



I hope that this blog post made it simple to automate your application deployment across multiple availability domains on Oracle Cloud Infrastructure.

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.