社内のRedashをEC2からECSに移行してv5からv8にした話 

# はじめに
こんにちは。
この記事はEC2上で稼働するRedashをECSに移しつつv5からv8にアップグレードした際に行ったことをまとめたものです。Redashの移行やアップグレードを検討されている方のお役に立てれば幸いです。

### 背景
改善前の環境は、あるインスタンス1台の中にRedash関連の全てが納められており、Dockerも利用されていないというものでした。さらに同インスタンスの中ではその他様々な仕事が行われており、度々リソース不足でRedashが利用不能に陥いるという問題がありました。それらを解決すべく、同サーバーからRedash及び関連機能を全てインスタンス外に出す作業に着手することとなりました。また、当社はRedashのヘビーユーザーであり、過去作成したダッシュボードやクエリごと移行したいというニーズもありました。

# 概要
実際のところバージョンアップそれ自体より`過去作成したダッシュボードやクエリごと移行`する部分が厄介でした。移行とアップグレードのおおまかな手順は次の通りです。

### 移行手順
 - 1.0 Redisの移行
    - 1.1 ElastiCacheクラスターの作成
    - 1.2 create_dbタスクを流す
 - 2.0 PostgreSQLの移行
    - 2.1 RDSインスタンスの作成
    - 2.2 PostgreSQLのダンプとリストア 
    
### アップグレード手順
PostgreSQL、Redisと一緒にアップグレードします

 - 3.0 アップグレード用タスク定義の作成
    - 3.1 タスクの**順次**実行


# 環境の移行
### 1.0 Redisの移行
RedashにおけるRedisはクエリ実行の際のqueueingに利用されています。従ってメンテナンスウィンドウを設ければ中身の移行は不要と判断し、ElastiCacheクラスターの新規作成及びRedashからの利用準備を行いました。

#### 1.1 ElastiCacheクラスターの作成
クラスターエンジンでRedisを選択し作成します。その他環境等はお使いのものに合わせ設定下さい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/000cc762-92c0-f805-7784-b9152277fb91.png)

*後の工程でエンドポイントを利用するので控えておくと楽になります。

#### 1.2 create_dbタスクを流す
作成したRedisクラスターにRedash側で用意されているcreate_dbタスクを流し利用準備を行います。
docker-compose.ymlに必要な環境変数を書き込み`docker-compose run --rm server create_db`する方法もありますが、ここではECSから実行する方法を記載します。なお、ECSクラスター自体の作成については触れませんので環境に合わせて読み替えてください。

#### タスク定義
ECSタスク定義におけるコンテナ設定の重要な部分について記述します。その他設定は環境に応じ設定下さい。

 - イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/74331fd2-b395-0c30-e791-6a6fe7dcde77.png)
現在のバージョンに合わせて入力下さい。バージョン一覧は[こちら][1]に載っています。



 - コマンド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/fa7f1167-00d5-885d-90b8-003dbe5c9cc0.png)
`create_db`を渡して下さい。

 - 環境変数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/f98443b5-c307-459a-7e5e-123ad16b56c4.png)
上記例では各種入力していますが、REDISの入力部分は`REDASH_REDIS_URL`です。
記法は`redis://[hostname]:[ポート番号]/0`です。

設定完了後、任意のクラスターから同タスクを実行すれば完了です。

#### その他の方法
EC2内で直接Redashをホスティングしている場合(手元にRedashのリソースがある場合)は次の方法でも実施可能です。

 - `.env`ファイルをいじり、環境変数をElastiCacheのエンドポイントに書き換える
 - Redashのディレクトリ内で`sudo -u redash ./bin/run ./manage.py database create_tables`



### 2.0 PostgreSQLの移行
Redashはメタデータの保存先としてPostgreSQLを利用しています。ダッシュボードやクエリを移行する場合はこれを移行しなければなりません。

### 2.1 RDSインスタンスの作成
インスタンス作成に関しては割愛します。PostgreSQLで作成し、その他設定は環境に応じご準備下さい。
マスターユーザー名、パスワード、及びエンドポイントを控えておくと後の作業が楽になります。

### 2.2 PostgreSQLのダンプとリストア 
PostgreSQLのダンプ、リストア方式はいくつかありますが、ここではアーカイブ方式を選択しました。
当社環境に於いて最も安定していたことと、分かりやすかった為です。


#### RDS事前準備

 - 移行先DBに接続
    - `psql -h [エンドポイント] -U postgres`
 - 必要なDB、ロール等の作成
    - `create database redash;`
    - `create role redash;`
    - `GRANT ALL ON ALL TABLES IN SCHEMA public TO redash;`
    - `create role redash_reader;`
    - `GRANT ALL ON ALL TABLES IN SCHEMA public TO redash_reader;`
    - `create role redash_user;`
    - `GRANT ALL ON ALL TABLES IN SCHEMA public TO redash_user;`
    
権限は環境に応じ適切に設定下さい。ちなみにpsqlの抜け方は`\q`です。

#### ダンプとリストア
 - ダンプ
    - `sudo -u postgres pg_dump -Fc redash > redash.dmp`
 - リストア
    - `pg_restore -h [エンドポイント] -U postgres -c -d redash redash.dmp`


### 3.0 アップグレード用タスク定義の作成
[こちら][1]によると、5->6、6->7、7->8というように段階的にアップグレードする必要があります。
詳細はこちらの[issue][2]より。

#### タスク定義
コンテナ設定を次のようにします。

 - イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/492e3760-6f32-8529-c97f-57da37d54ebc.png)
XXXの部分をアップグレード先のバージョンに合わせます。
当社の場合は現状が5.0.2であったのでredash/redash:6.0.0.b8537と入力。

 - コマンド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/47731d9e-9365-7aa5-06b4-58e439b99c63.png)
`manage,db,upgrade`とした。

 - 環境変数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/e71eb625-64b4-1c4b-540e-04db43825bb1.png)
アップグレード対象であるPostgreSQLとRedisの接続情報を入力する。
 - **REDASH_DATABASE_URL**
    - `postgresql://[user]:[password]@[hostname]:[ポート番号]/[database]`
 - **REDASH_REDIS_URL**
    - `redis://[hostname]:[ポート番号]/0`

その他の環境変数は環境に応じて設定下さい。    

### 3.1 タスクの**順次**実行
上述の通り段階的にアップグレードする必要がある為、3.0で作成したタスクのイメージ部分のバージョンを逐一を変えて対応します。**redash/redash:6.0.0.b8537**で実行、次いで**redash/redash:7.0.0.b18042**で実行、最後に**redash/redash:8.0.0.b32245**で実行、といった具合です。それぞれECSクラスターからタスク実行->タスク定義変更->タスク実行、、、といったように対応すれば問題ありません。


# Appendix
ECSでRedashを実行する場合はタスク定義を次のようにします。
これらはあくまで一例ですが、アップグレードに使用した各種情報を用いて比較的容易に起動することができます。

 - コンテナ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/675151c0-37f3-7a95-b5fc-0fa738dba991.png)
serverとworkerの2台を用意します。

 - ポートマッピング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/197a6dce-6d35-b8ea-a044-889ce1e9ad9b.png)
5000を入力します。

 - コマンド
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/cb3d203a-53de-93c6-0396-5cc725c37a54.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/8a4dc82d-9637-b4a5-d422-7986bf72e88a.png)
server側コンテナは`server`、worker側コンテナは`scheduler,worker`を入力します。

 - 環境変数(server側)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/fa1e2f70-f5db-b5c3-057e-b8bcb365c9e8.png)

 - 環境変数(worker側)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570763/f4022589-52b4-1486-498a-f20511947617.png)

 - 環境変数まとめ
    - `PYTHONUNBUFFERED`
        - stdout/stderrをbufferさせない効果がある。空でない文字列ならなんでも良いと思われる。
    - `REDASH_ALLOW_SCRIPTS_IN_USER_INPUT`
        - Dashboardに置くテキストでJavaScriptが使えるようになる。
    - `REDASH_DATABASE_URL`
        - PostgreSQLの接続情報。
    - `REDASH_REDIS_URL`
        - Redis接続情報。
    - `REDASH_DATE_FORMAT`
        - 日付フォーマット。YY/MM/DDなど。
    - `REDASH_LOG_LEVEL`
        - デフォルトでINFO。
    - `REDASH_PASSWORD_LOGIN_ENABLED`
        - 入力しなかった場合Login to Re:dash画面で止まってしまった為入力した。
    - `REDASH_ADDITIONAL_QUERY_RUNNERS`
        - redash.query_runner.pythonを入力するとRedashのデータソースでpythonが利用可能になる。
    - `REDASH_GOOGLE_xxx`
        - Google認証を利用する場合、必要な情報を入力。Google認証を利用しない場合の入力は不要。
    - `QUEUES`
        - worker側に入力しておく。

なお、環境変数にはIDやパスワードなど秘匿すべき情報が含まれることになりますので、AWS Secrets Managerを用いて認証情報を保護するのも良いでしょう。

# まとめ
Redashは便利ですが運用が大変だという話を結構聞くような気がします。
当社はこれにてECS環境に移行することができましたが、これから大変な部分も出てくることでしょう。
その際は問題や解決方法など別途記事にできればと考えています。

# 参考
[Redash パラメータ一覧][3]
[Re:Dashでpythonデータソースを使ってクエリ結果をごにょごにょしたい][4]
[Google OAuth Setup][5]

[1]:https://redash.io/help/open-source/admin-guide/how-to-upgrade
[2]:https://discuss.redash.io/t/database-migration-using-incorrect-key-for-encryption/4833
[3]:https://qiita.com/kyoshidajp/items/3528e3cd470eafef6edf
[4]:https://qiita.com/axm-aoki/items/4982cf8999aebc46b3d4
[5]:https://redash.io/help/open-source/setup#Google-OAuth-Setup