0. Свеженький debian 11
1. Ставим пакеты
apt-get install git pip sshpass
pip install ansible
pip install Jinja2>=2.11
2. Добавляем пользователя от которого будем все ставить
!!! На сервере куда будем устанавливать также его добавляем
adduser user
2.1 Переключаемся на пользователя user
su - user
3. Генерируем ключи и отправляем его на сервер куда будем ставить openwisp
ssh-keygen
ssh-copy-id YOU_IP_ADDRESS
4. Устанавливаем galaxy openwisp.openwisp2 под пользователем user
ansible-galaxy install openwisp.openwisp2
ansible-galaxy collection install "community.general:>=3.6.0"
5. Создаем каталог и переходим в него
mkdir ~/openwisp2-ansible-playbook
cd ~/openwisp2-ansible-playbook
6. Создаем конфиг для ansible
vim ansible.cfg
---------------
[defaults]
host_key_checking = False
pipelining = True
deprecation_warnings = False
retry_files_enabled = False
inventory = ./hosts.txt
#roles_path = ./roles
forks = 10
timeout = 10
log_path = ./ansible.log
interpreter_python = python3
[diff]
always = True
context = 3
---------------
7. Создаем файл с хостами на которые будем накатывать openwisp
vim hosts
---------
[openwisp2]
YOU_IP_OR_DNS
---------
8. Готовим playbook opewisp
vim playbook.yml
----------------
- hosts: openwisp2
roles:
- openwisp.openwisp2
# the following line is needed only when an IP address is used as the inventory hostname
vars:
postfix_myhostname: localhost
openwisp2_network_topology: true
openwisp2_monitoring: true
openwisp2_firmware_upgrader: true
openwisp2_radius: true
----------------
Готовим сервер куда будем устанавливать openwisp:
0. Ставим пакеты
apt install sshpass python pip python3-pip git sudo
1. Редактируем sudo для пользователя user
visudo
-------------------------------
user ALL=(ALL) NOPASSWD: ALL
-------------------------------
2. Пример /etc/apt/source.list в debian 11:
!!! Внимание по рекомендации openwisp должна быть свежая система
!!! # Включение бэк портов на сервере (куда ставим) приводит к ошибки установки redis
-----------------------------------------------------------------
deb http://deb.debian.org/debian bullseye main contrib non-free
deb-src http://deb.debian.org/debian bullseye main contrib non-free
deb http://deb.debian.org/debian-security/ bullseye-security main contrib non-free
deb-src http://deb.debian.org/debian-security/ bullseye-security main contrib non-free
deb http://deb.debian.org/debian bullseye-updates main contrib non-free
deb-src http://deb.debian.org/debian bullseye-updates main contrib non-free
#deb http://deb.debian.org/debian bullseye-backports main contrib non-free
#deb-src http://deb.debian.org/debian bullseye-backports main contrib non-free
------------------------------------------------------------------
Приступаем к установке( На сервере с ansible):
!!! При установке на debian 11 могут быть несколько проблем ()
0. Проверяем и правим файл в зависимости от версии pip
!!! не правильная версия pip будет приводить к даунгрейду и ошибкам дальнейшей установки openwisp
vim ~/.ansible/roles/openwisp.openwisp2/tasks/pip.yml
-----------------------------------------------------
- pip==22.0.4
# - pip==20.2.4
-----------------------------------------------------
1. Переходим в каталог
cd /home/user/openwisp2-ansible-playbook
2. Запускаем установку
ansible-playbook -i hosts playbook.yml -b
3. Наблюдаем за выхлопом ansible и в случаи не удачи, решаем проблемы.
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-inventory --list - покажет все хосты и какие переменные к ним относятся
ansible-inventory --graph - - покажет все хосты и какие группы в виде дерева
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»
!!! Вот такая ошибка "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
...
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
---
- 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
Просто страничка для тестов
hello MEN
страница generate
print owner: {{ owner }}
print hostname: {{ ansible_hostname }}
print fqdn: {{ ansible_fqdn }}
print os: {{ ansible_os_family }}
IP address: {{ ansible_default_ipv4.address }}
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, будут созданы каталоги и файлы
---------------------------------------
└── 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
---
- 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
---
# 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 }}
...
---
- 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 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
---
- 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 и ждем
---
- 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
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
Прежде чем использовать модули shell в ansible убедитесь что нет подходящего модуля что бы решить вашу проблему!!!
Прежде чем использовать модули shell в ansible убедитесь что нет подходящего модуля что бы решить вашу проблему!!!
Прежде чем использовать модули shell в ansible убедитесь что нет подходящего модуля что бы решить вашу проблему!!!
!!! expect - является языком сценариев, основные команды: expect(ожидает строку) и send(отправляет ответ)
!!! autoexpect - позволяет создать файл сценарий, по умолчанию с именем script.exp
cd /root - перешли в каталог root
autoexpect mysql_secure_installation - будет создан script.exp сценарий ответов на команду mysql_secure_installation
/root/script.exp - будет выполнен скрипт mysql_secure_installation и применятся ответы из script.exp
Пример:
Допустим, у нас есть простой сценарий оболочки test.sh
Он берет IP-адрес и порт, затем запускает команду nc.
cat test.sh
-----------------------------------------------------
#!/bin/bash
echo "IP address:"
read ip_addr
echo "Port:"
read port
nc -vz $ip_addr $port
-----------------------------------------------------
Пример playbook для скрипта
cat ansible-playbook
---------------------------
- hosts: localhost
vars:
send_ip_addr: "1.2.3.4"
send_port: "22"
tasks:
- shell: |
spawn ./test.sh
expect "IP address:"
send -- "{{ send_ip_addr }}
"
expect "Port:"
send -- "{{ send_port }}
"
expect eof
args:
executable: /usr/bin/expect
---------------------------
Пример 0:
# You can use shell to run other executables to perform actions inline
- name: Run expect to wait for a successful PXE boot via out-of-band CIMC
shell: |
set timeout 300
spawn ssh admin@{{ cimc_host }}
expect "password:"
send "{{ cimc_password }}\n"
expect "\n{{ cimc_name }}"
send "connect host\n"
expect "pxeboot.n12"
send "\n"
exit 0
args:
executable: /usr/bin/expect
delegate_to: localhost
Пример 1:
- name: Case insensitive password string match
ansible.builtin.expect:
command: passwd username
responses:
(?i)password: "MySekretPa$$word"
# you don't want to show passwords in your logs
no_log: true
Пример 2:
- name: Generic question with multiple different responses
ansible.builtin.expect:
command: /path/to/custom/command
responses:
Question:
- response1
- response2
- response3
Пример 3:
- name: Install Asternic
shell: |
set timeout 60
cd /usr/src/asternic-stats-pro-2.3.5
spawn /bin/bash -c "make install"
expect "Please enter the MySQL root password: "
send "{{ mysql_root_password }}\n"
expect "Select a password for the 'admin' user: "
send "{{ asternic_password }}\n"
expect "Confirm the password for the 'admin' user: "
send "{{ asternic_password }}\n"
sleep 60 # Нужно для того что бы было время установится и терминал не захлопнулся.
exit 0
args:
executable: /usr/bin/expect
https://docs.ansible.com/ - документация
https://docs.ansible.com/ansible/latest/reference_appendices/config.html - параметры конфига
https://jinja.palletsprojects.com/en/3.0.x/ - язык jinga, используется в шаблонах ansible
https://docs.ansible.com/ansible/latest/user_guide/playbooks_tags.html - пример с тегами
https://galaxy.ansible.com/ - роли
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html - роли
https://ansible-for-network-engineers.readthedocs.io/ru/latest/ - для сетевых инженеров
https://github.com/natenka/Ansible-for-network-engineers - для сетевых инженеров
https://molecule.readthedocs.io/en/latest/ - молекула, автоматизация проверок playbook
https://habr.com/ru/post/437216/ - молекула, автоматизация проверок playbook
https://github.com/ansible/awx - автоматизация ansible, планировщик
https://github.com/ansible/awx/blob/devel/INSTALL.md - автоматизация ansible, планировщик
ansible.cfg
[defaults]
host_key_checking = False ### не проверять ключи
pipelining = True
deprecation_warnings = False
retry_files_enabled = False # не будут создаваться файлы при не удачном подключение
inventory = ./hosts.txt ### файл с описанием хостов
roles_path = ./roles ### каталог ролей
forks = 10 ### количество одновременных выполнений
timeout = 10
log_path = ./ansible.log ### файл с логами
interpreter_python = python3
#ansible_user = vagrant # пользователь по умолчанию
#auto_silent=auto
#transport = ssh
#allow_world_readable_tmpfiles = true # Решает баг с py mysql
[diff]
always = True #
context = 3
hosts.txt
#Применить локально
localhost ansible_connection=local
[all_servers:vars] #переменные для группы all_servers
ansible_user = root
ansible_connection=ssh
[all_servers] #группа all_servers
192.168.1.31
[CentOS7:vars] #переменные для группы CentOS7
ansible_python_interpreter=/usr/bin/python2
ansible_user = root
ansible_connection=ssh
#ansible_user=vagrant
#ansible_ssh_pass=vagrant
[CentOS7] №группа CentOS7
192.168.1.244
superserver
[prod_servers:vars] #переменные для группы prod_servers
ansible_user=USERNAME1
ansible_ssh_private_key_file=/home/USERNAME1/.ssh/nameSSHKey1.pem
[prod_servers] #групп prod_servers
linux1 ansible_host=192.168.1.14
linux2 ansible_host=192.168.1.15
#Пример с группировкой хостов
[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_DB, staging_WEB, staging_APP) сгруппировали в одну группу staging_ALL
[staging_ALL:children]
staging_DB
staging_WEB
staging_APP
#Хосты из группы (staging_APP, prod_APP) сгруппировали в группу APP_ALL
[APP_ALL:children]
staging_APP
prod_APP
[APP_ALL:vars] #для группы APP_ALL задали переменную
message=Hello
[staging_servers] # Также переменные можно задавать для хоста
linuXXX ansible_host=192.168.1.16 ansible_user=USERNAME7 ansible_ssh_private_key_file=/home/USERNAME7/.ssh/id_rsa
test.yaml
test.yaml
---
- name: My TEST Playbook
hosts: all
become: yes
tasks:
- name: Ping test
ping:
...
Пример обновления пакетов :
---
- hosts: all
become: yes
tasks:
- name: Cheack and Print Linux Version
debug: var=ansible_os_family
- name: Debian update apt-get repo and cache
apt: update_cache=yes force_apt_get=yes cache_valid_time=3600
when: ansible_os_family == "Debian"
- name: Debian upgrade all apt packages
apt: upgrade=dist force_apt_get=yes
when: ansible_os_family == "Debian"
- name: CentOS upgrade all packages
yum:
name: '*'
state: latest
when: ansible_os_family == "RedHat"
...
Пример создание пользователя, создания файлов и условия(when), debug
# when - выполнить если
---
- hosts: all
become: yes
gather_facts: false
vars:
source_file_group_sudo: ./FILE_SUDO
destin_file_group_sudo: /etc/sudoers.d/FILE_SUDO
user_name: USERNAME
user_key_pub: USERKEY.pub
user_password: USER_HESH_PASSWORD
user_groups_debian: sudo,ADD_GROUP
user_groups_centos: wheel,ADD_GROUP
add_group: ADD_NEW_GROUP
tasks:
- name: Add a group called
group:
name: "{{ add_group }}"
state: present
- name: Cheack and Print Linux Version
debug: var=ansible_os_family
- name: Copy file zxc to Servers
copy: src={{ source_file_group_sudo }} dest={{ destin_file_group_sudo }} mode=0555
- name: Add user to remote hosts
user: name={{ user_name }} groups={{ user_groups_debian }} shell=/bin/bash password={{ user_password }}
when: ansible_os_family == "Debian"
- name: Add user to remote hosts
user: name={{ user_name }} groups={{ user_groups_centos }} shell=/bin/bash password={{ user_password }}
when: ansible_os_family == "RedHat"
- name: Add SSH keys to remote hosts
authorized_key: user={{ user_name }} key="{{ lookup('file', "{{ user_key_pub }}") }}"
...
Пример файла FILE_SUDO
#--# zxc administrators
%zxc ALL=(ALL) NOPASSWD: ALL
Пример установки apache2, использование handlers и notify
# говорит что сделать
# где сделать
---
- 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
...
Loop, списки и циклы
# Существует несколько видов записи
# Пример первый:
#tasks/main.yaml
- name: install packages
yum:
name: {{ item }}
state: present
loop:
- htop
- bind-utils
- mtr
# Пример второй
#vars/main.yaml
packages:
- htop
- bind-utils
- mtr
# tasks/main.yml
name: install packages
yum:
name: {{ item }}
state: present
loop: {{ packages }}
# Пример третий
# tasks file for install_pkg
- name: Install a list of packages
apt:
pkg:
- libreoffice
- git
- wget
- curl
# Пример с пакетам для вуишфт
- name: Install a list of packages
apt:
pkg:
- qemu-kvm
- libvirt-daemon-system
- ovmf
- virtinst
- openvswitch-switch
- tcpdump
- git
- dnsutils
- mtr
- iotop
- virt-top
- logwatch
- postfix
- python3-minimal
- python3-pip
- python3-setuptools
- python3-libvirt
- python3-lxml
- smartmontools
state: latest
update_cache: True
when: ansible_os_family == "Debian"
TAG
Пример в таске:
- name: Install ntp
ansible.builtin.yum:
name: ntp
state: present
tags: ntp
Пример использования:
ansible-playbook --tags ntp name_playbook.yaml - будут выполнены из плейбука таски с тагом (ntp)
ansible-playbook --skip-tags ntp name_playbook.yaml - таски с тагом (ntp) будут проигнорированы , все остальные задачи будут выполнены
Роли \ roles
# Roles - это структурированные palybook, с возможностью версионности.
# В ansible.cfg должна быть запись (roles_path = ./roles) - каталог ролей
# cd roles
# ansible-galaxy init adduser_groups - создали роль
# структура роли
.
├── defaults # дефолтные переменные var
│ └── main.yml # Сюда сыпем наши переменные
├── handlers # обработчики (для notify)
│ └── main.yml
├── meta # мета данные
│ └── main.yml
├── README.md # описание ( например как создать paybook запуска)
├── tasks # задачи \ таски
│ └── main.yml # - include role.yaml
├── template # шаблоны (файлы j2, jinja)
│ └── main.yml
├── files # сюда складываем все статические файлы
│
├── tests # данные для тестов (используется очень редко)
│ ├── inventory
│ └── test.yml
└── vars # переменные с более высоким приоритетом
└── main.yml
Пример playbook для запуска роли:
---
- hosts: all
become: yes
gather_facts: false
roles:
- adduser_groups
...
Include и Import
!!! Отличие import от include заключается в следующем
!!! Include читает из файлов значения, ansible подставляет значения при выполнении (дошел до строчки с include тогда и подставил)
!!! Import читает и подставляет значения, ansible подставляет сразу все значения
!!! рекомендуют использовать include
!!! Также можно сократить запись
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
---
- 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"
...
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
---
- 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
---
# 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 - ну собственно запуск установки роли
!!! Пробелы ОЧЕНЬ ВАЖНЫ
!!! НЕ ИСПОЛЬЗУЙТЕ "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
...
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
--------------
Обычный текстовый файл
--- всегда начинаются с двух минусов
... заканчиваются точками
1. myfile.yml
---
- command1 первая команда начинается с одного минуса
- command2 вторая команда минус должен располагаться четко под минусом первой команды
...
2. myfile.yml
---
fruits: список команд заканчивается на двоеточие, и начинается с минуса если списков несколько
- apple
- orange
- mango
...
3. myfile.yml
---
- fruits: список команд заканчивается на двоеточие, и начинается с минуса если списков несколько
- apple
- orange
- mango
- vegetables:
- carrots
- cucumbers
...
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-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
-----------------------
Можно записывать так просто перечислить 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 - - покажет все хосты и какие группы в виде дерева
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 если все ок