こんにちは、滝澤です。

いくつかのプロジェクトでタスクランナーFabric 2を使う機会がありました。少しですが知見が溜まったので紹介します。 また、Fabric 1.xを利用していた方は互換性も気になると思いますでのその点についても紹介します。

記事が長くなったので3編に分けます。

本記事は前編の「Fabricの概要」になります。

なお、執筆時点(2018年11月21日)での最新バージョンはFabric 2.4.0、Invoke 1.2.0です。 動作確認はPython 3.7.1にて行っています。

Fabricの概要

FabricはSSH経由でリモートシェルコマンドを実行するPythonライブラリです。 タスクランナーとして利用できます。

Fabricの簡単な理解のために、実行例を紹介します。

次のような内容のfabfile.pyというファイルがあるとします。unameという名前のタスクを定義しています。

from fabric import task

@task
def uname(c):
    """Execute uname."""
    result = c.run("uname -n", hide=True)
    print(result.stdout.strip())

Fabricをインストールすると提供されるfabコマンドで次のようにタスクunameを実行すると、ホストhost01にSSH接続してコマンド"uname -n"を実行します。さらに、コマンドの実行結果の標準出力をPythonの関数print()で出力します。

$ fab -H host01 uname
host01

この例では1個のコマンドを実行しましたが、複数のコマンドをまとめて実行することもできます。 コマンドの実行結果の終了コードや標準出力・標準エラーも処理できます。 そのため、定型作業や時々実行する作業で実行するコマンドをタスクとしてまとめておくと便利です。

次のように定義したタスクの一覧を取得することもできます。

$ fab --list
Available tasks:

  add-user     Create a new user account.
  delete-user  Delete a user account

また、FabricをSSH経由でリモートシェルコマンドを実行するPythonライブラリとして利用することもできます。 Pythonで書かれたアプリケーション中でFabricのライブラリを利用すると、リモートのホストにSSH接続して、シェルコマンドを実行して、その結果を処理するといったことができます。

from fabric import Config, Connection

def get_uname(hostname, config=None):
    """Execute uname."""
    c = Connection(hostname, config=config)
    result = c.run("uname -n", hide=True)
    uname = result.stdout.strip()
    return uname

なお、本記事では執筆時点(2018年11月21日)での最新バージョンFabric 2.4.0について説明します。 バージョン1系と区別するために、バージョン2系以降のことを本記事ではFabric 2と記述しています。

後述しますが、Fabric 2は関連するプロジェクトのタスクランナーInvokeのSSHラッパーです。そのため、Fabricを利用するためにはInvokeの理解が必要となります。そのため、Invokeの使い方については中編で説明しています。 Invokeへの理解ができた上で、Fabric 2の使い方については後編で説明します。

Fabric 1.xとFabric 2

Fabric 1.xを使ったことがある人はご存じだと思いますが、Fabricは最近(2018年5月)までPython 3に対応していませんでした。 そのため、非公式のPython 3対応のフォークであるFabric3が開発されてきました。

2018年5月18日にPython 3対応(2.7および3.4以降対応)のFabric 2.0.0がリリースされました。これでやっとPython 3でFabricが利用できるようになりました。

しかし、Fabric 2はFabric 1.xをそのままPython 3対応にしたものではありません。 関連するプロジェクトのタスクランナーInvokeのSSHラッパーとして作り直されたものでした。ちなみに、SSHライブラリにはParamikoを利用しています。

さらに、Fabric 1.xの全ての機能がFabric 2に実装されているわけではありません。また、環境設定の方法もライブラリの使い方もfabコマンドの使い方も異なります。 詳しくは「Upgrading from 1.x」をご覧ください。 そのため、Fabric 1.x用に作成したスクリプトはそのままでは動きません。

個人的な感想としては、Fabric 1.xとFabric 2は全く別物と考えた方が幸せだと思います。 Fabric 1.xで機能があったのに、Fabric 2.xには何でその機能が無いんだとイライラするのは不幸です。 Fabric 1.x用のスクリプトをFabric 2に移行するのは完全に作り直すくらいの作業工数を想定した方が無難です。 さらに言うと、用途によっては他の選択肢も検討してもよいです。例えば、デプロイツールとして利用したい場合はAnsibleを検討してみてもよいと思います。

目次

参考サイト

株式会社ハートビーツのインフラエンジニアから、ちょっとした情報をお届けします。