ゆるい感じのプログラムを書きたい。

プログラムの敷居を下げて、多くの人が開発出来るように色々書いていきます!

【モジュールの使い方】Copy

機能

Ansibleがインストールされている端末のローカル環境に存在する
ファイルやディレクトリをhostsで指定したサーバへ転送することが出来る。

使用例

  • 転送元(クライアントローカル側):/root/index.conf
  • 転送先(指定したサーバ側):/root/index.conf
  • 所有ユーザ、所有グループ、権限:root,root,0664
- hosts: group1
  tasks:
  - name: copy test
    copy:
      src: /root/index.conf
      dest: /root/index.conf
      owner: root
      group: root
      mode: 0664


主なパラメータ

パラメータ 必須 デフォルト値 選択肢 説明
src ローカル環境のファイル/ディレクトリパス(転送元パス)
ディレクトリの場合
・パスが"/"で終わる場合ディレクトリの中身のみ転送する
・パスの最後が"/"でない場合ディレクトリごと転送する。
dest hostsで指定したサーバのパス(転送先パス)
srcがディレクトリの場合、destもディレクトにする必要がある
owner 転送後のファイル/ディレクトリの所有ユーザ
group 転送後のファイル/ディレクトリの所有グループ
mode 転送後のファイル/ディレクトリの権限
例:"0664"、"u=rw,g=r,o=r"
force yes no
yes
yes:destが存在する場合、内容が異なればsrcで置換
no:destが存在しない場合のみsrcを転送


全パラメータ

パラメータ 必須 デフォルト値 説明
attributes ファイルの属性を指定
backup no タイムスタンプを含むバックアップファイルを作成
何らかの理由で誤って元ファイルを壊した場合に元のファイルを復元できる。
checksum 転送中のファイルのSHA1チェックサム
ファイルのコピーが成功したことを検証するために使用されます。
これが指定されない場合、ansibleはsrcファイルのローカルで計算されたチェックサムを使用します。
content srcの代わりに使用すると、ファイルの内容を指定された値に直接設定します。
destがファイルの場合にのみ機能し、ファイルが存在しない場合は作成します。
高度なフォーマットの場合、またはcontent変数が含まれている場合は、ansible.builtin.templateモジュールを使用します。
decrypt yes このオプションは、valutを使用したソースファイルの自動復号化を制御します。
dest hostsで指定したサーバのパス(転送先パス)
srcがディレクトリの場合、destもディレクトにする必要がある
directory_mode 再帰コピーを行うときは、ディレクトリのモードを設定します。
これが設定されてない場合は、システムのデフォルトが使用されます。
このモードは、新しく作成されたディレクトリのみ設定され、既存のディレクトリには影響しません。
follow no このフラグは、宛先にファイルシステムリンクが存在する場合は、それに従う必要があることを示します。
force yes yes:destが存在する場合、内容が異なればsrcで置換
no:destが存在しない場合のみsrcを転送
group 転送後のファイル/ディレクトリの所有グループ
local_follow yes このフラグは、ソースツリーにファイルシステムリンクが存在する場合は、それに従う必要があることを示します。
mode 転送後のファイル/ディレクトリの権限
例:"0664"、"u=rw,g=r,o=r"
owner 転送後のファイル/ディレクトリの所有ユーザ
remote_src no srcを転送する必要があるか、または既にリモートに存在するかどうかに影響を与える
noの場合、コントローラノードでsrcを検索します
yesの場合、管理対象(リモート)ノードでsrcを検索します

version2.8以降、remote_src再帰的コピーをサポートします
version2.6以降、remote_srcmode=preserveでのみ機能します
remote_src=yesの場合、ファイルの自動復号化は機能しません。
selevel SELinuxファイルシステムオブジェクトコンテキストのlevel部分
これはMLS/MCS属性であり、rangeとしても扱われる
_defaultに設定すると、使用可能な場合はポリシーのlevel部分が使用されます。
serole SELinuxファイルシステムオブジェクトコンテキストのrole部分
_defaultに設定すると、使用可能な場合はポリシーのrole部分が使用されます。
setype SELinuxファイルシステムオブジェクトコンテキストのtype部分
_defaultに設定すると、使用可能な場合はポリシーのtype部分が使用されます。 |
seuser SELinuxファイルシステムオブジェクトコンテキストのuser部分
これはMLS/MCS属性であり、systemとしても扱われる
_defaultに設定すると、使用可能な場合はポリシーのuser部分が使用されます。
src ローカル環境のファイル/ディレクトリパス(転送元パス)
ディレクトリの場合
・パスが"/"で終わる場合ディレクトリの中身のみ転送する
・パスの最後が"/"でない場合ディレクトリごと転送する。
unsafe_writes no ターゲットファイルシステムオブジェクトからのデータの破損や一貫性のない取り組みを防ぐために、アトミック操作を使用するタイミングに影響を与えます

デフォルトでは、このモジュールにアトミック操作を使用して、データの破損やターゲットファイルシステムオブジェクトからの一貫性のない読み取りを防ぎますが、これを防ぐ方法でシステムが構成されているのか、単に壊れている場合があります。

例1:Dockerがマウントしたファイルシステムオブジェクトです。
これは、コンテナ内からアトミックに更新することは出来ず、安全でない方法でのみ書き込みことが出来ます。

このオプションにより、Ansibleはアトミック操作が失敗し時にファイルシステムオブジェクトを更新する安全でない方法にフォールバックできます。(ただし、Ansibleに安全でない書き込みを強制することはありません)

重要!安全でない書き込みは競合状態の影響を受けやすく、データの破損につながる可能性があります。
validate 更新されたファイルを最終的な宛先にコピーする前に実行する検証コマンド

検証には一時ファイルパスが使用され、次の例のように存在する必要がある%sを介して流されます。
また、コマンドは安全に渡されるため、展開やパイプなどのシェル機能は機能しません
このオプションが提供するものよりも複雑な検証を処理する方法の例については、「複雑な構成の検証」 を参照してください。

アトミック操作 他からの割り込みがない状態にすること

戻り値

Key Type Returned 説明
backup_file String 変更されて、backup=yesの場合 作成されたバックアップファイルの名前 /path/to/file.txt.2015-02-12@22:09~
checksum String 成功した場合 コピー実行後のファイルのSHA!チェックサム 6e642bb8dd5c2e027bf21dd923337cbb4214f827
dest String 成功した場合 宛先ファイル/パス /path/to/file.txt
gid String 成功した場合 実行後のファイルのグループID 100
group String 成功した場合 実行後のファイルのグループ httpd
md5sum String サポートされている場合 コピー実行後のファイルのMD5チェックサム 2a5aeecc61dc98c4d780b14b330e3282
mode String 成功した場合 実行後のターゲットの権限 0644
owner String 成功した場合 実行後のファイルの所有者 httpd
size String 成功した場合 実行後のターゲットのサイズ 1220
src String 変更された場合 ターゲットマシンでのコピーに使用されるソースファイル /home/httpd/.ansible/tmp/ansible-tmp-1423796390.97-147729857856000/source
state String 成功した場合 実行後のターゲットの状態 file
uid String 成功した場合 実行後のファイルの所有者ID 100

ドキュメント

【Ansible Documentation】Module Copy

参考サイト

参考サイト:copyモジュールについて

【Playbook概要】変数について 4章:タスクの実行結果を制御

4.タスクの実行結果を制御する

shellで実行したコマンドの戻り値が0でない場合は失敗以降の処理は実行されなくなる。が、
戻り値が0以外でも正常終了として次の処理を実行したい場合
ignore_errors failed_when要素を利用する


4.1.実行失敗とみなされた場合でも無視して次のタスクに進む「ignore_errors」

ignore_errors を指定したタスクは実行失敗した場合でも次のタスクを実行できる。

  • 記載例
tasks:
  - name:0以外を返すシェルの実行
    shell: /home/hoge/hoge.sh
    ignore_errors: true


4.2.任意の条件を使ってタスクの失敗判定を行う「failed_when」

failed_whenは任意の条件を使ってタスクの失敗判定を行いたい場合
実行したシェルの戻り値が2以上なら失敗の条件は以下のように記載

  • 記載例
tasks:
  - name: 2以上ならエラーとするタスク
    shell: /home/hoge/hoge.sh
    register: result
    failed_when: result.rc >= 2

register:実行結果を変数に保存する機能、
registerで指定した値が変数名になり実行結果が保存される。


実行結果はマッピングで値が保存され、実行結果はrcというキーに保存
以下のように条件式として利用できる。

  • 記載例
<省略>
    register: result
    failed_when: result.rc >= 2

注意! モジュールの実行結果はモジュールごとに異なる

例: shellモジュールの場合
stdout:標準出力
stderr:エラー出力

上記のキーで取得可能


モジュールの実行結果を確認したい場合

debugモジュールを利用
以下のようにモジュール結果を確認する方法として利用できる。

  • 記載例
tasks:
  - shell: /home/hoge/hoge.sh
    register: result
  - debug: msg={{ result }}



参考サイト

【Playbook概要】変数について 3章:条件分岐でタスクの事項要否を制御

3.条件分岐でタスクの事項要否を制御する

タスクを実行するかどうかの判定を行う方法を紹介


3.1.条件を使ってタスクの実行を成業する「when」

一部のタスクは特定のOSだけで実行したい場合
タスクに対しwhen要素を追加、whenの値として条件式を記述し、その条件が満たされた場合のみタスクが実行

OSがCentOSの場合:yum
OSがUbuntuの場合:apt

を使って、httpdをインストールさせる場合は以下のように記述

  • 記載例
tasks:
  - name: CentOS用httpdインストール
    yum: name=httpd state=latest
    when: ansible_distribution == 'CentOS'
    
  - name: Ubuntu用httpdインストール
    apt: name=apache2 state=latest
    when: ansible_distribution == 'Ubuntu'

ymlで指定しているansible_distributeはAnsibleが自動で実行しているsetupモジュールにより設定された変数名 4.デフォルトで用意される変数を使うを参照


whenの構文で変数は{{}}で囲まずに参照可能
whenで指定する条件はJinja2というPythonのテンプレートエンジンの文法を使用
whenで利用できる演算子は以下の通り

機能 演算子 利用例
比較 ==,!=,>,M,>=,<= when:size > 100
論理 and,or when:size > 100 and size < 200
真偽値 true,false when:false
含まれる in, not in when: name in ['hoge','hogehoge']|


3.2.複数のタスクをまとめて制御する「block」

複数のタスクに対し同じ条件を設定する場合

whenのみでは以下のように同じ条件判定を記載する必要がある。
修正に手間が掛かり、修正漏れも起こる可能性がある。

  • 記載例
tasks:
  - name:CentOS用httpdインストール
    yum: name=httpd state=latest
    when: ansible_distribution == 'CentOS'
  
  - name:設定ファイルの転送
    copy: src=httpd.conf dest=/etc/httpd/conf/
    when: ansible_distribution == 'CentOS'


block要素を利用し、複数のタスクをまとめることが出来る。
blockに対しwhen要素を指定することで、条件判定を1箇所のみに可能

  • 記載例
tasks:
  - block:
    - name: CentOS用httpdインストール
      yum: name=httpd state=latest
    - name: 設定ファイルの転送
      copy: src=httpd.conf dest=/etc/httpd/conf/
    when: ansible_distribution == 'CentOS'

【Playbook概要】変数について 2章:繰り返し実行

2.繰り返し実行

複数のファイルをコピーしたり、複数のユーザを追加したい場合
追加したい数だけ対応するモジュールを書くことで実現できるが、Playbookが長く読みづらくなる。
その際は、以下のようにタスクの繰り返しを扱う機能を使うと良い。


2.1.単純な繰り返しを行う「with_items」

userコマンドを使い複数のユーザを追加する場合
with_itemsをタスクに指定することで、一括で追加可能

  • 記載例
tasks:
  user: name={{ item }}
  with_items:
    - hoge
    - hogehoge

with_itemsに渡されたシーケンスの内容が順にitemという名称の変数に設定、繰り返し実行


以下のように あらかじめシーケンスを変数で作成し、with_itemsで指定することも可能

  • 記載例
vars:
  users:
    - hoge
    - hogehoge
tasks:
  user: name={{ item }}
  with_items: "{{ users }}"

ユーザ名と一緒にパスワードを指定したい場合は以下の通り + 記載例

vars:
  users:
    - name: hoge
      pasword: gbfgjghjghkhhk
    - name: hogejpge
      pasword: gbfgjghjghkhhk
tasks:
  - user: name={{ item.name }} password={{ item.password }}
    with_items:"{{ users }}"    


2.2.マッピングを繰り返す「with_dict」

with_itemsでは以下のようなマッピングのすべての要素を繰り返したい場合は使えません。

  • 記載例
vars:
  users:
    admin:
      - name: hoge
        password: gbfgjghjghkhhk
    workes:
      - name: hogehoge
        password:  gbfgjghjghkhhk

マッピングを繰り返しに利用する場合with_itemsの代わりにwith_dictを利用
with_dictを利用すると、with_itemsと同様にitems変数からマッピングのキーとバリューを取得可能

変数を指定
  • 記載例
vars:
  users:
    admin:
      - name: hoge
        password: gbfgjghjghkhhk
    workes:
      - name: hogehoge
        password:  gbfgjghjghkhhk
with_dictの記載例は以下の通り
  • 記載例
tasks:
  - user: name={{ itme.value.name }} password={{ iteme.value.password }}
    with_dict:"{{ users }}"

キーを取得するにはitem.keyを指定
バリューを取得するにはitem_valueを指定


2.3.ワイルドカードを使って繰り返す「with_filelob」

ある拡張子のファイルだけコピーしたい場合

以下のようにsrc引数にはワイルドカードを利用することは出来ません。
実行すると*.txtという名称のファイルがコピーされます。

  • 記載例
tasks:
  - copy: src=/home/vagrant/*.txt dest=/home/hoge/text/


解決方法として、with_fileglobを利用します。
with_itemsと同じようにシーケンスでファイル指定することで、ヒットしたファイルパスだけタスクが繰り返し実行

with_fileglobの記載例は以下の通り

  • 記載例
tasks:
  - copy: src={{ item }} dest=/home/hoge/txt/
    with_fileglob
      - /home/vagrant/*/txt

【Playbook概要】変数について 1章:一般的な使い方

1.変数の利用

変数定義にはvars要素を使用します。
定義した変数の値を参照するには{{user_name}}のように{{変数名}}という形式を使います。

1.1.一般的な使い方

  • 記載例
vars:
  user_name:hoge
  dest_file_path:/home/{{ user_name }}/


但し、以下のように
値の最初に変数の参照を記載したい場合は
ダブルコーテーションで囲むと参照できるようになります。

  • 記載例
vars:
  user_name:hoge
  file_name:"{{ user_name }}"


1.2.変数の値をマッピング定義

ユーザ名とパスワードのように、セットで扱った方が良い場合
以下のようにマッピングを使って階層的に変数定義できる。

  • 記載例
vars:
  admin_user_data:
  name: hoge
  password: gbfgjghjghkhhk


以下のように.を付けて参照

  • 記載例
tasks:
  - user: name={{ admin_user.name }} password={{ admin_user.password}}


1.3.変数の値をコンソールから受け付ける

ユーザの入力を受け付けて値を設定することも可能

例えば、リリースを行う際、ファイル名にリリースバージョンが入っていて
それを参照したい、という場面で便利です。

変数の値を入力させるには、varsの代わりにvars_prompt要素を利用します。
vars_promptの利用例は以下の通り

  • 記載例
vars_prompt:
  - name: release_version
    prompt: "input release_version(ex 20220131)"
    private: no
task
  - copy: src=/home/foo/release_{{release_version}}.zip dest=/home/piyo

name:指定した値が変数となる。
prompt:指定したメッセージがユーザに表示
privete:ユーザの入力値がコンソールに表示されるかどうかを示します。

(もしパスワードのように他人に見られたくない入力をする場合はprivet: yesを指定)
※デフォルトはyes

入力値を暗号化することも可能

  • 記載例
vars_prompt:
  - name: password
    prompt: "input newuser password"
    encrypt: sha512_crypt
    confirm: yes
tasks
  - user: name=hoge password={{ password }}

encrypt:暗号化の種類を設定 confirm:ユーザに確認用に2度入力をさせるのか指定


1.4.デフォルトで用意される変数を使う

setupというタスクでAnsibleの非管理ホストの情報を取得し 変数にセットしてくれます。


setタスクで取得される値については、以下のコマンドで確認可能

  • 記載例
ansible -i hosts <ホスト名> -m setup


setupでは以下のような値が取得可能

変数名 内容 値の例
ansible_distribution 被管理ホストのディストリビューション CentOS
ansible_date_time.date Ansibleの実行時間 2022-1-31
ansible_hostname 被管理ホスト名 localhoost
ansible_pkg_mgr 被管理ホストで利用できるパッケージマネージャ名 yum



2.繰り返し実行

複数のファイルをコピーしたり、複数のユーザを追加したい場合。
追加したい数だけ対応するモジュールを書くことで実現できるが、Playbookが長く読みづらくなる。
その際は、以下のようにタスクの繰り返しを扱う機能を使うと良い。

2.1.単純な繰り返しを行う「with_items」

userコマンドを使い複数のユーザを追加する場合
「with_items」をタスクに指定することで、一括で追加可能

tasks:
  user: name={{ item }}
  with_items:
    - hoge
    - hogehoge

with_itemsに渡されたシーケンスの内容が順にitemという名称の変数に設定、繰り返し実行

以下のように
あらかじめシーケンスを変数で作成し、with_itemsで指定することも可能

vars:
  users:
    - hoge
    - hogehoge
tasks:
  user: name={{ item }}
  with_items: "{{ users }}"

ユーザ名と一緒にパスワードを指定したい場合は以下の通り

vars:
  users:
    - name: hoge
      pasword: gbfgjghjghkhhk
    - name: hogejpge
      pasword: gbfgjghjghkhhk
tasks:
  - user: name={{ item.name }} password={{ item.password }}
    with_items:"{{ users }}"    


2.2.マッピングを繰り返す「with_dict」

with_itemsでは以下のようなマッピングのすべての要素を繰り返したい場合は使えません。

vars:
  users:
    admin:
      - name: hoge
        password: gbfgjghjghkhhk
    workes:
      - name: hogehoge
        password:  gbfgjghjghkhhk

マッピングを繰り返しに利用する場合with_itemsの代わりにwith_dictを利用
with_dictを利用すると、with_itemsと同様にitems変数からマッピングのキーとバリューを取得可能

キーを取得するにはitem.keyを指定
バリューを取得するにはitem_valueを指定

変数を指定

vars:
  users:
    admin:
      - name: hoge
        password: gbfgjghjghkhhk
    workes:
      - name: hogehoge
        password:  gbfgjghjghkhhk

with_dictの記載例は以下の通り

tasks:
  - user: name={{ itme.value.name }} password={{ iteme.value.password }}
    with_dict:"{{ users }}"

ファイル抽出に利用できるかも。



2.3.ワイルドカードを使って繰り返す「with_filelob」

ある拡張子のファイルだけコピーしたい場合

以下のようにsrc引数にはワイルドカードを利用することは出来ません。
実行すると*.txtという名称のファイルがコピーされます。

tasks:
  - copy: src=/home/vagrant/*.txt dest=/home/hoge/text/

解決方法として、with_fileglobを利用します。
with_itemsと同じようにシーケンスでファイル指定することで、ヒットしたファイルパスだけタスクが繰り返し実行

with_fileglobの記載例は以下の通り

tasks:
  - copy: src={{ item }} dest=/home/hoge/txt/
    with_fileglob
      - /home/vagrant/*/txt



3.条件分岐でタスクの実行要否を制御する

3.1.条件を使ってタスクの実行を成業する「when」

一部のタスクは特定のOSだけで実行したい場合
タスクに対しwhen要素を追加、whenの値として条件式を記述し、その条件が満たされた場合のみタスクが実行

OSがCentOSの場合:yum
OSがUbuntuの場合:apt

を使って、httpdをインストールさせる場合は以下のように記述

tasks:
  - name: CentOS用httpdインストール
    yum: name=httpd state=latest
    when: ansible_distribution == 'CentOS'
    
  - name: Ubuntu用httpdインストール
    apt: name=apache2 state=latest
    when: ansible_distribution == 'Ubuntu'

ymlで指定しているansible_distributeはAnsibleが自動で実行しているsetupモジュールにより設定された変数名 4.デフォルトで用意される変数を使うを参照

whenの構文で変数は{{}}で囲まずに参照可能
whenで指定する条件はJinja2というPythonのテンプレートエンジンの文法を使用
whenで利用できる演算子は以下の通り

機能 演算子 利用例
比較 ==,!=,>,M,>=,<= when:size > 100
論理 and,or when:size > 100 and size < 200
真偽値 true,false when:false
含まれる in, not in when: name in ['hoge','hogehoge']|


3.2.複数のタスクをまとめて制御する「block」

複数のタスクに対し同じ条件を設定する場合

whenのみでは以下のように同じ条件判定を記載する必要がある。
修正に手間が掛かり、修正漏れも起こる可能性がある。

tasks:
  - name:CentOS用httpdインストール
    yum: name=httpd state=latest
    when: ansible_distribution == 'CentOS'
  
  - name:設定ファイルの転送
    copy: src=httpd.conf dest=/etc/httpd/conf/
    when: ansible_distribution == 'CentOS'

block要素を利用し、複数のタスクをまとめることが出来る。
blockに対しwhen要素を指定することで、条件判定を1箇所のみに可能

tasks:
  - block:
    - name: CentOS用httpdインストール
      yum: name=httpd state=latest
    - name: 設定ファイルの転送
      copy: src=httpd.conf dest=/etc/httpd/conf/
    when: ansible_distribution == 'CentOS'



4.タスクの実行結果を制御する

shellで実行したコマンドの戻り値が0でない場合は失敗
以降の処理は実行されなくなる。が、
戻り値が0以外でも正常終了として次の処理を実行したい場合

ignore_errors failed_when要素を利用する

4.1 実行失敗とみなされた場合でも無視して次のタスクに進む「ignore_errors」

ignore_errors を指定したタスクは実行失敗した場合でも次のタスクを実行できる。

tasks:
  - name:0以外を返すシェルの実行
    shell: /home/hoge/hoge.sh
    ignore_errors: true


4.2.任意の条件を使ってタスクの失敗判定を行う「failed_when」

failed_whenは任意の条件を使ってタスクの失敗判定を行いたい場合
実行したシェルの戻り値が2以上なら失敗の条件は以下のように記載

tasks:
  - name: 2以上ならエラーとするタスク
    shell: /home/hoge/hoge.sh
    register: result
    failed_when: result.rc >= 2

register:実行結果を変数に保存する機能、
registerで指定した値が変数名になり実行結果が保存される。

実行結果はマッピングで値が保存され、実行結果はrcというキーに保存
以下のように条件式として利用できる。

<省略>
    register: result
    failed_when: result.rc >= 2

注意!
モジュールの実行結果はモジュールごとに異なる
例:
shellモジュールの場合
stdout:標準出力
stderr:エラー出力

上記のキーで取得可能

モジュールの実行結果を確認したい場合

debugモジュールを利用
以下のようにモジュール結果を確認する方法として利用できる。

tasks:
  - shell: /home/hoge/hoge.sh
    register: result
  - debug: msg={{ result }}

その他の条件の書き方 Ansible Playbook の基本 | when / assert の条件指定 記法まとめ - Qiita

 Command実行後の戻り値

戻り値 — Ansible Documentation

ファイルに行を追記、置換を行う
方法 メリット デメリット
lineinfileモジュール ある程度複雑な行の指定が可能 該当行が複数あると難あり
replaceモジュール 複数箇所の変更が可能 複雑な行指定ができない
変数定義

参考サイト

変数定義には「vars」要素を使用します。
定義した変数の値を参照するには{{user_name}}のように{{変数名}}という形式を使います。