Ansible-сервер — Centos7 – ansible.kamaok.org.ua-192.168.1.40
Ansible-клиент- Debian8 — ansible-client.kamaok.org.ua-192.168.1.41
1.Установка Ansible на Centos7
Проверяем,что подключен EPEL-репозитарий
1 |
# yum repolist enabled | grep epel |
1 2 |
* epel: ftp.colocall.net epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 10,859 |
Установка Ansible
1 |
# yum install ansible |
Проверка версии установленной версии Ansible
1 |
# rpm -qa | grep ansible |
1 |
ansible-2.2.0.0-4.el7.noarch |
1 |
# ansible --version |
1 2 3 |
ansible 2.2.0.0 config file = /etc/ansible/ansible.cfg configured module search path = Default w/o overrides |
По умолчанию список хостов/групп, к которым применяются команды содержится в файле /etc/ansible/hosts,
1 |
# grep -E '^#inventory' /etc/ansible/ansible.cfg |
1 |
#inventory = /etc/ansible/hosts |
но при необходимости его можно переопределить с помощью опции
1 |
--inventory-file(-i) |
Добавим в inventory-файл описание групп и хостов
1 |
# nano /etc/ansible/hosts |
1 2 3 4 5 6 7 8 9 |
[web] 192.168.1.41 [localhost] 127.0.0.1 [all] 127.0.0.1 192.168.1.41 |
Создание пары SSH-ключей на Ansible-сервере
1 |
# ssh-keygen -t rsa -b 4096 -C root@ansible.kamaok.org.ua |
Добавим публичный ключ Ansible-сервера в файл ~/.ssh/authorized_keys на клиенте
Либо через команду
1 |
# ssh-copy-id root@192.168.1.41 |
Либо средствами самого Ansible через модуль authorized_key
1 |
# ansible web -m authorized_key -a "user=root key='{{ lookup('file', '/root/.ssh/id_rsa.pub') }}' path=/root/.ssh/authorized_keys manage_dir=no" --ask-pass |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
SSH password: 192.168.1.41 | SUCCESS => { "changed": true, "exclusive": false, "gid": 0, "group": "root", "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC3cVoUmYDUWAeqGC5869Otow6+6i1VPzjMPghrgfeoWVNuT/ujTVPEcMV0P5h4dL9h9WRgQT2AehoUVQDelMAbYJLa7b47hpMr8QCQ31m9QVTmgDGPiYywUi42zHsAqj1Ogfm0loMMKKT7No8TKqcuJ0maLcW5bySSr3ynwJrmXJ8cJuMSKnEZUAx4SpunwWWaNTpF84Z9ePS0SYxTw1ne+uJFDQ6NroIfYdVvwHW/iRMaZslC23FZTnZchvbGihR6SAx1ViUyBNm8Y+L3o719HIEZ3pwPKu4PJsUr9wfRllROQB0KPxO2Qjr8f0RI675eswolgrHPsv/KkTDoS/NhInpg7HdV7m1TdoCjth5PPu4BvUlR99kWsxSajieF2OVhakm2fFxRdoP43uTRiBVge1v6i+Igi+fmYygHIXZW5FL6Ep9VmfLNxThBGniQoO49Zy18X/jXaucC6dfcFkr/Z+8vPeFnPZuCIg0+LK6wHMsHBq8wfKqOfsG9LLPl6GLEG54mbP15aHPdPMKdKpz/ctZd1RDxNStYZfGzbKMzZ+nMvhXfsNIh+yw5AcUK3Vm3j/02tnxWj6c69Nsw8812MdLVxrSeUJNvcRupewPV0EdzKicdshh1vKI1MkdaLt0/Ao7a+rBvi72VYCl8CR8t6x8+0E7u6KDFcjkXT/oNlQ== root@ansible.kamaok.org.ua", "key_options": null, "keyfile": "/root/.ssh/authorized_keys", "manage_dir": false, "mode": "0600", "owner": "root", "path": "/root/.ssh/authorized_keys", "size": 1561, "state": "file", "uid": 0, "unique": false, "user": "root", "validate_certs": true } |
Проверяем беспарольный вход по SSH-ключам c сервера на клиента
1 |
# ssh 192.168.1.41 |
Также настроим безпарольный вход с Ansible-сервера на самого себя
1 |
# cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys |
Выполним несколько команд в Ad Hoc режиме
1 |
# ansible all -a 'uptime' |
1 2 3 4 5 |
192.168.1.41 | SUCCESS | rc=0 >> 22:44:35 up 1:28, 2 users, load average: 0.07, 0.10, 0.23 127.0.0.1 | SUCCESS | rc=0 >> 22:45:00 up 1:28, 2 users, load average: 0.33, 0.17, 0.25 |
1 |
# ansible all -m 'ping' |
1 2 3 4 5 6 7 8 |
192.168.1.41 | SUCCESS => { "changed": false, "ping": "pong" } 127.0.0.1 | SUCCESS => { "changed": false, "ping": "pong" } |
1 |
# ansible web -m command -a 'apt-get update' |
1 |
# ansible localhost -m command -a 'yum update' |
Установим sudo-пакет на клиенте с помощью Ansible-сервера
1 |
# ansible web -m apt -a "name=sudo state=present" |
Установим пакетный менеджер Python — pip
1 |
# ansible web -m apt -a "name=python-pip state=present" |
Установим Passlib через Ansible
1 |
# ansible web -m command -a 'pip install passlib' |
С клиента узнаем хеш-пароля пользователя,который будет создан на клиенте
1 |
root@ansible-client:~# python -c "from passlib.hash import sha512_crypt; print sha512_crypt.encrypt('mypassword')" |
1 |
$6$rounds=656000$6G5H7yesfp8FCM5o$HcCpYm3PR5wirg13F92LB5QfCzjTXvXg2Y1Ex8lkQlrJ72P2AsQnj5xHJXw.aB.6mXL2hbLaYK7M/SR92FcNO0 |
2.Создание playbook, который создает пользователя с привилегиями root-пользователя через sudo, добавит SSH-ключ для этого пользователя
1 |
# nano /etc/ansible/basic_user.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
--- - hosts: web remote_user: root vars: MY_USER_NAME: 'kamaok' tasks: - name: "Create a secondary, non-root user" user: name={{ MY_USER_NAME }} password='$6$rounds=656000$6G5H7yesfp8FCM5o$HcCpYm3PR5wirg13F92LB5QfCzjTXvXg2Y1Ex8lkQlrJ72P2AsQnj5xHJXw.aB.6mXL2hbLaYK7M/SR92FcNO0' shell=/bin/bash - name: Add remote authorized key to allow future passwordless logins authorized_key: user={{ MY_USER_NAME }} key="{{ lookup('file', '/root/.ssh/id_rsa.pub') }}" - name: Add normal user to sudoers lineinfile: dest=/etc/sudoers regexp="{{ MY_USER_NAME }} ALL" line="{{ MY_USER_NAME }} ALL=(ALL) ALL" state=present |
Выполняем этот плейбук
1 |
# ansible-playbook -u root /etc/ansible/basic_user.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.1.41] TASK [Create a secondary, non-root user] *************************************** changed: [192.168.1.41] TASK [Add remote authorized key to allow future passwordless logins] *********** changed: [192.168.1.41] TASK [Add normal user to sudoers] ********************************************** changed: [192.168.1.41] PLAY RECAP ********************************************************************* 192.168.1.41 : ok=4 changed=3 unreachable=0 failed=0 |
Проверяем, что на клиенте был создан пользователь kamaok и работает доступ по SSH-ключам
под этим пользователем
1 |
# ssh kamaok@192.168.1.41 |
А также то,что пользователь был добавлен в файл /etc/sudoers
1 |
root@ansible-client:~# grep kamaok /etc/sudoers |
1 |
kamaok ALL=(ALL) ALL |
3.Создание playbook для базовой настройки системы
Установка часового пояса
Настройка имени сервера
Обновление пакетов
1 |
# nano /etc/ansible/basic_system.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
--- - hosts: web remote_user: kamaok become: yes become_method: sudo vars: LOCAL_HOSTNAME: 'ansible-client' LOCAL_FQDN_NAME: 'ansible-client.kamaok.org.ua' tasks: - name: Set the timezone for the server to Europe/Kiev command: ln -sf /usr/share/zoneinfo/Europe/Kiev /etc/localtime - name: Set up a unique hostname hostname: name={{ LOCAL_HOSTNAME }} - name: Add the server's domain to the hosts file lineinfile: dest=/etc/hosts regexp='.*{{ item }}$' line="{{ hostvars[item].ansible_default_ipv4.address }} {{ LOCAL_FQDN_NAME }} {{ LOCAL_HOSTNAME }}" state=present when: hostvars[item].ansible_default_ipv4.address is defined with_items: "{{ groups['web'] }}" - name: Update packages apt: update_cache=yes upgrade=dist |
Выполняем плейбук
Будет запрошен пароль пользователя kamaok под которым и будут производиться все действия
1 |
# ansible-playbook /etc/ansible/basic_system.yml --ask-become-pass |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
SUDO password: PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.1.41] TASK [Set the timezone for the server to Europe/Kiev] ************************** changed: [192.168.1.41] [WARNING]: Consider using file module with state=link rather than running ln TASK [Set up a unique hostname] ************************************************ changed: [192.168.1.41] TASK [Add the server's domain to the hosts file] ******************************* changed: [192.168.1.41] => (item=192.168.1.41) TASK [Update packages] ********************************************************* ok: [192.168.1.41] PLAY RECAP ********************************************************************* 192.168.1.41 : ok=5 changed=3 unreachable=0 failed=0 |
Проверяем применились ли настройки на клиенте
1 |
root@ansible-client:~# ls -al /etc/localtime |
1 |
lrwxrwxrwx 1 root root 31 Dec 1 23:48 /etc/localtime -> /usr/share/zoneinfo/Europe/Kiev |
1 |
root@ansible-client:~# grep ansible-client /etc/hosts |
1 |
192.168.1.41 ansible-client.kamaok.org.ua ansible-client |
1 |
root@ansible-client:~# hostname -f |
1 |
ansible-client.kamaok.org.ua |
4.Создание playbook, который устанавливает Apache, MySQL, PHP
1 |
# nano /etc/ansible/basic_webserver.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
--- - hosts: web remote_user: kamaok become: yes become_method: sudo tasks: - name: "Install Apache, MySQL, PHP5" apt: name={{ item }} state=present with_items: - apache2 - mysql-server - python-mysqldb - php5 - php-pear - php5-mysql - name: "Turn on Apache and MySQL and set them to run on boot" service: name={{ item }} state=started enabled=yes with_items: - apache2 - mysql - name: Create a test database mysql_db: name=mytestdb state=present - name: Create a new user for connections mysql_user: name=mytestuser password=mysqlpassword priv=*.*:ALL host=localhost state=present - name: Install Hello World PHP script copy: src=index.php dest=/var/www/html/index.php mode=0664 |
Создаем фалй index.php
1 |
# cd /etc/ansible/ |
1 |
# echo -e "<?php\necho 'Hello World';\n" > ./index.php |
Выполняем этот плейбук
1 |
# ansible-playbook /etc/ansible/basic_webserver.yml --ask-become-pass |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
SUDO password: PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.1.41] TASK [Install Apache, MySQL, PHP5] ********************************************* changed: [192.168.1.41] => (item=[u'apache2', u'mysql-server', u'python-mysqldb', u'php5', u'php-pear', u'php5-mysql']) TASK [Turn on Apache and MySQL and set them to run on boot] ******************** ok: [192.168.1.41] => (item=apache2) ok: [192.168.1.41] => (item=mysql) TASK [Create a test database] ************************************************** ok: [192.168.1.41] TASK [Create a new user for connections] *************************************** changed: [192.168.1.41] TASK [Install Hello World PHP script] ****************************************** changed: [192.168.1.41] PLAY RECAP ********************************************************************* 192.168.1.41 : ok=5 changed=3 unreachable=0 failed=0 |
Проверяем установку Apache, PHP, MySQL
5.Создание playbook для установки Nginx (предварительно остановив apache)
Создаем структуру каталогов
1 |
# mkdir -p /etc/ansible/roles/nginx/{files,tasks} |
Создаем файл index.html
1 |
# nano /etc/ansible/roles/nginx/files/index.html |
1 |
Nginx was installed via Ansible role |
Создаем файл с описанием задачи
1 |
# nano /etc/ansible/roles/nginx/tasks/main.yml |
1 2 3 4 5 6 7 8 9 |
--- - name: Update local cache packets and install package nginx apt: name=nginx state=present update_cache=yes - name: Starting service nginx and enable to autoload service: name=nginx state=started enabled=true - name: Copy file index.html copy: src=index.html dest=/var/www/html/index.html mode=0664 |
Файл basic_nginx приводим к виду
1 |
# nano /etc/ansible/basic_nginx.yml |
1 2 3 4 5 6 7 |
--- - hosts: web remote_user: kamaok become: yes become_method: sudo roles: - nginx |
1 |
# ansible-playbook /etc/ansible/basic_nginx.yml --ask-become-pass |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
SUDO password: PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.1.41] TASK [nginx : Update local cache packets and install package nginx] ************ changed: [192.168.1.41] TASK [nginx : Starting service nginx and enable to autoload] ******************* ok: [192.168.1.41] TASK [nginx : Copy file index.html] ******************************************** changed: [192.168.1.41] PLAY RECAP ********************************************************************* 192.168.1.41 : ok=4 changed=2 unreachable=0 failed=0 |
Проверяем, стартовую страницу,которую должен открыть Nginx
6.Настройка вложенных плейбуков (вызов одного плейбука из другого плейбука)
Например, создадим playbook для обновления локального кеша пакетов и установленных пакетов и подключим его в playbook по установке Nginx
1 |
# nano /etc/ansible/roles/nginx/tasks/update_os.yml |
1 2 3 4 5 6 |
--- - name: Update local cache packets apt: update_cache=yes - name: Upgrade packets apt: upgrade=full |
Файл с описанием задачи примит вид
1 |
# nano /etc/ansible/roles/nginx/tasks/main.yml |
1 2 3 4 5 6 7 8 9 10 11 12 |
--- - include: update_os.yml - name: Install package nginx apt: name=nginx state=present - name: Starting service nginx and enable to autoload service: name=nginx state=started enabled=true - name: Copy file index.html copy: src=index.html dest=/var/www/html/index.html mode=0664 |
Плейбук для установки Nginx имеет прежний вид
1 |
# nano /etc/ansible/basic_nginx.yml |
1 2 3 4 5 6 7 |
--- - hosts: web remote_user: kamaok become: yes become_method: sudo roles: - nginx |
Проверка синтаксиса плейбука
1 |
# ansible-playbook /etc/ansible/basic_nginx.yml --syntax-check |
1 |
playbook: /etc/ansible/basic_nginx.yml |
Запуск плейбука
1 |
# ansible-playbook /etc/ansible/basic_nginx.yml --ask-become-pass |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
SUDO password: PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.1.41] TASK [nginx : Update local cache packets] ************************************** changed: [192.168.1.41] TASK [nginx : Upgrade packets] ************************************************* fatal: [192.168.1.41]: FAILED! => {"changed": false, "failed": true, "msg": "Could not find aptitude. Please ensure it is installed."} to retry, use: --limit @/etc/ansible/basic_nginx.retry PLAY RECAP ********************************************************************* 192.168.1.41 : ok=2 changed=1 unreachable=0 failed=1 |
Установим пакет aptitude на клиенте через модуль apt Ansible-сервера
1 |
# ansible web -m apt -a "name=aptitude state=present" |
После чего снова запускаем плейбук по установке Nginx
1 |
# ansible-playbook /etc/ansible/basic_nginx.yml --ask-become-pass |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
SUDO password: PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.1.41] TASK [nginx : Update local cache packets] ************************************** changed: [192.168.1.41] TASK [nginx : Upgrade packets] ************************************************* ok: [192.168.1.41] TASK [nginx : Install package nginx] ******************************************* ok: [192.168.1.41] TASK [nginx : Starting service nginx and enable to autoload] ******************* ok: [192.168.1.41] TASK [nginx : Copy file index.html] ******************************************** changed: [192.168.1.41] PLAY RECAP ********************************************************************* 192.168.1.41 : ok=6 changed=2 unreachable=0 failed=0 |
Полезные команды ansible
Проверка синтаксиса playbook
1 |
# ansible-playbook /etc/ansible/basic_webserver.yml --syntax-check |
1 |
playbook: /etc/ansible/basic_webserver.yml |
Просмотр задач, которые будут выполнены
1 |
# ansible-playbook /etc/ansible/basic_webserver.yml --list-tasks |
1 2 3 4 5 6 7 8 |
playbook: /etc/ansible/basic_webserver.yml play #1 (web): web TAGS: [] tasks: Install Apache, MySQL, PHP5 TAGS: [] Turn on Apache and MySQL and set them to run on boot TAGS: [] Create a test database TAGS: [] Create a new user for connections TAGS: [] Install Hello World PHP script TAGS: [] |
Просмотр списка хостов, на которых будет выполняться playbook
1 |
# ansible-playbook /etc/ansible/basic_webserver.yml --list-hosts |
1 2 3 4 5 6 |
playbook: /etc/ansible/basic_webserver.yml play #1 (web): web TAGS: [] pattern: [u'web'] hosts (1): 192.168.1.41 |
Выполнение определенной части плейбука(не всего плейбука)(например, части с именем «Install Hello World PHP script»
1 |
# ansible-playbook /etc/ansible/basic_webserver.yml --start-at-task="Install Hello World PHP script" --ask-become-pass |
1 2 3 4 5 6 7 8 9 10 11 12 |
SUDO password: PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [192.168.1.41] TASK [Install Hello World PHP script] ****************************************** ok: [192.168.1.41] PLAY RECAP ********************************************************************* 192.168.1.41 : ok=2 changed=0 unreachable=0 failed=0 |
Источник:
http://docs.ansible.com/ansible/
https://www.linode.com/docs/applications/ansible/getting-started-with-ansible
https://letsclearitup.com.ua/category/ansible