Hi everyone,

Hope you’re doing good!

In my last blog post, I explained how to apply the latest Release Update on OEM 13.5. You can check it here.

In the blog post described above, one of the required steps is to apply Release Update 13.5.0.16 on OEM Agents after Release Update is applied on OEM.

But, before you apply RU on OEM Agents, you need to update AgentPatcher in all servers where you have OEM Agent running. As described in the last post, you can do it manually running some commands in all servers.

The main problem is: if you have hundreds of servers, you need to repeat the same tasks in all servers, this will be a time consuming and a very annoying task!

If your company use Ansible, you can automate this. I will share on this blog post a simple Ansible Playbook to perform this task. So, with Ansible, does not matter if you have one server or thousands servers to perform the activity. The time you will spend it should be roughly the same!

Note: this playbook is a “version 0” of it. I am not using Ansible modules like file (to perform rename of files), copy (to copy files) or unarchive (to perform unzip of the file), instead, I only used the module shell. Again, this is not the best practice, but it worked like a charm and save us few hours on our task!

I will not explain the files shared below in detail, mostly of them are self-explained. Files ansible.cfg and update_agent_patcher.yml have some parameters required by Ansible, I encourage you to read the Ansible documentation for more details. It will be a pleasure if I can help with some question, but please, keep in mind, I am not a huge expert on Ansible!

Below we have the basic folder structure for this playbook:

Explaining just a little bit the folder structure described above:

  • ansible.cfg: basic parameters for Ansible. On this file we describe what will be the log file name, what is the user that will connect through SSH from Ansible Server to Servers where we have OEM Agents running, and some others parameters;
  • main.log: the execution log;
  • update_agent_patcher.yml: the playbook file, on this file, we have some others parameters that Ansible will use and we have what roles Ansible will execute, on this case, Ansible will only execute a role called update_AgentPatcher;
  • inventories/OEM_Agents/hosts: the list of hosts where Ansible must connect to perform the activities;
  • roles/update_AgentPatcher/tasks/main.yml: all the tasks that role update_AgentPatcher will perform, like copy the file, unzip it, etc.

So, below, we’ll have the full content of every file described above except by the log file.

Note that I am setting two variables on below files:

  • agent_patcher_file_dir: the directory where we have the zip file for most recent AgentPatcher;
  • agent_patcher_file: the name of zip file for most recent AgentPatcher.

Please note that it’s a best practice to have a separate file to keep all the versions for AgentPatcher, and then use a parameter on main file to set the target version you will like to use for update it. So, I am not following the best practice here! šŸ™‚

ansible.cfg:


[defaults]

# output
display_skipped_hosts = no
stdout_callback = default

# allow new fingerprints
host_key_checking = false

# inventory
inventory = inventories/OEM_Agents/hosts

# logging
log_path = main.log

# retry
retry_files_enabled = False

# default ssh user
remote_user = svc_ansible

# general settings
timeout = 120
forks = 50

[ssh_connection]
pipelining = true
scp_if_ssh = true

update_agent_patcher.yml:


---

- hosts: all
  gather_facts: true
  any_errors_fatal: true
  become: true
  pre_tasks:

 
  roles:

    - { role: update_AgentPatcher } 

inventories/OEM_Agents/hosts:


SERVER01
SERVER02
SERVER03
SERVER04
SERVER05
SERVER06
SERVER07
SERVER08
SERVER09
SERVER10
SERVER11
SERVER12
SERVER13
SERVER14
SERVER15
SERVER16
SERVER17
SERVER18
SERVER19
SERVER20
SERVER21
SERVER22
SERVER23
SERVER24
SERVER25
SERVER26
SERVER27
SERVER28
OEM-01

roles/update_AgentPatcher/tasks/main.yml:


---

- name: get the user which is AGENT_OWNER
  shell: |
    ps -ef |grep agent_13 | grep -v grep | grep emw | awk '{print $1}'
  register: agent_owner_ps
  become_user: root

- name: get the AGENT_HOME
  shell: |
    ps -ef |grep agent_13 | grep -v grep | grep emw | awk '{print $8}'  | sed 's/\/perl\/bin\/perl//g'
  register: agent_home_ps
  become_user: root

- name: get the actual date
  shell: |
    date +"%Y%m%d"
  register: actual_date_server
  become_user: root

- name: set facts
  set_fact:
    agent_home: '{{ agent_home_ps.stdout }}'
    agent_owner: '{{ agent_owner_ps.stdout }}'
    date_host: '{{ actual_date_server.stdout }}'
    agent_patcher_file_dir: '/sapcd/enkitec/19c/OEM_13.5.0.16/AgentPatcher'
    agent_patcher_file: 'p33355570_135000_Generic.zip'

- name: get the actual version of AgentPatcher
  shell: |
    ${ORACLE_HOME}/AgentPatcher/agentpatcher version | grep AgentPatcher | awk '{print $3}' | head -1
  environment:
    ORACLE_HOME: "{{ agent_home }}"
    PATH: "{{ agent_home }}/bin;/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
  register: actual_agentpatcher_version
  become_user: "{{ agent_owner }}"

- name: take a backup of AgentPatcher and copy new AgentPatcher
  shell: |
    cd ${ORACLE_HOME}
    mv AgentPatcher AgentPatcher.bkp.{{ date_host }}
    cp {{ agent_patcher_file_dir }}/{{ agent_patcher_file }} ${ORACLE_HOME}
  environment:
    ORACLE_HOME: "{{ agent_home }}"
    PATH: "{{ agent_home }}/bin;/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
  become_user: "{{ agent_owner }}"

- name: unzip new AgentPatcher
  shell: |
    cd ${ORACLE_HOME}
    unzip -q -o {{ agent_patcher_file }}
  environment:
    ORACLE_HOME: "{{ agent_home }}"
    PATH: "{{ agent_home }}/bin;/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
  become_user: "{{ agent_owner }}"

- name: get the new version of AgentPatcher
  shell: |
    ${ORACLE_HOME}/AgentPatcher/agentpatcher version | grep AgentPatcher | awk '{print $3}' | head -1
  environment:
    ORACLE_HOME: "{{ agent_home }}"
    PATH: "{{ agent_home }}/bin;/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin"
  register: new_agentpatcher_version
  become_user: "{{ agent_owner }}"


- name: show the old version of AgentPatcher
  debug:
    msg: "{{ actual_agentpatcher_version.stdout }}"


- name: show the new version of AgentPatcher
  debug:
    msg: "{{ new_agentpatcher_version.stdout }}"

As you can see in the above file, I am setting the owner for OEM Agent based on process running on OS, getting the ORACLE_HOME for agent, saving in a variable the current/old version of AgentPatcher, taking a backup of current AgentPatcher, copying the new AgentPatcher (zip file) to OEM Agent ORACLE_HOME, extracting the most recent AgentPatcher and checking the new version of AgentPatcher.

To execute the playbook you can first set which ansible.cfg you would like to use. We’ll use the same file we have in our directory.

Below I am showing how to execute the playbook and also showing a small piece of the execution (just to make easier to read):

export ANSIBLE_CONFIG=`pwd`/ansible.cfg

ansible-playbook update_agent_patcher.yml


TASK [update_AgentPatcher : show the new version of AgentPatcher] ************************************************
ok: [SERVER01] => {
“msg”: “13.9.5.5.0”
}
ok: [SERVER02] => {
“msg”: “13.9.5.5.0”
}
ok: [SERVER03] => {
“msg”: “13.9.5.5.0”
}

PLAY RECAP *******************************************************************************************************
SERVER01 : ok=9 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
SERVER02 : ok=9 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
SERVER03 : ok=9 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Hope this helps!

Peace!

Vinicius