てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] Ansible Automates 2024 Japan 参加メモ

はじめに

2024/08/07 に、Red Hat 社主催で、Ansible に関する年次イベント「Ansible Automates 2024 Japan」がオンラインで開催されました

今回のテーマは「実践から学ぶインフラ自動化、国内事例大集合!」

events.redhat.com

ほぼハッシュタグ #ansibleautomates でポストした内容ですが、個人的なメモとしてまとめておきます

なお、後日セッション動画、講演資料は以下のページ経由で公開されるとのことなので、正確で詳細は情報はそちらをご参照ください

www.redhat.com

そういえば、今回は「自動化2.0」という言葉は使われませんでした。

インフラ自動化の今、そして未来の自動化

  • Policy as Code
  • AI が生成したPlyabookを自信をもって利用できるように、ガードレールを敷く
  • ポリシーをコード化するメリット。透明性、再現性、変更管理、自動化、コンプライアンス対応
  • 「ポリシー」の例。作業時間帯の制限、セキュリティのチェックが通ってないと実行させな、署名の有無など

ansible-policy としてはまだバージョニングもされない状態で発展途上だと思うので、これからも様子をウォッチしていきたいと思います

参考: tekunabe.hatenablog.jp

Ansible Lightspeedを活用したPlayboook開発

  • Ansible Playbook を AI で生成する Ansible Lightspeed
  • 自部門ではAnsibleの心理的ハードルが高いなどの課題があった。そこで Ansible Lightspeed と出会った
  • 自然言語によるコード化、作業のタスク分解してくるところがポイントと感じた
  • Ansible Lightspeed、まずは3か月の検証。Ansible上級者、初心者、Red Hat コンサルタントによる
  • 頑張らなくても自動化できるような理想の姿を描いていた。しかし、生成の制約が多く、自分で書いたほうが早い場面も。適切なプロンプトも分からず。正直がっかり
  • Playbook生成機能などの追加が転機になった
  • Playbookを生成し、Task Generation を利用してタスクレベルで修正、Playbook Explanation でPlaybookを説明してもらう。という使い方で自動化を加速できた
  • Ansible 初心者の視点。自動化対象にあったモジュールが分からない。1からコーディングできない。初歩的な文法エラーが多発。難しくて挫折しがち
  • これらの課題を Ansible Lightspeed を用いて解決。モジュールが分からなくてもよくなって、ブログを調べる手間がなくなった。また、生成されたPlaybookを修正するだけなので1からか書かなくてよく、ケアレスミスによるエラーも少ない
  • Ansible Lightspeed を使ったデモ。Playbookを生成し、解説してもらう
    • シナリオは、AWSVPC、仮想ネットワーク作成、ルートテーブル作成、EC2デプロイなど
  • デモ中のおはなし。一番いいと思ったのは、1からコーディングすることのハードルが下がり、手直し感覚でできたこと。Ansibleは一ヶ月だけの勉強だけだったが 初心者が Ansible Ligthspeed を利用するのがよいのではないか。プロンプトの書き方を正しくできれば有用
  • デモの流れ
    • プロンプトを英語で入力(日本語はサポート対象外のため)するとPlaybookが生成される
    • アドレスの指定が正しくなかったので修正
    • Playbook実行、確認
    • Multi Task Generation でタスクを2つ追加、少し修正
    • 再実行、確認
    • Task Explanationで説明書を生成
  • 成果。エラーが約80%現状、コード開発時間が約65%減少。Litghtspeed を使った初心者の方が上級者よりも開発時間が短いことも
  • 発展途上なので、今後の機能拡張に期待
  • 今後の展望。Ansible Ligthspeed を活用して社内に自動化を広げていく

初期のリリースからと比べると、実用レベルに達してきているみたいですね。ドキュメントを生成してくれるのはよさそうです

Ansible活用によるシステム運用高度化の取り組み

  • Ansible採用理由、エージェントレス、シンプル、パワフル
  • 最初はサーバー構築の自動化からはじめ、開発・配布環境の整備、運用業務への適用、というAnsible活用の歴史
  • サーバー自動構築システム(内部はAnsible)。申請を受けて設定パラメーターをAnsibleように加工して実行。結果を申請DBに返す
  • サーバー自動構築システムを入れる前後の比較、効果。従来は各基盤ごとに担当がいたが、現在はサーバー基盤担当のみ。また、ゲストサーバー構築にかかる時間も短く。PJごとの予算取りが不要になり、コストの運用枠でおさまる程度に
  • 申請が複数部署にまたがって大変だったがが、簡単になった
  • ヒューマンエラーがなくなって、ストレスからも解放。従業員の仕事への満足度が向上

業員の仕事への満足度が向上というレベルまでいっているのが驚きでした

自律化へ向けて

  • 自動化のポイント。量子化、標準化、一元化。自分たちの仕事、経験を言語化することが重要
  • やっていることを置き換え。システム状態の確認は監視システムへ。など。置き換えた部分を省くとシンプルになる
  • 再利用できるところ、仕様の差が少ないところをさがしてロールへ寄せる

事前確認と設定と事後確認の手順を、自動化をしやすくするために切り口を変えて見る話が興味深かったです

オリックス銀行におけるIaC内製化の挑戦と成果・将来

  • システムの安定稼働のために、まずはシステム自動復旧。
  • 自動化前の課題感
    • 手作業による品質のブレやヒューマンエラーがあった(名前付けなど)
    • 変更管理が申請とドキュメントベースで、差分が即座に判断できない
    • 手作業の業務が多い
    • ベンダー任せ(詳しく知らない)
  • 実装機能を検討
    • 自動化効果が高いもの頻度が多く、時間がかかっていて、手順が複雑なもの
    • 拡張性があるもの
    • 実現可能性があるもの。限られた時間で実装できるか
    • 結果、IAM権限移譲、IAMユーザー作成業務を自動化対象に選定
  • 成功したところ
    • 内製で実装
    • 未経験からの実装
    • リリースできた
  • 失敗したところ
    • コード品質(ロール間の密結合など)
    • 標準化(環境が個人裁量)
    • マネジメント(スケジュール見積りの甘さ、フォローが後手に)
  • 得られたもの
    • やってみることの大事さ(PoCや机上評価では得られない生々しさなど)
    • 0から1へ(やったことがある、へ)
    • 悔しさ
    • モチベーション
  • これから
    • 再利用可能な機能の拡充(よく使う機能)
    • 開発環境の標準化
    • Ansible開発者の拡大(ガイドライン、コンテンツ)

モブプロがすごく効果的だったそうです

Ansibleが日常になるまで

  • 現在のプライベートはクラウドは第3世代。徐々に内製化へ。Ansibleの活用も定着してきた
    • 導入期: 盛り上がってるのは個人レベル
    • 成長期: ベンダーが作ったPlaybookを読んだり修正
    • 定着期: 共通言語化されている。だれでお教えられる。いまここ
  • 導入期
    • DevOpsの始まり。Gitea 導入。カスタムモジュールのプロトタイプの開発までやった
  • 成長期
    • ベンダー開発のPlaybookを読み解いて書き換えるのが大変だったので、可読性の重要さを知るきっかけに
    • 変数の利用は少なくするという方針に
  • 定着期
    • ここまできたらAnsibleが日常。現在はテナントにAAPを提供
  • うまくいったこと
    • DevOps、運用課題の改善のモチベージョンをもとに取り組めた
    • 内製化
    • 小さい再組織で、対象を絞って始められた
  • うまくいかなかったこと
    • 日常になるまで時間がかかった
    • インベントリの共通化(標準化はできた)

「もし組織の広い範囲でいきなり自動化をはじめたら、どこか他人事になってしまったかもしれない」というお話があ印象に残りました。

おわりに

各事例ではストーリーが伺えて大変興味深かったです。覚えておきたいヒントがたくさんありました 登壇者のみなさまありがとうございました!

JANOG54 Meeting レポートその2: 登壇編「自動化の教育ってどうやってますか?」

はじめに

2024/07/03-05 に奈良県奈良市奈良県コンベンションセンターで JANOG54 Meeting in NARA が開催されました。

本記事では、登壇の機会をいただいたプログラム「自動化の教育ってどうやってますか?」の、準備や当日のことなどをまとめます。

なお、参加したプログラムについては別の記事にしてあります。

tekunabe.hatenablog.jp

応募までの経緯と共同登壇

私が所属している自動化専門の部署では、3年間ほど配属される方に対して技術的、業務的なトレーニングを行っています。

どんなことを教えていて、どんな工夫をしているかなど、いつか JANOG でお話できればなと思っていました。

私は、初代の講師を担当していて、最近講師の引き継ぎをしました。これまでのふりかえりを含めて良いタイミングかなと思って、今回プログラムに応募しました。

これまで JANOG のプログラムに応募するときは、事前資料を出せずにいたのですが、今回ははじめて事前資料を作成して応募時に提出しました。

また、応募した段階では人選までは未定だったのですが、引き継ぎ先の講師の社員との共同登壇にしようと考えてました。プログラムを採択いただいたあとに、講師(複数名)に声をかけて、そのうち一人が登壇してくれることになりました。良い感じに登壇の機会を作れたかなと思いました。

本編

本編は大きく分けて2つのパートで構成しました。

まず、私からトレーニング全体の概要やポリシー、工夫、扱っている技術要素などをお伝えしました。

次の佐々木さんのパートでは、自動化業務の進める上で必要なナレッジを扱うパート(ナレッジ編)についてお伝えしました。このナレッジ編は、トレーニングの重要なポイントの1つです。たとえば、手作業での手順書を自動化するときにどう最適化するか、などを扱っています。 ここの技術要素の解説書籍でもあまり扱ってないような内容かなと思います。

当日使用した資料は以下のページにリンクがあります。

www.janog.gr.jp

直リンクも貼っておきます。

アーカイブ動画はこちら。いつもより期限が長く(半年、2025年1月まで)なっています。ありがたいです。

www.youtube.com

Slack にも書いたのですが、トレーニングのお「ナレッジ編」で受講者に伝えている内容は、もともとチーム内で Wiki に積み上げたナレッジを基にしています。業務経験で得たことをおナレッジにし、重要なことはトレーニングに落とし込むというサイクルです。

Slack

Slack の本プログラム用チャンネルでもご意見、お悩み、ご質問をいただきました。ありがとうございました。

#janog54-ansible-自動化の教育ってどうやってますか

本編の最終にも壇上で拝見していたので、このあとのディスカッションでどんな話題になりそうか予想できることもあったので助かりましまた。

ディスカッション(議論)

議論時間の様子

本ブログラム全体の 45 分のうち、15分をディスカッションの時間に割り当てました。アーカイブ動画では 31:17ころから。

ありがたいことに、時間いっぱいご意見やご質問をいただきました。

せっかくですので、ディスカッションパートでの話のいくつかを抜粋します。

  • 技術を定着させるための、どのくらい時間をかけているか
    • Ansible でいうと10数時間。これは書いてあることをやればいいレベルで一周目という位置づけ。
    • 加えて、定着させるために2周目として総合演習(見本がないハンズオン)を設けている
  • ついていくことが難しい人へのフォローはどうしているか
    • 質疑応答のタイミングを設けている
    • オンラインだと、受講者の様子が見えないので、困ったら声をかけてもらえるように、雰囲気づくりが重要
  • ハンズオンと業務レベルのギャップと乗り越え方
    • すべてのギャップを埋めることはできない
    • 調べ方、ドキュメントの読み方、聞き方などを含めてトレーニング、という位置づけにしている
  • 顧客ヒアリングなどはシミュレーションしているか
    • 現状は要件を講師側から提示している。それに対してどう実現するかを考えてもらっている
  • 教育を横展開する時の考え方
    • 基本的な部分を抑える方針にしているため、各現場固有の事情は取り込んでいない
    • いい意味で汎用的、悪い意味ではフィットしきらない部分もある
    • フィットしない部分は、ナレッジ編で調べ方などを学習してもらう形でカバーしている

替え玉エリア(延長ディスカッション)

JANOG 53 に続いて今回も「替え玉エリア」という延長ディスカッションが設けられていました。Ask the Speaker的な場です。

プログラムの時間内のディスカッションでは、時間やプレッシャーの面でマイク前に立ちにくいこともありますが、替え玉エリアではそういった制約が少なく、双方リラックスしてお話できたような気がします。

多くの人に並んでいただいて、制限時間いっぱい、たくさんお話させていただきました。

show int さんの動画で、ちょうど私達が替え玉エリアで会話している様子を撮っていただいていました(以下動画 7:21 頃)。ありがとうございます!雰囲気が分かりやすいと思います。

youtu.be

おわりに

今回の場で、自分たちのチームで行っているトレーニングの仕組みに少し自身が持てました。一方で、継続的に改善していく必要があることも改めて認識できました。

ご参加いただいたみなさま、ディスカッションパートで、替え玉エリアに起こしいただいたみなさま、ご担当いただいたスタッフの方々、ありがとうございました!

普段の取り組みを、組織を超えて話し合える場をいただけてとてもありがたかったです。

参考

togetter

2024-07-04 13:37:51 のポストからまとめていただきてます。ありがとうございます!

togetter.com

その他

JANOG54 関連で見かけたの記事は、参加編の記事の参考をご参照ください。

私と JANOG のこれまで

本ブログにおける他の JANOG 関連の記事です。

JANOG54 Meeting レポートその1: 参加編

はじめに

2024/07/03-05 に奈良県奈良市奈良県コンベンションセンターで JANOG54 Meeting in NARA が開催されました。

今回はありがたいことに、登壇の機会ブース出展があったため、現地で参加しました。

来場者数は過去最多 3,249人だったそうです。大盛り上がりですね。

本記事では、当日に参加したプログラムアンケート締め切り前に視聴したいくつかのプログラムや、全体的な所感についてまとめます。

なお、各プログラムの詳細ページから資料や、アーカイブ動画が見れます(一部アーカイブなし)。アーカイブ動画は2025年1月下旬頃までの公開です。今回は期限がいつもより延長されています。気になるプログラムがあれば見てみてください。

また、参加された方はぜひアンケート回答を!(2024年7月26日(金) 23:59 まで)

www.janog.gr.jp

なお、登壇したプログラム「自動化の教育ってどうやってますか?」については別の記事で扱う予定です。

[2024/08/09 追記] 投稿しました JANOG54 Meeting レポートその2: 登壇編「自動化の教育ってどうやってますか?」 - てくなべ (tekunabe)

参加プログラム

商用サービスインフラにおけるSONiCスイッチ障害交換運用の実際

www.janog.gr.jp

www.youtube.com

SONiC の使われ方と ZTP の実現方法が気になったので参加しました。

資料 P18 にあるように以下の範囲をZTPでカバーしたそうです。

  • OS イメージ投入
  • 初期Config投入
  • Config以外の追加設定

ZTP サーバーは Apache HTTP Serverで準備。

ディスカッションパートでは、ZTP でどの範囲のコンフィグを投入するのがよいかという議論がありました。

今回紹介されたケースでは、いったん投入したらそうそう変更しない性質だったため、ZTPで一通りのコンフィグを投入したそうです。 そうではなく、コンフィグ生成テンプレートの修正が見込まれる場合、SSHでの疎通ができるところまでは ZTP で投入し、そのあとのコンフィグは Ansible などで投入するとよいのでは、という話がありました(Yahoo! JAPAN での例)。

すみわけについて勉強になりました。

あと、ONIE を初めて知りました。今回は SONiC の OSイメージ自体の導入を ONIE が持つ仕組みで行ったそうです。

OpenConfigを活用したNW検証業務自動化への取り組みと課題

www.janog.gr.jp

アーカイブなし)

このプログラムでは、手動では検証できない検証項目(1500以上)をこなすために、OpenConfig による検証自動化した結果のお話がされていました。

OpenConfig は以前から興味がありましたが、近況や詳細を追えていなかったので参加しました。

Ondatra」という、OpenConfig の利用とした検証自動化フレームワークを初めて知りました。 テストとポロシーの定義ファイルと、検証項目の定義ファイルを書き、go test コマンド経由で検証するそうです。気になるので後で調べてみたいと思いました。

github.com

gNOI(gRPC Network Operations Interface)という言葉も初めてしりました。gMNI とはまた別ものなのですね。gMNI が状態取得や設定変更であるのにたいして、gNOI は ping や reload などの機器操作を担うものだそうです。言われてみると確かに性質がことなるものですね。

P22の「NW機器からの情報取得」、やはりパースが不要なのはうれしいですね。

P28 で紹介されている「各ベンダで対応しているYANGモデル情報の確認方法」、こういうのは本当にありがたいですね。慣れないと(慣れてても?)対応するパスが見つけにくかったりするので・・。

OpenConfig そのものだけではなく、周辺を取り巻くツールや仕様をセットで知れて、大変ありがたかったです。

全体的には、OpenConfig は便利であるものの、機器側の対応状況に左右される部分も大きいという印象でした。

プログラム終了後の替え玉エリアでも登壇者お二方を会話させていただきました。ありがとうございました!

技術的負債と向き合い、ネットワークアーキテクチャの改善とモノの管理、コスト構造の見直しに取り組んだ話

www.janog.gr.jp

www.youtube.com

大変なご苦労されたことがにじみ出るプログラムでした。複雑になり続けたネットワーク構成を、腹をくくって責任感を持ち、改善し続けてこられた様子に尊敬するばかりでした。

原価算出ロジックが実態とあっていない、などコスト構造を見直すといった取り組みもされていて、技術だけでなく、幅広い知識が必要とされていたことが分かりました。

ツール面でいうと、資料には記載はありませんが Containerlab が登場しました。ネットワークの検証環境を構築できるツールです。過去の JANOG Meeting でもちらほら名前は出てきましたが、実際はどのような使われ方をされているのかに関心がありました。今回の場合は、Containerlab で予め検証して、問題がなければ本番環境にも投入するというプロセスにしているそうです。

ディスカッションパートでは、過去に担当されていた方がマイクの前に立ち、当時は最善だと思ってやっていたが・・、という話がありました。敬意を表したいですね。このような話になあるのも、さまざまな立場の方が集まる場ならでだなと思いました。

こちらのプログラムも、終了後に替え玉エリアでお話をお伺いできました。ご対応いただきありがとうございました!

アーカイブ視聴予定

当日参加できたプログラム以外にも、興味深いプログラムがあるため、アーカイブが公開されているうちに視聴しようと思います。

なお、これまでアーカイブが残るのは1か月程度でしたが、今回は半年(2025年1月くらい?)になったそうです。ありがたい!

主に以下のプログラムを中心に視聴予定です。

プログラム以外

プログラム本編以外で感じたことです。

替え玉エリア

前回の JANOG53 Meeting in HAKATAに続いて、今回も「替え玉エリア」が設けられました。

いわゆる「Ask the Speaker」的な場で、発表が終わって本編を締めたあと、廊下のようなばで個別に質問や議論、名刺交換をできる場です。ラーメンの替え玉が由来のようです。

今回の場合、部屋の外に丸いテーブルとホワイトボードがあり、そこが替え玉エリアの目印でした。

プログラム本編でも質疑応答の時間が設けられ、そこでの話は参加者にも自然と共有されます。しかし、大勢の前でマイクの前に立つのは緊張してしまったり、時間の制約で話せない場合もあります。そんなときの救済措置としてとても有効に機能しているように思いました。

「気になることあればあとで捕まえて声かけてください」というのもなかなかハードルが高い場合もあるので、公式の場があるのは助かります。場所と時間の制約はあるものの、逆にその制約が行動の後押しになって、コミュニケーションのハードルがさがっている気がします。

実際に、私もいくつかのプログラムで替え玉エリアで有意義なお話をお伺いできました。

Slack のプログラムごとのチャンネル

こちらも前回の JANOG53 Meeting in HAKATAくらいから始まった記憶があるのですが、今回もプログラムのごとの Slackのチャンネルが用意されていました。

たとえば「自動化の教育ってどうやってますか?」というプログラムであれば、チャンネル #janog54-ansible-自動化の教育ってどうやってますか といった具合です。

以前は、会場の部屋単位でのチャンネルでした。最近はプログラム単位でのチャンネルなので、そのプログラムに関心がある人だけが集まっているはずです。そのため、以前と比べると書き込みのハードルも低くなっているのではないかと思います。時間が経って情報が錯誤しない点もメリットです。

キッチンカー

会場敷地内に、キッチンカーが数台来ていました。

美味しいホットドッグ

いちじくやきそばのキッチンカー

いちじくやきそば

ちょっとした隙間時間でもさくっと頼んで食事がとれるので、とても便利でした。2日目、3日目はキッチンかーを利用させていただきました。

あと、コーヒーのサービスもありました。コーヒー大好きなのでありがたく頂戴しました。

地域に染み出るJANOG

現地参加するたびに思うのですが、 地域に JANOG が滲み出ててる感じが好きです。

JANOGの看板1(新大宮駅

JANOGの看板2(新大宮駅

おわりに

久しぶりの現地での参加で大変な熱気を感じることができました。はじめましての方にも、お久しぶりの方にもお会いしてお話ができました。

スタッフのみなさま、登壇者のみなさま、ホスト企業のみなさま、ブースで対応いただいたみなさま、楽しい3日間をありがとうございました!

次回の JANOG55 Meeting は 2025/01/22-24 に京都で開催予定だそうです。近畿地方が続きますね。会場のみやこめっせは趣味の関係で行ったことがあるので、個人的に親近感があります。

参考

各プログラムごとの関連記事など

solution.netone-pa.co.jp

blog.bbsakura.net

show int さんの関連動画

ふりかえり動画

www.youtube.com

前編

www.youtube.com

後編

www.youtube.com

togetter

実況ポスト、まとめありがとうございます。

togetter.com

私と JANOG のこれまで

[Ansible/AAP] AAP のサポート期限の表記が伸びていることがある

Ansible Automation Platform の各サポート期限の表が以下のページにまとまっています。

access.redhat.com

見やすくてありがたいです。このサポート期限ですが、私が観測している範囲では伸びることがあるようです。

たまたま 2023年9月時点 にとったキャプチャがあります。

2023年9月時点のキャプチャ

そして、以下が2024年6月時点のキャプチャです。

2024年6月時点のキャプチャ

たとえば、2.4 の「Full support ends」が「2023年12月23日」から「2024年10月1日」に延長されています。

「最新版のFull support endsを迎える頃に次のバージョンがリリースされるだろう」みたいな見方をする場合は、定期的にチェックするのがよいかもしれません。

[Ansible] ansible-core 2.17.0 で Linux ディストリビューションに基づくインタープリター検出機能がなくなった

はじめに

Ansible では、マネージドノード(自動化対象)が Linux の場合は、マネージドノード側の Python を利用します。どの Python インタープリターを利用するかは、設定項目 INTERPRETER_PYTHON (変数だと ansible_python_interpreter)で指定できます。

明示的に指定しない場合に備えて、自動検出する仕組みが複数ああります。このうち INTERPRETER_PYTHON_DISTRO_MAP による検出が、ansible-core 2.17.0 でなくなりました。

(そもそも)Python インタープリター自動検出の仕組み

Python インタープリターを明示的に指定しない場合は、Ansible 2.8 で導入された Interpreter Discovery (参考)という機能により、自動的に検出されます。

Interpreter Discovery では、ansible-core 2.16 までは以下の順序で検出処理が行われていました。

  1. INTERPRETER_PYTHON_DISTRO_MAP による検出
  2. INTERPRETER_PYTHON_FALLBACK による検出 (1で決まらない場合)

ansible-core 2.17.0 で INTERPRETER_PYTHON_DISTRO_MAP の廃止

ansible-core 2.17.0 では、前述の 2つの検出の仕組みのうち、1 の INTERPRETER_PYTHON_DISTRO_MAP による検出が廃止されました。

ansible-core 2.17.0 の Changelog では以下のように記載されています(関連PR)。

Interpreter Discovery - Remove hardcoded references to specific python interpreters to use for certain distro versions, and modify logic for python3 to become the default.

そもそも、明示的にインタープリターを指定していれば関係のない話ですが、この検出に頼っていた場合に困るケースがあります。

困るケースを検証

RHEL 8 を minimal でインストールした場合は、/usr/libexec/platform-python のみです、pythonpython3 コマンドのパスも通っていません。ansible-core 2.17.0 でこのサーバーを対象に実行した場合、最終的に Python インタープリターが見つからないエラーになってしまいます。

これを実際に試しています。

検出された Python インタープリターが分かりやすく表示されるため、ad-hoc コマンド(ansible コマンド)で ansible.builtin.ping モジュールを利用する、というシンプルな方法で検証します。

%  ansible -i inventory.ini rhel84 -m ping 
[WARNING]: No python interpreters found for host rhel84 (tried ['python3.12',
'python3.11', 'python3.10', 'python3.9', 'python3.8', 'python3.7',
'/usr/bin/python3', 'python3'])
rhel84 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "module_stderr": "Shared connection to 192.168.1.99 closed.\r\n",
    "module_stdout": "/bin/sh: /usr/bin/python3: No such file or directory\r\n",
    "msg": "The module failed to execute correctly, you probably need to set the interpreter.\nSee stdout/stderr for the exact error",
    "rc": 127
}

/bin/sh: /usr/bin/python3: No such file or directory というエラーが表示されました。

INTERPRETER_PYTHON_DISTRO_MAP による検出もなく、INTERPRETER_PYTHON_FALLBACK によるフォールバックでも見つからなかったという現象です。

(tried ['python3.12','python3.11', 'python3.10', 'python3.9', 'python3.8', 'python3.7','/usr/bin/python3', 'python3'])

でフォールバックを試みたリストが示されています。

そもそも ansible-core 2.17 系はマネージドノード側は Python 3.7 以上のサポートです。そのため、仮に Python 3.6 である /usr/libexec/platform-python が見つかったり明示指定してもエラーになります(参考)。

そのため、対策方針としては、マネージドノード側に別途 Python 3.7 以上をインストールして作成した環境のパスを INTERPRETER_PYTHON で明示的に指定するのが良いです。

(仮に Python 3.6 がサポート対象だとしても /usr/libexec/platform-python 以外の環境を別途作ったほうが環境がきれいに保てると思います)

参考 ansible-core 2.16 系の場合

比較のために ansible-core 2.16 系で同じ対象に実行した結果を載せておきます。これは正常です。

INTERPRETER_PYTHON_DISTRO_MAP により、/usr/libexec/platform-python が見つかっています。

% ansible -i inventory.ini rhel84 -m ping                                                                     
rhel84 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}

おわりに

ansible-core では 2.17.0 では、マネージドノードで Python 2 のサポートがなくなったり、Python 3系のサポートも 3.7 に引き上がったりしました。

自動検出の仕組みの一部廃止との組み合わせによって、内容含め、Python インタープリター周りのつまずきが出てくるかもしれません。

利用する ansible のバージョンとサポートする Python バージョンを確認しつつ、INTERPRETER_PYTHON で明示的にインタープリターのパスを指定するのが良いかなと思います。

関連

tekunabe.hatenablog.jp

tekunabe.hatenablog.jp

[Ansible] エラー「SyntaxError: future feature annotations is not defined」発生時は Python インタプリターを要チェック

はじめに

ansible-core 2.17.0 で Linux サーバーをマネージドノード(自動化対象)に実行したとき、以下のエラーに出くわしたことがありました。

SyntaxError: future feature annotations is not defined

調べてみると、マネージドノード側の Python が 3.6 しか入っていないことによるものでした。

このエラーが必ずこの原因かはわからないですが、私が出くわした時のことをまとめます。

  • 検証環境
    • コントロールノード
      • ansible-core 2.17.0
    • マネージドノード
      • RHEL 8.5
      • Python 3.6.8 のみ (パスは /usr/bin/python3)

実行

ansible コマンドで ping モジュールを実行するだけで発生しました。

%  ansible -i inventory.yml all -m ping
[WARNING]: Unhandled error in Python interpreter discovery for host vm-sakana: Expecting value:
line 1 column 1 (char 0)
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: SyntaxError: future feature annotations is not defined
[WARNING]: Platform linux on host vm-sakana is using the discovered Python interpreter at
/usr/bin/python3, but future installation of another Python interpreter could change the meaning
of that path. See https://docs.ansible.com/ansible-
core/2.17/reference_appendices/interpreter_discovery.html for more information.
vm-sakana | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "module_stderr": "Shared connection to 192.168.1.228 closed.\r\n",
    "module_stdout": "Traceback (most recent call last):\r\n  File \"/home/adminuser/.ansible/tmp/ansible-tmp-1719059368.2095401-62904-248254909367870/AnsiballZ_ping.py\", line 107, in <module>\r\n    _ansiballz_main()\r\n  File \"/home/adminuser/.ansible/tmp/ansible-tmp-1719059368.2095401-62904-248254909367870/AnsiballZ_ping.py\", line 99, in _ansiballz_main\r\n    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)\r\n  File \"/home/adminuser/.ansible/tmp/ansible-tmp-1719059368.2095401-62904-248254909367870/AnsiballZ_ping.py\", line 44, in invoke_module\r\n    from ansible.module_utils import basic\r\n  File \"<frozen importlib._bootstrap>\", line 971, in _find_and_load\r\n  File \"<frozen importlib._bootstrap>\", line 951, in _find_and_load_unlocked\r\n  File \"<frozen importlib._bootstrap>\", line 894, in _find_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1157, in find_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1131, in _get_spec\r\n  File \"<frozen importlib._bootstrap_external>\", line 1112, in _legacy_get_spec\r\n  File \"<frozen importlib._bootstrap>\", line 441, in spec_from_loader\r\n  File \"<frozen importlib._bootstrap_external>\", line 544, in spec_from_file_location\r\n  File \"/tmp/ansible_ping_payload_4phdfb99/ansible_ping_payload.zip/ansible/module_utils/basic.py\", line 5\r\nSyntaxError: future feature annotations is not defined\r\n",
    "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error",
    "rc": 1
}

いちばん重要なメッセージは最後の方の以下の箇所です。

SyntaxError: future feature annotations is not defined

他にちょっと気にするべきポイントは、"discovered_interpreter_python": "/usr/bin/python3" です。明示的に Python インタープリターを指定しなかったため、Interpreter Discovery 機能によって検出された結果が、/usr/bin/python3 だったということを示しています。

今回のマネージドノードでは、/usr/bin/python3Python 3.6.8 でした。そして、ansible-core 2.17.0 からは、マネージドノードは Python 3.7 以上である必要があるため、Python レベルのエラーが発生していたということのようです。

なお、話はそれますが ansible-core 2.17.0 からは INTERPRETER_PYTHON_DISTRO_MAPディストリビューション/バージョンと Python インタープリタの対応マップ)がなくなったため、RHEL 8 系ですが /usr/libexec/platform-python ではなく /usr/bin/python3 が検出されました。

対策

マネージドノード側の Python のバージョンを上げることにします。

今回はひとまず Python 3.9 にバージョンアップしたことで、エラーはなくなりました。

$ sudo dnf install python3.9 -y
...()...
$ /usr/bin/python3 --version
Python 3.6.8
$ /usr/bin/python3.9 --version
Python 3.9.19
[WARNING]: Platform linux on host vm-sakana is using the discovered Python interpreter
at /usr/bin/python3.9, but future installation of another Python interpreter could change
the meaning of that path. See https://docs.ansible.com/ansible-
core/2.17/reference_appendices/interpreter_discovery.html for more information.
vm-sakana | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3.9"
    },
    "changed": false,
    "ping": "pong"
}

ひっそり、検出された Python インタープリタのパスが /usr/bin/python3.9 になっていることにも注目です。

ansible-core 2.17 では、Python インタープリタを検出する順番

  • python3.12
  • python3.11
  • python3.10
  • python3.9
  • python3.8
  • python3.7
  • /usr/bin/python3
  • python3

となっています。

残った WARNING は、Python インタープリターの検出に任せずに ansible_python_interpreter 変数などで明示指定すれば消えます。明示しておくほうがいいかなと思います。

関連事例

Python 3.9 を指定しているはずなので、同様のエラーが発生することもあるようです。少し特殊で、別の古い Python 環境で respawn した結果、ということのようです。

forum.ansible.com

おわりに

今回に限らないのですが、ansible-core 2.17 では、Python インタープリターの指定周りでときどきつまずくことがあります。

[Ansible] Playbook の実装ポリシーをチェックできる ansible-policy(開発進行中)をためした

はじめに

2024年5月の AnsibleFest 2024 のキーノートでたびたび「Policy as Code」という言葉が出てきました。Policy as Code 自体はほかでも耳にしますが、Ansible の場合は例えば、Playbook 中で指定するAWS インスタンスタイプを制限する、のようなことができるという話でした。コンセプトはふんわり分かったものの、当時はどういう実装の仕方になるのかまではわかりませんでした。

最近、ansible/ansible-policy という、Policy as Code を実現するための実装のリポジトリが公開されたため、実装面の情報がで始めてきました。

Playbook に対するポリシーを YAML で定義するファイルのことを「Policybook」と呼びます。Policybook のサンプルリポジトリも公開されました。

ansible-policy はリポジトリの説明にもあるとおり、現状はプロトタイプとしての実装で、破壊的な変更が起きる可能性も十分あります。バージョン管理もされておらず、PyPi にもありません。そのため、まだ導入する段階ではありません。

README.md にも冒頭に以下の説明があります。

Note: This repository is in prototype phase and under active development with subject to breaking changes.

とはいえ、ちょっと触ってみたい欲があったので触ってみました。あくまで、現時点でこうやったらこうなった、程度です。

ためしたのは、モジュールのオプションのポリシーチェックと、利用コレクションのポリシーチェックです。

  • 検証環境
    • ansible-policy 2024/06/20 の コミットハッシュ f9a80faf2a55aed7d67f368303076b5a8f44b03b 時点
      • 本記事内の各種リンクもこのコミット時点です。どんどん古くなるのでご注意ください
    • ansible-core 2.17.1
    • Python 3.11.3
    • macOS 13.6

環境の準備

前述の通り、まだ PyPi に公開されていないため、リポジトリを clone してからインストールします。

% git clone https://github.com/ansible/ansible-policy.git
% cd ansible-policy
% pip install -e .

また、ansible-poilcy は内部的に OPA (Open Policy Agent) と使っているらしいので、インストールしておきます。

% brew install opa

おためし1: モジュールのオプションのポリシーチェック

このモジュールのこのオプションは、この値しか指定しちゃだめ、のようなポリシーの実現です。

Policybook の作成

Playbook に対するポリシーの定義を Policybook として作成します。

あとででてきますが、ポリシーチェックの実行時は、複数(もちろん1つでも)の Policybook を含んだディレクトリを指定します。そのため、適当(今回は policies ディレクトリの中に Policybook を作成します。

あまり凝ったことを試しても後で変わるかもしれないので、シンプルなポリシーで雰囲気だけつかむようにします。

今回は、examples ディレクトリにあるcheck_pkg.ymlを参考にし、以下のポリシーとします。

  • ansible.builtin.packges モジュールでインストールするパッケージは httpd のみ許可

これを実現する Policybook は以下のとおりです。

pollicies/check_packages.yml:

---
- name: Check for httpd package installation
  hosts: localhost 

  vars:
    allowed_packages:
      - httpd

  policies:
    - name: Check for package name
      target: task
      condition: input["ansible.builtin.package"].name not in allowed_packages
      actions:
        - deny:
            msg: The package {{ input["ansible.builtin.package"].name }} is not allowed, allowed packages are one of {{ allowed_packages }}
      tags:
        - compliance

policies 配下にポリシー(複数可)を指定し、各ポリシーで targettaskplayrole)や、条件、そのときのアクションを指定します。

ansible_policy/policybook/README.md に説明があります。ただ、hosts が一番ピンときていません・・。

condition が一番肝ですかね。 input が唐突に感じましたが、おそらく targettask の場合はタスクを指すという感じだと思います。

Playbook の作成とポリシーチェック(違反あり)

チェック対象の Playbook は以下のとおりです。あえて許可されていないパッケージ git を指定しています。

playbook.yml:

---
- name: Test Play
  hosts: sv
  gather_facts: false

  vars:
    package_list:
      - git     # 許可されていない
      - httpd

  tasks:
    - name: Install Packages
      ansible.builtin.package:
        name: "{{ package_list }}"
        state: present

それでは、ansible-policy コマンドでポリシーチェックを実行します。-p で Playbook、--policy-dir で Policybook を格納したディレクトリを指定します。

% ansible-policy -p playbook.yml --policy-dir policies
TASK [Install Packages] playbook.yml L12-17 ************************************************************************
... Check_for_package_name Not Validated
    The package ["git", "httpd"] is not allowed, allowed packages are one of ["httpd"]

------------------------------------------------------------------------------------------------------------------------------
SUMMARY
... Total files: 1, Validated: 0, Not Validated: 1

Violations are detected! in 1 task

違反(Not Validated)が検出されて、actions 配下で指定したメッセージが表示されました。

Playbook の変数も評価してるのは良いですね。ただし、現時点で試した限り ansible.builtin.import_tasks`ansible.builtin.include_tasks で読み込んだ先の違反は検出できませんでした。

なお、ansible-policy コマンドに --format json をつけると、結果が JSON で表示されます。機械処理させたいときに便利ですね。

% ansible-policy -p playbook.yml --policy-dir policies --format json | jq .
{
  "summary": {
    "policies": {
      "total": 1,
      "violation_detected": 1,
      "list": [
        "Check_for_package_name"
      ]
    },
    "files": {
      "total": 1,
      "validated": 0,
      "not_validated": 1,
      "list": [
        "playbook.yml"
      ]
    }
  },
  "files": [
    {
      "path": "playbook.yml",
      "violation": true,
      "policies": [
        {
          "policy_name": "Check_for_package_name",
          "target_type": "task",
          "violation": true,
          "targets": [
            {
              "name": "Install Packages",
              "lines": {
                "begin": 12,
                "end": 17
              },
              "validated": false,
              "action_type": "deny",
              "message": "The package [\"git\", \"httpd\"] is not allowed, allowed packages are one of [\"httpd\"]\n"
            }
          ]
        }
      ],
      "metadata": {}
    }
  ]
}

Playbook の作成とポリシーチェック(違反なし)

つづいて、違反なしの Playbook で試します。

---
- name: Test Play
  hosts: sv
  gather_facts: false

  vars:
    package_list:
      - httpd

  tasks:
    - name: Install Packages
      ansible.builtin.package:
        name: "{{ package_list }}"
        state: present

ポリシーチェックを実行します。

% ansible-policy -p playbook.yml --policy-dir policies                     
------------------------------------------------------------------------------------------------------------------------------
SUMMARY
... Total files: 1, Validated: 1, Not Validated: 0

No violations are detected

違反がなくなりました。

おためし2: モジュールのオプションのポリシーチェック

今度は、使っていいコレクションのポリシーの実現です。

Policybook の作成

今回は、examples ディレクトリにあるcheck_collection.ymlをベースにします。

ansible.builtinamazon.aws のみの利用を許可することにします。

policies/check_collection.yml:

---
- name: Check for using collection
  hosts: localhost
  vars:
    allowed_collections:  # 利用を許可するコレクション
      - ansible.builtin
      - amazon.aws
  policies:
    - name: Check for collection name
      target: task
      condition: input._agk.task.module_info.collection not in allowed_collections
      actions:
        - deny:
            msg: The collection {{ input._agk.task.module_info.collection }} is not allowed, allowed collection are one of {{ allowed_collections }}
      tags:
        - compliance

condition の条件の書き方が先ほどとは異なりますね。

Playbook の作成とポリシーチェック(違反あり)

examples/check_project/playbook.yml をベースにして、唐突に azure.azcollection コレクションの利用を混ぜます。

---
- name: Provision EC2 instance and set up MySQL
  hosts: localhost
  gather_facts: false
  become: True
  vars:
    region: "your_aws_region"
    instance_type: "t2.micro"
    ami_id: "your_ami_id"
    key_name: "your_key_name"
    security_group: "your_security_group_id"
    subnet_id: "your_subnet_id"
    mysql_root_password: "your_mysql_root_password"
    package_list:
    - unauthorized-app
  tasks:
    - name: Create EC2 instance
      amazon.aws.ec2_instance:
        region: "{{ region }}"
        key_name: "{{ key_name }}"
        instance_type: "{{ instance_type }}"
        image_id: "{{ ami_id }}"
        security_group: "{{ security_group }}"
        subnet_id: "{{ subnet_id }}"
        assign_public_ip: true
        wait: yes
        count: 1
        instance_tags:
          Name: "MySQLInstance"
      register: ec2

    - name: Create a resource group
      azure.azcollection.azure_rm_resourcegroup:     # 許可されていないコレクション
        name: myrg
        state: present

ポリシーチェックを実行します。

% ansible-policy -p playbook2.yml --policy-dir policies 
TASK [Create a resource group] playbook2.yml L32-36 ****************************************************************
... Check_for_collection_name Not Validated
    The collection azure.azcollection is not allowed, allowed collection are one of ["ansible.builtin", "amazon.aws"]

------------------------------------------------------------------------------------------------------------------------------
SUMMARY
... Total files: 1, Validated: 0, Not Validated: 1

Violations are detected! in 1 task

違反が検出されました。

他にできそうなこと

サンプルを見る限り、become を禁止(タスクレベル、プレイレベル) などのポリシーチェックもできるようです。

サンプル

つまりポリシーチェックってどういうこと?

現時点での私の浅い理解ではありますが、「Playbook の実装ポリシーをチェックできる。ポリシーはYAMLで定義でき、Policybookと呼ぶ」ということなのかなと思います。

似たようなものだと ansible-lint を連想しますが、私なりに比較すると以下の通りです。

私が誤解しているかもしれないですし、今後仕様が変わるかもしれない点はご了承ください。

ansible-policy ansible-lint
チェックレベル 実装 文法
ルールの定義 YAML (Policybook) Python

おわりに

まだまだ発展途上ですが、今後もチェックしていきたいと思います。

参考