1 ポイント 投稿者 GN⁺ 4 시간 전 | 1件のコメント | WhatsAppで共有
  • サーバー自動化作業をPythonコードで記述し、SSHで並列実行して、エージェントなしでコマンドを冪等に実行する
  • pyinfraは同一ワークロードでAnsibleより6倍高速を掲げており、geventとSSHベースの同時実行を使用する
  • --dryオプションで適用前にホストごとの変更diffを確認でき、実際の実行時には結果が並列ストリーミングで返ってくる
  • 対象ホストにはshellとSSHだけが必要で、デーモン・状態ファイル・コントロールプレーンがない
  • YAMLに制御フローをエンコードせず、Pythonのループや条件文をそのまま使うコード中心の構成を強調している

主要機能と実行フロー

  • 数千台のサーバー自動化

    • pyinfraはPythonネイティブのagentless自動化ツールで、SSHでコマンドを実行する
    • コマンド実行は並行性、冪等性、速度を重視し、同一ワークロードでAnsibleより6倍高速を掲げている
    • インストールコマンドは $ uv tool install pyinfra である
    • 記載されている基本条件はMIT license、Python 3.10以上、no agents、zero configである
  • デプロイコード例

    • aptfilessystemd操作をPythonコードで読み込み、パッケージのインストール、テンプレートの配置、サービスのリロードを行う
    • 例のコードは nginxcertbot パッケージをインストールし、templates/nginx.conf.j2/etc/nginx/sites-enabled/api に配置する
    • 最後の段階で systemd.service("nginx", reloaded=True) により nginx サービスをリロードする
    from pyinfra.operations import apt, files, systemd
    
    apt.packages(
        packages=["nginx", "certbot"],
        update=True,
    )
    
    files.template(
        src="templates/nginx.conf.j2",
        dest="/etc/nginx/sites-enabled/api",
    )
    
    systemd.service("nginx", reloaded=True)
    
  • インベントリと実行結果

    • インベントリの例では web-01.prod から web-23.prod までのWebホストと、db-01.proddb-02.prod のデータベースホストを構成する
    • $ pyinfra inventory.py deploy.py --limit web コマンドは web 対象のみに絞って実行する
    • 実行出力はインベントリの読み込み、並行fact収集、deploy.py 実行、サマリーの順で進む
    • 例のサマリーでは23ホスト成功、18変更、失敗0、合計2.1秒を記録している
  • 変更前確認

    • --dry はpyinfraが実行するすべての作業についてホストごとのdiffを先に確認できるようにする
    • 実際の実行では結果が並列にストリーミングされ、各ホストの変更数と実行時間が表示される
    • 例の実行では24ホスト中18変更、6変更なし、失敗0、合計2.1秒を記録している

特徴、Ansible比較、原則

  • pyinfraを選ぶ6つの理由

    • Just Python: YAMLやJinja-in-YAMLなしで、実際の制御フローをPythonで記述する
    • Concurrent SSH: geventとSSHベースで同時実行し、同一ワークロードでAnsibleより6倍高速
    • Diff before apply: --dry ですべての変更を事前に確認でき、冪等な作業は再実行時にno-opになる
    • 0 agents: ホストにはshellとSSHだけが必要で、デーモン・状態ファイル・コントロールプレーンがない
    • Scale-ready: 1ホストから10,000ホストまで動作し、並列実行とリアルタイムのストリーミング出力をサポートする
    • Hackable: 10行でカスタム操作を作成でき、shellと通信するdocker、lxc、k8sに接続できる
  • Ansibleとpyinfraのコード比較

    • Ansibleの例は playbook.yml 16行で nginx のインストール、テンプレートのレンダリング、ハンドラーベースのサービスリロードを構成する
    • pyinfraの例は deploy.py 8行で同じ流れをPythonコードで記述する
    • pyinfraの例では files.template の結果の cfg.will_change が真のときだけ systemd.service("nginx", reloaded=True) を実行する
    from pyinfra.operations import apt, files, systemd
    
    apt.packages(["nginx"], update=True)
    
    cfg = files.template(
        src="nginx.conf.j2",
        dest="/etc/nginx/sites-enabled/api",
    )
    if cfg.will_change:
        systemd.service("nginx", reloaded=True)
    
  • 宣言

    • Code > config: ループはループのままであり、制御フローをYAMLにエンコードしない
    • Show, then do: まずdiffを見て、その後に適用することで予期しない変更を避ける
    • Stay out of the way: エージェント、状態ファイル、コントロールプレーンなしでSSHから直接実行する
    • Read like english: 操作は apt.packagesfiles.templatesystemd.service のように名詞と動詞の形で読める
  • 開始コマンド

    • インストールコマンドは $ uv tool install pyinfra である
    • 5分のquickstartを読み、最初のホストをデプロイするよう案内している

1件のコメント

 
GN⁺ 4 시간 전
Lobste.rsの意見
  • pyinfraは、Ansibleが本来こうあるべきだったと思わせる。テンプレート混じりのYAMLに制御フローを付け足す代わりに、自動化をPythonで直接書ける
    Ansibleを長く扱ってきた後だと新鮮で、別にAnsibleが嫌いだったわけでもない

    • 正確にはPython製のAnsibleというより、Pythonをシェルに変換するインタープリタに近く見え、それなりの問題もある
      対象サーバー側でもPythonを使うハイブリッドのほうがよさそうだ。ファイル更新時の引用符地獄が減り、sedの正規表現の限界のような問題も避けられるからだ
  • pyinfraは好きだし、もっと広く使われてほしい
    これまで働いた会社はどこも、Terraformを併用しているかどうかに関係なくAnsibleを使っていて、経験のないツールのために既存の自動化を全部書き直す準備ができているところはなかった
    pyinfraはSysOpsがPythonを知っている必要があるが、個人的にはSysOpsはスクリプト言語をひとつくらい知っているべきだと思う。特にAnsibleでもPythonでモジュールを書けばYAMLの混沌は減らせるが、少なくともフランスでは一般的な考えではないようだ

    • Ansibleはかなり使ってきたが、実際のところスクリプト言語のふりをしたものだと思う
      そこまで激しい論争の種ではないかもしれない
  • ホームラボでAnsibleを使っていたが、だんだん窮屈に感じるようになった。YAML設定はひどく、すべてがハックのように感じられ、速度も悲しいほど遅かった。シェルコマンドをいくつか実行するためだけにサーバーにpython3が必要なのも納得できなかった
    Google AI Modeのおかげでpyinfraを知り、ほぼ1か月使った範囲ではずっと快適だった。利点はAnsibleよりはるかに速く、繰り返しや条件をPythonで書けて、ロールやネストしたディレクトリなしでサーバー側にはシェルさえあればいいことだ。実行前に現在の状態に基づいたプランを作り、-yを付けなければ確認も求める
    欠点は、標準のタスク群がAnsibleのモジュールに比べてかなり小さい部分集合であること、コードがすぐにスパゲッティ化し得ること、そしてif 'web_server' in hosts.groupsのようなやり方もあまり良くないことだ。operation(..., filter_group='web_server')のほうがよいのかもしれない
    最悪なのは、カスタムコネクタの作成があまりにもつらいことだ。pyinfra専用のentry pointが入ったpyproject.tomlが必要に見え、uvを使っても社内コネクタ開発は悪夢のようだ。プロジェクト内の普通のPythonファイルとして作れるべきだ

  • 数日間、pyinfraをホームラボのデプロイツールとして試しているが、Ansibleと比べて今のところ一番気に入っているのはPython構文より速度
    Ansibleはいつも耐えられないほど遅く感じていた

    • この領域は興味深い。私もデプロイツールを作っていて、本業でも実際のデプロイに使っている
      たいていの場所でAnsibleやSaltの利用を置き換えたい
  • コードとしてのインフラが一周したのは面白い。スクリプトからYAMLへ行き、またより洗練されたスクリプトへ戻ってきた
    それぞれのアプローチにはちょうどよい地点があり、Ansibleユーザーの観点から見るとpyinfraはかなり良さそうだ

  • Ansibleを採用する決め手になったのは、ドライランと差分表示モードだった。想定外の作業をしないと確信できたからだ
    でも、pyinfra CLIにはそのようなオプションがないように見える。すべてのオプションをアルファベット順に並べたリファレンス文書を見つけられていないので、見落としているのかもしれない

    • —dryフラグがあり、pyinfraの最初の画面にすぐ出ている
  • 興味のある人向けに、これに似た14年前の自分のプロジェクトもある: https://github.com/sebastien/cuisine/tree/main
    エージェントレスでSSHだけを使い、コア管理機能の上にPythonらしいAPIを載せているが、ドライモードはサポートしていない

  • 私たちはOpenStackでリソースをプロビジョニングするときはAnsibleを使い、それ以外はpyinfraで処理しているが、この数年かなりうまく動いている
    最大の欠点はコミュニティが小さいので、自分で解決策を書くことになる点だ。たとえば、デプロイに必要な共有シークレットはkeyring + privyでディスクに保存し、OpenStackのコンピュートインベントリをhostsデータに変換する数行のコードも自分で書いている