AnsibleでGCEロードバランシング

今回は、

* [gce_net](http://docs.ansible.com/gce_net_module.html) : GCEネットワーク・ファイアウォール設定
* [gce_lb](http://docs.ansible.com/gce_lb_module.html) : GCEロードバランサー設定

を使ったplaybookです。

[New Google Compute Engine Ansible Modules](https://asciinema.org/a/5996)
が分かりやすかったので、ほぼ丸々参考にさせてもらいました。

[ディレクトリ構成は前回同様](http://qiita.com/curious-eyes@github/items/c7feb3edbeb7c7c640e6#2-2)です。

以下、１つのplaybookですが、解説を入れるために分割して紹介します。
## playbook
### インスタンス生成

```yaml:master.yml
- name: Create new GCE instances
  hosts: localhost
  gather_facts: no
  vars_files:
    - "vars/instance.yml"
    - "vars/gce_auth.yml"
  tasks:
    - name: Launch instances
      local_action:
        module: gce
        instance_names: "{{ names }}"
        machine_type: "{{ type }}"
        image: "{{ image }}"
        zone: "{{ zone }}"
        service_account_email: "{{ service_account_email }}"
        pem_file: "{{ pem_file }}"
        project_id: "{{ project_id }}"
        tags: webserver
      register: gce
    - name: Wait for SSH to be available
      local_action: wait_for host={{ item.public_ip }} port=22
                    delay=20 timeout=30 state=started
      with_items: gce.instance_data
    - name: Get hostname and add host
      local_action: add_host hostname={{ item.public_ip }}
                    groupname=new_instances
      with_items: gce.instance_data
```

ここまでは前回とほぼ同様です。

インスタンス生成後に

* [wait_for](http://docs.ansible.com/wait_for_module.html)
* [add_host](http://docs.ansible.com/add_host_module.html)

を使って、生成先の情報を取得して、new_instances という Inventory変数に格納してます。

### Apacheインストール

```yaml:master.yml
- name: Install apache, set a custom index.html
  hosts: new_instances
  sudo: yes
  tasks:
    - name: Update apt
      apt: update_cache=yes
    - name: Install apache
      apt: pkg=apache2 state=present
    - name: remove default index.html
      command: removes=/var/www/index.html rm /var/www/index.html
    - name: custom index.html
      copy: dest=/var/www/index.html
            content='Hi, I am {{ ansible_hostname }}'
    - name: set file stats on index.html
      file: path=/var/www/index.html owner=root group=root mode=0644
    - name: custom healthstatus
      copy: dest=/var/www/isup.html content='ALIVE'
    - name: set file stats on healthstatus
      file: path=/var/www/isup.html owner=root group=root mode=0644
    - name: start apache
      service: name=apache2 state=started
```

取得した情報「hosts: new_instances」を使って、生成したインスタンス側で実行します。

OSはDebianを入れているので、apt-getでApacheをインストール。
その他、index.html を書き換えたり、
GCEロードバランサーのヘルスチェック用 isup.html を生成しています。

最後にApache起動。


### GCEネットワーク設定

```yaml:master.yml
- name: set up networking
  hosts: localhost
  gather_facts: no
  vars_files:
    - "vars/gce_auth.yml"
  tasks:
    - name: Allow HTTP traffic
      local_action:
        module: gce_net
        fwname: all-http
        name: default
        allowed: tcp:80
        service_account_email: "{{ service_account_email }}"
        pem_file: "{{ pem_file }}"
        project_id: "{{ project_id }}"
```

再び localhost での実行です。

gce_netモジュールを使ってファイアウォールを設定、
HTTP(80)を許可します。


### GCEロードバランサー設定

```yaml:master.yml
- name: Set up the load-balancer
  hosts: localhost
  gather_facts: no
  vars_files:
    - "vars/instance.yml"
    - "vars/gce_auth.yml"
  tasks:
    - name: Create LoadBalancer
      local_action:
        module: gce_lb
        name: lb
        httphealthcheck_name: hc
        httphealthcheck_port: 80
        httphealthcheck_path: "/isup.html"
        region: "{{ region }}"
        members: "{{ members }}"
        service_account_email: "{{ service_account_email }}"
        pem_file: "{{ pem_file }}"
        project_id: "{{ project_id }}"
```

最後にgce_lbモジュールで、ロードバランサー設定です。
冒頭で作成したヘルスチェック設定も追加してます。

以上がplaybookの内容です。

## vars | 変数の管理

```yaml:vars/instance.yml
names: www2,www3
type: f1-micro
image: debian-7
zone: asia-east1-a
region: asia-east1
members: ["asia-east1-a/www2", "asia-east1-a/www3"]
```

ロードバランシングするので、インスタンスを一度に２つ生成します。
names にカンマ区切りで複数指定できます。

gce_lbに渡す members パラメータは、GCEゾーン名も含める必要があるため、
別途定義しています。

## 実行！

```bash
$ cd ~/gce_ansible
$ ./play.sh master.yml

PLAY [Create new GCE instances] ******************
...(略)...

TASK: [Create LoadBalancer] **********************
changed: [127.0.0.1] => {"changed": true, "external_ip": "107.167.187.229", ...

PLAY RECAP ***************************************
107.167.178.56             : ok=9    changed=4    unreachable=0    failed=0
107.167.182.216            : ok=9    changed=4    unreachable=0    failed=0
127.0.0.1                  : ok=5    changed=3    unreachable=0    failed=0
```

最後の方に出力される「TASK: [Create LoadBalancer]」の結果に「external_ip」が出力されます。
これが今回のロードバランサーの公開IPアドレスですので、アクセスして確かめてみましょう。

## 動作確認

以下の確認用シェルスクリプトを「lb-test.sh」として作成してください。

```bash:lb-test.sh
#!/bin/bash
while true;
do
  curl -s http://$1;
  echo "";
  sleep 0.5;
done
```

公開IPアドレスを指定して、実行すると index.html に記述した文言が返却されて、ロードバランシングされていることが確認できます。

（「Ctrl-C」で強制終了）

```bash
$ cd ~/gce_ansible
$ ./lb-test.sh 107.167.187.229
Hi, I am www3
Hi, I am www2
Hi, I am www3
Hi, I am www3
Hi, I am www2
Hi, I am www2
Hi, I am www2
Hi, I am www3
Hi, I am www2
Hi, I am www2
^C
```

なかなか良いですね。