Olá pessoal,

Espero que estejam bem!

No meu último blog post, eu expliquei como aplicar o mais recente Release Update on OEM 13.5. Você pode conferir aqui.

No blog post descrito acima, um dos passos requeridos é aplicar o Release Update 13.5.0.16 nos Agentes do OEM após aplicar o Release Update no OEM.

Mas, antes de aplicar o RU nos Agentes do OEM, você precisa atualizar o AgentPatcher in todos os servidores onde você possui o Agente do OEM sendo executado. Como descrito no último post, você pode fazer essas tarefas manualmente executando alguns comandos em todos os servidores.

O principal problema é: se você tiver centenas de servidores, você precisará repetir as mesmas tarefas em todos os servidores, isso será uma tarefa que consumirá bastante tempo, além de ser uma tarefa chata de ser feita!

Se você possui Ansible no seu ambiente, você pode automatizar isso. Eu vou mostrar nesse blog post um simples Playbook Ansible para realizar essa tarefa. Portanto, com o Ansible, não importa se você possui um servidor ou milhares de servidores para realizar a atividade. O tempo que você gastará será aproximadamente o mesmo!

Nota importante: esse playbook é uma versão “0”. Eu não estou usando módulos do Ansible como file (para renomear arquivos), copy (para copiar arquivos) ou unarchive (para descompactar arquivos), ao invés disso, eu estou apenas usando o módulo shell. Novamente, essa não é uma boa prática, mas está funcionando muito bem e nos salvou algumas horas nessa tarefa!

Eu não vou explicar os arquivos compartilhados abaixo em detalhes, até porque muitos são fáceis de serem compreendidos. Os arquivos ansible.cfg e update_agent_patcher.yml possuem alguns parâmetros necessários para o funcionamento do Ansible, eu te encorajo a ler a documentação do Ansible para maiores detalhes. Será um prazer te ajudar caso tenha alguma dúvida, mas por favor, tenha em mente que eu não sou um grant expert em Ansible!

Abaixo temos uma estrutura de diretórios básica para esse playbook:

Explicando um pouco sobre a estrutura de diretórios acima:

  • ansible.cfg: parâmetros básicos do Ansible. Nesse arquivo a gente pode descrever qual será o nome do arquivo de log que será gerado, qual será o usuário que se conectará via SSH do servidor do Ansible para os servidores onde temos os agentes de OEM sendo executados, e alguns outros parâmetros;
  • main.log: o arquivo para o log de execuções do Ansible;
  • update_agent_patcher.yml: o arquivo de playbook, nesse arquivo, nós temos alguns outros pâmetros que o Ansible, também temos as roles que o Ansible executará. Nesse caso, o Ansible executará uma única role chamada update_AgentPatcher;
  • inventories/OEM_Agents/hosts: a lista dos hosts onde o Ansible precisará se conectar para executar as atividades;
  • roles/update_AgentPatcher/tasks/main.yml: todas as tarefas que a role update_AgentPatcher realizará, como cópia de arquivos, unzip, etc.

Portanto, abaixo, temos o conteúdo na íntegra de cada arquivo descrito acima, exceto o arquivo de log.

Observe que eu também estou definindo duas variáveis nos arquivos abaixo:

  • agent_patcher_file_dir: o diretório onde o arquivo zip do mais recente AgentPatcher está localizado;
  • agent_patcher_file: o nome do arquivo zip do mais recente AgentPatcher.

Por favor, observe que a melhor prática é ter um arquivo separado para manter uma lista de todas as versões de AgentPatcher, e então, usar um parâmetro no arquivo principal para definir a versão “alvo” que queremos atualizar. Portanto, eu não estou seguindo a melhor prática aqui! 🙂

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 }}"

Como você pode ver no arquivo acima, estou definindo o owner do OEM Agent através do processo no Sistema Operacional, também estou definindo o ORACLE_HOME à partir do processo no SO, estou também salvando a versão atual (que será a versão antiga em breve) numa variável, fazendo um backup do AgentPatcher atual, copiando o novo AgentPatcher (arquivo zip) para o ORACLE_HOME do Agente, extraindo o mais recente AgentPatcher e checando a nova versão do mesmo.

Para executar o playbook, você primeiro precisa definir qual ansible.cfg você gostaria de usar. A gente pode usar o mesmo arquivo que está no nosso diretório.

Abaixo estou mostrando como executar o playbook e também mostrando apenas uma parte do output (que foi truncado para facilitar a leitura):

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

Espero que seja útil!

Um abraço!

Vinicius