2015-10-15

そんなスケジューラで大丈夫か? Rundeck超入門(基礎編)

こんにちは、記事の更新頻度が安定しません。

Rundeckの記事を書くことを今季の目標としてしまったために(勝手に)追い詰められながら記事を書いています。

まぁやるからにはちゃんと書きます。Rundeckは機能が多いから時間がかかるのは仕方ないでしょう?俺は悪くない。

info
  • この記事はRundeckの概要・用語・主な使い方について書きます。
  • 内容はリファレンスっぽい感じに仕上がっているので実際に使いながら参照することをオススメします。
  • DockerでRundeckをちょっとだけ試してみたかった でセットアップできます。
  • この記事はRundeck 2.5.3 を使用しており、バージョンによっては動作が異なる可能性があります。

概要

Rundeckは一言で言うと「すごいcron」です(ドドーン

hirokiky氏shimizukawa氏 の発表でもそう言っていたからいいよね?

少しだけ補足します。

RundeckはWebアプリ上で操作できるJava製のスケジューラです。

WebUI上から操作・閲覧できるというのは当然ですが、他にも以下のようなメリットが挙げられます。

他にもあると思うけど、これだけあれば使う意味は十分にありますよね?

ちなみにky氏の発表スライドはこちら: 価値を届ける技術 #bpstudy 96 (35ページ目辺りから)

shimizukawa氏のスライドはこちら: Rundeck better crond

この記事でも大体のニュアンスは詰め込みました。

以下の記事も参考にさせていただきました。

すばらしい記事・スライドに多謝。

用語

概要はこのくらいでいいですよね。次はRundeckを知る上で必要な用語を見ていきましょう。

プロジェクト

ジョブをまとめる単位がプロジェクトです。

本番環境/開発環境/ステージング環境/案件のサブプロジェクト等の単位でプロジェクトを分けるのが一般的だと思います。

ジョブ

Rundeckがスケジューリング可能な実行単位です。これは特定のプロジェクトに紐付きます。

別プロジェクトのジョブを実行することはできません。

ジョブは1つ以上のステップを持ちます。

ジョブの実行結果はあとから閲覧できます。

ジョブのステータス

実行後のジョブ履歴は以下のいずれかのステータスを持ちます。

成功
    • 処理の成功を意味するステータスです。強調します。「成功」を指すのはこのステータスのみです。
    • 後述する 成功率の表示成功通知 もこのステータスをアテにしています。
失敗
    • 処理の失敗を意味するステータスです。
中断
    • 処理が途中で中断した場合のステータスです。画像の表示上では「Killed」となっていますがこの場合の終了ステータスは「Aborted」です。
    • 正確に言うと「Killed」は中断ステータスの1つで ジョブの強制終了 によって終了した場合には表示上でこのようになるんだと思います。
タイムアウト
    • タイムアウト によって処理が終了した場合に、このステータスとなります。
リトライ?
  • 画像なし
    • 確かに存在はするようですが、これの発生条件は表面上触っているだけではわかりませんでした。
    • 「リトライして最終的に失敗」「リトライして最終的に成功」のいずれかと思ったんですが、どうやら違うみたい。
    • なくてもそんなに困らない(負け惜しみではない)

ステップ

ステップはジョブを構成する最小単位です。

大抵はコマンド、複数行のコマンドはシェルスクリプトとして登録します。やることは同じですけどね。

その他、ジョブをステップとして利用することもできます。

ノード

ノードはジョブを実行する対象ホストです。

これもプロジェクトに紐付くため、別プロジェクトのノードを利用することはできません。

対象ノードの振り分けはジョブ単位で設定されることを理解してください。 処理ごとに対象ノードを変えたい場合、ステップではなくジョブ単位で分離する必要があります。

キー

全プロジェクトを横断して参照可能なノードへの認証情報です。

キーはどのプロジェクトからも参照でき、どのノードに対しても設定可能です。

登録可能なキーは「秘密鍵」「パスワード」「公開鍵」があります。

「秘密鍵」に関しては秘密鍵ファイルを設置してもそのまま指定できるので無理にキー登録する必要はありません。

RundeckのWebUIから管理できるというメリットはありますが。

「パスワード」はノードの登録ファイル(resources.xml)に直接指定できないのでキー登録したほうが圧倒的に使いやすいです。圧倒的感謝。

キーを使わない場合、ジョブのセキュアリモート認証 という機能をつかって指定する必要があります。これはすべてのジョブで指定する必要があるのであまり推奨できません。

キーの登録方法

ユーザ

Rundeckを操作するためのユーザ(アカウント)です。ユーザの追加はRundeckのUI上からは行えません。

通常は $RDECK_BASE/realm.properties にユーザを追加すれば十分です。

デフォルトでは admin: admin,user,admin というユーザのみが登録されています。

パスワードにはハッシュ化したものを指定することもできます。

例えば、admin3ユーザにハッシュ化したパスワード「admin3」を作るためには以下のようにします。

[vagrant@localhost ~]$ java -cp /var/lib/rundeck/bootstrap/jetty-all-7.6.0.v20120127.jar org.eclipse.jetty.util.security.Password admin3 admin3 admin3 OBF:1igd1unp1vgj1vgb1uo91idt MD5:32cacb2f994f6b42183a1300d9a3e8d6 CRYPT:adNjjKXvSro/A

MD5でハッシュ化する場合は admin: MD5:32cacb2f994f6b42183a1300d9a3e8d6,user,admin のように指定します。

もちろん OBF:1igd1unp1vgj1vgb1uo91idt といったものも指定可能です。どうゆうハッシュ関数かわかってないけど。

LDAP による管理も行えるようです。

いつか挑戦してみたいですね。 ユーザには以下の権限があるようです。

user

ログインするための権限です。

admin

管理者権限です。この権限があるとプロジェクト(後述します)の作成、および、すべてのプロジェクトを操作できます。

逆にこの権限を持たない一般ユーザは許可されたプロジェクトしか閲覧・操作できません。

admin権限はuser権限の上位互換ではないため、これだけの記述ではログインできません。

その他

architect,deploy,buildという権限が存在しているようですが、何に使うものかわかりませんでした。

参考になりそうな情報を知っている方はぜひ教えてくださいm()m

概念図

言葉だけではわかりにくいかもしれないので以下に簡単な概念図(例)を用意しました。

解説
  • プロジェクト1 に
    • ジョブ1 が登録されている。 ジョブ1 には
      • ステップ1 が登録されている。 ステップ1 は ジョブ2 を実行する。
      • ステップ2 が登録されている。 ステップ2 は キー1 を用いて ノード1 に SSH ログインし sleep 5 を実行する
      • ステップ3 が登録されている。 ステップ3 は キー1 を用いて ノード1 に SSH ログインし echo 'ステップ3だよ!' を実行する
    • ジョブ2 が登録されている
      • ステップ4 が登録されている。 ステップ4 は キー2 を用いて ノード2 に SSH ログインし echo 'ステップ4だよ!' を実行する
  • プロジェクト2 に
    • ジョブ3 が登録されている ジョブ3 には
      • ステップ5 が登録されている。 ステップ5 は キー2 を用いて ノード2 に SSH ログインし sleep 5 を実行する
      • ステップ6 が登録されている。 ステップ6 は キー2 を用いて ノード2 に SSH ログインし echo 'ステップ6だよ!' を実行する
  • キー1 は Rundeck の全プロジェクトから参照できる。 鍵認証をするときに利用する。
  • キー2 は Rundeck の全プロジェクトから参照できる。 パスワード認証をするときに利用する。
  • キー3 は Rundeck の全プロジェクトから参照できる。 何に使うかよくわからない。
  • admin というログインユーザが登録されている。 Rundeck に対して全権限を持つ
  • user という ログインユーザが登録されている。 許可されたプロジェクトのみを操作、閲覧できる。

プロジェクト

ジョブは特定のプロジェクトに紐付くため、先にプロジェクトを作成する必要があります。

必須項目は「プロジェクト名(Project Name)」だけで画面最下部の「Create」ボタンを押せば、ひとまずプロジェクトは作成されます。(プロジェクト作成の設定項目は詳しく調べてないので書きません)

作成が完了するとデフォルトで $RDECK_BASE/projects/ のパスにプロジェクト名のディレクトリが作成されます。

project.name=testproj resources.source.1.config.requireFileExists=true project.ssh-authentication=privateKey service.NodeExecutor.default.provider=jsch-ssh resources.source.1.config.includeServerNode=true resources.source.1.config.generateFileAutomatically=true resources.source.1.config.format=resourcexml resources.source.1.config.file=/var/rundeck/projects/testproj/etc/resources.xml project.ssh-keypath=/var/lib/rundeck/.ssh/id_rsa project.description=test project service.FileCopier.default.provider=jsch-scp resources.source.1.type=file

ただし、このままは「localhost」でのみ、つまりRundeckがインストールされているホスト上でしかジョブを実行できません。

ノードの登録

RundeckのノードはWebUI上から追加できません(よね?)

操作対象のノードは $RDECK_BASE/projects/${project.name}/etc/resources.xml に記述されます。(以下リソースファイルという

パスは変更でき、フォーマットは XMLYAML が使えます。

XML

デフォルトはXML形式です。

以下は node1, node2 というホストを登録する例です。

<?xml version="1.0" encoding="UTF-8"?> <project> <node name="node1" description="target node1" tags="" hostname="192.168.34.78" osArch="amd64" osFamily="unix" osName="Linux" osVersion="3.10.0-123.el7.x86_64" ssh-authentication="privateKey" ssh-key-storage-path="keys/privatekey/node1.pem" username="vagrant" /> <node name="node2" description="target node2" tags="" hostname="192.168.34.90" osArch="amd64" osFamily="unix" osName="Linux" osVersion="3.10.0-123.el7.x86_64" ssh-authentication="password" ssh-password-storage-path="keys/password/vagrant-password" username="vagrant" /> </project>

YAML

YAMLでも表現可能です。 その場合、 project.propertiesresources.source.1.config.format=resourceyaml を指定します。

以下は node3 を登録する例です。

node3: description: target node3 hostname: 192.168.34.78 nodename: node3 osArch: amd64 osFamily: unix osName: Linux osVersion: 3.10.0-123.el7.x86_64 tags: '' username: vagrant ssh-authentication: privateKey ssh-keypath: /vagrant/.vagrant/machines/node3/virtualbox/private_key

ノードの登録が終わるとプロジェクトのノード一覧で確認できます。これについては後述します。

キーの登録

キー はRundeckが共通で参照できる認証情報でしたね。 (プロジェクト単位ではありません)

各ノード設定にKeyを指定すると認証に利用できます。 キーの作成は以下のような手順で行います。

  1. 右上のギアマークから設定に移動して、「Key Storage」を選択します。
  2. 「Add or Upload a Key」をクリックするとモーダルが起動します。
  3. Key Type: を選択します。 Private Key は秘密鍵、 Password はパスワードを登録できます。
  4. 登録したい鍵を入力します。手入力もできますし、実際の鍵ファイルをアップロードすることもできます。
  5. Storage path: は必須ではありません。入力したパスによってディレクトリが区切られます。省略するとフラットにKeyが置かれます。
  6. Name: にKey名を入力します。
  7. Save をクリック!

作成されたキーファイルの保存パスは以下のように表示されます。

キーの指定方法はさりげなく XMLのnode登録 で紹介しています。

秘密鍵の場合は ssh-key-storage-path パスワードの場合は ssh-password-storage-path に指定します。

ちなみに YAMLのnode登録 ではキーを使わずに秘密鍵ファイルを直接参照しています。

(なんかVagrantのバージョンが上がって毎回鍵ファイルが変わるとか何とからしいので、覚えておいて損はない)

warning
  • 鍵ファイルの所有者およびパーミッションには十分注意してください。
  • rw------- (600) でrundeckの実行ユーザが見られれば問題ないっす。

ジョブの作成

ジョブを作成するにあたり、それぞれの項目について説明します。

ジョブ名

ジョブを識別するための名称です。

入力は必須ですが、一意である必要はありません。

一意性は後述するUUIDによって管理されます。

グループ

ジョブがファイルだとするとグループはディレクトリに相当します。

指定したグループが存在しない場合グループは動的に生成され、既存のグループを指定した場合は同じグループにジョブが入るという感じです。

グループだけを作成することはできず、ジョブを持たないグループは存在できません。

/(スラッシュ) でグループを階層構造にすることができます。これもディレクトリと同じですね。

ジョブの説明

グループの説明です。入力は必須ではありません。

マルチバイト文字の入力(未変換の先頭文字)が化けるという現象が確認されていますが、確定しちゃえば特に問題ないです。

オプション

環境や状況に応じて、処理に指定するパラメータを変更したくなるというのはよくある話ですね。 こういった箇所はオプションとして定義しましょう。

例えば、日次のバッチでは対象日付が「入力されなかったら常に前日を対象」、「入力された場合はその日付を対象」といった使い分けができますね。 他にも対象ホスト、対象ファイルなど状況・環境に応じて手動で指定する可能性がある箇所はオプションにすると便利です。

残念ながら複数のジョブにまたがるオプションというのは書けず、一つ一つ定義するしかありません。

新規でオプションを追加する場合は「Add an Option」です。

オプション名

オプション名を半角英数字で指定します。数値だけのオプション名も可能です。

1つのジョブ内での重複は許されません。

説明

オプションに関するヘルプをお好きなように書いてください。

初期値

オプションの初期値を入力します。入力は必須ではありません。

入力型

プレーン
  • 平文「type="text"」の入力フィールドです。これがデフォルトです。
セキュア
  • 「type="password"」の入力フィールドです。入力文字列がそのまま表示されません。
  • Rundeckではジョブの実行、その時に渡したオプションをDBで管理していますが、この入力型を選ぶとDBに保存されません。
セキュアリモート認証
  • このオプションは特殊です。(公式の日本語ドキュメントはなくなってました)
  • ノード実行するための組み込みの SSH プロパイダは SSH, Sudo 認証メカニズムのため、パスワードを利用します。

    パスワードはジョブ内に定義されたセキュアリモート認証オプションで供給することができます。

    セキュアリモート認証オプションは平文・セキュアオプションと比較していくつかの制約を持ちます。

    通常のスクリプトとコマンドオプション値の展開にユーザが入力した値を使うことはできません。

    言い換えると、このオプションはリモート認証のためにしか利用できません。

  • だめだわからん。いや、なんとなくはわかる。
  • どうやらSSHやsudoなどのパスワードを求められた際の入力に使用できるみたいですね。 とはいえ、単に入力しただけでばっちりうまくいくわけではありません。
  • resourcexml(またはresourceyml)に受け取るオプションとパスワード認証を使用する旨を記述する必要があります。

選択肢

選択肢の提示です。指定方法は以下の2種類があります。

List
  • ,(カンマ) 区切りの文字列を入力します。これがデフォルトです。
  • 以下のことに注意しましょう。
    • 選択肢文字列前後の半角スペースは無視される。
    • 空文字や半角スペースのみの文字列は選択肢にできない。
    • 選択肢にカンマを含めることができない。 "(ダブルクォート)'(シングルクォート) で囲ってもダメ。
      • (バッククォート) でカンマのエスケープもできない。
Remote URL
  • 外部から入力可能な値(JSON)を受け取る方法です。状況に応じて選択肢を変更したい場合に使うことになるでしょう。

  • JSONの取得は閲覧しているブラウザではなくRundeckのホスト経由で行われます。

  • ブラウザから閲覧可能なJSONであっても、Rundeckホストから閲覧不可能であれば選択肢として表示できない(はず)です。

  • APIとして提供したいが一般の閲覧を制限したい場合は、GETパラメータにトークンを持たせたりIP制限するのがよいでしょう。

  • JSONのフォーマットは以下の3種類があります。

  • 配列
    • ["x value for test","y value for test"]

      配列型の場合、選択肢に表示される値と入力欄の値が同じになります。入力された順番で表示されます。

  • オブジェクト(ハッシュ)
    • { "Name": "value1", "Name2":"value2" }

      オブジェクト型の場合、選択肢に「key」、入力欄に「value」が表示されます。 ご覧の通り選択肢の順番は「key」文字列の昇順となります。ハッシュだから仕方ないね。

  • オブジェクトの配列
    • [ {"name":"X Label", "value":"x value"}, {"name":"Y Label", "value":"y value"}, {"name":"A Label", "value":"a value"} ]
    • 「順番は指定通り」「選択肢と入力欄を分けられる」という2つのメリットを組み合わせた記述方法です。
    • その他詳しく知りたい方は Configuration を参照してください。

入力値制限

入力された値が適切かどうかの判断方法を指定します。

なし(None)
  • どのような値も指定可能です。これがデフォルト。
選択肢に含まれる値のみ(Enforced from Allowed Values
  • 選択肢 の入力を強制させます。選択肢にない入力をするとエラーになります。
  • 逆に言うとこれを選択しないと入力値以外の値をオプションとして入力できるということになりますね。ここ、勘違いポイントな気がするので十分に気をつけてください。
正規表現(Match Regular Expression )
  • 入力可能な値を正規表現で指定します。これがあれば大半は何とかなるでしょう。
  • 選択肢に List入力 を選択している場合、すべての選択肢を満たすような正規表現を書く必要があります。
  • 条件を満たさない場合、実行時点で以下のようなエラーが発生します。
  • error
    • Option 'a' doesn't match regular expression [0-9], value: a
  • 数値の範囲制限とかはないんですかね?結構需要あると思うんだけど。

省略可否

オプションの入力を省略できるか否かです。

半角スペースは入力に含まれます。デフォルト 可能 です。

値を複数受け取るか

有効にするとオプション入力UIが変化し、複数の値を受け取れるようになります。 複数受け取った値を連結するための文字(列)を Delimiter に指定します。

デリミタに , 入力値を a, b, c とした場合、 それぞれのステップには a,b,c と行った文字列がオプションとして渡されます。

Delimiter入力必須 で2文字以上の文字列でも構いません。

warning
  • 「入力された値を特定の文字で分割して複数値として扱う」ではありません。
  • (私は最初そう思い込んでました

オプションの説明はこれで終わり.

処理の流れ

さて、ジョブの中核です。ステップを列挙してジョブを構成していきます。

ここには入力項目がたくさんあります。

ステップの継続設定

失敗したステップで処理が終了してほしい時は Stop at the failed step.

失敗したジョブは置いておいて、残りのジョブを実行したい時は Run remaining steps before failing. を選択します。

後者を選択した場合であっても、途中で失敗した場合ジョブのステータスは失敗となることに注意してください。

ステップの実行規則

この時「ノードごと(Node-oriented)」に実行するか、「ステップごと(Step-oriented)」に実行するかを選択できます。

ステップを「A」「B」「C」とすると、それぞれの実行順は以下のようなイメージです。

  • ノードごと(Node-oriented)
    • node1 に対して
      • A を実行
      • B を実行
      • C を実行
    • node2 に対して
      • A を実行
      • B を実行
      • C を実行
  • ステップごと(Step-oriented)
    • A を実行
      • node1 に対して
      • node2 に対して
    • B を実行
      • node1 に対して
      • node2 に対して
    • C を実行
      • node1 に対して
      • node2 に対して

ステップの追加

ステップには以下の種類があります。

コマンド(Command)
  • シェルのコマンドを実行します。おそらく一番多用する形式になるでしょう。
スクリプト(Script)
  • 複数行のシェルコマンドやスクリプトを実行するのに適した形式です。
  • 単純なシェルスクリプトを実行できるのはもちろん、 先頭行にshebang(たとえば !/usr/bin/env python)などのようにインタプリタを指定して実行することもできます。
  • 当然ながら実行対象のホストでそのインタプリタがインストールされていることが前提です。
  • 指定がない場合はシェルスクリプトとして実行されます。
スクリプトのパスかURL(Script file or URL)
  • パスかURLに該当したスクリプトファイルを実行します。
  • パスを指定する場合、Rundeckを実行中のユーザがスクリプトファイルの閲覧権限が必要です。
  • 実行権限は必要ありません。
ジョブ参照(Job Reference)
  • ジョブをステップとして実行するための形式です。ジョブ名で指定します。

  • 指定した名称のジョブが存在しないとエラーになりますが、該当するジョブが複数存在しても一意に特定できないためかエラーになります。

  • error
    • Job [test] not found, project: testproj
  • また、自分自身のジョブを循環参照させてはいけません。 ジョブの登録・編集の時点で警告はでませんが、これも以下のように実行時にエラーとなります。

  • error
    • Request: /execution/tailExecutionOutput?format=json

      Message: null

      Caused by: null

      Class: ExecutionController

      (これ、エラーメッセージとしてはわかりづらいですよね)

  • ジョブ参照によってジョブを実行する場合、 同時実行 の制御が効きません。

  • 他ステップの状態 を参照して、ジョブの実行を制御する機能があるため、 直接実行しているジョブ以外で同時実行を制御したい場合はこちらを利用するとよいでしょう。

引数(Arguments)
  • -option1 value1 -option2 value2 のようにジョブに渡したいオプション値を指定することができます。
実行位置(Run as a)
  • ステップ(参照しているジョブ)の実行位置という認識で大体あっていると思います。

  • 「Node Step」はノード毎にステップを実行します。

  • 「Workflow Step」はステップを設定した位置で一度だけ実行されます。

  • 似たような設定が ステップの実行規則 でもありましたね。

  • 組み合わせによって実行順が若干変化します。

  • 言葉ではわかりづらいですよね。ぼくも説明しづらいです。でも頑張って理解してください。

  • 以下のようなジョブがあったとします。

    1. [Command] echo 1
    2. [Job Ref] testジョブを参照 (testジョブは echo test コマンドがあるだけ)
    3. [Command] echo 3
  • このジョブの実行位置(Run as a)、 および実行規則(Strategy)の変化によるステップの実行順は以下のようになります。

    Run as/Strategy
      • Node-oriented
      • Step-oriented
    Node Step
    Workflow Step
  • 「Workflow Step」を選択すると強制的に「ステップごと」の実行に固定されるようです。

  • 「Node Step」と「ステップ毎の実行」は組み合わせる価値がほとんどなさそうですね。

ファイルのコピー
  • Rundeckノードのファイルをコピーします。コピーはリモートホストへだけでなく、ローカルホストに対しても行われます。 srcとdestに同じファイルパスを指定するとファイルが空になるので十分に注意してください。
  • バリデーション欲しいこれ。
ローカルコマンド
  • Rundeck(local)上でのみ実行するコマンドです。
  • ただし、対象ノードが複数ある場合ノードの数だけ(ローカルで)実行されるということに注意してください。
  • ローカルで1回だけ実行したい場合はジョブに隔離し、呼び出すことで表現できます。

エラーハンドリング

ステップが失敗した場合に実行する処理を指定できます。

やることは ステップの追加 と同じです。

処理の継続可否(Keep going on success)
  • エラーハンドリングを設定してもステップの終了ステータスが失敗であれば、ジョブの実行はそこでストップしてしまいます。
  • このオプションを有効にするとエラーハンドリングの処理が成功した時点で終了ステータスが成功となり、処理を継続することができます。
  • ステップの継続設定 にて Run remaining steps before failing を設定した場合、 エラーハンドリングの処理が失敗しない限りステータスは成功となります。
  • この挙動が仕様として正しいかどうかはわかりません。

ワークフロー制御

ジョブを任意のタイミングで終了するのに利用されます。

正常終了(Halt)
  • 終了ステータスに入力したステータスでジョブを終了させます。
異常終了(Fail)
  • こちらをチェックした場合、終了ステータスの入力及び 正常終了 のチェックは無視されます。
  • 片方しか意味ないならチェックボックスじゃなくてラジオボタンにするべきじゃないですかね。。?
終了ステータス
  • カスタマイズされた終了ステータスです。(以降正式名称は不明だがカスタムステータスという)省略した場合は強制的に異常(エラー)終了となります。
  • もともとRundeckが持っているステータスを選択すると「Failed」となるようです。 (以降あってるかわからないけど ビルトインステータス という。正しい呼称を知ってる人は教えてね!)
ステップの説明(Step Description)
  • ジョブの定義に表示される説明です。ログに出力されるわけではありません。
  • いずれの終了方法を選んだ場合でも、複数ノード存在しても終了メッセージの表示は一度だけです。

ジョブの実行状況

ジョブ名(Job Name)かUUID(Job UUID)によって一意に特定されたジョブの状態を見てジョブを制御するステップです。

いずれかの入力は必須ですが、当然バリデーションはありません。

空のまま保存しちゃうと実行時に以下のエラーがでます。

error
  • Configuration invalid: jobUUID or jobName is required
実行中(Running)
  • 参照しているジョブが「実行中」であるかどうかを判断する設定です。
  • 「true」は「実行中であること」、「false」は「実行中でないこと」を期待します。
実行ステータス(Execution State)
  • 指定したジョブの最終実行ステータスに期待する値を記述します。
  • 右のセレクトボックスから ビルトインステータス を選択することもできますし、入力した値を変更することも可能です。
  • Running か、こちら、いずれかの入力が必須です。
    • Never というのはステータスというより、まだ一度も実行されていないという意味です。
実行ステータス条件(Condition)
  • 「Equals(一致する)」か「Not Equals(一致しない)」かのいずれかです。

残りの設定項目はワークフロー制御と同じです。

重要なのはこの条件を満たしたときには処理は成功(Success)となり、 満たさなかったときは 指定した 実行ステータス によって終了するという点です。

実行ノード

実行対象のノードを指定します。デフォルトでは「(ローカル)Execute locally」のみです。

「Dispatch Node」を選択するとノードの選択UIが展開されます。

フィルタ

入力した正規表現と一致したノードが抽出されます。 このとき抽出されるノードはプロジェクトに登録されているノードに限定されます。

「Matched Nodes」に該当したノード名が出力されます。 すぐに反映されない場合は「refresh」ボタンを押してみてください。

このことから分かるとおりノードにつける名前は重要です。 同じジョブを実行させるノードであれば、同じプレフィックスをつけるなどすれば、簡易な正規表現ですべてのノードを抽出できますね。シンプルで壊れにくい設定を目指しましょう。

並列ノード数

対象ノードが複数存在する場合の並列数です。

デフォルトは 1 で直列実行します。

ノード属性による実行順序制御

そもそも属性ってなんだって話だって思った方もいるでしょう。 Rundeckにおける実行ノードはリソースファイルによって管理しているという話を先ほどしました。

ノードには任意の属性値を指定することができます。その属性値の値を元に実行順を設定できるというわけです。 リソースファイルの変更は即座に反映されるため、再起動は必要ありません。

昇順・降順

昇順は「Ascending」、降順の場合は「Descending」です。

昇順がデフォルト。

ノードの継続設定

ステップが失敗した場合、別ノードのステップを実行するかという設定です。

ステップの継続設定 という設定にて失敗時に残りのステップを続行する選択肢がありましたね。

両方を選択することによってすべてのステップを網羅できます。

以下のコマンドを「node1」「node2」に対して実行する例で検証してみましょう。

  1. echo 1
  2. false
  3. echo 3
Step/Node
    • stop
    • run
stop
run

いずれを有効にしても途中の処理が失敗すればジョブの終了ステータスはやはり「失敗」となります。

処理の継続可否でも記述しましたが、 失敗するステップに対してエラーハンドリングを設定することにより終了ステータスを「成功」させることができます。

この場合ジョブのステータスは成功となるため、ノードの継続設定は必要ありませんが、 すべてのノードのすべてのステップを絶対に実行したいような場合は設定しておくのが無難でしょう。

通知

デフォルトは「No」、つまり通知なし、「Yes」にチェックを入れると設定項目が展開されます。

どうでもいいことですが「Yes」を選んで通知設定せずにSaveすると「No」に戻ります。

通知するタイミングは以下の3種類です。

成功時(On Success)
  • ジョブのステータスが成功のときにのみ発動します。
失敗時(On Failure)
  • ジョブのステータスが成功のとき以外に発動します。
  • 失敗以外のカスタムステータスやタイムアウトでも発動します。
開始時(On Start)
  • ジョブのステータスにかかわらず、ジョブの開始時に発動します。
  • それぞれの条件で以下の動作をとることができます。

メール送信

Toには送信先のメールアドレスをカンマ区切りで入力できます。(CCやBCCの設定は見つからなかった)

Subjectはご存知の通りメールタイトルです。

いずれのフィールドからも コンテキスト の参照が可能なようです。

例えば失敗通知でタイトルに度のステータスで失敗したかを通知したければ ${notification.eventStatus} とすればできるようです。

この項目は地味に Custom Email Templates に載っていました。

Webフック

取得したWebフックのURLを指定します。ここではコンテキストの参照はできません。

slackの通知をするためには プラグイン が必要です

諸事情により手元では設定できなかったので設定手順は書きません。

定期実行するか

「No」だと手動で選択しない限り実行されません。これがデフォルトです。

「Yes」の場合、以下の指定方法により定期実行されます。

Simple
  • 指定した「時刻」「曜日」「月」に一度実行する指定方法です。
  • 「曜日」「月」はデフォルトですべてが指定されており毎日実行されますが、チェックを外すと特定曜日、特定月だけ実行が可能です。
Crontab
  • cronライクな記述によりSimpleでは実現できない「5分間隔で実行」「1時から5時まで」「5分と30分に実行」などの複雑な指定が可能です。

  • 本家のcronフォーマットに加え、秒(Second)、年(Year)の指定が追加されているので既存のcronルールをそのまま移植できない点に注意してください。

  • カーソルを当てるとテキストボックスの右にフィールドの案内がでるのでそれにしたがって入力してください。

    cron
      • 分(m)
      • 時(h)
      • 日(d)
      • 月(M)
      • 曜日(w)
    Rundeck
      • 秒(s)
      • 分(m)
      • 時(h)
      • 日(d)
      • 月(M)
      • 曜日(w)
      • 年(y)

cron記法についてわからない方はググってください。

ログレベル

Debugを選択すると実行時のログに詳細な情報が出力されます。

通常は「Normal」となっており、これで十分でしょう。

同時実行可否

ジョブを同時に実行できるか否かです。

デフォルトで「No」。同時実行 不可 です。

同時実行しようとすると以下のようなエラーが発生します。

error
  • Job "test" [5460a29f-b1f0-4cdb-a9e2-82b157547510] is currently being executed (execution [[187]])

タイムアウト

ジョブの制限時間です。ジョブの実行が設定した時間以上かかる場合にエラー終了させる機能です。

0か空白の場合はタイムアウト設定は無効となり、数値の後ろにつける文字によって、時間の単位が変わります。

m
  • 分(m)
h
  • 時間(H)
d
  • 日付(D)

そのほか、大文字の「M」を指定した時は分(m)や秒(s)とは違う結果になりました。

もしかしたら月(Month)かもしれませんが、そんな長い期間のタイムアウトは検証していません。

ステップごとの時間ではなく、ジョブ全体の時間であることに注意してください。

ステップの実行に多少オーバーヘッドがあることを見込んで設定するようにしましょう。

リトライ

ジョブが失敗した場合に再実行する機能です。 当たり前の話かもしれませんが、再実行されるジョブは失敗したジョブとは別に実行され、ログも別途出力されます。

失敗とはシェルの実行ステータス($?)が 0 以外の場合を指します。

warning
  • バッチを何らかの言語で自作する場合、 何も考えずに例外(エラー)をキャッチし正常終了させると0が返却され、Rundeck側で失敗を検知できないので注意してください。

UUID

ジョブを一意に識別するIDです。

これはプロジェクト内で一意であれば UUID フォーマットでなくとも構いません。

入力しないと勝手に UUID が振られます。 このときのUUIDは俗に言うUUIDで、こういう 1341c6b8-2169-421e-acf6-3376c7d287a1 やつです。

ジョブを実行するときにURLにこの UUID が指定されることになります。処理を識別しやすいような値を自分で設定することを推奨します。

一度作ってしまうと編集できないため、間違えてしまった場合は作り直す必要があります。とは言っても、再度入力し直す必要はありません。

「Action▼」の Duplicate this Job... を選択するとジョブをUUIDを除き全く同じ内容でジョブをコピーできます。

UUIDは全プロジェクトを通して一意である必要があります。重複すると以下のようなエラーメッセージが出ます。

error
  • Cannot create a Job with UUID test: a Job already exists with this UUID.
  • Change the UUID or delete the other Job.

以上でジョブの入力項目説明は終了です。

ジョブの定義は時間をかけすぎるとタイムアウトするので気をつけましょう。

ジョブの実行

ジョブが スケジュール設定されていると次の実行予定時間が画面上部に表示されます。

ジョブは「Run Job Now ▶」ボタンクリックで実行されます。 このときボタン下の Follow execution がチェックをはずすと、実行後も同じページにとどまります。

チェックしたままだとジョブの実行画面に遷移します。

「Log Output」タブを選択すると標準出力の内容をリアルタイムで確認することができます。

そのほか、ジョブのオプション、ログレベル、対象ノードの書き換えが行えます。

ただし、ノードの書き換えに関しては現在のジョブに設定されているものの中から再選択できるのみで、別のノードを選択できるわけではありません。

また、ジョブの実行には1度限り有効なトークンが必要で、実行後にブラウザバックで戻って再実行すると以下のようなエラーメッセージをお目にかかることができます。

error
  • Invalid request token The request did not include a valid token, or the token has expired. Please try your request again.

正しいリンクから遷移するか、ページを再読み込みしましょう。

ジョブの強制終了

  • 実行に時間がかかるジョブを間違って実行してしまった
  • そのタイミングで実行してはならないジョブを実行してしまった
  • 実行直後にパラメータが間違っていることに気付いた

実行を取り消したくなる理由は数えだしたらキリがありません。

ジョブの中断は容易でジョブの実行中に「Kill Job」をクリックするだけです。

ただし、この操作はあまり推奨されていないようです。 (そのことが書いてあったドキュメントは 404 になりました)

どうしてもという時以外は控えましょう。

強制終了したジョブは Aborted となります。

ジョブの実行結果

実行結果はジョブ画面の下に表示されます。

実行結果統計

EXECUTIONS
  • 総実行回数
SUCCESS RATE
  • ジョブの成功率(成功ステータス の実行履歴だけを成功数としてカウントする)。小数点以下は四捨五入ぽい
AVERAGE DURATION
  • 平均実行時間

実行結果一覧

以下の分類で実行履歴を表示する

running
  • 実行中のジョブ履歴だけを表示
recent
  • 実行履歴を20件ずつ新しい順で表示。この内容はメニューの「Activity」からも確認できます。
failed
  • 失敗したジョブ履歴だけを表示
Ω by you
  • 現在ログイン中のユーザで実行した履歴だけを表示

それぞれの実行履歴には履歴詳細へのリンクが張られており、その時のジョブ実行後画面に遷移することができます。

実行詳細

実行(履歴)詳細からは以下のことがわかります。

  • いつ実行したか
  • だれが実行したか
  • どのノードに実行したか
  • どのくらいかかったか
  • 実行後のステータスはどうなったか
  • どのような処理(ステップ)を実行したか(ステップが変わっても覚えている)
  • どのようなオプションを渡したか(secretでなければ渡した値が保存される)(オプションが変わっても覚えている)
  • どのようなログを出力したか

また、右上の「▶ Run Again...」をクリックすると、同じオプションを与えて再実行することができます。 ただし、オプションが削除されている場合は渡されません。

ワンショットでコマンドを実行したい

Rundeckではジョブ以外にも任意のコマンドを任意のタイミングで登録ノードに対して実行することができます。

この画面へはメニューの「Commands」から遷移できます。実行結果は同画面にリアルタイムで出力されます。

Rundeckで登録されているノードに対してなんらかのコマンドを実行する場合はログを共有できるのでおすすめです。

いかがだったでしょうか。

多機能すぎてまだ何が何だかわからない方も多いかもしれませんが、慣れてくると心強い味方になってくれることでしょう。

Let's try!