てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] ロールの処理を正常のまま止める meta モジュールのキーワード「end_role」

はじめに

Ansible には、やや特殊な ansible.builtin.meta というモジュールがあります。

このモジュールに、ロールの処理を正常のまま止めるキーワード end_role が、ansible-core 2.18.0 で追加されました。

changelogから:

Add a new meta task end_role (#22286)

現状は、devel の公式ドキュメントの ansible.builtin.meta のモジュールの説明に end_role が記載れています。

end_role (added in Ansible 2.18) causes the currently executing role to end without failing the host(s).

せっかくなので試してみました。

検証環境:

  • ansible-core 2.18.0

ansible.builtin.meta: end_role を試す

まず2つのロールを用意します。それぞれ、ちょとした debug を仕込んでいます。

role1 の方に ansible.builtin.meta: end_role を挟んでいます。これで role1 の次のタスク Task 1-2 が実行されないことを期待しています。

roles/role1/tasks/main.yml:

---
- name: Task 1-1
  ansible.builtin.debug:
    msg: 1-1

- name: End role
  ansible.builtin.meta: end_role    # 今回のポイント

- name: Task 1-2   # これは実行されない想定
  ansible.builtin.debug:
    msg: 1-2

roles/role2/tasks/main.yml

---
- name: Task 2-1
  ansible.builtin.debug:
    msg: 2-1

Playbook はこちら。ただ上述の2つのロールをインポートするだけです。

---
- name: Test play for end_role
  hosts: localhost
  gather_facts: false

  tasks:
    - name: Import role role1
      ansible.builtin.import_role:
        name: role1

    - name: Import role role2
      ansible.builtin.import_role:
        name: role2

それでは実行します。

% ansible-playbook -i localhost, import_role.yml

PLAY [Test play for end_role] *************************************************************************************

TASK [role1 : Task 1-1] *******************************************************************************************
ok: [localhost] => {
    "msg": "1-1"
}

TASK [role1 : End role] *******************************************************************************************

TASK [role2 : Task 2-1] *******************************************************************************************
ok: [localhost] => {
    "msg": "2-1"
}

PLAY RECAP ********************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

期待通り role1 内の Task 1-2 は実行されず、次のロールである role2 の処理は実行されました。

なお、今回 end_role を仕込んだ場所に、代わりに end_play を仕込むと、Task 1-2 はもちろん、role2 の処理も実行されません。この比較がわかりやすいと思います。

おわりに

完全に余談ですが 「エンドロール」と聞くと映画の最後とかの end roll を連想してしまいます。

[Ansible] プラグインが利用している環境変数一覧

とあるコレクションのドキュメントを antsibull-docs でビルドしてたら、そのコレクションが利用している環境変数の一覧が掲載された environment_variables.html というファイルが生成されたことに、たまたま気が付きました。

見慣れないものだったので、他のコレクションはどうなんだろう、と調べてたら、 Ansible community package のドキュメントにも一覧がありました。

docs.ansible.com

網羅性は把握できていませんが、どうもどのプラグインから利用されている環境変数なのかを示す Used by: 〜 とかは自動生成しているようでした。

このページは、どこからもリンクされていないように見えます。あとで探すとき迷いそうなので、ブログの記事にしておきます。

[Ansible] 2024年の Ansible 関連リリースや動向まとめ

この記事は Ansible Advent Calendar 2024 の 24日目の記事です。

はじめに

ここ数年、アドベントカレンダーのタイミングで、その年の Ansible 関連のリリースや動向をまとめるようにしているので、今年もやりたいと思います。

例年通り、半年に一度の ansible-core のバージョンアップがあったほか、2024年9月リリースの AAP 2.5 では、インストール方法やアーキテクチャに大きな変更がありました。

ほか、Playbook のポリシーをチェックする Policy as Code についての発表もありました(ツールとしては未リリース)。

この記事では、今年の個人的にポイントだと思った Ansible 関連リリースや動向をまとめます。

リリースや発表

AAP 2.5 リリース

2024年9月30日に、AAP (Ansible Automation Platform) 2.5 がリリースされました。今回のリリースは、AAP 2 系になって、一番大きな変化が起きたという印象があります。

ポイントは以下のとおりです。

  • 統合UI「Platform Gateway」の導入
  • コンテナによるデプロイ方式の追加

Platform Gateway の導入によって、Automation Controller や Automation Hub、EDA Controller の画面が1つに統合されました。認証も統一されており、シームレスに操作できるようになりました。

コンテナによるデプロイは、従来からある RPM ベースのインストールと比べると処理が早くて良かったです。API リクエストの仕方も変わってるのは注意点です。

AAP 2.4 で GA になった Event-Driven Ansible も AAP 2.5 で順調にアップデートされているようです。

Policy as Code

AnsibleFest 2024 や Ansible Automates 2024 Japan で Policy as Code についての発表がありました。

Ansible における Policy as Code は、例えば Playbook で指定する AWS インスタンスタイプが指定したポリシーにあっているかどうか確認するよなことを指します。

ansible-lint が文法的なチェックだとすると、Policy as Code は内容のチェックといったところでしょうか。Ansible Lightspeed が生成した Playbook をより安全に使うためにチェックする、いわばガードレールのような使い方もできそうです。

ポリシーを記述したものを Policybook と呼びます。チェックする具体的なツールとして ansible-policy が公開されていますが、現状は prototype implementation です。

2025 年は、このジャンルの動きもあるのではないかと思います。

AAP 1.2 の Extended life cycle support (ELS) add-on 終了

去年「Maintenance support 2」が終わった AAP 1.2 ですが、一定の条件下、「Extended life cycle support (ELS) add-on」が設けられていました。それも 2024年12月31日 に終了を迎えます。

access.redhat.com

ansible-core 2.17 / Ansible 10 リリース

2024年5月に、ansible-core 2.17.0 がリリースされました

Ansible Community Package (pip install ansible でインストールされるもの) としても、ansible-core 2.17 系を含む バージョン 10 が続いてリリースされました。

コントロールノード側の Python 要件が、Python 3.6 以上になりました。Python 2 系のサポートがいよいよ無くなったのも特徴です。

また、Linux ディストリビューションに基づくインタープリター検出機能も廃止されました。

総じて、新機能の追加よりも、Python の扱いの変化が大きなポイントのように感じたバージョンアップでした。

ansible-core 2.18 / Ansible 11 リリース

2024年11月に、ansible-core 2.18.0 がリリースされました。

Ansible Community Package (pip install ansible でインストールされるもの) としても、ansible-core 2.18 系を含む バージョン 11 が続いてリリースされました。

ループを抜ける条件を指定する break_when がサポートされたり、ansible.builtin.meta モジュールend_role がサポートされたりしました。

コントロールノードで Python 3.11 以上が、マネージドノードで Python 3.8 以上が必要になりました。このように、バージョンアップによってサポートされる Python のバージョンが引き上がることがあります。対応表は以下の「ansible-core support matrix」がわかりやすいです。

Releases and maintenance — Ansible Community Documentation

あと、vars ディレクティブに変数を定義する方法で、一部非推奨だった方法がありますが、それがいよいろエラーになるようになりました。

ansible-builder 3.1.0 リリース

Python 依存パッケージ関連の処理が一部変わって、3.0 系でビルドできたけど、3.1.0 でビルドできないというケースが出てきたので、少し注意ですが、基本は正常なバージョンアップです。

ポーティングガイドも出ています。

Terraform の ansible/aap プロバイダー 1.0.0 リリース

Terraform 「で」AAP 「を」設定するためのプロバイダーがリリースされました。今後どのような扱いになるのか気になっています。

コレクションの Ansible 2.9 切りが進む

たとえば、以下は ansible.posix コレクション 1.6.0 の changelog より。

Dropping support for Ansible 2.9, ansible-core 2.15 will be minimum required version for this release

AWX がリニューアル工事に入る

プラグイン化、UI の切り離しなど、さまざまな方面でアーキテクチャー変更のための工事に入りました。この関係で、バージョン 24.6.1 からあとのリリースはありません。

cisco.asa コレクションが deprecated 扱いへ

Ansible community package から削除されるのはまだ先ですが、Deprecated(非推奨)になりました。

2024/12/23 時点の latest のドキュメントにも以下の記載があります。

The cisco.asa collection has been deprecated and will be removed from Ansible 12. See the discussion thread for more information.

その他

周辺ツールのバージョン表記が CalVer に

ansible-lint や ansible-navigator などの周辺ツールのバージョン表記が、SemVer から CalVer になりました。

年月ベースの YY.MM.MCIRO であり、たとえば 2024年12月の初回リリースが 24.12.0 で、同月 2回目のリリースは 24.12.1 です。

「いきなりバージョン 24 系になったんだが!?」と驚かれた方もいらっしゃるかもしれません。

Devtools Projects Transitioning to CalVer Releases - News & Announcements - Ansible

ansible-core は従来のままです。

書籍「インフラの構成管理と自動化のための実践Ansible」発売

Playbook の書き方のみならず、ansible-navigator や molecule、自動化の始め方など、広範囲に書かれていてとても参考になりました。

www.shuwasystem.co.jp

おわりに

2024年の Ansible 関連の気になったリリースや動向をまとめました。

例年通り、ansible-core やバージョンアップや AAP のバージョンがありました。AWX の扱いの変化は大きく感じました。

2025 年は、Policy as Code (ansible-policy)の動向に注目していこうかなと思います。

Happy Automation!

[Ansible/AAP] AAP の設定自動化が便利になる infa.aap_configuration コレクションを試す

この記事は Ansible Advent Calendar 2024 の 18日目の記事です。

はじめに

AAP(Ansible Automation Platform) に含まれる、Automation Controller などの GUI のプロダクトを設定するための ansible.controller というコレクションがあります。

ansible.controller コレクションをそのまま使っても良いのですが、より便利に使うための infra.aap_configuration というコレクションがあります(from Automation Hub / from Ansible Galaxy)。

redhat-copRed Hat Communities of Practice)配下のリポジトリで管理されているコレクションです。

前身の infra.controller_configuration コレクションの頃から気になっていたのですが、AAP 2.5 のコンテナベースのインストーラーでも、事後処理として類似の仕組みによって設定投入できるようになった(Technical Preview としては AAP 2.4 から)ので、この機会に試してみることにしました。使ってみるとかゆいところに届くところもあって便利でした。

この記事では、infra.aap_configuration コレクションの概要や、嬉しい点、ためしてみたこと、留意点などをまとめます。

検証環境:

  • infra.aap_configuration コレクション 3.1.0
  • ansible.controller コレクション 4.6.2
  • ansible-core 2.17.7
  • AAP 2.5 (Automation Controller 4.6.2)

infra.aap_configuration コレクションの概要

infra.aap_configuration コレクションは、AAP 内のプロダクトの設定を Ansible から便利に設定するためのコレクションです。

たとえば、Automation Controller 上のプロジェクト、インベントリ、認証情報、テンプレートなどの設定を自動化できます。基本的には、各オブジェクト種別ごとにロールって「非同期で設定開始、待機」という処理がなされます。

基本的な情報は README.md に掲載されています。これ以外にもトップや docs ディレクトリに他のドキュメントがあるので、Ansible Galaxy のページよりも、リポジトリを直接見たほうが情報を得やすいかもしれません。

なお、infra.aap_configuration コレクション自体にはモジュールは含まれておらず、ロールがメインです。ロールが、ansible.controller コレクションのような設定モジュールが含まれるコレクションを利用するかたちになっています。そのため、infra.aap_configuration コレクション単体では動作せず、モジュールが含まれるコレクションもあわせてインストールする必要があります。

AAP 内の 各プロダクトとinfra.aap_configuration コレクション内のロールが利用(依存)するコレクションは以下のとおりです。

プロダクト コレクション名
Automation Gateway (性質上、 AAP 全般的な位置づけ) ansible.platform
Automation Controller ansible.contoller
Automation Hub ansible.hub
Event Driven Ansible `ansible.eda

コレクション統合の経緯

AAP 2.4 までは Automation Controller 向けの infra.controller_configuration、Automation Hub 向けの infra.ah_configuration、のように AAP 内の各プロダクトごとにコレクションが別れていました。

AAP 2.5 対応時に、本記事で紹介する infra.aap_configuration コレクション に統合されました。バージョンとしては 3.0.0 として統合されました。統合前と統合後では共通の仕様も多くあります。

周辺コレクションのまとめ

infra.aap_configuration コレクション は、実際に設定を担当する ansible.controller コレクション内のモジュールを利用します。また、AAP 2.4 以前向けに infra.controller_configuration という前身のコレクションもあります。

このあたりの事情をまとめると以下の図のようになります。

周辺コレクションまとめ

以下、補足です。

  • 応用コレクション、基本コレクションという呼び方はこの記事固有で正式なものではありません
  • 図をシンプルに保つため、dispatch ロールや、upstream (AWX など)関連は省略しました
  • 操作の矢印が、各コレクションから各プロダクトに伸びていますが、API リクエストの視点では AAP 2.5 の場合は Automation Gateway 経由 です

■ うれしい点

設定モジュール ansible.controller を直接使っても設定の自動化はできますが、infra.aap_configuration コレクションを利用すると、うれしい点がいくつかあります。

私が感じたうれしい点をまとめます。いくつかは後述のサンプル Playbook でも触れます。

うれしい点1: dispatch ロールによる宣言的な指定

これが個人的に一番うれしい点です。

Ansible は Playbook 単位でみると手続きベースなので、Playbook を書く側が設定の順番を意識する必要があります。この点が、柔軟で便利だったり、面倒だったり、両面があります。

Automation Controller でいえば、ジョブテンプレートを作成する前に、関連するプロジェクトやインベントリを作成しておく必要があります。infra.aap_configuration コレクションとしては、controller_job_templates ロールでジョブテンプレートを作成する前に、controller_projectscontroller_inventories ロールでプロジェクト、インベントリなどを作成する必要があります。

そこで便利なのが、順番を意識しなくてよい(ここでは宣言的と表現します) infra.aap_configuration.dispatch ロールです。

infra.aap_configuration.dispatch ロール利用する場合、ただ決められたフォーマットの設定用の変数ファイルを用意しておけば良くて、実際にどういう順番で処理するかは infra.aap_configuration.dispatch ロール内部で面倒を見てくれています(おそらく作成時を前提)。設定用の変数ファイル内の定義順はジョブテンプレートが先でも問題ありません。

仕組みとしては、あらかじめ dispatch ロール内で然るべき順番が定義されているだけです。たとえば、ジョブテンプレートを設定する controller_job_templates ロールよりも前に controller_projectscontroller_inventories ロールが呼ばれるようになっています。

設定用の変数ファイルは複数に分けておき、まとめて読み込みたい(例えば ansible.builtin.include_vars モジュールdir オプションや host_vars/ホスト名/*.yml)ときにも、宣言的な性質が活きてきそうです。

dispatch ロールについては、本記事のあとで試します。

うれしい点2: コレクションに Playbook が含まれている

Ansible のコレクションは仕様上、モジュールやプラグインだけでなく Playbook を含めることができます。

infra.aap_configuration コレクションにもいくつか Playbook が含まれています。特に configure_aap.yml という Playbook が便利です。

configure_aap.yml には、設定用変数ファイルを読み込むタスクと、先述の dispatch ロールを呼ぶタスクがあります。

つまり、一番楽できるパターンは、変数ファイルだけ用意して、Playbook を書かず、以下を実行するだけです。

ansible-playbook -i localhost, infra.aap_configuration.configure_aap

infra.aap_configuration.configure_aapconfigure_aap.ymlFQCN 表記です)

私は、これで済むならこれで済ませたい、という気持ちが芽生えました。

コレクション内の configure_aap.yml という Playbook については、本記事のあとで試します。

うれしい点3: デフォルト値に戻すのがラク

Ansible を使って自動化するとき、ジュールのオプションで値を指定すると設定が入るけど、設定が入っている状態で対応するオプションを指定しないで Playbook を実行すると、設定が残ったままになるケースが多い印象があります。つまりマージ的、 REST API に例えると PATCH 的な動作です。この動作がありがたいときもあれば、デフォルト値(未設定など)に戻ってほしいなと思うときもあります。

infra.aap_configuration コレクションでは、どちらの動作にするか選択できます。デフォルトはマージ/PATCH的な動作です。

たとえば、Automation Controller のプロジェクトの設定で、「説明」に該当する設定を設定しなかった場合、何もしない動作(マージ/PATCH的)にもできるし、デフォルトの未設定を強制する動作(PUT的)にもできます。

infra.aap_configuration コレクションでは、デフォルト値を強制する動作のことを、Enforcing defaults と呼んでいるようです()。

うれしい点4: 横断的な共通設定がラク

前述の Enforcing defaults の動作にするかどうかや、実行ログ上のパスワード類を隠すかどうか、などの設定を、ロールごとだけでなく、横断的(グローバル)にも指定できます。

他にも、各オブジェクトの stateplatform_state という変数で、全ロール(全オブジェクト)まとめて指定できます(ロールごとの指定がある場合はそちらが優先)。

うれしい点5: AAP 2.5 事後設定の仕組みに流用しやすい

「はじめに」でも少し触れましたが、コンテナベースの AAP 2.5 のインストーラーの事後処理(post install)で、設定投入できるようになっています。

この仕組みとして infra.aap_configuration コレクションの前身(統合前)である、infra.controller_configurationinfra.ah_configuration コレクションが利用されます(あくまで現時点。そのうち infra.aap_configuration になるかもしれません)。

そのため、設定の変数定義ファイルを流用しやすいです。本記事では、Automation Gateway への認証情報も変数で定義していますが、AAP 2.5 のインストーラーの事後処理で設定を流し込む場合は、認証情報の定義は不要です(インストーラーの inventory に定義済みのため)。

なお、コレクションの統合時に、ロールが利用する変数名が変わっているものもあります。詳細は以下のドキュメントを参照してください。

infra.aap_configuration/CONVERSION_GUIDE.md at devel · redhat-cop/infra.aap_configuration · GitHub

■ おためし

いくつかのパターンでためします。

今回は、一番馴染のある Automation Controller への設定を例にします。

1台(というか1セット)のみを対象とするので、インベントリファイルを作成せず、対象ホストは localhost のみにします。

準備: コレクションのインストール

まず環境の準備として以下のコレクションをインストールしておきます。

  • infra.aap_configuration
  • ansible.controller

インストールコマンド:

ansible-galaxy collection install infra.aap_configuration
ansible-galaxy collection install ansible.controller

今回は Automation Controller への設定のみ行うので、infra.aap_configuration 以外に必要なのは ansible.controller のみです。もし、 Automation Gateway の設定をするなら ansible.platformEDA なら ansible.eda、Automation Hub なら ansible.hub もインストールする必要があります(参考)。

なお、ansible.controlleransible.platformansible.edaansible.hub コレクションは、Ansible Galaxy にありません。ansible-galaxy collection install コマンドでインターネット経由でインストールする場合は、Red Hat 社がホストする Automation Hub を参照するように設定しておく必要があります(参考)。

(補足)AWX への対応について

infra.aap_configuration はドキュメント上、内部的に利用するコレクションとして ansible.controllerawx.awx コレクションの両方に対応している旨の記述があります。おそらくこれは前身の infra_controller_configuration コレクションの名残ではないかと思います。

infra.aap_configuration コレクションは、 Automation Gateway が導入された AAP 2.5 以上向けと明記(リポジトリの説明などに)されており、この面でも AWX とアーキテクチャーが異なります。infra.aap_configuration コレクションで AWX に対する設定は試していませんが、おそらくうまくいかないところも出てくると思います。

ちなみに、試した限りansible.controllerawx.awx コレクションの両方がインストールされている場合、ansible.controller が優先されるようでした。

おためし1: オブジェクト個別のロールを呼ぶ

まず一番単純な以下のパターンです。

  • Playbook: 自分で書く
  • ロール: controller_projects などのオブジェクト個別ロールを利用
  • 設定の変数定義ファイル: 自分で書く

いろんな設定ができますが、基本ともいえる Automation Controller の以下のオブジェクトを作ります。

対象オブジェクト 利用ロール
プロジェクト controller_projects
インベントリ controller_inventories
認証情報 controller_credentials
ジョブテンプレート controller_job_templates

変数定義ファイルの準備

認証情報の定義

まず、API リクエストする際の、リクエスト先や認証情報の指定をします。

AAP 2.5 では、Automation Gateway を通じた API リクエストが基本です。そのため、リクエスト先や認証情報は Automation Controller ではなく、Automation Gateway のものを指定します。変数名はドキュメントにも記載があります。

configs/auth.yml:

---
aap_hostname: 192.168.1.100     # Automation Gateway の接続先
aap_token: XXXXXXXXXXXXXXXXXX   # Automation Gateway の API トークン。実際は ansible-vault で暗号化しておくなど
aap_validate_certs: false

# 以下は設定とは直接は関係ありませんが、Python インタープリター決定時の警告を出さないようにするため
ansible_python_interpreter: "{{ ansible_playbook_python }}"

aap_tokenトークンで指定する場合は、予めトークンを作成(例 Automation Gateway にログイン > Access Management > ユーザー > [ユーザー名] > Token )しておきます。

もし、ユーザー名とパスワードの組み合わせを利用する場合は、変数 aap_usernameaap_password で指定します。 ユーザー名とパスワードの組み合わせだと、内部的に都度トークンを作成、削除を繰り返します。

リクエスト数を少なくしたいなどの場合は、トークンがよいと思いまいます。なお、 2024/12/17 現在 リポジトリトップの README.mdには、controller_oauthtoken という変数名がありますが、誤りのようです(おそらく前身コレクションの名残)。正しくは各ロールの README.md にもある通り aap_token のはずです。(修正PRは提出済み)。

設定値の定義

次に、各オブジェクトに対する設定値を、変数定義ファイルとして定義します。ここでは設定値を 1つのファイルにまとめますが、たとえばオブジェクト種別ごとにファイルを分けても、まとめて読み込めばOKです。

設定変数のフォーマットの詳細は各ロールの README.md を参照してくだい(controller_projects であれば roles/controller_projects/README.md )。

configs/controller_config.yml:

---
# Automation Controller の設定の変数定義ファイル
# ここの定義順は依存性を意識しなくてよい
controller_inventories:
  - name: test_inventory
    organization: Default
    description: hogehoge

controller_hosts:
  - name: test_host01
    inventory: test_inventory
    enabled: true
    variables:
      ansible_host: 192.168.1.201

controller_groups:
  - name: servers
    inventory: test_inventory
    hosts:
      - test_host01

controller_credentials:
  - name: test_credential
    credential_type: Machine
    organization: Default
    inputs:
      username: myuser
      password: dummy_password       # 実際は ansible-vault で暗号化しておくなど

controller_projects:
  - name: test_project
    organization: Default
    scm_type: git
    scm_url: https://github.com/ansible/ansible-tower-samples
    scm_branch: master
    scm_update_on_launch: true

controller_templates:
  - name: test_job_template
    inventory: test_inventory
    project: test_project
    playbook: hello_world.yml

(補足1) aap_hostname に Automation Gateway のアドレスを指定する理由

ansible.controller コレクションは、バージョン4.6.0 からAPI リクエストのベースのが以下のように変わりました。

  • 4.5 まで https://アドレス/api/
  • 4.6.0 から https://アドレス/controller/api/

これは、バージョン 4.6.0 から AAP 2.5 向け、つまり Automation Gateway 経由が前提だから、ということのようです。

https://Automation Gateway のアドレス/controller/api/ をリクエストすることによって、最終的には Automation Controller の /controller/api/ にリクエストできます。リダイレクトされるわけではなく、透過的に処理されるので、API クライアントから意識しません。

aap_hostname に Automation Gateway のアドレスを指定しても Automation Controller を操作できるのはこのような仕組みのためです。

厳密には、https://Automation Controller のアドレス/controller/api/ のように Automation Controller を直接指定しても Automation Controller を操作できますが、infra.aap_configuration が Automation Controller 以外の AAP のプロダクトも扱うことを考慮すると、やはり aap_hostname は Automation Gateway のアドレスを指定するのが妥当でしょう。

参考: Automation Gateway と Automation Controller と API の関係

(補足2)各種変数定義の方法について

今回は、認証情報と設定の変数定義ファイルをドキュメントの方法に寄せて、独立した変数定義ファイルを作成しました。

普通の変数の読み込みの仕組みを使っているだけなので、以下のような定義、読み込み方法も可能です。

  • インベントリ変数として定義する
  • 任意のファイル名、任意の単位で分割して、ディレクトリ丸ごと変数を読み込む
  • 逆に、認証情報と設定の変数定義ファイルを1つにまとめる

(補足3)変数定義ファイルのフォーマットとエクスポートについて

utomation Controller の各オブジェクトの設定変数のフォーマットは、awx コマンド(awxkit)の export 機能で出力したフォーマットが参考になりそうです。もし awx export する場合は、接続対象を Automation Gateway ではなく Automation Controller 直のアドレスや認証情報にする必要があります。Automation Gateway 経由だと、API エンドポイントのパスの整合性がないためです(少なくともデフォルトの場合)。

エクスポートの情報は以下のドキュメントを参照してください。

infra.aap_configuration/EXPORT_README.md at devel · redhat-cop/infra.aap_configuration · GitHub

Playbook の準備

続いて Playbook の準備です。変数ファイルを読み込み、各オブジェクトに応じたロールを呼びます。

configure.yml:

---
- name: Configure AAP by each roles
  hosts: localhost
  gather_facts: false
  connection: local

  tasks:
    # 変数ファイルをディレクトリ丸ごと読み込む
    - name: Include vars
      ansible.builtin.include_vars:
        dir: ./configs
        extensions:
          - yml

    # 各オブジェクトに対応するロールを依存性を意識した順番で呼びだす
    - name: Import infra.aap_configuration.controller_inventories
      ansible.builtin.import_role:
        name: infra.aap_configuration.controller_inventories

    - name: Import infra.aap_configuration.controller_hosts
      ansible.builtin.import_role:
        name: infra.aap_configuration.controller_hosts

    - name: Import infra.aap_configuration.controller_host_groups
      ansible.builtin.import_role:
        name: infra.aap_configuration.controller_host_groups

    - name: Import infra.aap_configuration.controller_credentials
      ansible.builtin.import_role:
        name: infra.aap_configuration.controller_credentials

    - name: Import  infra.aap_configuration.controller_projects
      ansible.builtin.import_role:
        name: infra.aap_configuration.controller_projects

    - name: Import infra.aap_configuration.controller_job_templates
      ansible.builtin.import_role:
        name: infra.aap_configuration.controller_job_templates

ここまでの作業で、ファイル、ディレクトリ構造は以下のようになります。

├── configs
│   ├── auth.yml
│   └── controller_config.yml
├── configure.yml

実行

先ほど自分で作成した Playbook を実行します。

ansible-playbook -i localhost, configure.yml 

実行ログ(クリックして開く):

$ ansible-playbook -i localhost, configure.yml 

PLAY [Configre AAP by each roles] ***************************************************************************************

TASK [Include vars] *****************************************************************************************************
ok: [localhost]

TASK [infra.aap_configuration.meta_dependency_check : Print dependency check status] ************************************
ok: [localhost] => {
    "msg": "Dependency check is deactivated. Required collections presence will not be verified. This might cause failure in the next tasks."
}

TASK [infra.aap_configuration.meta_dependency_check : Check awx.awx is installed] ***************************************
skipping: [localhost]

TASK [infra.aap_configuration.meta_dependency_check : Check ansible.controller is installed] ****************************
skipping: [localhost]

TASK [infra.aap_configuration.meta_dependency_check : Ensure one is installed] ******************************************
skipping: [localhost]

TASK [infra.aap_configuration.controller_inventories : Validating arguments against arg spec 'main' - An Ansible Role to create inventories on Ansible Controller.] ***
ok: [localhost]

TASK [infra.aap_configuration.controller_inventories : Managing Inventories] ********************************************
ok: [localhost] => (item=Create/Update inventory test_inventory)

TASK [infra.aap_configuration.controller_inventories : Flag for errors (check mode only)] *******************************
skipping: [localhost]

TASK [infra.aap_configuration.controller_inventories : Managing Controller Inventories | Wait for finish the inventories management] ***
FAILED - RETRYING: [localhost]: Managing Controller Inventories | Wait for finish the inventories management (30 retries left).
changed: [localhost] => (item=Create/Update Controller inventory test_inventory | Wait for finish the inventories creation)

TASK [infra.aap_configuration.controller_hosts : Validating arguments against arg spec 'main' - An Ansible Role to create hosts on Ansible Controller.] ***
ok: [localhost]

TASK [infra.aap_configuration.controller_hosts : Managing Controller Hosts] *********************************************
ok: [localhost] => (item=Create/Update Controller host test_host01)

TASK [infra.aap_configuration.controller_hosts : Flag for errors (check mode only)] *************************************
skipping: [localhost]

TASK [infra.aap_configuration.controller_hosts : Managing Controller Hosts | Wait for finish the Hosts management] ******
FAILED - RETRYING: [localhost]: Managing Controller Hosts | Wait for finish the Hosts management (30 retries left).
changed: [localhost] => (item=Create/Update Controller Host test_host01 | Wait for finish the Hosts creation)

TASK [infra.aap_configuration.controller_host_groups : Validating arguments against arg spec 'main' - An Ansible Role to create groups on Ansible Controller.] ***
ok: [localhost]

TASK [infra.aap_configuration.controller_host_groups : Managing Controller Groups] **************************************
ok: [localhost] => (item=Create/Update Controller Group servers)

TASK [infra.aap_configuration.controller_host_groups : Flag for errors (check mode only)] *******************************
skipping: [localhost]

TASK [infra.aap_configuration.controller_host_groups : Managing Controller Groups | Wait for finish the Controller Groups management] ***
FAILED - RETRYING: [localhost]: Managing Controller Groups | Wait for finish the Controller Groups management (30 retries left).
changed: [localhost] => (item=Create/Update Controller Group servers | Wait for finish the Controller Group creation)

TASK [infra.aap_configuration.controller_credentials : Validating arguments against arg spec 'main' - An Ansible Role to create credentials on Ansible Controller.] ***
ok: [localhost]

TASK [infra.aap_configuration.controller_credentials : Managing Credentials] ********************************************
ok: [localhost] => (item=None)
ok: [localhost]

TASK [infra.aap_configuration.controller_credentials : Flag for errors (check mode only)] *******************************
skipping: [localhost]

TASK [infra.aap_configuration.controller_credentials : Managing Controller Credentials | Wait for finish the credential management] ***
FAILED - RETRYING: [localhost]: Managing Controller Credentials | Wait for finish the credential management (30 retries left).
changed: [localhost] => (item=None)
changed: [localhost]

TASK [infra.aap_configuration.controller_projects : Validating arguments against arg spec 'main' - An Ansible Role to create projects on Ansible Controller.] ***
ok: [localhost]

TASK [infra.aap_configuration.controller_projects : Managing Projects] **************************************************
ok: [localhost] => (item=Create/Update Project test_project)

TASK [infra.aap_configuration.controller_projects : Flag for errors (check mode only)] **********************************
skipping: [localhost]

TASK [infra.aap_configuration.controller_projects : Managing Projects | Wait for finish the projects management] ********
FAILED - RETRYING: [localhost]: Managing Projects | Wait for finish the projects management (30 retries left).
FAILED - RETRYING: [localhost]: Managing Projects | Wait for finish the projects management (29 retries left).
FAILED - RETRYING: [localhost]: Managing Projects | Wait for finish the projects management (28 retries left).
FAILED - RETRYING: [localhost]: Managing Projects | Wait for finish the projects management (27 retries left).
FAILED - RETRYING: [localhost]: Managing Projects | Wait for finish the projects management (26 retries left).
FAILED - RETRYING: [localhost]: Managing Projects | Wait for finish the projects management (25 retries left).
FAILED - RETRYING: [localhost]: Managing Projects | Wait for finish the projects management (24 retries left).
changed: [localhost] => (item=Create/Update Project test_project | Wait for finish the project creation)

TASK [infra.aap_configuration.controller_job_templates : Validating arguments against arg spec 'main' - An Ansible Role to create job templates on Ansible Controller.] ***
ok: [localhost]

TASK [infra.aap_configuration.controller_job_templates : Managing Controller Job Templates] *****************************
ok: [localhost] => (item=Create/Update Controller Job Template test_job_template)

TASK [infra.aap_configuration.controller_job_templates : Flag for errors (check mode only)] *****************************
skipping: [localhost]

TASK [infra.aap_configuration.controller_job_templates : Managing Job Templates | Wait for finish the Job Templates management] ***
FAILED - RETRYING: [localhost]: Managing Job Templates | Wait for finish the Job Templates management (30 retries left).
FAILED - RETRYING: [localhost]: Managing Job Templates | Wait for finish the Job Templates management (29 retries left).
changed: [localhost] => (item=Create/Update Job Template {'failed': 0, 'started': 1, 'finished': 0, 'ansible_job_id': 'j639891192001.998282', 'results_file': '/home/yokochi/.ansible_async/j639891192001.998282', 'changed': False, '__controller_template_item': {'name': 'test_job_template', 'inventory': 'test_inventory', 'project': 'test_project', 'playbook': 'hello_world.yml', 'credentials': ['test_credential'], 'execution_environment': 'Default execution environment'}, 'ansible_loop_var': '__controller_template_item'} | Wait for finish the Job Template creation)

PLAY RECAP **************************************************************************************************************
localhost                  : ok=20   changed=6    unreachable=0    failed=0    skipped=9    rescued=0    ignored=0   

事後確認

無事に設定できました。(そろそろ Red Hat Developer Subscription for Individual 更新の時期で警告が・・)

インベントリ、ホスト、グループが作成された

認証情報が作成された

プロジェクトが作成された

ジョブテンプレートが作成された

ジョブテンプレートも実行できました。

ジョブテンプレートが実行できた

おためし2: dispatch ロールを利用

続いてのパターンは、オブジェクト個別のロールではなく、dispatch ロールを利用するパターンです。

  • Playbook: 自分で書く
  • ロール: dispatch ロールを利用
  • 設定の変数定義ファイル: 自分で書く

準備

変数定義ファイルは、おためし1 と同じものを利用します。

Playbook は以下のように、dispatch ロールを利用するものにします。

---
- name: Configure AAP by dispatch role
  hosts: localhost
  gather_facts: false
  connection: local

  tasks:
    # 変数ファイルをディレクトリ丸ごと読み込む
    - name: Include vars
      ansible.builtin.include_vars:
        dir: ./configs
        extensions:
          - yml

    # dispatch ロールで丸ごと設定
    - name: Import infra.aap_configuration.dispatch
      ansible.builtin.import_role:
        name: infra.aap_configuration.dispatch

ファイル、ディレクトリ構造は以下のようになります。

├── configs
│   ├── auth.yml
│   └── controller_config.yml
└── dispatch.yml

実行

先ほど作成した Playbook を実行します。

ansible-playbook -i localhost, dispatch.yml

ログやキャプチャは省略しますが、無事に設定できました。

おためし3: コレクション内の Playbook を利用する

3つめのパターンは、コレクションに含まれる Playbook を利用するパターンです。

  • Playbook: コレクションに含まれる configure_aap.yml を利用
  • ロール: dispatch ロールを利用(上記 Playbook で呼ばれる)
  • 設定の変数定義ファイル: 自分で書く

準備

引き続き、変数定義ファイルは同じものを利用します。Playbook はコレクションに含まれるものを利用するので他に準備はいりません。

ファイル、ディレクトリ構造は以下のようになります。

└── configs
    ├── auth.yml
    └── controller_config.yml

実行

コレクション内にある Playbook configure_aap.yml を実行します。この Playbook は、変数定義ファイルの読み込みと、dsipatch ロールの呼よびだしをします。コレクション内の Playbook を呼ぶために FQCN で指定する点と、変数定義ファイルがあるディレクトリのパスを変数 aap_configs_dir で指定する点がポイントです。

ansible-playbook -i localhost, infra.aap_configuration.configure_aap -e aap_configs_dir=${PWD}/configs

変数 aap_configs_dir の事情は configure_aap.yml の以下のタスクを見ると分かります。

    - name: Include vars from configs directory
      ansible.builtin.include_vars:
        dir: "{{ aap_configs_dir | default((lookup('env', 'AAP_CONFIGS_DIR') == '') | ternary('./configs', lookup('env', 'AAP_CONFIGS_DIR'))) }}"
        ignore_files: [controller_config.yml.template]
        extensions: [yml]

相対パスで指定すると、Playbook 起点(infra.aap_configuration コレクションのインストール先の playbooks ディレクトリ)になります。今回は、ansible-playbook コマンド実行のカレントディレクトリ配下の config ディレクトリを利用したかったため、aap_configs_dir のパスは ${PWD} を補完して絶対パスに調整しています。

ログやキャプチャは省略しますが、無事に設定できました。

■ 留意点

便利なコレクションではありますが、今のところ気づいている考慮点として以下の点が挙げられます。

いずれも、今回ためしたinfra.aap_configuration コレクション 3.1.0 時点です。

留意点1: バグの入る余地

ansible.controller などのコレクションをロールとして抽象化している以上、どうしてもバグが入る余地も出てきていまいます。たとえば、前述の dispatch ロールは、controller_roles ロールを呼ばないという不具合があります(3.1.0時点。おそらく次のリリースで修正予定)。

ただ、バグがあるとしてもパブリックなリポジトリで管理、メンテされていることは意味があることだと思っています。

留意点2: 一部ドキュメントの不整合

また、前身の infra.controller_configuration コレクションから流用した影響もあってか、実装とドキュメントの不整合が一部残っています。たとえば、ロールに指定する変数のデフォルト値が、各ロールの README.mddefaults/main.ymlmeta/argument_specs.yml の間で整合性がないことがあります。デフォルト値については、実装である defaults/main.yml を確認することをおすすめします。

ドキュメント不整合や typo 的なものは、最近私もちまちま修正をしていますので、少しずつ改善できる見込みです。

留意点3: キー名を間違えてもエラーにならない

ansible.controller などにに含まれるモジュールを直接利用する場合は、モジュールのオプション名はシビアです。存在しないオプション名を指定すると Unsupported です、といったエラーになります。

しかし infra.aap_configuration コレクション内のロールに与える変数のチェックである Role argument validation の定義はゆるめです。例えば、 controller_hosts ロールの場合、定義が一部コメントアウトにされています。

このため、キー名が間違っていてもバリデーションではエラーにならず気が付かないケースがありえます。利用する側が注意を払う必要があります。

なお、各ロールが利用する変数定義ファイルは、あくまでただの変数定義ファイルです。そのため、VS Code の Ansible の拡張によるモジュールのオプションのキー名補完機能は利用できません。もし補完したい場合は、別途 JSON Schema を割り当てるなどの対応が必要になるはずです。

■ おわりに

AAP の各プロダクトの設定自動化が便利になる infa.aap_configuration コレクションをためしてみました。

おそらく、似たようなロールを各自で作成しているケースも多いのではないかと思いました。このコレクションのように、どうせならパブリックなリポジトリで、改善を重ねていくのが良いかなと思いました。

参考(再掲含む)

JSTQB 認定テスト技術者資格試験 Foundation Level を受験してきました(シラバス2023V4.0)

はじめに

先日、JSTQB 認定テスト技術者資格試験のうち一番基礎的な Foundation Level (FL)を受験してきました。

以前から興味はあったのですが、2024年11月にシラバスが更新されたのをきっかけに受けてみようと思いました。

簡単ですがまとめます。

JSTQB 認定テスト技術者 Foundation Level

ソフトウェアのテストに関する知識な知識が問われる試験です。詳細は、シラバスを参照してください。

サンプル問題も公開されています。

勉強方法

今回のシラバス変更にした以下の書籍を利用しました。

book.impress.co.jp

一通り知識が学べて、各章末に練習問題があり、最後にまとめた問題があります。

結果的には私はこの1冊で十分でした。3-4 週間かけました。

なんとなくですが、昔に ITIL Foundation を勉強していたときの感覚に近かったです。特に、これにはこういうプロセスがあって各プロセスでは誰が何をして・・といった流れを覚える類のものです。

苦手と感じたのは以下の点です。

  • テストプロセスには何があるか、それぞれ何をするのか
    • テスト計画
    • テストのモニタリングとコントロール
    • テスト分析
    • テスト設計
    • テスト実装
    • テスト実行
    • テスト完了
  • テストの四象限と、各テストがどこにあたるか
    • 縦軸: ビジネス指向/テクノロジー指向
    • 横軸: チームを支援する/プロダクトを批評する

これまでの経験でそれはそうと思える部分もありますが、「なるほどこういう考え方もあるのか」とリセットしてインプットする部分もありました。

たとえば「テスト実装ではアレする。正しいか」と問われると、他にどういうプロセスがあるかを覚えておかないと、それっぽいなと思ってしまう事が多いです。なので、感覚に任せずに、どういうプロセスがあるかを覚えることを最初にしました。

正直テストの四象限はずっとしっくり来てませんでした・・

境界値分析や同値分割など、テクニック的なことは多くなかったです。ここ部分に関しては、基本情報技術者、応用技術者レベルといった感覚です。

テストの7原則は、共通認識をつくるときに便利だなと思いました。シラバスにも掲載されています。

  1. テストは欠陥があることは示せるが、欠陥がないことは示せない
  2. 全数テストは不可能
  3. 早期テストで時間とコストを節約
  4. 欠陥の偏在
  5. テストの弱化
  6. テストはコンテキスト次第
  7. 「欠陥ゼロ」の落とし穴

当日とその後

よくある CBT と同じような予約をして、当日もテストセンター的なところで受けました。

少し時間を余らせるくらいのタイミングで試験を終えました。

受け付けてで試験レポートを受け取りましたが、そこには結果は書かれていません。

あとでしべたら、当日は結果はわからず、2週間以内に分かるとのことでした。CBT = その場で合否がわかると思い込んでいたのですが、ちゃんと書かれていることを読んでおいたほうがいいですね。反省です。

私の場合は 5日後くらいにJSTQB認定試験申し込みWebサイトで合格を確認できました。2週間後には紙の認定証が届きました。

おわりに

ふりかえってみると、テクニック的なことよりは、プロセス、枠組みを問われることが多い試験に感じました。

[Ansible] loop を抜ける条件を指定する break_when

この記事は Ansible Advent Calendar 2024 の 12日目の記事です。

はじめに

タスクを loop で実行する際、ループを抜ける条件を指定する break_when というキーワードが、ansible-core 2.18.0 で追加されました。

changelogから:

loop_control - add a break_when option to to break out of a task loop early based on Jinja2 expressions (#83442).

公式ドキュメント: Breaking out of a loop

せっかくなので試してみました。

検証環境:

  • ansible-core 2.18.0

break_when を試す

以下の Playbook で試します。1 から 5 までループしですが、3 まででループを終わらせるものです。

---
- name: Test Play
  hosts: localhost
  connection: local
  gather_facts: false

  vars:
  tasks:
    - name: Test break_when
      ansible.builtin.debug:
        msg: "{{ item }}"
      loop:
        - 1
        - 2
        - 3
        - 4
        - 5
      loop_control:
        break_when:
          - item == 3

実行結果は以下のとおりです。

$ ansible-playbook -i localhost, break_when.yml

PLAY [Test Play] ***************************************************************************************************

TASK [Test break_when] *********************************************************************************************
ok: [localhost] => (item=1) => {
    "msg": 1
}
ok: [localhost] => (item=2) => {
    "msg": 2
}
ok: [localhost] => (item=3) => {
    "msg": 3
}

PLAY RECAP *********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

3「まで」ループして、4 と 5 は処理されませんでした。skipにもならないのでログがすっきりしていますね。

おわりに

これまでこういう機能を使いたいことがあったようななかったような、という感じですが、もしかしたら今後使いたいときがくるかもしれません。

[Ansible] コレクション内の Playbook のファイル名に - (ハイフン)は使えない

この記事は Ansible Advent Calendar 2024 の 9日目の記事です。

はじめに

コレクションというと、モジュールやプラグイン、ロールを含む単位のイメージが強いかもしれませんが、Playbook も含めることができます。

たとえば、local.sakana コレクションに install.yml という Playbook がある場合、ansible-playbook コマンドなどからは、local.sakana.install という指定で Playbook を呼べます(拡張子はなくてもOK)。

最近、Plyabook のファイル名に - (ハイフン)は使えないという制約があることを知りました。

The dash - character is not valid for playbook names in collections

https://docs.ansible.com/ansible/latest/collections_guide/collections_using_playbooks.html#using-a-playbook-from-a-collection

少し気になったので試してみます。

検証環境

  • ansible-core 2.16.6

おためし

コレクション内にハイフンあり、なしの Playbook をそれぞれ仕込んでおきます。playbooks ディレクトリに格納するのは、そういう仕様のためです。

 ~/.ansible/collections/ansible_collections/
└── local
    └── sakana
        └── playbooks
            ├── test-playbook.yml
            └── test_playbook.yml

Playbook は、ただ debug するだけの簡単なものです。

- なし(代わりに _)の Playbookの場合、正常に実行できます。

% ansible-playbook -i localhost, local.sakana.test_playbook

PLAY [localhost] **************************************************************************************************

TASK [ansible.builtin.debug] **************************************************************************************
ok: [localhost] => {
    "msg": "Hello world!"
}

PLAY RECAP ********************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

続いて - ありの場合、Playbook が見つからないエラーになりました。.yml をつけても同じでした。

% ansible-playbook -i localhost, local.sakana.test-playbook
ERROR! the playbook: local.sakana.test-playbook could not be found

なお、コレクション内の Playbook としての指定ではなく、普通のファイルパスで指定する分には - ありでも実行できます。この場合は、拡張子まで必須です。

% ansible-playbook -i localhost, ~/.ansible/collections/ansible_collections/local/sakana/playbooks/test-playbook.yml 

PLAY [localhost] *************************************************************************************************************************************************************

TASK [ansible.builtin.debug] *************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "Hello world!"
}

PLAY RECAP *******************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

おわりに

Ansible は、グループ名に - を使うと警告が表示されたり、ロール名は -を使わない規則にしているコレクションがあったり、たまに - を使うと都合が悪い時があります。

そんなこともあって、どちらかというと私は _ を使うことが多いです。