Geautomatiseerd Middleware omgevingen opzetten met Ansible

In dit artikel laten we zien hoe middleware-omgevingen geautomatiseerd worden opgezet met Ansible.

De voorbereiding

In het voorbeeld zullen we de volgende software gebruiken:

De Directory-structuur

Eerst moeten we beslissen welke directorystructuur we gaan gebruiken. Hieronder wordt een voorbeeld gegeven waarin de binaries (die de WebLogic run-time creëren) gescheiden zijn van de configuratie (hier volgen we de zogenaamde Optimal Flexible Architecture

{{ base_directory }}
    {{ runtime_home }}
        {{ configuration_home }} ( directory that contains the middleware configuration )
            {{ domain_application_home }}
            {{ domain_configuration_home ]}
            {{ node_manager_home }}
        {{ middleware_home }} ( directory that contains the middleware binaries )
            {{ coherence_home }}
            {{ fusion_middleware_home }}
            {{ weblogic_home }}
        {{ java_home }} ( directory that contains the java binaries )

De bovenstaande directory-structuur kan als volgt worden geparametriseerd:

root_directory:                  "/u01"
    
# Base directory
base_directory:                  "{{ root_directory }}/app/oracle"

# Directory that will used for the installaton and configuration
runtime_home:                    "{{ base_directory }}/soabpm12.2.1"

# Directory where the JVM will be installed (this is dependent on the used tar)
java_install_dir:                "{{ runtime_home }}/jdk1.8.0_271"
# Java Home will be used to rename java_install_dir
java_home:                       "{{ runtime_home }}/jdk"
# Default temporary-file directory that will be specified by the system property java.io.tmpdir
java_temp_dir:                    "/tmp"

# Directory that will be used as the middleware home (holds software binaries)
middleware_home:                 "{{ runtime_home }}/installation"
    
# Location of the Oracle inventory
oracle_inventory_home:           "{{ base_directory }}/oraInventory"

# Name of the domain
domain_name:                     "soabpm_domain"

# Directory where the log files will be placed, for example, "{{ runtime_home }}/logs"
# The default is ${DOMAIN_HOME}/servers/${SERVER_NAME}/logs which is fine
# To use the default leave logs_home empty, i.e., ""
logs_home:                       ""

# Directory where the configuration will be placed
configuration_home:              "{{ runtime_home }}/configuration"

# Domain home (directory that contains the domain configuration files)
domain_configuration_home:       "{{ configuration_home }}/domains/{{ domain_name }}"

# Domain application home (directory in which application related artifacts are placed)
domain_application_home:         "{{ configuration_home }}/applications/{{ domain_name }}"

# Node manager home (directory that contains the node manager configuration files)
node_manager_home:               "{{ configuration_home }}/nodemanagers/{{ domain_name }}"

# Default homes that are created when the software is installed
coherence_home:                  "{{ middleware_home }}/coherence"
fusion_middleware_home:          "{{ middleware_home }}/oracle_common"
weblogic_home:                   "{{ middleware_home }}/wlserver"


# Directory where the software to be installed is located
software_directory:              "/mnt/hgfs/vmware_temp"
    
# Name of JVM file that is used in the installation
jvm_file_name:                   "jdk-8u271-linux-x64.tar.gz"
    
# Name of the WebLogic file that is used in the installation
weblogic_file_name:              "fmw_12.2.1.4.0_infrastructure.jar"

# Name of the FMW file that is used in the installation
fmw_file_name:                   "fmw_12.2.1.4.0_soa.jar"

# The scripts create files that are placed in this directory
temporary_directory:             "{{ software_directory }}/soabpm_files"

# shared directory for the templates that is used by pack and unpack
templates_directory:             "{{ temporary_directory }}/templates"
    
# WebLogic and JVM installer locations
jvm_installer:                   "{{ software_directory }}/{{ jvm_file_name }}"
weblogic_installer:              "{{ software_directory }}/{{ weblogic_file_name }}"
fmw_installer:                   "{{ software_directory }}/{{ fmw_file_name }}"

# User and Group under which the software needs to be installed
oracle_install_user:             "weblogic"
oracle_install_password:         "set_in_environment_specific_group_vars_file"
oracle_install_group:            "javainstall"
oracle_install_group_id:         "1000"

De bovenstaande parameters leiden tot de volgende directory-structuur:

/u01/app/oracle
    /soabpm12.2.1
        /configuration
            /applications
                /application_name_env_domain
            /domains
                /application_name_env_domain
            /nodemanagers
                /application_name_env_domain
        /installation ( directory that contains the middleware binaries )
            /coherence
            /oracle_common
            /wlserver
        /jdk

Response files

Om de installer in silent mode te gebruiken moeten we response files creëren

#####
# RESPONSE FILE FOR THE FUSION MIDDLEWARE INFRASTUCTURE INSTALLER

[ENGINE]

#DO NOT CHANGE THIS.
Response File Version=1.0.0.0.0

[GENERIC]

#The oracle home location. This can be an existing Oracle Home or a new Oracle Home
ORACLE_HOME={{ middleware_home }}

#Set this variable value to the Installation Type selected. e.g. Fusion Middleware Infrastructure, Fusion Middleware Infrastructure With Examples.
INSTALL_TYPE=Fusion Middleware Infrastructure

#Provide the My Oracle Support Username. If you wish to ignore Oracle Configuration Manager configuration provide empty string for user name.
MYORACLESUPPORT_USERNAME=

#Provide the My Oracle Support Password
MYORACLESUPPORT_PASSWORD=

#Set this to true if you wish to decline the security updates. Setting this to true and providing empty string for My Oracle Support username will ignore the Oracle Configuration Manager configuration
DECLINE_SECURITY_UPDATES=true

#Set this to true if My Oracle Support Password is specified
SECURITY_UPDATES_VIA_MYORACLESUPPORT=false

#Provide the Proxy Host
PROXY_HOST=

#Provide the Proxy Port
PROXY_PORT=

#Provide the Proxy Username
PROXY_USER=

#Provide the Proxy Password
PROXY_PWD=

#Type String (URL format) Indicates the OCM Repeater URL which should be of the format [scheme[Http/Https]]://[repeater host]:[repeater port]
COLLECTOR_SUPPORTHUB_URL=

#####
# RESPONSE FILE FOR THE FUSION MIDDLEWARE COMPONENT

[ENGINE]

#DO NOT CHANGE THIS.
Response File Version=1.0.0.0.0

[GENERIC]

#The oracle home location. This can be an existing Oracle Home or a new Oracle Home
ORACLE_HOME={{ middleware_home }}

#Set this variable value to the Installation Type selected. e.g. Service Bus, SOA Suite, BPM.
INSTALL_TYPE={{ fmw_install_type }}

De installatie

Om een Oracle Fusion Middleware-product te installeren, kunnen we de volgende stappen volgen:

  • Maak de directory-structuur zoals hierboven gespecificeerd.
  • (Optioneel) Kopieer stop- en startscripts voor de Node Manager, Admin Server en Managed Servers. Deze scripts worden naar de directory runtime_home/scripts gekopieerd.
  • Creëer silent install files.
  • Installeer de Java Virtual Machine.
  • Pas de entropy gathering device aan.
  • Installeer de fusion middleware infrasctructuur.
  • Installeer een fusion middleware product.

Als we de bovenstaande stappen in een Ansible rol plaatsen hebben we het volgende:

# /etc/ansible/roles/fmw_install/tasks/main.yml

- name: create root directory
  file:
    path={{ root_directory }}
    state=directory
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0755
    
- name: create directories
  file:
    path="{{ item }}"
    state=directory
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0755
  when: not( (item is undefined) or (item is none) or (item | trim=='') )
  with_items:
    - "{{ scripts_directory }}"
    - "{{ temporary_directory }}"
    - "{{ templates_directory }}"
    - "{{ logs_home }}"
    - "{{ file_store_directory }}"
    - "{{ weblogic_extension_directory }}"
    
- name: copy shell scripts
  copy: 
    src=roles/fmw_install/files/scripts/lifecycle/shell/
    dest="{{ scripts_directory }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0744
    
- name: copy python scripts
  copy:
    src=roles/fmw_install/files/scripts/lifecycle/python/
    dest="{{ scripts_directory }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644

- name: create SetEnvironmentVariables.sh
  template:
    src=roles/fmw_install/templates/set_environment_variables_sh.j2 
    dest="{{ setenvironmentvariables_sh }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0744
    
- name: create environment.properties
  template:
    src=roles/fmw_install/templates/environment_properties.j2 
    dest="{{ environment_properties }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644
    
- name: create weblogic silent install file
  template:
    src=roles/fmw_install/templates/silent_weblogic_txt.j2 
    dest="{{ wls_silent_install_file }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644
  register: weblogic_silent_install_file_created
  
- name: create fmw silent install file
  template:
    src=roles/fmw_install/templates/silent_fmw_txt.j2 
    dest="{{ fmw_silent_install_file }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644
  register: fmw_silent_install_file_created
    
- name: create oraInst.loc
  template:
    src=roles/fmw_install/templates/ora_inst_loc.j2 
    dest="{{ ora_inst_loc }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644
  register: orainst_loc_created
    
- name: install java virtual machine
  unarchive:
    copy=no
    creates="{{ java }}"
    src="{{ jvm_installer }}"
    dest="{{ runtime_home }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
  register: jvm_installed

- name: rename java virtual machine directory
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: sudo
  command: /bin/sh -c "/usr/bin/mv {{java_install_dir}} {{java_home}}"
    creates="{{ java_home }}"
  register: jvm_directory_renamed
  when: jvm_installed is success
  
- name: set entropy gathering device
  replace:
    dest="{{ java_security }}"
    regexp='^securerandom\.source=file:/dev/random'
    replace="securerandom.source={{ securerandom_source }}"
  when: jvm_installed is success
    
- name: install weblogic server
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: sudo
  command: /bin/sh -c "{{ java }} -Xms1024m -Xmx1024m -Djava.io.tmpdir={{ java_temp_dir }} -jar {{ weblogic_installer }} -silent -responseFile {{ wls_silent_install_file }} -invPtrLoc {{ ora_inst_loc }}"
    creates="{{ wlst_sh }}"
  register: weblogic_installed
  when: jvm_installed is success and weblogic_silent_install_file_created is success and orainst_loc_created is success
  
- name: install fmw component
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: sudo
  command: /bin/sh -c "{{ java }} -Xms1024m -Xmx1024m -Djava.io.tmpdir={{ java_temp_dir }} -jar {{ fmw_installer }} -silent -responseFile {{ fmw_silent_install_file }} -invPtrLoc {{ ora_inst_loc }}"
    creates="{{ fmw_wlst_sh }}"
  register: weblogic_installed
  when: weblogic_installed is success and fmw_silent_install_file_created is success and orainst_loc_created is success

De configuratie

De WebLogic Scripting Tool (WLST) kan worden gebruikt als de command-line equivalent voor de WebLogic Server Administration Console (WLST online) of als de command-line equivalent voor de configuratiewizard (WLST offline). WLST offline heeft echter een aantal beperkingen, waaronder: “offline edits worden genegeerd door draaiende servers”. Wanneer we werken met Fusion Middleware-producten zoals BAM, BPM, OSB of SOA, moeten we werken met Fusion Middleware-product-templates en moeten we dus WLST offline gebruiken.

De templates

  • OSB
    • template name: Oracle Service Bus
    • server groups: OSB-MGD-SVRS-COMBINED
    • fmw install type: Service Bus
  • SOA
    • template name: Oracle SOA Suite
    • server groups: SOA-MGD-SVRS
    • fmw install type: SOA Suite
  • BPM
    • template name: Oracle BPM Suite
    • server groups: SOA-MGD-SVRS
    • fmw install type: BPM
  • BAM
    • template name: Oracle Business Activity Monitoring
    • server groups: BAM12-MGD-SVRS
    • fmw install type: SOA Suite

Het WebLogic Cluster

Om een WebLogic-cluster in WLST offline-mode te maken, gebruiken we

def create_cluster():
    print 'CREATING CLUSTER: ' + cluster_name;
    cluster = create(cluster_name, 'Cluster');
    cluster.setClusterMessagingMode('unicast');
    cluster.setWeblogicPluginEnabled(java.lang.Boolean('true'));
    
    #cluster_address_list = [];
    #for machine_listen_address in machine_listen_addresses:
    #    for i in range(number_of_managed_servers_per_machine):
    #        managed_server_listen_port = str(managed_server_listen_port_start + i);
    #        cluster_address_list.append(machine_listen_address + ':' + managed_server_listen_port);            
    #cluster_address = ','.join(cluster_address_list);
    #cluster.setClusterAddress(cluster_address);
    
    number_of_servers_in_cluster = len(machine_listen_addresses) * number_of_managed_servers_per_machine;
    cluster.setNumberOfServersInClusterAddress(number_of_servers_in_cluster);
    
    return cluster;

De WebLogic Machine

Om een WebLogic-machine te maken, gebruiken we

def create_machine(index_machine_listen_address):
    machine_name = 'machine_' + machine_listen_addresses[index_machine_listen_address].split('.')[0];
    
    print 'CREATING MACHINE: ' + machine_name;
    machine = create(machine_name, 'UnixMachine');
    machine.setPostBindUIDEnabled(java.lang.Boolean('true'));
    machine.setPostBindUID(machine_user_id);
    machine.setPostBindGIDEnabled(java.lang.Boolean('true'));
    machine.setPostBindGID(machine_group_id);
    cd('/Machine/' + machine_name);
    
    print '- CREATING NODE MANAGER';
    nodemanager = create(machine_name, 'NodeManager');
    nodemanager.setListenAddress(machine_listen_addresses[index_machine_listen_address]);
    nodemanager.setListenPort(node_manager_listen_port);
    nodemanager.setNMType(node_manager_mode);
    cd('/');
    
    return machine;

De WebLogic Managed Server

Om een WebLogic managed server te maken, gebruiken we

def create_server(managed_server_server_name, managed_server_listen_port, cluster, machine, index_machine_listen_address, index_number_of_managed_servers_per_machine):
    if index_machine_listen_address==0 and index_number_of_managed_servers_per_machine==0:
        print 'ADJUSTING EXISTING MANAGED SERVER TO ' + managed_server_server_name + ':' + str(managed_server_listen_port);
        servers = cmo.getServers();
        if servers:
            for server in servers:
                if server.getName() != admin_server_name:
                    cd('Servers/' + server.getName());
                    cmo.setName(managed_server_server_name);			
                    cmo.setListenPort(managed_server_listen_port);
                    cmo.setListenAddress(machine_listen_addresses[index_machine_listen_address]);
                    cmo.setCluster(cluster);
                    cmo.setMachine(machine);
    else:
        print 'CREATING SERVER: ' + managed_server_server_name + ':' + str(managed_server_listen_port);
        server = create(managed_server_server_name, 'Server');
        server.setListenPort(managed_server_listen_port);
        server.setListenAddress(machine_listen_addresses[index_machine_listen_address]);
        server.setCluster(cluster);
        server.setMachine(machine);
        cd('Servers/' + managed_server_server_name);
    
    print '- CONFIGURING OVERLOAD PROTECTION';
    overload_protection = create(managed_server_server_name, 'OverloadProtection');
    overload_protection.setFailureAction('force-shutdown');
    overload_protection.setPanicAction('system-exit');
    cd('OverloadProtection/' + managed_server_server_name);
    create(managed_server_server_name, 'ServerFailureTrigger');
    cd('../..');
    overload_protection.getServerFailureTrigger().setMaxStuckThreadTime(600);
    overload_protection.getServerFailureTrigger().setStuckThreadCount(0);
    
    print '- CONFIGURING LOGGING';
    server_log = create(managed_server_server_name, 'Log');
    server_log.setRotationType('bySize');
    server_log.setFileMinSize(5000);
    server_log.setNumberOfFilesLimited(java.lang.Boolean('true'));
    server_log.setFileCount(10);
    server_log.setLogFileSeverity('Info');
    server_log.setStdoutSeverity('Error');
    server_log.setDomainLogBroadcastSeverity('Error');
    server_log.setRotateLogOnStartup(java.lang.Boolean('true'));
    if logs_home:
        server_log.setFileName(logs_home + '/' + domain_name + '/' + managed_server_server_name + '/' + managed_server_server_name + '.log');
        #server_log.setLogFileRotationDir(logs_home + '/' + domain_name + '/archives/' + managed_server_server_name);
    
    web_server = create(managed_server_server_name, 'WebServer');
    cd('WebServer/' + managed_server_server_name);
    create(managed_server_server_name, 'WebServerLog');
    cd('../..');
    web_server.getWebServerLog().setLoggingEnabled(java.lang.Boolean('false'));
    web_server.getWebServerLog().setRotationType('bySize');
    web_server.getWebServerLog().setFileMinSize(5000);
    web_server.getWebServerLog().setNumberOfFilesLimited(java.lang.Boolean('true'));
    web_server.getWebServerLog().setFileCount(10);
    web_server.getWebServerLog().setRotateLogOnStartup(java.lang.Boolean('true'));
    if logs_home:
        web_server.getWebServerLog().setFileName(logs_home + '/' + domain_name + '/' + managed_server_server_name + '/access_' + managed_server_server_name + '.log');
        #web_server.getWebServerLog().setLogFileRotationDir(logs_home + '/' + domain_name + '/archives/' + managed_server_server_name);
    cd('../..');
    
    print '- SETTING SERVER GROUPS'; 
    setServerGroups(managed_server_server_name, server_groups);
    
    print '- ASSIGNING SERVER ' + managed_server_server_name + ' TO CLUSTER ' + cluster_name;
    assign('Server', managed_server_server_name, 'Cluster', cluster_name);
    cd('/');

Merk op dat Fusion Middleware-product-templates al een managed server bevatten, in het WLST-fragment hierboven wordt deze managed server aangepast om een bepaalde naamgevingsconventie weer te geven en natuurlijk is deze toegewezen aan de juiste cluster en machine.

De domein creatie

We maken eerst een domein zonder Fusion Middleware-componenten. Hiervoor gebruiken we

def create_basic_configuration():
    print 'SELECTING TEMPLATES';
    selectTemplate(weblogic_template_name, weblogic_template_version);
    print 'LOADING TEMPLATES';
    loadTemplates();

    print 'SETTING DOMAIN OPTIONS';
    setOption('DomainName', domain_name);
    setOption('OverwriteDomain', 'true');
    setOption('JavaHome', java_home);
    setOption('ServerStartMode', 'prod');
    setOption('NodeManagerType', 'CustomLocationNodeManager');
    setOption('NodeManagerHome', node_manager_home);

    print 'CHANGING ADMIN USER';
    cd('/Security/base_domain/User/weblogic');
    cmo.setName(admin_username);
    cmo.setUserPassword(admin_password);
    cd('/');

    print 'SAVING DOMAIN';
    writeDomain(domain_configuration_home);
    closeTemplate();

Merk op dat dit niet verschilt met het aanmaken van een domein voor een WebLogic Server. Om een bepaalde Fusion Middleware Product template toe te voegen, gebruiken we het volgende

def add_fmw_configuration_to_basic_configuration():
    print 'READING DOMAIN: ' + domain_configuration_home;
    readDomain(domain_configuration_home);

    print 'SELECTING TEMPLATES';
    selectTemplate(fmw_template_name, fmw_template_version);
    print 'LOADING TEMPLATES';
    loadTemplates();
    print 'SETTING DOMAIN OPTIONS';
    setOption('AppDir', domain_application_home);

    print 'CREATING CLUSTER';
    cluster = create_cluster();

    print 'CREATING MACHINES AND SERVERS';
    for index_machine_listen_address in range(len(machine_listen_addresses)):
        machine = create_machine(index_machine_listen_address);
        for index_number_of_managed_servers_per_machine in range(number_of_managed_servers_per_machine):
            managed_server_listen_port = managed_server_listen_port_start + index_number_of_managed_servers_per_machine;
            managed_server_server_name = managed_server_server_name_prefix + str(index_machine_listen_address) + '_' + str(index_number_of_managed_servers_per_machine);
            create_server(managed_server_server_name, managed_server_listen_port, cluster, machine, index_machine_listen_address, index_number_of_managed_servers_per_machine);


def save_changes():
    print 'SAVING CHANGES';
    updateDomain();
    closeDomain();

waarin ook aanroepen staan om een cluster, machines en aanvullende managed servers te creëren.

De resources aanpassen

Standaard worden de messaging management containers, zoals JMS Servers, gekoppeld aan migratable targets. Om de targets aan te passen, kunnen we het volgende gebruiken:

def adjust_jms_resources():
    print 'ADJUSTING JMS RESOURCES';
    
    print '- ADJUSTING FILE STORES';
    file_stores = cmo.getFileStores();
    if file_stores:
        for file_store in file_stores:
            print ' - ADJUSTING FILE STORE: ' + file_store.getName();
            file_store.setDirectory(file_store_directory);
            targets = file_store.getTargets();
            if targets:
                for target in targets:
                    if ' (migratable)' in target.getName():
                        assign('FileStore', file_store.getName(), 'Target', target.getName().strip(' (migratable)'));
    
    print '- ADJUSTING JMS SERVERS';
    jms_servers = cmo.getJMSServers();
    if jms_servers:
        for jms_server in jms_servers:
            print ' - ADJUSTING JMS SERVER: ' + jms_server.getName();
            targets = jms_server.getTargets();
            if targets:
                for target in targets:
                    if ' (migratable)' in target.getName():
                        assign('JMSServer', jms_server.getName(), 'Target', target.getName().strip(' (migratable)'));
    
    print '- ADJUSTING SAF AGENTS';
    saf_agents = cmo.getSAFAgents();
    if saf_agents:
        for saf_agent in saf_agents:
            print ' - ADJUSTING SAF AGENT: ' + saf_agent.getName();
            targets = saf_agent.getTargets();
            if targets:
                for target in targets:
                    if ' (migratable)' in target.getName():
                        assign('SAFAgent', saf_agent.getName(), 'Target', target.getName().strip(' (migratable)'));

De data sources moeten worden aangepast zodat deze de juiste JDBC URIs krijgen

def adjust_data_source_settings():
    print 'ADJUSTING DATA SOURCE SETTINGS';
    jdbc_system_resources = cmo.getJDBCSystemResources();
    if jdbc_system_resources:
        for jdbc_system_resource in jdbc_system_resources:
            print '- ADJUSTING: ' + jdbc_system_resource.getName();
            cd ('/JDBCSystemResource/' + jdbc_system_resource.getName() + '/JdbcResource/' + jdbc_system_resource.getName() + '/JDBCConnectionPoolParams/NO_NAME_0');
            cmo.setInitialCapacity(1);
            cmo.setMaxCapacity(15);
            cmo.setMinCapacity(1);
            cmo.setStatementCacheSize(0);
            cmo.setTestConnectionsOnReserve(java.lang.Boolean('false'));
            cmo.setTestTableName(data_source_test);
            cmo.setConnectionCreationRetryFrequencySeconds(30);
            cd ('/JDBCSystemResource/' + jdbc_system_resource.getName() + '/JdbcResource/' + jdbc_system_resource.getName() + '/JDBCDriverParams/NO_NAME_0');
            cmo.setUrl(data_source_url);
            cmo.setPasswordEncrypted(data_source_rcu_password);
            cd ('/JDBCSystemResource/' + jdbc_system_resource.getName() + '/JdbcResource/' + jdbc_system_resource.getName() + '/JDBCDriverParams/NO_NAME_0/Properties/NO_NAME_0/Property/user');
            cmo.setValue(cmo.getValue().replace('DEV',data_source_rcu_user_prefix));

In 12.2 worden templates voor resourcegroepen geïntroduceerd, omdat we ze niet gebruiken, verwijderen we ze

def remove_resource_group_templates():
    print 'REMOVING RESOURCE GROUP TEMPLATES';
    resource_group_templates = cmo.getResourceGroupTemplates();
    if resource_group_templates:
        for resource_group_template in resource_group_templates:
            print '- REMOVING RESOURCE GROUP TEMPLATE: ' + resource_group_template.getName();
            delete(resource_group_template.getName(), 'ResourceGroupTemplate');

Ansible

De stappen om een basis WebLogic-domein te maken zijn:

  • Maak een domein aan op basis van het Basic WebLogic Server Domain template en een Fusion Middleware Product template.
  • Maak de Node Manager-configuratie, d.w.z. het bestand nodemanager.properties.
  • Maak Node Manager-opstartscripts (in het algemeen wordt het aanbevolen om de Node Manager te starten wanneer de machine opstart, zodat een automatisch herstel kan worden gestart.)
  • Maak user config files voor de Node Manager en Admin Server, zodat er geen wachtwoordbestanden in platte tekst op het systeem nodig zijn.

Als we op basis van de bovenstaande stappen een Ansible role maken, hebben we het volgende:

# /etc/ansible/roles/fmw_config_admin_server/tasks/main.yml

- name: create create_basic_domain.py
  template:
    src=roles/fmw_config_admin_server/templates/create_basic_domain_py.j2 
    dest="{{ create_basic_domain_py }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644
  register: script_created
    
- name: create basic domain
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: sudo
  command: /bin/sh -c "{{ wlst_sh }} {{ create_basic_domain_py }}"
    creates="{{ config_xml }}"
  register: created_basic_domain
  
- name: debug basic domain creation
  debug: 
    var=created_basic_domain.stdout_lines
  when: created_basic_domain is changed
    
- name: create application home directory
  file:
    path="{{ domain_application_home }}"
    state=directory
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0755
    
- name: create nodemanager.properties
  template:
    src=roles/fmw_config_admin_server/templates/nodemanager_properties.j2 
    dest="{{ node_manager_properties }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644

- name: disable derby flag
  replace:
    dest="{{ set_domain_env_sh }}"
    regexp='^[ \t]+DERBY_FLAG="true"'
    replace='DERBY_FLAG="false"'
    
- name: create setUserOverrides.sh
  template:
    src=roles/fmw_config_admin_server/templates/set_user_overrides_sh.j2 
    dest="{{ set_user_overrides_sh }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0744

- name: remove old template
  file:
    path="{{ wls_template_file }}"
    state=absent
  register: removed_old_template
  when: created_basic_domain is changed
    
- name: create new template
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: sudo
  command: /bin/sh -c "{{ pack_sh }} -managed=true -domain={{ domain_configuration_home }} -template={{ wls_template_file }} -template_name={{ domain_name }}"
    creates="{{ wls_template_file }}"
  when: created_basic_domain is changed and removed_old_template is success
    
- name: create nodemanager init script
  template:
    src=roles/fmw_config_admin_server/templates/nodemanager.j2 
    dest="{{ node_manager_service }}"
    owner='root'
    group='root'
    mode=0744
  when: ansible_os_family == 'RedHat' and ansible_distribution_major_version == '6'

- name: create nodemanager systemd script
  template:
    src=roles/fmw_config_admin_server/templates/nodemanager_service.j2 
    dest="{{ node_manager_systemd }}"
    owner='root'
    group='root'
    mode=0644
  when: ansible_os_family == 'RedHat' and ansible_distribution_major_version == '7'
    
- name: enable and start nodemanager service
  service:
    name="{{ node_manager_service_name }}"
    state=started
    enabled=yes
  register: nodemanager_started

- name: create store_user_config.py for node manager
  template:
    src=roles/fmw_config_admin_server/templates/store_user_config_node_manager_py.j2 
    dest="{{ store_user_config_py }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644

- name: create user configuration file and associated key file
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: sudo
  command: /bin/sh -c "{{ wlst_sh }} {{ store_user_config_py }} <<< 'y'"
    creates="{{ node_manager_config_file }}"
  register: created_node_manager_user_configuration_file
  
- name: debug user configuration file and associated key file creation
  debug: 
    var=created_node_manager_user_configuration_file.stdout_lines
  when: created_node_manager_user_configuration_file is changed
    
- name: start admin server
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: sudo
  command: /bin/sh -c "{{ admin_server_start_service }}"
    creates="{{ admin_server_lock_file }}"
  when: nodemanager_started is success

- name: create store_user_config.py for admin server
  template:
    src=roles/fmw_config_admin_server/templates/store_user_config_admin_server_py.j2 
    dest="{{ store_user_config_py }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644

- name: create user configuration file and associated key file
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: sudo
  command: /bin/sh -c "{{ wlst_sh }} {{ store_user_config_py }} <<< 'y'"
    creates="{{ admin_server_config_file }}"
  register: created_admin_server_user_configuration_file
  
- name: debug user configuration file and associated key file creation
  debug: 
    var=created_admin_server_user_configuration_file.stdout_lines
  when: created_admin_server_user_configuration_file is changed

- name: delete temporary files that contain usernames and passwords
  file:
    path="{{ item }}"
    state=absent
  with_items:
    - "{{ create_basic_domain_py }}"
    - "{{ store_user_config_py }}"

Dit kopieert de bestanden die nodig zijn voor de basisconfiguratie, voert het WLST-script uit om het domein te maken als het niet bestaat, en voegt het setUserOverrides.sh-bestand toe aan de $ {DOMAIN_HOME}/bin directory. Nadat het domein is gemaakt, wordt er een service gemaakt voor de Node Manager. Ten slotte starten we de Node Manager en de AdminServer (en maken we de bijbehorende user config files).

Additional Changes

In het geval van de BPM Suite hebben we enkele aanvullende wijzigingen nodig, anders lopen we de volgende fouten tegen:

  • Failed to initialize the application “OracleBPMBACServerApp” due to error weblogic.management.DeploymentException: Could not find OSGi framework with name bac-svnserver-osgi-framework: weblogic.management.DeploymentException: Could not find OSGi framework with name bac-svnserver-osgi-framework
  • Failed to initialize the application “BPMComposer” due to error weblogic.management.DeploymentException: Could not find OSGi framework with name bac-svnserver-osgi-framework: weblogic.management.DeploymentException: Could not find OSGi framework with name bac-svnserver-osgi-framework

De reden hiervoor is dat het bac-svnserver-osgi-framework alleen gekoppeld is aan de AdminServer en niet aan het cluster. Merk op dat BPMComposer en OracleBPMBACServerApp gekoppeld zijn aan het cluster. Om dit te corrigeren, moeten we het volgende uitvoeren:

def adjust_osgi_frameworks():
    print 'ADJUSTING OSGI FRAMEWORKS';
    osgi_frameworks = cmo.getOsgiFrameworks();
    if osgi_frameworks:
        for osgi_framework in osgi_frameworks:
            print ' - ADJUSTING OSGI FRAMEWORK: ' + osgi_framework.getName();
            target_names = [];
            targets = osgi_framework.getTargets();
            if targets:
                for target in targets:
                    target_names.append(target.getName());
                if not cluster_name in target_names:
                    assign('OsgiFramework', osgi_framework.getName(), 'Target', cluster_name);

Voor wijzigingen zoals deze is online WLST de betere optie – bepaalde configuraties werken niet in offline WLST (zoals hierboven weergegeven).

Ansible

Om een Fusion Middleware-product op te zetten, gebruiken we de volgende playbooks:

  • fmw_host – configureert de (Linux) hosts, dwz schakelt SELinux uit, schakelt iptables uit, installeert (noodzakelijke) packages, creëert een groep en een gebruiker voor WebLogic, wijzigt kernelparameters ( /etc/sysctl.conf), en stelt limieten in voor de systeem resources die kunnen worden verkregen in een gebruikerssessie (/etc/security/limits.conf).
  • fmw_install – installeert de Java Virtual Machine en WebLogic.
  • fmw_repository – maakt de benodigde databaseschema’s voor het Fusion Middleware-product.
  • fmw_config_admin_server – maakt een domein aan (met een Admin Server) en stelt de Node Manager in op de node waarop de Admin Server zal draaien. Verder creëert of past het de implementatieomgeving aan, zoals clusters, machines, managed servers, messaging-resources, enzovoort. Het maakt ook een WebLogic-domein templates aan die zal worden gebruikt door het fmw_config_managed_servers-playbook om het domein op andere machines te maken.
  • fmw_config_managed_servers – distribueert het domein naar meerdere machines met behulp van de WebLogic-domein templare gemaakt door het fmw_config_admin_server playbook.
  • fmw_config_extent_environment – breidt een bestaand domein uit.
  • fmw_application_fusion_middleware_product_name_config – bevat extra configuratie en templates die specifiek zijn voor het fusion middleware-product.
  • fmw_application_fusion_middleware_product_name_vars – bevat parameters die worden gebruikt om de resources voor een specifiek fusion-middlewareproduct te creëren, merk op dat de inventories parameters bevatten die per omgeving verschillen, zoals hostnamen en wachtwoorden.

De directory-structuur voor de playbooks ziet er als volgt uit

/etc/ansible
    /inventories
        /development
            /group_vars
                fusion_middleware_product_name_servers.yml
            fusion_middleware_product_name_hosts.cfg
        /test
            /group_vars
                fusion_middleware_product_name_servers.yml
            fusion_middleware_product_name_hosts.cfg
        /acceptance
            /group_vars
                fusion_middleware_product_name_servers.yml
            fusion_middleware_product_name_hosts.cfg
        /production
            /group_vars
                fusion_middleware_product_name_servers.yml
            fusion_middleware_product_name_hosts.cfg
    /roles
        /fmw_application_fusion_middleware_product_name_config
            /tasks
                main.yml
            /templates
                fusion_middleware_product_name_config_py.j2
        /fmw_application_fusion_middleware_product_name_vars
            /defaults
                main.yml
        /fmw_config_admin_server
            /tasks
                main.yml
            /templates
                create_basic_domain_py.j2
        /fmw_config_extent_environment
            /tasks
                main.yml
            /templates
                extent_domain_py.j2
        /fmw_config_managed_servers
            /tasks
                main.yml
        /fmw_host
            /handlers
                main.yml
            /tasks
                main.yml
            /templates
        /fmw_install
            /files
                /scripts
            /tasks
                main.yml
            /templates
    fusion_middleware_product_name_admin_server.yml
    fusion_middleware_product_name_extent.yml
    fusion_middleware_product_name_managed_servers.yml

Een goede manier om productieomgevingen en andere omgevingen gescheiden te houden, is door afzonderlijke inventoty-bestanden te gebruiken, zoals wordt gedaan in de bovenstaande directory-indeling. Het inventory-bestand voor test heeft bijvoorbeeld de volgende inhoud:

# /etc/ansible/inventories/test/bpm_hosts.cfg

[bpm_admin_server]
javanode1

[bpm_managed_servers]
javanode2

[bpm_servers:children]
bpm_admin_server
bpm_managed_servers

Merk ook op dat we in de bovenstaande directory-indeling gebruik maken van group_vars om variabelen te overschrijven. Het bestand fusion_middleware_product_name_servers.yml bevat omgevingsspecifieke instellingen, bijvoorbeeld

# /etc/ansible/inventories/test/group_vars/bpm_servers.yml


##### SetEnvironmentVariables.sh #####
oracle_install_password:                         "password"


##### environment.properties #####
admin_qualified_name:                            ".ms.com"
managed_qualified_name:                          ".ms.com"
node_manager_listen_address:                     "{{ inventory_hostname }}{{ managed_qualified_name }}"
node_manager_password:                           "password"
admin_server_listen_address:                     "javanode1{{ admin_qualified_name }}"
admin_password:                                  "password"


##### domain parameters #####
machine_listen_addresses:                        "javanode1{{ managed_qualified_name }},javanode2{{ managed_qualified_name }}"

data_source_rcu_sys_password:                    "password"
data_source_rcu_password:                        "password"

data_source_rcu_service_connect_string:          "datanode.ms.com:1521/orcl12"
data_source_url:                                 "jdbc:oracle:thin:@//{{ data_source_rcu_service_connect_string }}"

Merk op dat dit bestand de verschillen tussen omgevingen regelt, zoals adresinstellingen zoals weergegeven in het bovenstaande voorbeeld. Het bestand fusion_middleware_product_name_servers.yml bevat ook gevoelige gegevens, zoals wachtwoorden, en daarom moet dit bestand worden versleuteld. We kunnen bestanden versleutelen met behulp van Vault. Om een file te versleutelen kunnen we gebruik maken van ansible-vault encrypt fusion_middleware_product_name_servers.yml.

De (overridable) variabelen worden gezet in het bestand .../fmw_application_fusion_middleware_product_name_vars/defaults/main.yml, bijvoorbeeld

fmw_install_type:                             "BPM"
server_groups:                                "SOA-MGD-SVRS"
weblogic_template_name:                       "Basic WebLogic Server Domain"
weblogic_template_version:                    "12.2.1.4.0"
fmw_template_name:                            "Oracle BPM Suite"
fmw_template_version:                         "12.2.1.4.0"

cluster_name:                                 "soabpm_cluster"
machine_listen_addresses:                     "set_in_environment_specific_group_vars_file"
machine_user_id:                              "{{ oracle_install_user }}"
machine_group_id:                             "{{ oracle_install_group }}"
number_of_managed_servers_per_machine:        "1"
managed_server_server_name_prefix:            "soabpm_server_"
managed_server_listen_port_start:             "10001"
coherence_managed_server_server_name_prefix:  "coherence_server_"

data_source_rcu_service_connect_string:       "set_in_environment_specific_group_vars_file"
data_source_rcu_operation:                    "createRepository"
data_source_rcu_database_type:                "ORACLE"
data_source_rcu_database_user:                "sys"
data_source_rcu_database_role:                "sysdba"
data_source_rcu_sys_password:                 "set_in_environment_specific_group_vars_file"
data_source_rcu_password:                     "set_in_environment_specific_group_vars_file"
data_source_rcu_user_prefix:                  "SOABPM"
data_source_rcu_components_list:              "MDS,IAU,IAU_APPEND,IAU_VIEWER,OPSS,UCSUMS,WLS,STB,SOAINFRA"
data_source_rcu_profile_type:                 "LARGE"

data_source_url:                              "set_in_environment_specific_group_vars_file"
data_source_driver:                           "oracle.jdbc.OracleDriver"
data_source_test:                             "SQL SELECT 1 FROM DUAL"

file_store_directory:                         "/mnt/hgfs/vmware_temp/file_stores"

extent_machine_listen_addresses:              "{{ machine_listen_addresses }}"
extent_number_of_managed_servers_per_machine: "1"

Om dit op te nemen in de .../fmw_config_admin_server/templates/create_basic_domain_py.j2-template, gebruiken we

node_manager_username = str('{{ node_manager_username }}');
node_manager_password = str('{{ node_manager_password }}');
node_manager_listen_port = int('{{ node_manager_listen_port }}');
node_manager_listen_address = str('{{ node_manager_listen_address }}');
node_manager_mode = str('{{ node_manager_mode }}');

admin_server_name = str('{{ admin_server_name }}');
admin_username = str('{{ admin_username }}');
admin_password = str('{{ admin_password }}');
admin_server_listen_port = int('{{ admin_server_listen_port }}');
admin_server_listen_address = str('{{ admin_server_listen_address }}');

cluster_name = '{{ cluster_name }}';
machine_listen_addresses = '{{ machine_listen_addresses }}'.split(',');
machine_user_id = '{{ machine_user_id }}';
machine_group_id = '{{ machine_group_id }}';
number_of_managed_servers_per_machine = {{ number_of_managed_servers_per_machine }};
managed_server_server_name_prefix = '{{ managed_server_server_name_prefix }}';
managed_server_listen_port_start = {{ managed_server_listen_port_start }};

data_source_url = '{{ data_source_url }}';
data_source_driver = '{{ data_source_driver }}';
data_source_rcu_user_prefix = '{{ data_source_rcu_user_prefix }}';
data_source_rcu_password = '{{ data_source_rcu_password }}';
data_source_test = '{{ data_source_test }}';

file_store_directory = '{{ file_store_directory }}';

server_groups = '{{ server_groups }}'.split(',');
weblogic_template_name = '{{ weblogic_template_name }}';
weblogic_template_version = '{{ weblogic_template_version }}';
fmw_template_name = '{{ fmw_template_name }}';
fmw_template_version = '{{ fmw_template_version }}';

Om tempated-WLST-scripts uit te voeren, kunnen we het volgende gebruiken:

- name: create create_basic_domain.py
  template:
    src=roles/fmw_config_admin_server/templates/create_basic_domain_py.j2 
    dest="{{ create_basic_domain_py }}"
    owner="{{ oracle_install_user }}"
    group="{{ oracle_install_group }}"
    mode=0644
  register: script_created
    
- name: create basic domain
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: su
  command: /bin/sh -c "{{ wlst_sh }} {{ create_basic_domain_py }}"
    creates="{{ config_xml }}"
  register: created_basic_domain
  
- name: debug basic domain creation
  debug: 
    var=created_basic_domain.stdout_lines
  when: created_basic_domain is changed

- name: remove old template
  file:
    path="{{ wls_template_file }}"
    state=absent
  register: removed_old_template
  when: created_basic_domain is changed
    
- name: create new template
  become: true
  become_user: "{{ oracle_install_user }}"
  become_method: su
  command: /bin/sh -c "{{ pack_sh }} -managed=true -domain={{ domain_configuration_home }} -template={{ wls_template_file }} -template_name={{ domain_name }}"
    creates="{{ wls_template_file }}"
  when: created_basic_domain is changed and removed_old_template is success

Een playbook dat verschillende rollen combineerd ziet er als volgt uit:

- hosts: bpm_admin_server
  user: root
  
  vars:
    # ansible-playbook bpm_admin_server.yml --inventory=inventories/test/bpm_hosts.cfg --tags "repository"
    # rcu operation - createRepository, generateScript, dataLoad, dropRepository
    data_source_rcu_user_prefix:                  "SOABPM"
    data_source_rcu_operation:                    "createRepository"

  roles:
    - { role: fmw_application_bpm_vars, tags: ['repository'] }
    - fmw_install
    - { role: fmw_repository, tags: ['repository'] }
    - fmw_config_admin_server
    - fmw_application_bpm_config

Hier worden eerst de variabelen geladen, vervolgens worden de Java Virtual Machine en de binaire bestanden van het Fusion Middleware Product geïnstalleerd. Vervolgens wordt de repository gemaakt die nodig is voor het Fusion Middleware-product. Waarna het domein wordt aangemaakt en geconfigureerd.

Om het playbook uit te voeren, maken we gebruik van ansible-playbook fusion_middleware_product_name_admin_server.yml --inventory=inventories/test/fusion_middleware_product_name_hosts.cfg --ask-vault-pass. Merk op dat --ask-vault-pass weggelaten kan worden als we de vault_password_file variabele in de Ansible configuratie file (ansible.cfg) specificeren.

Hulp nodig met bovenstaande of ander Ansible cq. Middleware vragen?

Scroll to Top