Vagrantの設定(2)
3. Roleの作成
ようやく、実際に実行するRole及びTaskの作成に移ります。
ここでは以下のRoleを作成します。
- common:共通的にインストールするツールなどを定義
- user_setup:Linux上でのユーザーに関する設定
- web:Webサーバ(Nginx)のインストールと設定
他にもPHPのインストールなどが必要な場合は同様にRoleを作成します。
vagrant_playbook.ymlのrolesに指定したRole名と同じディレクトリをvagrant/provisioning/roles以下に作成し、tasks/main.ymlを生成することでRoleのタスクが実行されます。
まず、commonを作成します。
--- # 共通なタスク # インストールするツール - import_tasks: install_common_tools.yml
ここでは、install_common_tools.ymlに記載されたタスクをインポートしているだけです。同じRoleでも複数のタスクがある場合があるため、main.ymlではそれらをまとめるだけにしておきます。
---
- name: Install tools
yum:
state: installed
name:
- vim
- wget
- lsof
- git
- ruby
- tcpdump
- jq
ここで実際にyumを用いていくつかのパッケージをインストールしています。以降でも同様ですが、基本的にはAnsibleで用意されているモジュール(ここではyum)を使用します。Ansibleのモジュールは冪等性を確保するように作られており、state等の状態(ここではinstalled:インストールされた状態にする)を確認しており、インストール済みだとこのタスクは実行されません(一部例外があります。commandやshellモジュールは実装者が冪等性の考慮をする必要があります。ですのでやむを得ない限り、使用しないようにします)。
続いて、user_setupを作成します。
--- # Linux上のユーザ関連の設定 - import_tasks: add_user.yml
--- # user setup
# デフォルトユーザ用グループの追加
- name: Add group for default user
group:
name: "{{ default_user.group }}"
state: present
# デフォルトユーザを追加
- name: Add user default user
user:
name: "{{ default_user.name }}"
uid: "{{ default_user.uid }}"
group: "{{ default_user.group }}"
password: "{{ default_user.password}}"
state: present
# デフォルトユーザをsudo可能に
- name: Add default user to sudoers
template:
src: default_user_sudoers.j2
dest: /etc/sudoers.d/{{ default_user.name }}
owner: root
group: root
mode: '0644'
# 以下、packerの場合
- block:
# デフォルトユーザの.sshディレクトリを作成
- name: create .ssh directory for default user
file:
path: "/home/{{ default_user.name }}/.ssh"
state: directory
owner: "{{ default_user.name }}"
group: "{{ default_user.group }}"
mode: 0700
# ec2-userの公開鍵をデフォルトユーザに追加
- name: check authorized_keys for default user
stat: path="/home/{{ default_user.name }}/.ssh/authorized_keys"
register: default_user_authorized_keys
# EC2ではEC2インスタンス生成時にキーペアを指定します。指定したキーはec2-userに配置されるため、作成したユーザにもコピー
- name: copy authorized_keys for default user from ec2-user
shell: "cp -p /home/ec2-user/.ssh/authorized_keys /home/{{ default_user.name }}/.ssh/authorized_keys"
when: not default_user_authorized_keys.stat.exists
# キーを使用可能に
- name: chown/chmod authorized_keys for default user
file:
path: "/home/{{ default_user.name }}/.ssh/authorized_keys"
owner: "{{ default_user.name }}"
group: "{{ default_user.group}}"
mode: '0600'
# セキュリティ上、ec2-userの接続禁止
- name: deny ec2-user on ssh connection
lineinfile:
path: /etc/ssh/sshd_config
state: present
line: 'DenyUsers ec2-user'
when: not is_vagrant
ここでは、vagrant/provisioning/group_vars/all.ymlの定義に従い、ユーザーを作成しています。
また、Packerでの利用を鑑み、PackerとVagrantでの分岐をis_vagrantを用いて実施しています。
ここで新たにtemplateモジュールを使用しており、タスク内のtemplateフォルダにあるファイルをjinja2テンプレートエンジンを用いて変数を展開し、ファイルを配置しています。
{{ default_user.name }} ALL=(ALL) ALL
最後に、webを作成します。
--- # Webサーバのインストール - import_tasks: install_nginx.yml
--- # nginxのインストール
# Extra Libraryのnginxが有効かどうか確認
- name: Check amazon-linux-extras for nginx
shell: amazon-linux-extras | grep nginx{{nginx_version}} | grep enabled
register: nginx
failed_when: nginx.rc not in [0, 1]
changed_when: False
# Extra Libraryが有効でない場合、有効化
- name: Enable nginx in amazon-linux-extra
shell: amazon-linux-extras enable nginx{{nginx_version}}
changed_when: False
when: nginx.rc==1
# nginxのインストール
- name: Install nginx
yum:
name: "nginx"
state: installed
# nginxの設定ファイルを配置
- name: Put nginx.conf template
template:
dest: /etc/nginx/nginx.conf
src: nginx.conf.j2
owner: root
group: root
mode: 0644
# nginxのvirtualhost用設定ファイルを配置
- name: Put virtual.conf template
template:
dest: /etc/nginx/conf.d/virtual.conf
src: virtual.conf.j2
owner: root
group: root
mode: 0644
# 一度nginxを起動(ログファイル生成のため)
- name: Start nginx
systemd: name=nginx state=started enabled=yes
changed_when: False
# 一度nginxを停止
- name: Stop nginx
systemd: name=nginx state=stopped
changed_when: False
# ログ出力ディレクトリ、ログ・ファイル等のパーミッションを変更
- name: chown /var/log/nginx for default user
file:
path: "/var/log/nginx"
owner: "{{ default_user.name }}"
group: "{{ default_user.group}}"
mode: '0700'
- name: chown /var/log/nginx/access.log for default user
file:
path: "/var/log/nginx/access.log"
owner: "{{ default_user.name }}"
group: "{{ default_user.group}}"
mode: '0600'
- name: chown /var/log/nginx/error.log for default user
file:
path: "/var/log/nginx/error.log"
owner: "{{ default_user.name }}"
group: "{{ default_user.group}}"
mode: '0600'
- name: chown /var/lib/nginx for default user
file:
path: "/var/lib/nginx"
owner: "{{ default_user.name }}"
group: "{{ default_user.group}}"
mode: '0700'
- name: chown /var/lib/nginx/tmp for default user
file:
path: "/var/lib/nginx/tmp"
owner: "{{ default_user.name }}"
group: "{{ default_user.group}}"
mode: '0700'
# 再度nginxを起動
- name: Start nginx
systemd: name=nginx state=started
changed_when: False
ここで、changed_when: Falseをいくつか使用しています。理由は最後に詳しく解説しますが、再実行されたときに、タスクがchangedになってほしくない(状態が変更されてもされていないように表示してほしい)場合に使用しています。
また、テンプレートファイルは以下の2つを使用しています。
user {{ default_user.name }} {{ default_user.group }};
pid /var/run/nginx.pid;
# 動的モジュールのロード
include /usr/share/nginx/modules/*.conf;
events {
# 最大同時接続数
worker_connections 1024;
# 接続をマルチに処理
multi_accept on;
# 多重IOをカーネルで処理
use epoll;
# mutex処理失敗時の待機時間(デフォルト500mx)
accept_mutex_delay 100ms;
}
error_log /var/log/nginx/error.log warn;
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_proto" $request_time $upstream_response_time';
# 他ファイルのインクルード
include /etc/nginx/conf.d/*.conf;
server {
listen 80;
# Nameベースのバーチャルホスト
server_name {{ hostname }};
# DocumentRoot
root /var/www/html/app/public;
# access_log
access_log /var/log/nginx/access.log main;
index index.html;
}
さらに、このタスク(web)でのみ有効な変数を作成します。
nginx_version: 1.12
このように、バージョンを切り出しておくと、今後のメンテナンスが容易になります。
4. Vagrantの起動
ようやくVagrantを起動します。
ここでは解説しませんが、動作確認のため、PROJECT_ROOT/app/public/index.htmlを作成しておいてください。
cd PROJECT_ROOT/vagrant vagrant up
うまくいけば、VagrantでゲストOSが起動し、Ansibleによるプロビジョニングが動作します。
動作の途中で、vagrant-hostupdaterにより、/etc/hostsを更新するためにパスワードを聞かれますが、その際にはホストOSのユーザーのパスワードを入力してください。
最終的に、以下のような表示がされ、起動状態になります。
・・・ TASK [web : Start nginx] ******************************************************* ok: [default] PLAY RECAP ********************************************************************* default : ok=18 changed=12 unreachable=0 failed=0
動作を確認するため、ホストOSで、index.htmlにアクセスすると、以下の表示になるかと思います。
$ curl http://sample.test/index.html test
これで環境構築は完了です。
なお、開発中にplaybookを変更する場合があると思います。その際はvagrant upした状態で、以下を実行すると、プロビジョニングのみ実施されます。
vagrant provision
冪等性が確保されている場合は、以下のようになります。
PLAY RECAP ********************************************************************* default : ok=17 changed=1 unreachable=0 failed=0
okは変更されなかったタスクの数、changedは変更されたタスクの数となります。
他にもよく使用するコマンドとして、以下のようなものがあります。
# 仮想マシンの停止 vagrant halt # ゲストOSにvagrantユーザーでssh接続 vagrant ssh # 仮想マシンの破棄 vagrant destroy
