LoginSignup
2
1

More than 5 years have passed since last update.

【Ansible】varsファイルをOSディストリビューションごとに切り替える

Last updated at Posted at 2018-10-28

はじめに

同じパッケージであるにも関わらず、ディストリビューションで名称が違う場合があります。またインストールパス/設定ファイルのパスが微妙に違う場合があります。

たとえばApache2.4のパッケージ名は、CentOS7の場合は「httpd」ですが、Amazon Linuxの場合は「httpd24」となります。タスクごとにwhen句で指定しても良いのですが、同じ値を複数個所で使う場合はPlaybookが煩雑になります。

このような場合、ディストリビューション/OS環境ごとに変数をあらかじめ定義し、切り替えられたら便利です。またこの制御をグローバルに行う(≒Role呼び出し元のPlaybookで制御する)のではなく、Roleに閉じた範囲で制御できた方が見通しが良くなります。

このようなケースの解決策を以下にまとめます。

TL;DR

  • vars(roles/????/vars/main.yml)の中ではwhen句で切り替えられない
  • 各Roleのタスク(roles/????/tasks/main.yml)で、include_varsを使う
  • include_varsと併せてwhen句を使う

試してみる

環境

CentOS7とAmazon Linuxで動作を確認しました。
いずれもVirtual BoxとVagrantでローカルにVMを作った環境となります。

必要な設定ファイル、Playbookは下記に公開しています。
https://github.com/tmiki/server-config

CentOS7

OS: CentOS Linux release 7.5.1804 (Core)
Python: 2.7.5
Ansible: 2.7.0

Amazon Linux

OS: Amazon Linux AMI 2017.03
Python: 2.7.12
Ansible: 2.6.4

Ansible Playbookディレクトリ構成

Ansible Playbookのディレクトリ構成は下記であるとします。

/path/to/ansible-playbooks/
  - ansible.cfg
  - ssh_config
  - sys_local.yml  ### ローカルホスト用のPlaybook。この中で各種Roleを読み込む。
  - hosts/  ### 環境ごとのホスト、変数の定義。今回は省略。
  - roles/  ### 各種Roleを格納しているディレクトリ
    - common/
    - common_httpd/  ### 今回はこのRoleの中の話になります。
    - common_supervisor/
    - :
    - :

Playbookの定義

まず、OSディストリビューションごとに変数定義ファイルを用意します。名前は、vars-CentOS7.ymlとvars-AmazonLinux.ymlとします。
これらのvarsファイルの中で、「httpd_package_name」変数を定義します。

roles/common_httpd/vars/vars-CentOS7.yml
---
httpd_package_name: httpd
roles/common_httpd/vars/vars-AmazonLinux.yml
---
httpd_package_name: httpd24

タスクから下記のように指定します。when句でOSディストリビューションごとに読み込むvarsファイルを切り替えています。
実際にApacheをインストールするyumモジュールの「name」パラメータに、上記で定義した「httpd_package_name」変数を渡しています。

roles/common_httpd/tasks/main.yml
---
- name: Configure packages' name for AmazonLinux
  include_vars: vars-AmazonLinux.yml
  when: (ansible_distribution == "Amazon")

- name: Configure packages' name for CentOS7
  include_vars: vars-CentOS7.yml
  when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "7")

- name: Install Apache2.4
  yum: name="{{httpd_package_name}}" state=present update_cache=yes

解説・補足

想定していないOSディストリビューションで実行する

このPlaybookを、CentOS7/AmazonLinux以外のディストリビューションで実行するとエラーとなります。「httpd_package_name」変数が未定義状態になるので。

include_varsに変数を指定する。

「include_vars」を指定している個所は通常のPlaybookのタスクファイルであるため、任意の変数が利用できます。
したがって、下記のような指定も可能です。

roles/common_httpd/tasks/main.yml
- name: Configure packages' name for each distributions
  include_vars: vars-{{ansible_distribution}}{{ansible_distribution_major_version}}.yml

CentOSやUbuntuでは「ansible_distribution_major_version」が正しく設定されるので上記で問題なく動きます。
Amazon Linuxは「ansible_distribution_major_version」が「NA」になりますので、注意が必要です。
# 恐らくAmazon Linux 2は当該値が2になるのではないかと思いますが、未検証

とはいえこの場合、「NA」は単なる文字列なので、「vars-AmazonNA.yml」というファイルを置いておけば事足ります。

ちなみに、「ansible -m setup localhost」の結果はそれぞれ下記のようになります。

CentOS7
$ ansible -m setup localhost
### ※途中省略
        "ansible_distribution": "CentOS",
        "ansible_distribution_file_parsed": true,
        "ansible_distribution_file_path": "/etc/redhat-release",
        "ansible_distribution_file_variety": "RedHat",
        "ansible_distribution_major_version": "7",
        "ansible_distribution_release": "Core",
        "ansible_distribution_version": "7.5.1804",
### ※途中省略
AmazonLinux
$ ansible -m setup localhost
### ※途中省略
        "ansible_distribution": "Amazon",
        "ansible_distribution_file_parsed": true,
        "ansible_distribution_file_path": "/etc/system-release",
        "ansible_distribution_file_variety": "Amazon",
        "ansible_distribution_major_version": "NA",
        "ansible_distribution_release": "NA",
        "ansible_distribution_version": "2017.03",
### ※途中省略
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1