脱cron!Rundeckでジョブスケジューラを構築

# はじめに
既存の複数台のサーバーに対して定期実行する処理を作らなければならず、2017年にcronを書きまくるという選択肢は無いだろうと思いまして、いくつかジョブスケジューラを検討した結果Rundeckに落ち着いたので設定〜定期実行までのメモです。

試した環境はCentOS7です。

# インストール

## Javaのインストール
Javaが無ければRundeckは動きません。もしJavaがインストールされていなければインストールしてください。

```
yum install java-1.8.0
```

## Rundeckのインストール
```
rpm -Uvh http://repo.rundeck.org/latest.rpm
yum install rundeck
```
以上でインストールは完了です。

# Rundeckの設定

## URLの変更

ローカルのブラウザからアクセスさせたいため、外からアクセスさせるグローバルIPなりドメインなりに変更します。

```
vi /etc/rundeck/rundeck-config.properties
```

```vim:rundeck-config.properties
grails.serverURL=http://ドメイン OR IP:4440
```

## 4440のポートを開ける
サーバー側、ネットワークのセキュリティで4440で通信出来るように設定しましょう


## adminユーザーの設定
### デフォルトのユーザー設定
ユーザー名:admin
パスワード:admin

でアクセスできます。

<img width="403" alt="スクリーンショット 2017-06-23 10.49.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/c9559fa8-fdbf-b555-c597-488af9e107b9.png">


この設定は``/etc/rundeck/realm.properties``に書かれているのですがパスワードも平文でセキュリティ的にも全く良くない状態です。

```vim:realm.properties
admin:admin,user,admin,architect,deploy,build
```

### adminのパスワード変更とmd5化

まずはこの平文パスワードを変更して、設定ファイルの記述もmd5にします。

この例では``newadmin``を新たなパスワードに設定します。

```
sudo java -cp /var/lib/rundeck/bootstrap/jetty-all-9.0.7.v20131107.jar org.eclipse.jetty.util.security.Password admin newadmin
```

すると以下のようなハッシュ値が生成されます

```
OBF:1x151t331u2a1y7z1b301t121x1h
MD5:b0a24b98c089b3b0f5d4174420cebe0c
CRYPT:advDltGLaH7Bo
```

ここの ``MD5:b0a24b98c089b3b0f5d4174420cebe0c``の部分を丸コピーします。

そして、``/etc/rundeck/realm.properties``を開いて以下のように変更します。

```vim:realm.properties
admin:MD5:b0a24b98c089b3b0f5d4174420cebe0c,user,admin,architect,deploy,build
```

### このスクリプトについて
``/var/lib/rundeck/bootstrap/``に``.jar``ファイルがあるのですが、Rundeckのバージョンによって微妙に番号が違うようです。``cd  /var/lib/rundeck/bootstrap``して、``jetty-all-``から始まる.jarファイルのファイル名を使ってみてください。


## 新しいユーザーの追加
ここではadminと同等のユーザー``poweruser``、パスワード``mypassword``を追加します。

### ユーザー追加コマンド

```
java -cp /var/lib/rundeck/bootstrap/jetty-all-9.0.7.v20131107.jar org.eclipse.jetty.util.security.Password poweruser mypassword
```

### realm.propertiesに追記

adminの時と同じようにハッシュが生成されるのでコピーします。
以下のように``/etc/rundeck/realm.properties``にpoweruserの設定をadmin同様に追加します。

```vim:realm.properties
# admin
admin:MD5:b0a24b98c089b3b0f5d4174420cebe0c,user,admin,architect,deploy,build
# poweruser
poweruser:MD5:abc24b98c089b3b0f5d4174420cebe0c,user,admin,architect,deploy,build
```

### aclpolicyの追加
ユーザーの権限設定などがこの``aclpolicy ``ファイルに書いてあります。

``cd /etc/rundeck && ll``をすると、adminユーザーのaclpolicyや、今回変更はしませんが``properties``などのファイルがあります。

今回は``admin``と同じ権限のユーザーを作るので、adminのaclpolicyをコピーします。

```
cd /etc/rundeck
cp admin.aclpolicy poweruser.aclpolicy
```

これで新しいユーザーの設定は完了です。

#### rundeckを再起動
設定を反映します。

```
systemctl restart rundeckd
```

# プロジェクトの追加

## 最低限の設定
ひとまず名前だけあればプロジェクト作成は出来ます

<img width="250" alt="スクリーンショット 2017-06-23 11.57.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/b2f3b6d0-29e9-826e-f879-3042ed73c6ae.png">

# ジョブの作成

Create Jobボタンからジョブの作成をします。
<img width="274" alt="スクリーンショット 2017-06-23 11.57.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/c9ab2523-9d94-08d4-d73c-d2b97b78e718.png">

## ジョブの名前と説明の追加
<img width="444" alt="スクリーンショット 2017-06-23 11.58.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/a27b2fc8-8eaf-1bf4-6b0e-89e9a2c42c55.png">

## Workflowの追加

今回は Script を選択して、`` echo "this is TEST"``を記入しました。

<img width="386" alt="スクリーンショット 2017-06-23 12.01.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/bbe025cf-32ef-9042-d9a0-4eca1a7cbfb8.png">

<img width="273" alt="スクリーンショット 2017-06-23 12.01.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/9cd32ae4-80ff-c458-a115-e4b7e0cbc16d.png">

入力したらSaveボタンを押下して、ジョブのCreateボタンを押下します。

# ジョブの手動実行
登録したジョブをRun Job Nowボタンから実行します。
<img width="130" alt="スクリーンショット 2017-06-23 12.03.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/d1f53b25-fa1c-ea85-5135-695d0ddd9010.png">

成功するとこんな感じの画像が表示されます。
<img width="623" alt="スクリーンショット 2017-06-23 12.03.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/494ef226-bac9-b866-841e-7943d5e229ff.png">

## 実行の詳細を確認
``Report``のタブの``Node``を見てみると、入力したechoの処理が実行されていることが分かります。
<img width="407" alt="スクリーンショット 2017-06-23 12.39.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/95a0a128-2dfe-ed7b-b982-820a8fd79564.png">

# ジョブの定期実行
ジョブの編集画面を開きます
Jobsメニュー⇒Edit this Jobです。

<img width="317" alt="スクリーンショット 2017-06-23 12.41.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/a622d7c0-22c5-6f57-0dcc-e0fa8796917f.png">

## Schedule to run repeatedly?を設定

ジョブの設定画面かから``Schedule to run repeatedly?``を``Yes``に変更して設定していきます。

<img width="249" alt="スクリーンショット 2017-06-23 13.03.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/9137d769-4523-27e5-5812-dbcc4ccc67cb.png">

かなり直感的にと言うか、見たまま設定してもらえれば大丈夫です。

<img width="802" alt="スクリーンショット 2017-06-23 13.04.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/548bbbbe-a93a-3c07-59ee-e842f563a92e.png">


* 何時に？
* 毎日なのか？
* 毎月なのか？

設定はこれだけです。Crontabモードもあるので、既存のCrontabから移植したりする際は便利そうです。

設定した時間を過ぎたら実行出来ているかを確認してみます。
確認方法は手動実行の時と同じです。

# サーバーにログインして処理を実行
ここまではRundeckがインストールされたサーバーに対しての処理を行ってきました。ここからは実際に使うであろう他のサーバーにログインしての処理実行の方法を書いていきます。

## 前準備
Rundeckがインストールされているサーバーから処理を実行したいサーバーに対してパスワード無しの鍵認証ログインが出来るようになっている必要があります。

## ノードの追加
ノードの追加が残念ながらGUIから出来ません。
設定ファイルを以下のように変更します。
今回は``test``というプロジェクトを作成したので、以下のファイルを編集します。
``/var/rundeck/projects/test/etc/resources.xml``

```vim:resources.xml
<?xml version="1.0" encoding="UTF-8"?>
<project>
# 既にあるはずのlocalhostの設定
<node name="localhost" description="Rundeck server node" tags="" hostname="localhost" osArch="amd64" osFamily="unix" osName="Linux" osVersion="el7.x86_64" username="rundeck"/>

# 以下を追加
<node name="remotehost" description="Remote server node" tags="" hostname="10.1.0.12" osArch="amd64" osFamily="unix" osName="Linux" osVersion="6.5" username="remoteuser"/>
</project>
```
``<project></project>``に以下設定を追加していきます。

* name:ノードの名前 (必須)
* description:ノードの説明 (オプション)
* hostname:接続先のIPアドレス (必須)
* osArch:OSのアーキテクチャ (オプション)
* osFamily: windowsとかunixとか (オプション)
* osName:OS名 (オプション)
* osVersion:OSのバージョン (オプション)
* username:sshログインするユーザーの名前 (必須)

詳細はオフィシャルを
http://rundeck.org/docs/man5/resource-xml.html

## 秘密鍵のセット
今回は既に各SSHにログイン出来るユーザーが居て、秘密鍵と公開鍵のペアがある前提です。

### デフォルトの秘密鍵の設定を確認
プロジェクトのホーム画面からConfigureボタンを押下します。
<img width="76" alt="スクリーンショット 2017-06-23 22.13.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/1a855c25-9a27-4760-d8e0-b988a60c1845.png">

Simple Configurationボタンを押下します。
<img width="177" alt="スクリーンショット 2017-06-23 22.14.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/bb4666e8-b043-8031-295e-8d1d79996f12.png">

Default Node Executorを確認すると
<img width="347" alt="スクリーンショット 2017-06-23 22.15.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/efbe3565-82b2-997b-c1a0-b271d8b04b5a.png">

```
/var/lib/rundeck/.ssh/id_rsa
```

となっています。``Default Node File Copier``の``SCP``にも同じ値がセットされていると思います。

今回はこの``/var/lib/rundeck/.ssh/``配下に既存の秘密鍵をセットしていきます。

### 秘密鍵のコピー
既に``remoteuser``というユーザーが居て、``id_rsa``があって、接続先のサーバには``authorized_keys``がセットされているという前提です。

``remoteuser``の秘密鍵を``/var/lib/rundeck/.ssh``配下にコピーして、グループと所有者を``rundeck``に変更

```
cp /home/remoteuser/.ssh/id_rsa /var/lib/rundeck/.ssh/remoteuser_id_rsa
chown rundeck remoteuser_id_rsa
chgrp rundeck remoteuser_id_rsa
```
### プロジェクトのkey設定を変更
既出の``デフォルトの秘密鍵の設定を確認``と同じ手順で設定画面に遷移します。

コピーした``remoteuser``のキーを設定します。
<img width="418" alt="スクリーンショット 2017-06-23 22.25.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/979e69c4-cd34-b84c-e540-91afe30834b2.png">

## リモートサーバー実行の処理を追加
ジョブを開いて、``Workflow ``の``Add a Step``の``Command - Execute a remote command``を設定していきます。

テストとして``pwd``を実行します。

<img width="332" alt="スクリーンショット 2017-06-23 22.29.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/e1652fdb-ce99-975c-e020-2d77e0794dd8.png">

Saveすると以下の状態になっているはずです。
<img width="154" alt="スクリーンショット 2017-06-23 22.30.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/717d7cdf-b443-0cde-6c38-1bd74d4fcd84.png">

## ノードの設定
``Dispatch to Nodes``を選択して``Node Filter``に``remotehost``と入力すると、設定されたノードが候補として表示されます。

<img width="632" alt="スクリーンショット 2017-06-23 22.31.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/73a1eac7-9714-7624-aa15-35711856edb3.png">

ここまで設定したらSaveを押下して保存します。

## リモートホストの実行確認
これまでと同じように実行をして、``Succeeded``の表示が出ていれば成功です。
失敗すると以下のように``Faild``の表示がされるので設定の再確認をしてみてください
<img width="622" alt="スクリーンショット 2017-06-23 22.36.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/65968/f3120d61-90d3-e68a-f9f0-b4d7be9214f6.png">

# おわりに
これでジョブの定期実行とリモートホストでの実行が出来るようになりました。
cronはcronで手軽に実行出来るのですが、何の目的で誰が追加したか分からない設定が出てきたり、エラーが起きたり、今回のようにサーバーが複数ある時にそれぞれに設定を書いたりすると結構辛かったり、実行エラーが追いにくかったりと様々な問題もあったりします。

Rundeckが全て解決と言うのは少し違うと思いますが、少なくともcronで実行するよりは格段にクリアになる事が多いので、残りの今あるcronも徐々にこちらに移行していこうと思っています。

あと、操作していると感覚的にはJenkinsに近い気がしました。