構成管理101:Ansible Playbookの作成

はじめに

要するに、サーバー構成管理(一般的にITオートメーションとも呼ばれる)は、インフラ管理をコードベースに変換し、サーバーを展開するために必要なすべてのプロセスを記述したプロビジョニングスクリプトのセットに変換するソリューションです。これにより、サーバーインフラストラクチャの信頼性を長期間にわたって大幅に向上させることができます。

以前のガイドでは、サーバーインフラストラクチャに構成管理戦略を実装する主な利点、構成管理ツールの動作方法、およびこれらのツールが一般的に持つ特徴について説明しました。

このシリーズのこの部分では、Ansibleを使用してサーバープロビジョニングを自動化するプロセスを説明します。Ansibleは、完全な自動化フレームワークとオーケストレーション機能を提供し、究極のシンプリシティと最小限の機能を維持しながら、サーバーの展開を完全に自動化することを目指しています。ここでは、Ubuntu 18.04ウェブサーバーの展開を完全に自動化するための簡略化された例を作成するのに必要な言語用語、構文、および機能に焦点を当てます。

次のリストに、目標を達成するために自動化する必要があるすべての手順が含まれています:

  1. aptキャッシュを更新する
  2. Apacheをインストールする
  3. カスタムドキュメントルートディレクトリを作成する
  4. index.htmlファイルをカスタムドキュメントルートに配置します
  5. カスタム仮想ホストの設定にテンプレートを適用します
  6. Apacheを再起動します

まず、Ansibleが使用する用語を見て、その後、playbookを記述するために使用できる主要な言語機能の概要を示します。ガイドの最後には、Ubuntu 18.04でApacheをセットアップするために記述された手順を自動化するための完全なプロビジョニング例の内容が記載されています。

注意: このガイドは、Ansible言語とサーバープロビジョニングを自動化するためのplaybookの書き方について紹介することを意図しています。Ansibleのより入門的なビュー、このツールのインストールと開始方法、およびAnsibleコマンドとplaybookの実行方法に必要な手順については、当社のUbuntu 18.04でAnsibleをインストールして設定する方法ガイドを参照してください。

はじめに

Ansibleのより実践的なビューに移る前に、このツールによって導入された重要な用語や概念に慣れておくことが重要です。

用語

以下のリストは、Ansibleで使用される最も関連性の高い用語の概要です:

  • コントロールノード: Ansibleがインストールされているマシンであり、管理しているサーバー上でプロビジョニングを実行する責任があります。
  • インベントリ: 管理しているサーバーに関する情報を含むINIファイルです。
  • プレイブック: 自動化すべき手順の一連を含むYAMLファイルです。
  • タスク: 実行する単一の手順を定義するブロックです。例: パッケージのインストール。
  • モジュール: 通常、パッケージの取り扱いやファイルの作成や変更など、システムタスクを抽象化するモジュールです。Ansibleには多数の組み込みモジュールがありますが、カスタムモジュールも作成できます。
  • ロール: 関連するプレイブック、テンプレート、およびその他のファイルのセットで、再利用と共有を容易にするために事前に定義された方法で整理されています。
  • プレイ: 開始から終了まで実行されるプロビジョニングをプレイと呼びます。
  • ファクト: ネットワークインターフェースやオペレーティングシステムなどのシステムに関する情報を含むグローバル変数です。
  • ハンドラ: サービスの状態変更をトリガーするために使用されます。例えば、サービスの再起動やリロードです。

タスクフォーマット

A task defines a single automated step that should be executed by Ansible. It typically involves the usage of a module or the execution of a raw command. This is how a task looks:

- name: This is a task
  apt: name=vim state=latest

name 部分は実際にはオプションですが、実行時にタスクの出力に表示されるため、推奨されています。 apt 部分は、Debianベースのディストリビューションでパッケージの管理を抽象化する組み込みのAnsibleモジュールです。 この例のタスクは、パッケージ vim の状態を latest に変更する必要があることをAnsibleに伝えます。これにより、パッケージマネージャがこのパッケージがまだインストールされていない場合には、このパッケージをインストールします。

プレイブックの形式

プレイブックは、サーバーのプロビジョニングを自動化するための一連の指示を含む YAML ファイルです。次の例は、2つのタスクを実行する単純なプレイブックです: apt キャッシュを更新し、その後に vim をインストールします:

---
- hosts: all
  become: true
  tasks:
     - name: Update apt-cache 
       apt: update_cache=yes

     - name: Install Vim
       apt: name=vim state=latest

YAML は、データ構造を直列化するためにインデントを使用します。そのため、プレイブックを作成する際には特に、例をコピーする際には、正しいインデントを維持するように特に注意する必要があります。

このガイドの終わりまでに、詳細に説明されたプレイブックのより実践的な例を見ることになります。次のセクションでは、Ansibleプレイブックを記述するために使用できる最も重要な要素と機能について概説します。

プレイブックの作成

今、Ansibleのプレイブックとタスクの基本用語や全体の形式に慣れたところで、より柔軟な自動化を作成するのに役立ついくつかのプレイブックの機能について学びます。

変数の操作

Ansibleでは変数を定義するさまざまな方法があります。最も簡単な方法は、プレイブックのvarsセクションを使用することです。以下の例では、後でタスク内で使用されるpackageという変数が定義されています:

---
- hosts: all
  become: true
  vars:
     package: vim
  tasks:
     - name: Install Package
       apt: name={{ package }} state=latest

package変数はグローバルスコープを持っているため、プロビジョニングの任意のポイントからアクセスできます。これには、含まれるファイルやテンプレートも含まれます。

ループの使用

ループは、異なる入力値を使用してタスクを繰り返すために通常使用されます。たとえば、10個の異なるパッケージをインストールするために10のタスクを作成する代わりに、1つのタスクを作成して、使用したいすべての異なるパッケージでタスクを繰り返すためにループを使用できます。

タスク内でループを作成するには、値の配列とともにwith_itemsオプションを含めます。内容は、以下の例に示すようにループ変数itemを介してアクセスできます:

- name: Install Packages
  apt: name={{ item }} state=latest
  with_items:
     - vim
     - git
     - curl  

また、配列変数を使用してアイテムを定義することもできます。

---
- hosts: all
  become: true
  vars:
     packages: [ 'vim', 'git', 'curl' ]
  tasks:
     - name: Install Package
       apt: name={{ item }} state=latest
       with_items: "{{ packages }}"

条件文の使用

条件文は、変数やコマンドの出力に基づいて、タスクを動的に実行するかどうかを決定するために使用できます。

次の例では、Debianベースのシステムのみシャットダウンします。

- name: Shutdown Debian Based Systems
  command: /sbin/shutdown -t now
  when: ansible_os_family == "Debian"

条件文whenは評価する式を引数として受け取ります。式がtrueに評価された場合にのみタスクが実行されます。この例では、ファクトをテストして、オペレーティングシステムがDebianファミリーかどうかを確認しました。

A common use case for conditionals in IT automation is when the execution of a task depends on the output of a command. With Ansible, the way we implement this is by registering a variable to hold the results of a command execution, and then testing this variable in a subsequent task. We can test for the command’s exit status (if failed or successful). We can also check for specific contents inside the output, although this might require the usage of regex expressions and string parsing commands.

次の例では、php -vコマンドの出力に基づいて2つの条件付きタスクを示しています。このサーバーにPHPがインストールされていない場合、コマンドの実行が失敗することがわかっているので、コマンドの終了ステータスをテストします。タスクのignore_errors部分は、コマンドが実行に失敗した場合でもプロビジョニングを続行するために重要です。

- name: Check if PHP is installed
  register: php_installed
  command: php -v
  ignore_errors: true

- name: This task is only executed if PHP is installed
  debug: var=php_install
  when: php_installed|success
  
- name: This task is only executed if PHP is NOT installed
  debug: msg='PHP is NOT installed'
  when: php_installed|failed

ここで使用されているdebugモジュールは、変数の内容やデバッグメッセージを表示する便利なモジュールです。文字列を出力する場合はmsg引数を使用し、変数の内容を出力する場合はvar引数を使用できます。

テンプレートの操作

テンプレートは、通常、設定ファイルを設定するために使用され、これらのファイルをより柔軟で再利用可能にするための変数やその他の機能を利用します。AnsibleはJinja2テンプレートエンジンを使用します。

次の例は、Apache仮想ホストを設定するためのテンプレートであり、このホストのドキュメントルートを設定するための変数を使用しています:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot {{ doc_root }}

    <Directory {{ doc_root }}>
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

組み込みモジュールtemplateを使用して、タスクからテンプレートを適用します。上記のテンプレートファイルの名前をvhost.tplとし、それをプレイブックと同じディレクトリに配置した場合、デフォルトのApache仮想ホストを置き換えるためにテンプレートを適用する方法は次のとおりです:

- name: Change default Apache virtual host
  template: 
    src: vhost.tpl
    dest: /etc/apache2/sites-available/000-default.conf

ハンドラの定義とトリガー

ハンドラは、サービスの状態変更(再起動停止など)をトリガーするために使用されます。通常、通常のタスクと非常に似て見えるかもしれませんが、ハンドラは以前にタスク内のnotifyディレクティブからトリガーされたときにのみ実行されます。通常、プレイブックのhandlersセクション内で配列として定義されますが、別のファイルに存在することもあります。

前述のテンプレート使用例を考慮してみましょう。Apache仮想ホストを設定しました。仮想ホストの変更後にApacheが再起動されることを確認したい場合、まずApacheサービスのためのハンドラを作成する必要があります。これが、プレイブック内でハンドラが定義される方法です:

handlers:
    - name: restart apache
      service: name=apache2 state=restarted
    
    - name: other handler
      service: name=other state=restarted

nameディレクティブは、このハンドラの一意の識別子になるため重要です。タスクからこのハンドラをトリガーするには、notifyオプションを使用する必要があります:

- name: Change default Apache virtual host
  template: 
    src: vhost.tpl
    dest: /etc/apache2/sites-available/000-default.conf
  notify: restart apache

AnsibleのPlaybookを作成するのに使える最も重要な機能のいくつかを見てきました。次のセクションでは、UbuntuでApacheのインストールと設定を自動化するPlaybookの実例について詳しく見ていきます。

実例のPlaybook

さて、このガイドの紹介で議論されているように、Ubuntu 18.04システム内にApacheウェブサーバーを自動インストールするPlaybookを見てみましょう。

テンプレートファイルを使用してApacheを設定し、ウェブサーバーで提供されるHTMLファイルも含めた完全な例は、GitHubで見つけることができます。また、このフォルダには、Vagrantによって管理される仮想マシンを使用してPlaybookを簡略化されたセットアップでテストできるVagrantfileも含まれています。

Playbookの内容

このPlaybookの全内容は、以下でご確認いただけます:

playbook.yml
  1. ---
  2. - hosts: all
  3. become: true
  4. vars:
  5. doc_root: /var/www/example
  6. tasks:
  7. - name: Update apt
  8. apt: update_cache=yes
  9. - name: Install Apache
  10. apt: name=apache2 state=latest
  11. - name: Create custom document root
  12. file: path={{ doc_root }} state=directory owner=www-data group=www-data
  13. - name: Set up HTML file
  14. copy: src=index.html dest={{ doc_root }}/index.html owner=www-data group=www-data mode=0644
  15. - name: Set up Apache virtual host file
  16. template: src=vhost.tpl dest=/etc/apache2/sites-available/000-default.conf
  17. notify: restart apache
  18. handlers:
  19. - name: restart apache
  20. service: name=apache2 state=restarted

このPlaybookの各部分を詳しく見てみましょう。

ホスト: 全て
プレイブックは、インベントリ内のすべてのホストに適用されるべきであることを述べて始まります(hosts: all)。プレイブックの実行を特定のホストまたはホストグループに制限することも可能です。このオプションは実行時に上書きすることができます。

become: true
become: true の部分は、Ansibleにすべてのタスクを実行するための特権昇格(sudo)を使用するよう指示します。このオプションはタスクごとに上書きすることができます。

vars
タスクで後で使用される変数doc_rootを定義します。このセクションには複数の変数を含めることができます。

tasks
実際のタスクが定義されるセクションです。最初のタスクはaptキャッシュを更新し、2番目のタスクはapache2パッケージをインストールします。

3番目のタスクでは、ドキュメントルートとして機能するディレクトリを作成するために組み込みモジュールfileを使用します。このモジュールはファイルとディレクトリを管理するために使用できます。

4番目のタスクでは、ローカルファイルをリモートサーバーにコピーするためにcopyモジュールを使用します。Apacheによってホストされるウェブサイトとして提供される単純なHTMLファイルをコピーしています。

handlers
最後に、サービスが宣言されるhandlersセクションがあります。Apacheテンプレートが適用される4番目のタスクから通知されるrestart apacheハンドラを定義します。

プレイブックの実行

このプレイブックの内容をAnsibleコントロールノードにダウンロードしたら、ansible-playbookを使用して、インベントリ内の1つまたは複数のノードで実行できます。次のコマンドは、SSHキーペア認証を使用して現在のシステムユーザーとして接続し、デフォルトのインベントリファイルからすべてのホストでプレイブックを実行します。

  1. ansible-playbook playbook.yml

-lを使用して、インベントリから単一のホストまたはホストグループに実行を制限することもできます。

  1. ansible-playbook -l host_or_group playbook.yml

リモートサーバーに接続するための異なるSSHユーザーを指定する必要がある場合は、そのコマンドに引数-u userを含めることができます。

  1. ansible-playbook -l host_or_group playbook.yml -u remote-user

Ansibleコマンドとプレイブックの実行方法の詳細については、Ubuntu 18.04にAnsibleをインストールして構成する方法を参照してください。

結論

Ansibleは、プロビジョニングスクリプトにYAMLを使用するミニマリストのIT自動化ツールです。インストールパッケージやテンプレートの作成などのタスクを抽象化するために使用できる多数の組み込みモジュールがあります。シンプルなインフラ要件と簡単な言語を備えており、構成管理を始める人々に適しています。ただし、PuppetやChefのより複雑なツールには見られる一部の高度な機能が不足しているかもしれません。

このシリーズの次の部分では、プロビジョニングスクリプトを記述するためにRubyをベースとした表現力豊かで強力なカスタムDSLを使用する人気で確立された構成管理ツールであるPuppetの実践的な概要を見ていきます。

Source:
https://www.digitalocean.com/community/tutorials/configuration-management-101-writing-ansible-playbooks