はじめに
この記事では、Ansibleのcopy
モジュールについて説明します。
copy
モジュールは、その名の通りcp
コマンドと同じ機能を果たすもので、ファイルをコピーします。
ディレクトリごとファイルをコピーすることはできますが、空のディレクトリだけコピーすることはできません。
※公式ドキュメントは、こちらから確認できます
パラメータ(アーギュメント)
パラメータに値を指定することで、処理を細かく制御することができます。
パラメータ | 選択肢:デフォルト | 機能 |
---|---|---|
attributes | - | ファイルの属性を指定する。 |
backup |
選択肢: ・no← ・yes |
yes の場合、上書きされるファイルのバックアップを作成する。 |
checksum | - | SHA1チェックサムを指定する。 |
content | - | コピー先ファイルに記述する内容を指定する。 |
decrypt |
選択肢: ・no ・yes← |
yes の場合、暗号化されたファイルを復号化する。 |
dest | - | コピー先を指定する。 |
directory_mode | - | ディレクトリのパーミッションを指定する。 |
follow |
選択肢: ・no← ・yes |
yes の場合、dest で指定したリンクに従う。 |
force |
選択肢: ・no ・yes← |
yes の場合、dest で指定したファイルの有無にかかわらず処理が実行される。 |
group | - | グループ名を指定する。 |
local_follow |
選択肢: ・no ・yes← |
コピー元で指定したリンクに従う。 |
mode | - | ファイルのパーミッションを指定する。 |
owner | - | ユーザー名を指定する。 |
remote_src |
選択肢: ・no← ・yes |
no の場合、src で指定したファイルをコントロールノードで探す。yes の場合、src で指定したファイルをターゲットノードで探す。 |
selevel | デフォルト: "s0" | SELinuxファイルコンテキストのセキュリティレベルを指定する。 |
serole | - | SELinuxファイルコンテキストのロール識別子を指定する。 |
setype | - | SELinuxファイルコンテキストのタイプ識別子を指定する。 |
seuser | - | SELinuxファイルコンテキストのユーザー識別子を指定する。 |
src | - | コピー元を指定する。 |
unsafe_writes |
選択肢: ・no← ・yes |
yes の場合、アトミックでない書込みを強制する。 |
validate | - | コピーする前に実行する検証コマンドを指定する。 |
①dest
, src
, content
ここからは、copy
モジュールのパラメータをどのように使えばよいのか、Playbookを使って説明していきます。
まず、ファイルをコピーする上で必要なのがdest
です。
これを使ってコピー先となるファイル/ディレクトリを指定します。
コピー元となるファイル/ディレクトリは、src
を使って指定します。
src
を使用しない場合、content
でコピー先ファイルに記述する内容を指定することもできます。
まずは、src
を使用したPlaybookです。
- name: srcにコピー元を指定
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
このPlaybookを実行することで、src
で指定したコントロールノードのファイルがdest
で指定したコピー先にコピーされます。
これは、コピー先に指定するファイルの有無に関係なく実行されます。
ファイルが既に存在する場合は上書きされ、存在しない場合は新たに作成されます。
content
を使用したPlaybookは以下のとおりです。
- name: contentで記述内容指定
copy:
content: '# This file was moved to /etc/other.conf'
dest: /etc/mine.conf
コピー先ファイルの中身は、content
で指定した値が記述されています。
②force
ファイルの有無によって処理の成否を制御できるパラメータがあります。それがforce
です。
これはcp
コマンドの-f
オプションと同じ効果を持ちます。
デフォルトではyes
ですが、no
にすることでコピー先に指定したファイルが存在しない場合は処理が失敗し、コピーされません。
force
を使用したPlaybookは以下のとおりです。
- name: 上書きのみ実行する
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
force: no
③remote_src
src
で指定したファイルが、コントロールノードのファイルであるか、もしくはターゲットノードのファイルであるか指定することができます。
そのパラメータがremote_src
です。デフォルト値のno
の場合、src
で指定したファイルをコントロールノードで探します。yes
の場合、src
で指定したファイルをターゲットノードで探します。
つまり、Playbookにremote_src
を記述しない場合はコントロールノードとターゲットノードとの間でコピーが実行され、remote_src
の値がyes
の場合はターゲットノード内でコピーが実行されます。
remote_src
を使用したPlaybookは以下のとおりです。
- name: ターゲットノード内でのコピー
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
remote_src: yes
④owner
, group
, mode
ファイルの所有者、グループ、権限(パーミッション)を変更したいときはowner
, group
, mode
を使います。
これはchown
コマンド、chgrp
コマンド、chmod
コマンドと同じ効果を持ちます。
パーミッションの指定方法は、記号、数字どちらも対応しています。
owner
, group
, mode
を使用したPlaybookは以下のとおりです。
- name: 所有者、グループ、パーミッション変更(記号指定①)
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
owner: ec2-user
group: ec2-user
mode: u=rw,g=r,o=r
- name: 所有者、グループ、パーミッション変更(記号指定②)
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
owner: ec2-user
group: ec2-user
mode: u-rw,g+wx,o-r
- name: 所有者、グループ、パーミッション変更(数字指定①)
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
owner: ec2-user
group: ec2-user
mode: 0600
- name: 所有者、グループ、パーミッション変更(数字指定②)
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
owner: ec2-user
group: ec2-user
mode: '600'
数字指定の場合、先頭に「0」をつけるか、もしくは引用符を使ってください。
mode
の値をpreserve
にすることで、パーミッションが保持された状態でコピーできます。
- name: パーミッションの保持
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
mode: preserve
⑤directory_mode
Playbookを実行することによって新規で作成される全てのディレクトリの、「パーミッション」を指定できます。
mode
と異なる点ですが、mode
がコピー先ファイルのパーミッションを指定するのに対し、directory_mode
はコピー先で新規に作成されるディレクトリのパーミッションを指定します。
例えば、下記のPlaybookを実行するとします。
- name: 新規で作成されるディレクトリのパーミッション一括指定
copy:
src: /srv/myfiles
dest: /etc/qiita/copy
directory_mode: 0444
コントロールノードのディレクトリ構成
/srv
└── myfiles
└── foo.conf
ターゲットノードのディレクトリ構成
/etc
すると、ターゲットノードにファイル「foo.conf」がコピーされるのですが、etc配下に新規で作成されるディレクトリのみ、パーミッションがdirectory_mode
で指定した0444
になります。
Playbook実行後のターゲットノードのディレクトリ構成
※括弧内の数値はdirectory_mode
によって設定されたパーミッションです
/etc
└── qiita(0444)
└── copy(0444)
└── myfiles(0444)
└── foo.conf
実際に手を動かした方が理解しやすいと思うので、是非、試してみてください。
⑥attributes
ファイルの属性を変更したいときはattributes
を使います。
これはchattr
コマンドと同じ効果を持ちます。
attributes
を使用したPlaybookは以下のとおりです。
- name: 属性変更
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
attributes: '+acdijstuADS'
ターゲットノードでlsattr
コマンドを実行すると、ファイルの属性が変更されていることを確認できます。
$ lsattr /etc/foo.conf
suS-iadAc-j-t-e---- /etc/foo.conf
⑦backup
ファイルのバックアップを作成したいときはbackup
を使います。
backup
を使用したPlaybookは以下のとおりです。
- name: バックアップ作成
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
backup: yes
コピー元のファイルを上書きしてPlaybookを実行するたび、コピー先でバックアップが作成されます。
⑧checksum
SHA1チェックサムを指定したいときはchecksum
を使います。
SHA1チェックサムは、sha1sum
コマンドで確認します。
# sha1sum /srv/myfiles/foo.conf
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx /srv/myfiles/foo.conf
表示されたコピー元ファイルのSHA1チェックサムを、checksum
の値として設定します。
checksum
を使用したPlaybookは以下のとおりです。
- name: SHA1チェックサム指定
copy:
src: /srv/myfiles/foo.conf
dest: /etc/foo.conf
checksum: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ただし、デフォルトでsrc
のファイルのチェックサムと照らし合わせてくれるので、あまりこのパラメータを使う機会はないと思います。
⑨decrypt
暗号化されたファイルをコピーする際、コピー先で自動復号化する必要がない場合、decrypt
の値をno
に設定します。
まず、このパラメータの機能を確認するためにコピー元となるファイルを暗号化します。
このパラメータで自動復号化できるファイルの拡張子は「yml」と「json」の2つのみです。
下記コマンドを実行するとパスワードの入力が求められるので、パスワードを設定してください。
※詳細はこちらから確認お願いします
# ansible-vault encrypt /srv/myfiles/foo.yml
ここで、decrypt
の値がno
の場合とyes
の場合を比較したいと思います。
①decrypt
の値がno
の場合
Playbookです。
- name: 暗号化した状態のままコピー
copy:
src: /srv/myfiles/foo.yml
dest: /etc/foo.conf
decrypt: no
Playbook「copy.yml」を下記コマンドで実行すると、ファイルが暗号化された状態のままコピーされます。
# ansible-playbook copy.yml
②decrypt
の値がyes
の場合
Playbookです。
- name: 自動復号化
copy:
src: /srv/myfiles/foo.yml
dest: /etc/foo.conf
decrypt: yes
decrypt
はデフォルトの値がyes
なので、わざわざ明示的に書く必要はありません。
書いても書かなくても効果は同じです。
自動復号化する場合は、下記コマンドでPlaybook「copy.yml」を実行する必要があります。
# ansible-playbook --vault-id @prompt copy.yml
パスワードを求められるので、暗号化の際に設定したパスワードを入力してください。
コピー先のファイルが自動で復号化されます。
⑩follow
, local_follow
follow
は、値をyes
にすることでdest
にリンクを指定できます。
まず、このパラメータの機能を確認するために、ターゲットノードでシンボリックリンクを作成します。
# ln -s /path/to/file /path/to/link
follow
の値がyes
のPlaybookを実行すると、コピー元のファイル /etc/foo.conf が /path/to/file に上書きされます。
- name: destで指定したリンクに従う
copy:
src: /etc/foo.conf
dest: /path/to/link # link to /path/to/file
follow: yes
follow
の値がno
のPlaybookを実行すると、記述内容のとおり、/etc/foo.conf をコピーした /path/to/link が新規で作成されます。
- name: destで指定したリンクに従わない
copy:
src: /etc/foo.conf
dest: /path/to/link # link to /path/to/file
follow: no
local_follow
は設定した値によってコピー元で作成したシンボリックリンクに従うかどうか制御できると思ったのですが、値をno
にしてもコピーは実行できたので、このパラメータの正しい使い方はまだ理解できていません。
⑪seuser
, serole
, setype
, selevel
これらのパラメータに値を設定することで、SELinuxファイルコンテキストを制御できます。
⑫unsafe_writes
デフォルト値のno
の場合、/proc/sys/net/ipv4/conf/all/forwarding に書込みはできないのですが、yes
にすることでアトミックでない書込みを強制することができます。
- name: 書込みを強制する
copy:
content: 1
dest: /proc/sys/net/ipv4/conf/all/forwarding
unsafe_writes: yes
⑬validate
validate
には、コピーする前に実行する検証コマンドを指定します。
validate
を使用したPlaybookは以下のとおりです。
- name: コピー前に検証する
copy:
src: /etc/sudoers
dest: /etc/sudoers.edit
validate: /usr/sbin/visudo -csf %s
あとがき
基本的なモジュールであるにもかかわらず、ほとんどのパラメータの使い方を分かっていませんでした。そこで、時間をかけて調べてみようと思ったのが、この記事を作成するきっかけでした。
全てを理解することは難しかったのですが、他のモジュールにも同じようなパラメータはあるので、時間をかけて調べることができたのは良かったと思っています。
今後も、モジュールの調査を続けます。