このブログ記事では、Ansibleにおけるプレイブックの更なる機能について紹介します。
前回の記事では、すべての管理対象ノードにパッケージをインストールするための基本的なアドホックコマンドとプレイブックについて説明しました。 しかし、実際のプロジェクトでよく必要とされる、サーバーを柔軟に設定するための機能は他にもあります。 そこで、この記事では、Ansibleプレイブックの他の機能について議論を続けていきます。
ノードとタスクのターゲティング
前回の記事では、すべてのノードに同じパッケージをインストールしましたが、リバースプロキシ、 Webサーバー、データベースサーバー、ファイルサーバーなど、異なるサーバーに対して異なるインストール要件を持つことがよくあります。 異なるサーバーセットに対して異なるコマンドを実行するには、以下に示すようにインベントリでそれらをグループ化できます。
[web_servers]
253.78.154.178
84.246.7.193
[db_servers]
156.72.61.90プレイブックでは、hostsフィールドの値をweb_serversまたはdb_serversに設定して、
指定されたノードでタスクを実行できます。例えば、WebサーバーにApacheとPHPをインストールしながら、
データベースサーバーにPostgreSQLをインストールするといったことです。
ただし、これらのタスクを同時に実行したくない場合があります。
実行するタスクをターゲットにするには、各タスクにapacheやpostgresのようなtagフィールドを追加し、
--tags <tag>フラグを付けてansible-playbookコマンドを実行できます。
指定されたタグに関係なく実行する必要があるタスクには、特別なタグalwaysを利用でき、
他のすべてのタスクの前に実行する必要があるタスクには、tasksの代わりにpre_tasksを使用できます。
ファイルとサービス
これまで、パッケージマネージャーを扱い、ノードにパッケージをインストールしてきました。
しかし、ローカルファイルやリモートファイルをノードにコピーする必要があることがよくあり、
これは以下に示すようにcopyモジュールで行うことができます。ソースファイルをsrc
(プレイブックと同じ親ディレクトリ内のfilesディレクトリのファイル名)で指定し、
宛先をdestで指定し、ユーザーとグループの権限を他のフィールドで指定できます。
...
# ローカルのhtmlをコピー
- name: copy html file
tags: apache
copy:
src: site.html
dest: /var/www/html/index.html
owner: root
group: root
mode: 0644
# unzipをインストール & リモートのファイルのインストールと解凍
- name: install unzip
package:
name: unzip
- name: install terraform
unarchive:
src: https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_linux_amd64.zip
dest: /usr/local/bin
remote_src: yes
owner: root
group: root
mode: 0755
...(Webサーバーよりもローカルワークステーションで必要とされることが多いとはいえ)上のように、
Terraformなどのリモートアーカイブをインストールして解凍することもできます。
管理対象ノードにファイルをコピーしてインストールすることで、
単にパッケージをインストールするよりもはるかに多くのことが可能になります。
さらに、httpdのような一部のパッケージでは、特定のノードでサービスを開始するためにsystemctlが必要であり、
これはserviceモジュールを使用して実現できます。
...
- name: start httpd (CentOS)
tags: apache
service:
name: httpd
state: started
enabled: yes
when: ansible_distribution == "CentOS"
- name: change http config
tags: apache
lineinfile:
path: /etc/httpd/conf/httpd.conf
regexp: '^ServerAdmin'
line: ServerAdmin example@exmaple.com
when: ansible_distribution == "CentOS"
register: httpd
- name: restart httpd upon config change
tags: apache
service:
name: httpd
state: restarted
when: httpd.changed
...最初のタスクはhttpdサービスを開始し、サービスがすでに開始されていて何らかの理由で無効になっている場合でも、
サービスが有効になっていることを確認します。2番目のタスクはlineinfileモジュールを使用してhttpd.confに変更を適用します。
httpd変数は、設定の変更時に実行される3番目のタスクのために登録され、httpd.changedで検出できます。
重要なのは、httpd.changedは、httpdが登録された直前のタスクが実行された場合にのみtrueを返すということです。
(間にhttpdが登録された別のタスクがあり、それが実行されなかった場合、httpd.changedはfalseと評価されます。)
ユーザーとブートストラップ
これまで、管理対象ノードでsudoコマンドを実行するために、すべてのコマンド実行で--ask-become-passを使用してsudoパスワードを使用してきました。
しかし、Ansible用の新しいユーザー(デフォルトユーザーではない)を作成し、そのユーザーのSSHキーを登録し、
ユーザーをsudoersファイルに追加し、そのユーザーを使用することでこのフラグを使わずにコマンドを実行することができます。
これらのプロセスは各ノードに対して手動で行うか、Ansibleプレイブックを利用してブートストラップすることができます。
- hosts: all
become: true
vars:
ansible_manager_user: ansible_user
ssh_public_key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"
tasks:
- name: create ansible user
tags: user
user:
name: "{{ ansible_manager_user }}"
group: "{{ 'wheel' if ansible_os_family == 'RedHat' else 'sudo' }}"
create_home: true
shell: /bin/bash
- name: add ssh key for ansible
tags: user
authorized_key:
user: "{{ ansible_manager_user }}"
key: "{{ ssh_public_key }}"
- name: add sudoer file for ansible
tags: user
copy:
src: sudoer_ansible # 'ansible ALL=(ALL) NOPASSWD: ALL' in it
dest: /etc/sudoers.d/{{ ansible_manager_user }}
owner: root
group: root
mode: 0440
validate: /usr/sbin/visudo -cf %s上記のbootstrap.yamlプレイブックは、varsフィールド、user、authorized_key、
およびcopyモジュールを利用して、ユーザー、そのSSHキー、およびsudoer権限を設定します。
-u <initial_user>、--ask-pass、--ask-become-passなどのフラグを使用してプレイブックを実行し、
ansible.cfgを編集してデフォルトユーザーをansible_userに設定することができます。
これが正常に実行された後は、--ask-become-passやsudoパスワードの使用なしに今後のプレイブックを実行できます。
結論
この記事では、Ansibleプレイブックで特定のノードやタスクをターゲットにし、ファイルやサービスを管理し、 ユーザーを設定する方法について説明しました。これらの機能により、実世界のアプリケーションに対してより柔軟で便利なサーバー設定が可能になります。 しかし、プレイブックがより長く、より複雑になってきています。そのため、次の記事では、Ansibleで必要なコンポーネントをきれいに整理するために利用できる追加機能について説明します。
リソース
- Ansible. n.d. Ansible Documentation. Ansible Community Documentation.
- Learn Linux TV. 2020. Getting started with Ansible. YouTube.