TT Lab
はじめる
学ぶ 学習パス コース

Ansible実戦

社内コレクションを作り、版を固定して配布する

TT Labで続きを見る

目標

ロール複数を1つのコレクションにまとめてバージョンを付け、ビルドしたバンドルをインストールしてFQCNで呼び、固定ファイルでインストールされるバージョンをロックするという一連の流れを、自分で回せるようになります。

なぜ重要なのか

ロールは再利用の単位で、コレクションは配布の単位です。チームが増えると、問題は「このロールをどう使うか」から「今あのサーバーで動いているロールはどのバージョンか」に移っていきます。コレクションは、その問いに答えるために3つを導入しました。名前に出典を書き(FQCN)、バンドルにバージョンを付け(SemVer)、インストールするバージョンをファイルに書きます(requirements.yml)。この3つがないと、検索パスの順序が何が実行されるかを決めますが、その順序は人ではなく環境が決めます。ここにロールの引数仕様を加えると、誤った値がタスクを動かす前に止まります。他人が使うコードを出すとき、ドキュメントよりも先に備えるべきものです。このラボは、その一連の流れを、インターネットなしでローカルのバンドルだけで回します。

ステップ

  1. ansible-galaxy collection initで、acme.platformコレクションのスケルトンを/root/ans/coll/srcの下に作成してください。そして、/root/ans/inventory/hosts.iniにweb1・web2・db1を書いたインベントリを作成してください(ansible_host=127.0.0.1、ansible_port=2222、ansible_user=root)。
  2. /root/ans/coll/src/acme/platform/galaxy.ymlのversionを1.2.0に、description・authors・repositoryを社内の値で埋め、licenseにMIT、tagsにinfrastructureとlinuxを入れてください。そして、同じコレクションのmeta/runtime.ymlに、requires_ansibleを範囲表記で書いてください。
  3. コレクションの中のroles/motd/にロールを作成してください。defaults/main.ymlにmotd_banner(デフォルトはacme-platform)・motd_owner(デフォルトはplatform)・motd_path(デフォルトは/root/ans/coll/out/motd.txt)を置き、tasks/main.ymlは、motd_pathにbanner=<motd_banner>とowner=<motd_owner>の2行を書く、名前の付いたタスク1つで埋めてください。モジュールはFQCNで呼びます。
  4. roles/motd/meta/argument_specs.ymlを作成し、mainエントリポイントにshort_descriptionと3つの引数を書いてください。3つともtype: strでdescriptionが必要で、motd_ownerにはchoicesでplatformとsreの2つの値だけを許可してください。
  5. コレクションをビルドして/root/ans/coll/dist/acme-platform-1.2.0.tar.gzを作成し、バンドルの中にMANIFEST.json・FILES.jsonとロールのファイルが入っているかを確認してください。
  6. 作成したバンドルを/root/ans/coll/collectionsにインストールし、そのパスでacme.platformが1.2.0として見えるか、ansible-docでacme.platform.motdロールの引数が調べられるかを確認してください。
  7. /root/ans/coll/use.ymlを作成し、acme.platform.motdロールをFQCNで呼び出して、motd_bannerをacme-platform in productionに、motd_ownerをsreにして渡してください。インベントリのweb1を対象に実行して、/root/ans/coll/out/motd.txtを残してください。
  8. ソースのgalaxy.ymlのバージョンを1.3.0に上げて再ビルドし(バンドルが2つになります)、/root/ans/coll/requirements.ymlに1.2.0のバンドルをtype: fileで固定して、そのファイルでインストールしてください。そして、インストールされたバージョンを/root/ans/coll/out/pinned.txtに1行で残してください。

参考

コレクションのスケルトンを作る

ansible-galaxy collection initで、acme.platformコレクションのスケルトンを/root/ans/coll/srcの下に作成してください。そして、/root/ans/inventory/hosts.iniにweb1・web2・db1を書いたインベントリを作成してください(ansible_host=127.0.0.1、ansible_port=2222、ansible_user=root)。

コレクション名は、<네임스페이스>.<이름>(プレースホルダーはネームスペースと名前です)で1つの塊として渡します。作る場所は--init-pathで指定し、スケルトンはその下に、ネームスペース/名前の2階層で作られます。

galaxy.ymlを埋めて、最小のansibleバージョンを指定する

/root/ans/coll/src/acme/platform/galaxy.ymlのversionを1.2.0に、description・authors・repositoryを社内の値で埋め、licenseにMIT、tagsにinfrastructureとlinuxを入れてください。そして、同じコレクションのmeta/runtime.ymlに、requires_ansibleを範囲表記で書いてください。

スケルトンが入れておいた例の文言(your name、your collection description)が残っていると、ビルドはできますが、配布物としては使えません。runtime.ymlはほとんどがコメントなので、必要なキーだけを新しく書くほうが早いです。

コレクションの中にロールを入れる

コレクションの中のroles/motd/にロールを作成してください。defaults/main.ymlにmotd_banner(デフォルトはacme-platform)・motd_owner(デフォルトはplatform)・motd_path(デフォルトは/root/ans/coll/out/motd.txt)を置き、tasks/main.ymlは、motd_pathにbanner=<motd_banner>とowner=<motd_owner>の2行を書く、名前の付いたタスク1つで埋めてください。モジュールはFQCNで呼びます。

コレクションの中のロールも、ディレクトリの規約は従来のロールと同じです。値をハードコードするとロールが再利用できないので、3つの値すべてを変数で受け取ってください。2行を一度に書くには、複数行文字列(|)をcontentとして渡せば構いません。

引数仕様で誤った値を防ぐ

roles/motd/meta/argument_specs.ymlを作成し、mainエントリポイントにshort_descriptionと3つの引数を書いてください。3つともtype: strでdescriptionが必要で、motd_ownerにはchoicesでplatformとsreの2つの値だけを許可してください。

仕様はドキュメントではなく検証です。一覧にない値を入れてロールを呼び出し、最初のタスクが動く前に止まるかどうかを、自分で確認してください。

バンドルとしてビルドして内容物を確認する

コレクションをビルドして/root/ans/coll/dist/acme-platform-1.2.0.tar.gzを作成し、バンドルの中にMANIFEST.json・FILES.jsonとロールのファイルが入っているかを確認してください。

ビルドは、コレクションのソースディレクトリの中で実行します。結果を置く場所は--output-pathで指定します。バンドルの中を見るには、展開せずに一覧だけを見ても構いません。

ローカルのパスにインストールしてドキュメントで確認する

作成したバンドルを/root/ans/coll/collectionsにインストールし、そのパスでacme.platformが1.2.0として見えるか、ansible-docでacme.platform.motdロールの引数が調べられるかを確認してください。

インストール先は-pで渡します。調べるときは、ansibleにそのパスを見させる必要があり、検索パスを決める環境変数が別にあります。ディストリビューションに同梱のコレクションが数百個入っているので、一覧は名前を指定して見てください。

FQCNで呼び出して実行する

/root/ans/coll/use.ymlを作成し、acme.platform.motdロールをFQCNで呼び出して、motd_bannerをacme-platform in productionに、motd_ownerをsreにして渡してください。インベントリのweb1を対象に実行して、/root/ans/coll/out/motd.txtを残してください。

ロールを呼び出すときに渡した値は、ロールのdefaultsに勝ちます。コレクションが見つからないと言われたら、まず検索パスを確認してください。インストールした場所と、実行時に見る場所が同じである必要があります。

ソースが先に進んでもインストールされるバージョンは固定する

ソースのgalaxy.ymlのバージョンを1.3.0に上げて再ビルドし(バンドルが2つになります)、/root/ans/coll/requirements.ymlに1.2.0のバンドルをtype: fileで固定して、そのファイルでインストールしてください。そして、インストールされたバージョンを/root/ans/coll/out/pinned.txtに1行で残してください。

ローカルのバンドルファイルを指すときは、名前にパスを書き、種類を別に明示します。インストールされたバージョンは手で書かず、collection listの出力から抜き出して書いてください。