くらしのマーケット開発ブログ

「くらしのマーケット」を運営する、みんなのマーケット株式会社のテックブログ。積極採用中です。

Ansible の variable register は when でスキップできない

f:id:curama-tech:20200930155627p:plain

こんにちは。 バックエンドエンジニア / SRE のまのめです。

くらしのマーケットのデプロイには、 Ansible が採用されています。
Ansible では、実行したコマンドの結果などを変数に入れる register というキーワードがあります。
小ネタですが、この register で本番デプロイ時にハマったので、そのことを書いていきます。

問題の Task

やりたかったことは、以下のような処理です。

もし env が prod なら本番環境用の 設定値 を、
そうではなく env が kaizen なら 改善環境用の 設定値 を
AWS の Parameter Store から取ってきて、register する

これを愚直に playbook に起こすと、以下のようになります。

- name: Set Prod Config
  command: aws ssm get-parameters --region ap-northeast-1 --name prod.config --query Parameters[0].Value --output text
  register: config
  when: "env == 'prod'"

- name: Set Kaizen Config
  command: aws ssm get-parameters --region ap-northeast-1 --name kaizen.config --query Parameters[0].Value --output text
  register: config
  when: "env == 'kaizen'"

- name: Print Result
  command: "echo '{{ config.stdout }}'"

※ Print している箇所は、実際は template に render するなどしています。

さて、結果はどうなるでしょうか。

  • 改善環境( env = 'kaizen' ): 改善環境用の設定値がセットされる
  • 本番環境( env = 'prod' ): dict object has no attribute stdout という エラー

本番デプロイ中だというのに、困りました。

原因

先程の例で、 env = 'prod' のとき、config に register されていたものは、以下のような dict です。

"msg": {
    "changed": false, 
    "skip_reason": "Conditional result was False", 
    "skipped": true
}

condition が false になるパターンは env == 'kaizen' の場合ですね。
register がスキップされたのではなく、「評価されて false になった」という内容が register されて上書きされてしまっていました。

つまり記事タイトルのとおりですが、Ansible の register は when によってスキップできないようです。
ドキュメントにも書いてありました。

If a task fails or is skipped, Ansible still registers a variable with a failure or skipped status, unless the task is skipped based on tags.

Using Variables / Ansible Documentation

回避策

この箇所をコメントアウトし、ファイルに直書きしたものを読み込む方式に切り替えました。
本当は、「値が更新されても 1 箇所変えれば全てに適用されるようにしたい」という意図で Parameter Store から取る方式にしていたので、ちょっと不本意な形です。
何かいい方法はないのでしょうか……もし知見がある方がいらっしゃいましたら、教えていただきたいです。

最後に

こういう小ネタも案外ドキュメントにちゃんと書いてあることもあるので、しっかりと目を通しておかないといけないですね。
なお、結局未だにいい解決方法が確立できていません。
くらしのマーケットは、まだまだデプロイ周りでもこういった改善ができるところがたくさんあります。
SRE として一緒に育ててくださる方は、ぜひ こちら からお気軽にご連絡ください!