Ansible NavigatorでPlaybookを実行する
はじめに
こんにちは。SHIFT ITソリューション部の水谷です。
AnsibleのPlaybook実行方法には、ansible-playbookコマンドでコマンドラインから実行する方法と、AWXおよびAnsible Automation Platform(AAP)上に作成したジョブテンプレートをGUIから(あるいはREST APIで)実行する方法があります。
少し前まではこの2つだけだったのですが、少し前にAnsible Navigatorを使う方法が追加されました(少し前と言っても、もう2年ほど経ちますが……)。
私はAnsible Navigatorについて、「ちょと面倒そうだな」という先入観があって使わずにいたのですが、ここらで少し勉強しておこうかなと思って触ってみましたので、記事として残しておこうと思います。
Playbookの実行環境
ansible-playbookでのPlaybook実行と、AWXやAAPでのPlaybook実行には大きな違いがあります。それは前者がOS上で直接実行されるのに対して、後者は指定したコンテナインスタンス上で実行されることです。
このコンテナインスタンスは、Execution Environment(EE)と呼ばれ、AWXやAAPをインストールすると標準的なものがPullされます。AWXやAAPを使用された経験がある方なら、ジョブテンプレートを作成するときに、どのEEを使用するかが指定できることを覚えていらっしゃるのではないでしょうか。そう、ジョブテンプレートを実行するときに、ここで指定したEEのインスタンスが作成されて、その中でPlaybookが実行されるのです。
ちょっとややこしい仕組みになっていますが、これには大きなメリットがあります。
それは、毎回新しく作成されたインスタンス上で実行されることで、Playbookの実行環境を確実に統一できることです。「同じPlaybookを実行すれば結果は同じになる」、これは当然のことのように聞こえますが、Playbookが同じだとしても、Ansibleのバージョンが違ったり、Ansibleの実行に使用されるPythonのバージョンが違ったり、あるいは環境変数の値に差があったり、と様々な要因で実行結果が変わる可能性が(僅かかもしれませんが)存在します。
このEEによる実行結果の同一性保証という恩恵を得るためには、AWXやAAPを導入しなければいけないのか? というと実はそうではなく、今回のお題であるAnsible Navigatorを使えば、コマンドラインからでも、EE上でPlaybookを実行することが可能となり、実行結果を確実に同じにすることができるのです。
インストール方法
では、さっそくインストール方法から見ていきましょう。
ansible-navigatorはPythonのプログラムであり、pipで簡単にインストールすることができます。
$ pip3 install ansible-navigator
インストールが完了したら、バージョンを確認しておきましょう。
$ ansible-navigator --version
ansible-navigator 24.2.0
なお、ansible-navigatorはコンテナインスタンス作成しますので、dockerあるいはpodmanなどのコンテナツールがインストールされている必要があります。
対話モード
ansible-navigatorをオプションなしで実行すると、creator-eeというEEが自動的にPullされます。
$ ansible-navigator
---------------------------------------------------------------------
Execution environment image and pull policy overview
---------------------------------------------------------------------
Execution environment image name: ghcr.io/ansible/creator-ee:v0.22.0
Execution environment image tag: v0.22.0
Execution environment pull arguments: None
Execution environment pull policy: tag
Execution environment pull needed: True
---------------------------------------------------------------------
Updating the execution environment
---------------------------------------------------------------------
Running the command: docker pull ghcr.io/ansible/creator-ee:v0.22.0
v0.22.0: Pulling from ansible/creator-ee
ca6ff2c3ecc4: Pull complete
2941e6f1d2bc: Pull complete
32db66e6bbce: Pull complete
92e1f4a92098: Pull complete
600b306c9749: Pull complete
2764fac24a7d: Pull complete
d419ad167630: Pull complete
7b03b9e3c798: Pull complete
05a232cb5cea: Pull complete
be915b595e0a: Pull complete
25380a2f785a: Pull complete
1a57afb20498: Pull complete
09f2372dbd92: Pull complete
Digest: sha256:2edd3559b9fa2f3a386d078bff531874a1d30455f8171d027cf3a9c7f50118d4
Status: Downloaded newer image for ghcr.io/ansible/creator-ee:v0.22.0
ghcr.io/ansible/creator-ee:v0.22.0
その後、以下のような対話型のCUIが表示されます。
どうやら、ansible-navigatorで実行できるコマンドが並んでいて、「:」の後に入力すればそのコマンドが実行できるようですね。
Playbook実行
もちろん対話型インターフェイスでPlaybookを実行することもできるのですが、非対話型の実行の方が(スクリプト化とかを考えると)より使う頻度が高いと思いますので、非対話型実行で行ってみます。
実行するPlaybookは、とりあえずこれ。EE内で動作するAnsibleのバージョンを表示するだけ(とは言え、興味あるポイント)の超簡単なモノです(ファイル名はsite.yml)。
- name: Test Playbook
hosts: localhost
tasks:
- name: Show ansible version
ansible.builtin.debug:
msg: "{{ ansible_version }}"
※Playbookはコンテナ内で実行されるので、localhostはコンテナ(EE)自体を指します。コンテナを動かしているPC(VM)ではないことに注意してください。
Ansible NavigatorのPlaybook実行コマンドはこのような書式になります。
ansible-navigator run {Playbookファイル名} -i {インベントリファイル名} --ee {EEを使って実行するか否かtrue/false} --eei {EEイメージ名} -m stdout
最後の-m stdoutが、対話型ではなく実行結果を標準出力に表示する、つまり非対話型で実行することを指定するオプションになります。
今回のPlaybookはlocalhostへの実行なので、インベントリは指定せず、そして、まずはEE関連のコマンドラインオプションは何も指定はせずに実行してみます。
$ ansible-navigator run site.yml -m stdout
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
PLAY [Test Playbook] ***********************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Show ansible version] ****************************************************
ok: [localhost] => {
"msg": {
"full": "2.16.2",
"major": 2,
"minor": 16,
"revision": 2,
"string": "2.16.2"
}
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
結果を見ると、Ansibleのバージョンが2.16.2になっていますね。今回はEEを指定しなかったので、デフォルトのcreator-ee(先ほどPullされたもの)がPlaybookの実行に使用されたのですが、このEEに入っているAnsibleのバージョンが2.16.2だったようです。
手元の環境にはAnsibleのバージョン2.16.5がインストールされているので、-ee falseを指定して、EEを使わずに実行してみます。
$ ansible-navigator run site.yml --ee false -m stdout
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
PLAY [Test Playbook] ***********************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Show ansible version] ****************************************************
ok: [localhost] => {
"msg": {
"full": "2.16.5",
"major": 2,
"minor": 16,
"revision": 5,
"string": "2.16.5"
}
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
このように、ローカルにインストールされているAnsibleが使われました(ローカルのAnsibleを使うのなら、ansible-playbookコマンドを使えば良いので、あまり意味はありませんが)。
では、EEを明示的に指定して実行してみましょう。
使ってみるのは、quay.io/ansible/awx-ee:latest です。これは、AWXでデフォルトとなるEEの最新版ですね。
$ ansible-navigator run site.yml --ee true --eei quay.io/ansible/awx-ee:latest -m stdout
----------------------------------------------------------------
Execution environment image and pull policy overview
----------------------------------------------------------------
Execution environment image name: quay.io/ansible/awx-ee:latest
Execution environment image tag: latest
Execution environment pull arguments: None
Execution environment pull policy: tag
Execution environment pull needed: True
----------------------------------------------------------------
Updating the execution environment
----------------------------------------------------------------
Running the command: docker pull quay.io/ansible/awx-ee:latest
latest: Pulling from ansible/awx-ee
97a053fecd3c: Pull complete
94b5d55fa621: Pull complete
6fa56a489f5b: Pull complete
f82a387ece20: Pull complete
92c08c4ced57: Pull complete
d62b4c5d1e60: Pull complete
f3bc7f8319d2: Pull complete
a329daa3843b: Pull complete
b94326a26c88: Pull complete
ca634930b3d8: Pull complete
022d57bb3257: Pull complete
fd3e05e19c61: Pull complete
4f4fb700ef54: Pull complete
a540a270db98: Pull complete
48fcd0a198ff: Pull complete
eaf671aa9fbf: Pull complete
bfcd72bbf16f: Pull complete
Digest: sha256:e1a3a327f3f8108513be069ce3808894d165ab6a65fdd08ca700a9d162fa21d8
Status: Downloaded newer image for quay.io/ansible/awx-ee:latest
quay.io/ansible/awx-ee:latest
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that
the implicit localhost does not match 'all'
PLAY [Test Playbook] ***********************************************************
TASK [Gathering Facts] *********************************************************
ok: [localhost]
TASK [Show ansible version] ****************************************************
ok: [localhost] => {
"msg": {
"full": "2.15.11rc1",
"major": 2,
"minor": 15,
"revision": "11rc1",
"string": "2.15.11rc1"
}
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
期待通り、quay.ioからawx-eeがPullされて、そのイメージからインスタンスが作成され、そしてPlaybookが実行されました。
実行結果をよく見ると、Ansibleのバージョンは"2.15.11rc1"となっていますね。latestのタグを使うと、このようなRCリリースのイメージがPullされることもあるようなので、latestのタグは避けて、バージョン(タグ)を指定した方が良いかもしれません。
ansible-navigatorの設定ファイル
使用するEEを毎回コマンドラインで指定するのは面倒なので、設定ファイルを作成しましょう。
Playbookと同じディレクトリ(あるいは環境変数ANSIBLE_NAVIGATOR_CONFIGで指定したパス)にansible-navigator.ymlというファイルを作成し、以下のような内容を書き込みます。
---
ansible-navigator:
execution-environment:
container-engine: docker
enabled: true
image: quay.io/ansible/awx-ee:latest
pull:
policy: never
mode: stdout
これで、常にEEとして quay.io/ansible/awx-ee:latest が使われ、非対話型モードで実行されるようになります。
コマンドラインも、以下のようにすっきりしたものになりました。
$ ansible-navigator run site.yml
なお、このファイルで設定できる項目は多岐にわたりますので、こちらのドキュメントを参照してください。 https://ansible.readthedocs.io/projects/navigator/settings/
Ansible Lintの実行
やや「おまけ」的な話ですが、Ansible NavigatorのコマンドラインオプションにLintがあって、Ansible Lintの実行もここからできるようなので、試してみました。
$ ansible-navigator lint site.yml -m stdout
yaml[trailing-spaces]: Trailing spaces
site.yml:5
yaml[empty-lines]: Too many blank lines (1 > 0)
site.yml:7
どうやら、標準的なルールで、Ansible Lintを実行してくれたようです。
Ansible Lintも簡単にインストールして使うことができるツールなので、Ansible Navigatorから実行することにそれほど大きな意味はないような気はしますが、(Ansible LintがEE内で実行されるため)Lintのルールを固定することができる、というメリットはあるかもしれないですね。
おわりに
ちょっとしたPlaybookの開発や実行に、EEを管理しなければいけないAnsible Navigatorは不要かな、と考えていたのですが、やってみればそれほど手間もかからず使い始められました。これは、ちょっとうれしい誤算でしたし、設定ファイルも一度作ってしまえば使いまわしでき、パフォーマンスも落ちてないように見えるので、これからはAnsible Navigatorを積極的に使っていこうかな、と思えました。
Ansible Navigatorのコマンドに"builder"というものもあったので、EEの作成もAnsible Navigatorからできそうに見えます。次回はこのあたりを少しやってみたいと思います。
▼この筆者の記事一覧
IaC支援サービスのご紹介
SHIFTではTerraformやCDKを使ったクラウドインフラ構築の自動化や、Ansibleを使ったサーバOSの設定自動化や構成管理のご支援も行っております。ご依頼・ご相談は下記リンクからお願いします。
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/
PHOTO:UnsplashのFotis Fotopoulos