Ansible: template モジュールを使って nginx の バーチャルホスト設定

先日まとめたAnsible の Files モジュール群を見ていて、
そういえば template モジュールをあまりちゃんと使っていなかったなぁ、と思いました。
そんなわけで、軽く勉強がてらに記事にします。

Ansible Files Modules を整理してみる

前置き

template を適用するシーンは?

「同じようなことを一部だけ変えながら」作業する、というシーンで使えそうです。
今回は、nginx でバーチャルホスト設定をする想定で進めていきましょう。

環境

nginxを手っ取り早く動かすために、Vagrant + VirtualBox + Ubuntu で環境を作ります。
利用したVagrantfileは下記となります。

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.box = "ubuntu/trusty64"
  config.vm.network "private_network", ip: "192.168.33.10"

end

テンプレートエンジン

世の中にはテンプレートエンジンは数多あると思いますが、Ansibleで使えるのは Jinja2 というものです。

書き方は、こちらを参照してみてください。

Ansible template モジュールを使ってみる

nginx でバーチャルホスト利用する設定

Ansibleコマンドを実行するマシンで、OSのhostsファイルに下記を追加します。
私はmacOSなので、/etc/hostsファイルを修正。

192.168.33.10 sample1
192.168.33.10 sample2
192.168.33.10 sample3

ホスト2台として設定

下記のPlaybookファイルを作成します。
varshostsに、動作させたいサーバ名を記載しています。
今回は、sample1sample2だけを記載しておきます。

- hosts: all
  vars:
    hosts:
      - { name: sample1 }
      - { name: sample2 }
  tasks:
    - name: install nginx
      apt:
        name: nginx
        update_cache: yes
        state: latest

    - name: mkdir document root
      file:
        path: /var/www/{{ item.name }}
        state: directory
        mode: 0755
      with_items:
        "{{ hosts }}"

    - name: put vhost config
      template:
        src: vhost.conf.j2
        dest: /etc/nginx/sites-enabled/vhost.conf
      register:
        vhost_stat

    - name: put index.html
      template:
        src: index.html.j2
        dest: /var/www/{{ item.name }}/index.html
      with_items:
        "{{ hosts }}"

    - name: start nginx
      service:
        name: nginx
        state: restarted
      when: vhost_stat.changed

バーチャルホストの設定となる、nginx用のテンプレートファイルを下記のように作成します。

{% for host in hosts %}
server {
    listen 80;
    server_name {{ host.name }};

    access_log  /var/log/nginx/{{ host.name }}.access.log;

    location / {
        root   /var/www/{{ host.name }};
        index  index.html index.htm;
    } 
}

{% endfor %}

こちらは、動作確認用のHTMLファイル。これもテンプレートとして作成します。

Hello {{ item.name }} !

最後に、 Ansible 用のインベントリファイルを作成します。 Vagrant 向けの設定を書き込んでおく感じです。

[nginx-server]
server1 ansible_host=192.168.33.10

[nginx-server:vars]
ansible_user=vagrant
ansible_become=yes

実行 その1

では、実行してみましょう。

$ ansible-playbook -k -i hosts playbook.yml 
SSH password: 

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************

paramiko: The authenticity of host '192.168.33.10' can't be established.
The ssh-rsa key fingerprint is be44e9f69bbaee579121fa9e272e021c.
Are you sure you want to continue connecting (yes/no)?
yes
ok: [server1]

TASK [install nginx] ***********************************************************
changed: [server1]

TASK [mkdir document root] *****************************************************
changed: [server1] => (item={u'name': u'sample1'})
changed: [server1] => (item={u'name': u'sample2'})

TASK [put vhost config] ********************************************************
changed: [server1]

TASK [put index.html] **********************************************************
changed: [server1] => (item={u'name': u'sample1'})
changed: [server1] => (item={u'name': u'sample2'})

TASK [start nginx] *************************************************************
changed: [server1]

PLAY RECAP *********************************************************************
server1                    : ok=6    changed=5    unreachable=0    failed=0   

$ 

実行は無事できました。

ちゃんとWebサーバに繋がるでしょうか?ブラウザで接続してみましょう。

サーバsample1

http://sample1/へ接続します。
無事に表示されましたね。

サーバsample2

http://sample2/へ接続します。
こちらも当然ですが、きちんと表示されました。

サーバsample3

最後に、/etc/hostsに記載しましたが、Playbookでは記載していないホストです。
http://sample3/へ接続してみると。。。
nginxの初期ページが表示されました。これはこれで、想定通りです。

ホスト3台として設定

では、設定変更してみましょう。
varshostsに、sample3を下記のように追記します。

- hosts: all
  vars:
    hosts:
      - { name: sample1 }
      - { name: sample2 }
      - { name: sample3 }

実行 その2

では、再び Ansible を実行してみましょう。

$ ansible-playbook -k -i hosts playbook.yml 
SSH password: 

PLAY [all] *********************************************************************

TASK [setup] *******************************************************************
ok: [server1]

TASK [install nginx] ***********************************************************
changed: [server1]

TASK [mkdir document root] *****************************************************
ok: [server1] => (item={u'name': u'sample1'})
ok: [server1] => (item={u'name': u'sample2'})
changed: [server1] => (item={u'name': u'sample3'})

TASK [put vhost config] ********************************************************
changed: [server1]

TASK [put index.html] **********************************************************
ok: [server1] => (item={u'name': u'sample1'})
ok: [server1] => (item={u'name': u'sample2'})
changed: [server1] => (item={u'name': u'sample3'})

TASK [start nginx] *************************************************************
changed: [server1]

PLAY RECAP *********************************************************************
server1                    : ok=6    changed=5    unreachable=0    failed=0   

$

sample3が増えたことで影響のある箇所はchangedとなっていますね。素晴らしい。

サーバsample3

再度、sample3に接続してみましょう。
http://sample3/

はい、今度はきちんと表示されました。

まとめ

template便利ですね。
今後も使い所を研究していきたいと思います。

tacck
  • tacck
  • 北の大地の普通のソフトウェアエンジニア。
    インフラ・バックエンド・フロントエンドと、色々やります。

    初心者・若手向けのメンターも希望あればお受けします。

    勉強会運営中
    * ゆるWeb勉強会@札幌
    * スマートスピーカーで遊ぼう会@札幌