書きたいことがたくさんあって渋滞しているどうも私です!
さて、Ansibleでディレクトリを作成したいぞと思った時に、私はfileモジュールを使っています。
今回の話は、既存のサーバに対する構成管理をしていたときに起きたことです。
何回dryrunで確認してもokがでないコード
既存のディレクトリのアクセス権や所有者・グループ名、ディレクトリパスも正しいのに、どうしてもansibleのdryrun実行時にchange
が出てしまった時がありました。
このままliverunをするのはさすがにヤヴァイです。
たとえばこういうコードを書いていたとします。
- name: install test file: path: /home/ec2-user/{{ item.dir }} state: directory owner: ec2-user group: ec2-user mode: 0777 with_items: - { dir: test1/test2/test3 }
上記のコードでは、/home/ec2-user/
配下にtest1
、test2
、test3
というディレクトリを作らせるコードです。
ちなみに、ディレクトリがなかった場合はきちんと階層的にディレクトリを作成してくれます。(mkdir -p
と同じ挙動と言える)
コードの記述方式に致命的なミスがあった
試しにテストとして、さきほどのコードでディレクトリを作成させました。
[root@my-server ec2-user]# ll 合計 4 drwxr-xr-x 3 root root 4096 2月 28 11:09 test1 [root@my-server test1]# ll 合計 4 drwxr-xr-x 3 root root 4096 2月 28 11:09 test2 [root@my-server test2]# ll 合計 4 drwxrwxrwx 2 ec2-user ec2-user 4096 2月 28 11:09 test3
あ〜^
なんだよこれ最後のディレクトリにしか適用されてないじゃん。
どうやらこの部分が問題らしい。設定は再帰的に適用してくれるんじゃないのね。
with_items: - { dir: test1/test2/test3 }
つまり、既存サーバに対して何度dryrunを打ってもokが出なかったのは途中の部分(test1,test2)の部分が意図していたアクセス権や所有者・グループじゃなかった可能性があります。(実際に確認したら違ってた)
知らないうちにAnsible側でokとみなしている書き方があるかも
仮に既存サーバのディレクトリ構成と所有者・グループが以下の様になってたとしますよ。
すると、Ansible的には最後の指定されたディレクトリの設定とコードの記述に整合性があるのでokを返してきます。
[root@my-server ec2-user]# tree . └── test1 root:root └── test2 root:root └── test3 ec2-user:ec2-user
TASK [test : install test] ************************************************************************************************************************************************************************************************************************************************ ok: [my-server] => (item={u'dir': u'test1/test2/test3'}) PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************* my-server : ok=3 changed=0 unreachable=0 failed=0
この下記のような、間抜けな書き方をしていなければ全然よいのですがぶっちゃけmkdir -p
と同じ役割をしてくれるならこの書き方のほうが速いじゃん?
とか思ったのが運の尽きだったかもしれない。
- name: install test file: path: /home/ec2-user/{{ item.dir }} state: directory owner: ec2-user group: ec2-user mode: 0777 with_items: - { dir: test1/test2/test3 }
回避する書き方
で、今のところ以下のように書けば回避できます。
- name: install test file: path: /home/ec2-user/{{ item.dir }} state: directory owner: ec2-user group: ec2-user mode: 0777 with_items: - { dir: test1 } - { dir: test1/test2 } - { dir: test1/test2/test3 }
この何度も同じこと書く感じが嫌なんですよね・・・^^;
誰かいい方法求ム。
Ansibleのループ処理をループさせる方法は前にやったことがある
with_items
をループさせたいってことは前にあったので、やったことはありますが・・・。
今回の件に適用するかは別ですね、絶対読みづらくなるw
tasks/main.yml declares {{server_number}} as a variable of with_items. After that, using the original {{ item }} by using {{ server_number }} in env/servers-1-10/main.yml that was included. % tree roles/zabbix-server-host (zabbix-ansible) RyonoMac-mini . ├── env │ ├── servers-1-10 │ │ ├── main.yml │ │ ├── www1.yml │ │ ├── wwwN.yml │ │ └── wwwN.yml │ ├── servers-11-20 │ │ └── main.yml │ ├── servers-21-30 │ │ └── main.yml │ ├── servers-31-40 │ │ └── main.yml │ ├── servers-41-50 │ │ └── main.yml │ ├── servers-51-60 │ │ └── main.yml │ └── servers-61-70 │ └── main.yml └── tasks └── main.yml
==tasks/main.yml==================================================================================== - name: include task include_tasks: roles/zabbix-server-host/env/servers-{{ servers_number }}/main.yml with_items: - 1-10 - 11-20 - 21-30 - 31-40 - 41-50 - 51-60 - 61-70 loop_control: loop_var: servers_number
==env/servers-1-10/main.yml==================================================================================== - name: include_tasks: roles/zabbix-server-host/env/servers-{{ servers_number }}/{{ item }}.yml with_items: - www1 - www2 - www3 - www4 - www5 - www6 - www7 - www8 - www9 - www10
loopコントロールの話はまた今度で!w