Digdagサーバの設定メモ

プロジェクトでdigdagをサーバモードで動かそうとしたときの覚えがき。

**[前提]**
digdagはjavaで動くため、JDKのバージョン8をインストールする必要がある。

## 1.digdagをインストール

以下の通りcurlでバイナリを取ってくる。ここでは/usr/local/binにインストールしているが、適宜変更してよい。

```
curl -o /usr/local/bin/digdag --create-dirs -L "https://dl.digdag.io/digdag-latest"
chmod +x /usr/local/bin/digdag
```

次に、digdag用のユーザを作成する。

```
sudo groupadd digdag
sudo useradd -g digdag -d /opt/digdag digdag # ユーザを追加
sudo passwd digdag #パスワードを設定しておく
```

ここではホームディレクトリを`/opt/digdag`としているが適宜変えてよい。
次に、ホームディレクトリ配下にログファイルのフォルダを作成しておく。

```
sudo mkdir /opt/digdag/logs # digdag serverのログ
sudo mkdir /opt/digdag/logs/accesslogs # WebUIのアクセスログ
sudo mkdir /opt/digdag/logs/tasklogs # ワークフロー処理のログ
sudo chown -R digdag:digdag /opt/digdag
```

## 2.PostgreSQLをインストール

バージョンは特に指定されていないが、9.6以降が推奨されている。
インストール後は管理ユーザでdigdag用のユーザ、DBを作成する。

```
CREATE ROLE digdag WITH PASSWORD 'digdagユーザのパスワード' NOSUPERUSER NOCREATEDB NOCREATEROLE LOGIN;
CREATE DATABASE digdag_db WITH OWNER digdag; -- ここではdigdag_dbとしておく。
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- uuidを使うため。
```

また、必要に応じて`postgresql.conf`と`pg_hba.conf`を設定する。
ここでは最低限の設定のみ記載し、詳細は省略。

```postgresql.conf
# コメントアウトを解除する。
listen_addresses = '*'
```

```pg_hba.conf
# 設定を追記する。
host digdag_db digdag 192.168.34.41/32 md5
```

再起動が必要なパラメータであるため、
confファイルの設定を変更したら、PostgreSQLを再起動する。


## 3.digdagのプロパティファイル作成

digdagサーバ用のpostgresに関するプロパティファイルを作成する。
プロパティファイルの名前はserver.propertiesとし、/opt/digdag配下に配置する。

```/opt/digdag/server.properties
database.type = postgresql
database.user = digdag
database.password= [2で設定したdigdagユーザのパスワード]
database.host = [postgresを動かすサーバのIP] # デフォルトは5432
database.port = [postgresのポート]
database.database = digdag_db
database.maximumPoolSize = 32
```

## 4.digdagサーバの起動

コマンドラインから起動する場合は以下を実行する。初回起動時はDBに関連するテーブルが作成される。`--config`でDBのプロパティファイルのパスを指定する。

```
digdag server --config /opt/digdag/server.properties
```

なお、停止はCtrl-Cかプロセスのkillで行う。

## 5.サービス化

systemdのサービスとして起動できるようにする。
商用環境で利用する場合は、以下のような起動スクリプトを作ってデーモン化しておく。
スクリプト名は`digdag.service`としておき、`/etc/systemd/system`に配置する。

```
[Unit]
Description=digdag

[Service]
Type=simple
User=digdag
Restart=always
RestartSec=5
TimeoutStartSec=30s
WorkingDirectory=/opt/digdag
KillMode=process

ExecStart=exec /usr/local/bin/digdag server --config /opt/digdag/server.properties --log /opt/digdag/logs/digdag_server.log --task-log /opt/digdag/tasklogs --access-log /opt/digdag/accesslogs --bind 0.0.0.0

[Install]
WantedBy=multi-user.target
```

`--log`,`--task-log`,`--access-log`でログ出力の場所を指定している。
`--log`を指定するとdigdagサーバはSTDOUT(標準出力)の代わりに指定したログファイルへ出力する。

サービスのデーモン化は以下のコマンド。

```
sudo systemctl enable digdag
sudo systemctl start digdag
```

Digdagサーバが起動すると、WebUIに接続して以降の手順で登録したプロジェクトやワークフローを確認できる。

**[WebUI]**
以下のURLへアクセスするとdigdagのWebUIが確認できる。
http://${digdagサーバのIPアドレス}:65432/

プロジェクトや実行中/実行済みのタスクなどが一覧で確認できる。
また、ワークフローの内容もWebUIから更新できる。


## 6. ワークフローの作成とプロジェクトの登録

digdagのワークフローを作成する。
以下のコマンドでディレクトリ内にテンプレートを作成できる。

```
digdag init [ディレクトリ名]
```

ワークフローファイルは拡張子.digで保存しておく。ここでは`sample.dig`とする


プロジェクトを登録する。
digdagサーバが起動している状態で以下コマンドを実行する。
プロジェクト名は任意のもので構わない。

```
cd [ワークフローのディレクトリ]
digdag push [プロジェクト名] 
```

digdagを起動する際に、起動フォルダにdigファイルが存在していないとワークフローが登録されないので注意。
例えば`~/digdag_sample/sample.dig`というファイルがある場合、
`~/digdag_sample`ディレクトリ上でdigdagを実行する必要がある。

なお、複数のdigファイルが存在しているとプロジェクトに対して複数のワークフローが登録される。

例えば、`~/digdag_sample`ディレクトリ内に`test_workflow.dig`と`test_workflow2.dig`というdigファイルがあれば、`digdag push sample_project`を実行すると`sample_project`プロジェクトに
`test_workflow`と`test_workflow2`という名前の2つのワークフローが登録される。

**登録されたワークフローの確認**
以下を実行すると以下のようにプロジェクト名と
プロジェクトに登録されたワークフロー名が一覧で表示される。

```
digdag workflows [プロジェクト名]
```
```
# 実行例)
$ digdag workflows sample_project
2018-06-04 09:43:35 +0900: Digdag v0.9.25
  sample_project
    test_workflow
```

**ワークフローの起動**
digdagサーバが起動した状態で以下を実行する。

```
digdag start [プロジェクト名] [ワークフロー名]
```

例)
test_workflowのワークフローを今動かす場合、以下の通り実行する。

```
digdag start sample_project test_workflow --session now
```

`--session`で起動タイミングを指定する。

* `--session now`: 今すぐ起動する
* `--session daily`: 一日ごとに起動する
* `--session hourly`: 一時間ごとに起動する

**secretsの利用**

デフォルトでは`secrets`は無効になっているので、`server.properties`に以下をセットして`secrets`を有効にしておく。

```server.properties
digdag.secret-access-policy-file = secret-access-policy.yaml
digdag.secret-encryption-key = MDEyMzQ1Njc4OTAxMjM0NQ==
```

`secret-encryption-key`には自分で決めた文字列をBASE64エンコードした値を記入する。
上の値は公式ドキュメントにある"0123456789012345"をBASE64にしたもの。
**必ず16Bytesの文字列をBASE64でエンコードしたものを記入する**。

次に以下のようなyamlファイル(`secret-access-policy.yaml`)を作成し、`server.properties`と同じパスに配置する。
※ここではpgオペレータの`secrets`のみを利用するため、pgオペレータに関する設定のみ記載している。

```secret-access-policy.yaml
operators:
  pg:
    secrets:
      - pg.*
```

yamlを作成したらdigdagサーバを再起動する。


ここではpostgresのパスワードのsecretsを登録する。
パスワードは`pg.password`という名前で登録する必要があり、**プロジェクト1つで1個のpg.passwordのsecretsがセット可能**である。
※複数のパスワードを使う場合は、プロジェクトを複数に分ける必要がある。

digdagサーバが起動した状態で以下のコマンドを実行して`pg.password`の`secret`を登録する。

```
digdag secrets --project [プロジェクト名]  --set pg.password
```

シークレットの入力が促されるので、pgオペレータで利用するpostgresのパスワードを入力する。

```
$ digdag secrets --project sample_project --set pg.password
2018-06-04 15:17:21 +0900: Digdag v0.9.25
pg.password:    #<-- ここでシークレットの入力が促されるので、postgresのパスワードを入力しEnterを押す。
Secret 'pg.password' set # <-- 正しく入力されたらこのメッセージが表示される。
```

ワークフロー定義digファイルから利用する場合について、
pgオペレータでは自動的にpg.passwordという名前のsecretsからパスワードが自動的に抽出されるのでワークフロー上で特に何も設定等追加しなくてもいい。

```
_export:
  pg:
    # pg.passwordは登録済みのため、特に設定を追加する必要がない。
    host: [postgresのIPアドレス]
    port: [postgresのポート番号]
    database: [database名]
    user: gpadmin
    ssl: false
    schema: [schema名]

# test_sqlというタスク。
+test_sql:
  pg>: select_test.sql # select_test.sqlというsqlファイルに記載されたSQLを実行する。
```

※sqlファイルのパスは相対パスの場合、digdagサーバを起動したワーキングディレクトリに対する相対パスとなる。

## 参考情報
[環境構築周り,secrets周り]
https://qiita.com/bwtakacy/items/da1800f007718ed27bb1
https://qiita.com/hoto17296/items/b73b605033fb79473024
https://qiita.com/toyama0919/items/142d290c8dcb2c86851c

[公式サイト]
https://docs.digdag.io/command_reference.html