VTRyo Blog

一歩ずつ前に進むブログ

Ansibleのfileモジュールで見落としていたところ

f:id:vtryo:20180714235526p:plain

書きたいことがたくさんあって渋滞しているどうも私です!

さて、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/配下にtest1test2test3というディレクトリを作らせるコードです。

ちなみに、ディレクトリがなかった場合はきちんと階層的にディレクトリを作成してくれます。(mkdir -pと同じ挙動と言える)

コードの記述方式に致命的なミスがあった

試しにテストとして、さきほどのコードでディレクトリを作成させました。

[root@my-server ec2-user]# ll
合計 4
drwxr-xr-x 3 root root 4096  228 11:09 test1

[root@my-server test1]# ll
合計 4
drwxr-xr-x 3 root root 4096  228 11:09 test2

[root@my-server test2]# ll
合計 4
drwxrwxrwx 2 ec2-user ec2-user 4096  228 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