dependenciesとtagsを使い、依存しているroleを実行する

2018/02/02

version: ansible 2.4

Ansibleでtagsを指定してplaybookを実行するとき、依存しているroleを自動で呼び出すようにしたい。

Subversionのinstallを例にとる

例えば、Subversionをinstallするとき、フロントにApacheをおいてユーザ認証にBasic認証を利用するとする。
Subversionのroleの各taskに設定されているtagsがsvnで、Apacheのroleのtagsがapacheとする。
tagsを指定して実行する場合、通常であればansible-playbook -i hosts.yml setup_middleware.yml --tags apache,svnのように二つ指定しなければならない。また汎用的なroleにするためにApache用の変数設定とSubversion用の変数設定を通常であれば用意すると思うので、SubversionとApacheのそれぞれの変数設定もしなければならない。
しかし達成したい本質はSubversionのinstallであって、Apacheの部分はあまり細かく変数設定せずにほとんど固定値で問題ないし、tagsを指定するときにapacheを入れるのではなく、svnを入れるだけでSubversionが必要としている設定が全て自動で入ってほしい。

このようなときはdependenciesを使って--tags svnだけでApacheも自動でsetupされるようにするのがいい。

dependenciesについて書く前に、ApacheとSubversionのroleの一部を抜粋する。

Apacheのrole

confファイルをtemplateから作成したりしている。

Subversionのrole

単一Repositoryと複数Repositoryの両方を構築できるようにしている。変数svn.multi_repository.usetrueを設定し、svn.multi_repository.repositoriesでリポジトリ名を列挙すれば、その分だけリポジトリが作成される。
複数のコンポーネントを作成しなければいけないプロジェクトにおいて、単一Repositoryと複数Repositoryのどちらを採用すればいいかは会社やチーム次第だが、こちらが参考になる。

Subversionのリポジトリ構成より

  1. 単一リポジトリ単一trunk型
  2. 単一リポジトリ複数trunk型
  3. 複数リポジトリ型

Subversionサーバを構築して渡す身としては、複数Repositoryを選ぶとRepositoryが増えるたびにApacheとの連携の設定をしなければいけないので、単一Repositoryを採用して、中のRepositoryを自由に使ってもらいたい。

SubversionのApache用confのtemplateも掲載する。

単一Repository用

複数Repository用

変数設定

dependenciesを使わない場合

もしdependenciesを使わないと、変数設定においてSubversionだけでなく、汎用的に作ってあるApacheについても詳細に決めなくてはいけなくなる。

以下のような変数設定になる。

dependenciesを使う場合

FQDNとなるserver_name以外は決めうちでいいと考え、server_nameだけを設定できるようにする。またapache.server_nameで設定させるのではなく、svn.server_nameで設定できるようにする。

dependenciesの書き方

inventoryのhosts.ymlにおいて、先に述べたような書き方をできるようにするために、またplaybook実行時に--tags svnだけでApacheのroleまで実行できるようにするために、dependenciesを導入する必要がある。

dependenciesは、Subversionのroleディレクトリ配下のmeta/main.ymlに書く。

dependenciesでは依存するroleが指定できる。ここではApacheを指定する。

role名とともにApacheのroleで必要とする変数をここで設定することができる。Apacheのroleで使う変数はapache.sitesの配列になっている。上記ではYamlをフロースタイルの一行で書いてしまったが、ちょっと複雑なのでブロックスタイルで複数行にわたって書いた方がよかったかもしれない。
server_name以外の変数は決めうちでいいという考えなので、document_root等は固定値を渡す。server_nameはinventoryで設定したsvn.server_nameを採用したい。'{{変数}}'で変数参照と変数設定ができるため、server_name: '{{ svn.server_name }}'としている。

ちなみにSubversionの前段にいるApacheの設定について「変数は固定値、決めうちで十分」というスタンスで書いているが、inventoryを書く労力を削減するだけでなく、Apacheを使うときにHTTPSを強制させることができていることも評価したい。Basic認証というパスワードが平文でネットワークを流れてしまう認証方式を用いている以上、SSL/TLSで通信自体を暗号化しなければいけない。
もしこのAnsibleをチームに展開して、案件ごとに各メンバにApacheの変数設定を全て記載してもらうようにすると、listen:80, enable_https: falseと設定する人が出ないとも限らない。

tagsもここで指定することができる。Apacheのroleの各taskでtags指定がなければ不要だが、現在のroleでは全taskにapacheというtagをつけている。もしtagsをここで指定しないと、ansible-playbook -i hosts.yml setup_middleware.yml --tags svnのように実行するとき、dependencies機能でApacheのroleを呼び出してもApacheのroleのtags: apacheにマッチせず、Apacheのtaskは一つも実行されない。
SubversionのdependenciesからApacheを呼び出す場合は、Apacheのroleにtags: svnをつけてあげることで、--tags svnで実行してもApacheのroleのタグにもマッチするようになる。

はじめよく理解せずに以下のようにtags: apacheとしてしまっていた。ansible-playbook -i hosts.yml setup_middleware.yml --tags svnで実行したとしても、dependenciesから呼び出すときは--tags svn, apacheというようにapacheタグを補う役割をすると誤解してしまっていた。ansible-playbookコマンド実行時の--tagsを補うのではなく、dependenciesで呼び出しているrole全体に対してtagsを付与しているということになる。

playbookでroleを読み込む場合にtagsを指定でき、role全体にそのtagsを付与することができる。dependenciesでのtagsも全く同じ考え方なので、上記のような誤解は普通はしないと思うが、「--tagsを自動で補ってほしい」という考えに頭がなってしまっていたのでdependenciesでのtagsのつけ方を勘違いしてしまったようだ。

-Linux
-,