RareJob Tech Blog

レアジョブのエンジニア・デザイナーによる技術ブログです

Ansible の cron モジュールで環境差分を減らしてみる

ご無沙汰してます

先日、大好きな女性アーティストである aiko の楽曲がサブスクリプションで提供されて狂喜乱舞しております DevOps チームのおくさんです
好きな aiko の曲は「ジェット」の再録音 ver. です
これまでライブには 3 回程しか行けていませんが、一度もライブで「ジェット」を聴いたことはないです・・・

さて、前回記事を書いてから約半年経過し、久々の執筆となります

前回は AWS の CloudWatch に関する記事を書きましたが、今回は Ansible の利用において便利だなと思った「cron モジュール」について書いてみようと思います

rarejob-tech-dept.hatenablog.com

目次

Ansible の cron モジュール

Ansible では、サーバやネットワーク機器等の設定に関する構成管理を行うことができますが、行う操作によってはモジュールという形で提供されています
たとえば、yum でパッケージをインストールするには「yum モジュール」を利用して各種パッケージのインストール等を行います

「cron モジュール」は文字通り cron 設定を管理するためのモジュールで、以下のドキュメントに利用方法が記載されています
こちらのモジュールを利用することにより、cron 設定の管理を Ansible にて行うことが可能になります

docs.ansible.com

やってみよう

cron モジュールのドキュメントに Examples がありますので、これを参考にしつつ動かしてみましょう

今回はサンプルとして、以下のような Playbook を作成してみました
設定内容は、毎日 0:00 にroot ユーザで date コマンドを実行するものとなります

test_cron.yml

---
- hosts: test
  become: yes
  tasks:
    - name: Test
      cron:
        name: 'Test'
        minute: '0'
        hour: '0'
        day: "*"
        month: "*"
        weekday: "*"
        job: 'date'
        state: 'present'
        user: 'root'

なお、今回利用する Ansible のバージョンは以下です

/work/ansible # ansible --version
ansible 2.9.2

では、作成した Playbook を実行してみましょう

/work/ansible # ansible-playbook -i inventory.ini test_cron.yml

PLAY [test] ********************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [x.x.x.x]

TASK [Test] ********************************************************************************************************************************************************************************************************
changed: [x.x.x.x]

PLAY RECAP *********************************************************************************************************************************************************************************************************
x.x.x.x              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

サーバの crontab を確認すると、無事に root ユーザで cron の設定が行われたことを確認できます

[root@x.x.x.x ~]# crontab -l -u root
#Ansible: Test
0 0 * * * date

環境にあわせて cron の有効無効を変更する

さて、本題です

Ansible を利用する際には、本番環境や開発環境でなるべく同じ Playbook を利用したい場合があると思います
しかし、「本番環境では cron を動かしたいが、開発環境では cron を動かしたくない」といったように、環境によって行うべき挙動に差が生まれることも多々あると思います

その場合、cron モジュールにおいては、「disabled パラメータ」を利用することにより環境の差分を吸収することが可能です
disabled パラメータはドキュメントに以下のように記載されています

disabled 
boolean

Choices:
no ←
yes

If the job should be disabled (commented out) in the crontab.
Only has effect if state=present.

したがって、本番環境で cron を有効にする場合は「disabled: no」、開発環境で cron を無効にする場合は「disabled: yes」とすることにより、開発環境のみ cron のコメントアウトを行うことができます
これにより、同一の Playbook を利用して環境によって挙動を変更することができます

せっかくなので、上述で利用した Playbook を変更して試してみましょう
本番環境で cron を動かしたいときは以下のような Task になります

- hosts: test
  become: yes
  tasks:
    - name: Test
      cron:
        name: 'Test'
        minute: '0'
        hour: '0'
        day: "*"
        month: "*"
        weekday: "*"
        job: 'date'
        state: 'present'
        user: 'root'
        disabled: 'no'

また、開発環境で cron を動かしたくないときは、以下のような Task になります

- hosts: test
  become: yes
  tasks:
    - name: Test
      cron:
        name: 'Test'
        minute: '0'
        hour: '0'
        day: "*"
        month: "*"
        weekday: "*"
        job: 'date'
        state: 'present'
        user: 'root'
        disabled: 'yes'

違いは disabled パラメータだけであり、このままだと冗長になってしまうので、変数を利用して切り替えましょう
変数を利用することにより、1 つのタスクで動作の切り替えが可能になります

- hosts: test
  become: yes
  tasks:
    - name: Test
      cron:
        name: 'Test'
        minute: '0'
        hour: '0'
        day: "*"
        month: "*"
        weekday: "*"
        job: 'date'
        state: 'present'
        user: 'root'
        disabled: "{{ DISABLED }}"

それでは、変更した Task を利用して Playbook を実行してみましょう

今回はサンプルなので、extra-vars でサクッと変数に値を代入して Playbook を実行します
まずは DISABLED 変数に yes を代入します

/work/ansible # ansible-playbook -i inventory.ini test_cron.yml -e DISABLED=yes

PLAY [test] ********************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [x.x.x.x]

TASK [Test] ********************************************************************************************************************************************************************************************************
changed: [x.x.x.x]

PLAY RECAP *********************************************************************************************************************************************************************************************************
x.x.x.x              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

実行した結果、cron をコメントアウトができました

[root@x.x.x.x ~]# crontab -l -u root
#Ansible: Test
#0 0 * * * date
[root@x.x.x.x ~]#

今度は、DISABLED 変数に no を代入します

/work/ansible # ansible-playbook -i inventory.ini test_cron.yml -e DISABLED=no

PLAY [test] ********************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************************************************************************************************
ok: [x.x.x.x]

TASK [Test] ********************************************************************************************************************************************************************************************************
changed: [x.x.x.x]

PLAY RECAP *********************************************************************************************************************************************************************************************************
x.x.x.x              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

実行した結果、cron 有効にすることができました

[root@x.x.x.x ~]# crontab -l -u root
#Ansible: Test
0 0 * * * date

まとめ

ジョブについては各種 OSSクラウドベンダーのサービスを利用して管理することも多いと思いますが、まだまだ各サーバ内で cron として実行している環境も多いと思います
Ansible を利用することでも cron の管理は可能ですので、 この記事がどなたかのお役に立ちますと幸いです

また、Ansible で提供されているモジュールは非常に便利なので、各種ドキュメントをしっかり読みながら、今後もいろいろ探して導入検証をしてみようと思います