You are here

Playbook: Блоки, условия и циклы. Lesson 7

Linux: 

Ansible: Блоки, условия и циклы. Урок 7

В данной статье разберем более подробно такие понятия как: боки, условия и циклы в Playbook Ansible. Для начала вспомни два урока ранее:

Из которых мы воспользуемся готовым Playbook по установке Nginx, связкой "handlers и notify" и переменной "ansible_os_family".

1. Изучаем block и условия

Приступим:

  1. sudo nano install_apache.yml

После создания файла, заполним его:

  1. ---
  2. - name: Install Nginx
  3. hosts: all
  4. become: yes
  5.  
  6. tasks:
  7. - name: Install Nginx of Debian 10
  8. apt: name=nginx update_cache=yes state=latest
  9.  
  10. - name: Start Nginx and boot
  11. service: name=nginx state=started enabled=yes

Изменим пакет Nginx на Apache, для наглядности. Так как под разными системами, к примеру Debian и CentOS, этот пакет имеет разное название и оператор установки (apt и yum). В итоге получим такой код:

  1. ---
  2. - name: Install Apache
  3. hosts: all
  4. become: yes
  5.  
  6. vars:
  7. source_file: ./index.html
  8. destin_file: /var/www/html
  9.  
  10. tasks:
  11. # 1. В этой части будет переменная которая определяет версию Linux в (п.3 и 4)
  12. - name: Check version Linux
  13. debug: var=ansible_os_family
  14.  
  15. # 2. Для установки на Debian и CentOS используем when: условия для (п.3 и 4)
  16.  
  17. # 3. Устанавливаем Apache на Debian где Apache=apache2 через apt
  18. - name: Install Apache web Server Debian
  19. apt: name=apache2 update_cache=yes state=latest
  20. when: ansible_os_family== "Debian"
  21.  
  22. # 4. Устанавливаем Apache на CentOS где Apache=httpd через yum
  23. - name: Install Apache web Server CentOS
  24. yum: name=httpd update_cache=yes state=latest
  25. when: ansible_os_family== "CentOS"
  26.  
  27. # 5. Блок отвечающий за копирование файлов в папку www на удаленном сервере из vars
  28. - name: Copy files in www CentOS
  29. copy: src={{ source_file }} dest={{ destin_file }}
  30. notify: Restart Apache CentOS
  31.  
  32. - name: Copy files in www Debian
  33. copy: src={{ source_file }} dest={{ destin_file }}
  34. notify: Restart Apache Debian
  35.  
  36. # 6. Этот блок отвечает за запуск сервиса, для него так же используем when: условия
  37. - name: Start CentOS
  38. service: name=httpd state=started enabled=yes
  39. when: ansible_os_family== "CentOS"
  40.  
  41. - name: Start Debian
  42. service: name=apache2 state=started enabled=yes
  43. when: ansible_os_family== "Debian"
  44.  
  45. # 7. Добавим handlers для указания якоря "Restart Apache CentOS/Debian", для п.5
  46. handlers:
  47. - name: Restart Apache CentOS
  48. service: name=httpd state=restarted
  49.  
  50. - name: Restart Apache Debian
  51. service: name=apache2 state=restarted

Подробнее о работе Playbook:

  • п. 1 проверяет версию linux (CentOS или Debian). Для этого взяли переменную ansible_os_family
  • п. 2 через when: ansible_os_family определяется какие пункты запустить по версии linux (CentOS или Debian)
  • п. 3, 4 производит установку Apache согласно определенным Linux (по сути уходит на 2 ветки одновременно)
  • п. 6 отвечает за запуск Apache после установки (п. 3 и 6 связанны переменной ansible_os_family)
  • п. 5 производит копирование нового файла index.html на удаленный сервер /var/www/html
  • п. 7 Якорь делает рестарт по п. 5

Переделаем тот же код блоками, с общим when:

  1. ---
  2. - name: Install Apache
  3. hosts: all
  4. become: yes
  5.  
  6. vars:
  7. source_file: ./testers.html
  8. destin_file: /var/www/html
  9.  
  10. tasks:
  11. - name: Check version Linux
  12. debug: var=ansible_os_family
  13.  
  14. - block:
  15.  
  16. - name: Install Apache web Server Debian
  17. apt: name=apache2 update_cache=yes state=latest
  18.  
  19. - name: Copy files in www Debian
  20. copy: src={{ source_file }} dest={{ destin_file }}
  21. notify: Restart Apache Debian
  22.  
  23. - name: Start Debian
  24. service: name=apache2 state=started enabled=yes
  25. when: ansible_os_family== "Debian"
  26.  
  27. when: ansible_os_family == "Debian"
  28.  
  29. - block:
  30.  
  31. - name: Install Apache web Server CentOS
  32. yum: name=httpd update_cache=yes state=latest
  33.  
  34. - name: Copy files in www CentOS
  35. copy: src={{ source_file }} dest={{ destin_file }}
  36. notify: Restart Apache CentOS
  37.  
  38. - name: Start CentOS
  39. service: name=httpd state=started enabled=yes
  40. when: ansible_os_family== "CentOS"
  41.  
  42. when: ansible_os_family == "CentOS"
  43.  
  44. handlers:
  45. - name: Restart Apache CentOS
  46. service: name=httpd state=restarted
  47.  
  48. - name: Restart Apache Debian
  49. service: name=apache2 state=restarted

Запускаем наш код (ВАЖНО: в нашем случае сервер только на Debian, поэтом установку на CentOS наш playbook пропустит):

  1. ansible-playbook install_apache.yml
  2. ...
  3. PLAY [Install Apache] **********************************
  4.  
  5. TASK [Gathering Facts] ********************************
  6. ok: [debi]
  7.  
  8. TASK [Check version Linux] *****************************
  9. ok: [debi] => {
  10. "ansible_os_family": "Debian"
  11. }
  12.  
  13. TASK [Install Apache web Server Debian] ******************
  14. ok: [debi]
  15.  
  16. TASK [Copy files in www Debian] *************************
  17. changed: [debi]
  18.  
  19. TASK [Start Debian] ***********************************
  20. changed: [debi]
  21.  
  22. TASK [Install Apache web Server CentOS] ******************
  23. skipping: [debi]
  24.  
  25. TASK [Copy files in www CentOS] *************************
  26. skipping: [debi]
  27.  
  28. TASK [Start CentOS] ***********************************
  29. skipping: [debi]
  30.  
  31. RUNNING HANDLER [Restart Apache Debian] ****************
  32. changed: [debi]
  33.  
  34. PLAY RECAP ******************************************
  35. 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

  1. ---
  2. - name: Install Nginx + repositories
  3. hosts: all
  4. become: yes
  5.  
  6. tasks:
  7. - name: download PGP-key
  8. get_url:
  9. url: http://nginx.org/keys/nginx_signing.key
  10. dest: /etc/nginx_signing.key
  11.  
  12. - name: install PGP-key
  13. apt_key:
  14. file: /etc/nginx_signing.key
  15. state: present
  16.  
  17. - name: Add Nginx Repo deb
  18. apt_repository:
  19. repo: deb https://nginx.org/packages/mainline/debian/ buster nginx
  20.  
  21. - name: Add Nginx Repo deb-src
  22. apt_repository:
  23. repo: deb-src https://nginx.org/packages/mainline/debian/ buster nginx
  24.  
  25. - name: Del Nginx-common
  26. apt: name=nginx-common state=absent
  27.  
  28. - name: Install Nginx of Debian 10
  29. apt: name=nginx update_cache=yes state=latest
  30.  
  31. - name: Start Nginx and Enable it on the every boot
  32. service: name=nginx state=started enabled=yes
  33.  
  34. # INSTALL PHP-FPM
  35.  
  36. - name: Install PHP-FPM of Debian 10
  37. apt: name=php-fpm update_cache=yes state=latest

Код рабочий, но он большой и его можно упростить при помощи цикла с использованием loop (пояснения в коде):

  1. ---
  2. - name: Install Nginx + php7.3-fpm
  3. hosts: all
  4. become: yes
  5.  
  6. tasks:
  7. # INSTALL NGINX
  8. - name: download PGP-key
  9. get_url:
  10. url: http://nginx.org/keys/nginx_signing.key
  11. dest: /etc/nginx_signing.key
  12.  
  13. - name: install PGP-key
  14. apt_key:
  15. file: /etc/nginx_signing.key
  16. state: present
  17. # после repo: указали "{{ item }}" который будет подставлять loop.
  18. # Тем самым нам не надо дублировать этот блок для каждого репозитория
  19. - name: Add Nginx Repo deb&deb-src
  20. apt_repository:
  21. repo: "{{ item }}"
  22.  
  23. loop:
  24. - "deb https://nginx.org/packages/mainline/debian/ buster nginx"
  25. - "deb-src https://nginx.org/packages/mainline/debian/ buster nginx"
  26.  
  27. - name: Del Nginx-common
  28. apt: name=nginx-common state=absent
  29.  
  30. - name: Install Nginx of Debian 10
  31. apt: name=nginx update_cache=yes state=latest
  32.  
  33. - name: Start Nginx and Enable it on the every boot
  34. service: name=nginx state=started enabled=yes
  35.  
  36. # INSTALL PHP-FPM
  37.  
  38. - name: Install PHP-FPM of Debian 10
  39. apt: name=php-fpm update_cache=yes state=latest
  40.  
  41. # Так как пакет PHP-FPM содержит доп модули и они ставятся отдельно, применим как и выше loop
  42. - name: Install of packages PHP-FPM
  43. apt: name={{ item }} state=latest
  44. loop:
  45. - php-mysql
  46. - php-bcmath
  47. - php-json
  48. - php-mbstring
  49. - php-tokenizer
  50. - php-xml
  51. - php-curl

Вместо "loop"(новее) можно писать "with_items"(старее).

with_file global
В первом примере мы устанавливали Apahe 2 на разные сервера, копировали 1 файл и делали рестарт с использованием блоков. Теперь разберем все тоже самое, только будем копировать несколько файлов из локальной директории ./MyWebFiles на удаленный сервер. Блоки отвечающие за файлы объединим в один и используем loop для перечисления файлов из локальной директории:

  1. ---
  2. - name: Install Apache
  3. hosts: all
  4. become: yes
  5.  
  6. # 1. Меняем file на folder и указываем каталог с файлами
  7. vars:
  8. source_folder: ./MyWebFiles
  9. destin_folder: /var/www/html
  10.  
  11. tasks:
  12. - name: Check version Linux
  13. debug: var=ansible_os_family
  14.  
  15. - block:
  16.  
  17. - name: Install Apache web Server Debian
  18. apt: name=apache2 update_cache=yes state=latest
  19.  
  20. - name: Start Debian
  21. service: name=apache2 state=started enabled=yes
  22. when: ansible_os_family== "Debian"
  23.  
  24. when: ansible_os_family == "Debian"
  25.  
  26. - block:
  27.  
  28. - name: Install Apache web Server CentOS
  29. yum: name=httpd update_cache=yes state=latest
  30.  
  31. - name: Start CentOS
  32. service: name=httpd state=started enabled=yes
  33. when: ansible_os_family== "CentOS"
  34.  
  35. when: ansible_os_family == "CentOS"
  36.  
  37. # 2. Два блока объединяем в один и удваеваем notify
  38. # 3. Меняем file на folder, добавляем item с loop (п. 1)
  39. - name: Copy files in www CentOS&Debian
  40. copy: src={{ source_folder }}/{{ item }} dest={{ destin_folder }} mode=0555
  41. loop:
  42. - "index.html"
  43. - "ico.png"
  44. notify:
  45. - Restart Apache CentOS
  46. - Restart Apache Debian
  47.  
  48. # 4. Ограничим их через "when:" из-за п. 2, т.к. notify задвоен
  49. handlers:
  50. - name: Restart Apache CentOS
  51. service: name=httpd state=restarted
  52. when: ansible_os_family == "CentOS"
  53.  
  54. - name: Restart Apache Debian
  55. service: name=apache2 state=restarted
  56. when: ansible_os_family == "Debian"

Всем спасибо за внимание. Дальше интереснее!

Источник: http://linuxsql.ru