てくなべ (tekunabe)

ansible / network 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-cop (Red 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_projects や controller_inventories ロールでプロジェクト、インベントリなどを作成する必要があります。

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

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

仕組みとしては、あらかじめ dispatch ロール内で然るべき順番が定義されているだけです。たとえば、ジョブテンプレートを設定する controller_job_templates ロールよりも前に controller_projects や controller_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_aap は configure_aap.yml の FQCN 表記です)

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

コレクション内の 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 の動作にするかどうかや、実行ログ上のパスワード類を隠すかどうか、などの設定を、ロールごとだけでなく、横断的(グローバル)にも指定できます。

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

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

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

この仕組みとして infra.aap_configuration コレクションの前身(統合前)である、infra.controller_configuration や infra.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.platform、EDA なら ansible.eda、Automation Hub なら ansible.hub もインストールする必要があります(参考)。

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

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

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

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

ちなみに、試した限りansible.controller と awx.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_username、aap_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.md と defaults/main.yml と meta/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 コレクションをためしてみました。

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

参考(再掲含む)