Oracle cloud infrastructure with packer, terraform and ansible

This blog will leverage oracle cloud services along with the below industry standard tools,

Packer
Terraform
Ansible

We will see overview of oracle cloud services and the tools used in this article:

Oracle cloud infrastructure
Oracle Cloud Infrastructure provides the infrastructure services for the oracle public cloud with the granular control, security, and predictability of on-premise infrastructure to deliver high-performance, high availability and cost-effective infrastructure services.
Products include Compute, Networking, Storage, Database, Containers, FastConnect, Edge Services, Security.
For more info: https://cloud.oracle.com/en_US/iaas

Packer
Packer is the first step in achieving immutable infrastructure. Built by Hashicorp, packer is the current best tool available to create custom images for the different cloud providers by provisioning the base image with custom softwares using the different provisioners like shell, ansible etc.
For more info: https://www.packer.io/

Terraform
Another tool from Hashicorp, which can spin up the entire infrastructure stack from the terraform scripts. Basically there are terraform providers available for different cloud providers. We can create, destroy the whole infrastructure using terraform.
For more info: https://www.terraform.io/

Ansible
Ansible is used for configuration management automation, where you can install software, deploy applications to thousands of servers and it is agent-less.
For more info: https://www.ansible.com/

Now let us see how this has been setup.

Overview diagram

As shown in the above diagram, packer will create custom image after installing the weblogic server on OCI instance using Ansible. Using this custom image Terraform will spin-up the infrastructure.

Let us see how packer creates a custom image in oracle cloud:
We have used build.json file for creation of the custom image. There are two sections in the build.json file.

  1. Builders section specifies which cloud provider we want to use, here it is ‘oracle cloud’. We must provide the ‘ocid’ details for user, tenancy, base image, compartment, subnet that we are using. Also fingerprint, key_file, region, Availability Domain, shape of the instance required.
  2. Provisioner section specifies any provisioning tool used for the new image. Here we have used ‘shell’ provisioner to install ansible in the instance and then using ansible-local provisioner to run the ansible playbook in the instance.

{
“builders”: [{
“user_ocid”: “ocid1.user.oc1.**************************”,
“tenancy_ocid”: “ocid1.tenancy.oc1.*****************************”,
“fingerprint”: “**************************”,
“key_file”: “oci_api_key.pem”,
“availability_domain”: “UAFK:US-ASHBURN-AD-1”,
“region”: “us-ashburn-1”,
“base_image_ocid”: “ocid1.image.oc1.*****************************”,
“compartment_ocid”:“ocid1.compartment.oc1.*********************”,
“image_name”: “PackerAnsible-new”,
“shape”: “VM.Standard1.1”,
“ssh_username”: “opc”,
“ssh_password”: “welcome1”,
“subnet_ocid”: “ocid1.subnet.oc1.**********************************”,
“type”: “oracle-oci”
}],

“provisioners”: [{
“type”: “shell”,
“inline”: [
“sleep 30”,
“sudo easy_install pip”,
“sudo pip install ansible”
]},

{
“type”: “ansible-local”,
“playbook_file”: “weblogic-fmw-domain.yml”,
“inventory_file”: “hosts”,
“playbook_dir”: “.”,
“extra_arguments”: [
“-v”]}]
}

When we execute above build.json using packer, this will create an instance, run the commands mentioned in the provisioners section. So first it will install pip and ansible. Then it will run ansible playbook to install weblogic server as per the instructions written in the ansible roles. Also it deploys the war file to weblogic server.

Once the packer completes the execution we can see one custom image (with the name that we specified in the build.json) in oracle cloud infrastructure dashboard images section.

Now let us see ansible roles:
I have used some of the roles from the below github repository and modified according to this requirement.
Original github : https://github.com/cvezalis/weblogic-ansible.git

Modified ansible roles: https://github.com/Shasthri/PackerWeblogicAnsible.git

This ansible repo has several roles:

linux-wls Role:
This role installs the required libraries on Oracle Linux, disables the Security Enhanced Linux and firewall and configures some kernel parameters required for WebLogic to run smoothly. It also creates the required OS user and groups.

Also it downloads the JDK archive and Oracle webogic installer from the oracle cloud storage container and keep it in the specified directory in the build server.

linux-jdk Role:
linux-jdk role installs the JDK on the Oracle Linux. WebLogic 12c R2 needs JDK8. Download it from Oracle Support and upload it to oracle storage container as this file is too large to upload to Github. It also creates the JAVA_HOME environment variable for oracle user and add the java bin folder to user PATH.

fmw-software Role:
This role installs the Middle-ware Infrastructure software. You need to download from ‘Oracle support the installer fmw_12.2.1.3.0_infrastructure.jar’ and upload it to oracle storage container as this file is too large to upload to Github before running the playbook.

fmw-domain Role:
This role creates the repositories in database and then executes a python script with WLST( WebLogic Scripting Tool) to create the domain, apply the Enterprise Manager template to domain, set domain mode to production and set weblogic admin username and password and set the data sources to point to our repository.

fmw-managed-server Role:
This role creates a managed server, boot.properties file and then starts the server.

war-deploy Role:
Application war file can be kept in the folder roles/war-deploy/files. Alternatively this can be pushed to oracle cloud infrastructure storage container once the application is built using any continuous integration tool and can be fetched from that bucket prior to deployment. This role runs the WLST script to set environment, set java home and then deploy the war file using weblogic.Deployer command line interface.

Next step is to use Terraform to spin up infrastructure from the custom image created by packer.

Below is the terraform scripts that are used:
https://github.com/Shasthri/packerterraform/tree/master/devcs-repos/Terraform/TerraformOCI

We must mention all OCID details for user,tenancy,subnet etc in env-vars file.
During execution just replace the ‘image_OCID’ string with the packer image OCID in variables.tf

variable “InstanceImageOCID” {
type = “map”
default = { 
// Oracle-provided image “Oracle-Linux-7.4–2017.12.18–0” 
// See https://docs.us-phoenix-1.oraclecloud.com/Content/Resources/Assets/OracleProvidedImageOCIDs.pdf
us-ashburn-1 = “image_OCID” 
//us-ashburn-1 = “ocid1.image.oc1.iad.**********************” 
//eu-frankfurt-1 = “ocid1.image.oc1.eu-frankfurt-1.***********” 
}
}

Once you execute the terraform apply command, you can see an instance will be created with the pre-configured oracle Weblogic server along with the application. You can also access weblogic console if you open the port 7002 to public. Also you can start using the application which was bundled in the packer image.

These can be integrated with the Oracle Developer Cloud service to implement CI/CD for the execution of commands as shown below.

Complete execution flow using Oracle DevCS

This way we can leverage oracle cloud services for immutable servers creation and management, implementing CI/CD for the projects along with the industry standard tools available by third party providers.

Thanks,
Prasanna Shasthri
prasanna.shasthri@oracle.com
Linked-In : www.linkedin.com/in/prasanna-shasthri-b1a77961
Twitter : https://twitter.com/PShasthri