この記事は「Ansible Advent Calendar 2019 18日目」です
まず…まずですよ…
遅くなって大変申し訳ございませんでした゚゚\(´O`/)°゜゚
言い訳は、しない…
さて!改めまして、tomoと申します。DBAをやりながらAnsible芸人もやってます( ´ ▽ ` )
今日はAnsibleをDBに対して使用する際、私が気をつけていることを書いてみます。
ポエマー記事です。全て個人見解ですので、あらかじめご了承ください。(色々お許しください)
何故DBオペレーションを自動化したいの?
技術的な話をする前に、DBに対する自動化に対する想いについて、少し語らせてください。
DBAの人数が少ない
DBAの数ってNWとかサーバエンジニアより絶対数が少ないと感じています。
複数のシステムを1人のDBAが担当しているとか、あるある事案。
そうすると、DBAとしては「いかに問題を発生させないようにするか」を考えます。
例えば、AシステムのDBの障害対応していたら、今度はBシステムのDBも障害が発生した。なんてあるあるですよね。これが、DBAが最も避けるべき未来だと思います。
そのために一番大切なことは「日頃からDBをモニタリングし、少しの変化も見逃さないようにする」ことではないかな、と。そしてそのタスクの中で「情報収集」に対していかに正確に、いかに早く行うべきかが焦点となるんじゃないかな、と思っています。
だから私は、DBオペレーションこそ自動化をすべきと考えています。
(まぁ監視&モニタリング頑張ればいいんだよねって論は大正解ですがw)
DBはこれから進化をするもの
10年以上前だと、DBはシステムに一つか二つしかない、アプリサーバ等の他に比べたら圧倒的に数が少ないエンティティだったように思います。複数台に同時にログインして操作することなんて滅多にないし、そもそも許されていないシステムも多くあったんじゃ無いかなぁ、なんて。
ただし最近ではマイクロサービスだったり、CloudNativeなんて時代に。DBは更に多様化、複雑化、複数化していくんじゃないかな、と思っています。
インスタンスの数が三桁とか、案外珍しく無い時代になっているような…?!
最初は勉強のために手で一つずつコマンド打ったオペレーションをした方が良い。でもいつか、それでは追いつかなくなる。事業やサービスの加速に、DBがボトルネックにならないようにする1つの手段として、「DBの自動化」があるのではないかな。と思っています。
この記事では、RDBに対する自動化を前提で書きますが、根本的なところは「DB」であれば基本は変わらないんじゃないか、と思っています。
DBへのAnsibleによるオペレーション自動化において気をつけていること
100点じゃ無いことを理解する
冪等性など、出来ないことをあれこれ悩んでも仕方ありません。勿論、モジュールが対応していれば冪等性を担保できるので、それはそのまま、ありがたく使えばいいかなと思います。
ただ、DBは操作言語が大抵SQLなので、実行したSQLの冪等性を担保するのはAnsibleだけではできないです。DDL文とか無理やん。なので、最初から諦める。
冪等性を約束するのは、AnsibleではなくてDB自体がしたらいいんじゃないでしょうか。
もしどうしても戻したいのであれば、バックアップ&リストアをすればいい。DBは基本的にその辺りは高機能だから、DBに頑張って貰えばいいと思っています。
Playbookだけでなく「実行するSQL」も気をつけて
恐らく大抵が、SQLファイルを copy でDBサーバに持っていって、それを実行するという方式だと思います。となると怖いのが Ansible の Playbook だけでなく実行するSQLファイル。
間違っても TRUNCATE とか入ってたら泣くので、実行するSQLファイルはしっかり確認してます。
慣れるまでは「select」系の処理だけにする
今私がAnsibleで自動化しているのは、ほとんどDBに対して操作を行わない select 系です。それも V$INSTANCE(Oracle) とか performance_schema(MySQL) を覗く系です。
現在ではそのほかの処理も実務で実行しています。表領域の拡張、パラメータ変更、バックアップリストア…でもそれも、まずはSQLファイル単体でしっかり動作確認した上で実施します。
実行前に必ず「実行しますか?」をきく。
よく使っているのは、こんなplaybookです。(サンプルです)
## ./vars/common.yml YES_CONFIRM_STR: [ "Y" , "YES" ] INPUTABLE_LIST: [ "Y" , "YES" , "N" , "NO" ] INPUT_RETRIES: 3 INPUT_RETRY_DELAY: 1
## ./tasks/yes_no.yml - name: 確認メッセージ pause: prompt="{{ disp_msg }} (y/n)" register: user_yes_no until: user_yes_no.user_input|upper in INPUTABLE_LIST retries: "{{ INPUT_RETRIES }}" delay: "{{ INPUT_RETRY_DELAY }}" ignore_errors: yes - name: 入力結果による処理中止 fail: msg=“!!ユーザーの入力により処理を中止します!!" when: user_yes_no.user_input|upper not in YES_CONFIRM_STR run_once: true
## main.yml - name: DBリストアPlaybook hosts: "{{ host_name }}" gather_facts: false become: yes vars_files: - vars/common.yml tasks: - name: DBリストア実施前確認 import_tasks: ./tasks/yes_no.yml vars: disp_msg: "ホスト名 {{ host_name }} へDBリストアを開始して良いですか?"
この yes_no.yml を main.yml のなかにincludeしています。
これをすれば、うっかりbash等の過去履歴から誤って Playbook を実行してしまっても、一瞬「ん???」と踏みとどまることができます。
自動化したいのにyes/no聞くんかいっ!というご意見は最も。全然スマートじゃない自覚はあります。
でも間違ってDBリストアするより、マシだと思うんですよ。
ansibleである必要って?
まっったく無いです。
これについては色々議論があると思うのですが、自分が慣れているものであればなんでもいいんじゃ無いでしょうか。
sh py go .....開発言語は沢山ありますし、他にもオーケストレーターのツールはあります。慣れてるものを使えばいいと思います。
ただ私は個人的に、以下の理由でAnsibleが気に入っているので使っています。
さいごに
来年一年間は、DBの自動化を頑張って行きたいな!と思っております。
と言っても、DBAとしても自動化エンジニアとしても未熟ですが、がばるぞーー!!