February 25 2017

Introduction

Prepping a server for an Oracle Fusion Middleware installation is comprised of a number of mundane, repetitive, somewhat time consuming and always inconsistently applied steps.  At AVIO we use the the Rubicon Red MyST tool for FMW provisioning.  There is no better configuration management tool for FMW platform provisioning.  Since MyST does all the hard stuff for us it seemed odd the server prep tasks weren't automated as well.  The key server prepping steps are listed below.

  • Creating the oracle user and group
  • Downloading and Installing a compatible Java
  • Setting up the oracle user's login
  • Creating System swap file that would be used by FMW installers
  • Downloading the FMW installation binaries.  

There are a number of configuration management tools like Chef, Puppet, Ansible that can perform these tasks quite easily.  In this case we needed a tool that could be easily installed and run in fewer steps than the current manual prepping steps take.

Chef from Chef

Chef comes in several flavors.  For mature configuration management scenarios there is the Chef Server tool that contains a fully distributed environment consisting of a Chef Developer client (DK) and the Chef Server that coordinates the configuration to the Chef target servers.   In my use case I was interested in a simpler setup, one that I could run one-time on a server and do it in the fewest possible steps.

For standalone use on a server there is Chef Solo, which provides a thin Chef client to implement standalone server configurations.  In this blog you will see there are just three steps to install and then execute the Chef recipes.   

Getting Started

  • In my case I was using Amazon Linux EC2 for the server instance and reference Amazon S3 in various wget recipes to pull down the requisite binaries.
  • Internet access on the server is needed or manually copy the Chef Solo installation.
  • SSH to the server with sudo access is required.  

Step 1: Install Chef Solo

The Chef Client installer could be downloaded and run (RPM install) or you may ssh into the server and run the following Omnitruck installer that will detect the OS, download and install the correct Chef package.

sudo curl -L https://omnitruck.chef.io/install.sh | sudo bash

Step 2: Checkout the Chef Recipes from Source Control

Good Community of Chef Resources

Ideally, you should be storing the Chef configuration management recipes in a source repository. Chef is nicely integrated with GitHub and provides publicly available recipes that are nicely documented and integrated on the Chef website. I cloned the Git Chef recipes into an "aviochef" directory, in the ec2-user's home.

Illustrated aviochef Directory

The structure and contents of the aviochef Git directory is illustrated below. There are two files, listed at the end that Chef Solo cares about: solo.rb and node.json.  (The recipes are kept in the cookbooks/recipes directory and will be summarized at the conclusion of the blog.)

aviochef
+-- cookbooks
¦   +-- fmw_aws
¦   ¦   +-- attributes
¦   ¦   ¦   +-- default.rb
¦   ¦   +-- definitions
¦   ¦   +-- files
¦   ¦   +-- libraries
¦   ¦   +-- metadata.rb
¦   ¦   +-- providers
¦   ¦   +-- README.md
¦   ¦   +-- recipes
¦   ¦   ¦   +-- create_oracle.rb
¦   ¦   ¦   +-- default.rb
¦   ¦   ¦   +-- get_installers.rb
¦   ¦   ¦   +-- install_java.rb
¦   ¦   ¦   +-- update_bashrc.rb
¦   ¦   ¦   +-- yum_wget.rb
¦   ¦   +-- resources
¦   ¦   +-- templates
¦   ¦       +-- default
¦   ¦       +-- oracle_bashrc.erb
¦   +--
+-- node.json
+-- solo.rb

The Chef Solo Configuration File

The solo.rb file contains properties to identify where the Chef cookbooks are and a reference to the location of the file (node.json) with the Chef recipe run list.

file_cache_path '/home/ec2-user/aviochef'
cookbook_path '/home/ec2-user/aviochef/cookbooks'
json_attribs '/home/ec2-user/aviochef/node.json'

The Chef Solo Recipe Runlist

The node.json file shown below references the recipe runlist the Chef Solo requires.  

{
"run_list": [
    "recipe[fmw_aws::create_oracle]"
  , "recipe[fmw_aws::yum_wget]"
  , "recipe[fmw_aws::install_java]"
  , "recipe[fmw_aws::update_bashrc]"
  , "recipe[fmw_aws::create_swap]"
  , "recipe[fmw_aws::get_installers]"
  ]
}

Step 3: Run Chef Recipes 

Use the Chef Solo command to run the recipes contained in the runlist, as shown below and it's done.

sudo chef-solo -c ~/aviochef/solo.rb

    Review Chef Recipes

    As described on the preceding steps there were only three commands required to install Chef and run our cookbook recipes to provision the server.  What about the recipes?  The devil's in the details as they say, so let's take a quick look at the more interesting of the recipes.

    create_oracle.rb

    Ruby script first create an oracle user, providing the user command with details about then name, group, home directory and lastly the password.    

    user node.default['fmwmain']['oracle_user'] do
      action :create
      username node.default['fmwmain']['oracle_user']
      gid node.default['fmwmain']['oracle_group']
      manage_home true
      home node.default['fmwmain']['oracle_user_home']
      shell '/bin/bash'
      password node.default['fmwmain']['oracle_password']
    end

    Chef Best Practice

    The property values used in this command are derived from the attributes/default.rb file that consists of the following values.  By using this best practice then other Chef recipes can reference the same property values.

    default['fmwmain']['oracle_user']            = 'oracle'
    default['fmwmain']['oracle_group']          = 'oinstall'
    default['fmwmain']['oracle_password']   ='$1$PLrT6HBF$O6cvMEfUGLPPm/xrAwNga0'
    default['fmwmain']['oracle_user_home'] = '/home/oracle'
    default['fmwmain']['oracle_home']          = '/opt/u01/oracle'
    default['fmwmain']['oracle_software']     = '/opt/u01/oracle/software/12.2.1.1'
    default['fmwmain']['oracle_java']            = '/opt/u01/oracle/software/java'
    default['fmwmain']['java_root']                = '/opt/java'
    default['fmwmain']['java_home']             = '/opt/java/jdk1.8.0_111'
     

    install_java.rb

    In this recipe various directories are created and then the Java installer is downloaded (in this case we use Amazon S3 to keep the binaries) using the remote_file command which performs a "wget" to the specified directory and file location.  Lastly, a bit of bash is run to extract Java into the Java home.  

    directory node.default['fmwmain']['oracle_java'] do
      action :create
    end
    directory node.default['fmwmain']['java_root'] do
      action :create
    end
    java_software =node.default['fmwmain']['oracle_java'] +'/jdk-8u111-linux-x64.tar.gz'
    tar_command='tar xzvf '+java_software
    remote_file java_software do
      source 'https://s3-server/product-installers/oracle/java/jdk-8u111-linux-x64.tar.gz' 
      mode '0755'
      action :create
    end
    # run shell command to do tar extract
    execute 'extract_java_tar' do
      command tar_command
      cwd node.default['fmwmain']['java_root']
      not_if { File.exists?(node.default['fmwmain']['java_home']) }
    end

    update_bash.rb

    Chef Best Practice

    When creating files for a configuration a Chef best practice is to use an "embedded" Ruby template.  This was done for the creation of the .bashrc file for the oracle user.  The reference to the template is on the "source" line below. The "variables" line passes the export_home and export_path variable to the template.  

    bashrc_dir = node.default['fmwmain']['oracle_user_home'] + '/.bashrc'
    export_home = 'export JAVA_HOME=' +node.default['fmwmain']['java_home']
    export_path = 'export PATH=' +node.default['fmwmain']['java_home'] +'/bin'+':$PATH'
    template bashrc_dir do
    source "oracle_bashrc.erb"
    variables({ :export_home => export_home, :export_path => export_path })
    action :create
    owner node.default['fmwmain']['oracle_user']
    group node.default['fmwmain']['oracle_group']
    mode '0755'
    end

    The template file (templates/oracle_bashrc.erb) contains references to the export_home and export_path variables, as shown on the last two lines of the file.

    # .bashrc
    # # Source global definitions
    if [ -f /etc/bashrc ]; then
      . /etc/bashrc
    fi
    # User specific aliases and functions
    <%= @export_home %>
    <%= @export_path %>
     

    Cleaning Up With Chef

    Let's push the cooking metaphor to the limit and wrap things up with some kitchen cleanup.   If you need to remove the aforementioned server prep then run the remove_oracle.rb Chef recipe shown below.  

    remove_oracle.rb

    # recipe will remove the oracle user/group and (most) directories created by create_oracle recipe
    user node.default['fmwmain']['oracle_user'] do
      action :remove
      username node.default['fmwmain']['oracle_user']
      ignore_failure true
    end
    group node.default['fmwmain']['oracle_group'] do
      action :remove
      ignore_failure true
    end
    directory node.default['fmwmain']['oracle_user_home'] do
      owner node.default['fmwmain']['oracle_user']
      action :delete
      recursive true
    end
    directory '/opt/java' do
      action :delete
      recursive true
    end
    #Uses swap cookbook method
    swap_file '/swapfile' do
      action :remove
      ignore_failure true
      only_if { File.exists?("/swapfile")}
    end

    Chef Worked Out Nicely

    The Chef tool proved to be easy to install, configure and run.  Between Chef and MyST it provides full automation all of the tasks associated with Fusion Middleware provisioning.  While shell scripting may have been an alternative, using Chef provide a Ruby programming syntax and a large community of Chef recipes to draw upon should the need arise for more complicated configuration. The full scripts are available on request.

     

    About the Author

    Greg Hughlett

    Greg has more than twenty-five years of experience in all phases of design, development, and implementation of software applications.  He has developed and architected BPM/SOA technologies for more than ten of those years from Fuego BPM to BEA AquaLogic BPM to Oracle BPM/SOA 11g.  He has worked for clients within banking, financial services, Life Insurance,  Health Care, public sector and telecommunications industries.  His areas of expertise include Oracle SOA and Oracle BPM (formerly AquaLo

    Join the Conversation

    Enter your first name. It will only be used to display with your comment.
    Enter your email. This will be used to validate you as a real user but will NOT be displayed with the comment.
    By submitting this form, you accept the Mollom privacy policy.