Rundeckサーバーを立てる

# はじめに
Rundeckの前段にApacheのSSLプロキシをたてるサンプルです。
未来の自分に向けた備忘録です。

# 構築
## インストール
```bash
mkdir rundeck
```

公式の docker-compose.yml を使う。
https://github.com/rundeck/docker-zoo/blob/master/mysql/docker-compose.yml

```bash
cd rundeck
vi docker-compose.yml
```

```yaml:docker-compose.yml
version: '3'

services:
    rundeck:
        #image: rundeck/rundeck:4.12.0
        build:
          context: .
          dockerfile: Dockerfile-rundeck
        links:
          - mysql
        environment:
          RUNDECK_DATABASE_DRIVER: org.mariadb.jdbc.Driver
          RUNDECK_DATABASE_USERNAME: rundeck
          RUNDECK_DATABASE_PASSWORD: rundeck
          RUNDECK_DATABASE_URL: jdbc:mysql://mysql/rundeck?autoReconnect=true&useSSL=false
          RUNDECK_GRAILS_URL: https://<クライアントに見せるサーバー名>
        volumes:
          - ${RUNDECK_LICENSE_FILE:-/dev/null}:/home/rundeck/etc/rundeckpro-license.key
          - ./config/rundeck/realm.properties:/home/rundeck/server/config/realm.properties:ro
          - ./config/rundeck/resources.yml:/home/rundeck/etc/resources.yml
          - /etc/localtime:/etc/localtime:ro
        restart: always

    mysql:
        image: mysql:5.7
        expose:
          - 3306
        environment:
          - MYSQL_ROOT_PASSWORD=root
          - MYSQL_DATABASE=rundeck
          - MYSQL_USER=rundeck
          - MYSQL_PASSWORD=rundeck
        volumes:
          - ./dbdata:/var/lib/mysql
          - ./config/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
        restart: always

    apache:
      image: httpd:2.4
      ports:
        - 443:443
      volumes:
        - ./config/httpd:/usr/local/apache2/conf
        - ./ssl:/usr/local/apache2/certs
```

rundeckユーザーが使用するSSH秘密鍵をコンテナ内に格納する。
rundeckの設定を変更するためのファイル群もコピーする。
```bash
vi Dockerfile-rundeck

FROM rundeck/rundeck:4.12.0
COPY --chown=rundeck:root rundeck.sec /home/rundeck/.ssh/id_ed25519
COPY --chown=rundeck:root config/rundeck/remco /etc/remco
```

特権ポートでLISTEN出来るようにする。 (rootless docker環境だけ必要)
```bash
sudo setcap cap_net_bind_service=ep $(which rootlesskit)
systemctl --user restart docker
```

常時起動を有効にしておく。(rootless docker環境だけ必要)
```bash
systemctl --user enable docker
sudo loginctl enable-linger $(whoami)
```

ログインパスワードを設定する。

```bash
vi config/rundeck/realm.properties
```

```text:realm.properties
#
# This file defines users passwords and roles for a HashUserRealm
#
# The format is
#  <username>: <password>[,<rolename> ...]
#
# Passwords may be clear text, obfuscated or checksummed.  The class
# org.mortbay.util.Password should be used to generate obfuscated
# passwords or password checksums
#
# This sets the temporary user accounts for the Rundeck app
#
admin:<adminユーザーのパスワード>,user,admin
```

ノードを登録しておく。
```bash
vi config/rundeck/resources.yml
```

```yaml:resources.yml
node1:
  hostname: node1.example.lan (必要に応じてFQDN指定する)
```

Apacheのリバースプロキシを設定する。
SSL用の鍵も作成して配置する。 (自己署名証明書を使ったが作成手順は割愛)

```bash
vi config/httpd/httpd.conf
```

```config:httpd.conf
LoadModule headers_module modules/mod_headers.so
LoadModule mpm_event_module modules/mod_mpm_event.so

LoadModule authn_core_module modules/mod_authn_core.so
LoadModule authz_core_module modules/mod_authz_core.so

LoadModule log_config_module modules/mod_log_config.so

LoadModule ssl_module modules/mod_ssl.so

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

LoadModule unixd_module modules/mod_unixd.so

ServerRoot "/usr/local/apache2"
Listen 443

<IfModule unixd_module>
    User daemon
    Group daemon
</IfModule>

<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    ServerName <クライアントに見せるサーバー名>
    DocumentRoot "/usr/local/apache2/htdocs"

    # SSL設定
    SSLEngine on
    SSLCertificateFile /usr/local/apache2/certs/server.crt
    SSLCertificateKeyFile /usr/local/apache2/certs/server.key

    # リバースプロキシ設定
    ProxyPass / http://rundeck:4440/
    ProxyPassReverse / http://rundeck:4440/

    <Directory />
        AllowOverride None
    </Directory>

    <Directory "/usr/local/apache2/htdocs">
        Options Indexes FollowSymLinks
        AllowOverride None
    </Directory>

    ErrorLog "logs/error.log"
    LogLevel warn

    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    CustomLog "logs/access.log" combined
</VirtualHost>

LoadModule dir_module modules/mod_dir.so
DirectoryIndex index.html
```

APIトークンの期限の延長とCORSを有効化する。
社内用WebアプリからRundeck API経由でジョブを実行したいためCORSは設定しているが、そのような要件がなければ不要。

```bash
mkdir -p config/rundeck/remco/resources.d/
vi config/rundeck/remco/resources.d/rundeck-config.properties-extra.toml
```

```toml:rundeck-config.properties-extra.toml
[[template]]
    src         = "${REMCO_TEMPLATE_DIR}/rundeck-config-extra.properties"
    dst         = "${REMCO_TMP_DIR}/rundeck-config/rundeck-config-extra.properties"
    mode        = "0644"
```

```bash
mkdir -p config/rundeck/remco/templates/
vi config/rundeck/remco/templates/rundeck-config-extra.properties
```

```properties:rundeck-config-extra.properties
grails.cors.enabled={{ getv("/grails.cors.enabled", "true") }}
rundeck.api.tokens.duration.max={{ getv("/rundeck/api/tokens/duration/max", "10y") }}
```

起動する。

```bash
docker compose up
```

↓のようなメッセージが出たらdocker composeを止める。
```bash
rundeck-mysql-1    | 2023-04-21T07:35:43.161177Z 0 [Note] mysqld: ready for connections.
```

その後、もう一度
```bash
docker compose up -d
```
するとRundeckの構築が始まるので放置する。不安になるぐらいかかる。(約5分)

Rundeckが起動すると
```
rundeck-rundeck-1  | Grails application running at http://0.0.0.0:4440/ in environment: production
```

というメッセージが表示される。
RUNDECK_GRAILS_URL で指定したURLにアクセスするとRundeckにアクセスできる。
初期状態のID/PWはadmin/<ファイル内で指定したパスワード>

# 初期設定
## SSH鍵を有効化する
初期状態ではed25519の鍵を読めないので設定変更する。
* Rundeckにログインして PROJECT SETTINGS ➝ Default ノードエクズキュータ を開く
* Executorに SSHJ-SSH を選択する
* SSH Authenticationに privateKey を選択する
* SSH Key File pathに /home/rundeck/.ssh/id_ed25519 を入力する
* <b>同様に Default ファイルコピー を開いて設定する</b>
* 保存 をクリックする

## 他サーバーを登録する
一応ファイルの生成から書いているが、すでに生成済みの場合は編集するだけで良い。
* Rundeckにログインして PROJECT SETTINGS ➝ EDIT NODES を開く
* Sources タブを開く
* Add a new Node Source をクリックする
* File を選択する
* Formatに resourceyaml を選択する
* File Pathに /home/rundeck/etc/resources.yml を入力する
* Generate のチェックを入れる
* Writeable のチェックを入れる
* Edit タブを開く
* 先程登録したファイルの Modify をクリックする
* 追加するノードを以下のフォーマットで記載する

```
<Rundeck上のノード名>:
    hostname: <Rundeckサーバーからアクセス可能な名前>