もなかアイスの試食品

「とりあえずやってみたい」そんな気持ちが先走りすぎて挫折が多い私のメモ書きみたいなものです.

ゼロから始めた構成管理。Ansibleでhttpd(apache)、vsftpd構築、iptables設定をやってみた

「構成管理」との出会い

普段からサーバの管理・運用はやらないものの、ちょっとした動作確認を行うときにサーバをよく立てている。

慣れてきたとはいえ、ポート解放を忘れてたり、yumを何回も実行したりと時間がかかる。

慣れましたけど・・・(震え声)

だいたい構築する環境は同じだし、少しは楽に早くサーバを構築したいできないかなぁ思い、調べてみると色々出てくるツール

Docker、Chef、Vagrant・・・

使ったことがないツール&日本語なのに読めない不思議

しかもよく見るサイトが、「VagrantとChefで・・・」っていう掛け算してやがる!

ちょっとだけ動かしたいだけなのに・・・

やべぇな・・・こうせいかんり・・・(゚A゚;)ゴクリ

構成管理ツールといえば「Chef」をよく見かけるので、一回サンプルを動かして見た

しかしワイRuby読めない・・・orz

しかも「Solo」とか「Server」とか「Knife-Solo」とかあるよ! とか何か書いてある


つまり・・・どういうことだってばよ?


もっと簡単なものはないかと、他に調べてみると「Ansible」というのがあった。

インストールするモノが少なく、設定ファイルも知っているコマンドを書き換えている感じだったので、「Ansible」を使うようにした。

インストール・入門的な話は以下のサイトを参考。


環境の準備

今回Ansibleを使用するため、自分のPCに CentOS 6.7 64bit の仮想OSを2台VMPlayerにインストールした。

片方は、Ansible実行用(以下 管理マシン
もう片方は、Ansibleであれやこれやいじられる、Ansible環境構築先(以下 構築サーバ

ちなみに、CentOSは最小構成でインストールした。

以下のコマンドで管理マシンにAnsibleをインストールする。

# yum install -y epel-release
# yum install -y ansible

「/etc/ansible/hosts」ファイルに、管理対象とするサーバを記載する。
構築サーバIPアドレスは「192.168.255.139」だったので、「webservers」セクションに IPアドレスを追加した。

# This is the default ansible 'hosts' file.
#
# It should live in /etc/ansible/hosts
#
#   - Comments begin with the '#' character
#   - Blank lines are ignored
#   - Groups of hosts are delimited by [header] elements
#   - You can enter hostnames or ip addresses
#   - A hostname/ip can be a member of multiple groups

[webservers]
192.168.255.139

[dbservers]


接続確認

通信できるか確認するため、管理サーバでAnsibleのpingモジュールを実行する。

ssh秘密鍵を作っていないので、--ask-passでsshのパスワードログインするようにする。

# ansible -m ping 192.168.255.139 -u root --ask-pass

成功した場合、以下のような出力がある。

192.168.255.139 | success >> {
    "changed": false, 
    "ping": "pong"
}


playbookを準備する

今回は「httpd」、「vsftpd」を構築することを目指した。

playbookを書いたり消したりCentOSを作りなおしたりした結果、playbookは以下のようになった。
ちなみにファイル名を「http-ftp-install.yml」にして管理サーバに保存した。

- hosts: webservers
  tasks:
    - name: be sure libselinux-python is installed
      yum: name=libselinux-python state=installed

    - name: be sure httpd is installed
      yum: name=httpd state=installed

    - name: be sure httpd is running and enabled
      service: name=httpd state=running enabled=yes

    - name: be sure ftp in installed
      yum: name=vsftpd state=installed

    - name: be sure ftp is running and enabled
      service: name=vsftpd state=running enabled=yes

    - name: check httpd iptable rule
      shell: iptables -L | grep -q ftp
      register: register_ftp
      failed_when: register_ftp.rc not in [0, 1]
      changed_when: false

    - name: add ftpd iptable rule
      shell: iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 20:21 -j ACCEPT -m comment --comment "ftpd"
      when: register_ftp.rc

    - name: check httpd iptable rule
      shell: iptables -L | grep -q http
      register: register_http
      failed_when: register_http.rc not in [0, 1]
      changed_when: false

    - name: add httpd iptable rule
      shell: iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -m comment --comment "httpd"
      when: register_http.rc

    - name: save iptables
      shell: service iptables save

    - name: iptables restart
      service: name=iptables state=restarted

「libselinux-python」は、AnsibleでSELinuxの操作するときに必要らしい。今回の環境では必要ないかもしれないが、 途中でコケるのは困るので一応最初にインストールする。*1

パッケージのインストールはいろんなサイトでも見かける方法で問題なく動作したが、iptablesの設定で結構時間がかかった。

iptablesの「べき等性」

構成管理で必ず出てくる性質(考え方?)。

「操作を1回行っても複数回行っても結果が同じであること」

iptablesの設定はコマンド(shell)を実行している。shellは記載されたコマンドをそのまま実行するだけなので「べき等性」が保証されない。

Ansibleを実行たびにhttpポート、ftpポートの設定が累積してしまう。
iptablesのファイルをコピペすればべき等性が簡単に実現出来ると思うが)

なので、httpまたはftpのポート設定があるかどうか確認して、なければiptablesに設定を追加するようにした。

httpd用だけ取り上げると以下の部分が該当する。

    - name: check httpd iptable rule
      shell: iptables -L | grep -q http
      register: register_http
      failed_when: register_http.rc not in [0, 1]
      changed_when: false

    - name: add httpd iptable rule
      shell: iptables -I INPUT 5 -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -m comment --comment "httpd"
      when: register_http.rc


1. 「shell: iptables -L | grep -q http」でhttpポートの設定がすでにあるかどうかを確認する。
2. 結果を「register: register_http」により「register_http」の中に格納する。*2
3. 「failed_when: register_http.rc not in [0, 1]」で、register_http.rcが0, 1以外だったらコケるようにしておく
4. 「changed_when: false」は、サーバの環境を変えているわけでもないのに「changed」と表示されるのを防ぐために入れている。*3
5. 「when: register_http.rc」にて、iptablesのコマンドを実行するかどうかを判定する。

iptablesの設定の保存が「iptables-save」コマンドで何故かうまく動作してくれなかったので、 代わりに「service iptables save」を使用してiptablesの状態を保存している。

playbookの実行

管理サーバで、以下のコマンドを実行すると構築サーバの構成を変更してくれる。

# ansible-playbook -i /etc/ansible/hosts http-ftp-install.yml -u root --ask-pass

ブラウザで「192.168.255.139」にアクセスすると、ApacheのWelcomeページ(?)が表示されようになっている。

ちなみに、ftpはrootユーザしか作ってないのに、rootユーザがログイン不可でダメだったでござる\(^o^)/

「/etc/vsftpd/ftpusers」、「/etc/vsftpd/user_list」のrootユーザをコメント化するとFTP接続出来るようになった。こんなのあったっけ?

今度はAnsibleのみでftp接続出来るように設定ファイルのコピーするのと、ファイルが結構長くなったので playbookファイルの分割について調べてみようと思う。