てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible/EDA] カスタム の Decision Environment (DE)を ansible-builder でビルドする

はじめに

EDA Controller では、Rulebook を実行するために Decision Environment(画面上の文言は "決定環境" )が必要です。実態は利用するコンテナイメージの指定です。Automation Controller が Playbook を実行するために、Execution Environment(EE、実行環境)が必要なのと同じような関係です。ansible.eda コレクションを含む標準的なものもありますが、ほかのコレクションを含めたいときなどではカスタム Decision Environment をビルドする必要があります。

本記事では、カスタムの Decision Environment のビルドを試したときのことをまとめます。やや試行錯誤も含まれます。

今回は環境の都合上、Rulebook のアクティベーションを作成できるところまでの簡単な動作確認までにします。今回取り上げるイベントソースプラグインを使うための正確な手順を示すというよりは、カスタムビルドする一般的な大まかな流れを追う、という位置づけの記事です。

なお、Red Hat のナレッジベースにアクセスできる方は、以下のページを見ていただくほうが早いかもしれません。

How do I Build a Custom Decision Environment for Event Driven Ansible within Ansible Automation Platform? - Red Hat Customer Portal

本記事は誰でもアクセスできる情報と自分で試した結果を組み合わせています。

  • 環境
    • ansible-builder 3.0.0
    • EDA Controller 1.0.0
      • バージョン番号は rpm のファイル名から類推
      • AAP 2.4 のインストーラーで構築したもの

前提: カスタムの Decision Environment が必要になるケース

先日 AAP 2.4 インストーラーで構築した EDA Controller には Default Decision Environment という名前の Decision Environment がありました。イメージは registry.redhat.io/ansible-automation-platform-24/de-supported-rhel8:latest が指定されていました。この Decision Environment は、ansible.eda コレクションのみ含まれていました。そのため、webhookurl_check などのイベントソースプラグインが利用できます。

一方で、ansible.eda コレクション以外のイベントソースプラグインを利用するには、別途コレクションをインストールするようにカスタムした Decision Environment が必要になってきます。この辺の事情も Automation Controller における カスタム EE の必要性と似ていますね。

なお、今回は本当に必要に迫られて作ったわけではなく、一応やり方を試してみるという程度です。

イメージの準備

まず、ビルドするための定義ファイルを作成して、ビルドします。

定義ファイルの作成

今回は、見本として ansible-rulebook 1.0.0 に含まれる minimal-decision-environment.ymlをベースにします(改善のプルリクエストあり)。このファイルには、基本的なイベントソースプラグインが含まれる ansible.edaコレクションや、そのコレクションが依存している Python パッケージが指定されています。(実際は、ここでの明示的な指定以外にもコレクションの requirements.txt を読み込んでインストールするので、明示的な指定は不要におもいます。分かりやすい例にするために明示をしているようです)

今回用に、ファイル名を decision-environment.yml として、以下の内容で作成します。ベースから追加、変更したところにコメントを入れています。ベースイメージに registry.redhat.io/ansible-automation-platform-24/de-supported-rhel8:latestquay.io/ansible/ansible-rulebook を利用してカスタマイズしても良いかと思います。

---
version: 3

images:
  base_image:
    name: 'registry.access.redhat.com/ubi9/python-39:latest'  # A. Pythonバージョン調整

dependencies:
  galaxy:
    collections:
      - name: ansible.eda
      - name: paloaltonetworks.panos  # B. 追加コレクション
        version: 2.17.3    
  python:
    - azure-servicebus
    - aiobotocore
    - aiohttp
    - aiokafka
    - watchdog
    - systemd-python
    - dpath
    - ansible-rulebook
    # C. ここから paloaltonetworks.panos の依存パッケージ
    - pan-python
    - xmltodict
    - paramiko
  ansible_core:
    package_pip: ansible-core==2.14.4
  ansible_runner:
    package_pip: ansible-runner
  system:
    - java-17-openjdk-devel [platform:rpm]

A. Python バージョン調整(やや余談)

ベースにした定義ファイルでは registry.access.redhat.com/ubi9/python-311:latest が指定されていました。何も考えずに使えば Python 3.11 の Ansible 環境が作れると思いましたが、実際ためすと Python 3.9 で Ansible 環境が作られました(Ansible 環境は /usr/bin/python3Python 3.11 は /opt/app-root/bin/python3.11)。イメージ名と直感的に合うように、Ansible 環境も Python 3.11 にしようと思って、

dependencies:
  python_interpreter:
    package_system: python3.11
    python_path: /usr/bin/python3.11

のように指定しましたが、今度は systemd_python のインストールがエラーになってしまいました。

と、紆余曲折ありまして、結局ベースイメージは registry.access.redhat.com/ubi9/python-39:latest を指定することにしました。

B. 追加コレクション paloaltonetworks.panos について

追加コレクションで指定しているのは paloaltonetworks.panosです。これを選んだ理由は、モジュール以外にもpaloaltonetworks.panos.logs というイベントソースプラグインが含まれているためです。なお、paloaltonetworks.panos コレクションの 2.17.2 の paloaltonetworks.panos.logs イベントソースプラグインにはバグがあるので利用しないようにします。

C. 依存 Python パッケージについて

一応依存 Python パッケージの指定もしています。実際はモジュールが依存しているだけで、イベントソースプラグインは依存していなさそうです。

少しややこしい事情ですが、ansible-builder build-v 3 付きで実行すると、failed to parse requirements from paloaltonetworks.panos, error: not enough values to unpack (expected 1, got 0) という warning が表示されます。どうも paloaltonetworks.panos コレクションの requirements.txtを書式的にうまく読み込めていないようです。今回のように、dependencies.python に明示的に指定すれば指定した Python パッケージはインストールされます。

ビルドする

Decision Environment も Execution Environment と同様に、ansible-builder でビルドします。今回は GitHub のコンテナレジストリに push する想定の名前にします。デフォルトでは execution-environment.yml というファイルを読み込むため、-f オプションで先ほど作成した定義ファイル名 decision-environment.yml を指定します。数分時間がかかるので、処理の様子が分かるように -v 3 も付けます。

ansible-builder build -t ghcr.io/akira6592/ansible-de-test -f decision-environment.yml -v 3

これでイメージがビルドできました。docker iamges で確認します。

$ docker images
REPOSITORY                          TAG       IMAGE ID       CREATED              SIZE
ghcr.io/akira6592/ansible-de-test   latest    29cd8f09aa16   About a minute ago   1.6GB
...()...

念のため、インストールされたコレクションを確認します。

 $ docker run -it ghcr.io/akira6592/ansible-de-test ansible-galaxy collection list

# /usr/share/ansible/collections/ansible_collections
Collection             Version
---------------------- -------
ansible.eda            1.4.2  
paloaltonetworks.panos 2.17.3 

インストールされた Python パッケージも確認します。

 $ docker run -it ghcr.io/akira6592/ansible-de-test /usr/bin/pip3 list
Package                   Version
------------------------- ---------
aiobotocore               2.5.2
aiohttp                   3.8.4
aioitertools              0.11.0
aiokafka                  0.8.1
aiosignal                 1.3.1
ansible-core              2.14.4
ansible-rulebook          1.0.0
ansible-runner            2.3.3
async-timeout             4.0.2
attrs                     23.1.0
azure-core                1.28.0
azure-servicebus          7.11.1
botocore                  1.29.161
...()...
pan-os-python             1.11.0
pan-python                0.17.0
...()...
xmltodict                 0.13.0
yarl                      1.9.2
zipp                      3.16.2

今回の場合、単に pip3 を指定すると ansible 環境とは別の /opt/app-root/bin/pip3 のパスのほうを使うため、上記のように指定しました。この辺りは調整可能かなと思います。

ちなみに、当初 ansible-navigator images コマンド経由で色々確認しようと思ったのですが、Unexpected errors were encountered while running 'select' というエラーが発生してしまいました。詳細は追えていません。

イメージの確認が済んだところで、 push します(ここでは docker login ghcr.io で認証済みのものとします)。

docker push ghcr.io/akira6592/ansible-de-test:latest

これで、カスタムビルドしたイメージをコンテナレジストリに置けました。

EDA Controller で利用する

先ほどビルドしたイメージを、EDA Controller で利用できるように設定して、アクティベーションを作成します。

Decision Environment (決定環境)の定義

画面左メニューから 決定環境 を開きます。デフォルトでは Default Decision Environment が定義済みで ansible.eda コレクションのイベントソースプラグインのみを利用するのであればこちらで済みます。

今回は、別途カスタムビルドしたイメージを利用するので、決定環境の作成 ボタンをクリックします。

Decision Environment 一覧

作成画面

決定環境作成画面で以下のように入力して、作成します。

項目 意味 今回の設定値
名前 Decision Environmentの名前 ansible-de-test
イメージ イメージのパスやタグ ghcr.io/akira6592/ansible-de-test:latest

今回はパブリックなコンテレジストリにイメージをおいているので、認証情報の指定は不要です。

Rulebook の準備

カスタムの Decision Environment に入れたコレクション paloaltonetworks.panos を使った Rulebook を用意しておきます。ここでは、rulebooks/panos_debug.yml というファイル名とします。

---
- name: panos test
  hosts: all

  sources:
    - name: Listen logs via HTTP server Profile
      paloaltonetworks.panos.logs:
        host: 0.0.0.0
        port: 5000

  rules:
    - name: Say Hello
      condition: event.payload is defined
      action:
        debug: 
          msg: "{{ event }}"

paloaltonetworks.panos コレクションのドキュメントの例を参考にしています。

前述通り、今回は Rulebook のアクティベーションを作成できるところまでの簡単な動作確認までなので、内容は割と適当です・・。

ルールブックのアクティベーションの作成

続いて、画面左メニューから ルールブックのアクティベーション を開いて、ルールブックのアクティベーションの作成 ボタンをクリックします。

アクティベーション作成画面

アクティベーション作成画面で以下のように入力して、作成します。

項目 意味 今回の設定値 備考
名前 ルールブックアクティベーション の名前 panos_activation
プロジェクト Rulebook があるプロジェクト rulebook-sample 事前に作成したもの。先ほど作成委した panos_debug リポジトリを参照するプロジェクト
ルールブック プロジェクト内の Rulebook のファイル名 panos_debug.yml 今回は rulebooks ディレクトリ配下
決定環境 Rulebook を実行する環境 ansible-de-test 先ほど作成したものの

作成したアクティベーションの [履歴] 画面経由で、作成したアクティベーションのログを確認します。

Pulling image ghcr.io/akira6592/ansible-de-test:latest
Starting Container

...(略)...

2023-07-19 06:15:11,129 - ansible_rulebook.engine - INFO - Calling main in paloaltonetworks.panos.logs

2023-07-19 06:15:11,129 - ansible_rulebook.websocket - INFO - websocket wss://host.containers.internal/api/eda/ws/ansible-rulebook connecting

2023-07-19 06:15:11 131 [drools-async-evaluator-thread] INFO org.drools.ansible.rulebook.integration.api.io.RuleExecutorChannel - Async channel connected

2023-07-19 06:15:11,137 - ansible_rulebook.engine - INFO - Waiting for all ruleset tasks to end

2023-07-19 06:15:11,170 - ansible_rulebook.rule_set_runner - INFO - Waiting for actions on events from panos test

2023-07-19 06:15:11,170 - ansible_rulebook.rule_set_runner - INFO - Waiting for events, ruleset: panos test

ステータスも実行中になり、正常に待機状態となりました。今回はここまでの動作確認とします。

インベントリソースが見つからない場合のエラー

デフォルトの Decision Environment で、paloaltonetworks.panos.logs イベントソースプラグインを含む Rulebook のアクティベーションを作成すると、以下のようなエラーになりました。ansible.eda コレクションに含まれていないイベントソースプラグインを使おうとしているため、想定どおりのエラーです。

2023-07-19 06:19:23,663 - ansible_rulebook.engine - ERROR - Source error Could not find source plugin for paloaltonetworks.panos.logs

2023-07-19 06:19:23,663 - ansible_rulebook.engine - ERROR - Shutting down source: paloaltonetworks.panos.logs error : Could not find source plugin for paloaltonetworks.panos.logs

おわりに

paloaltonetworks.panos コレクションを含む、カスタムの Decision Environment を作成してみました。

基本的には Execution Environment の作成方法と同じなので、

参考