Websphere profile management with Ansible
Two variations of managing WAS profiles with Ansible.
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.ymlhosts: 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
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
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
- Posted by Kostas Koutsogiannopoulos · May 25, 2016