tjinjin's blog

インフラ要素多めの個人メモ

Ansibleでignore_errors使うよりfailed_whenを使っていきたい

About

ignore_errorの表示が嫌だったので辞めた。

敬意

最近Ansible直していて、謎の表示が出ていて気になっていて調べた。

ignore_errors

Ansibleでshellを使ったときに冪等性を担保するにはちょっと一工夫がいる。修正前のイメージ

- name: Download nvm install.sh
  get_url:
    url: https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh
    dest: /var/tmp
    mode: 0755

- name: check nvm version
  become_user: ec2-user
  shell: source /home/ec2-user/.nvm/nvm.sh && nvm version 6.11
  register: nvm_version
  changed_when: false
  ignore_errors: true

- name: install.sh ec2-user
  become_user: ec2-user
  shell: /var/tmp/install.sh
  when: ansible_env.NVM_DIR is undefined

- name: source nvm.sh ec2-user
  become_user: ec2-user
  shell: source /home/ec2-user/.nvm/nvm.sh && nvm install v6.11 && nvm alias default 6.11
  when: nvm_version.rc != 0

check nvm versionというtask内でignore_errorsをtrueにしている。初回実行時にnvmがまだないので、必ずエラーになる。実行イメージはこんな感じ。

f:id:cross_black777:20180816225209p:plain

知っていればいいけど、知らないとちょっとぎょっとする。なので、failed_when使う感じにした。

- name: Add file for nvm check
  copy:
    src: ../files/nvm_check.sh
    dest: /home/ec2-user/
    owner: ec2-user
    group: ec2-user
    mode: 0755

- name: check installed nvm?
  shell: /home/ec2-user/nvm_check.sh nvm
  register: nvm_check
  changed_when: False
  failed_when: nvm_check.rc not in  [0, 255]

- name: Download nvm install.sh
  get_url:
    url: https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh
    dest: /var/tmp
    mode: 0755
  when: nvm_check.rc != 0

- name: install.sh ec2-user
  become_user: ec2-user
  shell: /var/tmp/install.sh
  when: nvm_check.rc != 0

- name: check installed nodejs?
  shell: /home/ec2-user/nvm_check.sh nodejs
  register: node_check
  changed_when: False
  failed_when: node_check.rc not in  [0, 255]

- name: install node.js
  become_user: ec2-user
  shell: source /home/ec2-user/.nvm/nvm.sh && nvm install v6.11 && nvm alias default 6.11
  when: node_check.rc != 0

冪等性判定用のスクリプトを用意して、そのexit codeが想定内だったら成功とみなし、想定外だったらエラーで落とすようにした。なのでexit codeが正常(0)かユーザ定義の(255)だったら、エラーにしないことにした。もうちょっときれいにかけそう。255にしたのは、通常プログラムで使わなそうなcodeだったため。

Exit Codes With Special Meanings

check系の実行結果はansibleに登録してその結果を引き回してその後の実行有無をハンドリングする感じにした。

nvm_check.shのイメージはこんな感じ

#!/bin/bash

# nvmがinstallされていることの確認
function nvm_check(){
  source /home/ec2-user/.nvm/nvm.sh 2> /dev/null
  RC=$?

  if [ $RC != 0 ];then
    exit -1
  fi
}

# nodejsが入っていることを確認
function node_check(){
  node -v 2> /dev/null
  RC=$?

  if [ $RC != 0 ];then
    exit -1
  fi
}

if [ $1 == "nvm" ];then
  nvm_check
elif [ $1 == "nodejs" ];then
  node_check
else
  echo "Invalid parameter"
  exit 1
fi

これで実行するとこんな感じ。いきなりokとなっているけどエラーよりはいいかなっていうところ。 f:id:cross_black777:20180816231254p:plain

お気持ち

チーム内とかで合意取れていればよさそうだけど、そうでない場合に実行時に赤い表示がでるのは心臓に悪い。もっと良い書き方あれば知りたい気持ち。

参考

Error Handling In Playbooks — Ansible Documentation