Ansible — система управления конфигурациями
Ansible — это программное решение для удаленного управления конфигурациями. Оно позволяет настраивать удаленные машины. Главное его отличие от других подобных систем в том, что Ansible использует существующую инфраструктуру SSH, в то время как другие (chef, puppet, и пр.) требуют установки специального PKI-окружения.
Ссылки:
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
Подключение:
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
Файл пример:
Можно записывать так просто перечислить 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-invertory --list - покажет все хосты и какие переменные к ним относятся
ansible-inventory --graph - - покажет все хосты и какие группы в виде дерева
ansible запуск ad-hoc команд, -m , ping , setup , shell , copy , file , get_url , yum , apt , service , uri , ansible-invertory , ansible-doc
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://bookflow.ru" - как бы тестик, проверить доступность страницы
ansible all -m uri -a "url=https://bookflow.ru 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-invertory --list - покажет все хосты и какие переменные к ним относятся
ansible-inventory --graph - покажет все хосты и какие группы в виде дерева
Для работы -b и ошибка «msg»: «Missing sudo password»
!!! Вот такая ошибка "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
---
- 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:
[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
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
---
- 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
---
- 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
---
- 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
---
- 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
---
- 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 по маске
---
- 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
<!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
---
- 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
вводное
cd ~ansible - зашли в домашний каталог ansible
mkdir roles - создали каталог roles
cd roles - зашли в каталог roles
ansible-galaxy init deploy_apache_web_site - создание роли, а точнее в каталоге roles, будут созданы каталоги и файлы
---------------------------------------
L-- deploy_apache_web_site
+-- defaults
¦ L-- main.yml
+-- files
+-- handlers
¦ L-- main.yml
+-- meta
¦ L-- main.yml
+-- README.md
+-- tasks
¦ L-- main.yml
+-- templates
+-- tests
¦ +-- inventory
¦ L-- test.yml
L-- vars
L-- main.yml
---------------------------------------
Наш playbook.yml который мы будем распихивать в роль deploy_apache_web_site
---
- 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 …
---
- 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
С файлами получится вот так:
L-- deploy_apache_web_site
+-- defaults
¦ L-- main.yml
+-- files
¦ +-- file0.txt
¦ +-- file1.txt
¦ +-- file2.txt
¦ +-- file3.txt
¦ +-- file4.txt
¦ +-- file5.txt
¦ L-- index.css
+-- handlers
¦ L-- main.yml
+-- meta
¦ L-- main.yml
+-- README.md
+-- tasks
¦ L-- main.yml
+-- templates
¦ L-- index.j2
+-- tests
¦ +-- inventory
¦ L-- test.yml
L-- vars
L-- 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
---
# 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
---
- 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
---
- 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
---
- 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
---
- name: My playbook create file
hosts: all
become: yes
vars:
mytext: "Privet ot bookflow"
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
---
- name: My playbook create file
hosts: all
become: yes
vars:
mytext: "Privet ot bookflow"
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 и ждем
---
- name: My playbook create file
hosts: all
become: yes
vars:
mytext: "Privet ot bookflow"
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 игнорим ошибки и выполняем следующие таски
---
- 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
---
- 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
---
- 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
---
- 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
---
- 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
---
- 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 — будем шифровать этот файл
---
- 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
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
---
- 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 с зашифрованной строкой
источник b14esh.com
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.