Difference between revisions of "Ansible Howto"
(42 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
* changing root passwords: https://www.redpill-linpro.com/sysadvent/2017/12/02/ansible-change-passwords.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 13: | 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-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 26: | Line 27: | ||
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 |
add user to sudo group |
||
grep sudo /etc/group |
grep sudo /etc/group |
||
Line 32: | Line 36: | ||
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 |
from here in user context |
||
Line 39: | 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 == |
||
Line 55: | Line 73: | ||
or better: |
or better: |
||
sudo apt install keychain |
sudo apt install keychain |
||
then add |
|||
echo "eval `keychain --eval id_rsa`" >>/home/tim/.bashrc |
|||
eval `keychain --eval id_rsa` |
|||
to $HOME/.bashrc |
|||
Make ssh timeout resistant: |
|||
tim@spike-vm:~$ cat .ssh/config |
|||
Host * |
|||
ServerAliveInterval 240 |
|||
=== test client connectivity === |
=== test client connectivity === |
||
Line 100: | Line 125: | ||
= ansible ad-hoc commands = |
= 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 === |
|||
display os version: |
|||
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 === |
|||
e.g. add public key to authorized_keys |
|||
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'" |
ansible all -m authorized_key -a "user=tim key='ssh-rsa AAAA...XXX == tim@hostname'" |
||
== use |
== use case edit file == |
||
=== Add alias in .bashrc === |
|||
ansible all -m lineinfile -a "dest=/etc/group regexp='^(users:x:100:)(.*)' line='\1ldapusername,\2 |
|||
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 |
|||
= ansible playbooks = |
= simple ansible playbooks = |
||
== use cases debian/ubuntu sys management using apt == |
== use cases debian/ubuntu sys management using apt == |
||
Line 145: | Line 224: | ||
ansible_distribution == 'Ubuntu' |
ansible_distribution == 'Ubuntu' |
||
</pre> |
</pre> |
||
=== reboot / restart services that need it === |
|||
For use of checkrestart, install package: |
|||
sudo apt install needrestart |
|||
=== autoremove unused packages === |
=== autoremove unused packages === |
||
Line 197: | Line 281: | ||
- name: install package "{{ package }}" |
- name: install package "{{ package }}" |
||
apt: |
apt: |
||
name: |
name: "{{ package }}" |
||
when: > |
when: > |
||
ansible_distribution == 'Debian' |
ansible_distribution == 'Debian' |
||
Line 208: | Line 292: | ||
apt install python-passlib |
apt install python-passlib |
||
=== |
=== change password for your own user on all targets === |
||
<pre> |
<pre> |
||
tim@spike-vm:~/ansi$ ansible-playbook change-user-password.yml -l spike -K |
tim@spike-vm:~/ansi$ ansible-playbook change-user-password.yml -l spike -K |
||
Line 283: | 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 16:39, 22 September 2019
ansible first steps
documentation
- 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 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.