Начало
Ссылки:
|
https://www.ansible.com/ - офф сайт https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html - бест практик https://pastebin.com/9hpUPE1z - пример конфига vpn клиента https://www.youtube.com/watch?v=Ck1SGolr6GI&list=PLg5SS_4L6LYufspdPupdynbMQTBnZd31N&index=1 - видосики от ADV-IT https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html - установка офф документация |
Вводное:
|
Ansible - Automation Configure Tool Минимальные требования Control Server - Master Server: 1. Linux only (RedHat, Debian, Centos, OS X, ubuntu) 2. Python 2.6 или Python 3.5+ Controlled Servers - Managed Servers: Linux: Admin Username/Passwords или SSH Key и Python 2.6+ Windows: Admin Username/Passwords, Powershell 3.0 и запустить скрипт ConfigureRemotingForAnsible.ps1 Работа происходит через следующие порты: Linux -> SSH Port 22 Windows -> WinRM Port 5986 |
Установка:
|
Установка на Ubuntu 16.04: sudo apt-add-repository ppa:ansible/ansible sudo apt-get update sudo apt-get install ansible Установка на CentOS 7: sudo yum install epel-release sudo yum install ansible Ansible - Установка на Amazon Linux через PIP sudo pip install ansible ansible --version - узнаем версию ansible |
ansible подключение к клиентам
Пример генерации ключей
|
ssh-keygen - создаем пару ключей на сервере с которого будем подключатся. ssh-copy-id username@IP_адрес_вашего_сервера - копирование открытого ключа автоматизация... ssh-keygen && for host in $(cat hosts.txt); do ssh-copy-id $host; done |
Подключение:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
cd ~ - перешли в домашний каталог mkdir ansible - создали каталог ansible для удобства cd /ansible - перешли в новый каталог ansible touch host.txt - создадим специальный файл для подключения к хостам nano host.txt - отредактируем ---host.txt--- если используются пароли [staging_servers] linux1 ansible_host=192.168.15.142 ansible_user=USERNAME1 ansible_pass=Mypassword123 -------------- nano host.txt - отредактируем ---host.txt--- если используются SSHKEY [staging_servers] linuxX ansible_host=192.168.15.142 ansible_user=USERNAME1 ansible_ssh_private_key_file=/home/USERNAME1/.ssh/id_rsa [prod_servers] linux1 ansible_host=192.168.15.145 ansible_user=USERNAME1 ansible_ssh_private_key_file=/home/USERNAME1/.ssh/nameSSHkey1.pem linux2 ansible_host=192.168.15.145 ansible_user=USERNAME1 ansible_ssh_private_key_file=/home/USERNAME1/.ssh/nameSSHKey2.pem [windows_servers] windows1 ansible_host=192.168.15.147 windows2 ansible_host=192.168.15.146 [windows_servers:vars] ansible_user = admin ansible_password = PASSWORD@123 !!! можно убрать пароль из конфига, а при запуске команды ansible писать --ask-pass ansible_port = 5986 ansible_connection = winrm ansible_winrm_serv_cert_validation = ignore -------------- |
Дополнительная настройка ansible.cfg
|
ansible --version - покажет версию, где находится конфиг файл ansible.cfg /etc/ansible/ansible.cfg - в ubuntu тут cd ~ansible - перешли в каталог ansible tauch ansible.cfg - создадим пустой файл nano ansible.cfg ---ansible.cfg--- [defaults] host_key_cheking = false - отключаем проверку для finger ssh-key inventory = /home/USERNAME/host.txt - файл настроек хостов ----------------- |
Проверка ping:
|
cd ~ansible - перешли в каталог ansible ansible -i host.txt all -m ping - запустили проверку в ответ прилетит PONG -i host.txt - файл с хостами all - группа в данном случае для всех -m ping - используем модуль ping для linux хостов -m win_ping - используем модуль ping для windows хостов Если в ansible.cfg добавили invertory то можно не писать опцию -i host.txt ansible all -m ping - запустили проверку в ответ прилетит PONG если все ок ansible windows_servers -m win_ping - запустили проверку в ответ прилетит PONG если все ок ansible windows_servers -m win_ping --ask-pass - запустили проверку в ответ прилетит PONG если все ок |
ansible invertory и файл host.txt
Файл пример:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
Можно записывать так просто перечислить ip адреса 192.168.0.1 192.168.0.2 192.168.0.3 192.168.0.4 192.168.0.5 Можно записывать имена серверов name1 name2 name3 name4 name5 !!! Все хосты входят в группы !!! Все хосты входят в группу all !!! Все хосты которым не назначена группа, входят в группу ungrouped и all [staging_DB] 192.168.0.10 192.168.0.11 [staging_WEB] 192.168.0.20 192.168.0.21 [staging_APP] 192.168.0.30 192.168.0.31 [staging_ALL:children] staging_DB staging_WEB staging_APP [prod_DB] 10.10.10.1 [prod_WEB] 10.10.10.2 [prod_APP] 10.10.10.3 [prod_ALL:children] prod_DB prod_WEB prod_APP [DB_ALL:children] staging_DB prod_DB [APP_ALL:children] staging_APP prod_APP [APP_ALL:vars] message=Hello [staging_servers] linuxX ansible_host=192.168.15.142 ansible_user=USERNAME7 ansible_ssh_private_key_file=/home/USERNAME7/.ssh/id_rsa [prod_servers] linux1 ansible_host=192.168.15.145 linux2 ansible_host=192.168.15.146 [prod_servers:vars] ansible_user=USERNAME1 ansible_ssh_private_key_file=/home/USERNAME1/.ssh/nameSSHKey1.pem [windows_servers] windows1 ansible_host=192.168.15.147 windows2 ansible_host=192.168.15.146 [windows_servers:vars] ansible_user = admin ansible_password = PASSWORD@123 !!! можно убрать пароль из конфига, а при запуске команды ansible писать --ask-pass ansible_port = 5986 ansible_connection = winrm ansible_winrm_serv_cert_validation = ignore |
ДОП
|
ansible-inventory --list - покажет все хосты и какие переменные к ним относятся ansible-inventory --graph - - покажет все хосты и какие группы в виде дерева |
ansible запуск ad-hoc команд, -m , ping , setup , shell , copy , file , get_url , yum , apt , service , uri , ansible-invertory , ansible-doc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
|
ansible -i host.txt all -m ping - запустили проверку в ответ прилетит PONG -i host.txt - файл с хостами all - группа в данном случае для всех -m ping - используем модуль ping для linux хостов -m win_ping - используем модуль ping для windows хостов Если в ansible.cfg добавили invertory то можно не писать опцию -i host.txt ansible all -m ping - запустили проверку в ответ прилетит PONG если все ок ansible all -m setup - выведет параметры всех серверов ansible staging_servers -m setup - выведет параметры группы taging_servers ansible all -m shell -a "uptime" - выполнить на всех серверах команду uptime -m shell - модуль шелл -a аргумент (комманда) uptime ansible all -m shell -a "df -h" - выполнить на всех серверах команду df -h (занятое место) ansible all -m command -a "uptime" - тоже самое что и shell но в нем не будут работать переменные и спец символы !@#$%^&*(}| и тд ansible all -m copy -a "src=xxx.txt dest=/home mode=777" - скопировать файл xxx.txt в каталог /home ansible all -m copy -a "src=xxx.txt dest=/home mode=777" -b - повысить привилегии (sudo) ansible all -m copy -a "src=xxx.txt dest=/home mode=777" -b --ask-become-pass - повысить привилегии и ввести пароль -b - повысить привилегии -m copy - модуль копирования ansible all -m file -a "path=/home/XXX.txt state=absent" -b - удаление файла XXX.txt ansible all -m get-url -a "url=http://example.com/path/file.conf dest=/home/foo.conf" ansible all -m get_url -a "url=http://example.com/path/file.conf dest=/home/foo.conf username=USERNAME password=USERNAME" ansible all -m yum -a "name=httpd state=latest" -b - установка пакета stress на CentOS (проверял установит и на Debian) ansible all -m yum -a "name=stress state=present" -b - установка пакета stress на CentOS (проверял установит и на Debian) ansible all -m yum -a "name=stress state=absent" -b - удаление пакета stress на CentOS (проверял удалит и на Debian) ansible all -m apt -a "name=apache2 state=present" -b - установка apache2 на Debian ansible all -m apt -a "name=apache2 state=absent" -b - удаление apache2 на Debian ansible all -m service -a "name=httpd state=started enabled=yes" - запускать веб сервер CentOS ansible all -m service -a "name=apache2 state=started enabled=yes" - запускать веб сервер Debian ansible all -m uri -a "url=https://b14esh.com" - как бы тестик, проверить доступность страницы ansible all -m uri -a "url=https://b14esh.com return_content=yes" - как бы тестик, проверить доступность страницы, покажет страницу ansible all -m shell -a "df -h " -vvvvv - дебаг(debug) выполнения команды ( чем больше "v" тем больше дебагу) ansible-doc -l - офф документация в консоли ansible-doc -l | grep windows - поиск по windows ansible-doc -l | grep ec2 - поиск по ec2 !!! https://docs.ansible.com/ - используй тут много полезного ansible-inventory --list - покажет все хосты и какие переменные к ним относятся ansible-inventory --graph - покажет все хосты и какие группы в виде дерева |
Для работы -b и ошибка «msg»: «Missing sudo password»
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
!!! Вот такая ошибка "msg": "Failed to get information on remote file может появятся если сломали sudo !!! "msg": "Missing sudo password" ошибка появляется с опцией -b временно поможет опция --ask-become-pass !!! sudo groupadd sudo - создать группу sudo в Ubuntu эта группа уже существует sudo usermod -a -G sudo username - добавить вашего пользователя к этой группе где username - имя вашего пользователя в системе Отредактировать /etc/sudoers файл sudo nano /etc/sudoers ---------------------- Найти строку ниже в этом файле (если нет, то создать) %sudo ALL=(ALL:ALL) ALL и поменять на следующую %sudo ALL=(ALL:ALL) NOPASSWD: ALL ----------------------- |
ansible формат yaml , файлов yml , примеры
0. myfile.yml
|
Обычный текстовый файл --- всегда начинаются с двух минусов ... заканчиваются точками |
1. myfile.yml
|
--- - command1 первая команда начинается с одного минуса - command2 вторая команда минус должен располагаться четко под минусом первой команды ... |
2. myfile.yml
|
--- fruits: список команд заканчивается на двоеточие, и начинается с минуса если списков несколько - apple - orange - mango ... |
3. myfile.yml
|
--- - fruits: список команд заканчивается на двоеточие, и начинается с минуса если списков несколько - apple - orange - mango - vegetables: - carrots - cucumbers ... |
4. myfile.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
--- - fruits: - apple - orange - mango fruits: ['apple' , 'orange' , 'mango' ] - vegetables: - carrots - cucumbers - vasya: nick: vasek position: developer skills: - python - perl - php - petya: nick: pet postition: manager skills: - manage - make_noise - petyak: nick: "pettya: krutoy" postition: manager skills: - manage - make_noise - kolya: {nick: kolyan, position: administrator, skills: killer } - kolya1: {nick: kolyan, position: administrator, skills: ['killer', 'cleaner' } ... |
5. Популярный вид записи myfile.yml
|
- petya: nick: pet postition: manager skills: - manage - make_noise |
ansible перенос переменных , group_vars
Дано host.txt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
[STAGING_SERVERS_WEB] LinuxX1 ansible_host=192.168.30.10 LinuxX1 ansible_host=192.168.30.11 password=mysecret [STAGING_SERVERS_WEB:vars] ansible_user=user1 ansible_ssh_private_key_file=/home/user1/.ssh/super-key1.pem [PROD_SERVERS_WEB] Linux1 ansible_host=10.10.10.10 Linux1 ansible_host=10.20.20.11 [PROD_SERVERS_WEB:vars] ansible_user=user1 ansible_ssh_private_key_file=/home/user1/.ssh/super-key2.pem [STAGING_SERVERS_DB] 192.168.30.20 192.168.30.21 [PROD_SERVERS_DB] 10.10.10.20 10.10.10.21 [ALL_SERVERS_DB:children] STAGING_SERVERS_DB PROD_SERVERS_DB [ALL_SERVERS_DB:vars] db_endpoint=db.sytekxxx.com:4151 owner=vasya location="Huston,TX" |
Выносим переменные из файла host.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
cd ~ansible - перешли в каталог ansible в домашнем каталоге пользователя (естественно в каталоге /etc/ansible/ у меня нет конфигов) mkdir group_vars - создаем каталог group_vars в каталоге ansible cd group_vars - перешли в каталог group_vars touch STAGING_SERVERS_WEB PROD_SERVERS_WEB ALL_SERVERS_DB - создаем файлы PROD_SERVERS_WEB и ALL_SERVERS_DB nano STAGING_SERVERS_WEB - файл будет иметь YAML синтаксис (в начале файла ---, в конце файла ... , равно(=) заменить на двоеточие(:) ---STAGING_SERVERS_WEB--- --- ansible_user : user1 ansible_ssh_private_key_file : /home/user1/.ssh/super-key1.pem ... ---------------------- nano PROD_SERVERS_WEB - файл будет иметь YAML синтаксис (в начале файла ---, в конце файла ... , равно(=) заменить на двоеточие(:) ---PROD_SERVERS_WEB--- --- ansible_user : user1 ansible_ssh_private_key_file : /home/user1/.ssh/super-key2.pem ... ---------------------- nano ALL_SERVERS_DB - файл будет иметь YAML синтаксис (в начале файла ---, в конце файла ... , равно(=) заменить на двоеточие(:) ---ALL_SERVERS_DB--- --- db_endpoint : db.sytekxxx.com:4151 owner : vasya location : "Huston,TX" ... -------------------- nano host.txt - приводим к следующему виду ---host.txt--- [STAGING_SERVERS_WEB] LinuxX1 ansible_host=192.168.30.10 LinuxX1 ansible_host=192.168.30.11 password=mysecret [PROD_SERVERS_WEB] Linux1 ansible_host=10.10.10.10 Linux1 ansible_host=10.20.20.11 [STAGING_SERVERS_DB] 192.168.30.20 192.168.30.21 [PROD_SERVERS_DB] 10.10.10.20 10.10.10.21 [ALL_SERVERS_DB:children] STAGING_SERVERS_DB PROD_SERVERS_DB -------------- |
ansible playbook
вводное
|
!!! Пробелы ОЧЕНЬ ВАЖНЫ !!! НЕ ИСПОЛЬЗУЙТЕ "TAB" будут ошибки на ровном месте ansible-playbook NAMEPLAYBOOK.yml - запуск плейбука |
playbook0.yml ping
|
--- - name: Test connection to my servers hosts: all become: yes tasks: - name: Ping my servers ping: ... |
playbook1.yml install httpd CentOS
|
--- - name: Install default Apache Web Servers hosts: all become: yes tasks: - name: Install Apache Web Server yum: name=httpd state=latest - name: Start Apache and Enable it on every boot service: name=httpd state=started enabled=yes ... |
playbook2.yml install apache2 Debian
|
--- - name: Install default Apache Web Servers hosts: all become: yes tasks: - name: Install Apache Web Server yum: name=apache2 state=present - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes ... |
playbook3.yml install apache2 Debian and copy index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes vars: source_file: ./website/index.html destin_file: /var/www/html tasks: - name: Install Apache Web Server yum: name=apache2 state=present - name: Copy index html to Servers copy: src={{ source_file }} dest={{ destin_file }} mode=0555 notify: Restart Apache - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes handlers: - name: Restart Apache service: name=apache2 state=restarted ... |
ansible переменные , Debug , Set_fact , Register
host.txt
|
ansible all -m setup - выведет параметры всех серверов ansible staging_servers -m setup - выведет параметры группы taging_servers [staging_servers] linux1 ansible_host=192.168.15.142 owner=LOL |
playbook_debug.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
|
--- - name: My super Playbook hosts: all become: yes vars: message1: privet message2: word secret : LKKDKDKDKDLSDKLSKD tasks: - name: Print Sectret variable debug: var: secret - debug: msg: "Sekretnoe slovo {{ secret }}" - debug: msg: "Vladelec etogo servera --> {{ owner }} <--" - set_fact: full_message=" {{ message1 }} {{ message2 }} from {{ owner }}" - debug: var: full_message - debug: var: ansible_distribution - debug: var: ansible_all_ipv4_addresses - shell: uptime register: results - debug: var: results - debug: var: results.stdout ... |
ansible блоки , условия , apache , copy , install , when , block
playbook.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes vars: source_file: ./website/index.html destin_file: /var/www/html tasks: - name: Cheack and Print Linux Version debug: var=ansible_os_family - block: # === BLOCK REDHAT ==== - name: Install Apache Web Server for RedHat yum: name=httpd state=present - name: Copy index html to Servers copy: src={{ source_file }} dest={{ destin_file }} mode=0555 notify: Restart Apache RedHat - name: Start Apache and Enable it on every boot service: name=httpd state=started enabled=yes when: ansible_os_family == "RedHat" - block: # === BLOCK DEBIAN ==== - name: Install Apache Web Server for Debian apt: name=apache2 state=present - name: Copy index html to Servers copy: src={{ source_file }} dest={{ destin_file }} mode=0555 notify: Restart Apache Debian - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes when: ansible_os_family == "Debian" handlers: - name: Restart Apache Redhat service: name=httpd state=restarted when: ansible_os_family == "RedHat" - name: Restart Apache Debian service: name=apache2 state=restarted when: ansible_os_family == "Debian" ... |
ansible , циклы , loop , with_items , until , with_fileglob , copy , folder , копирование
playbook-loop.yml примеры циклов loop, with_items
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
|
--- - name: Loops Hello hosts: all become: yes tasks: - name: Say Hello to ALL debug: msg="Hello {{ item }}" loop: - "Vasya" - "Masha" - "Olga" - "Petr" - name: loop until example shell: echo -n Z >> myfile.txt && cat myfile.txt register: output delay: 2 retries: 10 until: output.stdout.find("ZZZZ") == false - name: Print Final Output debug: var: output.stdout # - name: Install many packeg # apt: name={{ item }} state=present # with_items: # - apache2 # - htop # - tree ... |
playbook.yml install-and-copy-folder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes vars: source_folder: ./website destin_folder: /var/www/html tasks: - name: Cheack and Print Linux Version debug: var=ansible_os_family - block: # === BLOCK REDHAT ==== - name: Install Apache Web Server for RedHat yum: name=httpd state=present - name: Start Apache and Enable it on every boot service: name=httpd state=started enabled=yes when: ansible_os_family == "RedHat" - block: # === BLOCK DEBIAN ==== - name: Install Apache Web Server for Debian apt: name=apache2 state=present - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes when: ansible_os_family == "Debian" - name: Copy folder to web Servers copy: src={{ source_folder }}/{{ item }} dest={{ destin_folder }} mode=0555 loop: - "file0.txt" - "file1.txt" - "file2.txt" - "file3.txt" - "file4.txt" - "file5.txt" notify: - Restart Apache RedHat - Restart Apache Debian handlers: - name: Restart Apache RedHat service: name=httpd state=restarted when: ansible_os_family == "RedHat" - name: Restart Apache Debian service: name=apache2 state=restarted when: ansible_os_family == "Debian" ... |
playbook.yml install-and-copy-folder по маске
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes vars: source_folder: ./website destin_folder: /var/www/html tasks: - name: Cheack and Print Linux Version debug: var=ansible_os_family - block: # === BLOCK REDHAT ==== - name: Install Apache Web Server for RedHat yum: name=httpd state=present - name: Start Apache and Enable it on every boot service: name=httpd state=started enabled=yes when: ansible_os_family == "RedHat" - block: # === BLOCK DEBIAN ==== - name: Install Apache Web Server for Debian apt: name=apache2 state=present - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes when: ansible_os_family == "Debian" - name: Copy folder to web Servers copy: src={{ item }} dest={{ destin_folder }} mode=0555 with_fileglob: "{{ source_folder }}/*.*" notify: - Restart Apache RedHat - Restart Apache Debian handlers: - name: Restart Apache RedHat service: name=httpd state=restarted when: ansible_os_family == "RedHat" - name: Restart Apache Debian service: name=apache2 state=restarted when: ansible_os_family == "Debian" ... |
ansible , шаблоны , template , jinja , generate
index.2j
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
<!DOCTYPE html> <html lang="ru"> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="index.css"> <title> Просто страничка для тестов</title> </head> <body> <p> hello MEN </p> <p> страница generate </p> </tr> <p> print owner: {{ owner }} </p> <p> print hostname: {{ ansible_hostname }} </p> <p> print fqdn: {{ ansible_fqdn }} </p> <p> print os: {{ ansible_os_family }} </p> <p> IP address: {{ ansible_default_ipv4.address }} </p> </body> </html> |
playbook.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes vars: source_folder: ./website destin_folder: /var/www/html tasks: - name: Cheack and Print Linux Version debug: var=ansible_os_family - block: # === BLOCK REDHAT ==== - name: Install Apache Web Server for RedHat yum: name=httpd state=present - name: Start Apache and Enable it on every boot service: name=httpd state=started enabled=yes when: ansible_os_family == "RedHat" - block: # === BLOCK DEBIAN ==== - name: Install Apache Web Server for Debian apt: name=apache2 state=present - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes when: ansible_os_family == "Debian" - name: Generate INDEX.HTML file template: src={{ source_folder }}/index.j2 dest={{ destin_folder }}/index.html mode=555 notify: - Restart Apache RedHat - Restart Apache Debian - name: Copy folder to web Servers copy: src={{ source_folder }}/{{ item }} dest={{ destin_folder }} mode=0555 loop: - "file0.txt" - "file1.txt" - "file2.txt" notify: - Restart Apache RedHat - Restart Apache Debian handlers: - name: Restart Apache RedHat service: name=httpd state=restarted when: ansible_os_family == "RedHat" - name: Restart Apache Debian service: name=apache2 state=restarted when: ansible_os_family == "Debian" ... |
ansible role
вводное
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
cd ~ansible - зашли в домашний каталог ansible mkdir roles - создали каталог roles cd roles - зашли в каталог roles ansible-galaxy init deploy_apache_web_site - создание роли, а точнее в каталоге roles, будут созданы каталоги и файлы --------------------------------------- └── deploy_apache_web_site ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml --------------------------------------- |
Наш playbook.yml который мы будем распихивать в роль deploy_apache_web_site
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes vars: source_folder: ./website destin_folder: /var/www/html tasks: - name: Cheack and Print Linux Version debug: var=ansible_os_family - block: # === BLOCK REDHAT ==== - name: Install Apache Web Server for RedHat yum: name=httpd state=present - name: Start Apache and Enable it on every boot service: name=httpd state=started enabled=yes when: ansible_os_family == "RedHat" - block: # === BLOCK DEBIAN ==== - name: Install Apache Web Server for Debian apt: name=apache2 state=present - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes when: ansible_os_family == "Debian" - name: Generate INDEX.HTML file template: src={{ source_folder }}/index.j2 dest={{ destin_folder }}/index.html mode=555 notify: - Restart Apache RedHat - Restart Apache Debian - name: Copy folder to web Servers copy: src={{ source_folder }}/{{ item }} dest={{ destin_folder }} mode=0555 loop: - "file0.txt" - "file1.txt" - "file2.txt" notify: - Restart Apache RedHat - Restart Apache Debian handlers: - name: Restart Apache RedHat service: name=httpd state=restarted when: ansible_os_family == "RedHat" - name: Restart Apache Debian service: name=apache2 state=restarted when: ansible_os_family == "Debian" ... |
Планируем распил….. playbook.yml …
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes vars: source_folder: ./website --- это директива нам будет не нужна (так как есть спец каталог для файлов) destin_folder: /var/www/html --- эту запись добавим в defaults\main.yml tasks: --- все таски добавим в tasks\main.yml - name: Cheack and Print Linux Version debug: var=ansible_os_family - block: # === BLOCK REDHAT ==== - name: Install Apache Web Server for RedHat yum: name=httpd state=present - name: Start Apache and Enable it on every boot service: name=httpd state=started enabled=yes when: ansible_os_family == "RedHat" - block: # === BLOCK DEBIAN ==== - name: Install Apache Web Server for Debian apt: name=apache2 state=present - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes when: ansible_os_family == "Debian" - name: Generate INDEX.HTML file template: src={{ source_folder }}/index.j2 dest={{ destin_folder }}/index.html mode=555 --- тут надо будет кое что поправить см ниже notify: - Restart Apache RedHat - Restart Apache Debian - name: Copy folder to web Servers copy: src={{ source_folder }}/{{ item }} dest={{ destin_folder }} mode=0555 --- тут надо будет кое что поправить см ниже loop: - "file0.txt" - "file1.txt" - "file2.txt" notify: - Restart Apache RedHat - Restart Apache Debian handlers: - все хендлеры положим в файл handlers\main.yml - name: Restart Apache RedHat service: name=httpd state=restarted when: ansible_os_family == "RedHat" - name: Restart Apache Debian service: name=apache2 state=restarted when: ansible_os_family == "Debian" ... Файл website/index.j2 копулируем в каталог templates Остальные файлы из каталога website копируем в каталог deploy_apache_web_site/files |
С файлами получится вот так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
└── deploy_apache_web_site ├── defaults │ └── main.yml ├── files │ ├── file0.txt │ ├── file1.txt │ ├── file2.txt │ ├── file3.txt │ ├── file4.txt │ ├── file5.txt │ └── index.css ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates │ └── index.j2 ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml |
Редактируем deploy_apache_web_site\defaults\main.yml
|
--- # defaults file for deploy_apache_web_site destin_folder: /var/www/html |
Редактируем deploy_apache_web_site\hendlers\main.yml
|
--- # handlers file for deploy_apache_web_site - name: Restart Apache RedHat service: name=httpd state=restarted when: ansible_os_family == "RedHat" - name: Restart Apache Debian service: name=apache2 state=restarted when: ansible_os_family == "Debian" |
Редактируем deploy_apache_web_site\tasks\main.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
|
--- # tasks file for deploy_apache_web_site - name: Cheack and Print Linux Version debug: var=ansible_os_family - block: # === BLOCK REDHAT ==== - name: Install Apache Web Server for RedHat yum: name=httpd state=present - name: Start Apache and Enable it on every boot service: name=httpd state=started enabled=yes when: ansible_os_family == "RedHat" - block: # === BLOCK DEBIAN ==== - name: Install Apache Web Server for Debian apt: name=apache2 state=present - name: Start Apache and Enable it on every boot service: name=apache2 state=started enabled=yes when: ansible_os_family == "Debian" - name: Generate INDEX.HTML file template: src=index.j2 dest={{ destin_folder }}/index.html mode=555 notify: - Restart Apache RedHat - Restart Apache Debian - name: Copy folder to web Servers copy: src={{ item }} dest={{ destin_folder }} mode=0555 loop: - "file0.txt" - "file1.txt" - "file2.txt" notify: - Restart Apache RedHat - Restart Apache Debian |
Создаем файл playbook.yml для установки ролей
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes roles: - deploy_apache_web_site - deploy_db - deploy_vpn - deploy_xxx ... |
Создаем файл playbook.yml для установки ролей с условием если ос linux
|
--- - name: Install Apache and Upload my Web Page hosts: all become: yes roles: - { role: deploy_apache_web_site, when: ansible_system == 'Linux' } ... ansible-playbook playbook.yml - ну собственно запуск установки роли |
ansible внешние переменные extra-vars
В playbook.yml добавили переменную
|
--- - name: Install Apache and Upload my Web Page hosts: "{{ MYHOSTS }}" become: yes roles: - { role: deploy_apache_web_site, when: ansible_system == 'Linux' } ... |
Использование переменной
|
ansible-playbook playbook10.yml -e "MYHOSTS=all" ansible-playbook playbook10.yml -extra-var "MYHOSTS=NAME-HOST" ansible-playbook playbook10.yml -extra-vats "MYHOSTS=NAME-GROUP" ansible-playbook playbook10.yml -e "MYHOSTS=PROD owner=DENIS" !!! Переменные переданные в extra-vars имеют наивысшие значение |
ansible import , include , file , folder , generate
include_playbook.yml его будем уменьшать и использовать include / import
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
--- - name: My TEST Playbook hosts: all become: yes vars: mytext: "Privet MEN" tasks: - name: Ping test ping: - name: Create folder1 file: path: /home/secret/folder1 state: directory mode: 0755 - name: Create folder2 file: path: /home/secret/folder2 state: directory mode: 0755 - name: Create file1 copy: dest: /home/secret/file1.txt content: Text Line1, in file1 Text Line2, in file1 Text Line3, {{ mytext }} - name: Create file2 copy: dest: /home/secret/file2.txt content: Text Line1, in file2 Text Line2, in file2 Text Line3, {{ mytext }} ... |
create_folder.yml
|
--- - name: Create folder1 file: path: /home/secret/folder1 state: directory mode: 0755 - name: Create folder2 file: path: /home/secret/folder2 state: directory mode: 0755 ... |
create_files.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
--- - name: Create file1 copy: dest: /home/secret/file1.txt content: | Text Line1, in file1 Text Line2, in file1 Text Line3, {{ mytext }} - name: Create file2 copy: dest: /home/secret/file2.txt content: | Text Line1, in file2 Text Line2, in file2 Text Line3, {{ mytext }} ... |
include_playbook.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
--- - name: My TEST Playbook hosts: all become: yes vars: mytext: "Privet MEN" tasks: - name: Ping test ping: - name: Create Folders include: create_folder.yml - name: Create Files import: create_files.yml ... !!! Отличие import от include заключается в следующем !!! Include читает из файлов значения, ansible подставляет значения при выполнении (дошел до строчки с include тогда и подставил) !!! Import читает и подставляет значения, ansible подставляет сразу все значения !!! рекомендуют использовать include !!! Также можно сократить запись --- - name: My TEST Playbook hosts: all become: yes vars: mytext: "Privet MEN" tasks: - name: Ping test ping: - include: create_folder.yml - include: create_files.yml mytext="Hello from Mosckow" ... |
ansible delegate_to , выполнить где нужно , run_once , shell , copy
playbook.yml delegate_to
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
--- - name: My playbook create file hosts: all become: yes vars: mytext: "Privet ot b14esh" tasks: - name: Test ping ping: - name: Create File file1.txt copy: dest: /home/file1.txt content: | This is file1.txt On ohhh {{ mytext }} delegate_to: linux1 - name: Create file file2.txt copy: dest: /home/file2.txt content: | This is File2 Mytext {{ mytext }} lol lol lol lol lol ... |
playbook.yml delegate_to на ansible master 127.0.0.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
--- - name: My playbook create file hosts: all become: yes vars: mytext: "Privet ot b14esh" tasks: - name: Test ping ping: - name: Unregister Server from Load Balance shell: echo this server {{ inventory_hostname }} was deregisterred from our load balancer, node name is {{ ansible_nodename }} >> /home/log.txt delegate_to: 127.0.0.1 - name: Create File file1.txt copy: dest: /home/file1.txt content: | This is file1.txt On ohhh {{ mytext }} delegate_to: linux1 - name: Create file file2.txt copy: dest: /home/file2.txt content: | This is File2 Mytext {{ mytext }} lol lol lol lol lol ... |
playbook.yml delegate_to , run_once выполнить один раз , reboot и ждем
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
|
--- - name: My playbook create file hosts: all become: yes vars: mytext: "Privet ot b14esh" tasks: - name: Test ping ping: - name: Unregister Server from Load Balance shell: echo this server {{ inventory_hostname }} was deregisterred from our load balancer, node name is {{ ansible_nodename }} >> /home/log.txt delegate_to: 127.0.0.1 - name: Update my database shell: echo Update database run_once: true delegate_to: 127.0.0.1 - name: Create File file1.txt copy: dest: /home/file1.txt content: | This is file1.txt On ohhh {{ mytext }} delegate_to: linux1 - name: Create file file2.txt copy: dest: /home/file2.txt content: | This is File2 Mytext {{ mytext }} lol lol lol lol lol - name: reboot my servers shell: sleep 4 && reboot now async: 1 poll: 0 - name: wait my server will come online wait_for: host: "{{ inventory_hostname }}" state: started delay: 5 timeout: 40 delegate_to: 127.0.0.1 ... |
ansible перехват и контроль ошибок , игнор , failed_when , result.rc , any_errors_fatal
playbook.yml пытаемся установить не существующий пакет treeee и выводим echo
|
--- - name: Error find and control hosts: all become: yes tasks: - name: Tasks number1 yum: name=treeee state=present - name: Tasks number2 shell: echo Hellow world! - name: Tasks number3 shell: echo Privet Man! ... |
playbook.yml ignore_errors игнорим ошибки и выполняем следующие таски
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
--- - name: Error find and control hosts: all become: yes tasks: - name: Tasks number1 yum: name=treeee state=present ignore_errors: yes - name: Tasks number2 shell: echo Hellow world! - name: Tasks number3 shell: echo Privet Man! ... |
playbook.yml дебаг ignore_errors
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
--- - name: Error find and control hosts: all become: yes tasks: - name: Tasks number1 yum: name=treeee state=present ignore_errors: yes - name: Tasks number2 shell: ls -la /var/ register: results - debug: var: results - name: Tasks number3 shell: echo Privet Man! ... |
playbook.yml failed_when
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
--- - name: Test ansible hosts: all become: yes tasks: - name: Tasks number1 yum: name=treeee state=present ignore_errors: yes - name: Tasks number2 shell: echo Hellow world register: results failed_when: "'world' in results.stdout" - debug: var: results - name: Tasks number3 shell: echo Privet Man! ... |
playbook.yml failed_when result.rc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
--- - name: Test ansible hosts: all become: yes tasks: - name: Tasks number1 yum: name=treeee state=present ignore_errors: yes - name: Tasks number2 shell: echo Hellow world register: results failed_when: result.rc == 0 # failed_when: "'world' in results.stdout" - debug: var: results - name: Tasks number3 shell: echo Privet Man! ... |
playbook.yml выполнится только там где есть file1.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
--- - name: Test ansible hosts: all become: yes tasks: - name: Tasks number1 yum: name=treeee state=present ignore_errors: yes - name: Tasks number2 shell: cat /home/secret/file1.txt register: results - debug: var: results - name: Tasks number3 shell: echo Privet Man! ... |
playbook.yml any_errors_fatal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
--- - name: Test ansible hosts: all any_errors_fatal : true become: yes tasks: - name: Tasks number1 yum: name=treeee state=present ignore_errors: yes - name: Tasks number2 shell: cat /home/secret/file71.txt register: results - debug: var: results - name: Tasks number3 shell: echo Privet Man! ... |
ansible , ansible-vault , хранение секретов , шифрованный файл , шифрованные строки
вводное
|
ansible-vault create mysecret.txt - создание специального зашифрованного файла для хранения секретов (AES256) (редактор vim) ansible-vault view mysecret.txt - посмотреть зашифрованный файл (просто cat) ansible-vault edit mysecret.txt - редактировать зашифрованный файл (редактор vim) ansible-vault encrypt playbook_vault.yml - шифруем файл playbook_vault.yml (AES256) ansible-vault decrypt playbook_vault.yml - расшифровываем файл playbook_vault.yml ansible-playbook playbook_vault.yml --ask-vault-pass - запуск зашифрованного playbook, ansible попросит ввести пароль ansible-playbook playbook_vault.yml --vault-password-file mypass.txt - запуск зашифрованного playbook, ansible будет искать пароль в mypass.txt (пароль просто записан текстом) |
playbook_vault.yml — будем шифровать этот файл
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
--- - name: vault playbook hosts: all become: yes vars: admin_pass: Pass123 tasks: - name: Install package tree yum: name=tree state=present - name: Create Config File copy: dest: "/home/secret/myconfig.conf" content: | port = 9092 log = 7days home = /home/secret/ user = admin password = {{ admin_pass }} ... |
Шифрование строк в ansible
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
ansible-vault encrypt_string - шифрование строки ansible-vault encrypt_string --stdin-name "Mypassword" - шифрование строки New Vault password: у нас спрашивают для пароль для расшифровки, ввел 1 Confirm New Vault password: вводим пароль для расшифровки еще раз 1 Reading plaintext input from stdin. (ctrl-d to end input) нажимаем Ctrl+d Pass123 - это мы шифруем Mypassword: !vault | $ANSIBLE_VAULT;1.1;AES256 39633633373832373034633265323832353636363733643431636535346535643532643439386435 6638306639306430363664633036386332313133373231390a386338373232373765353964373634 35363336353962646137663631366265336362323431393263356436313935373735366465363936 3265633730376163390a376564336565316330393261373931356339656164366162633839666463 6337 Encryption successful Нас интересует вот это !vault | $ANSIBLE_VAULT;1.1;AES256 39633633373832373034633265323832353636363733643431636535346535643532643439386435 6638306639306430363664633036386332313133373231390a386338373232373765353964373634 35363336353962646137663631366265336362323431393263356436313935373735366465363936 3265633730376163390a376564336565316330393261373931356339656164366162633839666463 6337 echo -n "$%^SecretWord&&^%" | ansible-vault encrypt_string - еще один вариант шифровать строку New Vault password: Confirm New Vault password: Reading plaintext input from stdin. (ctrl-d to end input) !vault | $ANSIBLE_VAULT;1.1;AES256 37343432306532653463666138393336396366303664613332373337323730623034663639336530 3561333338623638343532396130636461356638643931640a303436613561343634363965373863 62663935313362363535663064316635643636613535386438366239623265633633663066396237 6430396435323739370a343964613933633964353937336437346536656364313738323130613836 35613038326338633439623063396264303961313639376466363332323362623866 Encryption successful |
Шифрование строки в plabook.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
--- - name: vault playbook hosts: all become: yes vars: admin_pass: !vault | $ANSIBLE_VAULT;1.1;AES256 39633633373832373034633265323832353636363733643431636535346535643532643439386435 6638306639306430363664633036386332313133373231390a386338373232373765353964373634 35363336353962646137663631366265336362323431393263356436313935373735366465363936 3265633730376163390a376564336565316330393261373931356339656164366162633839666463 6337 tasks: - name: Install package tree yum: name=tree state=present - name: Create Config File copy: dest: "/home/secret/myconfig.conf" content: | port = 9092 log = 7days home = /home/secret/ user = admin password = {{ admin_pass }} ... ansible-playbook playbook_vault.yml --ask-vault-pass - запуск playbook с зашифрованной строкой |