Difference between revisions of "Ansible Howto"

From Cactus Howto
Jump to navigationJump to search
 
(78 intermediate revisions by the same user not shown)
Line 3: Line 3:
== documentation ==
== documentation ==
* https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html
* https://docs.ansible.com/ansible/latest/user_guide/intro_getting_started.html
* changing root passwords: https://www.redpill-linpro.com/sysadvent/2017/12/02/ansible-change-passwords.html


== installation ==
== installation ansible host ==
=== on ubuntu >= 18.04 ===
=== on ubuntu >= 18.04 ===
sudo apt install ansible
sudo apt install ansible
Line 12: Line 13:


<pre>
<pre>
as root:
sudo echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" >> /etc/apt/sources.list
echo "deb http://ppa.launchpad.net/ansible/ansible/ubuntu trusty main" >> /etc/apt/sources.list
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
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 update
sudo apt upgrade
sudo apt upgrade
Line 23: Line 24:
using user tim for ssh sessions, setting user up for sudo, ssh pub key auth
using user tim for ssh sessions, setting user up for sudo, ssh pub key auth


as root user
useradd -m tim -s /bin/bash
useradd -m tim -s /bin/bash
passwd tim
passwd tim

install sudo (as root, if sudo does not exist)
apt-get install sudo
add user to sudo group
grep sudo /etc/group
grep sudo /etc/group
sudo:x:<id>:tim
sudo:x:<id>:tim
allow sudo group to use all commands via sudo
grep sudo /etc/sudoers
grep sudo /etc/sudoers
%sudo ALL=(ALL:ALL) ALL
%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
su - tim
mkdir /home/tim/.ssh
mkdir /home/tim/.ssh
Line 34: Line 51:
echo "<ssh-public-key>" >> /home/tim/.ssh/authorized_keys
echo "<ssh-public-key>" >> /home/tim/.ssh/authorized_keys
chmod 600 /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 ==
== initial ansible serverconfig ==
Edit /etc/ansible/hosts
=== fill /etc/ansible/hosts ===
add all your hosts/groups to your /etc/ansible/hosts file



= ansible advanced topics =
=== 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:
<pre>
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."]}
</pre>

= 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:
<pre>
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:~$
</pre>
== 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 ==
== use cases debian/ubuntu sys management using apt ==

=== update and upgrade packages ===
tim@spike-vm:~/ansi$ cat apt-update-upgrade.yml
<pre>
---

- 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'
</pre>


=== 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.
This only works for ansible >=2.4.


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

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


<pre>
<pre>
tim@spike-vm:~/ansi$ cat apt-autoremove.yml
---
---


Line 52: Line 243:
become: yes
become: yes
tasks:
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
- name: Autoremove unused packages
apt:
apt:
Line 85: Line 281:
- name: install package "{{ package }}"
- name: install package "{{ package }}"
apt:
apt:
name: apache2
name: "{{ package }}"
when: >
when: >
ansible_distribution == 'Debian'
ansible_distribution == 'Debian'
Line 92: Line 288:


== use case change passwords for linux systems ==
== 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 ===
<pre>
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$
</pre>
playbook:
<pre>
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$
</pre>

=== change root password ===

<pre>
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$
</pre>

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

= ansible advanced topics =


== use case add firewall rule ==
== use case add firewall rule ==
Line 98: Line 367:


=== check point R80 API ===
=== 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.

Latest revision as of 17:39, 22 September 2019

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 "Template:Package"
      apt:
       name: "Template: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.