redisのコマンドが失敗した時にfailするようにするansibleのtaskを作る

公開日:2019-01-02
最終更新:2019-01-02
※この記事は外部サイト(https://takuan-osho.hatenablog.com/entry/2...)からのクロス投稿です

仕事で直面したちょっとしたtipsを掘り起こしてブログにする形式の記事です。

プロダクトでredashを使っていて、その関係でAWSのElastiCache(redis)を使っているのですが、redashの内部で使われているCeleryがCPUを食い潰すくらい暴走することがあったりして時折再起動する必要があり、再起動した後redisをflushdbする必要があるのですが、その際に直面した問題がありました。

どういう問題かというと、redisをflushdbしたとき、成功しようが失敗しようがexit codeが0になってしまい、ansibleのtaskでredis flushdbしたときにそのままでは失敗した時にfailして落ちるという動作にならないということです。

細かい検証をしたわけでは無く、仕事でやったときはredis-cliではなくncコマンドを利用してflushdbするようにしていたので、全般的にそうなのか分かりませんが、今手元のPCで軽く確認した限りではerrorと出るようなコマンドをredis-cliで実行してもexit codeが0のままでした。

$ redis-cli flushdb  
OK  
$ echo $?  
0  

$ redis-cli flushdb -n 0  
(error) ERR syntax error  
$ echo $?  
0

単にコマンドをマニュアルで叩く形式なら出力結果を目で確認し、失敗したら再度実行すればいいのですが、今回は長いansibleのplaybookの中にある一つのansibleのtaskとして利用したかったので、flushdbが失敗したらその場でansibleが失敗するようにしたかったのです。

失敗を検知したかったといっても、失敗した時にもexit codeが0が返ってくる状況でどうやればいいのか分からなかったのですが、検索して見たらredisの公式ドキュメントに解決の糸口になる情報が書かれていました。

[https://redis.io/topics/protocol#resp-errors]

RESP has a specific data type for errors. Actually errors are exactly like RESP Simple Strings, but the first character is a minus ‘-‘ character instead of a plus. The real difference between Simple Strings and Errors in RESP is that errors are treated by clients as exceptions, and the string that composes the Error type is the error message itself.
The basic format is:

“-Error message\r\n”

要するに、コマンドが失敗したら、返ってくるエラーの頭の文字が - になるということです。

これを利用して、以下のようにansibleのfailモジュールを組み合わせれば、redisのコマンドが失敗した時にansibleがfailするtaskを実装できます。

以下のコマンドは実際に仕事で書いたansibleのtaskで、面倒なので行頭の空白は調整してないです。

       - name: Execute redis flushdb  
         shell: <省略>  
         register: redis_command_result  

       - fail:  
           # The first character of redis RESP Errors is minus '-' character.  
           # See https://redis.io/topics/protocol#resp-errors  
           msg: "Fail because redis flushdb failed."  
         with_items: "{{ redis_command_result.stdout_lines }}"  
         when: item|first == "-"

jinja2のfilterのfirstを利用して、返ってくるエラー文字列の各行の頭に - が存在したときはfailするというようにして解決しました。

マニュアルで実行するときは特に問題ならないことがansible経由だと問題になることが多々あって面倒ですね。

記事が少しでもいいなと思ったらクラップを送ってみよう!
18
+1
@takuanoshoの技術ブログ ところで `-` と `_` をユーザー名に使えないWebサービスはダメなのではないか?

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする