Ansbile Navigatorを使ってカスタムEEを作ってみる
はじめに
株式会社SHIFT ITソリューション部の水谷です。
前回は、Ansible EE(Execution Engine=AnsibleやPlaybookの実行に必要なコレクションなどがインストールされたコンテナ)でAnsible Playbookを実行するコマンドラインツールであるAnsible Navigatorについて書いてみました。その記事の最後で少しふれましたように、Ansible NavigatorにはEEをビルドする機能も備わっていますので、今回はこれを試してみます。
EEのビルドツールとしては、Ansible Builderがあります。Ansible NavigatorでのEEビルドはAnsible Builderのそれと何が違うのでしょうか?
ファイルの準備
EEのビルドには、いくつかの設定ファイルが必要がありますので、まずはそれらを作成します。
1つ目のファイルは execution-environment.yml です。これがEEをビルドする際の主ファイルで、多くの情報をここに記述します。
以下はRed Hat Developerサイトにあったサンプルです。
version: 1
dependencies:
galaxy: requirements.yml
python: requirements.txt
system: bindep.txt
additional_build_steps:
prepend: |
RUN whoami
RUN cat /etc/os-release
append:
- RUN echo This is a post-install command!
- RUN ls -la /etc
dependenciesのところには、galaxy: requirements.ymlと書かれていて、requirements.ymlに記述したCollectionをAnsible Galaxyからダウンロードして、EEに含めてくれます。
例えば、requirements.ymlを以下のように記述すると、community.windowsとamazon.awsを含めてくれるのです。
collections:
- community.windows
- amazon.aws
続くrequirements.txtには、コレクション(実際にはその中に含まれるモジュールの実行に)必要となるPythonライブラリを列挙しておきます。
今回は、amazon.awsコレクションを使用するのに必要なboto3とbotocoreを書いておきました。
boto3>=1.26.0
botocore>=1.29.0
そして、bindep.txtには、rpmでインストールしたいパッケージを指定します。下はその例です(インストールしたいパッケージがなければ、system: bindep.txtの行や、bindep.txtは不要です。
findutils [compile platform:centos-8 platform:rhel-8]
gcc [compile platform:centos-8 platform:rhel-8]
make [compile platform:centos-8 platform:rhel-8]
一番最後の additional_build_steps には、コンテナのビルド前後に実行したいコマンドを、Dockerfileの書式で記述します。今回は特に実行したいコマンドがないので、このままにしておきます。
ビルドしてみると…
ファイルの準備ができたので、さっそくビルドしてみましょう。
ビルドのコマンドは、ansible-navigator builder build -m stdoutです。
$ ansible-navigator builder build -m stdout
Running command:
docker build -f context/Dockerfile -t ansible-execution-env:latest context
...showing last 20 lines of output...
#13 ERROR: process "/bin/sh -c ANSIBLE_GALAXY_DISABLE_GPG_VERIFY=1 ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path \"/usr/share/ansible/collections\"" did not complete successfully: exit code: 250
------
> [galaxy 5/5] RUN ANSIBLE_GALAXY_DISABLE_GPG_VERIFY=1 ansible-galaxy collection install -r requirements.yml --collections-path "/usr/share/ansible/collections":
0.720 Starting galaxy collection install process
0.720 Process install dependency map
9.012 to see the full traceback, use -vvv
9.012 [WARNING]: Skipping Galaxy server https://galaxy.ansible.com/api/. Got an
9.012 unexpected error when getting available versions of collection amazon.aws: '/ap
9.012 i/v3/plugin/ansible/content/published/collections/index/amazon/aws/versions/'
9.012 ERROR! Unexpected Exception, this is probably a bug: '/api/v3/plugin/ansible/content/published/collections/index/amazon/aws/versions/'
------
Dockerfile:36
--------------------
34 |
35 | RUN ansible-galaxy role install $ANSIBLE_GALAXY_CLI_ROLE_OPTS -r requirements.yml --roles-path "/usr/share/ansible/roles"
36 | >>> RUN ANSIBLE_GALAXY_DISABLE_GPG_VERIFY=1 ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path "/usr/share/ansible/collections"
37 |
38 | # Builder build stage
--------------------
ERROR: failed to solve: process "/bin/sh -c ANSIBLE_GALAXY_DISABLE_GPG_VERIFY=1 ansible-galaxy collection install $ANSIBLE_GALAXY_CLI_COLLECTION_OPTS -r requirements.yml --collections-path \"/usr/share/ansible/collections\"" did not complete successfully: exit code: 250
An error occurred (rc=1), see output line(s) above for details.
結果は御覧の通りエラーが出て止まってしまいました。
ログを読んでみると、amazon.awsコレクションをインストールするときに、インストール可能なバージョンのリストを取得することに失敗したようです。
調べてみると、ここ に似たようなエラーについてのIssueが上がっており、どうやらこのエラーはAnsibleのバージョンが2.11や2.12の時に発生するようです。
いや、そんな古いバージョンのAnsibleを使っているつもりはないんだけど…、と思いつつ、もう少し詳しく調べてみることにします。
Ansible NavigatorでEEをビルドする際に、contextというディレクトリが作成されます。実行結果の2行目にあるように、このディレクトリにDockerfileが自動生成され、これをビルドすることでEEが生成されることがわかります。
では、そのDockerfileの中身を覗いてみましょう。
$ cat context/Dockerfile
ARG EE_BASE_IMAGE="quay.io/ansible/ansible-runner:latest"
ARG EE_BUILDER_IMAGE="quay.io/ansible/ansible-builder:latest"
ARG PYCMD="/usr/bin/python3"
ARG PKGMGR_PRESERVE_CACHE=""
ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS=""
ARG ANSIBLE_GALAXY_CLI_ROLE_OPTS=""
# Base build stage
FROM $EE_BASE_IMAGE as base
USER root
ARG EE_BASE_IMAGE
ARG EE_BUILDER_IMAGE
ARG PYCMD
ARG PKGMGR_PRESERVE_CACHE
ARG ANSIBLE_GALAXY_CLI_COLLECTION_OPTS
ARG ANSIBLE_GALAXY_CLI_ROLE_OPTS
...
先頭行でEE_BASE_IMAGEという変数が定義されていて、その後 FROM $EE_BASE_IMAGE as base となっているので、このEE_BASE_IMAGEがベースのイメージのだということがわかります。
Webブラウザで quay.io/ansible/ansible-runner を開いてみると……、このイメージのlatestタグはイメージ名が stable_2.12-latest のもののようですね。。。最終更新は2年前、つまり、ansible-runnerのイメージは2年更新されておらず、latestでもAnsible 2.12ベースのものでした。
ベースイメージを指定して解決
なぜこのような古いイメージがデフォルトで使用されるのかは不明ですが、この問題を解決することは難しくはないですね。ベースイメージとして、新しいバージョンのAnsibleが使われているものを指定すれば良いのですから。
ドキュメントを読むと、ベースイメージを指定するには execution-environment.yml に以下のように追加すればよいことがわかりました。
build_arg_defaults:
EE_BASE_IMAGE: <イメージ>:<タグ>
で、ベースイメージを何にするかですが、awx-eeとかでも良いかなと思いましたが、今回はAnsible Lintも入っている creator-ee:latest にしてみます。
build_arg_defaults:
EE_BASE_IMAGE: ghcr.io/ansible/creator-ee:latest
再度ビルドしてみます。
$ ansible-navigator builder build -m stdout
Running command:
docker build -f context/Dockerfile -t ansible-execution-env:latest context
Complete! The build context can be found at: /home/mizutani/test_ee/context
ということで、ansible-execution-env:latest というイメージ名(とタグ)でEEがビルドされました。
Ansible Builderを使ったことのある方なら、この出力からもお分かりかと思いますが、Ansible NavigatorでEEをビルドするといっても、実際にはAnsible Navigatorが作ったコンテナ内でAnsible Builderが実行されているだけのようですね。
なお、イメージ名とタグをビルド時に指定したい場合は、(Ansible Builderと同じで)ビルド時に -t <イメージ名>:<タグ> を指定すればOKです(以下は例)。
$ ansible-navigator builder build -m stdout -t my_ee:v1
もちろん、デフォルトのイメージ名でビルドした後に docker tag コマンドで変更しても問題ないです。
作ったEEでPlaybookを実行してみる
EEができたので、さっそく使ってみましょう。
実行するPlaybookは以下のようなものです。
- name: Test Playbook
hosts: localhost
tasks:
- name: Show ansible version
ansible.builtin.debug:
msg: "{{ ansible_version }}"
- name: Get all installed collections
ansible.builtin.command: 'ansible-galaxy collection list'
register: galaxy_result
- name: Show installed collection list
ansible.builtin.debug:
var: galaxy_result.stdout
内容は、EE内のAnsibleのバージョンと、EEにインストールされているコレクションを表示するだけです。
結果は以下のようになりました。
$ ansible-navigator run /mnt/c/Projects/note/temp/site.yml --ee true --eei my_ee:v1 -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.3",
"major": 2,
"minor": 16,
"revision": 3,
"string": "2.16.3"
}
}
TASK [Get all installed collections] *******************************************
changed: [localhost]
TASK [Show installed collection list] ******************************************
ok: [localhost] => {
"galaxy_result.stdout": "\n# /usr/share/ansible/collections/ansible_collections\nCollection Version\n----------------------- -------\namazon.aws 7.5.0 \nansible.posix 1.5.4 \nansible.windows 2.2.0 \nawx.awx 23.7.0 \ncommunity.windows 2.2.0 \ncontainers.podman 1.12.0 \nkubernetes.core 3.0.0 \nredhatinsights.insights 1.2.2 \ntheforeman.foreman 4.0.0 "
}
PLAY RECAP *********************************************************************
localhost : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ちょっと見づらいですが、requirement.ymlで追加したamazon.awsコレクションとcommunity.windowsコレクションがインストール済みであることが確認できました。期待通りですね。
おわりに
少しトラブルもありましたが、Ansible Navigatorだけを使ってEEの構築ができました。
これまで別々にインストールしていた Ansible Lint やEEをビルドするためのツールであるAnsible Builderなしに、Ansible Navigatorだけでこれらが実行できるのはちょっと嬉しいですね。Ansible Navigatorが今後どのように進化していくのかはわかりませんが、さらに統合が進んでより便利なツールになっていくのかもしれません。面白い機能の追加等がありましたら、紹介記事を書きたいと思います。
IaC支援サービスのご紹介
SHIFTではTerraformやCDKを使ったクラウドインフラ構築の自動化や、Ansibleを使ったサーバOSの設定自動化や構成管理のご支援も行っております。ご依頼・ご相談は下記リンクからお願いします。
お問合せはお気軽に
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/