前提
Ubuntu 2 台を以下の記事に沿って設定済であること。
学べる事
- vars の使い方
- 繰り返し処理を行いたいときの loop の使い方
- ファイル作成コマンドの冪等性の保ち方
- handlers の使い方
playbook の中身
ubuntu-1 に task2.yml として以下を作成する。
- name: Nginx https setup hosts: ubuntu-2 gather_facts: false become: true vars: fqdn: www.example.com tasks: - name: Set ufw community.general.ufw: rule: allow to_port: "{{ item }}" proto: tcp state: enabled loop: - 22 - 80 - 443 - name: Install apt Package ansible.builtin.apt: name: - nginx - name: Make server.key ansible.builtin.shell: openssl genrsa -out server.key 3072 args: chdir: /etc/nginx/ creates: /etc/nginx/server.key - name: Make CSR ansible.builtin.shell: "openssl req -new -key server.key -out server.csr -subj '/C=JP/ST=Tokyo/L=Default City/O=Default Company Ltd/CN={{ fqdn }}'" args: chdir: /etc/nginx/ creates: /etc/nginx/server.csr - name: Make sans.txt ansible.builtin.shell: echo "subjectAltName = IP:192.168.1.14, DNS:{{ fqdn }}" > sans.txt args: chdir: /etc/nginx/ creates: /etc/nginx/sans.txt - name: Make certificate ansible.builtin.shell: openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -extfile sans.txt args: chdir: /etc/nginx/ creates: /etc/nginx/server.crt - name: Set nginx https conf ansible.builtin.shell: | cat << EOF > /etc/nginx/conf.d/tls.conf server { listen 443 ssl http2; server_name {{ fqdn }}; ssl_certificate "/etc/nginx/server.crt"; ssl_certificate_key "/etc/nginx/server.key"; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA"; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:1m; ssl_session_timeout 120m; root /usr/share/nginx/html; } EOF args: creates: /etc/nginx/conf.d/tls.conf notify: Restart nginx Service handlers: - name: Restart nginx Service ansible.builtin.service: name: nginx state: restarted
上記を作成後、ansible-playbook task2.yml を実行すると、nginx が https で動作するようになります。
ブラウザで https で IP を指定して接続してみましょう。
また、ansible-playbook を 2 回連続実行して冪等性を確認してみましょう。
解説
vars の使い方
vars では ansible で扱える変数を定義することができます。定義した変数は {{ }} の中に変数名を入れることで呼び出せます。
上記のサンプルでは vars で fqdn: www.example.com を指定していますので、tasks の各所で {{ fqdn }} と書くことで "www.example.com" を呼び出すことができています。
なのでもし fqdn を変更したい場合はこの vars の fqdn だけを変更すればよいのです。
ansible は自分で変数を定義するだけでなく、内部で用意されているものもあります。例えば gather_facts: trueを設定した play については ansible 変数と呼ばれるものが使えます。
ubuntu-2 で使える ansible 変数を事前に確認するには以下コマンドを実行します。
$ ansible ubuntu-2 -m setup
また、次に紹介する loop も内部で用意されている変数 {{ item }} を使います。
繰り返し処理を行いたいときの loop の使い方
ufw を設定する際、モジュールとしては 1 つのルールを作ることしかできませんが、それを複数タスクに分けて書くと効率も悪いし視認性も悪いです。
ansible では繰り返し処理を loop で行うことができます。今回の ufw の例では、to_port の箇所に変数 "{{ item }}" を配置し、loop の箇所で "{{ item }}" に入るポート番号を指定しています。これにより ansible は to_port: 22, to_port: 80, to_port: 443 を順番に実行していきます。
なお、YAML ではこのような変数を使う場合は必ず "" でダブルクォーテートする必要があります。{{ }} だけを囲むわけではなく、{{ }} が含まれるよう全体を囲みます。
なので 例えば上記で to_port: "10{{ item }}" と記述した場合、ufw で開くポートは 1022, 1080, 10443 になります。
| を使った場合はダブルクォーテーションと同じ効果があります。
ファイル作成コマンドの冪等性の保ち方
args には色々な引数を入れられますが、冪等性を担保する手段として creates と removes がよく使われます。
creates: <<file名>> と指定すると、そのファイルが存在するときはそのコマンドは実行せず、changed は返さず ok のみを返します。
同様に removes: <<file名>> と指定した場合は、そのファイルが存在しないときはそのコマンドは実行せず changed は返しません。
今回は一度ファイルを作成したらその後は再作成はしないようにしています。
handlers の使い方
設定ファイルを変更した後、サービスにその設定を反映させるためにはサービス再起動が必要になることが多いです。このようなときに使えるのが handlers です。
今回の例では、nginx はインストール時にサービス起動してしまいます。その後に conf.d/tls.conf という設定を格納した後は nginx の再起動が必要になりますが、これを task として入れてしまうと毎回サービス再起動するため、不要なサービス再起動が毎回行われるだけでなく、冪等性の評価指標である changed が毎回付いてしまいます。
なのでこれを task ではなく handlers に含めることによって、「notify: Restart nginx Service」が指定された task が changed になった場合に限り、その play が実行された後に「name: Restart nginx Service」のハンドラーが 1 回だけ実行されます。
なのでその play の中で複数の nginx 設定ファイルを変更したとしても、サービス再起動になるのは 1 回だけで済みます。
逆に、タスク毎に handlers を動作させたいなら以下のように play を分けるしかありません。
- name: Nginx https setup1 hosts: ubuntu-2 gather_facts: false become: true tasks: - name: Set nginx https conf ansible.builtin.shell: echo hoge notify: Restart nginx Service handlers: - name: Restart nginx Service ansible.builtin.service: name: nginx state: restarted - name: Nginx https setup2 hosts: ubuntu-2 gather_facts: false become: true tasks: - name: Set nginx https conf ansible.builtin.shell: echo fuga notify: Restart nginx Service handlers: - name: Restart nginx Service ansible.builtin.service: name: nginx state: restarted
この書き方であれば echo hoge ⇒ nginx 再起動 ⇒ echo fuga ⇒ nginx 再起動 という順番で処理を行います。
コメント