SQLを実行するAnsible util taskを作った

SQLを実行するAnsible util taskを作った

背景

Grafanaのセッション・ダッシュボード情報のストレージは選べる。 もともとサービス内の別の箇所でPostgresを使っていたが、インスタンスのリソースが余っていたため、 Grafanaのデータベースも同じインスタンス上に共存させることを考えた。Grafanaの(おそらく)バグで少し苦労したので記録を残す。

現象としてはこのIssueと一緒。 上記のIssue関連PRはマージされているけど手元ではうまくいかなかった。

サービスのデプロイはAnsibleで行っている。そしてデータベースのテーブル管理はアプリケーションの責任。 そのためAnsibleでも、データベー, ユーザーは設定できるけど テーブルの設定は出来ない。

テーブルがなければアプリケーション側で勝手に作成して欲しい。 しかし先ほどIssueの通りGrafanaはPostgresを使った時には機能しないケースがある。 そしてバージョンなど詳細は異なるが自分も踏んだ。MySQLでは機能しているらしい

そんなわけでAnsibleで無理やり対処した。(時間ができたらバグレポートかPR出したいけど..業務でやりたい)

対応内容

ロールを利用するように requirements.yml に下のように追加して、 pre_tasks として呼び出す。 cloudalchemy.grafanaGrafana 立ち上がるのを待ちテーブルがないと立ち上がらないため pre_tasks として呼び出す必要がある。

requirements.yml

1
2
3
---
- src: https://github.com/masu-mi/ansible-util.git
  name: masu_mi.util

ロールのインストールは下みたいにすればよろし。

1
$ ansible-galaxy install -r requirements.yml

利用するにはプレイブックでこんな感じに書く。

site.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
- hosts: all
  pre_tasks:
  - apt:
      name: "{{ item }}"
      state: present
    become: true
    become_user: root
    with_items:
      - python-psycopg2
      - python3-psycopg2
  - postgresql_db:
      name:           "{{ grafana_pg_database }}"
      login_host:     "{{ grafana_pg_host }}"
      port:           "{{ grafana_pg_port }}"
      login_user:     "{{ grafana_pg_user }}"
      login_password: "{{ grafana_pg_pass }}"
      ssl_mode: "{{ grafana_pg_ssl_mode | default('disable') }}"
  - include_role:
      name: masu_mi.util
      tasks_from: execute-sql
      private: true
    vars:
      util_pg_host: "{{ grafana_pg_host }}"
      util_pg_port: "{{ grafana_pg_port }}"
      util_pg_db:   "{{ grafana_pg_database }}"
      util_pg_user:     "{{ grafana_pg_user }}"
      util_pg_password: "{{ grafana_pg_pass }}"
      util_pg_sql: |
        CREATE TABLE IF NOT EXISTS session (
               key          CHAR(16) NOT NULL,
               data         bytea,
               expiry       numeric(11)  NOT NULL,
               PRIMARY KEY  (key)
        );        
  roles:
  - role: cloudalchemy.grafana

追加説明

Postgres のデータベースを定義する postgresql_db はリモートホストに ansible_python 用の psycopg2 がインストールされている必要がある。 python2,3 の両方に対応できるように事前に apt で入れてる。ここはディストリビューションに合わせて頑張る。

テーブルを作ってる DDL上記のIssueからコピペした。

yaml では | でヒアドキュメントみたいなことができるので意外と綺麗にクエリを yaml に埋め込める。

comments powered by Disqus