digdag secrets を楽して環境変数にマップしたい

digdag のバージョンは v0.9.31

## 困りごと

digdag secrets で登録した秘密な情報を、embulk の liquid ファイルや docker の entrypoint.sh から参照したいことがある。

その場合、digdag secrets の変数を直接参照することはできないので、`_env` を使って環境変数にマップしてあげて参照できるようにする必要がある。

```yaml:embulk.yml.liquid
out:
  type: bigquery
  auth_method: json_key
  json_keyfile:
    content: ${env.secret_gcp_credential}
```

```yaml:sample.dig
+task1:
  _env:
    secret_gcp_credential: ${secret:gcp.credential}
    secret_aws_access_key_id: ${secret:aws.access_key_id}
    secret_aws_secret_access_key: ${secret:aws.secret_access_key}
  sh>: embulk run embulk.yml.liquid
```

しかし現行(v0.9.31)のdigdagでは、この `_env` 設定を全てのタスクに書かなければならない。global なタスクを作ってもダメで、`_export` に書こうとしてもダメ。辛い。

```yaml:sample.dig
+task1:
  _env:
    secret_gcp_credential: ${secret:gcp.credential}
    secret_aws_access_key_id: ${secret:aws.access_key_id}
    secret_aws_secret_access_key: ${secret:aws.secret_access_key}
  sh>: embulk run embulk.yml.liquid
+task2:
  _env:
    secret_gcp_credential: ${secret:gcp.credential}
    secret_aws_access_key_id: ${secret:aws.access_key_id}
    secret_aws_secret_access_key: ${secret:aws.secret_access_key}
  sh>: embulk run embulk.yml.liquid
+task3:
  _env:
    secret_gcp_credential: ${secret:gcp.credential}
    secret_aws_access_key_id: ${secret:aws.access_key_id}
    secret_aws_secret_access_key: ${secret:aws.secret_access_key}
  sh>: embulk run embulk.yml.liquid
```

こちらに同じ辛みを抱えている Issue がある[digdag#937](https://github.com/treasure-data/digdag/issues/937)

## !include で楽をする

別ファイルに切り出して `!include` を使えば、多少は短くなる。

```yaml:sub/secrets.dig
_env:
  secret_gcp_credential: ${secret:gcp.credential}
  secret_aws_access_key_id: ${secret:aws.access_key_id}
  secret_aws_secret_access_key: ${secret:aws.secret_access_key}
```

```yaml:sample.dig
+task1:
  !include : sub/secrets.dig
  sh>: echo ${secret_gcp_credential}
+task2:
  !include : sub/secrets.dig
  sh>: echo ${secret_gcp_credential}
+task3:
  !include : sub/secrets.dig
  sh>: echo ${secret_gcp_credential}
```

それでも全タスクに書かないとダメ。

## Python API で digdag.env.store に入れる

Python (または Ruby) API で digdag.env.store に入れると楽できそう。

以下のような Digdag の Python API を使ったスクリプトをどこか `tasks` ディレクトリにでもおいておく。

`secret_` で始まる `os.environ` な環境変数を`digdag.env.store` で設定するスクリプト。

```python:tasks/__init__.py
import digdag
import os

class Enviroment(object):
    def set_secret_env(self):
        params = {}
        for k, v in os.environ.items():
            if k.startswith("secret_"):
                params[k] = v
        digdag.env.store(params)
```

`digdag.env.store` で設定されたパラメータは以降のタスクでも環境変数として読み込めるようになる性質があるので、このスクリプトを先頭のタスクで呼び出せばよい。

`.dig` ファイルは次のようになる。つまり `_env` を一度だけ書けば済むようになる。

```yaml:sample.dig
+prepare_environment:
  _env:
    secret_gcp_credential: ${secret:gcp.credential}
    secret_aws_access_key_id: ${secret:aws.access_key_id}
    secret_aws_secret_access_key: ${secret:aws.secret_access_key}
  py>: tasks.Enviroment.set_secret_env
+task2:
  sh>: echo ${secret_gcp_credential}
+task3:
  sh>: echo ${secret_gcp_credential}
```

これで良いのでは、と最初は思ったのだが、digdag.env.store を使うと digdag server を使っている場合に Web UI の Store Params カラムに設定した secrets が表示されてしまうことに気づいた。server モードでは正直使いにくい。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/9641/5a1384ee-d6ab-ea21-9c62-b33666a0772a.png)

## 結論

digdag server を使うつもりなので、面倒だが !include するしかないか、という気持ちになっている。

なにか良いソリューションがあったら教えてください。

## 将来への期待

digdag.env.store しても Web UI に表示しないモードがあると嬉しい。[Issue digdag#968](https://github.com/treasure-data/digdag/issues/968)

さらに Python API で `${secret:gcp.credential}` のような secrets に直接アクセスできると、`_env` を１つも書かずに機械的にマップできるようになると思うのだが、現状ではそれもできないので Issue [digdag#942](https://github.com/treasure-data/digdag/issues/942) だけ上げてある。

あとはトップレベルの `_export` で secrets を環境変数にマッピングができると Python スクリプトを用意せずに済むので対応して欲しい。[digdag#926
](https://github.com/treasure-data/digdag/issues/926)