GUIな構成管理ツールRundeckをLDAPとZabbixと連携させる

![grumpy2.png](https://qiita-image-store.s3.amazonaws.com/0/14093/79ef24ab-65b9-ab34-01f5-9abf79a14756.png)

この記事は[【その1】ドリコム Advent Calendar 2015](http://www.adventar.org/calendars/1043)の15日目になります。

- [【その1】ドリコム Advent Calendar 2015](http://www.adventar.org/calendars/1043)の14日目は[ackaleen](http://www.adventar.org/users/8113)さんの[転職して一年で感じたこと](http://ackaleen.hatenablog.com/entries/2015/12/14)です。
- [【その2】ドリコム Advent Calendar 2015](http://www.adventar.org/calendars/1044)の14日目は[テラ](http://www.adventar.org/users/8222)さんの[絵について思ったこと](http://tecky0918.hatenablog.com/entry/2015/12/14/105348)です。

# 自己紹介
ID: [hiracy とか y05_net](https://twitter.com/y05_net)と呼ばれたり自称してます。

インフラエンジニアやってます。

* 去年のAdvent Calendar
    * [サーバが増えた時にインフラ担当者がやってきたこと](http://qiita.com/hiracy/items/c8bfb69ff624d4b711e4)

* 過去発表したスライド
    * [ドリコムのInfrastructure as Code](http://www.slideshare.net/y05_net/infrastructure-as-code-35373108)
    * [インフラ自動化とテストについて](http://www.slideshare.net/y05_net/ss-39978680)


# Rundeckとは？
ChefやAnsibleのような、サーバの構成を管理するツールです。
公式ページ：[rundeck.org](http://rundeck.org/index.html)

構成管理ツールの特徴として以下の点が挙げられます

- 管理しているサーバにシェルスクリプト・コマンド実行するというシンプルなものなので利用者はChefやAnsibleのようなDSLを勉強する必要なし
- 非商用にも関わらず必要な機能が揃っているGUI、APIサーバ
- スケジュール実行、GITで管理できる充実したタスク機能
- 誰が何を実行したかの履歴が追える

本記事は認証管理にLDAPを採用し、且つZabbixの管理ノード情報と同期する実用的なRundeckサーバを構築する手順について書いてみました。

![82m0gw.png](https://qiita-image-store.s3.amazonaws.com/0/14093/cb120c28-4177-2db0-4564-8f32aca48dd0.png)

※尚、ページ頭の画像はRundeckページエラー時に表示される謎生物(たぶん犬)です

# 前提条件
 * Rundeckのバージョンは現時点で最新のv2.6.1です
 * CentOS6.7での手順なので別OSの場合はファイルパス、コマンドに差分が生じます
 * コマンドはrootユーザ又は特に追記してませんがsudoを付けて実行するものとします
 * []で囲まれた部分は自分の環境に適したものに置換して下さい
 * LDAPでユーザパスワード認証を利用できる環境
 * Mysql系(MariaDB,Percona)のインストール・起動(自分はMysql5.5使用)
 * Zabbixでノードを管理しており、Zabbix-APIが利用できる環境
 * ruby1.9.3以降が利用できる環境
 * 管理しているノードには秘密鍵でsshログインできるものとする

# インストール
[公式ページ通りの方法](http://rundeck.org/downloads.html)で問題ありません。以下はCentOS6.7の場合です。

```
yum install java-1.7.0-openjdk.x86_64
rpm -Uvh http://repo.rundeck.org/latest.rpm
yum install rundeck
```

# データベース設定
Rundeckはデフォルトでは[H2 Database](http://www.h2database.com/html/main.html)というファイルベースのDBを使いますが、パフォーマンスや冗長化、バックアップ等運用が捗るRDBのほうが良いでしょう。
RDBを利用する場合はRundeckの使用するデータベースとユーザの作成が必要となります。

## mysql設定
```
mysql -uroot -p
```
```
create database rundeckdb default character set utf8;
grant all on *.* to 'rundeck'@'localhost' identified by 'rundeck';
grant all on *.* to 'rundeck'@'127.0.0.1' identified by 'rundeck';
flush privileges;
```

## rundeck-config

```/etc/rundeck/rundeck-config.properties
  :
grails.serverURL=http://localhost:4440
dataSource.dbCreate = update
- dataSource.url = jdbc:h2:file:/var/lib/rundeck/data/rundeckdb;MVCC=true;TRACE_LEVEL_FILE=4
+ dataSource.url = jdbc:mysql://localhost/rundeckdb?autoReconnect=true
+ dataSource.username = rundeck
+ dataSource.password = rundeck
  :

```

# ログイン認証設定
こちらも[公式ページ通りの設定](http://rundeck.org/docs/administration/authenticating-users.html)で問題ありません。
尚、LDAP認証でなくファイルベースの認証は[こちら](http://rundeck.org/docs/jp/administration/09-authentication.html)を参照して下さい。

```
touch /etc/rundeck/jaas-ldap.conf
chmod 644 /etc/rundeck/jaas-ldap.conf
chown runback:runback /etc/rundeck/jaas-ldap.conf
```

```/etc/rundeck/jaas-ldap.conf
ldap {
      com.dtolabs.rundeck.jetty.jaas.JettyCachingLdapLoginModule required
      debug="true"
      contextFactory="com.sun.jndi.ldap.LdapCtxFactory"
      providerUrl="ldap://[LDAPサーバのアドレス]:[LDAPサーバのポート番号]"
      authenticationMethod="simple"
      forceBindingLogin="true"
      userBaseDn="[ユーザベースDN]"
      userRdnAttribute="uid"
      userIdAttribute="uid"
      userPasswordAttribute="userPassword"
      userObjectClass="person"
      roleBaseDn="[グループベースDN]"
      roleNameAttribute="cn"
      roleUsernameMemberAttribute="memberUid"
      roleMemberAttribute="memberUid"
      roleObjectClass="posixGroup"
      cacheDurationMillis="300000"
      reportStatistics="true";
};
```

```/etc/rundeck/profile
  :
- export RDECK_JVM="-Djava.security.auth.login.config=/etc/rundeck/jaas-loginmodule.conf \
-        -Dloginmodule.name=RDpropertyfilelogin \
-        -Drdeck.config=/etc/rundeck \
-        -Drdeck.base=/var/lib/rundeck \
-        -Drundeck.server.configDir=/etc/rundeck \
-        -Dserver.datastore.path=/var/lib/rundeck/data \
-        -Drundeck.server.serverDir=/var/lib/rundeck \
-        -Drdeck.projects=/var/rundeck/projects \
-        -Drdeck.runlogs=/var/lib/rundeck/logs \
-        -Drundeck.config.location=/etc/rundeck/rundeck-config.properties \
-        -Djava.io.tmpdir=$RUNDECK_TEMPDIR"
+ export RDECK_JVM="-Djava.security.auth.login.config=/etc/rundeck/jaas-ldap.conf \
+         -Dloginmodule.name=ldap \
+         -Drdeck.config=/etc/rundeck \
+         -Drdeck.base=/var/lib/rundeck \
+         -Drundeck.server.configDir=/etc/rundeck \
+         -Dserver.datastore.path=/var/lib/rundeck/data \
+         -Drundeck.server.serverDir=/var/lib/rundeck \
+         -Drdeck.projects=/var/rundeck/projects \
+         -Drdeck.runlogs=/var/lib/rundeck/logs \
+         -Drundeck.config.location=/etc/rundeck/rundeck-config.properties \
+         -Djava.io.tmpdir=$RUNDECK_TEMPDIR"
  :
```

# ACL設定
ホワイトリスト方式でのACLになるので、Rundeckにログインできるユーザグループを登録します。

```/var/lib/rundeck/exp/webapp/WEB-INF/web.xml
        <security-role>
-                <role-name>user</role-name>
+                <role-name>[Rundeckログインユーザグループ]</role-name>
        </security-role>
```

```/etc/rundeck/admin.aclpolicy
  :
context:
  project: '.*' # all projects
  :
-  group: admin
+  group: [Rundeckログインユーザグループ]
  :
description: Admin, all access.
context:
  application: 'rundeck'
  :
-  group: admin
+  group: [Rundeckログインユーザグループ]
  :
```

# Rundeckサーバの起動と確認

```
service rundeckd start
```

`http://[RundeckサーバのIPアドレス]:4440`でアクセスします
※起動しない場合は/var/log/rundeck/service.log のエラーを見て下さい

# プロジェクト初期化
Zabbixとの連携の前にプロジェクトの初期化が必要となります。


 * Rundeckにログインしてプロジェクトを作成します。

<img width="800" alt="rlz_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/7d40702d-a74f-0637-4a57-6d40b2e33b54.png">

 * プロジェクト名を入力しResource Model Sourceを編集します

<img width="800" alt="rlz_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/a4f5fc87-3e70-6e94-d030-a30ff93326e3.png">

 * リソースファイルのフォーマットをresouceyaml、ファイルパスの拡張子をxmlからymlに変更します

<img width="805" alt="rlzd_3.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/63743452-8377-2ce7-3616-1ebef3d4b273.png">

* 他の項目は後から変更できるので一旦最下部のCreateにてプロジェクトを作成します

# Zabbix連携
zabbix連携には[zabbixapi](https://github.com/express42/zabbixapi)のgemと下記のrubyスクリプトを使用します。

[Gist:rundeck_zbx_node_update.rb](https://gist.github.com/hiracy/81083f0e0b95fa23443b)

```
gem install zabbixapi
wget https://gist.githubusercontent.com/hiracy/81083f0e0b95fa23443b/raw/edb9f2d400a15349abc3bce85be78dfeda9a4c70/gistfile1.txt -O /usr/local/bin/rundeck_zbx_node_update.rb
chmod u+x /usr/local/bin/rundeck_zbx_node_update.rb
```

Zabbixに接続するための情報とRundeckのプロジェクト固有の情報を定義するファイルを作成します

```
mkdir -m 700 -p ~/.rundeck
touch ~/.rundeck/rundeck_zbx.yml
```

```~/.rundeck/rundeck_zbx.yml
zabbix_url: [ZABBIX-APIエンドポイント]
zabbix_user: [ZABBIX-APIユーザ]
zabbix_password: [ZABBIX-APIユーザパスワード]
rundeck_ssh_port: [Rundeckサーバから各管理サーバにログインするためのsshポート]
rundeck_resource_path: /var/rundeck/projects/[上記作ったプロジェクト名]/etc/resources.yml
```

crontabにてこのスクリプトを定期的に実行するようにします

```/etc/cron.d/rundeck
*/10 * * * * root PATH=$PATH:/usr/local/bin:/usr/bin;rundeck_zbx_node_update.rb /root/.rundeck/rundeck_zbx.yml
```

# ユーザ秘密鍵とパスフレーズの登録
Rundeckから各サーバにsshで実行する際の秘密鍵を登録します。

 * ログイン後全体設定画面に遷移します

<img width="800" alt="rlzd_5.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/07cd3bc0-045b-cbdd-3bd5-d0228feac314.png">

 * Key Storageを選択します

<img width="800" alt="rlzd_7.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/176f7cb9-2553-ab55-bb3e-0d8772c73950.png">

 * ユーザ毎のKey Storageのパス(keys/users/[ユーザ])を指定して「Add or Upload a Key」を選択します

<img width="800" alt="rlzd_8.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/50c363ee-9104-65f6-b04b-dad91820ee45.png">

* Key Type: Private keyを選択し、秘密鍵をペースト又はファイルアップロードします。Nameには「default.pem」を入力し、Saveを選択します

<img width="800" alt="rlzd_9.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/97eb0ee8-4fe1-b281-7fcd-354ec21decd8.png">

 * 再度「Add or Upload a Key」を選択してから、今度はKey Type: Passwordを選択し、Enter testに秘密鍵のパスワード、Nameに「default.password」を入力し、Saveを選択します
**(※秘密鍵にパスフレーズが設定されている場合のみ)**

<img width="800" alt="rlzd_10.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/66c38941-842d-149b-306c-14bc5ccd4853.png">

# 実行の確認
* Noedesタブから遷移しNodes:にZabbixに登録されているノード名を正規表現を入力しSearchを選択します

<img width="８００" alt="rlzd_11.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/8bf40797-af44-8721-0927-5ba5079fec09.png">

* 検索結果が見つかったらActionsから「Run a command on * Node...」を選択します

![rlzd_12.png](https://qiita-image-store.s3.amazonaws.com/0/14093/6beae583-9499-0b34-0970-8b77532def07.png)

* Commandにて"hostname"のような対象に影響を与えないコマンドを入力し**(※検索結果の全てのサーバにコマンドが実行されます)**「Run on * Node」を選択します
<img width="800" alt="rlzd_13.png" src="https://qiita-image-store.s3.amazonaws.com/0/14093/d798f98d-8836-29f2-dd18-58c09b8e8fbe.png">

# 最後に
最近Rundeckにインスパイアされすぎて[Rund(**o**)ck](http://hiracy.hateblo.jp/entry/2015/09/28/070000)というシンプルな構成管理ツールを作ってみたので興味の有る方は使って苦情言ったりプルリク投げて頂けると作者が泣いて喜ぶかと思われます。

明日は

- [【その1】ドリコム Advent Calendar 2015](http://www.adventar.org/calendars/1043) 16日目は [ozabi](http://www.adventar.org/users/8203)さんです。
- [【その2】ドリコム Advent Calendar 2015](http://www.adventar.org/calendars/1044) 16日目は [chu-hi](http://www.adventar.org/users/8221)さんです。