include_varsで環境に応じた変数を読み込む

2015.10.07

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

渡辺です。

シェルスクリプトの中では、コマンドは可能な限りフルパスで記述することが望ましくなります。 しかし、環境によってコマンドのパスは異なる事があるため、スクリプトファイルに固定で記述することもできません。 このような場合、環境毎の変数をvarsに用意し、include_varsステートメントを利用します。

awsコマンドのパスを定義する

AWS CLIのコマンドはAmazon Linuxでは/usr/bin/awsとなり、Ubuntuでは/usr/local/bin/awsとなります。 はじめにvarsディレクトリの下にそれぞれファイルを用意して定義します。

# RedHat.yml
---
path_to_awscli: /usr/bin/aws
# Debian.yml
---
path_to_awscli: /usr/local/bin/aws

これらのファイルを読み込めば、変数「path_to_awscli」でテンプレートやタスクファイルから参照できるようになります。

include_varsステートメントで変数定義を読み込む

vars/main.ymlは自動的に読み込まれますが、それ以外のファイルは自動的には読み込まれません。 include_varsステートメントで読み込む必要があります。

include_varsステートメントとwhenステートメントを併用しても良いですが、もっとスマートに読み込むには次のように記述します。

# main.yml
---
- name: include vars
  include_vars: "{{ ansible_os_family }}.yml"

ファイル名にansible_os_familyの値が入りますので、これで各環境でのpath_to_awscliが設定されることになります。

templatesにスクリプトを定義する

templateモジュールで読み込むj2テンプレートは、templatesディレクトリに配置します。 j2テンプレートでは、変数を埋め込むことができるので、次のように記述することができます。

#!/bin/bash
{{ path_to_awscli }} --version

まとめ

最終的なtasks/main.ymlはこんな形になります。

# main.yml
---
- name: include vars
  include_vars: "{{ ansible_os_family }}.yml"
- name: place script file
  template: src=awstest.sh.j2 dest=/tmp/awstest.sh

構成はこうなりました。

roles/xxxx/
  tasks/
    main.yml
  templates/
    awstest.sh.j2
  vars/
    RedHat.yml
    Debian.yml

可読性を損ねず、可能な限りタスクをコンパクトにすることができますね。