Infrastructure setup is usually done by creating new instance, pre-configure it with the dependencies and then deploy the application. As the time goes by, new versions of the application would be deployed, many configuration changes would be done by administrators either through automation or many times through manually ssh into the server which may not have any record in version control systems. This makes the server unpredictable for the future deployments and may fail. This type of constantly updating the infrastructure as and when required is called mutable infrastructure.
On the other hand there is something called immutable infrastructure where once the application is bundled with the pre-configured custom image and an instance gets created, nothing can be changed on the instance thereafter. If there is any new changes needs to be done to the application or the configuration of the server, then new image gets created from base image. This replaces the old instance and same process is followed for the future releases as well. This makes the releases predictable and all the environment will be in sync since the same base image/custom image is used throughout.
So this blog helps to create a immutable infrastructure using popular tools such as packer and terraform by leveraging oracle cloud infrastructure and also implement Continuous Integration and Continuous Delivery of the same using Oracle Developer Cloud Service.
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.
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.
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.
Hope you learnt something!!
Follow me on twitter for interesting articles..
Thanks,