Ansibleで光の速さのWEBサーバーを光の速さで構成してみる。

 初エントリとなります。業務では主にインフラ周りを専門にエンジニアをしています。2015年12月はCentOS7.2がリリースされたり、phpがメジャーバージョンアップして7.0となったりと、色々と話題になった月でした。（少々、投稿する時期がずれてしまってはいますがw）
　それらをさっそくAnsibleで使ってみよう！ + 色々と試してみようということで今回は以下の構成を光の速さ(盛りすぎ)で構築することにしました。

※あまりに悠長に記事を書いていたら、投稿しようとした本日、Ansible2.0が公開されてしまいましたw

GitHub : [sak-2/ansible-example](https://github.com/sak-2/ansible-example)

## つかうもの
* インフラ
	* さくらのVPS(v4) SSD 1G
	* CentOS7.2 (OS)
* ミドルウェア
	* nginx 1.8.0 
	* php7.0-fpm (アプリケーション） 
	* MariaDB(SQL) 5.5.44
* フロントエンド
	* Wordpress 4.3
* 構成管理
	* Ansible 1.9.4
	* playbookはGitHub参照


## vagrantの準備

今回は、Ansibleのホストをvagrantで立てて、そこからSSHでさくらVPSへつなぐという構成にしました。vagrantを立てる端末はmacでもwinでもなんでもいい（はず）です。インストール方法はググればでてきますので割愛させていただきます。私自身はOSX 10.11.12 にvagrantをインストールして用意しました。

適当にフォルダを作ってカレントディレクトリを移動
> $ vagrant box add centos https://github.com/CommanderK5/packer-centos-template/releases/download/0.7.1/vagrant-centos-7.1.box
> $ vagrant init

でVagrantfileを作成し、中身を
> config.vm.box = "centos"

に書き換えて

> $ vagrant up

しちゃってください。


## さくらVPS側の準備
こっちはコントロールパネル上でカスタムISOインストールを選択して、CentOS７．２を入れます。しばらくするとコンソールが立ち上がるので、ポチポチと進めてください。ソフトウェアの選択はminimamを選択し、アドオンに開発ツールを選択しました。後はインストール完了したら、

> sudo yum update

を行います。

ここで念のため、先ほどvagrantで立てたホストからさくらVPSに繋がるかどうかSSHで確認しちゃいましょう。

>$ ssh root@xx.xx.xx.xx

で接続されればOKですね。


## Ansibleのインストール
vagrantで立てた仮想OS上にAnsibleをインストールします。Ansible自体はまごころこめて手動でインストールします。まあ、yumで入るので難しくないです。

> $ sudo yum install -y epel-release

でリポジトリを追加して、

> $ sudo yum -y install ansible

でAnsibleが入りました。

> $ ansible --version

と入力して、

> ansible 1.9.4

と返ってくれば、インストール完了です。


## 公開鍵の作成

ansibleのホストからさくらVPSへは公開鍵認証がされます。Ansibleとして推奨されている、認証方式なのでここは従いましょう。

ansibleホスト側で

> ssh-keygen

で、鍵ペアを作成します。全てEnterで応答します。（passフレーズ無し）これで、~/.ssh配下にid_rsa（秘密鍵）とid_rsa.pub(公開鍵)が作成されました。
続いてこの公開鍵をssh-copy-idコマンドでさくらVPS側へ引き渡します。

> ssh-copy-id -i ~/.ssh/id_rsa.pub root@xx.xx.xx.xx

これで鍵を渡すことができました。

## hosts,playbookの準備

さあ、いよいよプレイブックの実行…なんですが、その前に用意しなければいけないことがありますね。プレイブック自体を用意しなければなりませんでした。
調べてたら、ちょうどいいものが、GitHub上に公開されていたので、これを参考にしたらいけそうですね。

* [ansible-examples/wordpress-nginx_rhel7](https://github.com/ansible/ansible-examples/tree/master/wordpress-nginx_rhel7)

このplaybookでインストールされるphp-fpmは5.6になっているので、これを7.0のものに書き換えればいけそうですね。

それと、今回はVPSサーバということでSSH周りの設定も変更しましょう。

* SSHのポート22番を任意の番号に変更
* firewallの書き換え（22を塞いで任意の番号をあける）
* ユーザーの追加
* norootloginの設定
* SElinuxのOff

以上の設定を、playbookに書いてみました。

``` php-fpm:main.yml
---
- name: install remi repository
  yum: name=http://rpms.famillecollet.com/enterprise/remi-release-7.rpm state=present 

- name: install epel repository
  yum: name=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm state=present

- name: install webtatic repository
  yum: name=https://mirror.webtatic.com/yum/el7/webtatic-release.rpm state=present

- name: Install php-fpm and deps 
  yum: name={{ item }} state=present enablerepo=remi,epel,webtatic
  with_items:
  - php70w
  - php70w-fpm
  - php70w-enchant
  - php70w-mbstring
  - php70w-mysql
  - php70w-mcrypt
  - php70w-opcache
  - php70w-xml

- name: Disable default pool
  command: mv /etc/php-fpm.d/www.conf /etc/php-fpm.d/www.disabled creates=/etc/php-fpm.d/www.disabled
  notify: restart php-fpm
 
- name: Copy php-fpm configuration
  template: src=wordpress.conf dest=/etc/php-fpm.d/
  notify: restart php-fpm
``` 

また、SSHの設定とSELINUXの設定は以下のようにplaybookで書くことができました。

``` ssh:main.yml
---
- name: Add new user
  user:
    name: "{{ ssh_user }}"
    groups: wheel
    password: "{{ ssh_user_passwd }}"
    generate_ssh_key: yes
    ssh_key_bits: 2048

- name: Create an authorized_keys file
  command: /bin/cp /home/{{ ssh_user }}/.ssh/id_rsa.pub /home/{{ ssh_user }}/.ssh/authorized_keys

- name: Change attributes of an authorized_keys file
  file:
    path: /home/{{ ssh_user }}/.ssh/authorized_keys
    owner: "{{ ssh_user }}"
    group: "{{ ssh_user }}"
    mode: 0600

- name: Allow wheel group to use sudo
  lineinfile:
    dest: /etc/sudoers
    state: present
    insertafter: "^# %wheel\\s+ALL=\\(ALL\\)\\s+NOPASSWD:\\s+ALL"
    line: "%wheel ALL=(ALL) NOPASSWD: ALL"
    validate: "visudo -cf %s"
    backup: yes

- name: Fobid root to access via ssh
  lineinfile:
    dest: /etc/ssh/sshd_config
    state: present
    regexp: "^PermitRootLogin without-password"
    line: "PermitRootLogin no"
    backrefs: yes
    validate: "sshd -T -f %s"
    backup: yes
  notify:
    - restart sshd

- name: Permit only specific user to access via ssh
  lineinfile:
    dest: /etc/ssh/sshd_config
    state: present
    insertafter: "^PasswordAuthentication no"
    regexp: "^AllowUsers"
    line: "AllowUsers {{ ssh_user }}"
    validate: "sshd -T -f %s"
    backup: yes
  notify:
    - restart sshd

- name: Change ssh port number
  lineinfile:
    dest: /etc/ssh/sshd_config
    state: present
    insertafter: "^#Port 22"
    regexp: "^Port"
    line: "Port {{ ssh_port }}"
    validate: "sshd -T -f %s"
    backup: yes
  notify:
    - restart sshd

- name: Change acceptable tcp port for ssh on iptables
  firewalld: port={{ ssh_port }}/tcp permanent=true state=enabled immediate=yes

- name: shutdown ssh port
  firewalld: service=sshd permanent=true state=disabled immediate=yes

- name: Retrieve a private key from remote host
  fetch:
    src: /home/{{ ssh_user }}/.ssh/id_rsa
    dest: fetch/private_key-{{ ansible_hostname }}
    validate_md5: true
    fail_on_missing: true
    flat: true
```

```selinux:main.ml
---
- name: Install libselinux-python
  yum: name=libselinux-python state=present

- name: Check status of selinux
  shell: getenforce

- name: Permissive selinux
  selinux: policy=targeted state=permissive

- name: test connection (before reboot)
  ping:

- name: reboot!
  command: shutdown -r now

```

これらをGitHubにあるようなディレクトリ構成で配置します。これはansibleのベストプラクティスに準拠します。

最後にhostsにさくらVPSのIPアドレスを記入してターンエンド。
さあ、いよいよansibleで…プロビジョニングだー！

というところなんですが、ここでつまりました。このままansible-playbookしても、Permission Denyで弾かれちゃうんですね…。pingすら通らない状況に陥って、試行錯誤してたのですが、やはり認証周りで問題があったようです。

hostsに以下のように、鍵の場所を指定して追記すればOKです。

``` ansible:hosts 
[wordpress-server]
xx.xx.xx.xx ansible_ssh_private_key_file=~/.ssh/id_rsa ansible_ssh_user=root
```

## playbookの実行

それでは、やっとこさplaybookを実行してみましょう。その前に、一度pingを打ってみましょう。

> $ ansible -m ping -i hosts XX.XX.XX.XX
> 192.168.33.12 | success >> {
>     "changed": false, 
>     "ping": "pong”
> }

というように応答が返ってくれば、OKです。認証周りの問題はクリアされたようですね。
今回はプレイブックを２つに分けて実行してみます。

* wordpressのインストール用(php-fpm,nginx,MariaDB含む)
* OSのSSH周りの設定用

まずは、wordpressのインストールから。
カレントディレクトリを用意したplaybookの最上位に移動して、

> ansible-playbook init.yml -i hosts

と実行します。

うまくいけば次はSSHを実行すれば終了です！
（SSHのplaybookは最後にrebootするようにしてあるのでplaybook自体は途中で止まってしまいますが、成功している。）

さくらVPSへブラウザで接続すれば、Wordpressの画面が表示されているはず…！

ということで、次回はこのサーバーにLet’s encryptでSSL/TLS化してみようと思います。