
В данной статье разберем более подробно такие понятия как: боки, условия и циклы в Playbook Ansible. Для начала вспомни два урока ранее:
Из которых мы воспользуемся готовым Playbook по установке Nginx, связкой "handlers и notify" и переменной "ansible_os_family".
1. Изучаем block и условия
Приступим:
sudo nano install_apache.yml
После создания файла, заполним его:
---
- name: Install Nginx
hosts: all
become: yes
tasks:
- name: Install Nginx of Debian 10
apt: name=nginx update_cache=yes state=latest
- name: Start Nginx and boot
service: name=nginx state=started enabled=yes
Изменим пакет Nginx на Apache, для наглядности. Так как под разными системами, к примеру Debian и CentOS, этот пакет имеет разное название и оператор установки (apt и yum). В итоге получим такой код:
---
- name: Install Apache
hosts: all
become: yes
vars:
source_file: ./index.html
destin_file: /var/www/html
tasks:
# 1. В этой части будет переменная которая определяет версию Linux в (п.3 и 4)
- name: Check version Linux
debug: var=ansible_os_family
# 2. Для установки на Debian и CentOS используем when: условия для (п.3 и 4)
# 3. Устанавливаем Apache на Debian где Apache=apache2 через apt
- name: Install Apache web Server Debian
apt: name=apache2 update_cache=yes state=latest
when: ansible_os_family== "Debian"
# 4. Устанавливаем Apache на CentOS где Apache=httpd через yum
- name: Install Apache web Server CentOS
yum: name=httpd update_cache=yes state=latest
when: ansible_os_family== "CentOS"
# 5. Блок отвечающий за копирование файлов в папку www на удаленном сервере из vars
- name: Copy files in www CentOS
copy: src={{ source_file }} dest={{ destin_file }}
notify: Restart Apache CentOS
- name: Copy files in www Debian
copy: src={{ source_file }} dest={{ destin_file }}
notify: Restart Apache Debian
# 6. Этот блок отвечает за запуск сервиса, для него так же используем when: условия
- name: Start CentOS
service: name=httpd state=started enabled=yes
when: ansible_os_family== "CentOS"
- name: Start Debian
service: name=apache2 state=started enabled=yes
when: ansible_os_family== "Debian"
# 7. Добавим handlers для указания якоря "Restart Apache CentOS/Debian", для п.5
handlers:
- name: Restart Apache CentOS
service: name=httpd state=restarted
- name: Restart Apache Debian
service: name=apache2 state=restarted
Подробнее о работе Playbook:
Переделаем тот же код блоками, с общим when:
---
- name: Install Apache
hosts: all
become: yes
vars:
source_file: ./testers.html
destin_file: /var/www/html
tasks:
- name: Check version Linux
debug: var=ansible_os_family
- block:
- name: Install Apache web Server Debian
apt: name=apache2 update_cache=yes state=latest
- name: Copy files in www Debian
copy: src={{ source_file }} dest={{ destin_file }}
notify: Restart Apache Debian
- name: Start Debian
service: name=apache2 state=started enabled=yes
when: ansible_os_family== "Debian"
when: ansible_os_family == "Debian"
- block:
- name: Install Apache web Server CentOS
yum: name=httpd update_cache=yes state=latest
- name: Copy files in www CentOS
copy: src={{ source_file }} dest={{ destin_file }}
notify: Restart Apache CentOS
- name: Start CentOS
service: name=httpd state=started enabled=yes
when: ansible_os_family== "CentOS"
when: ansible_os_family == "CentOS"
handlers:
- name: Restart Apache CentOS
service: name=httpd state=restarted
- name: Restart Apache Debian
service: name=apache2 state=restarted
Запускаем наш код (ВАЖНО: в нашем случае сервер только на Debian, поэтом установку на CentOS наш playbook пропустит):
ansible-playbook install_apache.yml
...
PLAY [Install Apache] **********************************
TASK [Gathering Facts] ********************************
ok: [debi]
TASK [Check version Linux] *****************************
ok: [debi] => {
"ansible_os_family": "Debian"
}
TASK [Install Apache web Server Debian] ******************
ok: [debi]
TASK [Copy files in www Debian] *************************
changed: [debi]
TASK [Start Debian] ***********************************
changed: [debi]
TASK [Install Apache web Server CentOS] ******************
skipping: [debi]
TASK [Copy files in www CentOS] *************************
skipping: [debi]
TASK [Start CentOS] ***********************************
skipping: [debi]
RUNNING HANDLER [Restart Apache Debian] ****************
changed: [debi]
PLAY RECAP ******************************************
debi : ok=6 changed=3 unreachable=0 failed=0
2. Циклы: with_Items, loop, with_file global, until
with_Items, loop
Для дальнейшего примера, мы обратимся к коду из этого урока:
Playbook: install Nginx + PHP-FPM. Lesson 4
---
- name: Install Nginx + repositories
hosts: all
become: yes
tasks:
- name: download PGP-key
get_url:
url: http://nginx.org/keys/nginx_signing.key
dest: /etc/nginx_signing.key
- name: install PGP-key
apt_key:
file: /etc/nginx_signing.key
state: present
- name: Add Nginx Repo deb
apt_repository:
repo: deb https://nginx.org/packages/mainline/debian/ buster nginx
- name: Add Nginx Repo deb-src
apt_repository:
repo: deb-src https://nginx.org/packages/mainline/debian/ buster nginx
- name: Del Nginx-common
apt: name=nginx-common state=absent
- name: Install Nginx of Debian 10
apt: name=nginx update_cache=yes state=latest
- name: Start Nginx and Enable it on the every boot
service: name=nginx state=started enabled=yes
# INSTALL PHP-FPM
- name: Install PHP-FPM of Debian 10
apt: name=php-fpm update_cache=yes state=latest
Код рабочий, но он большой и его можно упростить при помощи цикла с использованием loop (пояснения в коде):
---
- name: Install Nginx + php7.3-fpm
hosts: all
become: yes
tasks:
# INSTALL NGINX
- name: download PGP-key
get_url:
url: http://nginx.org/keys/nginx_signing.key
dest: /etc/nginx_signing.key
- name: install PGP-key
apt_key:
file: /etc/nginx_signing.key
state: present
# после repo: указали "{{ item }}" который будет подставлять loop.
# Тем самым нам не надо дублировать этот блок для каждого репозитория
- name: Add Nginx Repo deb&deb-src
apt_repository:
repo: "{{ item }}"
loop:
- "deb https://nginx.org/packages/mainline/debian/ buster nginx"
- "deb-src https://nginx.org/packages/mainline/debian/ buster nginx"
- name: Del Nginx-common
apt: name=nginx-common state=absent
- name: Install Nginx of Debian 10
apt: name=nginx update_cache=yes state=latest
- name: Start Nginx and Enable it on the every boot
service: name=nginx state=started enabled=yes
# INSTALL PHP-FPM
- name: Install PHP-FPM of Debian 10
apt: name=php-fpm update_cache=yes state=latest
# Так как пакет PHP-FPM содержит доп модули и они ставятся отдельно, применим как и выше loop
- name: Install of packages PHP-FPM
apt: name={{ item }} state=latest
loop:
- php-mysql
- php-bcmath
- php-json
- php-mbstring
- php-tokenizer
- php-xml
- php-curl
Вместо "loop"(новее) можно писать "with_items"(старее).
with_file global
В первом примере мы устанавливали Apahe 2 на разные сервера, копировали 1 файл и делали рестарт с использованием блоков. Теперь разберем все тоже самое, только будем копировать несколько файлов из локальной директории ./MyWebFiles на удаленный сервер. Блоки отвечающие за файлы объединим в один и используем loop для перечисления файлов из локальной директории:
---
- name: Install Apache
hosts: all
become: yes
# 1. Меняем file на folder и указываем каталог с файлами
vars:
source_folder: ./MyWebFiles
destin_folder: /var/www/html
tasks:
- name: Check version Linux
debug: var=ansible_os_family
- block:
- name: Install Apache web Server Debian
apt: name=apache2 update_cache=yes state=latest
- name: Start Debian
service: name=apache2 state=started enabled=yes
when: ansible_os_family== "Debian"
when: ansible_os_family == "Debian"
- block:
- name: Install Apache web Server CentOS
yum: name=httpd update_cache=yes state=latest
- name: Start CentOS
service: name=httpd state=started enabled=yes
when: ansible_os_family== "CentOS"
when: ansible_os_family == "CentOS"
# 2. Два блока объединяем в один и удваеваем notify
# 3. Меняем file на folder, добавляем item с loop (п. 1)
- name: Copy files in www CentOS&Debian
copy: src={{ source_folder }}/{{ item }} dest={{ destin_folder }} mode=0555
loop:
- "index.html"
- "ico.png"
notify:
- Restart Apache CentOS
- Restart Apache Debian
# 4. Ограничим их через "when:" из-за п. 2, т.к. notify задвоен
handlers:
- name: Restart Apache CentOS
service: name=httpd state=restarted
when: ansible_os_family == "CentOS"
- name: Restart Apache Debian
service: name=apache2 state=restarted
when: ansible_os_family == "Debian"
Всем спасибо за внимание. Дальше интереснее!
Источник: http://linuxsql.ru