Ansible を使用して複数の OS に複数のパッケージをインストールする

Ansible を使用して複数の OS に複数のパッケージをインストールする

2 台のサーバーを持つホストがあります。1 台には CentOS がインストールされ、もう 1 台には Ubuntu がインストールされています。

両方のサーバーに apache、nginx、php-fpm をインストールすることにし、3 つのプレイブックを作成しました。

  1. 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
  1. 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
  1. 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.ymlubuntu.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

私の解決策は、これらが同じことを行うので、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 で複数のサーバーを listen させることはできません。タスクが誤って「Apache Service Start」とラベル付けされていたため、nginx をコメント アウトしました。これらのうちの 1 つを他のサーバーにプロキシさせたい場合などには、ポートを変更する構成ファイルを展開する必要があります。

実際のパッケージ マネージャーに委任するアクションを使用しましたpackage:。パッケージ インストール タスクをさまざまな OS で実行できるようにします。この方法では実行できませんupdate_cacheが、yum では apt のようにリポジトリを追加するときにこれは必要ありません。

Vars 構造は、OS ファミリー固有の値の辞書です。これにより、パッケージ名とサービス名をファクトでインデックス化できます。OS ファミリーなので、CentOS と Ubuntu に加えて、RHEL と Debian でも機能します。

インデントが間違っています。モジュール パラメータは、 などのタスク レベルのディレクティブより 1 レベル下にインデントする必要がありますname:

include_tasksのみ機能するプレイ全体は、そのようなファイル用のタスク ディレクトリを持つロールがあると簡単になりますimport_playbookinclude_tasks(プレイ レベルのタスクはありますが、私はロールですべてを行うことに賛成です。)


これを有用なものにするには、まだ作業が必要です。

設定をインストールするためにを使用する必要がある場合template、EL は configs を に配置します/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

タスク ファイルでは、ホストやタスクなどがなく、タスクのみが必要です。

関連情報