環境整備の一環で、Ansibleで現状存在するシンボリックリンクを管理しよう、という話があり、対応のために検証してたらちょっと困ったことがあったけど、色々調べてみたら解決した。で、日本語では見つからなかったので、一応書いて残しておこう、という目論見。
結論
follow
にno
やfalse
を指定しよう。
前提
既にあるけどドキュメントがなく実機を見るしかないのでリプレース作業の時に死ぬ(というか死んだ)ので、形式は問わないからやっていける範囲で実機の資産を確認する以外で見れる情報を作らないと、となった時のこと。
であるので、今ある設定がどういう前提の元行われたとか抜け落ちてるので、脳死で丸コピーしなくてはならなく(実際に必要かどうかはともかく変えるために顧客を説き伏せる労力がもったいないのでそうせざるを得ない)、実機の状態からそのままplaybookに書き記すことになった。
実機のシンボリックリンクの情報(リンク元・リンクファイル・オーナー・グループ)を一気に取る。半角スペースがあるパスが含まれる場合はこのコマンドでは無理です、ご愁傷さまです。
TARGETDIR="/XXX" ## 情報取得したいディレクトリのルート
find ${TARGETDIR} -type l -ls | awk '{ print $13,$11,$5,$6 }' | tee ~/symlink.txt
一覧から不要なものとかを目視で泥臭く取り除いたら、YAMLに変換。
awk 'BEGIN { print "symlink:" }; { print " - src: "$1; print " dest: "$2; print " owner: "$3; print " group: "$4 }' ~/symlink.txt | tee ~/vars.yml
以下のようなplaybookを作って実行。
tasks:
- name: Create symbolic link
file:
src: '{{ item.src }}'
dest: '{{ item.dest }}'
owner: '{{ item.owner }}'
group: '{{ item.group }}'
state: link
with_items: '{{ symlink }}'
シンボリックリンクはできたけど、オーナーとグループが変わってない。変わってないのみならず、リンク元のオーナーとグループが変わっている。
解決
Ansibleに関係なく、シンボリックリンク自体に対してchown
しようという時には-h
オプションが必要になる。それと同じような物が必要なのかもしれない。でも公式のドキュメントのリンク作成の例文にそんなの付いてないんだけど……。
となってたけど、GitHubのissuesでこの件についてのissueがあった。
これは2.5.0以降の挙動のはずでした。
しかし、バグのため、2.5.2でバグが修正されるまで挙動が適切に設定されませんでした。
リンクのターゲットではなく、リンク自体に適用したい場合は、follow=Falseを設定できるようにする必要があります。
ということで、fileモジュールの設定にfollow: no
を指定して、解決。
参考
- file – Manage files and file properties — Ansible Documentation
- file applying owner/group/mode to symlink destination, not the link itself in Ansible 2.5.2 · Issue #39553 · ansible/ansible · GitHub
余談
そもそもの話、シンボリックリンク自体のパーミッションとかオーナーとかの設定が必要な場面ってあるのか……?
Ansibleのバージョンが2.5以前は、follow
のデフォルトはno
だったらしく、この変更からして、シンボリックリンク自体の権限変更はデフォルトにするほどではない、という判断によるんじゃないのかな、と思うが、実際はどうなのだろう。