В данной статье разберем более подробно такие понятия как: боки, условия и циклы в 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