IRIS install automation using Ansible
Deploying new IRIS instances can be a time-consuming task, especially when setting up multiple environments with mirrored configurations.
I’ve encountered this issue many times and want to share my experience and recommendations for using Ansible to streamline the IRIS installation process. My approach also includes handling additional tasks typically performed before and after installing IRIS.
This guide assumes you have a basic understanding of how Ansible works, so I won’t go into much detail on its fundamentals. However, if you have questions about anything mentioned here, feel free to ask in the comments below.
The examples provided in this guide were tested using Ansible 3.6 on a Red Hat 8 server, with IRIS 2023.1.1 and Red Hat 8 as the client environment. Other versions of Ansible, Red Hat (or other UNIX flavors), and IRIS may also work, but your mileage may vary.
Ansible install
The Ansible server must be a Linux distribution. We use Red Hat 8 in this article, but other Linux distros and versions should work as well.
To install the Ansible packages, you must first install EPEL:
[ansible@auto01 ansible]$ yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpmThen install Ansible:
[ansible@auto01 ansible]$ yum install ansibleIn addition to the packages, Ansible requires SSH access to remote servers. I recommend creating an SSH key pair, which is more secure than using traditional passwords. Also, the user used to connect to remote servers must have administrative privileges (i.e., be part of the wheel group).
Files and folders
To maintain an organized structure, I recommend the following files and folders under the ansible directory:
[ansible@auto01 ansible]$ ls -l
total 4
-rw-r--r--. 1 ansible ansible 247 Dec 500:57 ansible.cfg
drwxrwxr-x. 2 ansible ansible 6 Dec 500:56 files
drwxrwxr-x. 2 ansible ansible 6 Dec 500:56 inventory
drwxrwxr-x. 2 ansible ansible 6 Dec 500:56 library
drwxrwxr-x. 2 ansible ansible 6 Dec 500:56 playbooks
drwxrwxr-x. 2 ansible ansible 6 Dec 500:56 templates
drwxrwxr-x. 2 ansible ansible 6 Dec 500:56 vars
drwxrwxr-x. 2 ansible ansible 6 Dec 500:56 vault| File/Folder | Description |
|---|---|
| ansible.cfg | Ansible configuration file. Contains directives on how Ansible behaves. |
| files | Contains extra files needed by playbooks, such as IRIS install tar.gz file. |
| inventory | Contains host inventory files. You can have one large inventory file or multiple smaller ones. Splitting the inventory requires more effort when running playbooks on multiple hosts. |
| library | Contains Ansible extra library files. Not required for this examples, but useful for future extensions. |
| playbooks | Contains all the playbooks that you develop, including the IRIS installation playbook discussed below. |
| templates | Contains template files used by playbooks. These are transferred to servers and instantiated with the correct parameters. |
| vars | Contains variables available to all playbooks. |
| vault | Contains sensitive variables accessible only through the ansible-vault command. Useful for handling passwords. |
After setting up this folder structure, copy the IRIS installer and IRIS license key into the files folder. It should look like this:
[ansible@auto01 ansible]$ ls -l files/
total 759976
-rw-rw-r--. 1 ansible ansible 778207913 Dec 514:32 IRISHealth-2023.1.1.380.0.22870-lnxrh8x64.tar.gz
-rw-rw-r--. 1 ansible ansible 1160 Sep 519:13 iris.key
The inventory
To run playbooks in Ansible, you must define your inventory of servers. There are several ways to do this, each with its own advantages. In this article, we’ll use a single file to define all servers.
The servers.yml file will contain the entire inventory, listing each server along with the variables required for the IRIS installation. Here’s an example:
[ansible@auto01ansible]$catinventory/servers.yml
---all: hosts:test01.mydomain: iris_user:irisusr iris_group:irisgrp mgr_user:irisown mgr_group:irismgr platform:lnxrh8x64 iris_cmd:iris iris_instances: - name:TEST01 superserver_port:51773 webserver_port:52773 binary_file:IRISHealth-2023.1.1.380.0.22870-lnxrh8x64 key_file:iris.key install_dir:/test/iris jrnpri_dir:/test/jrnpri jrnsec_dir:/test/jrnsec config_globals:16384 config_errlog:10000 config_routines:"0,128,0,128,0,1024" config_gmheap:1048576 config_locksiz:128057344
The vault
To keep passwords secure, create a vault file containing the passwords for the IRIS SuperUser and CSPSystem accounts.
Use the following command to edit the default vault file:
[ansible@auto01ansible]$ansible-vaulteditvault/defaults.yml---# Default passwordsiris_user_passwd:"Ch4ngeTh!s"
The playbook
To perform an IRIS installation, several tasks must be executed on the target server. These tasks are grouped and ordered in a file called a playbook.
A playbook is essentially a list of tasks that are executed sequentially on the remote hosts.
Below is the playbook I developed to install IRIS:
[ansible@auto01ansible]$catplaybooks/install_iris.yml## Playbook to install Iris#- hosts:all become:yes gather_facts:no tasks: - name:"Load default passwords" include_vars:"../vault/defaults.yml"### PRE-INSTALL TASKS: - name:"Install required packets" yum: name:"{{ item }}" state:latest loop: -"httpd" -"java-1.8.0-openjdk" -"mod_auth_mellon" -"mod_ssl" - name:"Create iris group" group: name:"{{ iris_group }}" gid:5005 - name:"Create iris mgr group" group: name:"{{ mgr_group }}" gid:5006 - name:"Create iris owner user" user: name:"{{ mgr_user }}" uid:5006 group:"{{ iris_group }}" groups:"{{ mgr_group }}" - name:"Create iris user" user: name:"{{ iris_user }}" uid:5005 group:"{{ iris_group }}" - name:"Create mgr folder" file: path:"{{ item.install_dir }}/mgr" state:directory owner:"{{ iris_user }}" group:"{{ iris_group }}" mode:0775 loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Copy license key" copy: src:"../files/{{ item.key_file }}" dest:"{{ item.install_dir }}/mgr/iris.key" owner:"{{ iris_user }}" group:"{{ iris_group }}" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Create /install folder" file: path:"/install" state:directory mode:0777 - name:"Create Instances install folders" file: path:"/install/{{ item.name }}" state:directory mode:0777 loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Copy IRIS installer" copy: src:"../files/{{ item.binary_file }}.tar.gz" dest:"/install/{{ item.name }}/" loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Untar IRIS installer" command: cmd:"tar -xzf /install/{{ item.name }}/{{ item.binary_file }}.tar.gz" chdir:"/install/{{ item.name }}/" loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}"### IRIS INSTALL: - name:"Install Iris" command: cmd:"./irisinstall_silent" chdir:"/install/{{ item.name }}/{{ item.binary_file }}" environment: ISC_PACKAGE_INSTANCENAME:"{{ item.name }}" ISC_PACKAGE_INSTALLDIR:"{{ item.install_dir }}" ISC_PACKAGE_PLATFORM:"{{ platform }}" ISC_PACKAGE_UNICODE:"Y" ISC_PACKAGE_INITIAL_SECURITY:"Normal" ISC_PACKAGE_MGRUSER:"{{ mgr_user }}" ISC_PACKAGE_MGRGROUP:"{{ mgr_group }}" ISC_PACKAGE_USER_PASSWORD:"{{ iris_user_passwd }}" ISC_PACKAGE_CSPSYSTEM_PASSWORD:"{{ iris_user_passwd }}" ISC_PACKAGE_IRISUSER:"{{ iris_user }}" ISC_PACKAGE_IRISGROUP:"{{ iris_group }}" ISC_PACKAGE_SUPERSERVER_PORT:"{{ item.superserver_port }}" ISC_PACKAGE_WEBSERVER_PORT:"{{ item.webserver_port }}" ISC_PACKAGE_CLIENT_COMPONENTS:"standard_install" ISC_PACKAGE_STARTIRIS:"N" loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Remove installers" file: path:"/install/{{ item.name }}" state:absent loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}"### IRIS CUSTOMIZATIONS: - name:"Change iris.cpf" lineinfile: path:"{{ item[0].install_dir }}/iris.cpf" regexp:"{{ item[1].from }}" line:"{{ item[1].to }}" backup:yes with_nested: -"{{ iris_instances }}" -[{from:"^TerminalPrompt=.*",to:"TerminalPrompt=8,3,2"},{from:"^FreezeOnError=0",to:"FreezeOnError=1"},{from:"^AutoParallel=.*",to:"AutoParallel=0"},{from:"^FastDistinct=.*",to:"FastDistinct=0"},{from:"^LockThreshold=.*",to:"LockThreshold=10000"},{from:"^EnsembleAutoStart=.*",to:"EnsembleAutoStart=1"},{from:"^MaxIRISTempSizeAtStart=.*",to:"MaxIRISTempSizeAtStart=300"}] loop_control: label:"{{ item[0].name }}: {{ item[1].to }}" - name:"Change Journal Current Dir" lineinfile: path:"{{ item.install_dir }}/iris.cpf" regexp:"^CurrentDirectory=.*" line:"CurrentDirectory={{ item.jrnpri_dir }}" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Change Journal Alternate Dir" lineinfile: path:"{{ item.install_dir }}/iris.cpf" regexp:"^AlternateDirectory=.*" line:"AlternateDirectory={{ item.jrnsec_dir }}" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Change Journal Prefix name" lineinfile: path:"{{ item.install_dir }}/iris.cpf" regexp:"^JournalFilePrefix=.*" line:"JournalFilePrefix={{ item.name }}_" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Change Globals memory" lineinfile: path:"{{ item.install_dir }}/iris.cpf" regexp:"^globals=.*" line:"globals=0,0,{{ item.config_globals }},0,0,0" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Change errlog memory" lineinfile: path:"{{ item.install_dir }}/iris.cpf" regexp:"^errlog=.*" line:"errlog={{ item.config_errlog }}" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Change routines memory" lineinfile: path:"{{ item.install_dir }}/iris.cpf" regexp:"^routines=.*" line:"routines={{ item.config_routines }}" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Change gmheap memory" lineinfile: path:"{{ item.install_dir }}/iris.cpf" regexp:"^gmheap=.*" line:"gmheap={{ item.config_gmheap }}" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}" - name:"Change locksiz memory" lineinfile: path:"{{ item.install_dir }}/iris.cpf" regexp:"^locksiz=.*" line:"locksiz={{ item.config_locksiz }}" backup:yes loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}"### START IRIS: - name:"Start Iris" command:"iris start {{ item.name }}" loop:"{{ iris_instances }}" loop_control: label:"{{ item.name }}"...As you can see, there are multiple tasks in this playbook—most of them self-explanatory by name. The comments indicate pre-install tasks, installation, and post-install customizations. After executing this playbook, you will have a new IRIS instance installed on the target system, customized with memory and other settings.
Run the installation!
After configuring the inventory, vault, and playbooks, you’re ready to execute the IRIS installation using Ansible.
To do so, run the following command:
[ansible@auto01 ansible]$ ansible-playbook -K --ask-vault-pass -i inventory/servers.yml playbooks/install_iris.yml
BECOME password:
Vault password:
PLAY [all] **************************************************************************************************************************************************
. . .
Once the playbook execution finishes, you’ll receive a summary of task statuses where you can verify that everything completed successfully.
And that’s it — you’ve just installed IRIS using Ansible! 😁
Comments
That's a great work, but today we have containers, why do not use containers?
Sure, containers are great for multiple scenarios. This is just an alternative when you need IRIS installed on a VM or a physical server.