Ansible Howto

Aus Cactus Howto
Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

ansible first steps

documentation

installation ansible host

on ubuntu >= 18.04

sudo apt install ansible

on ubuntu older than 18.04 and debian (up to 9/stretch)

These systems ship with ansible versions older than 2.4. For apt module to work smoothly (e.g. autoremove) we really should have ansible 2.4 or above.

as root:
 echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" >> /etc/apt/sources.list
sudo apt-key adv --keyserver-options http-proxy=http://10.5.1.10:3128/ --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
sudo apt update
sudo apt upgrade
sudo apt install ansible

prepare a client for ansible usage

using user tim for ssh sessions, setting user up for sudo, ssh pub key auth

as root user

useradd -m tim -s /bin/bash
passwd tim

install sudo (as root, if sudo does not exist)

apt-get install sudo

add user to sudo group

grep sudo /etc/group
sudo:x:<id>:tim

allow sudo group to use all commands via sudo

grep sudo  /etc/sudoers
%sudo	ALL=(ALL:ALL) ALL

make sure root path is set correctly when executing command via sudo:

grep secure_path /etc/sudoers
Defaults  secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

this can be automated later (with ansible working) using the following adhoc command:

ansible all -m lineinfile -a "dest=/etc/sudoers state=present line='secure_path=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"'" -b -K

Install python (if it does not already exist)

 sudo apt install python

from here in user context

su - tim
mkdir /home/tim/.ssh
chmod 700 /home/tim/.ssh
echo "<ssh-public-key>" >> /home/tim/.ssh/authorized_keys
chmod 600 /home/tim/.ssh/authorized_keys

additional useful packages on clients

install acl package to make sure "become_user" works correctly in debian:

ansible debsrv1 -m package -a "name=acl state=present" -b -K

install python (needed for Fedora clients):

ansible debsrv1 -m package -a "name=python state=present" -b -K

initial ansible serverconfig

fill /etc/ansible/hosts

add all your hosts/groups to your /etc/ansible/hosts file


setup ssh shell

tim@spike-vm:~/ansi$ ssh-agent bash
tim@spike-vm:~/ansi$ ssh-add /home/tim/.ssh/id_rsa
Enter passphrase for /home/tim/.ssh/id_rsa: 
Identity added: /home/tim/.ssh/id_rsa (/home/tim/.ssh/id_rsa)
tim@spike-vm:~/ansi$

or better:

sudo apt install keychain

then add

eval `keychain --eval id_rsa`

to $HOME/.bashrc

Make ssh timeout resistant:

tim@spike-vm:~$ cat .ssh/config 
Host *
ServerAliveInterval 240

test client connectivity

tim@spike-vm:~/ansi$ ansible itchy -m ping
itchy | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
tim@spike-vm:~/ansi$


Logging

Ansible has built-in support for logging. Add the following lines to your ansible configuration file:

[defaults] 
log_path=/var/log/ansible.log

and then run

tim@spike-vm:~$ sudo touch /var/log/ansible.log
tim@spike-vm:~$ sudo chmod 666 /var/log/ansible.log

This simply logs the command line output to the file

Debugging

Use -v switch to see playbook stdout:

tim@spike-vm:~$ ansible-playbook ansi/update-upgrade.yml -K -v
Using /etc/ansible/ansible.cfg as config file
SUDO password: 
/etc/ansible/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
/etc/ansible/hosts did not meet script requirements, check plugin documentation if this is unexpected

PLAY [all] *******************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************
ok: [itchy]
...
TASK [.deb do dist-upgrade] **************************************************************************************************************************
ok: [gware] => {"changed": false, "msg": "Reading package lists...\nBuilding dependency tree...\nReading state information...\n0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.\n", "stderr": "", "stderr_lines": [], "stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\n0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.\n", "stdout_lines": ["Reading package lists...", "Building dependency tree...", "Reading state information...", "0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded."]}

ansible ad-hoc commands

execute commands on remote hosts

execute simple command

ansible spiegel -m command -a "ls -la"

execute command as root via sudo

ansible spiegel -m command -a "checkrestart" -b -K

restart service

ansible spiegel -m service -a "name=puppet state=restarted" -b -K

gather system information

display os version

ansible all -m setup -a "filter=ansible_lsb"

use case add file

use case add public key to authorized_keys

ansible all -m authorized_key -a "user=tim key='ssh-rsa AAAA...XXX == tim@hostname'"

use case edit file

Add alias in .bashrc

ansible "target host" -m lineinfile -a "dest=/home/tim/.bashrc create=yes state=present line='alias ll=\'ls -l\"

Add new user "newuser" to sudo group

ansible "target host" -m lineinfile -a "backrefs=yes dest=/etc/group regexp='^(sudo:x:27:)(.*)' line='\1newuser,\2'"

Change setting: remove (deprecated) settings in config file only on specific os versions

tim@spike-vm:~$ cat test.conf
abc=123
pfad=44
xcd=77
tim@spike-vm:~/ansi$ ansible-playbook -l debians /home/tim/ansi/comment-out-lines.yml -K -e "path=test.conf regex='pfad'"
tim@spike-vm:~$ cat test.conf
abc=123
# removed deprecated config line "pfad=44"
xcd=77

playbook:

tim@spike-vm:~$ cat /home/tim/ansi/comment-out-lines.yml 
---

# expects variable regex to contain the string that matches the start of the config line
# expects variable path to contain the filename
# limited to debian version >= 9
- hosts: all
  become: yes
  tasks:

  - name: comment out config line
    lineinfile:
         backup=yes
         state=present
         path={{ path }}
         regexp='^({{ regex }}.*)'
         backrefs=yes
         line='# removed deprecated config line "\1"'
    when: >
           ansible_distribution == 'Debian'
           and
           ansible_lsb.major_release|int >= 9
tim@spike-vm:~$ 

use case install package

Install package "acl":

ansible debsrv1 -m package -a "name=acl state=present" -b -K

simple ansible playbooks

use cases debian/ubuntu sys management using apt

update and upgrade packages

tim@spike-vm:~/ansi$ cat apt-update-upgrade.yml

---

- hosts: all
  become: yes
  tasks:
    - name: assert ansible version
      assert:
        that:
          - "{{ ansible_version.string is version_compare('2.4', '>=') }}"
        msg: Ansible 2.4 or above is required
    - name: .deb do dist-upgrade
      apt: >
         update_cache=yes
         cache_valid_time=1200
         upgrade=dist
         autoremove=yes
         purge=yes
      when: >
         ansible_distribution == 'Debian'
         or
         ansible_distribution == 'Ubuntu'


reboot / restart services that need it

For use of checkrestart, install package:

 sudo apt install needrestart

autoremove unused packages

This only works for ansible >=2.4.

tim@spike-vm:~/ansi$ ansible-playbook -l puppet apt-autoremove.yml -K
tim@spike-vm:~/ansi$ cat apt-autoremove.yml
---

- hosts: all
  become: yes
  tasks:
     - name: assert ansible version
       assert:
         that:
           - "{{ ansible_version.string is version_compare('2.4', '>=') }}"
         msg: Ansible 2.4 or above is required
     - name: Autoremove unused packages
       apt:
         autoremove: yes
       when: >
        ansible_distribution == 'Debian'
        or
        ansible_distribution == 'Ubuntu'

use case install apt package

tim@spike-vm:~/ansi$ ansible-playbook -l puppet apt-install.yml -K -e "package=apache2"
SUDO password: 

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [puppet]

TASK [install package "apache2"] ***********************************************
ok: [puppet]

PLAY RECAP *********************************************************************
puppet                     : ok=2    changed=0    unreachable=0    failed=0   
tim@spike-vm:~/ansi$ cat apt-install.yml 
---

- hosts: all
 become: yes
 tasks:
    - name: install package "Vorlage:Package"
      apt:
       name: "Vorlage:Package"
      when: >
       ansible_distribution == 'Debian'
       or
       ansible_distribution == 'Ubuntu'

use case change passwords for linux systems

To make password encryption work:

apt install python-passlib  

change password for your own user on all targets

tim@spike-vm:~/ansi$ ansible-playbook change-user-password.yml -l spike -K
SUDO password: 
Enter New Password: 
confirm Enter New Password: 

PLAY [all] ******************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************
ok: [spike]

TASK [Change password of calling user] **************************************************************************************************
changed: [spike]

PLAY RECAP ******************************************************************************************************************************
spike                      : ok=2    changed=1    unreachable=0    failed=0   

tim@spike-vm:~/ansi$ 

playbook:

tim@spike-vm:~/ansi$ cat change-user-password.yml 
---
- hosts: all
  become: yes
  gather_facts: yes

  vars_prompt:
    - name: "new_password"
      prompt: "Enter New Password"
      private: yes
      encrypt: "sha512_crypt"
      confirm: yes
      salt_size: 7

  tasks:
    - name: Change password of calling user
      user: name={{ lookup('env', 'USER') }} update_password=always password={{new_password}}
tim@spike-vm:~/ansi$ 

change root password

tim@spike-vm:~/ansi$ cat change-root-password.yml 
---
- hosts: all
  become: yes
  gather_facts: yes

  vars_prompt:
    - name: "new_password"
      prompt: "Enter New Password"
      private: yes
      encrypt: "sha512_crypt"
      confirm: yes
      salt_size: 7

  tasks:
    - name: Change password of root user
      user: name=root update_password=always password={{new_password}}
tim@spike-vm:~/ansi$ 

call with:

tim@spike-vm:~/ansi$ ansible-playbook change-root-password.yml -l puppet -K

ansible advanced topics

use case add firewall rule

iptables

check point R80 API

using ansible via cron in pull mode

see https://github.com/ansible/ansible-examples/blob/master/language_features/ansible_pull.yml

ansible tower / AWX

Documentation

Documentation setting up AWX: https://www.jeffgeerling.com/blog/2017/ansible-open-sources-ansible-tower-awx

  • prepare
tower-cli config host http://<old-awx-host.example.com>
tower-cli config username <user>
tower-cli config password <pass>

Backup & Restore

Backup and restore (or migration): https://github.com/autops/awx-migrate, https://github.com/ansible/awx/blob/devel/DATA_MIGRATION.md

Backup

tower-cli receive --all > assets.json

Restore

tower-cli send backup.json

Then add credentials manually as they are not part of the backup.