てくなべ (tekunabe)

ansible / network automation / 学習メモ

Red Hat Summit: Connect 2024 参加レポート

はじめに

2024/10/17 に東京の虎ノ門Red Hat Summit: Connect 2024 が開催されました。

www.redhat.com

拝聴したセッションや、ブースでお伺いした話などをまとめます。

Ansible Lightspeedを活用したPlaybook開発

生成AI で Playbook を作成できる「Ansible Lightspeed with IBM Watson」を検証して分かった、最適な使い方などのお話がありました。

プレゼンのポイントをまとめます。

  • 導入の背景
    • 初心者は Ansible への心理的なハードルを感じていた
    • そこで Ansible Lightspeed を導入することに
  • 3か月の検証プロジェクト
    • Ansible 初心者と上級者混在のメンバーで検証を実施
    • 当初は楽観的だったが、一部のコード生成の精度が想定より低いなどの問題があった
    • しかし検証中にも Ansible Lightspeed がアップデートされ、期待を満たすレベルに近づいた
    • 文字列や数値は Playbook に反映されやすいが、IPアドレスのような複雑な値はうまく反映されないことがあった
    • 1からPlaybookを作成するというハードルはさげられた
  • 最適な使い方
    • Guided chat で Playbook を生成。この時点では80点
    • Task generation で完成度を高める
    • Content explanation でドキュメントを生成

総じてうまく活用されていたようでした。事例が多くないので難しいのですが、今回のように初心者と上級者で構成されるチームはうまくいくのではないかと思いました。

あくまで想像ですがが、

  • 初心者だけですと、生成されたものをチェックできないなどの事情で活用しきれない
  • 上級者だけだと、必要性を見出しにくい

といったケースになるのではないかと思いました。

一方で、初心者と上級者の構成であれば、上級者がチェックしつつ、初心者の力をブーストできるような気がしました。

なお、こちらの内容は Ansible Automates 2024 Japan でも類似の発表がありました。

tekunabe.hatenablog.jp

新時代到来!! RHELデプロイとアップグレードの今と未来

RHELは再インストールなしでアップグレードできるという話や、Insights Image Builder、Image Mode for RHEL の話がありました。

Insights Image Builderは、物理でもクラウドでも利用できる RHEL イメージをビルドできるもの。

Web (console.redhat.com) で管理ができるようです。たとえば、AWS でも Azure でも共通のイメージを使えるとのことで便利そうでした。

docs.redhat.com

Image Mode for RHELVMを コンテナのような感覚で扱うもので、現在はまだ Tech Preview

Containerfile/Dockerfile と同じような書式で、FROMrhel9/rhel-bootc:latest という特殊なイメージ、RUN でパッケージ追加、などを指定して、イメージを作成できるそうです。

理解しきれていませんが、コンテナと同じように CI/CD パイプラインに組み込みやすかったり、リビジョン管理されるのでロールバックを一瞬でできる、などのメリットがあるそうです。何かしらの事情で、VM を コンテナのようにビルドしたいときには便利なのかもしれません。

www.redhat.com

仮想サーバーの移行・構築・運用を Ansible で自動化せよ!

Ansible の技術的な解説というよりも、自動化が求められる背景や、仮想化基盤のモダナイズの進め方の説明がメインでした。

「Turn key Deployment」という言葉を初めて知りました。鍵を回す感覚ですぐ使えることを指しているようです。

あと、なるほどと思ったのは、リードタイムが短縮されると、良い意味で使い方を変えられるという点です。今回、仮想マシンのデプロイのリードタイムを一週間から5分に短縮する例があげられていました。

このレベルで短縮されると、以下のような変化が見込めるという話でした。

  • Before: デプロイに時間がかかるため、既存のVMを大事に使いまわしてテストする
  • After: 必要な時に都度クリーンな環境でテストでき、本番リリースの環境差分によるリスクを低減できる

Red Hat Tech Night

17:00 からの枠は「Red Hat Tech Night」。

さらに技術的に濃い LT や、Red Hat のカルチャーについてのパネルディスカッションがありました。

LT の資料は以下のページにアップされています。

ossbyredhat.connpass.com

濃すぎて飲み込めない内容が多かったですが、お土産として持ち帰られたものだけ書き留めておきます。

ルールエンジンとLLMで嘘をつかないAIを作ろう

航空会社のAIチャットボットが、誤った返金ルールの回答をしてしまい、裁判沙汰になってしまった事例があったそうです。

このような事例を防ぐアイディアとして、チャットボットにおいて、必要な情報を得るまでを LLM に、規程(ルール)との照合をルールエンジン(Drools)にやってもらうという方式が紹介されていました。

この分野は詳しくはないのですが、役割分担の参考にしたいなと思いました。

また、Drools は Event-Driven Ansible の文脈でしか聞いたことがなかったのですが、活用方法が知れてよかったです。

www.slideshare.net

ブース展示エリア

セッションが行われる部屋とは別に、Red Hat の各製品や各社のブースが設けられているエリアがありました。

OpenShift Virtualization

あまりゆっくり回れなかったのですが、OpenShift Virtualization のブースでご説明いただきました。 「コンテナのように VMオーケストレーションするもの」程度の理解だったのですが、いただいたチラシで「Red Hat Enterprise Linux仮想マシンは無償・無制限で使用可能」であることを知りました。

www.redhat.com

Migration Toolkit for Virtualization (MTV) という VM 移行ツールの存在も知りました。

Red Hat Developer Hub

他にも Red Hat Developer Hub のブースも少し拝見しました。最近、Ansible のプラグインが登場したので、気になり始めています。

www.redhat.com

おわりに

久しぶりに Red Hat さん主催のオフラインイベントに参加できました。

はじめましての方や、お久しぶりの方含め、ごあいさつさせていただいた皆様、ありがとうございました!

オフラインイベントは会場の熱気や雰囲気が伝わってきてよいものですね。

データベーススペシャリスト試験を受験してきました(不合格確定)

はじめに

2024年秋期のデータベーススペシャリスト試験(DB)を受験してきました。

この記事は、ただの個人的なふりかえりです。確実に不合格(午後の回答で空欄が半分以上)なので、勉強方法の参考にはなりませんのでご注意ください。

経緯

情報処理技術者試験は、20代の頃はたまに受けていましたが、30代以降はほとんど受けて来ませんでした。2016年に始まった時に受けた「情報セキュリティマネジメント試験」が最後でした。

ところで今年の私のテーマは「迷ったら地味な方を選ぶ」です。世の中、技術的におもしろいサービスやツールがたくさんあります。それらを触ってみたい気持ちがあるのですが、最近は「使い方」以外ところを強化したいなという思いがありました。

そこで思い出したのが、情報処理技術者試験です。高度試験の午前1の範囲は、「それ」に該当、かつチャレンジしやすいのではないかと思い、受験することにしました。

合格は狙っていなくて、午前1、あわよくば午前2も頑張れればいいな程度です。なので、高度の試験のどれを受けるかは、こだわりはありませんでした。

秋期の高度試験は、プロジェクトマネージャ試験、データベーススペシャリスト試験、エンベデッドシステムスペシャリスト試験、システム監査技術者試験があります。論文がある試験は、以前ITサービスマネージャ試験で苦い思い出があったので避けたかったのと、他と比べるとまだ馴染みがある方という理由で、データベーススペシャリスト試験を受けることにしました。

準備

午前1の範囲と難易度は、応用情報の午前と同じです。なので応用情報の参考書を買いました。最初の頃は、よーし基礎から勉強するぞ、と思っていたのですが、わりとすぐ気持ちが持たなくなってしまいました。自覚はあったのですが、本当に勉強が苦手になってしまったなと思いました。また、途中で中学レベルの数学が危ういことが発覚しました。解説の計算が理解できないものがあったのです。

15年近く前に応用情報を受けたのですが、もうびっくりするくらい内容は覚えていませんでした。それでもスラスラ解ける分野もあることはあるので、忘れる分野と忘れない分野の違いってなんだろうって思いました。自転車の乗り方や泳ぎ方のように、普段やるわけじゃないけど一度覚えたら忘れないもの、というのもありますよね。

正直なところ、当日の2日前まで、当日行くかどうかも迷ってるほどの準備不足でした。「会場の写真くらい撮ってきますよw」と人に話したのがけじめになりました。

当日

会場

午前1は思ったよりは解けて、午前2は怪しい感じでした。午前2では、DBの試験なのにDBの範囲外の問題に出会うとホッとする有り様でした。

誤りポイントにバツをつけながら回答することが多いです(午前2問20)

午後は1も2もキツかったです。歯が立たなかったです。対策をしてこなかったので、出題形式かもよく分かっていませんでした。エンティティやリレーションなどの表記ルールが冒頭に書かれていますが、毎回同じなのでしょうか。ここくらいは予習しておけばよかったなと思いました。

冒頭に書いた通り、空欄が半分以上なので確実に不合格です。

データモデルの不足しているリレーションの線を追加したり、関係スキーマの空欄に属性(1つまたは複数)を入れたりする問題がありましたが、この手の問題は、理解に加えて「慣れ」も必要そうだなと思いました。

今回の問題冊子は以下のページから見れます。

www.ipa.go.jp

試験の内容以外のところでいいますと、私が入った部屋では、午前の出席率は7割ほどで、午後2の頃には半分以下になっていました。あと、受験票に上履き持参と書いてあったら忘れちゃいけないなと思いました。本記事で唯一アドバイスできる事があるとすれば、受験票に記載の持ち物は必ず確認しましょう、です。

おわりに

午後2は、退出可能時間になってから、その部屋の中で一番最初に退出してしまいました。諦めて。あのときのバツの悪さは覚えておくべきと思いました。

うっかり午前1免除が得られたら、来年もなにか高度試験を受けてみようかなと思います。もはや合格が目的というよりは、普段やらない勉強をして、脳の退化に抗うみたいなノリです。

[Ansible/AAP] AAP 2.5 のインストールでエラー "c{'gateway_proxy_url': 'https://hoge:443 is not a valid URL'}" が発生する原因と対処

はじめに

AAP 2.5 のインストール Playbook を実行した時、以下のようなエラーの遭遇したことがありました。

"c{'gateway_proxy_url': 'https://aap25c:443 is not a valid URL'}"}

インストールドキュメント通り、指定したインベントリホスト名は名前解決できる状態にしてあるのに、なんでだろう、他に要件あるのかな?と結構悩みました。

調べて分かった原因と対処についてまとめます。

はじめに簡単にまとめておきますと、ホスト名を指定する場合、aap25c のような単一ラベルではなく aap25c.sakana.testのようにドメインを含む形のインベントリホスト名を指定する必要がありました。

前提環境

  • インストーラー: Ansible Automation Platform 2.5 Containerized Setup Bundle
    • ansible-automation-platform-containerized-setup-bundle-2.5-2-x86_64.tar.gz 最終更新日 2024-10-08

現象

インストール時には以下のようなインベントリファイルを利用しました。

[automationgateway]
aap25c ansible_connection=local

# 略

発生したエラーは以下の通りです。

TASK [ansible.gateway_configuration.settings : Update automation platform gateway Settings] **************************************************************
fatal: [aap25c]: FAILED! => {"changed": false, "msg": "c{'gateway_proxy_url': 'https://aap25c:443 is not a valid URL'}"}

このタスクは、インストーラーに同梱されている ansible.gateway_configuration.settings ロール内の、ansible.gateway_configuration.settings モジュールを利用したタスクです。

---
# tasks file for gateway_settings
- name: Update automation platform gateway Settings
  ansible.gateway_configuration.settings:
    settings:                 "{{ gateway_settings | default(omit, true) }}"
# 略

これは、Platform Gateway への各種設定をタスクで、設定内容(settings オプション)として、gateway_settings が渡されます。この gateway_settings は以下のような形式になります。

gateway_settings:
  gateway_proxy_url: aap25c

上記の内容が Platform Gateway の設定変更 API リクエストの body に添えられます。レスポンスとしてエラー {'gateway_proxy_url': 'https://aap25c:443 is not a valid URL'} が返ってきます。

インストーラー自身がエラーを返しているというよりは、API からのエラーが Playbook 実行結果のエラーとして表示されている形です。

なお、この現象は、Platform GatewayGUI の [設定] > [Platform gateway] 画面 の Gateway proxy url 欄への記入でも再現できます。

Gateway proxy url の指定エラー

原因

Platform Gateway 側の処理を追っていったところ、gateway_proxy_url に対して、バリデーションしてる箇所があってここでエラーが発生したようです。

机上で追っただけですが、バリデーションを定義している箇所は、コンテナ automation-gateway/usr/lib/python3.11/site-packages/aap_gateway_api/preferences/types.pyvalidate メソッドのようでした。

バリデーションは Djangodjango.core.validatorsURLValidator クラスによるものでした。コードはこちら

(バージョンは rpm -qa | grep django の結果の python3.11-django-4.2.16-1.el8ap.noarch で判断しました)

色々と正規表現が定義されていますが、今回の一番のポイントは以下の箇所かなと思います。

    # Host patterns
    hostname_re = (
        r"[a-z" + ul + r"0-9](?:[a-z" + ul + r"0-9-]{0,61}[a-z" + ul + r"0-9])?"
    )
    # Max length for domain name labels is 63 characters per RFC 1034 sec. 3.1
    domain_re = r"(?:\.(?!-)[a-z" + ul + r"0-9-]{1,63}(?<!-))*"
    tld_re = (
        r"\."  # dot
        r"(?!-)"  # can't start with a dash
        r"(?:[a-z" + ul + "-]{2,63}"  # domain label
        r"|xn--[a-z0-9]{1,59})"  # or punycode label
        r"(?<!-)"  # can't end with a dash
        r"\.?"  # may have a trailing dot
    )
    host_re = "(" + hostname_re + domain_re + tld_re + "|localhost)"```

ホスト名のパターンとしては、上記規則に基づいたドメイン名を含むか、localhost が OK とされています。これに対して、今回指定したのは aap25c という単一ラベルのホスト名だったのでエラーとなった、という話です。

このバリデーションでの、ホスト名のパターンの OK と NG パターンの例を以下にまとめます。

なお、URLValidator クラスには、他にも IPv4、IPv6 アドレスも OK とする正規表現も指定されていました。他、別途 http://https:// 等のスキームや :443 等のポート番号などのパターンもありました。

対処

インベントリファイルで指定するインベントリホスト名を、バリデーションがOKとなる形式に修正して再度インストールします。

例:

[automationgateway]
aap25c.sakana.test ansible_connection=local

# 略

もし今回のエラーが解消して、別の解せないエラーが発生した場合は、一度アンインストールしてから再度インストールするとうまくいくことがあります。

おわりに

何をもとにして valid か not valid か判定しているのかわかってスッキリしました。

最初はエラーメッセージをインストーラーの処理の中から探していましたが、見つからずに悩んでました。

[Ansible/AAP] AAP 2.5 で導入された統合UI「Platform Gateway」の概要と Automation Controller との関係

はじめに

2024/09/30 に、AAP (Ansible Automation Platform) 2.5 がリリースされました。

www.youtube.com

今回は個人的に注目している変更点は以下の2つです。

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

本記事では 1 に関連して、Platform Gateway がどういうものか、Automation Controller とはどういう関係かなど、調べてみたことをまとめます。

はじめに自分なりの言葉でまとめておきます。

  • Platform Gateway は、Automation Controller や Automation Hub を束ねる UI を備えるプロダクト
  • GUIAPI のアクセス先も Platform Gateway 経由が基本になる

(なお、2 のコンテナ版については AAP 2.4 時点で Technical Preview でした。詳細はこちらの記事をご参照下さい)

前提環境

  • インストーラー: Ansible Automation Platform 2.5 Containerized Setup Bundle
    • ansible-automation-platform-containerized-setup-bundle-2.5-2-x86_64.tar.gz 最終更新日 2024-10-08
  • デプロイ方式: コンテナ(RPM では本記事の内容と異なる点もあります)
  • Red Hat Enterprise Linux 9.4、ホスト名設定済み、サブスクリプション登録済み

用語整理: Unified UI = Platform Gateway

公式ブログでは、Platform Gateway という言葉は登場せず Unified UI と表現されていますが、リリースノートを見る限り、Unified UI = Platform Gateway とみなして問題なさそうです。

What is included in the Ansible Automation Platform」という表にも「Platform Gateway(Unified UI)」とあります。

また、 コンテナ名や、インストーラーが利用するインベントリファイルのグループ名としては、Platform Gateway ではなく、automation-gatewayautomationgateway のような言葉で表現されます。

Platform Gateway の概要

日本語版のリリースノートを引用します。

Ansible Automation Platform 2.5 では、Ansible Automation Platform の認証と認可を処理するサービスとしてプラットフォームゲートウェイが提供されます。プラットフォームゲートウェイを使用すると、Ansible Automation Platform を設定するすべてのサービスが 1 つの統合 UI に統合されます。統合された UI は、Ansible Automation Platform への単一のエントリーを提供し、単一の場所からすべての Ansible Automation Platform サービスに認証およびアクセスするためのプラットフォームユーザーインターフェイスとして機能します。

「AAP = Automation Controller (旧 Ansible Tower)」のイメージが強いかもしれませんが、実際は、複数のプロダクトやサービス群を指す総称です。実際は、Automation Controller 以外にも、自前でデプロイするプロダクトだけでも Private Automation Hub、EDA Controller があります。

これまで、それぞれ別々の管理画面でしたが、これらが Platform Gateway の画面経由で操作できるようになります。それぞれの画面をあちこちブラウザのタブを回っていた方には便利に感じるのではないでしょうか。

Platform Gateway のメニュー
 

メニュー構成

左のメニューと機能の大まかな対応は以下の通りです。リリースノートの「Terminology changes」にもまとめがあります。

メニュー名称 対応プロダクト 役割
Automation execution Automation Controller Playbook を動かす
Automation decision Event-Driven Ansible controller イベント駆動の Ansible
Automation content (Private) Automation Hub コレクションやEEを管理

インストールしなかったプロダクトに対応するメニューは非表示になります。たとえば、Event-Driven Ansible controller をインストールしなければ左のメニューに「Automation decision」は表示されません。

Platform Gateway から見ると各プロダクトを「機能」として扱うようなイメージでしょうか。

Platform Gateway の画面で操作する

バックエンド

この記事では、Platform Gateway 裏で動くプロダクトのことをバックエンドと呼ぶことにします(それらしい設定画面に backend という文言があったので)。

詳細を追い切れていませんが、Platform Gateway の service や route と呼ばれる設定によってバックエンドへの中継処理を実現している雰囲気でした。ただ、インストーラーの処理を追ったり、Platform GatewayAPI を少し触った上での勘でしかありません。Platform Gateway 自身のドキュメントがあれば確認したいです。

https://ゲートウェイ/api/gateway/v1/status/ をGETすると、以下のようなレスポンスが返ってきます。Platform Gateway が束ねている雰囲気が感じ取れます。

{
    "time": "2024-10-16T01:43:14.370615",
    "status": "good",
    "services": {
        "gateway": {
            "status": "good",
            "nodes": {
                "aap25c.sakana.local:8446": {
                    "url": "https://aap25c.sakana.local:8446/api/gateway/v1/ping/",
                    "status": "good",
                    "response": {
                        "version": "2.5",
                        "pong": "2024-10-16 01:43:14.438878",
                        "status": "good",
                        "db_connected": true,
                        "proxy_connected": true
                    }
                }
            }
        },
        "controller": {
            "status": "good",
            "nodes": {
                "aap25c.sakana.local:8443": {
                    "url": "https://aap25c.sakana.local:8443/api/v2/ping/",
                    "status": "good",
                    "response": {
                        "ha": false,
                        "version": "4.6.1",
                        "active_node": "aap25c.sakana.local",
                        "install_uuid": "8a8b171f-cdba-403c-b203-4365e07896b1",
                        "instances": [
                            {
                                "node": "aap25c.sakana.local",
                                "node_type": "hybrid",
                                "uuid": "65884d56-0636-8b8d-4343-eb43413873ac",
                                "heartbeat": "2024-10-16T01:43:11.436555Z",
                                "capacity": 136,
                                "version": "4.6.1"
                            }
                        ],
                        "instance_groups": [
                            {
                                "name": "controlplane",
                                "capacity": 136,
                                "instances": [
                                    "aap25c.sakana.local"
                                ]
                            },
                            {
                                "name": "default",
                                "capacity": 136,
                                "instances": [
                                    "aap25c.sakana.local"
                                ]
                            }
                        ]
                    }
                }
            }
        },
        //略

画面の操作例

以下、イメージをつかむために Platform Gateway のいくつかの操作例をまとめます。

操作例1: ジョブテンプレートの実行

Platform Gateway 経由で、Automation Controller の機能であるジョブテンプレートを実行する場合は以下のような操作です。

ジョブテンプレートの起動

ジョブテンプレートの実行結果

「Automation Execution」からたどれば良い点だけおさえておけば、特に迷う点はないかなと思います。

全面的に UI が刷新されていますね。Automation Controller 4.5 では Technical Preview 扱いで新しい UI がありましたが、あれの流れでしょうか。

操作例2: ユーザー管理

ユーザーやチームも Platform Gateway 側で管理します。

各機能(プロダクト)のメニュー配下ではなく「Access Management」から操作します。メニューの構成からも共通各機能共通であることが感じ取れます。

ユーザー作成

ユーザー作成画面

LDAP のような外部認証ではなく、ローカル認証を利用していた場合でも認証情報を一括管理できるのはよさそうです。

操作例3: Host Metrics の確認

これまで Automation Controller の左メニューの上の方にあった「ホストメトリックス」は「Automation Analytics」配下になりました。

自動化されたホストの数を把握することは、適切なライセンス運用をする上で重要なので、引き続きこの画面は見る機会があると思います。

Host Metrics

操作例4: バージョン確認

右上の「?」をクリックして「情報」をクリックすると、インストールしたプロダクトのバージョンが表示されます。

バージョン表示

ただ、Platform Gateway 自身のバージョンが表示されませんね。

今回の環境では、https://ゲートウェイ/api/gateway/v1/ping/ を GET すると、レスポンスヘッダに X-API-Product-Version: 2.5.0.dev1 とあったり、以下のボディがあったりしました。なので、2.5 ということなのかなと思います。AAP としてのバージョンのことなのか、Platform Gateway としてのバージョンなのか、両者を合わせているから同じに見えるのか、厳密には不明です。

{
    "version": "2.5",
    "pong": "2024-10-16 01:47:01.718247",
    "status": "good",
    "db_connected": true,
    "proxy_connected": true
}

各種インターフェースの変化

Platform Gateway が導入されることによって起こる GUIAPI の仕様の変化についてです。

GUI は Platform Gateway 側に統合

GUI は前述の通り、Platform Gateway 側に統合されます。

そのため、ユーザーは https://コントローラー:8443/ ではなく https://ゲートウェイ/ にアクセスして操作することになります。

いままで(AAP 2.4 / Automation Controller 4.5まで)通り、Automation Controller の画面を直接開いても、真っ白になりました。試す限り、どこにもリダイレクトされず Content-Length: 0 のレベルでした。以前の Automation Controller の画面を表示させる方法があるのかもしれませんが、ないものだと思ってよさそうです。

[2024/10/30 追記] 2024/10/28 のリリースでは Platform Gateway へのリダイレクトされるようになったようです(リリースノート)。

The automation controller, Event-Driven Ansible, and automation hub legacy UIs now display a redirect page to the Platform UI rather than a blank page.

API も基本的に Platform Gateway 側に統合

API も同様に、Platform Gateway 側に統合されます。

これまで、Automation Controller への API エンドポイントのベースは https://コントローラー/api/v2/ でした。

これが 、Platform Gateway 経由でのアクセスになることによって、https://ゲートウェイ/api/controller/v2/ になります。Automation Controller への操作であれば、パスに controller が含まれる点が特徴です。

Automation Controller への直接の API リクエストもまだ使えることは使えるようです。この点は GUI の事情と異なります。たとえば、https://コントローラー:8443/api/controller/v2/https://コントローラー:8443/api/v2/ (パスが今まで通り)です。

まとめると、Automation Controller への API アクセスは以下の 3通りが考えられます。

  1. https://ゲートウェイ/api/controller/v2/
  2. https://コントローラー:8443/api/v2/
  3. https://コントローラー:8443/api/controller/v2/

うまく表現できている自信がありませんが、以下の図のような関係です。

API リクエスト先

(図には含めていませんが Platform Gateway 自身を操作する API エンドポイントのベースは https://ゲートウェイ/api/gateway/v1/) です)

Automation Controller 側の /api/v2/users/ 等のユーザー管理エンドポイントは Platform Gateway 側へ移行)したとあります。ユーザー管理は、Platform Gateway 側で行うものであり、各 API へのアクセスも Platform Gateway を経由(https://ゲートウェイ/api/controller/v2/)するのが一番 AAP 2.5 らしいお作法なのでしょう。

なお、Automation Controller 側の API パスが controller ありでもなしでもアクセスできるようになっているのは、コンテナ automation-controller-web/etc/tower/settings.py の設定 OPTIONAL_API_URLPATTERN_PREFIX によるもののようでした。コメントには Platform Gateway 向けの設定であることが記載されています。

# Update URL prefix when gateway deployed so internal links work correctly
OPTIONAL_API_URLPATTERN_PREFIX = "controller"

Automation Controller への操作を Ansible で自動化する ansible.controller コレクション 4.6.0 では、 Automation Controller へのアクセスは /api/controller/v2/ に変更されているようです。

なお、公式ブログの記事では、

Services API will still be available but will eventually be deprecated later in 2.5.

とあります。「Services API 」が何を指すのかわからないのですが、もしかしたら Automation Controller でいうと /api/v2/ のことなのかもしれません。

インストール

インストール手順のドキュメントをベースにしてインストールします。

ここから先は、バックエンドは Automation Controller に絞ったパターンを前程にします。

準備

ホスト名、サブスクリプション登録をすませ、インストール(やトラブルシューティング)に必要なパッケージをインストールします。

$ sudo dnf install -y wget git-core rsync vim

インストーラーの配置

予めダウンロードしておいたインストーラーの tar.gz を作業マシン(今回はインストール先も兼ねる)にコピーします。

回答後、ディレクトリを移動します。

$ tar xzf ansible-automation-platform-containerized-setup-bundle-2.5-2-x86_64.tar.gz 
$ cd ansible-automation-platform-containerized-setup-bundle-2.5-2-x86_64

インベントリファイルの準備

AAP のインストールの詳細の指定には、従来通りインベントリファイルを使用します。

本記事では(RPM版ではなく)コンテナ版を扱います。1つのホストに対してすべてのコンテナをデプロイする、シンプルなインベントリファイルは以下の通りです。ファイル名は inventory とします。

[automationgateway]
aap25c.sakana.local ansible_connection=local

[automationcontroller]
aap25c.sakana.local

[database]
aap25c.sakana.local

[all:vars]
postgresql_admin_username=postgres
postgresql_admin_password=<DB の admin パスワード>

bundle_install=true
bundle_dir=<バンドル版に含まれるコンテナイメージのimagesディレクトリがあるディレクトリ>

controller_license_file=<マニフェストファイルのパス>

redis_mode=standalone

gateway_admin_password=<Platform Gateway の admin パスワード>
gateway_pg_host=aap25c.sakana.local
gateway_pg_password=<Platform Gateway の DB パスワード>

controller_admin_password=<Automation Controller の admin パスワード>
controller_pg_host=aap25c.sakana.local
controller_pg_password=<Automation Controller の DB パスワード>

aap25c.sakana.local は、作業マシン兼インストール先で、名前解決できるようにしています。aap25c のような単一ラベルのホスト名ではエラーになってしまいます(詳細は別の記事)。また、controller_license_file の指定は任意ですが、マニフェストファイルを指定しておくと、インストール処理の中でライセンスまで適用されます。

あとは、インストールの Playbook を実行するだけです。これにより、podman のインストールや、各コンテナのデプロイなどのインストール処理が行われます。

$ ansible-playbook -i inventory ansible.containerized_installer.install

なお、インストールの処理上 Platform Gateway の構築は必須です。試しに automationgateway グループ に所属するホストを空にしたら、You must have a host set in the [automationgateway] section というエラーが発生しました。

補足: 再インストール時は一度アンインストールする方が吉

インベントリファイルの、インベントリホスト名やポート番号を変更して、再度インストールのPlaybookを実行すると、解せないエラーが発生してしまうことがありました。

そのため、このようなインパクトの大きめな変更をする場合は、一度アンインストールの Plyaobook を実行してから、再度インストールの Playbook を実行するようが良いと思いました。

Platform Gateway を構成するコンテナと待ち受けポート

「Platform Gateway」と一言で言っても、2 つのコンテナで構成されます。

コンテナ名 役割
automation-gateway-proxy ブラウザのトラフィックの受け口。Envoy が動作していて、本体に流す
automation-gateway Platform Gateway 本体

バックエンドの Automation Controller を合わせると以下のような図になります。ポート番号はデフォルトの場合です。

コンテナ構成

コンテナ間のアクセスを示す線は少し自信がないのですが、少なくとも Platform Gateway でジョブテンプレートを実行する操作は ブラウザから Automation Controller へのアクセスはありませんでした。

待ち受けポートは、インストールに利用するインベントリファイル等の変数の指定で変更できます。

変数名 役割 デフォルト 補足
envoy_https_port Envoy (Platform Gateway の入り口) の HTTPS 待ち受けポート 443 注)ansible.containerized_installer.automationgateway ロール内の defaults/main にデフォルトの定義があります。ドキュメントの変数一覧には掲載はなく、試したら変更できたという程度で原理を追いきれていません。あまり変更されることを想定していないのかもしれません。[2024/10/18追記] 一部のドキュメントにはこの変数の利用に修正されました
gateway_nginx_https_port Platform Gateway 本体の HTTPS 待ち受けポート 8446 ドキュメントの変数一覧には掲載がないですが、インストーラーtar.gz解凍ディレクトリ/collections/ansible_collections/ansible/containerized_installer/README.md に記載があります
controller_nginx_https_port Automation Controller の HTTPS 待ち受けポート 8443

なお、「はじめに」に書いた通り本記事はコンテナ版でのインストールを前提にしています。PRM 版でのインストールの場合、デフォルトの待ち受けポートなのでご注意ください。

Envoy の挙動

※ 正直、Envoy はこれまで名前を聞いたことがある程度でした。なので Envoy の話はあいまいな理解が含まれます。なにか誤りなどあればお手数ですが @akira6592 までお知らせいただけると幸いです。

コンテナ automation-gateway-proxy 内の Envoy は以下のコンフィグで動きます。( /etc/envoy/envoy.yaml にコメントを追記)

node:
  id: aap25c.sakana.local
  cluster: envoy

dynamic_resources:
  cds_config:
    resource_api_version: V3
    api_config_source:
      api_type: REST
      transport_api_version: V3
      cluster_names:
        - gateway-control-plane-rest
      refresh_delay:
        seconds: 5

  lds_config:
    resource_api_version: V3
    api_config_source:
      api_type: REST
      transport_api_version: V3
      cluster_names:
        - gateway-control-plane-rest
      refresh_delay:
        seconds: 5

static_resources:
  clusters:
  - type: STRICT_DNS
    typed_extension_protocol_options:
      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
        "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
        explicit_http_config:
          http_protocol_options: {}
    name: gateway-control-plane-rest
    load_assignment:
      cluster_name: gateway-control-plane-rest
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: aap25c.sakana.local    # Platform Gateway 本体のアドレス(デフォルトではインベントリホスト名)
                port_value: 8446                # Platform Gateway 本体のポート(デフォルト 8446)
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext

  - type: STRICT_DNS
    typed_extension_protocol_options:
      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
        "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
        explicit_http_config:
          http2_protocol_options: {}
    name: gateway_control_plane
    load_assignment:
      cluster_name: gateway_control_plane
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 50051

Envoy から Platform Gateway に対して POST でリクエストが出されていました。

https://ゲートウェイ:8446/v3/discovery:listeners

Platform Gateway からは以下のようなレスポンスを返します。レスポンスにポート番号 443 が含まれます。

{
    "resources": [
        {
            "@type": "type.googleapis.com/envoy.config.listener.v3.Listener",
            "name": "port-443",
            "address": {
                "socketAddress": {
                    "address": "0.0.0.0",
                    "portValue": 443
                }
            },
          // 略

この結果、Platform Gateway 本体の代わりに Envoy が 443 で待ち受けるようです。

ちょっと自信がないので、別途 Envoy については調べようと思います。

まとめ

まとめ(再掲含む)

  • Platform Gateway は、Automation Controller や Auhtomation Hub を束ねる UI を備えるプロダクト
  • ユーザーや、システム連携 API のアクセス先も Platform Gateway 経由が基本になる
  • Platform Gatewayautomation-gateway-proxyautomation-gateway という 2つのコンテナで構成される
  • automation-gateway-proxy で Envoy が動作し、ユーザーのトラフィックをデフォルト 443/TCP で待ち受ける

AAP 内の複数のプロダクトを利用した場合は、統合 UI が提供されるのは便利になると思います。

一方で、もともと Automation Controller しか使っていなかった場合から比較すると、少々ファットになった印象です。逆に、これを機会に他のプロダクトも活用する後押しにはなりそうです。

参考

AAP 2.5 ドキュメント一式

Red Hat Ansible Automation Platform | Red Hat Product Documentation

[Ansible/AAP] コンテナでデプロイする AAP「Containerized AAP」を試して仕組みを少し調べた(AAP 2.4 時点の Technical Preview)

はじめに

Automation Automates 2023 Japan での AAP のロードマップの話の中で、「Containerized AAP」という言葉がありました。その後、AAP 2.4 内で「Technical Preview」という扱いで提供が始まりました。

どんな感じか気になりつつ、試せていなかったので試してみました。

デプロイそのもののほか、postinstall 処理(ライセンス自動適用、プロジェクトの設定投入)も試ました。インストール処理の中身や、自動起動、ポート開放などの仕組みにいて気になったこともあったため、ついでに調査しました。

手順については、公式ドキュメントや、先人のブログを参考にさせていただきました。ありがとうございます!

なお、将来的に Containerized AAP が GA になった場合、現在から大小さまざまな変更が入ると思います。本記事はあくまでも AAP 2.4 時点で Technical Preview のものを Technical Preview として扱い、一時的な環境で試してみるだけです。なので、GA になったらあまり意味がない内容になります。

まとめ

長いので先にポイントをまとておきます。

  • podman でデプロイする方式、ルートレス
  • デプロイ後にライセンスの適用や設定投入もできる
  • 各コンテナはユーザーレベルの systemd 経由で起動

■ 環境・要件

今回は以下の環境、要件です。

  • 環境
    • RHEL 9.4 (minimal)
    • サブスクリプション適用済み
    • ホスト名設定済み
    • パスワード入力で sudo できる非 root ユーザーを利用(今回は admin
    • podman 4.9.4-rhel (インストール Playbook 実行中にインストールされる)
    • オンライン版インストーラー(バンドル版ではないほう)
      • ansible-automation-platform-containerized-setup-bundle-2.4-2-x86_64.tar.gz
      • 最終更新日は 2024-01-16
    • 主なコレクション(インストーラーに同梱)
      • ansible.containerized_installer 1.3.3
      • ansible.controller 4.5.0
      • infra.controller_configuration 2.6.0
  • 要件
    • Autmation Controller のみデプロイ(実際は Automation Hub や EDA Controller もデプロイ可能)
      • 作業マシン自身にデプロイ
    • ライセンス適用も自動化
    • Automation Controller の事後設定も自動化(postinstall)

■ インストール手順

私の環境、要件でインストールした手順です。

準備

パッケージを一通りアップデートします。

$ sudo dnf update '*' -y
...(略)...
$ cat /etc/redhat-release 
Red Hat Enterprise Linux release 9.4 (Plow)

リポジトリのリストを表示し、ドキュメントに記載の appstreambaseos があることを確認します。

$ dnf repolist
Not root, Subscription Management repositories not updated
repo id                                                     repo name
rhel-9-for-x86_64-appstream-rpms                            Red Hat Enterprise Linux 9 for x86_64 - AppStream (RPMs)
rhel-9-for-x86_64-baseos-rpms                               Red Hat Enterprise Linux 9 for x86_64 - BaseOS (RPMs)

デプロイ対象マシンのホスト名を名前解決可能な状態にしておきます。

今回は今作業している(インストーラーを実行する)マシン自身をデプロイ対象としますので、作業マシンのホスト名 rhel9-aap24c192.168.1.139 で名前解決できるようにしました。

何が起こるか見たかったこともあり、ドキュメントとは異なり /etc/hosts で設定しました。あくまで検証目的であり、公式ドキュメントに載っている方法ではありません。

ansible-core のインストール

イントールに必要な ansible-core などをインストールします。

$ sudo dnf install -y ansible-core wget git rsync
...()...
Complete!

これまであった、VMRPM でインストールする方式では、インストールスクリプトinsstall.sh の処理の中で、(なければ)ansible がインストールされ、具体的な処理が書かれた Playbook を実行するという流れでした。

一方で、Containerized AAP の場合は、Playbook を直接実行するかたちなので予め ansible-core のインストールが必要です。

他に指定されている wgetgit などは、Playbook が依存しているからなのだと思います。git でいうと、postinstall のための定義ファイルを git clone する時に使うようです。

なお、ここまで作業しても podman はインストールされていません。

$ podman
bash: podman: command not found
$ rpm -qa | grep podman
$ 

インストーラーのダウンロード

ダウンロードページ(要ログイン)にブラウザでアクセスして、Tech Preview: Ansible Automation Platform 2.4 Containerized Setup をダウンロードします。

今回はバンドル版を利用しないので、末尾に Bundle が付かないほうです。最終更新日は 2024-01-16 となっていました。

ダウンロードした ansible-automation-platform-containerized-setup-2.4-2.tar.gz を作業マシンにコピーしておきます。

作業マシンで解凍して、作成されたディレクトリに移動します。

$ tar xzf ansible-automation-platform-containerized-setup-2.4-2.tar.gz 
$ cd ansible-automation-platform-containerized-setup-2.4-2

解凍した直下のファイル、ディレクトリは以下のとおりです。

ファイル・ディレクトリ名 説明
collections ディレクト インストーラーに同梱しているコレクションの親ディレクトリ。イントール用の Playbook がこの配下の ansible.containerized_installer コレクション内にある。後述の ansible.cfgcollections_path がこのディレクトリを指している。
ansible.cfg collections_path 等の設定
inventory インストール上のホスト、設定の定義
README.md インストール上の設定の変数の説明

inventory (インストール設定ファイル)の編集

これまでと同様、インストール上のさまざまな設定を inventory ファイルに指定します。普段と同じように、パスワード類は暗号化するなどしてセキュリティを高めることもできます。

rhel9-aap24c は作業マシン兼インストール先マシンです。

[automationcontroller]
# Aumation Controller のデプロイ先を指定
# 実際は作業マシン自身
# https の待ち受けポートを 443 に指定(デフォルト8443)
rhel9-aap24c ansible_connection=local nginx_https_port=443

[database]
# DB も同じホストのコンテナとしてデプロイする
rhel9-aap24c ansible_connection=local

[all:vars]
# DB の認証情報
postgresql_admin_username=postgres
postgresql_admin_password=<DBパスワード>

# オンライン版インストーラーの場合 registry.redhat.io からイメージを pull するので必要な認証情報を指定
registry_username=<Red Hat アカウントのユーザー名>
registry_password=<Red Hat アカウントのパスワード>

# Automation Controller の Web UI admin パスワード
controller_admin_password=<Automation Controller adminパスワード>

# Automation Controller から DB への接続情報
controller_pg_host=rhel9-aap24c
controller_pg_password=<DBパスワード>

# デプロイ後に設定流し込み処理(postinstall)をする
# postinstall の有効化(デフォルトは無効)
controller_postinstall=true
# マニフェストファイルのパス
controller_license_file=/home/admin/cac/manifest_sakana-trial-5nodes_20240913T050813Z.zip
# 設定流し込みに利用する定義ファイルを格納したディレクトリ
controller_postinstall_dir=/home/admin/cac

# 状況確認感覚のチューニング(トラブルシューティングで後述)
controller_postinstall_async_delay=2

automationedaautomationhub グループはグループ定義自体をしない形にしてみました。この影響で、後述の Playbook 実行時に警告が表示されます。気になる場合は、グループに定義は残しつつ所属ホストなしにするとよいと思います。

README.md にさまざまな変数の説明があります。上記の inventory で利用している変数のうち、いくつか以下で説明します。

デプロイ処理関連

Automation Controller の https の待ち受けポートとして nginx_https_port 変数で 443 を指定しています。これは、妥当性はさておき、一般ユーザーでデプロイしたらどうなるんだろうという好奇心で試したものです。実際はこれでいけました。インストール処理の中でカーネルパラメーター net.ipv4.ip_unprivileged_port_start が調整されるためです。

postintall 関連の設定

controller_postinstalltrue に指定して、postinstall(デプロイ後の設定流し込み)機能を有効化していました。

controller_license_file は適用したいマニフェストファイルのパスです。今回はトライアルライセンスから作成しました。試した限りマニフェストファイルの適用だけであれば controller_postinstall はデフォルトの false のままでも大丈夫でした。一方、controller_postinstalltrue とした場合は、controller_license_file の指定がセットで必要になります。

設定に利用する変数ファイル群が git 上にある場合は、hub_postinstall_repo_url で指定します。

今回は、変数ファイルを作業マシンに直接配置したので、controller_postinstall_dir のみの指定です。ここで指定したディレクトリ配下にある *.yml*.yaml ファイルを一式読み込みます。拡張子以外のファイル名は何でもよいです。今回は、controller.yml というファイル名で以下の内容のモノを作成して、controller_postinstall_dir で指定したディレクトリ配下に置きました。

---
controller_projects:
 - name: My Project
   organization: Default
   scm_type: git
   scm_url: https://github.com/akira6592/tower-sample-nw
   scm_branch: main
   scm_delete_on_update: false
   scm_update_on_launch: true
   scm_clean: true

今回はとにかく動くことを確認したかったので、プロジェクトを1つ作成するのみとしました。postinstall の機能自体は非常に興味深いので別途深掘りしたいと思います。

なお、この設定流し込みには infra.controller_configuration.dipatch ロールが利用されます。変数ファイルの書きっぷりは以下のページが参考になります。

インストール Playbook の実行

$ ansible-playbook -i inventory ansible.containerized_installer.install -K
BECOME password: (作業ユーザーのパスワードを入力)

(オプション -K でbecomeパスワードを対話的に入力するの手間な時は ansible_become_password を指定するなど)

8分位で終わりました。aap_install.log にログが記録さます。

なお、Playbook の指定はカレントディレクトリから見たファイル名ではなく、ansible.containerized_installer コレクション内の Playbook install を指しています。ansible.containerized_installer コレクションはインストーラーに同梱されていいて、Playbook の実体は <解凍ディレクトリ>/collections/ansible_collections/ansible/containerized_installer/playbooks/install.yml です。

ansible.cfg で以下のように collections_path が指定されているため、 ansible.containerized_installer コレクションを認識できるようになっています。

[defaults]
collections_path = ./collections
inventory = ./inventory
log_path = ./aap_install.log

Playbook のファイル名の補完ができなくて少し不便ですが、ansible-core 2.11 からこのようにコレクション内の Playbook を呼べるようになっています。

なお、2023年月時点の公式ブログでは、export ANSIBLE_COLLECTIONS_PATH=/full-path-to-installer/collections でコレクションがあるパスを指定していますが、上記の ansible.cfgansible-playbook コマンドを実行する分には export 不要です。

動作確認

無事にジョブテンプレートが実行できました。

ジョブの実行

Automation Controller のバージョンは、4.5.11 でした。ここは変動するかもしれません。

Automation Controller 4.5.11

postinstall の処理で指定したプロジェクト「My Project」も追加されて、同期も成功していました。

プロジェクトが追加された

■ インストール時のトラブルシューティング

本記事の手順はあたかも最初からうまくいったように書きましたが、実際は試行錯誤がありました。その中で出会った事象や対処などをまとめます。

あくまで今回利用したバージョンですので、今後のバージョンでは再現性がないかもしれません。

トラシュー1: ジョブテンプレートを実行しても「保留中」のままになる

インストールの Playbook が正常に終了した後、試しに Dome Job Template を実行すると「保留中」のまま先に進まないことがありました。

他にも、インストール Playbook を実行中、postinstall の処理にジョブが起動する処理(プロジェクトの設定など)があると、そのジョブが保留中のままタイムアウトとなり、タスク infra.controller_configuration.projects : Managing Projects | Wait for finish the projects management でエラーになることがありました。

原因: インベントリで localhost を指定していたため

複数のケースが考えられますが、今回の場合は、EE を実行するための receptor コンテナが起動していなかったためでした。

インストール Playbook 実行後の podman ps の結果は以下のとおり receptorautomation-controller-task がありませんでした。

$ podman ps
CONTAINER ID  IMAGE                                                                      COMMAND               CREATED        STATUS             PORTS       NAMES
f728f9c17261  registry.redhat.io/rhel8/postgresql-13:latest                              run-postgresql        6 minutes ago  Up 5 minutes                   postgresql
54a15d3dfdd7  registry.redhat.io/rhel8/redis-6:latest                                    run-redis             5 minutes ago  Up 5 minutes                   redis
f7e9f4709730  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest  /usr/bin/launch_a...  4 minutes ago  Up About a minute              automation-controller-rsyslog
f0b5d5f93ae5  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest  /usr/bin/launch_a...  4 minutes ago  Up About a minute              automation-controller-web

podman ps -a で調べてみると receptorautomation-controller-task はそれぞれ終了していました。

$ podman ps -a
CONTAINER ID  IMAGE                                                                        COMMAND               CREATED        STATUS                    PORTS       NAMES
f728f9c17261  registry.redhat.io/rhel8/postgresql-13:latest                                run-postgresql        8 minutes ago  Up 8 minutes                          postgresql
54a15d3dfdd7  registry.redhat.io/rhel8/redis-6:latest                                      run-redis             8 minutes ago  Up 8 minutes                          redis
12b94e181d9b  registry.redhat.io/ansible-automation-platform-24/ee-supported-rhel8:latest  /usr/bin/receptor...  7 minutes ago  Exited (1) 7 minutes ago              receptor
f7e9f4709730  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  7 minutes ago  Up 4 minutes                          automation-controller-rsyslog
12dbc9d8db3f  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  7 minutes ago  Exited (0) 3 minutes ago              automation-controller-task
f0b5d5f93ae5  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  7 minutes ago  Up 3 minutes                          automation-controller-web

で、まず receptor がなんで異常終了したんだろうと、podman logs receptor でログを確認したら Error: node ID "localhost" is reserved とありました。

$ podman logs receptor
Error: node ID "localhost" is reserved

どうやら、プログラムとしての receptor の処理として「localhost は予約されているため、node の id に指定できない」ということのようでした。

遡ってみると、試しに inventoryautomationcontroller グループのホストに localhost を指定したときがありました。この localhost という値が巡り巡って ansible.containerized_installer.receptor ロール内のテンプレート receptor.conf.j2 で、nodeid として利用され、先述のエラーとなっていたようです。

# roles/receptor/templates/receptor.conf.j2
---
- node:
    id: {{ _receptor_hostname }}
# ...(略)...

もう一つのコンテナ、podman logs automation-controller-task のほうは、詳細を追えませんでしたが、おそらく receptor のエラーとも関係があるのだと思います。

エラー抜粋

$ podman logs automation-controller-task
...(略)...
Traceback (most recent call last):
  File "/usr/bin/awx-manage", line 8, in <module>
    sys.exit(manage())
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/__init__.py", line 175, in manage
    execute_from_command_line(sys.argv)
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/main/management/commands/run_dispatcher.py", line 68, in handle
    consumer.run()
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/main/dispatch/worker/base.py", line 236, in run
    self.worker.on_start()
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/main/dispatch/worker/task.py", line 141, in on_start
    dispatch_startup()
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/main/tasks/system.py", line 120, in dispatch_startup
    cluster_node_heartbeat()
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/main/tasks/system.py", line 578, in cluster_node_heartbeat
    inspect_execution_and_hop_nodes(instance_list)
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/awx/main/tasks/system.py", line 517, in inspect_execution_and_hop_nodes
    mesh_status = ctl.simple_command('status')
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/receptorctl/socket_interface.py", line 81, in simple_command
    self.connect()
  File "/var/lib/awx/venv/awx/lib64/python3.9/site-packages/receptorctl/socket_interface.py", line 99, in connect
    raise ValueError(f"Socket path does not exist: {path}")
ValueError: Socket path does not exist: /run/receptor/receptor.sock
...(略)...

対処: localhost 以外を指定

もともとちょっと意地悪感覚で指定した inventoryautomationcontroller グループのホストに localhost を、実際のホスト名(名前解決可)に変更して再度インストール Playbook を実行しました。

・・一筋縄ではいかず以下のエラーになりました。変なタイミングでホスト名を変更したため、整合性が取れなくなったのだと思います。

TASK [ansible.containerized_installer.automationcontroller : Wait for the Controller API to te ready] ***
fatal: [rhel9-aap24c]: FAILED! => {"changed": false, "elapsed": 0, "msg": "Status code was -1 and not [200]: Request failed: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Hostname mismatch, certificate is not valid for 'rhel9-aap24c'. (_ssl.c:1129)>", "redirected": false, "status": -1, "url": "https://rhel9-aap24c:443/api/v2/ping/"}

詳細を調べる気力がなかったので、一度アンインストール Playbook を実行してから、インストール Playbook を実行しました。

完了の podman ps は以下のとおりです。

$ podman ps 
CONTAINER ID  IMAGE                                                                        COMMAND               CREATED        STATUS         PORTS       NAMES
1bdb7ba2d638  registry.redhat.io/rhel8/postgresql-13:latest                                run-postgresql        4 minutes ago  Up 4 minutes               postgresql
5db357812714  registry.redhat.io/rhel8/redis-6:latest                                      run-redis             4 minutes ago  Up 4 minutes               redis
2c9dfbbeb62b  registry.redhat.io/ansible-automation-platform-24/ee-supported-rhel8:latest  /usr/bin/receptor...  4 minutes ago  Up 4 minutes               receptor
3beee138c0e6  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  3 minutes ago  Up 34 seconds              automation-controller-rsyslog
fe2516aff573  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  3 minutes ago  Up 31 seconds              automation-controller-task
15133bf168e8  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  3 minutes ago  Up 20 seconds              automation-controller-web

receptorautomation-controller-task も起動しました。

これでジョブが正常に実行できるようになりました。postinstall でプロジェクトの設定をするようにしている場合も、無事に終了するようになりました。

トラシュー2: プロジェクトの設定がタイムアウトエラー

今回は postinstall の処理で、プロジェクト設定の流し込みを含めていますが、以下のエラーになることがありました。

TASK [infra.controller_configuration.projects : Managing Projects | Wait for finish the projects management] ************************************
FAILED - RETRYING: [rhel9-aap24c]: Managing Projects | Wait for finish the projects management (30 retries left).
FAILED - RETRYING: [rhel9-aap24c]: Managing Projects | Wait for finish the projects management (29 retries left).
FAILED - RETRYING: [rhel9-aap24c]: Managing Projects | Wait for finish the projects management (28 retries left).
...(略)...
FAILED - RETRYING: [rhel9-aap24c]: Managing Projects | Wait for finish the projects management (2 retries left).
FAILED - RETRYING: [rhel9-aap24c]: Managing Projects | Wait for finish the projects management (1 retries left).
failed: [rhel9-aap24c] (item=Create/Update Project My Project | Wait for finish the project creation) => {"__projects_job_async_results_item": {"__controller_project_item": {"name": "My Project", "organization": "Default", "scm_branch": "main", "scm_clean": true, "scm_delete_on_update": false, "scm_type": "git", "scm_update_on_launch": true, "scm_url": "https://github.com/akira6592/tower-sample-nw"}, "ansible_job_id": "j210680799387.309524", "ansible_loop_var": "__controller_project_item", "changed": false, "failed": 0, "finished": 0, "results_file": "/home/admin/.ansible_async/j210680799387.309524", "started": 1}, "ansible_job_id": "j210680799387.309524", "ansible_loop_var": "__projects_job_async_results_item", "attempts": 30, "changed": false, "finished": 0, "results_file": "/home/admin/.ansible_async/j210680799387.309524", "started": 1, "stderr": "", "stderr_lines": [], "stdout": "", "stdout_lines": []}

あれれと思って、Automation Controller の GUI にログインして確認すると、プロジェクトは正常に設定されていた、という状況でした。

原因: プロジェクト同期処理が間に合わなかった

設定の流し込みには、infra.controller_configuration.dipatch ロールが利用されます。この際、非同期で処理します。デフォルトでは 1秒間隔で状況確認して、30回リトライして処理が完了しなければエラーになります。

何度かインストールを試していると、デフォルトではうまくいったりいかなかったりしました。

プロジェクトについては、ただ設定するだけなく、設定直後に同期処理(git clone)が実行されるので、他の設定項目よりは時間がかかる傾向があるかもしれません。たまたまプロジェクトで試して出会えてよかったです。

なお、前述の「トラシュー1: ジョブテンプレートを実行しても「保留中」のままになる」の原因の一つである、コンテナ receptor がない場合もこの事象が発生します。この場合は、プロジェクト同期処理に必要なコンテナがないことになりますので、インストールを何回実行しても毎回タイムアウトになります。

対処: チューニング

コンテナ receptor があるのにタイムアウトになっている場合は、状況確認の間隔やリトライ回数を調整します。

inventory 内の以下の変数で調整できます。

変数名 デフォルト値 説明
controller_postinstall_async_delay 1 状態確認の間隔(秒)
controller_postinstall_async_retries 30 リトライ回数

公式ドキュメントにも本件についての記載があります。変数名が controller_configuration_async_* なので微妙に違いますが挙動としては同じようです。README.md に載ってる変数名だと controller_postinstall_async_* です。

今回は、controller_postinstall_async_delay2 に指定して、再度インストール Playbook を実行しました。

トラシュー3: 接続確認タスク Wait for the Web port to be reachable でエラーになる

一度インストールが完了した後、変数 nginx_https_port で nginx の listen ポートを変更し、再度 Playbook を実行すると、Automation Controller へのライセンス投入前の接続確認で、以下のエラーになってしまいました。

TASK [ansible.containerized_installer.automationcontroller : Wait for the Web port to be reachable] **************************
fatal: [rhel9-aap24c]: FAILED! => {"changed": false, "elapsed": 300, "msg": "Timeout when waiting for 127.0.0.1:443"}

処理の中身としては、ansible.containerized_installer.automationcontroller ロール内のタスクファイル license.yml にあるタスクで、ansible.builtin.wait モジュールが使用されています。

なお、このタスクは controller_license_file が定義されているときだけ実行されます。そのため、マニフェストファイルを指定していない場合はこのエラーは発生しません。

原因: listen ポートの変更が反映されないため

変数 nginx_https_port の値で nginx の設定ファイルを変更した後、コンテナ automation-controller-web を再起動していないためのようです。

以下詳細です。

ansible.containerized_installer.automationcontroller ロール内の containers.yml にあるタスク Create the automation controller web container で nginx の設定ファイルを生成します。そのタスクに notify: Restart controller web 指定されています。

ハンドラー Restart controller web では、ansible.builtin.systemd モジュールを利用して、サービス automation-controller-web.service を再起動します。結果的にコンテナ automation-controller-web が再起動されて、変更された nginx の設定ファイルも反映されます。

ここだけ見るとうまくいくように見えますが、再起動のハンドラーが起動する前に、接続確認のタスクがあるため、listen ポート変更すると正常に接続確認できなくなってしまいます。

一通りタスクが終わった後に、ハンドラーを起動する」という順番の仕様が考慮されていないように見えます。

対処: 一度アンインストール(暫定)

少々大げさですが、一度アンインストールしてから、再度インストールしました。

$ ansible-playbook -i inventory ansible.containerized_installer.uninstall -K
...(略)...
$ ansible-playbook -i inventory ansible.containerized_installer.install -K
...(略)...

他の方法として、接続確認のタスク Wait for the Web port to be reachable の実行中に、手動でサービス automation-controller-web.service を再起動する方法も考えらますが、タイミング勝負のため少々アクション要素があります。

なお、この事象はあくまで今回検証した ansible.containerized_installer コレクション 1.3.3 での事象のため、今後修正されるかもしれません。

その他: アンインストールしてもカーネルパラメーターの変更が残る

トラブルシューティングではないですが、気が付いたことが一点。

インストーラーが、カーネルパラメーター net.ipv4.ip_unprivileged_port_start を調整する際 /etc/sysctl.conf に、

net.ipv4.ip_unprivileged_port_start=443

のように記載されますが、アンインストールの Playbook を実行しても残ります。インストール前の値がどうだったか保存しておく術がないので、しょうがないのかなと思います。

もしかしたら他にもアンインストールで、設定が残るものもあるかもしれません。

■ 調べたこと

インストール処理の中身や、自動起動、ポート開放で気になったことをいくつか調べたので、まとめておきます。

全体

podman ps の結果は以下の通りです。概ねコンテナ名で役割がわかりそうです。

$ podman ps
CONTAINER ID  IMAGE                                                                        COMMAND               CREATED      STATUS      PORTS       NAMES
3910331f6865  registry.redhat.io/rhel8/postgresql-13:latest                                run-postgresql        4 hours ago  Up 4 hours              postgresql
86e602e1c6e4  registry.redhat.io/rhel8/redis-6:latest                                      run-redis             4 hours ago  Up 4 hours              redis
71b5bad7d7f1  registry.redhat.io/ansible-automation-platform-24/ee-supported-rhel8:latest  /usr/bin/receptor...  4 hours ago  Up 4 hours              receptor
84df241d5ae3  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  4 hours ago  Up 4 hours              automation-controller-rsyslog
7ffa833dd597  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  4 hours ago  Up 4 hours              automation-controller-task
344e8869af0c  registry.redhat.io/ansible-automation-platform-24/controller-rhel8:latest    /usr/bin/launch_a...  4 hours ago  Up 4 hours              automation-controller-web

後で再度触れますが PORTS 欄は空欄です。

podman info

インストールユーザー(非root)での podman info の結果は以下のとおりです。

▼クリックして展開(長いので)

$ podman info
host:
  arch: amd64
  buildahVersion: 1.33.8
  cgroupControllers:
  - memory
  - pids
  cgroupManager: systemd
  cgroupVersion: v2
  conmon:
    package: conmon-2.1.10-1.el9.x86_64
    path: /usr/bin/conmon
    version: 'conmon version 2.1.10, commit: fb8c4bf50dbc044a338137871b096eea8041a1fa'
  cpuUtilization:
    idlePercent: 99.19
    systemPercent: 0.23
    userPercent: 0.58
  cpus: 4
  databaseBackend: sqlite
  distribution:
    distribution: rhel
    version: "9.4"
  eventLogger: journald
  freeLocks: 2034
  hostname: rhel9-aap24c
  idMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  kernel: 5.14.0-427.35.1.el9_4.x86_64
  linkmode: dynamic
  logDriver: journald
  memFree: 144547840
  memTotal: 3836272640
  networkBackend: netavark
  networkBackendInfo:
    backend: netavark
    dns:
      package: aardvark-dns-1.10.0-3.el9_4.x86_64
      path: /usr/libexec/podman/aardvark-dns
      version: aardvark-dns 1.10.0
    package: netavark-1.10.3-1.el9.x86_64
    path: /usr/libexec/podman/netavark
    version: netavark 1.10.3
  ociRuntime:
    name: crun
    package: crun-1.14.3-1.el9.x86_64
    path: /usr/bin/crun
    version: |-
      crun version 1.14.3
      commit: 1961d211ba98f532ea52d2e80f4c20359f241a98
      rundir: /run/user/1000/crun
      spec: 1.0.0
      +SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +CRIU +YAJL
  os: linux
  pasta:
    executable: ""
    package: ""
    version: ""
  remoteSocket:
    exists: true
    path: /run/user/1000/podman/podman.sock
  security:
    apparmorEnabled: false
    capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
    rootless: true
    seccompEnabled: true
    seccompProfilePath: /usr/share/containers/seccomp.json
    selinuxEnabled: true
  serviceIsRemote: false
  slirp4netns:
    executable: /usr/bin/slirp4netns
    package: slirp4netns-1.2.3-1.el9.x86_64
    version: |-
      slirp4netns version 1.2.3
      commit: c22fde291bb35b354e6ca44d13be181c76a0a432
      libslirp: 4.4.0
      SLIRP_CONFIG_VERSION_MAX: 3
      libseccomp: 2.5.2
  swapFree: 4111724544
  swapTotal: 4227854336
  uptime: 16h 38m 46.00s (Approximately 0.67 days)
  variant: ""
plugins:
  authorization: null
  log:
  - k8s-file
  - none
  - passthrough
  - journald
  network:
  - bridge
  - macvlan
  - ipvlan
  volume:
  - local
registries:
  search:
  - registry.access.redhat.com
  - registry.redhat.io
  - docker.io
store:
  configFile: /home/admin/.config/containers/storage.conf
  containerStore:
    number: 6
    paused: 0
    running: 6
    stopped: 0
  graphDriverName: overlay
  graphOptions: {}
  graphRoot: /home/admin/.local/share/containers/storage
  graphRootAllocated: 26164068352
  graphRootUsed: 8558268416
  graphStatus:
    Backing Filesystem: xfs
    Native Overlay Diff: "true"
    Supports d_type: "true"
    Supports shifting: "false"
    Supports volatile: "true"
    Using metacopy: "false"
  imageCopyTmpDir: /var/tmp
  imageStore:
    number: 4
  runRoot: /run/user/1000/containers
  transientStore: false
  volumePath: /home/admin/.local/share/containers/storage/volumes
version:
  APIVersion: 4.9.4-rhel
  Built: 1723107101
  BuiltTime: Thu Aug  8 17:51:41 2024
  GitCommit: ""
  GoVersion: go1.21.11 (Red Hat 1.21.11-1.el9_4)
  Os: linux
  OsArch: linux/amd64
  Version: 4.9.4-rhel

systemd 連携の概要

podman は systemd との連携機能があり、Conteinerized AAP の各コンテナは systemd 経由で起動、停止するようになっています。

インストールユーザー(非root)でユニットファイルが作成されることが特徴です。~/.config/systemd/user/ ディレクトリ配下に、各コンテナに対応するユニットファイルがあります。

$ ls -l  ~/.config/systemd/user/
total 28
-rw-r--r--. 1 admin admin  864 Sep 24 12:40 automation-controller-rsyslog.service
-rw-r--r--. 1 admin admin  849 Sep 24 12:40 automation-controller-task.service
-rw-r--r--. 1 admin admin  844 Sep 24 12:40 automation-controller-web.service
drwxr-xr-x. 2 admin admin 4096 Sep 24 12:43 default.target.wants
drwxrwx---. 2 admin admin   27 Sep 24 12:37 podman.service.d
-rw-r--r--. 1 admin admin  698 Sep 24 12:39 postgresql.service
-rw-r--r--. 1 admin admin  688 Sep 24 12:40 receptor.service
-rw-r--r--. 1 admin admin  673 Sep 24 12:39 redis.service
drwxr-xr-x. 2 admin admin   27 Sep 24 12:37 sockets.target.wants

systemctl コマンドで操作する場合は --user オプションが必要です。

systemctl コマンド使用例1:

$ systemctl list-unit-files -t service --user
UNIT FILE                             STATE    PRESET  
automation-controller-rsyslog.service enabled  disabled
automation-controller-task.service    enabled  disabled
automation-controller-web.service     enabled  disabled
dbus-broker.service                   enabled  enabled 
dbus.service                          alias    -       
dirmngr.service                       static   -       
gpg-agent.service                     static   -       
grub-boot-success.service             static   -       
podman-auto-update.service            disabled disabled
podman-kube@.service                  disabled disabled
podman-restart.service                disabled disabled
podman.service                        disabled disabled
postgresql.service                    enabled  disabled
receptor.service                      enabled  disabled
redis.service                         enabled  disabled
ssh-agent.service                     static   -       
systemd-exit.service                  static   -       
systemd-tmpfiles-clean.service        static   -       
systemd-tmpfiles-setup.service        enabled  enabled 

19 unit files listed.

systemctl コマンド使用例2:

$ systemctl status automation-controller-web.service --user
● automation-controller-web.service - Podman automation-controller-web.service
     Loaded: loaded (/home/admin/.config/systemd/user/automation-controller-web.service; enabled; preset: disabled)
     Active: active (running) since Tue 2024-09-24 12:43:57 JST; 4h 58min ago
       Docs: man:podman-generate-systemd(1)
    Process: 27457 ExecStart=/usr/bin/podman start automation-controller-web (code=exited, status=0/SUCCESS)
   Main PID: 27469 (conmon)
      Tasks: 1 (limit: 23160)
     Memory: 756.0K
        CPU: 75ms
     CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/automation-controller-web.service
             └─27469 /usr/bin/conmon --api-version 1 -c 344e8869af0c02b02b2f72033143527167153164ad6adc548e675c4fcfa2995f -u 344e8869af0c02b02b2f720331435271671531>
...(略)...

systemctl コマンド使用例3:

$ systemctl list-dependencies --user
default.target
● ├─automation-controller-rsyslog.service
● ├─automation-controller-task.service
● ├─automation-controller-web.service
● ├─postgresql.service
● ├─receptor.service
● ├─redis.service
● └─basic.target
●   ├─systemd-tmpfiles-setup.service
●   ├─paths.target
●   ├─sockets.target
●   │ ├─dbus.socket
●   │ └─podman.socket
●   └─timers.target
●     ├─grub-boot-success.timer
●     └─systemd-tmpfiles-clean.timer

ユニットファイルの例

systemd のユニットファイルは、インストール処理内の containers.podman.podman_containerモジュールの generate_systemd オプションの指定によって生成されます。

generate_systemd.new オプションの指定はなくデフォルトの false 扱いです。なので、インストール処理内でコンテナを create して、systemd 経由で start する、という流れです。いきなり run ではないです。

コンテナの CreateCommand を確認すると、odman container create になっていました。

$ podman inspect automation-controller-web 
...(略)...
               "CreateCommand": [
                    "podman",
                    "container",
                    "create",
                    "--name",
                    "automation-controller-web",
...(略)...

以下は、私の環境の /.config/systemd/user/automation-controller-web.service の例です。ExecStartpodman start になっていることが確認できます。

# automation-controller-web.service
# autogenerated by Podman 4.9.4-rhel
# Tue Sep 24 12:40:39 JST 2024

[Unit]
Description=Podman automation-controller-web.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=/run/user/1000/containers

# User-defined dependencies
Requires=postgresql.service redis.service

[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=90
ExecStart=/usr/bin/podman start automation-controller-web
ExecStop=/usr/bin/podman stop  \
    -t 30 automation-controller-web
ExecStopPost=/usr/bin/podman stop  \
    -t 30 automation-controller-web
PIDFile=/run/user/1000/containers/overlay-containers/344e8869af0c02b02b2f72033143527167153164ad6adc548e675c4fcfa2995f/userdata/conmon.pid
Type=forking

[Install]
WantedBy=default.target

systemd 連携による自動起動

前述のユニットファイルにある通り、Install セクションでは、WantedBy=default.target が指定されていて、systemctl enable|disable できるようになっていました。

インストール処理内では、ansible.builtin.systemd モジュールで、起動と enable されるようになっています。これにより自動起動を実現しているようです。

ただ、前述通り、ユニットファイルはユーザーレベルのものです。この場合、デフォルトではユーザーがログインすると起動、ログアウトすると停止するため、サービス提供に向きません。

どうなってるんだろうと思ったのですが、インストール処理の中で loginctl enable-linger ユーザー名 が実行されていました。これにより、システ起動時にサービスが起動するようになるようです。

参考: 14.2. systemd サービスの有効化 | Red Hat Product Documentation

ポート開放の仕組み

前述通り podman ps での表示は PORTS は空欄でした。どうやってポート開放しているのかなと思ったので調べました。

--network host でコンテナが起動されていました。

$ podman inspect automation-controller-web 
...(略)...
               "CreateCommand": [
...(略)...
                    "--network",
                    "host",
...(略)...

なお、ホスト側での ss はこんな感じでした。

$ ss -nap | grep 443        # automation-controller-web の listen 分
tcp   LISTEN 0   511   0.0.0.0:443     0.0.0.0:*      users:(("nginx",pid=27533,fd=6),("nginx",pid=27532,fd=6),("nginx",pid=27531,fd=6),("nginx",pid=27530,fd=6),("nginx",pid=27525,fd=6))                                                                                                                                                                                                                                                                                                                                                   
tcp   LISTEN 0   511      [::]:443        [::]:*      users:(("nginx",pid=27533,fd=7),("nginx",pid=27532,fd=7),("nginx",pid=27531,fd=7),("nginx",pid=27530,fd=7),("nginx",pid=27525,fd=7))                                                                              

デフォルトでは、一般ユーザーでは 443 は listen できませんが、前述通りインストール処理内でカーネルパラメーター net.ipv4.ip_unprivileged_port_start を調整しているので listen できます。

インストール処理中、ansible.posix.firewalld モジュールで firewalld の調整もしてくれます。

ストレージ・ボリューム関連

ボリューム一覧は以下の通りです。

$ podman volume  ls
DRIVER      VOLUME NAME
local       postgresql
local       redis_data
local       redis_etc
local       redis_run
local       receptor_run
local       receptor_runner
local       receptor_home
local       receptor_data

ボリュームのパスは以下の通りです。ルートレス Podman としての標準のままです。

$ ls -l ~/.local/share/containers/storage/volumes/
total 0
drwx------. 3 admin admin 19 Sep 24 12:39 postgresql
drwx------. 3 admin admin 19 Sep 24 12:39 receptor_data
drwx------. 3 admin admin 19 Sep 24 12:39 receptor_home
drwx------. 3 admin admin 19 Sep 24 12:39 receptor_run
drwx------. 3 admin admin 19 Sep 24 12:39 receptor_runner
drwx------. 3 admin admin 19 Sep 24 12:39 redis_data
drwx------. 3 admin admin 19 Sep 24 12:39 redis_etc
drwx------. 3 admin admin 19 Sep 24 12:39 redis_run

また、~/aap に用途ごとにディレクトリがあり、この配下を各コンテナがバインドマウントしています。

$ ls -l  ~/aap/
total 0
drwxrwx---. 3 admin admin 55 Sep 24 12:37 containers
drwxrwx---. 7 admin admin 75 Sep 24 12:40 controller
drwxrwx---. 2 admin admin 42 Sep 24 12:39 postgresql
drwxrwx---. 3 admin admin 17 Sep 24 12:39 receptor
drwxr-x---. 3 admin admin 52 Sep 24 12:39 tls

例えば automation-controller-web の場合は以下の通り。

$ podman inspect automation-controller-web
...(略)...
 "HostConfig": {
               "Binds": [
                    "receptor_run:/run/receptor:U,rw,rprivate,nosuid,nodev,rbind",
                    "redis_run:/run/redis:z,rw,rprivate,nosuid,nodev,rbind",
                    "/home/admin/aap/controller/etc/tower.key:/etc/tower/tower.key:ro,rprivate,rbind",
                    "/home/admin/aap/controller/etc/tower.cert:/etc/tower/tower.cert:ro,rprivate,rbind",
                    "/home/admin/aap/controller/etc/launch_awx_task.sh:/usr/bin/launch_awx_task.sh:ro,rprivate,rbind",
                    "/home/admin/aap/controller/data/job_execution:/home/admin/aap/controller/data/job_execution:rw,rprivate,rbind",
                    "/home/admin/aap/controller/data/projects:/home/admin/aap/controller/data/projects:rw,rprivate,rbind",
...(略)...

おわりに

コンテナによるインストールはデプロイが早く、ライセンスの自動適用や設定の投入も一緒にできるが便利だなと思いました。

現状、インストールがうまくいかなかったときは、一度アンイストールしてから再度インストールするほうが良いような感覚でした。

将来の AAP のバージョンで GA になったら、またチェックしたいと思います。

まとめ(再掲)

  • podman でデプロイする方式、ルートレス
  • デプロイ後にライセンスの適用や設定投入もできる
  • 各コンテナはユーザーレベルの systemd 経由で起動

試せなかったこと

興味はあったけど今回試せなかったこと一覧

  • http の禁止(https のみ)
  • 作業マシン以外へのデプロイ
  • Automation mesh 構成
  • トラシュー1 のように、インストール処理中にコンテナ receptor に異常終了した時に、インストール処理を中断させる方法

参考

Podman と systemd の連携周りでは以下の書籍を参考にさせていただきました。

www.shuwasystem.co.jp

gihyo.jp

[Ansible/AAP] AAP 2.5 の変更点は?(リリース前の情報から)

はじめに

AAP(Ansible Automation Platform)2.4 の Full support 期限が 2024/10/01 と迫っていることから、次期の AAP 2.5 の足音が聞こえてきました。

(過去、サポート期限の表記が延長されたことはありました)

Red Hat Ansible Automation Platform Life Cycle - Red Hat Customer Portal

そんな中、Red Hat のナレッジベースに AAP 2.5 での変更点に関する記事が公開されました(要ログイン)。

access.redhat.com

[2024/09/30 追記] ログイン不要で見れる AAP 2.5 のリリースノートが公開されました。

docs.redhat.com

正確、詳細について Red Hat 社の記事を参照いただきたいですが、本ブログの記事としては、以前から公開されていた情報をさかのぼり「あれのことかなー?」「そういうことかなー?」と予測してみます。

本ブログ記事は一個人の予想でしかありませんのでご留意ください。

ポイントは、各種画面を束ねる統合 UI と、コンテナでのデプロイ方式です。個人的には、AAP 2系になってか一番大きな変化になるかなと思っています。

■ Platform Gateway (統合 UI)

これまで、Automation Controller、Automation Hub、EDA Controller は別々の画面として提供されていました。

これらを束ねるような画面の提供されるという情報が以前からありました。

Automation Automates 2023 Japanでの「Unified UX Experience」

2023年7月に開催された Automation Automates 2023 Japan では、AAP のロードマップの話がありました。

以下の動画の10:10 頃からのスライドの右の「Long term」のところに「Unified UX Experience」があります。これが各種画面を統合する画面のことだと思います。

Red Hat Ansible Automation Platform ロードマップ 10:10 頃より

動画:

www.redhat.com

口頭では以下の説明がありました。このころには Platform Gateway という呼称はあったようです。

中長期の目標は中央プラットフォームゲートウェイサーバー内で統一されたユーザーエクスペリエンスを提供することです

以下の説明から、画面が統合されるだけでなく、認証機能にも変更がありそうです。  

コンポーネントツリー全体にわたる一元認証も可能にします

AnsibleFest 2024 での見慣れない画面

感覚的には「ふいに出てきた」という感じだったのですが、とあるセッションの中で見慣れない画面が紹介されました。

AnsibleFest 2024 の動画 17:10 頃

以下の動画の 17:01 頃からです。これが Platform Gateway (の開発段階)なのでしょうか。

www.youtube.com

左のメニューに以下のような文字が見られます。

  • Projects
  • Automation Execution
  • Automation Decisions
  • Automation Infrastructure
  • Automation Content
  • Automation Analytics

たとえば、Automation Execution であれば、Automation Controller 相当ってことなのではないかと思います。

参考: [Ansible] AnsibleFest 2024 のキーノートで気になったポイント(事例、Event-Driven Ansible、Policy as Code など) - てくなべ (tekunabe)

ドキュメント

ansible/aap-docs という「Red Hat Ansible Automation Platform Documentation」という説明のリポジトリがあります。

中をあさっていると、Platform gateway の設定画面の説明らしきページが見つかりました。

aap-docs/downstream/modules/platform/proc-settings-platform-gateway.adoc at 2.5 · ansible/aap-docs · GitHub]

画像 aap-docs/downstream/images/platform_gateway_full.png at 2.5 · ansible/aap-docs · GitHub

また、インストール方式での説明に掲載されているインベントリファイルには、以下のように automationgateway というグループや、AAP Gateway という言葉が登場します。

# This section is for your AAP Gateway host(s)
# -----------------------------------------------------
[automationgateway]
fqdn_of_your_rhel_host ansible_connection=local
...(略)...
# AAP Gateway - mandatory
# ------------------------------
gateway_admin_password=<set your own>
gateway_pg_host=fqdn_of_your_rhel_host
gateway_pg_password=<set your own>

# AAP Gateway - optional
# -----------------------------
# To use custom TLS certificate/key you need to set these variables
#gateway_tls_cert=<full path to your TLS certificate file>
#gateway_tls_key=<full path to your TLS key file>
...(略)...

インベントリに定義する変数の一覧にも更新が入っています。

2.5 Update inventory file variables for controller and gateway (#1697) by michellemacrh · Pull Request #1698 · ansible/aap-docs · GitHub

例えば admin_password という変数は、

The password for an administration user to access the UI when the installation is complete.

から

The admin password used to connect to the {ControllerName} instance.

に変更されています。UI という言葉がなくなっているあたりが少々気になります。

インストール方法のページの、インストール後の確認手順では、まず platform gateway を開くとあります。

Verifying installation of Ansible Automation Platform(個別にビルドした画面)

■ コンテナでのデプロイ方式の追加

2023年から「Containerized AAP」という言葉で、コンテナでのデプロイ方式の追加がありました。AAP 2.4 では Technical Preview 扱いですが、おそらくこれが GA になるということなのかなと予想しています。

(OpenShift によるデプロイは別です)

もちろん、GA までに大小さまざまな変更はあるかと思います。

Automation Automates 2023 Japanでの「Containerized AAP」

Automation Automates 2023 Japan での AAP のロードマップの話の中で、「Containerized AAP」という言葉がありました。

おそらくこれが、コンテナ方式でのデプロイのことだと思います。

Red Hat Ansible Automation Platform ロードマップ 10:10 頃より(再掲)

動画(再掲):

www.redhat.com

AAP 2.4 時点では Tech Preview

Tech Preview 扱いですが、AAP 2.4 のドキュメントでは Containerized AAP の情報も載っていました。

docs.redhat.com

現在も更新が進められているようです。

github.com

公式ブログなどでの「Containerized AAP」

2023年9月の公式ブログでも Containerized AAP についての説明がありました。

www.redhat.com

公式動画:

www.youtube.com

個人ですが他にも動画があります。 www.youtube.com

同じく個人ですが、日本語としてはとても貴重な情報です。 zaki-hmkc.hatenablog.com

[2024/09/29 追記]

私も試してみました。podman のsystemd 連携が興味深かったです。

tekunabe.hatenablog.jp

おわりに

繰り返しになりますが、正確、詳細について Red Hat 社の記事をご参照ください。

access.redhat.com

本ブログ記事では、これまで公開されていた情報を中心にまとめました。

参考

github.com

ntc-templates のパース結果のキー名は標準化によって変わってきている

はじめに

ネットワーク機器の通常の show コマンド結果を、構造化データにパースしてくれる ntc-templates というパーステンプレート集があります。

TextFSM というパーサーに対応したテンプレートです。

例えば、Cisco IOS の 'show ip interface brief` の結果を以下のようにしてくれます。

        {
            "intf": "GigabitEthernet0/0",
            "ipaddr": "192.168.1.11",
            "proto": "up",
            "status": "up"
        }

ntc-templates は、様々なベンダーにの機器に対応するテンプレートがありますが、構造化データにした際のキー(interface など)が揃っていなかったようです。

そこで、この1年くらい前?から、キー名の標準化が進んできているようです。キー名の標準化は、特定のバージョンでいっぺんに行われているわけではなく、徐々に行われています。

今回は、たまたま気付いた show ip interface brief コマンド結果のキーの変化について Ansible 経由で検証してご紹介します。

検証環境:

  • ansible-core 2.15.7

Playbook

本題からややそれますが、Playbook は以下のものを利用します。

---
- hosts: ios01
  gather_facts: false

  tasks:
    - name: Run show ip interface brief
      ansible.utils.cli_parse:
        command: show ip interface brief
        parser:
          name: ansible.netcommon.ntc_templates
      register: result_parsed

    - name: Debug paresed
      ansible.builtin.debug:
        msg: "{{ result_parsed.parsed }}"

ntc-templates 3.0.0

3.0.0 で Playbook を実行すると以下のようになりあります。

TASK [Debug paresed] ****************************************
ok: [ios01] => {
    "msg": [
        {
            "intf": "GigabitEthernet0/0",
            "ipaddr": "192.168.1.11",
            "proto": "up",
            "status": "up"
        },
        ...(略)...
}

ntc-templates 4.0.0

続いて 4.0.0 での結果です。

TASK [Debug paresed] ******************************************
ok: [ios01] => {
    "msg": [
        {
            "interface": "GigabitEthernet0/0",
            "ip_address": "192.168.1.11",
            "proto": "up",
            "status": "up"
        },
        ...(略)...

比較

それぞれを比較すると以下の違いがあります。略さない方向になっているようです。

項目 3.0.0 4.0.0
インターフェース intf interface
IPアドレス ipaddr ip_address

4.0.0 の Changelog には以下の記述がありました。

Standardize interface capture group by @mjbear in #1419

関連PR: Standardize interface capture group by mjbear · Pull Request #1419 · networktocode/ntc-templates · GitHub

Standardize capture group IP_ADDRESS by @mjbear in #1439

関連PR: Standardize capture group IP_ADDRESS by mjbear · Pull Request #1439 · networktocode/ntc-templates · GitHub

「Breaking Changes」という扱いではないので、見落としてしまうかもしれません。。

おわりに

Changelog で確認する際は、Standardizenormalize といった言葉に注目するとこの手の変更が見つかりそうです。