何をしていたのか
自分のLinux環境にaws-vaultを導入しようと思い、まずはlinuxbrewを公式HPを見てインストールしていたら失敗した。
実行していたコマンドは下記。
sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
環境
- CentOS7.6
通知したいチャンネルのWebhook URLをまず取得します。
対象のワークスペースの対象チャンネルにIncoming Webhookインテグレーションを追加します。
表示されたWebhook URLをコピーし、スクリプト内でURLを指定します。
今回は、"zabbix_notify_to_slack.rb"というスクリプトを作成しました。
作成したスクリプトは、githubに置いています。
github.com
zabbixでは、アラートがあがったときに対象のディレクトリにスクリプトを配置しておくと自動的に実行されるので、対象ディレクトリを調べて移動させます。
Zabbixアラート用ディレクトリは、以下のように設定ファイルに書かれているので確認します。
# zabbixアラート用ディレクトリパスを確認 $ sudo cat /etc/zabbix/zabbix_server.conf | grep alertscripts # AlertScriptsPath=${datadir}/zabbix/alertscripts AlertScriptsPath=/usr/lib/zabbix/alertscripts # 対象ディレクトリに移動 $ mv zabbix_notify_to_slack.rb /usr/lib/zabbix/alertscripts # 忘れずにスクリプトに実行権限をつける $ chmod +x /usr/lib/zabbix/alertscripts/zabbix_notify_to_slack.rb
Zabbixにログイン後、[Administration]>[Media Types]>[Create media type]をクリックし、以下のように、対象スクリプトとスクリプトのパラメータを設定します。
スクリプトパラメータに設定しているのは、Zabbixがサポートしているマクロです。今回は、{ALERT.SENDTO}、{ALERT.SUBJECT}、{ALERT.MESSAGE}の3つを使います。これらは、スクリプトを実行する際に使用するコマンドライン引数になります。
Zabbixのマクロ一覧は下記から確認することができます。
www.zabbix.com
続いて、[Administration]>[Users]>[Admin]をクリックし、メディアを追加します。[Add]をクリックします。
Typeに登録したメディアタイプを選択し、Send toにはSlackのチャンネル名、アラートを通知したい深刻度にチェックを入れます。今回は、深刻度が[Warning]以上のものをSlackに通知させたいと思います。
最後にアクションの設定をします。[Configuration]>[Actions]>[Create action]をクリックします。
[Operations]の[Operations]>[New]から
"Send to User"に先ほどメディアを追加したユーザーを選択し、今回はSlackにのみ通知したいので"Send only to"でslackのメディアを選択しました。
これで設定完了です!
今回、ZabbixのトリガーでCPU使用率が80%超えたらアラートを出すようにテストアラートを設定したので、意図的にCPUの負荷を上げます。yesコマンドでサーバーのCPU負荷が80%超えるようにします。
# CPU負荷を上げる(今回はyesコマンドをバックグラウンドで5回実行することで負荷が80%を超えました) $ yes > /dev/null & $ yes > /dev/null & $ yes > /dev/null & $ yes > /dev/null & $ yes > /dev/null & # cpu使用率を確認する $ top # アラートが発生し、slackに通知が飛ぶことを確認したらkillコマンドでジョブを止める $ kill %1 %2 %3 %4 %5 [1] Terminated yes > /dev/null [2] Terminated yes > /dev/null [3] Terminated yes > /dev/null [4]- Terminated yes > /dev/null [5]+ Terminated yes > /dev/null # ジョブが止まっていることを確認する $ jobs [1] Terminated yes > /dev/null (wd: /usr/lib/zabbix/alertscripts) [2] Terminated yes > /dev/null (wd: /usr/lib/zabbix/alertscripts) [3] Terminated yes > /dev/null (wd: /usr/lib/zabbix/alertscripts) [4]- Terminated yes > /dev/null (wd: /usr/lib/zabbix/alertscripts) [5]+ Terminated yes > /dev/null (wd: /usr/lib/zabbix/alertscripts)
対象チャンネルに通知が来ているか確認します。ちゃんとアラートが飛んできていればOK!
ちょっとしたミスが多いですが、つまずいたところです。
Zabbixで設定したアクションが有効になっているか確認してみましょう。ステータスが"Disabled"だと通知飛ばないのでご注意。
以前、Ansibleでインベントリに書いたIPアドレスを使って、それを変数として使いたい場合の変数の書き方について記事を書きました。
akng-engineer.hatenablog.com
しかし、上記の書き方だと他のパターンに適用することが難しいので、今回は別の書き方についてまとめます。
前回は、インベントリにIPアドレスのみを記載していたのですが、この書き方だと各ホストを識別し各ホストのIPアドレスをリモートサーバー上で展開させるような変数を定義することが困難でした。
今回やりたいことは、playbookで作成したシェルスクリプトに自身のIPアドレスを変数定義し、templateモジュールでリモートサーバー上で変数を展開させるような処理を記述したいので、インベントリにホスト名を記載する書き方で私のやりたいことを実現させます。
今までは、インベントリを以下のように記載していました。
[compute] 192.168.10.xx 192.168.10.xx 192.168.10.xx 192.168.10.xx 192.168.10.xx
この書き方だと、どのホストのIPアドレスか識別するような変数の書き方ができません。
今回は、以下のようにインベントリを書きます。
このようにインベントリを記載し、テンプレート化するシェルスクリプト内では、"{{ ansible_host }}"と記述することで各ホストのIPアドレスをリモートサーバー上で展開することが可能になります。
hosts.ini [compute] host01 ansible_host=192.168.10.xx host02 ansible_host=192.168.10.xx host03 ansible_host=192.168.10.xx host04 ansible_host=192.168.10.xx host05 ansible_host=192.168.10.xx
テンプレート化するシェルスクリプトでは、以下のように変数を記述することでそれぞれのホストのIPアドレスが展開されるようになります。
test-script.sh.j2 host_ip_address={{ ansible_host }}
参考ドキュメントはこちら。
docs.ansible.com
おしまい!
今回遭遇したエラーは、テンプレートに関する内容で以下の通り。
- Ansible error: template error while templating string missing end of comment tag. - Ansible error: template error while templating string expected token end of print statement got '{'.
AnsibleでTemplateモジュールを使って、作成したシェルスクリプトをリモートサーバーに送ろうと思っていたところ、上記のエラーが発生しました。
シェルスクリプトの中で変数以外に"{"を使っていたことが原因でした。
変数以外で"{"を使うと変数が閉じていない、つまり"{}"となっていないからエラーになったり、他には"{#}"と書いていたため、"#"以降がコメントアウトとして認識されてしまったりと、Ansibleのjinjaテンプレートのルールに従ってないからタスクを実行できないよ!とのことでした。
どんな内容のシェルスクリプトを書いてエラーになったか一部抜粋すると、下記の通り。
echo -n $hostname universal.discovery {"data":["{#VCPU}": > $output_file
とか
sed -ie 's/,]}/]}/g' $output_file
とかを書いていてひっかかりました。なんでこのように書いていたかというと、シェルスクリプト内でjsonファイルを作成するために"{"を使っていました。
Ansibleのjinjaテンプレート内で変数以外で"{"を使いたい場合は、エスケープさせる必要があります。
対処法としては、2つあります。
例えば、こんな感じで。
{{ echo -n $hostname universal.discovery {"data":["{#VCPU}": > $output_file }}
エスケープさせたい処理が複数行にわたるときは、そのセクションを{% raw %}~{% endraw %}で囲みます。
例えば、このように。
{% raw %} echo -n $hostname universal.discovery {"data":["{#VCPU}": > $output_file {% endraw %}
参考にした文献は以下です。
docs.ansible.com
jinja.palletsprojects.com
上記の2つでエラーを回避することはできますが、囲んでいるセクションの中にAnsibleの変数が含まれていると展開されないので、注意しましょう。
おしまい!