Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions ansible/dpf/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
These are some sample Ansible playbooks to setup a Db2 DPF instance on a set of VMs.

The Db2 DPF instance uses NFS for the shared instance home directory.

The playbooks assume your storage is also virtualized.
Meaning a VM exists that provides storage (via iSCSI) to the VMs running Db2.

See the [vars.yaml](playbooks/vars.yaml) file for how you can specify things like the IP
addresses of the VMs, the name of the Db2 installation image, the number of MLNs per VM
and more.

With VMs created, the following commands would run the playbooks to setup the DPF instance:

```shell
ansible-playbook -i inventory.ini playbooks/vm_setup.yaml
ansible-playbook -i inventory.ini playbooks/storage_host_setup.yaml
ansible-playbook -i inventory.ini playbooks/storage_client_setup.yaml
ansible-playbook -i inventory.ini playbooks/db2_dpf_setup.yaml
ansible-playbook -i inventory.ini playbooks/db2_storage_setup.yaml
```
27 changes: 27 additions & 0 deletions ansible/dpf/inventory.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# All hosts that can run Db2
[db2_hosts]
dbhost1
dbhost2
dbhost3
dbhost4
dbhost5
dbhost6
dbhost7
dbhost8
dbhost9
dbhost10
dbhost11
dbhost12
dbhost13
dbhost14
dbhost15
dbhost16
dbhost17
dbhost18
dbhost19
dbhost20

# Only used if using a VM as a storage server.
# If you have a real SAN, or access your storage some other way, you don't need this.
[storage_host]
dbhost-storage
137 changes: 137 additions & 0 deletions ansible/dpf/playbooks/db2_dpf_setup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
---
- hosts: db2_hosts
any_errors_fatal: true
gather_facts: true
vars_files:
- vars.yaml

tasks:

- name: Run play to install Db2
include_tasks: db2_install.yaml

- name: Run play to setup shared home on NFS server
when: inventory_hostname == groups['db2_hosts'][0]
include_tasks: nfs_server_shared_home.yaml

- name: Run play to setup shared home on NFS clients
include_tasks: nfs_client_shared_home.yaml

- name: Copy private ssh key for root to hosts
copy:
src: root_id_rsa
dest: /root/.ssh/id_rsa
mode: '0400'

- name: Copy public ssh key for root to hosts
copy:
src: root_id_rsa.pub
dest: /root/.ssh/id_rsa.pub
mode: '0400'

- name: Update authorized_keys for root
authorized_key:
user: root
key: "{{ lookup('file', 'root_id_rsa.pub') }}"

- name: Update ssh_known_hosts
blockinfile:
path: /etc/ssh/ssh_known_hosts
create: true
insertafter: EOF
block: |
{% for host in groups['db2_hosts'] %}
{{ hostvars[host]['ansible_default_ipv4']['address'] }} {{ 'ssh-rsa' }} {{hostvars[host]['ansible_ssh_host_key_rsa_public'] }}
{{ hostvars[host]['ansible_hostname'] }} {{ 'ssh-rsa' }} {{hostvars[host]['ansible_ssh_host_key_rsa_public'] }}
{% endfor %}

- name: Create Db2 Instance
when: inventory_hostname == groups['db2_hosts'][0]
command:
cmd: /opt/ibm/db2/instance/db2icrt -u db2fenc1 db2inst1
creates: /home/db2inst1/sqllib

- name: Create .ssh dir for db2inst1
when: inventory_hostname == groups['db2_hosts'][0]
file:
path: /home/db2inst1/.ssh
state: directory
mode: '0700'
owner: db2inst1
group: db2inst1

- name: Copy private ssh key for db2inst1 to hosts
when: inventory_hostname == groups['db2_hosts'][0]
copy:
src: db2inst1_id_rsa
dest: /home/db2inst1/.ssh/id_rsa
mode: '0400'
owner: db2inst1
group: db2inst1

- name: Copy public ssh key for db2inst1 to hosts
when: inventory_hostname == groups['db2_hosts'][0]
copy:
src: db2inst1_id_rsa.pub
dest: /home/db2inst1/.ssh/id_rsa.pub
mode: '0400'
owner: db2inst1
group: db2inst1

- name: Update authorized_keys for db2inst1
when: inventory_hostname == groups['db2_hosts'][0]
become_user: db2inst1
authorized_key:
user: db2inst1
key: "{{ lookup('file', 'db2inst1_id_rsa.pub') }}"

- name: Set SELinux boolean to allow passwordless ssh when home is on NFS
seboolean:
name: use_nfs_home_dirs
state: true
persistent: true

- name: Create db2nodes.cfg
when: inventory_hostname == groups['db2_hosts'][0]
copy:
dest: /home/db2inst1/sqllib/db2nodes.cfg
content: |
{% for item in groups['db2_hosts'] | product(range(mlns_per_host)) %}
{{ loop.index - 1 }} {{ hostvars[item[0]]['ansible_hostname'] }} {{ item[1] }}
{% endfor %}
owner: db2inst1
group: db2inst1

- name: Remove entries from /etc/services
lineinfile:
path: /etc/services
search_string: 'db2inst1'
state: absent

# TODO Should use loop over mlns_per_host below
- name: Add entries to /etc/services
blockinfile:
path: /etc/services
insertafter: EOF
block: |
DB2_db2inst1 20016/tcp
DB2_db2inst1_1 20017/tcp
DB2_db2inst1_2 20018/tcp
DB2_db2inst1_3 20019/tcp
DB2_db2inst1_4 20020/tcp
DB2_db2inst1_5 20021/tcp
DB2_db2inst1_6 20022/tcp
DB2_db2inst1_7 20023/tcp
DB2_db2inst1_8 20024/tcp
DB2_db2inst1_END 20025/tcp
db2c_db2inst1 25010/tcp

# Need to open all non-privileged ports as per https://www.ibm.com/docs/en/db2/12.1.0?topic=support-packet-filter-firewalls
# Here we just add all our hosts to the trusted zone
- name: Add firewall rule for Db2
firewalld:
source: "{{ vm_ip_prefix }}.0/24"
zone: trusted
state: enabled
permanent: yes
immediate: yes
40 changes: 40 additions & 0 deletions ansible/dpf/playbooks/db2_install.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
- name: Check for Db2 Install
stat:
path: /opt/ibm/db2
register: db2_install_path

- name: Upload Db2 Image
unarchive:
src: "{{ db2_install_image }}"
dest: /root
creates: /root/server
when: db2_install_path.stat.exists == False

# For pacemaker
- name: Install Db2 Prereqs
dnf:
name:
- ksh
- python3-dnf-plugin-versionlock
state: present

- name: Install Db2
command:
cmd: /root/server/db2_install -n -y -p SERVER -b /opt/ibm/db2
creates: /opt/ibm/db2

- name: Remove installer files
file:
path: /root/server
state: absent

- name: Create db2inst1 user
user:
name: db2inst1
uid: 5000
create_home: false

- name: Create db2fenc1 user
user:
name: db2fenc1
uid: 5001
60 changes: 60 additions & 0 deletions ansible/dpf/playbooks/db2_storage_setup.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
- hosts: db2_hosts
any_errors_fatal: true
gather_facts: true
vars_files:
- vars.yaml

tasks:

- name: Create filesystem on data device
filesystem:
dev: "{{ '/dev/' }}{{ item.key }}"
fstype: xfs
opts: "{{ '-L DATA%04d' % item.value.model.split('_')[1] | int }}"
loop: "{{ ansible_devices|dict2items }}"
loop_control:
label: "{{ item.value.model }}"
when: "inventory_hostname == groups['db2_hosts'][0] and item.value.model != None and item.value.model.startswith('DB2DATA_')"

# This is not sufficient to pickup new labels, so we run udevadm below
- name: Rescan iSCSI devices to pickup LABELs
open_iscsi:
rescan: true

- name: Run command to read the new fs labels
command: udevadm trigger

- name: Update facts for devices so LABEL data is avaialble after filesystem create
setup:
gather_subset: devices

- name: Add data device filesystems to fstab
mount:
path: "{{ db2data_path }}/db2inst1/{{ item.value.links.labels[0] | replace('DATA', 'NODE') }}"
src: "{{ 'LABEL=' }}{{ item.value.links.labels[0] }}"
fstype: xfs
opts: defaults,noauto
state: present
loop: "{{ ansible_devices|dict2items }}"
loop_control:
label: "{{ item.value.model }}"
when: "item.value.model != None and item.value.model.startswith('DB2DATA_')"

- name: Mount needed data device filesystems for each host
mount:
path: "{{ db2data_path }}/db2inst1/{{ 'NODE%04d' % i }}"
src: "{{ 'LABEL=' }}{{ 'DATA%04d' % i }}"
state: mounted
fstype: xfs
loop: "{{ groups['db2_hosts'] | product(range(mlns_per_host)) }}"
loop_control:
index_var: i
when: "item[0] == inventory_hostname"

- name: Set permissions on db2data path
file:
path: "{{ db2data_path }}"
owner: db2inst1
group: db2inst1
recurse: true
20 changes: 20 additions & 0 deletions ansible/dpf/playbooks/db2_uninstall.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
- hosts: db2_hosts
any_errors_fatal: true
gather_facts: false
vars_files:
- vars.yaml

tasks:

- name: Drop Db2 Instance
when: inventory_hostname == groups['db2_hosts'][0]
command:
cmd: /opt/ibm/db2/instance/db2idrop db2inst1
removes: /home/db2inst1/sqllib

- name: Uninstall Db2
command:
cmd: /opt/ibm/db2/install/db2_deinstall -a
removes: /opt/ibm/db2

12 changes: 12 additions & 0 deletions ansible/dpf/playbooks/nfs_client_shared_home.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
- name: Install NFS package
dnf:
name: nfs-utils
state: latest

- name: Mount shared home
mount:
path: /home/db2inst1
src: "{{ groups['db2_hosts'][0] }}{{':'}}{{ shared_home_export }}"
fstype: nfs
opts: rw,sync,hard,nofail
state: mounted
68 changes: 68 additions & 0 deletions ansible/dpf/playbooks/nfs_server_shared_home.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
- name: Install NFS package
dnf:
name: nfs-utils
state: latest

- name: Stop NFS server
systemd:
name: nfs-server
state: stopped

- name: Create filesystem on shared home
filesystem:
dev: "{{ shared_home_dev }}"
fstype: xfs
opts: "-L SHARED_HOME"

- name: Mount shared home export
mount:
path: "{{ shared_home_export }}"
src: "{{ shared_home_dev }}"
fstype: xfs
opts: defaults,nofail
state: mounted

# XXX db2inst1 should be created by this point
- name: Set permissions on shared home export
file:
path: "{{ shared_home_export }}"
owner: db2inst1
group: db2inst1

- name: Initialize db2inst1 home directory
copy:
src: /etc/skel/
dest: /home/db2inst1
force: false
owner: db2inst1
group: db2inst1

- name: Generate ssh key for db2inst1
user:
name: db2inst1
uid: 5000
create_home: false
generate_ssh_key: true

- name: Setup /etc/exports
blockinfile:
path: /etc/exports
create: true
insertafter: EOF
block: |
{% for host in groups['db2_hosts'] %}
{{ shared_home_export }} {{ host }}{{ '(rw,no_root_squash)' }}
{% endfor %}

- name: Add firewall rule for NFS server
firewalld:
state: enabled
service: nfs
permanent: yes
immediate: yes

- name: Setup NFS server
systemd:
name: nfs-server
state: restarted
enabled: false
Loading