У меня есть хост с двумя серверами: на одном установлен CentOS, а на другом — Ubuntu.
Я решил установить Apache, Nginx и PHP-FPM на оба сервера и написал 3 сценария.
- ubuntu.yml (/home/ansible/playbook):
---
- name: Ubuntu Playbook
hosts: ubun
become: true
vars:
- packages:
- nginx
- apache2
- php-fpm
tasks:
- name: Update apt package
apt:
name: "*"
state: latest
update_cache: yes
- name: Install Packages
apt:
pkg: "{{ packages }}"
state: latest
update_cache: yes
- name: Apache Service Start
service:
name: nginx
state: restarted
enabled: yes
- centos.yml (/home/ansible/playbook):
---
- name: CentOS Playbook
hosts: cent
become: true
vars:
packages:
- epel-release
- httpd
- nginx
- php-fpm
tasks:
- name: Update yum package
yum:
name: "*"
state: latest
update_cache: yes
- name: Install Packages
yum:
name: "{{ packages }}"
state: latest
update_cache: yes
- name: Apache Service Start
service:
name: nginx
state: restarted
enabled: yes
- base.yml (/home/ansible/playbook):
---
- name: Base Playbook
hosts: aws
become: true
tasks:
- name: Performing Tasks for CentOS
when: ansible_facts['distribution'] == 'CentOS'
include_tasks: centos.yml
- name: Performing Tasks for Ubuntu
when: ansible_facts['distribution'] == 'Ubuntu'
include_tasks: ubuntu.yml
Мои 3 группы Ansible:
[aws], который содержит как сервер,
[cent] который содержит сервер CentOS
[ubun] который содержит сервер Ubuntu
Я попробовал сухой запуск centos.yml
и ubuntu.yml
по отдельности, и это сработало, но при попытке сухого запуска base.yml
возникает следующая ошибка:
FAILED! => {"reason": "unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>\n\nThe error appears to be in '/home/ansible/playbook/centos.yml': line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n---\n- name: CentOS Playbook\n ^ here\n"}
FAILED! => {"reason": "unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>\n\nThe error appears to be in '/home/ansible/playbook/ubuntu.yml': line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n---\n- name: Ubuntu Playbook\n ^ here\n"}
Я уже пробовал заменить import_tasks
на, include_tasks
но получаю ту же ошибку.
решение1
Мое решение — объединить их в одну пьесу, поскольку они делают одно и то же.
---
- name: php-fpm play
hosts: aws
become: true
vars:
- repo:
Debian:
- apt # already installed, but need something here
RedHat:
- epel-release
- packages:
Debian:
- apache2
#- nginx # cannot have 2 listening on port 80
- php-fpm
RedHat:
- httpd
#- nginx
- php-fpm
- services:
Debian: apache2
RedHat: httpd
tasks:
# TODO move update * task to different play
- name: Install repo
# Seperate package transaction for EPEL
# so it is available in the next task
package:
name: "{{ repo[ansible_os_family] }}"
- name: Install Web Server Packages
# Keyed by OS family fact to also support RHEL and Debian
package:
name: "{{ packages[ansible_os_family] }}"
state: latest
- name: Web Service Start
service:
name: "{{ services[ansible_os_family] }}"
state: restarted
enabled: yes
Невозможно иметь несколько серверов, прослушивающих порты 80 и 443. Я закомментировал nginx, так как задача была неправильно названа "Apache Service Start". Если вы хотите, чтобы один из них проксировал другой или что-то в этом роде, вам нужно будет развернуть файл конфигурации, чтобы изменить порты.
Использовалось package:
действие, делегирующее фактическому менеджеру пакетов. Позволяет запускать задачу установки пакета на разных ОС. update_cache
Так сделать нельзя, но yum не нуждается в этом при добавлении репозиториев, как это делает apt.
Структура Vars — это dicts значений, специфичных для семейства ОС. Это позволяет индексировать имена пакетов и служб по фактам. Семейство ОС, поэтому это также работает на RHEL и Debian в дополнение к CentOS и Ubuntu.
Отступ был неправильным. Параметры модулей должны быть отступлены на уровень ниже директив уровня задачи, таких как name:
.
Не может ли include_tasks
целая пьеса, которая работает только с import_playbook
. include_tasks
проще, когда у вас есть роли, у которых есть каталог задач для таких файлов. (Задачи уровня пьесы — это вещь, но я за то, чтобы роли делали все.)
Еще многое предстоит сделать, чтобы сделать это полезным.
Когда вам необходимо использовать template
для установки конфигурации, EL помещает конфигурации в /etc/httpd/
, а Debian — в /etc/apache2/
.
Множество ролей веб-сервера имеют открытый исходный код, который можно посмотреть, если вам нужны идеи. ПроверитьГалактика.
Рассмотрите возможность переноса задач в роли, что позволит повторно использовать их.
решение2
Лучше взять в качестве примера роль, вот вам фиксированный код:
---
- hosts: aws
remote_user: myuser
become: true
tasks:
- name: Performing Tasks for CentOS
include_tasks: centos.yml
when: ansible_facts['distribution'] == 'CentOS'
- name: Performing Tasks for Ubuntu
include_tasks: ubuntu.yml
when: ansible_facts['distribution'] == 'Ubuntu'
задачи centos.yml:
---
- name: installing httpd
yum: pkg=httpd state=present
Задачи ubuntu.yml:
- name: installing apache2
apt: pkg=apache2 state=present
В файлах задач вам нужны только сами задачи, без хостов, задач и т. д.