記事ディレクトリ
プレイブックの再利用
Ansible でサポートされている 2 つの再利用メカニズムは、ロールとインクルードです。
-
Roles
これは再利用可能なタスクと変数のコレクションであり、プログラミング言語のパッケージに似た概念です。 -
Includes
これは、Playbook を複数のファイルに分解する方法であり、よく使用されるいくつかのタスクと変数を別のファイルに配置し、必要な Playbook でこれらのファイルを参照できます。
インクルードステートメント
Ansible では、 include キーワードを使用して 1 つ以上のファイルをプレイブックに導入し、重用
コードの目的を達成できます。よく使うタスクや共通のタスクを1つのファイルに記述することで、それらのタスクのコードを避免
各 Playbook に含めることができ重复编写
、作業負荷が大幅に軽減されます。さらに、提高代码的可读性和可理解性
一般的なコードは抽象化されているため、 include ステートメントを使用しても問題ありません使得Playbook的代码更加简洁清晰,易于维护和更新
。同時に、 include ステートメントの使用も役立ちます降低代码的耦合性
。共通のタスクを抽象化すると、異なる Playbook 間の依存関係が明確になり、過剰なコード結合の問題を回避できるからです。
以下は、include ステートメントを使用した簡単な例です。
2 つの Playbook (web.yaml と db.yaml) が使用される Ansible プロジェクトがあるとします。これらは、それぞれ Web サーバーとデータベース サーバーのデプロイに使用されます。次に、2 つの Playbook に同じタスク コードを繰り返し記述することを避けるために、共通のタスク ファイル common.yaml を 2 つの Playbook に導入します。
まず、プロジェクトのルート ディレクトリに「tasks」という名前のフォルダーを作成し、共通タスク ファイル common.yml を保存します。次に、次の内容を含む common.yml という名前のファイルをフォルダーに作成します。
- name: install packages
remote_user: root
yum:
name: git,vim,curl,wget,unzip,zip,net-tools
state: present
このタスクは、Web サーバーとデータベース サーバーの両方にインストールする必要がある、一般的に使用されるいくつかのソフトウェア パッケージをインストールするために使用されます。
次に、web.yaml と db.yaml の include ステートメントを使用してファイルを導入します。コードは次のとおりです。
web.yaml ファイル:
- name: Deploy web server
hosts: test1
tasks:
- include: tasks/common.yaml
- name: install and configure Apache
yum:
name: httpd
state: present
- service:
name: httpd
enabled: true
state: started
db.yaml ファイル:
- name: Deploy database server
hosts: test2
tasks:
- include: tasks/common.yaml
- name: install and configure Mysql
yum:
name: mariadb-server
state: present
- service:
name: mariadb
enabled: true
state: started
上記のコードでは、include ステートメントを使用して、tasks/common.yml ファイル内のタスクを導入しています。これにより、共通ソフトウェア パッケージをインストールするためのタスク コードを web.yaml および db.yaml に繰り返し記述することがなくなります。
役割の書き方
ロールには、include よりも強力で柔軟なコードの再利用および共有メカニズムがあります。include はプログラミング言語の include に似ており、単一のファイルを再利用しますが、再利用機能は限られています。
この役割はプログラミング言語の「パッケージ」に似ており、一連のファイルを再利用して完全な関数を形成できます。たとえば、Apache のインストールと構成には、インストール パッケージを実装してテンプレートをコピーするタスクだけでなく、httpd.conf と Index.html のテンプレート ファイル、およびハンドラー ファイルによって実装される再起動機能も必要です。これらのファイルは、別の Playbook ファイルで再利用するためにロールに配置できます。
ロールの完全なディレクトリ構造を定義する
在Ansible中,通过遵循特定的目录结构,就可以实现对role定义。
では、ロール ディレクトリはどのように作成するのでしょうか?
ansible-galaxy init myrole
# 上述命令会在当前目录下创建一个名为myrole的目录,其默认包含了标准的角色目录结构。
標準的な役割のディレクトリ構造は次のとおりです。
ansible.yamlでロールを呼び出したい場合
---
- hosts: test1
remote_user: root
roles:
- myrole
Ansible では、ロールに上記のディレクトリとファイルをすべて含める必要はなく、ロールの機能に応じて対応するディレクトリとファイルを追加できます。各ディレクトリとファイルの機能は次のとおりです。
- タスク ディレクトリ: 必須のロール タスク ファイルを保存します
main.yaml
。必要に応じて他のタスク ファイルを追加できます。 - templates ディレクトリ: ロールで使用される Jinja2 テンプレート ファイルを保存します。
- ファイルディレクトリ: キャラクターが使用する通常のファイルを格納します。
- vars ディレクトリ: ロールによって使用される
main.yaml
必須の変数ファイルを保存します。必要に応じて他の変数ファイルを追加できます。 - デフォルト ディレクトリ: ロールのデフォルト変数を保存します。これは
main.yaml
必須です。必要に応じて、他のデフォルト変数ファイルを追加できます。 - メタ ディレクトリ: キャラクター名、作者、依存関係、その他の情報を含むキャラクターのメタデータ ファイルを保存します。
- handlers ディレクトリ: 必須のロール ハンドラーを格納します
main.yaml
。必要に応じて他のハンドラーを追加できます。 - README.md: ロールの目的、使用方法、その他の情報を含む、ロールの説明ファイル。
- テスト ディレクトリには次のファイルが含まれています。
inventory
: ロールのテスト ケースのホスト リスト ファイル。テスト ケースで使用する必要があるホストおよびホスト グループ情報を定義します。test.yaml
: ロールのテスト ケース ファイル。テスト ケースで実行する必要があるタスクとテスト メソッドを定義します。
また、以下のファイルは絶対パスや相対パスである必要はなく、同一ディレクトリに配置されたファイルと同様に直接使用できます。
copy または scipt は、roles/x/files/ の下にあるファイルを使用します。
テンプレートは、roles/x/templates の下にあるファイルを使用します
include は、roles/x/tasks の下にあるファイルを使用します
ロールを作成するときは、通常、ロール エントリ ファイルroles/x/tasks/main.yamlを含める必要がありますが、必要に応じて他のファイルやディレクトリを追加することもできます。
パラメータ付きのロール
以下は、myrole という名前のパラメーターを含むロールを定義します。そのディレクトリ構造は次のとおりです。
main.yaml
roles
myrole
tasks
main.yaml
role/myrole/tasks/main.yaml では、 { { }} で定義された変数を使用するだけです。
---
- name: use param
debug:
msg="{
{ param }}"
パラメータを指定してロールを使用する
main.yaml では、myrole を次のように使用できます。
---
- hosts: test1
remote_user: root
roles:
- role: myrole
param: 'Test ansible'
- role: myrole
param: 'Test ansible2'
ロールはデフォルトパラメータを指定します
デフォルトパラメータを指定した後、呼び出し時にパラメータが渡された場合は渡されたパラメータ値が使用され、呼び出し時にパラメータが渡されなかった場合はデフォルトのパラメータ値が使用されます。
デフォルトパラメータの指定は非常に簡単です。例として上記のパラメータを取り上げます。
main.yaml
roles
myrole
tasks
main.yaml
defaults
main.yaml
ロール/myrole/defaults/main.yaml 内
---
- hosts: test1
remote_user: root
roles:
- role: myrole
- role: myrole
param: "I am the value from external"
デフォルト変数と通常の変数の違い
前の定義で、なぜデフォルトフォルダーと vars 配下の変数が Play に追加されるのか不思議に思われるかもしれませんが、これらは上記とは異なるのでしょうか?
default/main.yaml はデフォルトの変数です。優先順位はすべての変数の中で最も低く、上書きする必要があるいくつかの変数を配置するために使用されます。
vars/main.yaml 内の変数は、比較的優先度の高いロール変数です。上書きされたくない変数も配置されます。そのため、通常、変数に名前を付けるときに、プレフィックスとしてロールの名前が追加されます。配置すると、ロールの名前が付加されます。 Playbook で定義された変数によって誤って上書きされる可能性があります。
task/main.yaml 変数、静的ファイル、テンプレートの使用方法
タスクは Playbook とロールの中核であり、ロールは Playbook を整理する方法であり、タスク、テンプレート、変数、ファイルなどのリソースが含まれます。ロールでは、タスク ファイル task/main.yaml がエントリ ファイルとなり、変数、静的ファイル、テンプレートなどのリソースを使用できます。これらのリソースの使用方法を学ぶことが、役割を作成するための鍵となります。
ロール内のリソースは、次の 2 つのカテゴリに分類できます。
- 1 つのクラスが自動的にロードされ、通常は x/*/main.yaml に配置されます。
- もう 1 つの型は明示的に呼び出す必要があり、通常は x/*/other_but_main.yaml に配置されます。
x/*/main.yaml で変数を使用する
x/*/main.yaml で変数とハンドラーを使用する
同じ Playbook 内のリソースと同じように、x/*/main.yaml 内の変数とハンドラーを使用します。
x/{files,template}/ にあるファイルを使用する
ここに配置された変数は、同じディレクトリ内のファイルであるかのように使用します。一致するために使用されるモジュールとファイルタイプが必要です
コピーとスクリプトはファイルディレクトリ内のファイルに対応します
テンプレートはテンプレートの下のファイルに対応します
たとえば、ロール x のディレクトリは次のとおりです。
[root@localhost ansible]# tree myrole/
myrole/
├── files
│ └── index.html
├── tasks
│ └── main.yml
├── templates
│ └── httpd.conf.j2
└── vars
└── main.yml
以下のファイルは、
<!DOCTYPE html>
<html>
<head>
<title>hello world</title>
</head>
<body>
hi I am csq
</body>
</html>
vars 配下のファイルは、
---
# http.conf vars
http_port: 9999
タスクの下にあるファイルは、
---
- name: Deploy server web
yum:
name: httpd
state: present
- name: copy index.html
copy:
src: index.html
dest: /var/www/html/index.html
- name: copy http.conf
template:
src: httpd.conf.j2
dest: /etc/httpd/conf/httpd.conf
- name: service restart
service:
name: httpd
enabled: true
state: restarted
- name: Release Port
firewalld:
port: 9999/tcp
permanent: true
state: enabled
この役割を実行します
---
- hosts: test1
remote_user: root
roles:
- myrole
x/*/other_but_main.yaml のリソースを使用する
ロール x のコンテンツがより複雑で、タスクまたは変数をさらに分類する必要がある場合は、main.yaml 以外のファイルを使用できます。他のファイルでタスクまたは変数を使用するにはどうすればよいですか? Ansible には、main.yaml 以外のロール内の他のファイルに含まれるタスクと変数を導入するために、それぞれ include と include_vars という 2 つのキーワードが用意されています。
たとえば、次のロールでは
myrole/
├── tasks
│ └── main.yml
│ └── http_install.yaml
│ └── http_configure.yaml
│ └── mysql_install.yaml
│ └── mysql_configure.yaml
├── templates
│ └── httpd.conf.j2
│ └── mysql.conf.j2
└── vars
└── httpd.yaml
└── mysql.yaml
次に、x/*/main.yaml で、include_var を介して httpd 変数を導入した後、include を介してファイル install.yaml および configure.yaml 内のタスクをロードできます。
---
- name: add the os specific varibles
include_vars: httpd.yaml
- name: install packages
yum:
name: {
{
packages}}
state: present
- include: http_install.yaml
- include: http_configure.yaml
役割の依存関係
Nginx をインストールするには、yum リポジトリを構成する必要があります。Nginx Playbook で yum リポジトリを構成する機能を再実装したくない場合は、ロールの依存関係によって解決できます。ロールの依存関係の定義ファイルはx/meta/main.yamlです。ロール x がロール y に依存するものとして定義されている場合、Playbook でロール x が呼び出される前に、ロール y が呼び出されます。複数のロールが同じロールに依存する場合、Ansible は自動的にフィルタリングして、同じパラメータでロールを繰り返し呼び出すことを回避します。
次の例では、ロール db と Web の両方がロール common に依存しています。Playbook で db と Web が呼び出された場合、Ansible はロール common が最初に 1 回だけ実行されてから、ロール db と Web が実行されるようにします。
playbook.yaml
roles
├── common
│ └── tasks
│ └── main.yaml
├── db
│ ├── meta
│ │ └── main.yaml
│ └── tasks
│ └── main.yaml
└── web
├── meta
│ └── main.yaml
└── tasks
└── main.yaml
{web,db}/meta/main.yaml に追加します
dependencies:
- {
role: common }
common以下のmain.yamlの内容は
- name: xiugai quanxian
command: chattr -a csq.txt
Web の下の main.yaml の内容は次のとおりです。
- name: shuru xinxi
shell: echo "I am web,hi csq" >> csq.txt
- name: jia quanxian
command: chattr +a csq.txt
db以下のmain.yamlの内容は
- name: shuru xinxi
shell: echo "I am db,hi csq" >> csq.txt
- name: jia quanxian
command: chattr +a csq.txt
playbook.yaml の内容は次のとおりです。
---
- hosts: test1
remote_user: root
roles:
- common
- db
- web
の結果
[root@localhost ansible]# ansible-playbook main.yaml
PLAY [test1] ***********************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************
ok: [192.168.200.30]
TASK [common : xiugai quanxian] ****************************************************************************************************************************
changed: [192.168.200.30]
TASK [db : shuru xinxi] ************************************************************************************************************************************
changed: [192.168.200.30]
TASK [db : jia quanxian] ***********************************************************************************************************************************
changed: [192.168.200.30]
TASK [web : shuru xinxi] ***********************************************************************************************************************************
changed: [192.168.200.30]
TASK [web : jia quanxian] **********************************************************************************************************************************
changed: [192.168.200.30]
PLAY RECAP *************************************************************************************************************************************************
192.168.200.30 : ok=6 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
次に、リモート ホストのコンテンツが変更されているかどうか、および非表示のアクセス許可がまだ存在しているかどうかを確認します。
[root@localhost ansible]# ansible test1 -m shell -a "cat csq.txt && lsattr csq.txt"
192.168.200.30 | CHANGED | rc=0 >>
I am web,hi csq
I am web,hi csq
-----a---------- csq.txt