16
15

More than 3 years have passed since last update.

はじめに

この記事では、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

あとがき

基本的なモジュールであるにもかかわらず、ほとんどのパラメータの使い方を分かっていませんでした。そこで、時間をかけて調べてみようと思ったのが、この記事を作成するきっかけでした。
全てを理解することは難しかったのですが、他のモジュールにも同じようなパラメータはあるので、時間をかけて調べることができたのは良かったと思っています。
今後も、モジュールの調査を続けます。

16
15
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15