Ansible — система управления конфигурациями

  • Михаил
  • 12 мин. на прочтение
  • 199
  • 20 Jun 2022
  • 20 Jun 2022

 

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