AnsibleでのPostgreSQLインストール方法

AnsibleでPostgreSQLをインストールする手順も調べたのでメモしておく。前回の[PuppetでのPostgreSQLインストール方法](http://qiita.com/bwtakacy/items/eb1fa4c081f864d94567)の姉妹編である。

環境は
* CentOS 7.2
* Ansible 2.0.2.0


# Ansibleのインストール

Pythonの2.6 or 2.7が必要らしい。

```
# python -V
Python 2.7.5
```

AnsibleのパッケージはEPELで公開されているので、epel-releaseを入れる。

```
# yum install epel-release
```

Ansibleをyumでインストール。

```
# yum install ansible
# ansible --version
ansible 2.0.2.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
```

# SSH接続の設定

AnsibleはSSH接続で動作するので、設定を行っておく。今回は自サーバにSSH接続する設定をする。

```
# ssh-keygen -t rsa
# cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
# chmod 600 ~/.ssh/authorized_keys
# ssh-agent bash
# ssh-add ~/.ssh/id_rsa
```

ansibleのhostsファイルに接続先サーバのIPアドレスを記載しておく。

```/etc/ansible/hosts
[dbservers]
192.168.56.101
```

設定が正しくできているかをping等で確かめる。

```
# ansible all -m ping
192.168.56.101 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
# ansible all -a "/bin/echo hello"
192.168.56.101 | SUCCESS | rc=0 >>
hello

# ansible all -a "/bin/date"
192.168.56.101 | SUCCESS | rc=0 >>
2016年  5月 21日 土曜日 23:22:10 JST

```

# お試しPlaybookを作る

Playbookの置き場所を用意しておく。

```
# mkdir /etc/ansible/playbooks
```

とりあえず、pingするだけのplaybookを作ってみる。

```/etc/ansible/playbooks/postgresql.yml 
---
- hosts: dbservers
  remote_user: root
  tasks:
    - name: test connection
      ping:
```

実行させる。

```
[root@localhost playbooks]# ansible-playbook postgresql.yml 

PLAY [dbservers] ***************************************************************

TASK [setup] *******************************************************************
ok: [192.168.56.101]

TASK [test connection] *********************************************************
ok: [192.168.56.101]

PLAY RECAP *********************************************************************
192.168.56.101             : ok=2    changed=0    unreachable=0    failed=0   

```

ふむ。うまくいっているようです。

# PostgreSQLのインストール&起動するplaybookを作る

[Ansibleのドキュメント](http://docs.ansible.com/ansible/index.html)を見ながら作ったのが以下のplaybook。


```postgresql.yml 
---
- hosts: dbservers
  remote_user: root
  tasks:
    - name: test connection
      ping:
    - name: install yum repository
      yum: name=https://download.postgresql.org/pub/repos/yum/9.5/redhat/rhel-7-x86_64/pgdg-centos95-9.5-2.noarch.rpm 
    - name: install postgresql server
      yum: name={{ item }} state=installed
      with_items:
        - postgresql95
        - postgresql95-server

    - stat: path=/var/lib/pgsql/9.5/data/PG_VERSION
      register: dbcluster
    - name: initdb
      shell: /usr/pgsql-9.5/bin/initdb -D /var/lib/pgsql/9.5/data --no-locale
      become: yes
      become_user: postgres
      when: not dbcluster.stat.exists

    - name: start postgresql server
      service: name=postgresql-9.5 state=started 

##Danger!! These below are not idempotent.
#    - name: create test db
#      shell: /usr/pgsql-9.5/bin/createdb test
#      become: yes
#      become_user: postgres
#
#    - name: create pgbench tables
#      shell: /usr/pgsql-9.5/bin/pgbench -i test
#      become: yes
#      become_user: postgres

```

## このplaybookでやっていること
PostgreSQL公式のRPMを使ってインストールしている。

少し面倒なのが、べき等性を守るように書かないといけないところ。
initdbのところでまずつまずいたので、上のようにstatを使ってDBクラスタが存在していないときだけinitdbすることを目指してみている。
PG_VERSIONの存在を使っているあたりがちょっと怪しい。
DBクラスタのディレクトリ自体の存在で判断したいところだが、空のディレクトリが用意されているだけの場合をどうするのか迷ったのでこんな感じにしている。

DB作成やテーブル作成はさらにべき等性の確保が難しい。。。
shellコマンドの戻り値でチェックしだすと、普通にオレオレshell scriptでやっていることを無理やりAnsibleの文法に置き換えるだけになりそうで止めてしまった。
Ansibleのドキュメントをもっと読み込めば、うまいやり方があるのかもしれない。

# 実行

```
# ansible-playbook postgresql.yml 

PLAY [dbservers] ***************************************************************

TASK [setup] *******************************************************************
ok: [192.168.56.101]

TASK [test connection] *********************************************************
ok: [192.168.56.101]

TASK [install yum repository] **************************************************
ok: [192.168.56.101]

TASK [install postgresql server] ***********************************************
skipping: [192.168.56.101] => (item=[u'postgresql95', u'postgresql95-server', u'postgresql95-devel']) 

TASK [stat] ********************************************************************
ok: [192.168.56.101]

TASK [initdb] ******************************************************************
skipping: [192.168.56.101]

TASK [start postgresql server] *************************************************
ok: [192.168.56.101]

PLAY RECAP *********************************************************************
192.168.56.101             : ok=6    changed=0    unreachable=0    failed=0   


```

以上！

# 参考

* [Ansible Documentation](http://docs.ansible.com/ansible/index.html)
* [CentOS7にPostgreSQLをインストールする](http://sheepdogjam.cocolog-nifty.com/blog/2016/04/centos7postgres.html)