Difference between revisions of "Install Rundeck on RockyLinux with Ansible"

From Bitbull Wiki
Jump to navigation Jump to search
Line 1: Line 1:
=Install Rundeck on Alma Linux 8 with Ansible=
 
Setup Rundeck with native Ansible integration for Windows and Linux with Dynamic Inventory
 
* OS: Alma Linux 8.6
 
* Hostname: rundeck01.domain.tld
 
* vMemory: 6GB
 
* vDisk: 40GB
 
* vCPU: 6
 
  
==SETUP RUNDECK SERVER==
+
=Setup Rundeck=
* vi /etc/ansible/playbooks/setup-rundeck.yml
+
* 4vCPU
 +
* 8 GB Memory
 +
* 50 GB HDD
 +
 
 
<pre>
 
<pre>
 +
vi setup-rundeck.yml
 +
---------------------------------
 
---
 
---
- hosts: rundeck01.domain.tld
+
- hosts: srundeck01.domain.local
 
   vars:
 
   vars:
     rundeck_admin_pass: xxxxxx
+
     rundeck_admin_pass: ***
 +
    # more vars as needed: look into role defaults
 
   roles:
 
   roles:
 
   - role: joe-speedboat.rundeck
 
   - role: joe-speedboat.rundeck
Line 26: Line 25:
 
       enabled: yes
 
       enabled: yes
 
       state: started
 
       state: started
  - name: open http port on firewalld
 
    firewalld:
 
      service: http
 
      permanent: true
 
      state: enabled
 
 
   - name: open https port on firewalld
 
   - name: open https port on firewalld
 
     firewalld:
 
     firewalld:
Line 42: Line 36:
 
       state: restarted
 
       state: restarted
 
...
 
...
</pre>
+
---------------------------------
 +
 
 +
ansible -m shell -a id srundeck01.domain.local
 +
ansible-playbook setup-rundeck.yml
 +
<pre>
  
ansible -m shell -a id rundeck01.domain.tld
+
* Now test rundeck login as admin with your WebBrowser
ansible-playbook setup-rundeck.yml
 
  
* Test webUI login
+
=COMPANY specific settings=
 +
sed -i 's/^mirrorlist=\(.*\)/# mirrorlist=\1/' /etc/yum.repos.d/*.repo
 +
sed -i 's/^#baseurl=/baseurl=/' /etc/yum.repos.d/*.repo
  
==BASIC SETUP==
+
=General settings=
  
 
  echo '#!/bin/sh
 
  echo '#!/bin/sh
Line 56: Line 55:
 
  chmod 755 /usr/local/bin/backup
 
  chmod 755 /usr/local/bin/backup
  
dnf -y install epel-release
+
=Ansible installation=
dnf -y install git wget curl rsync vim
+
<pre>
 +
# root user
 +
dnf -y remove ansible-collection-ansible-posix ansible
 +
dnf -y install python38-pip python38 git wget curl rsync vim sshpass
  
==SETUP ANSIBLE==
+
# rundeck user
dnf -y install python38-pip python38 sshpass
+
python3.8 -m pip install --user ansible
 
 
<pre>
 
su - rundeck
 
python3.8 -m pip install --user ansible pywinrm
 
 
 
echo '#ANSIBLE SETUP
 
echo '#ANSIBLE SETUP
 
export PATH=$HOME/.local/bin:$HOME/bin:$PATH
 
export PATH=$HOME/.local/bin:$HOME/bin:$PATH
 
' >> $HOME/.bashrc
 
' >> $HOME/.bashrc
 
 
ln -s $HOME/.local/bin $HOME/bin
 
ln -s $HOME/.local/bin $HOME/bin
 
cat /etc/skel/.bash_profile > $HOME/.bash_profile
 
cat /etc/skel/.bash_profile > $HOME/.bash_profile
 
exit
 
exit
</pre>
 
 
chown -R root.rundeck /etc/ansible
 
chmod -R ug+rwX /etc/ansible
 
  
* you can upgrade existing installation with
+
# root user
pip3.8 freeze > r.txt
+
chown -R rundeck.rundeck /etc/ansible
pip3.8 install -r r.txt --upgrade
+
chmod -R u+rwX,go-rwx /etc/ansible
rm -f r.txt
 
  
<pre>
+
# rundeck user
su - rundeck
 
 
cd /etc/ansible
 
cd /etc/ansible
 
rm -fv hosts
 
rm -fv hosts
Line 97: Line 87:
  
 
mkdir /etc/ansible/inventory/group_vars
 
mkdir /etc/ansible/inventory/group_vars
 +
vim /etc/ansible/inventory/group_vars/all.yml
 +
----------
 +
ansible_become: True
 +
ansible_user: deploy_rundeck_prod
 +
----------
 
</pre>
 
</pre>
  
* vim /etc/ansible/inventory/group_vars/all.yml
+
=USE AND PROTECT ANSIBLE VARS WITH VAULT=
# Ansible Linux client defaults
+
<pre>
ansible_become: True
+
# root user
ansible_user: rundeck-ops
+
curl https://raw.githubusercontent.com/joe-speedboat/shell.scripts/master/vault-unlock.sh > $HOME/bin/vault-unlock.sh
 +
chown rundeck.rundeck $HOME/bin/vault-unlock.sh
 +
chmod 700 $HOME/bin/vault-unlock.sh
 +
sed -i "s#^.vault_password_file=.*#vault_password_file=$HOME/bin/vault-unlock.sh#" ansible.cfg
 +
 
 +
# we do not start this services after reboot, we do this with vault unlock
 +
systemctl disable rundeckd nginx
  
* We need localhost exeption if we use variables for all
+
vim /usr/local/sbin/init-rundeck-and-ansible.sh
echo 'localhost ansible_become=False ansible_connection=local' > /etc/ansible/inventory/localhost
+
----------
 +
#!/bin/bash
 +
echo
 +
echo Feed the ssh private key passphrase for rundeck
 +
echo "Hashi Vault > linuxeng_kv > application_user > ansible_vault_pw@srundeck01.domain.local"
  
 +
sudo -u rundeck --login echo
 +
echo
 +
echo INFO: re/starting rundeck + nginx service
 +
systemctl restart rundeckd nginx
 +
echo
 +
echo
 +
echo All done
 +
echo Now login to rundeck webUI:
 +
echo .Test the inventory
 +
echo .Test AdHoc command
 +
----------
 +
chmod 700 /usr/local/sbin/init-rundeck-and-ansible.sh
  
 +
echo '
 +
#FEED ANSIBLE VAULT AND SSH-KEY PASSWORD after reboot
 +
  cmd: init-rundeck-and-ansible.sh
 +
' >> /etc/motd
  
* vim /etc/ansible/inventory/win.yml
+
# rundeck user
<pre>
+
echo '. $HOME/bin/vault-unlock.sh -b' > ~/.bashrc
all:
 
  hosts:
 
  children:
 
    win:
 
      hosts:
 
        win01:
 
 
</pre>
 
</pre>
  
* vim /etc/ansible/inventory/group_vars/win.yml
+
=ZABBIX CHECK FOR LOCKED VAULTS=
 
<pre>
 
<pre>
ansible_user: winrm
+
# root user
ansible_password: xxxxxx
+
vim /etc/zabbix/zabbix_agent2.d/rundeck-ssh-add.conf
ansible_become: False
+
----------
ansible_connection: winrm
+
AllowKey=system.run[sudo --login -u rundeck ssh-add -l]
ansible_winrm_server_cert_validation: ignore
+
DenyKey=system.run[*]
ansible_shell_type: powershell
+
----------
</pre>
+
chown root.zabbix /etc/zabbix/zabbix_agent2.d/rundeck-ssh-add.conf
 +
chmod 640 /etc/zabbix/zabbix_agent2.d/rundeck-ssh-add.conf
  
ansible-galaxy role install joe-speedboat.ansible_ospatch
+
vim /etc/sudoers.d/zabbix_agent_checks
ls -l /etc/ansible/roles/joe-speedboat.ansible_ospatch
+
----------
 +
Defaults:zabbix !requiretty
 +
Cmnd_Alias ZABBIX_CMD = /bin/bash -c ssh-add -l
 +
zabbix  ALL=(rundeck) NOPASSWD:ZABBIX_CMD
 +
----------
 +
systemctl restart zabbix-agent2
 +
systemctl status zabbix-agent2
  
ansible-galaxy collection install community.mysql
 
ls -l /etc/ansible/collections/ansible_collections/community/mysql
 
  
 +
* Create Zabbix Check Item
 +
  Name: ssh-agent
 +
  Type: Zabbix Agent
 +
  Key: system.run["sudo --login -u rundeck ssh-add -l"]
 +
  Type: Text
 +
  Preprocessing:
 +
    Name: Regular Expression
 +
    Search: .*(RSA|ERROR).*
 +
    Replace: \1
 +
    Type: Text
  
 
+
* Create Zabbix Trigger for this Item
 
+
  Name: Rundeck is locked
 
+
  Severity: Disaster
==USE AND PROTECT ANSIBLE VARS WITH VAULT==
+
  Expression: last(/srundeck01.domain.local/system.run["sudo --login -u rundeck ssh-add -l"])="ERROR"
 
+
  Allow manual close: FALSE
sed -i 's#^.vault_password_file=.*#vault_password_file=/etc/ansible/vault_unlock#' ansible.cfg
+
  Description:
 
+
    Ansible Vault and SSH keys on host are locked.
* create vault unlock helper which can store passwords until next reboot
+
    Please login as root and execute: init-rundeck-and-ansible.sh
<pre>
 
echo '#!/bin/bash
 
NAME=vault
 
PW_CNT=$(keyctl search @u user $NAME 2>/dev/null | wc -l)
 
if [ $PW_CNT -lt 1 ]
 
then
 
  read -s -p "Feed vault password: " PASS
 
  keyctl add user $NAME  "$PASS" @u >/dev/null 2>&1
 
  echo
 
else
 
  keyctl print $(keyctl search @u user $NAME 2>/dev/null)
 
fi' > /etc/ansible/vault_unlock
 
 
</pre>
 
</pre>
  
chmod 700 /etc/ansible/vault_unlock
+
=FREEIPA INVENTORY=
 
 
/etc/ansible/vault_unlock
 
Feed and remember the password for vault<br>
 
Call it again to get the password shown
 
 
 
* Create motd hint
 
 
<pre>
 
<pre>
echo '
+
# rundeck user
#FEED ANSIBLE VAULT PASSWORD after reboot
+
curl https://raw.githubusercontent.com/joe-speedboat/ansible.idm-inventory/main/inventory/freeipa.py > inventory/freeipa.py
  cmd: sudo -u rundeck --login /etc/ansible/vault_unlock
+
chmod 700 inventory/freeipa.py
' >> /etc/motd
+
python3.8 -m pip install --user python_freeipa
</pre>
 
 
 
 
 
cat /etc/ansible/inventory/group_vars/win.yml
 
See it is plain
 
 
 
* crypt your sensible data
 
ansible-vault encrypy /etc/ansible/inventory/group_vars/win.yml
 
 
 
 
 
cat /etc/ansible/inventory/group_vars/win.yml
 
It is crypted now
 
 
 
* Edit it
 
ansible-vault edit /etc/ansible/inventory/group_vars/win.yml
 
 
 
 
 
 
 
 
 
  
==FREEIPA INVENTORY==
 
 
su - rundeck
 
curl https://raw.githubusercontent.com/joe-speedboat/ansible.idm-inventory/main/inventory/freeipa.py > inventory/freeipa.py
 
chmod 700 inventory/freeipa.py
 
 
<pre>
 
 
echo '# FreeIPA Ansible Inventory Auth
 
echo '# FreeIPA Ansible Inventory Auth
export freeipaserver=directory01.domain.tld
+
# FreeIPA Ansible Inventory Auth
export freeipauser=rundeck-bind
+
export freeipaserver=freeipa01.domain.local
export freeipapassword=xxxxx
+
export freeipauser='svc_bind_rundeck_prod'
 +
export freeipapassword='******'
 
' >> $HOME/.bashrc
 
' >> $HOME/.bashrc
 
</pre>
 
</pre>
  
. $HOME/.bashrc
+
=RUNDECK FREEIPA AUTH=
python3.8 -m pip install --user python_freeipa
+
<pre>
 
 
 
 
 
 
==FREEIPA AUTH==
 
  
* vim /etc/rundeck/multiauth.conf
+
vim /etc/rundeck/multiauth.conf
<pre>
+
--------------------------------
 
multiauth {
 
multiauth {
  
Line 218: Line 201:
 
     debug="true"
 
     debug="true"
 
     contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
 
     contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
     providerUrl="ldaps://directory01.domain.tld:636"
+
     providerUrl="ldaps://freeipa01.domain.local:636 ldaps://freeipa02.domain.local:636"
     bindDn="uid=rundeck-bind,cn=users,cn=accounts,dc=domain,dc=tld"
+
    ldapsVerifyHostname="false"
     bindPassword="xxx"
+
     bindDn="uid=svc_bind_rundeck_prod,cn=users,cn=accounts,dc=domain,dc=local"
 +
     bindPassword="******"
 
     authenticationMethod="simple"
 
     authenticationMethod="simple"
 
     forceBindingLogin="true"
 
     forceBindingLogin="true"
     userBaseDn="cn=users,cn=accounts,dc=domain,dc=tld"
+
     userBaseDn="cn=users,cn=accounts,dc=domain,dc=local"
 
     userRdnAttribute="uid"
 
     userRdnAttribute="uid"
 
     userIdAttribute="uid"
 
     userIdAttribute="uid"
Line 231: Line 215:
 
     userFirstNameAttribute="givenName"
 
     userFirstNameAttribute="givenName"
 
     userEmailAttribute="mail"
 
     userEmailAttribute="mail"
 
+
     roleBaseDn="cn=groups,cn=accounts,dc=domain,dc=local"
     roleBaseDn="cn=groups,cn=accounts,dc=domain,dc=tld"
 
 
     roleNameAttribute="cn"
 
     roleNameAttribute="cn"
 
     roleMemberAttribute="member"
 
     roleMemberAttribute="member"
Line 243: Line 226:
 
     file="/etc/rundeck/realm.properties";
 
     file="/etc/rundeck/realm.properties";
 
};
 
};
</pre>
+
--------------------------------
 +
 
 +
chown root.rundeck /etc/rundeck/multiauth.conf
 +
chmod 640 /etc/rundeck/multiauth.conf
 +
 
  
chown root.rundeck /etc/rundeck/multiauth.conf
+
vim /etc/rundeck/rundeck-config.properties
chmod 640 /etc/rundeck/multiauth.conf
+
--------------------------------
 +
rundeck.security.syncLdapUser=true
 +
--------------------------------
  
 +
vim /etc/sysconfig/rundeckd
 +
--------------------------------
 +
JAAS_LOGIN=true
 +
LOGIN_MODULE=multiauth
 +
JAAS_CONF=/etc/rundeck/multiauth.conf
 +
--------------------------------
  
* vim /etc/rundeck/rundeck-config.properties
 
rundeck.security.syncLdapUser=true
 
  
  
* vim /etc/sysconfig/rundeckd
+
vim /etc/rundeck/ansibleadm.aclpolicy
JAAS_LOGIN=true
+
-------------------------------
LOGIN_MODULE=multiauth
+
description: FreeIPA Rundeck Admin, all access.
JAAS_CONF=/etc/rundeck/multiauth.conf
 
 
* vim /etc/rundeck/ansibleadmin.aclpolicy
 
<pre>
 
description: Admin, all access.
 
 
context:
 
context:
 
   project: '.*' # all projects
 
   project: '.*' # all projects
Line 273: Line 261:
 
     - allow: '*' # allow read/run for all nodes
 
     - allow: '*' # allow read/run for all nodes
 
by:
 
by:
   group: ansibleadmin
+
   group: rundeckadm
 
 
 
---
 
---
 
+
description: FreeIPA Rundeck Admin, all access.
description: Admin, all access.
 
 
context:
 
context:
 
   application: 'rundeck'
 
   application: 'rundeck'
Line 290: Line 276:
 
     - allow: '*' # allow read/create/update/delete for all /keys/* storage content
 
     - allow: '*' # allow read/create/update/delete for all /keys/* storage content
 
by:
 
by:
   group: ansibleadmin
+
   group: rundeckadm
</pre>
+
-----------------------------
 
+
chown root.rundeck /etc/rundeck/ansibleadm.aclpolicy
chown root.rundeck /etc/rundeck/ansibleadmin.aclpolicy
+
chmod 640 /etc/rundeck/ansibleadm.aclpolicy
chmod 640 /etc/rundeck/ansibleadmin.aclpolicy
 
 
 
 
 
echo | openssl s_client -showcerts -connect directory01.domain.tld:636 > /etc/rundeck/ssl/directory01_ldaps.pem
 
vim /etc/rundeck/ssl/directory01_ldaps.pem # remove comments
 
cp -av /etc/pki/ca-trust/extracted/java/cacerts /etc/pki/ca-trust/extracted/java/cacerts.orig
 
keytool -import -alias directory01.domain.tld -file /etc/rundeck/ssl/directory01_ldaps.pem -keystore /etc/pki/ca-trust/extracted/java/cacerts -storepass changeit
 
 
 
keytool -import -alias directory01.domain.tld -file /etc/rundeck/ssl/directory01_ldaps.pem -keystore /etc/rundeck/ssl/truststore -storepass adminadmin
 
chown rundeck.rundeck /etc/rundeck/ssl/*
 
 
 
==PROTECT SSH PRIVATE KEY==
 
dnf -y install keychain
 
su - rundeck
 
ssh-keygen -p # change passphrase
 
  
echo '# remember ssh passphrase until next reboot
+
echo | openssl s_client -showcerts -connect freeipa01.domain.local:636 > /etc/rundeck/ssl/idm.pem
keychain -Q -q ~/.ssh/id_rsa < /dev/null
+
vim /etc/rundeck/ssl/idm.pem # remove comments
[ -f $HOME/.keychain/$HOSTNAME-sh ] && source $HOME/.keychain/$HOSTNAME-sh
+
cp -av /etc/pki/ca-trust/extracted/java/cacerts /etc/pki/ca-trust/extracted/java/cacerts.orig
' >> $HOME/.bashrc
+
keytool -import -alias idm -file /etc/rundeck/ssl/idm.pem -keystore /etc/pki/ca-trust/extracted/java/cacerts -storepass changeit
  
<pre>
+
keytool -import -alias idm -file /etc/rundeck/ssl/idm.pem -keystore /etc/rundeck/ssl/truststore -storepass adminadmin
echo '#!/bin/bash
+
chown rundeck.rundeck /etc/rundeck/ssl/*
echo
 
echo Now feed the ssh private key passphrase for rundeck
 
sudo -u rundeck --login exit
 
echo
 
echo INFO: restarting rundeck service
 
systemctl restart rundeckd
 
echo
 
echo
 
echo All done
 
echo Now login to rundeck webUI:
 
echo .Test the inventory
 
echo .Test AdHoc command
 
' > /usr/local/sbin/init-rundeck-and-ansible.sh
 
 
</pre>
 
</pre>
  
chmod 700 /usr/local/sbin/init-rundeck-and-ansible.sh
+
=RUNDECK ANSIBLE PROJECT EXAMPLE=
 
 
echo '
 
#FEED RUNDECKs SSH PASSPHRASE AFTER EACH REBOOT
 
    cmd: init-rundeck-and-ansible.sh
 
' >> /etc/motd
 
 
 
reboot
 
 
 
 
 
 
 
 
 
 
 
==RUNDECK PROJECT: ansible==
 
 
<pre>
 
<pre>
 +
PROJECT: ansible
 +
--------------------------------------------------------
 
Detail:
 
Detail:
 
   Project Name: ansible
 
   Project Name: ansible
Line 362: Line 309:
 
   Type: local
 
   Type: local
 
   We just use native ansible, this is not needed
 
   We just use native ansible, this is not needed
</pre>
 
  
* PROJECT: ansible > Edit Nodes > Sources > Add
 
:* Type: Ansible Resource Model Source
 
:* Ansible config file path: /etc/ansible/ansible.cfg
 
  
 +
PROJECT: ansible > Edit Nodes > Sources > Add
 +
--------------------------------------------------------
 +
Type: Ansible Resource Model Source
 +
Ansible config file path: /etc/ansible/ansible.cfg
 +
</pre>
  
==BUGS & FIXES==
+
=BUGS & FIXES=
  
 
* Error Msg: /bin/sh: /tmp/0-1-localhost-dispatch-script.tmp.sh: Permission denied
 
* Error Msg: /bin/sh: /tmp/0-1-localhost-dispatch-script.tmp.sh: Permission denied
Line 375: Line 323:
 
echo '
 
echo '
 
# ----------------------------------------------------------------
 
# ----------------------------------------------------------------
# User Defined Values
+
# CUSTOM VALUES
 
# ----------------------------------------------------------------
 
# ----------------------------------------------------------------
 
framework.file-copy-destination-dir = ~/
 
framework.file-copy-destination-dir = ~/
Line 386: Line 334:
 
[[Category:Ansible]]
 
[[Category:Ansible]]
 
[[Category:Linux]]
 
[[Category:Linux]]
 +
[[Category:CentOS8]]

Revision as of 13:40, 23 September 2022

1 Setup Rundeck

  • 4vCPU
  • 8 GB Memory
  • 50 GB HDD
vi setup-rundeck.yml
---------------------------------
---
- hosts: srundeck01.domain.local
  vars:
    rundeck_admin_pass: ***
    # more vars as needed: look into role defaults
  roles:
  - role: joe-speedboat.rundeck
  tasks:
  - name: install firewalld
    yum:
      name: firewalld
      state: present
  - name: start firewalld
    service:
      name: firewalld
      enabled: yes
      state: started
  - name: open https port on firewalld
    firewalld:
      service: https
      permanent: true
      state: enabled
  - name: enable firewalld
    service:
      name: firewalld
      enabled: yes
      state: restarted
...
---------------------------------

ansible -m shell -a id srundeck01.domain.local
ansible-playbook setup-rundeck.yml
<pre>

* Now test rundeck login as admin with your WebBrowser

=COMPANY specific settings=
 sed -i 's/^mirrorlist=\(.*\)/# mirrorlist=\1/' /etc/yum.repos.d/*.repo
 sed -i 's/^#baseurl=/baseurl=/' /etc/yum.repos.d/*.repo

=General settings=

 echo '#!/bin/sh
 cp -av "$1" "$1.$(date +%Y%m%H%M%S)"
 ' > /usr/local/bin/backup
 chmod 755 /usr/local/bin/backup

=Ansible installation=
<pre>
# root user
dnf -y remove ansible-collection-ansible-posix ansible
dnf -y install python38-pip python38 git wget curl rsync vim sshpass

# rundeck user
python3.8 -m pip install --user ansible
echo '#ANSIBLE SETUP
export PATH=$HOME/.local/bin:$HOME/bin:$PATH
' >> $HOME/.bashrc
ln -s $HOME/.local/bin $HOME/bin
cat /etc/skel/.bash_profile > $HOME/.bash_profile
exit

# root user
chown -R rundeck.rundeck /etc/ansible
chmod -R u+rwX,go-rwx /etc/ansible

# rundeck user
cd /etc/ansible
rm -fv hosts
ansible-config init --disabled > ansible.cfg
sed -i 's/^.host_key_checking=.*/host_key_checking=False/' ansible.cfg
# sed -i 's/^.remote_user=.*/remote_user=rundeck-ops/' ansible.cfg
# sed -i 's/^.become=.*/become=True/' ansible.cfg
sed -i 's#^.inventory=.*#inventory=/etc/ansible/inventory #' ansible.cfg
sed -i 's#^.collections_path=.*#collections_path=/etc/ansible/collections:/usr/share/ansible/collections#' ansible.cfg
sed -i 's#^.roles_path=.*#roles_path=/etc/ansible/roles#' ansible.cfg
sed -i 's#^.interpreter_python=.*#interpreter_python=auto_silent#' ansible.cfg

mkdir /etc/ansible/inventory/group_vars
vim /etc/ansible/inventory/group_vars/all.yml
----------
ansible_become: True
ansible_user: deploy_rundeck_prod
----------

2 USE AND PROTECT ANSIBLE VARS WITH VAULT

# root user
curl https://raw.githubusercontent.com/joe-speedboat/shell.scripts/master/vault-unlock.sh > $HOME/bin/vault-unlock.sh
chown rundeck.rundeck $HOME/bin/vault-unlock.sh
chmod 700 $HOME/bin/vault-unlock.sh
sed -i "s#^.vault_password_file=.*#vault_password_file=$HOME/bin/vault-unlock.sh#" ansible.cfg

# we do not start this services after reboot, we do this with vault unlock
systemctl disable rundeckd nginx

vim /usr/local/sbin/init-rundeck-and-ansible.sh
----------
#!/bin/bash
echo
echo Feed the ssh private key passphrase for rundeck
echo "Hashi Vault > linuxeng_kv > application_user > ansible_vault_pw@srundeck01.domain.local"

sudo -u rundeck --login echo
echo
echo INFO: re/starting rundeck + nginx service
systemctl restart rundeckd nginx
echo
echo
echo All done
echo Now login to rundeck webUI:
echo .Test the inventory 
echo .Test AdHoc command
----------
chmod 700 /usr/local/sbin/init-rundeck-and-ansible.sh

echo '
#FEED ANSIBLE VAULT AND SSH-KEY PASSWORD after reboot
   cmd: init-rundeck-and-ansible.sh
' >> /etc/motd

# rundeck user
echo '. $HOME/bin/vault-unlock.sh -b' > ~/.bashrc

3 ZABBIX CHECK FOR LOCKED VAULTS

# root user
vim /etc/zabbix/zabbix_agent2.d/rundeck-ssh-add.conf
----------
AllowKey=system.run[sudo --login -u rundeck ssh-add -l]
DenyKey=system.run[*]
----------
chown root.zabbix /etc/zabbix/zabbix_agent2.d/rundeck-ssh-add.conf
chmod 640 /etc/zabbix/zabbix_agent2.d/rundeck-ssh-add.conf

vim /etc/sudoers.d/zabbix_agent_checks 
----------
Defaults:zabbix !requiretty
Cmnd_Alias ZABBIX_CMD = /bin/bash -c ssh-add -l
zabbix   ALL=(rundeck) NOPASSWD:ZABBIX_CMD
----------
systemctl restart zabbix-agent2
systemctl status zabbix-agent2


* Create Zabbix Check Item
  Name: ssh-agent
  Type: Zabbix Agent
  Key: system.run["sudo --login -u rundeck ssh-add -l"]
  Type: Text
  Preprocessing:
    Name: Regular Expression
    Search: .*(RSA|ERROR).*
    Replace: \1
    Type: Text

* Create Zabbix Trigger for this Item
  Name: Rundeck is locked
  Severity: Disaster
  Expression: last(/srundeck01.domain.local/system.run["sudo --login -u rundeck ssh-add -l"])="ERROR"
  Allow manual close: FALSE
  Description:
    Ansible Vault and SSH keys on host are locked.
    Please login as root and execute: init-rundeck-and-ansible.sh

4 FREEIPA INVENTORY

# rundeck user
curl https://raw.githubusercontent.com/joe-speedboat/ansible.idm-inventory/main/inventory/freeipa.py > inventory/freeipa.py
chmod 700 inventory/freeipa.py
python3.8 -m pip install --user python_freeipa

echo '# FreeIPA Ansible Inventory Auth
# FreeIPA Ansible Inventory Auth
export freeipaserver=freeipa01.domain.local
export freeipauser='svc_bind_rundeck_prod'
export freeipapassword='******'
' >> $HOME/.bashrc

5 RUNDECK FREEIPA AUTH


vim /etc/rundeck/multiauth.conf
--------------------------------
multiauth {

  com.dtolabs.rundeck.jetty.jaas.JettyCachingLdapLoginModule sufficient
    debug="true"
    contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
    providerUrl="ldaps://freeipa01.domain.local:636 ldaps://freeipa02.domain.local:636"
    ldapsVerifyHostname="false"
    bindDn="uid=svc_bind_rundeck_prod,cn=users,cn=accounts,dc=domain,dc=local"
    bindPassword="******"
    authenticationMethod="simple"
    forceBindingLogin="true"
    userBaseDn="cn=users,cn=accounts,dc=domain,dc=local"
    userRdnAttribute="uid"
    userIdAttribute="uid"
    userPasswordAttribute="userPassword"
    userObjectClass="posixAccount"
    userLastNameAttribute="sn"
    userFirstNameAttribute="givenName"
    userEmailAttribute="mail"
    roleBaseDn="cn=groups,cn=accounts,dc=domain,dc=local"
    roleNameAttribute="cn"
    roleMemberAttribute="member"
    roleObjectClass="groupOfNames"
    cacheDurationMillis="300000"
    reportStatistics="true";

  org.eclipse.jetty.jaas.spi.PropertyFileLoginModule required
    debug="true"
    file="/etc/rundeck/realm.properties";
};
--------------------------------

chown root.rundeck /etc/rundeck/multiauth.conf
chmod 640 /etc/rundeck/multiauth.conf


vim /etc/rundeck/rundeck-config.properties
--------------------------------
rundeck.security.syncLdapUser=true
--------------------------------

vim /etc/sysconfig/rundeckd
--------------------------------
JAAS_LOGIN=true
LOGIN_MODULE=multiauth
JAAS_CONF=/etc/rundeck/multiauth.conf
--------------------------------



vim /etc/rundeck/ansibleadm.aclpolicy
-------------------------------
description: FreeIPA Rundeck Admin, all access.
context:
  project: '.*' # all projects
for:
  resource:
    - allow: '*' # allow read/create all kinds
  adhoc:
    - allow: '*' # allow read/running/killing adhoc jobs
  job: 
    - allow: '*' # allow read/write/delete/run/kill of all jobs
  node:
    - allow: '*' # allow read/run for all nodes
by:
  group: rundeckadm
---
description: FreeIPA Rundeck Admin, all access.
context:
  application: 'rundeck'
for:
  resource:
    - allow: '*' # allow create of projects
  project:
    - allow: '*' # allow view/admin of all projects
  project_acl:
    - allow: '*' # allow admin of all project-level ACL policies
  storage:
    - allow: '*' # allow read/create/update/delete for all /keys/* storage content
by:
  group: rundeckadm
-----------------------------
chown root.rundeck /etc/rundeck/ansibleadm.aclpolicy
chmod 640 /etc/rundeck/ansibleadm.aclpolicy

echo | openssl s_client -showcerts -connect freeipa01.domain.local:636 > /etc/rundeck/ssl/idm.pem
vim /etc/rundeck/ssl/idm.pem # remove comments
cp -av /etc/pki/ca-trust/extracted/java/cacerts /etc/pki/ca-trust/extracted/java/cacerts.orig
keytool -import -alias idm -file /etc/rundeck/ssl/idm.pem -keystore /etc/pki/ca-trust/extracted/java/cacerts -storepass changeit

keytool -import -alias idm -file /etc/rundeck/ssl/idm.pem -keystore /etc/rundeck/ssl/truststore -storepass adminadmin
chown rundeck.rundeck /etc/rundeck/ssl/*

6 RUNDECK ANSIBLE PROJECT EXAMPLE

PROJECT: ansible
--------------------------------------------------------
Detail:
   Project Name: ansible
   Label: ansible_linux_ssh
Execution History Clean: 
   Enable: [X]
User Interface :
   Job Group Expansion Level: 9
Default Node Executor:
  Type: Ansible Ad-Hoc Node Executor
     Executable: /bin/bash
     Windows Executable: powershell.exe
     Ansible config file path: /etc/ansible/ansible.cfg
Default File Copier:
  Type: local
  We just use native ansible, this is not needed


PROJECT: ansible > Edit Nodes > Sources > Add
--------------------------------------------------------
Type: Ansible Resource Model Source
Ansible config file path: /etc/ansible/ansible.cfg

7 BUGS & FIXES

  • Error Msg: /bin/sh: /tmp/0-1-localhost-dispatch-script.tmp.sh: Permission denied
echo '
# ----------------------------------------------------------------
# CUSTOM VALUES
# ----------------------------------------------------------------
framework.file-copy-destination-dir = ~/
' >> /etc/rundeck/framework.properties

systemctl restart rundeckd