None

Websphere profile management with Ansible


Two variations of managing WAS profiles with Ansible.

By Kostas Koutsogiannopoulos

Ansible is an agentless open source tool that we are using in order to automate complex administration tasks.

You can find a basic installation tutorial here.

If you are insterested in other tasks like AWS management or python virtual enviroment management using Ansible, check our tag here.

We recently needed to automate an environment creation for a customer that included Websphere Application Server (WAS) profile creation  managed from a WAS deployment manager living in a different host.

If we assume that we already have a virtual machine template with WAS installation the task basicaly includes 2 steps:

  • Managed profile creation on the new node
  • Federate the new node on deployment manager

Of course we need to include some validation tasks like checking if a profile already exists (with the same name), if the new node is accessible from deployment manager, etc.

The first variation (Using only Ansible's core modules)

Here is a playbook that does the job uging only these core modules:

  • command
  • find

It also includes conditionals that implement some checks.

Refer to  "- name" lines for a quick description.

 was_profile_create.yml
hosts: new_node_servers
  remote_user: usename_for_login
  vars:
   - manageprofile_util: /opt/ibm/websphere/appserver/bin/manageprofiles.sh
   - addnode_util: /opt/ibm/websphere/appserver/bin/addNode.sh
   - profile_templates: /opt/ibm/websphere/appserver/profileTemplates
   - profile_name: Profile01
   - internal_dns: dns_server_host
   - dmgr_host: deplmanager
   - dmgr_port: 8879
   - dmgr_username: username
   - dmgr_password: ********
  tasks:
   - ping:
   - name: List existing profiles
     command: " -listProfiles"
     register: existing_profiles
     changed_when: False
   - name: Delete existing profiles if they exists
     command: " -deleteAll"
     when: existing_profiles.stdout.find('[]') == -1
   - name: Check for existing profile directories
     find: paths="/opt/ibm/websphere/appserver/profiles" patterns="*" file_type=directory
     register: find_results
   - name: Archive existing profile directories if they exists
     command: tar -cvf .tar.gz  --remove-files
     with_items: ""
     when: find_results
   - name: Create the new managed profile
     command: " -create -templatePath /managed -personalCertValidityPeriod 15 -signingCertValidityPeriod 20 -profileName "
   - name: Check if profile is created
     command: " -listProfiles"
     register: existing_profiles
     changed_when: False
   - name: Check if hostname is resolved by dns
     command: nslookup  
     changed_when: False
     register: dns_response
   - name: Federate the node to deployment manager
     command: "   -username  -password  -profileName "
     when: "dns_response.rc == 0 and existing_profiles.stdout.find('') == 1"

 

The second variation (Writting our own module)

This solution, although implements the same tasks is more elegant, portable and expandable. We created the following python module in a directory accessible by "ANSIBLE_LIBRARY" variable of Ansible's environment in order to call it from our playbooks.

 was_profile.py
#!/usr/bin/python
import os
import subprocess
import platform
import datetime
from ansible.module_utils.basic import *

module = AnsibleModule(
    argument_spec = dict(
        state   = dict(default='present', choices=['present', 'abcent']),
        wasdir  = dict(required=True),
        name    = dict(required=True),
        dmgr_host = dict(required=False),
        dmgr_port = dict(required=False),
        node_name = dict(required=False),
        personalCertPeriod = dict(required=False),
        signingCertPeriod = dict(required=False),
        username = dict(required=False),
        password = dict(required=False)
    )
)

state = module.params['state']
wasdir = module.params['wasdir']
name = module.params['name']
dmgr_host = module.params['dmgr_host']
dmgr_port= module.params['dmgr_port']
node_name = module.params['node_name']
personalCertPeriod = module.params['personalCertPeriod']
signingCertPeriod = module.params['signingCertPeriod']
username = module.params['username']
password = module.params['password']

def exists(profile_name):
    child = subprocess.Popen([wasdir+"/bin/manageprofiles.sh -listProfiles"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout_value, stderr_value = child.communicate()
    profile_list = stdout_value.strip("[]\n ").split(", ")
    if profile_name in profile_list:
        return True
    else:
        return False

def main():
    if not os.path.exists(wasdir):
        module.fail_json(msg=wasdir+" does not exists. Check the websphere installation path.")
    # Create a managed profile
    if state == 'present':
        if exists(name):
            module.fail_json(msg="Profile " + name + " creation failed, this name already exists")
        else:
            child = subprocess.Popen([wasdir + "/bin/manageprofiles.sh -create -templatePath " + wasdir + "/profileTemplates/managed -personalCertValidityPeriod " + personalCertPeriod + " -signingCertValidityPeriod " + signingCertPeriod + " -profileName " + name], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout_value, stderr_value = child.communicate()
        if child.returncode != 0:
            module.fail_json(msg="Profile " + name + " creation failed", stdout=stdout_value, stderr=stderr_value)
        else:
            # Federate the Node
            child = subprocess.Popen([wasdir + "/bin/addNode.sh "+ dmgr_host + " " + dmgr_port + " -username " + username + " -password " + password + " -profileName " + name], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout_value, stderr_value = child.communicate()
            if child.returncode != 0:
                module.fail_json(msg="Profile " + name + " federation failed", stdout=stdout_value, stderr=stderr_value)
            else:
                module.exit_json(changed=True, msg=name + " profile created successfully", stdout=stdout_value)

    # Remove a profile
    if state == 'absent':
        if exists(name):
            # Remove the node from deployment manager
            child = subprocess.Popen([wasdir+"/bin/removeNode.sh -username " + username + " -password " + password + " -profileName " + name], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout_value, stderr_value = child.communicate()
            # Remove the profile
            child = subprocess.Popen([wasdir+"/bin/manageprofiles.sh -delete -profileName " + name], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            stdout_value, stderr_value = child.communicate()
            while child.poll() is None:
               time.sleep(0.5)
            # Remove the profile directory. In not we can't create a new profiles with the same name
            shutil.rmtree(wasdir + '/profiles/' + name, ignore_errors=True, onerror=None)
            module.exit_json(changed=True, msg="Profile " + name + " removed successfully", stdout=stdout_value, stderr=stderr_value)
        else:
            module.fail_json(msg="Profile removal failed, check if profile exists")
        module.exit_json(changed=True, msg=name + " profile removed successfully", stdout=stdout_value, stderr=stderr_value)

# Import ansible module snippets
from ansible.module_utils.basic import *
if __name__ == '__main__':
    main()

 

Using this module, we achieved to cut our long playbooks to something like this:

 was_profile_create.yml

- hosts: new_node_servers
  remote_user: usename_for_login
  tasks:
   - ping:
   - name: Create new profile
     was_profile: state=present wasdir=/opt/ibm/websphere/appserver name=Profile01 dmgr_host=deplmanager dmgr_port=8879 username=username password=******** personalCertPeriod=15 signingCertPeriod=20

 

...or this:

 was_profile_delete.yml

- hosts: new_node_servers
  remote_user: usename_for_login
  tasks:
   - ping:
   - name: Create new profile
     was_profile: state=absent wasdir=/opt/ibm/websphere/appserver name=Profile01 dmgr_host=deplmanager dmgr_port=8879 username=username password=******** personalCertPeriod=15 signingCertPeriod=20

 


View epilis's profile on LinkedIn Visit us on facebook X epilis rss feed: Latest articles