The Integration blog covers the latest in product updates, best practices, customer stories, and more.

  • April 18, 2019

Getting ready to run SOA on Oracle Cloud Infrastructure with Terraform

Robert Wunderlich
Product Strategy Director

Oracle has a robust portfolio of cloud offerings ranging from SaaS to IaaS.  Some of the services like Autonomous Transaction Processing (ATP), or Oracle Integration Cloud (OIC) are fully managed by Oracle, lifting the burdens from DBAs and System Administrators.  These services run on Oracle Cloud Infrastructure (OCI) sometimes referred to as the "gen 2 cloud".  

Some of the services like SOA Cloud and Java Cloud that were originally delivered on OCI Classic ("gen 1 cloud"), can also run on OCI, but there are a number of prerequisites that must be completed before these services can be deployed.  For more information, see https://docs.cloud.oracle.com/iaas/Content/General/Reference/PaaSprereqs.htm

The prerequisites are well documented, but with the number of steps required, some mistakes can occur.  I experienced this when helping a partner troubleshoot an installation problem that turned out to be a simple typo.  This got me to thinking that Terraform by Hashicorp could help prevent these sort of problems, and make the process repeatable.

Terraform is a great open source offering supporting the "infrastructure as code" movement and we are using it quite extensively with Oracle Cloud Infrastructure (OCI).   We have an OCI Provider available for Terraform which enables all of the OCI configurations to be defined as terraforms.

Terraform takes the approach of describing what needs to be done, and Terraform itself handles the dependencies and order of execution.  With this in mind, I was able to take the prerequisites guide and translate the steps into a terraform script of about 260 lines. 

For most customers, setting these prerequisites is a one time event so creating a Terraform might be overkill, but if there are multiple domains, or a partner who is working with multiple customers, the investment may be worth it.

To set this up, I created three files; an environment file, a terraform variable declaration file and the main terraform file that defines the prerequisites.  I could have combined the terraform files, but I chose to separate the two.

First, I an environment file to set variables to be used by the script.  This makes the script reusable:

Here is an example (confidential values redacted)

Any environment variable that is TF_VAR_* will be be available to Terraform as the value following.  For example TF_VAR_tenancy_ocid is referenced as ${var.tenancy_ocid} . There are many ways to handle variables in Terraform, such as a .tfvars file, or at the command line.  This is just one method.

When I source my environment file, I can then run my terraform which performs all of the steps required for the prerequisites and also creates an OCI Native database for use with SOA Cloud Service.  The power here is that I do not have to deal with the minutiae of ordering the tasks but even more so, Terraform will calculate values based on previous steps.  To see some of this in action, we can run "terraform plan" but we will see this also in the beginning of the "terraform apply" step.  Before Terraform begins performing the work, we can review what will be done.  Here is an example of the policy that will be created.

This brings us back to the original problem encountered by the partner, when entering the policies in the free-form UI, the name of the compartment had a misspelling.  Here is an example of the UI.  Notice that it is a free form text.  If the compartment is misspelled, the policy statement can still be created, but there would never be a condition that would satisfy the policy statement.

In Terraform, this is eliminated by using the derived compartment name.  This is one of the many benefits of "Infrastructure as code" because once we validated this the first time, we can repeat without making a typo.  Of course, we also no longer have to type statements into a UI either!

This results in a repeatable definition that we can be sure no typos exist.  Derived values are quite useful because we may be applying this to different regions.  For example, the subnet definitions.

In this case, I was targeting the eu-frankfurt-1 region, and rather than hard-code the availability domains, I can perform lookups.  

This means with this terraform, I can target my configuration to any region, and the subnet creation will automatically discover and use the proper names of the availability domains for that region.  I'm sure with further refinement, I could also dynamically define the subnets rather than have three subnet entries, but this is a first draft of the script!

A key concept here is the ability to work in multiple regions from the same terraform.  In this case, I am working with both the eu-frankfurt-1 region and for identity actions (creating users, groups, compartments, policies, etc) I need to work in my home region which happens to be us-ashburn-1.  You can see at the very top of this post in my environment where I have a home and target region.  In my provider definitions, I created an alias

Since most of my work is performed in my target region, I simply specify my home region only.  Notice in each provider entry, region is referencing my target_region and home_region specifically.  Here is an example of an action that uses my home region

Notice how the provider is specified to use the "home" alias.  Now here is an example of some actions that uses the target provider

Notice there is no provider reference.  This means that the default provider will be used which I happened to have as my target provider.  This is simply a matter of preference and I could have created a "target" provider alias and used that throughout as well.  Notice how many derived values we are using.  For example, I create the Virtual Cloud Network (VCN) which all the other network components are associated, I am able to reference the computed VCN id in the other components.  Nothing is hard-coded.

With everything defined, I ran my Terraform script which took about an hour to complete, most of that time was spent creating the OCI Database VM.

Once that was complete, my terraform provided the auth token created for the user which will be used in the SOACS provisioning UI that is currently in PSM.


Now with my prerequisites in place, it is time to provision SOACS.  Here we can see my newly created Compartment and VCN


We can also select the Database created by Terraform and enter the credentials.


For our backup and recovery, we will use the storage user created by Terraform as well as the token that Terraform returned.


Here is the summary of the SOACS installation.  Notice the download button.  It is a good idea to use that which will give you JSON output that could be used with the REST API to create instances, but also is just a good way to capture your inputs.  Now is the time to click "Create"


Once created, I receive confirmation that my environment is ready for use, running on Oracle Cloud Infrastructure, the gen 2 cloud!

While this task is complete, I know I can further improve my Terraform.  Here are some next steps:

  • Tokenize the DB creation portion.  Yes, my DB password is in my Terraform which is not good.  I was simply getting my proof of concept to work, but now I would go make sure that my terraform script can be fully reusable.
  • Explore how I can tokenize other areas like the CIDR definitions, etc just to make the script more reusable
  • Provide the storage container as an output.  One of the areas that can be difficult is correctly defining the storage container URL in the SOACS UI.  This is something that the Terraform script could output along with the token making it easier for the user to quickly set up their SOACS environment.

Going forward, we will look at how we can leverage the latest cloud technologies to make installations and configurations easier and repeatable, but for now, this helps us complete the prerequisites as we move to the gen 2 cloud.

Join the discussion

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