rundeckのバックアップをrundeck自身で取る

概要
----

http://rundeck.org/docs/administration/backup-and-recovery.html

に沿ってrundeckのスケジューラで自分自身のバックアップを取ってみる。


バックアップについて
----

### バックアップ方針

バックアップはサーバーが死んでも何とかなるようメールで送る(気軽にアップロードできるストレージがなかったので)。

メールを送信するデータは2つに分割し、それぞれでバックアップの周期を変える。
ログファイルは運用上重要にならない、またデータ量が大きいためxzで圧縮した上で実施回数を減らす。

* ログ情報
    * 月に一回
* その他、プロジェクト情報
    * 毎日


### バックアップ方法

複数の手段を利用してバックアップを取る。

* [rd](https://rundeck.github.io/rundeck-cli/)を使用し、cli操作にてバックアップを取得する
* ファイルの直接のコピーによってバックアップを取得


### バックアップするものの説明

* /var/lib/rundeck/data/
    * ユーザー情報などrundeck全体の情報を持つデータベースを含む
* /var/rundeck/projects/
    * プロジェクトの情報を含む
    * ジョブの内容は含まない
* /etc/rundeck/
    * rundeckの設定全般を含む
* /var/lib/rundeck/var/storage/
    * ssh鍵やアカウントパスワードの情報を含む
* rdで取得したジョブ設定
    * ジョブの内容を含む


事前準備
----

### CAの準備(オレオレ証明書用)

オレオレ証明書を挿したnginxでリバースプロキシしてrundeckをhttpsで使っているが、オレオレの場合はCAを用意してそれを許可してやる必要がある。

詳細は省略。オレオレCAを立てた上で署名したオレオレ証明書を用意してnginxに当てて再起動する。

### rdのインストール

* https://github.com/rundeck/rundeck-cli/releases からrundeck-cli-x.y.z-all.jarをダウンロードする
* rundeckのUIにアクセスし、ログイン後マイページからAPI Tokenを発行する
* ~/.bash_profileに以下のように記載する

```bash
$ export RD_URL="https://example.com:443/rundeck"
$ export RD_TOKEN="Token"
$ export RD_AUTH_PROMPT=false
$ export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.101-3.b13.el7_2.x86_64"
# ※RD_TOKENは前項で取得したAPI Token, JAVA_HOMEはインストールしているjavaのディレクトリを指定
```

* /etc/rundeck/ssl/truststoreにca証明書を登録する

```bash
$ export CERTFILE=cert.txt
$ export KEYSTORE=/etc/rundeck/ssl/truststore
$ openssl s_client -connect example.com:443 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > $CERTFILE
$ keytool -printcert -sslserver example.com:443 #確認
$ sudo keytool -import -file $CERTFILE -alias example.com -keystore $KEYSTORE -noprompt
$ sudo chown rundeck:rundeck $KEYSTORE
```

* ジョブ実行ユーザー(rundeck)に設定を足す

```bash
$ sudo su - rundeck
$ vi .bash_profile
$ cat .bash_profile | tail -n2
export RD_URL="https://example.com:443/rundeck"
export RD_TOKEN="Token"
```

* 実行可能な場所にファイルを整備する
    * /usr/local/binにjarファイルと実行ファイルを設置する。

```bash
$ sudo cp rundeck-cli-x.y.z-all.jar /usr/local/bin/
$ echo '''#!/bin/sh
  java $RD_OPTS -jar /usr/local/bin/rundeck-cli-1.0.3-all.jar $*
  ''' | sudo tee /usr/local/bin/rd
$ sudo chmod +x /usr/local/bin/rd
```

ジョブ設置
----

内部メンテナンス用のプロジェクトを作成し、以下のジョブを登録してスケジューラーの設定を入れる。

ジョブのスクリプト。/tmpにバックアップ用のディレクトリ作ってまとめて圧縮するって流れ。
最後にそれをメールで送ればいい。sendmail用の文面作る部分はめんどいので省略。

ジョブ定義バックアップ

```bash:backup_definition.sh
#!/bin/sh
backup_path=/tmp/backup
backup_name=`basename $backup_path`
data_path=/var/lib/rundeck/data
log_path=/var/lib/rundeck/logs
etc_path=/etc/rundeck
projects_path=/var/rundeck/projects
storage_path=/var/lib/rundeck/var/storage
target=`date "+%Y%m%d"`
source ~/.bash_profile
projects=`rd projects list | tail -n +3 | head -n -1 | awk -F: '{print $1}'`

## backup definitions
for project in ${projects[@]}; do
    rd jobs list -f "$backup_path/${project}_$target.xml" -p ${project}
done

## backup directories
## ignored: "$log_path" 
for p in "$data_path" "$etc_path" "$projects_path" "$storage_path" ; do
  cp -pa "$p" "$backup_path/`basename $p`_$target"
done
tar cvfz "${backup_path}_$target.tar.gz" -C `dirname $backup_path` "$backup_name"
if [ ! -e ~/backup ]; then
  mkdir ~/backup
fi
cp "${backup_path}_$target.tar.gz" ~/backup
# ここでメールを送る
```

ログのバックアップ

```bash:backup_logs.sh
#!/bin/sh
backup_path=/tmp/backup
backup_name=`basename $backup_path`
log_path=/var/lib/rundeck/logs
target=`date "+%Y%m%d"`
source ~/.bash_profile
projects=`rd projects list | tail -n +3 | head -n -1 | awk -F: '{print $1}'`

## backup definitions
for project in ${projects[@]}; do
    rd jobs list -f "$backup_path/${project}_$target.xml" -p ${project}
done

## backup logs
for p in "$log_path" ; do
  cp -pa "$p" "$backup_path/`basename $p`_$target"
done
tar cvf "${backup_path}_$target.tar.xz" --xz -C `dirname $backup_path` "$backup_name"
if [ ! -e ~/backup ]; then
  mkdir ~/backup
fi
cp "${backup_path}_$target.tar.xz" ~/backup/${backup_name}_logs_$target.tar.xz
# ここでメールを送る
```


バックアップを利用して復旧する場合
----

復旧する際には以下のように処理する。

* サーバーを立ててrundeckとrdをインストールする
* ファイルの復旧(rundeck停止状態で実行)

```bash
$ sudo tar xvfz backup_yyyymmdd.tar.gz
$ cd backup
$ sudo cp -pa -R data_yyyymmdd/* /var/lib/rundeck/data/
$ sudo cp -pa -R projects_yyyymmdd/* /var/rundeck/projects/
$ sudo cp -pa -R rundeck_yyyymmdd/* /etc/rundeck/
$ sudo cp -pa -R storage_yyyymmdd/* /var/lib/rundeck/var/storage/
```

* プロジェクトの復旧

```bash
$ export HOST=example.com
$ export PORT=443
$ export RD_OPTS="-Djavax.net.ssl.trustStore=/etc/rundeck/ssl/truststore"
$ export RD_URL="https://example.com:443/rundeck"
$ export RD_TOKEN="API_TOKEN"
$ export RD_AUTH_PROMPT=false
$ export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.101-3.b13.el7_2.x86_64"
$ sudo supervisorctl start rundeck
$ rd jobs load hoge_yyyymmdd.xml -p hoge# 作成されているファイル分
```