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

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

【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}}のように{{変数名}}という形式を使います。