はじめに
今回は、Ansibleで冪等性を保ちながらファイルをコピーする方法について、試行錯誤した結果についてご紹介します。
環境説明
ansible --version
ansible [core 2.17.4]
やりたかったこと
WordPressの構築をAnsibleで自動化しようとしていました。その中の一部のタスクで、ダウンロードしたWordPressディレクトリの配下にあるファイルやディレクトリを、ドキュメントルートにコピーしたいと考えていました。
コピー元:/var/tmp/wordpress/
コピー先:/var/www/documentroot/
ここで、冪等性を考慮して、コピー元とコピー先に同名のファイルが存在する場合、コピー先を上書きしないように設定したいと思いました。
Ansibleの公式ドキュメントを調べたところ、force: false
を指定すれば、この動作が実現できそうだと考えました。
force
Influence whether the remote file must always be replaced.
Iftrue
, the remote file will be replaced when contents are different than the source.
Iffalse
, the file will only be transferred if the destination does not exist.
実際に設定したタスクは以下の通りです。
- name: Copy WordPress files to web root
copy:
src: /var/tmp/wordpress/
dest: /var/www/documentroot/
owner: www-data
group: www-data
mode: '0755'
force: false
remote_src: true
なお、コピー先の/var/www/documentroot
ディレクトリは存在しない状態で、このタスクを実行することでディレクトリが作成され、その配下にWordPressの各種ディレクトリやファイルが格納される想定です。
これ以前のタスクで、WordPressをダウンロードし、/var/tmp
に解凍しています。
はまったこと
プレイブックを実行すると、結果はok
と表示されます。本来であれば、初回実行時にファイルがコピーされ、changed
と表示されるはずですが、実際には以下のように表示されました。
TASK [wordpress : Copy WordPress files to web root] ********************************************************************************
ok: [hostname]
確認すると、/var/www/documentroot/
ディレクトリ自体は作成されていましたが、その中身は空でした。
調べたこと
ansible.builtin.copy
モジュールについて調べたものの、直接の原因は分かりませんでした。
次に、代替案としてansible.posix.synchronize
モジュールについても調べましたが、冪等性を保つためには、除外したいファイルを.rsync-filter
ファイルに記述する必要があり、設定が煩雑なため断念しました。
• To exclude files and directories from being synchronized, you may add
.rsync-filter
files to the source directory.
かわりにやったこと
最終的に、force: false
ではなく、force: true
を指定することで問題なくコピーができました。
ただし、ansible.builtin.copy
モジュールだけで冪等性を保つのではなく、when
ディレクティブを使用し、既にコピー済みかどうかを判定する方法を取りました。コピー済みでない場合のみ、タスクを実行するようにしています。
実際に設定したタスク
- name: Check if documentroot exists
stat:
path: /var/www/documentroot/
register: documentroot_stat
- name: Copy WordPress files to web root
copy:
src: /var/tmp/wordpress/
dest: /var/www/documentroot/
owner: www-data
group: www-data
mode: '0755'
force: true
remote_src: true
when: not documentroot_stat.stat.exists
まだコピーされていない場合のプレイブック実行結果
TASK [wordpress : Check if documentroot exists] *******************************************************
ok: [hostname]
TASK [wordpress : Copy WordPress files to web root] ***************************************************
changed: [hostname]
すでにコピー済みの場合のプレイブック実行結果
TASK [wordpress : Check if documentroot exists] *******************************************************
ok: [hostname]
TASK [wordpress : Copy WordPress files to web root] ***************************************************
skipping: [hostname]
skipping
となり、冪等性が担保されるようにタスクを設定できたことがわかります。
おわりに
今回はansible.builtin.copy
モジュールについて調べることに時間をかけ過ぎてしまいました。今後は、複数のアプローチを念頭にいれて問題に取り組んでいきたいと思います。
宣伝:エンジニアコミュニティのご案内
私が所属しているエンジニアコミュニティ TechBull では、定期的に輪読会やもくもく会を開催しています。これらのイベントは外部の方も参加可能で、技術書を通じて学びたいというエンジニアを歓迎しています。
輪読会
同じ書籍を読み進めながら、互いに意見を交換し、理解を深める場です。自分一人では難しい内容も、他のエンジニアと一緒に学ぶことで、新たな視点や理解が得られます。
もくもく会
集中して作業を進める時間を共有する場です。自分のペースで学びたい方にぴったりです。時には雑談に発展するかも??
インフラエンジニアやIT技術に興味があり、成長意欲のある方は、ぜひ一度ご参加ください。詳細やご質問があれば、ぜひお気軽にご連絡ください!
私がコミュニティに参加して1ヶ月の感想記事はこちらにあります!
興味を持たれた方はお読みいただけると嬉しいです。
ここまでお読み頂きありがとうございました!!