今回はAnsibleでWEBアプリケーション(Rails)環境を構築してみましょう。
- Ansibleを理解できる
- Ansibleを実戦で使えるようになる
Ansibleをまだ触ったことがない方は、こちらの記事でまずは全体感を理解してみてください。
モグモグさん
他の言語やフレームワークの環境にも応用できるので、
Ansibleを使えるようになりたい方みなさんにおすすめです。
目次
手順の確認
今回はRuby on Railsで作ったサービスを動かすための環境を作ります。
そのためには、今回下記の手順を実行する必要があります。
- Linuxユーザーを追加
- Gitの追加
- Rubyの追加
- Node.jsの追加
- 追加したRoleが動作しているかを確認
実際にアプリケーションを構築するときに使えるような構成になっていますので一緒に手を動かしつつ、やっていきましょう!
環境構築
まずはAnsibleを実行するための環境構築をしていきます。
今回はVagrantで環境を作っていきましょう。
Vagrantについてはこちらの記事を参考にしてください。
vagrant up
で仮想サーバーを立ててssh vagrant
で接続できるようになっているところまで進めてみましょう。
Ansibleが実行できる環境であれば、DockerでもEC2でもなんでも大丈夫です!
Ansibleを実装
動作環境は作成できたので、実際にAnsibleをガシガシ書きながら環境を構築していきたいと思います。
Inventoryファイルの作成
Inventory
ファイルを作成していきましょう。
今回はvagrantで作った環境に向けてAnsibleを流していくので、
hosts
というファイルでvagrantサーバーを指定しましょう。
[local]
vagrant
Playbookの作成
続いてlocal.yml
というPlaybookを作成していきましょう。
- name: Playbook for web server
hosts: local
become: yes
remote_user: vagrant
動作確認のために、Ansibleを流してみましょう。
$ ansible-playbook -i hosts local.yml
rolesを追加していないので何も起こらないですが、下記のようにok
になっていればvagrantに接続できていますし、Ansibleも動いているのでバッチリです。
PLAY [Playbook for web server] *****************************************************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************************************************************
ok: [vagrant]
PLAY RECAP *************************************************************************************************************************************************************************************************
vagrant : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Linuxユーザーの作成
続いてユーザーを作成していきましょう。
まずはroles/user/tasks/main.yml
を作成します。
- name: Add groups
group:
name: '{{ item.name }}'
with_items: '{{ group_list }}'
# admin
- name: Add admin users
user:
name: '{{ item.name }}'
group: admin
groups: admin,wheel
password: "{{ item.password | password_hash('sha512') }}"
update_password: on_create
with_items: '{{ admin_users }}'
- name: Add keys of admin users
authorized_key:
user: '{{ item.name }}'
key: "{{ lookup('file', 'roles/user/public_keys/'+ item.name + '.key.pub') }}"
with_items: '{{ admin_users }}'
- name: Add permissions to admin
lineinfile:
dest: /etc/sudoers
backup: yes
line: '%admin ALL=(ALL) NOPASSWD: ALL'
# developer
- name: Add developer users
user:
name: '{{ item.name }}'
group: developer
password: "{{ item.password | password_hash('sha512') }}"
update_password: on_create
with_items: '{{ developer_users }}'
- name: Add keys of developer users
authorized_key:
user: '{{ item.name }}'
key: "{{ lookup('file', 'roles/user/public_keys/'+ item.name + '.key.pub') }}"
with_items: '{{ developer_users }}'
基本的にAnsibleを書いていくときには、公式のドキュメントを参考に書いていきます。
例えば今回、user
というmodule
を使っていますが、下記の点を確認していきます。
- どんなmoduleなのか
- どんなパラメーターが使えるのか
公式のドキュメントを読んで実装していけば、他のmoduleも自在に扱えるようになり、応用が効くようになります。
Ansible用語整理
ここで簡単にAnsibleの用語の説明です。
コメントで基本を説明しているので読みつつ、ざっと理解してみてください。
このあたりがわかっていればあとはmodule次第なので他でも応用できます。
- name: Add groups // タスク単位の説明。ここではグループを追加するという意味。
group: // module。ここではgroupというmoduleを使っている。
name: '{{ item.name }}' // ループ処理の一つの値からデータを取得。ここではname。
with_items: '{{ group_list }}' // with_itemsを使うとループ処理ができる。
admin_users
やgroup_list
がありますが、それらは変数になっていて別ファイルから参照します。
直接書いても問題ないですが、ファイルに分けたほうが可読性や柔軟性が増します。
vars.yml
を作成して変数の実際のデータを作成していきましょう。
group_list:
- { name: 'admin' }
- { name: 'developer' }
admin_users:
- { name: 'admin1', password: 'password' }
- { name: 'admin2', password: 'password' }
developer_users:
- { name: 'developer1', password: 'password' }
そして、local.yml
でvars.yml
を参照するように追記します。
- name: Playbook for web server
hosts: local
become: yes
remote_user: vagrant
vars_files: vars.yml // 追加箇所
続いて秘密鍵と公開鍵のセットを作成しましょう。(メールアドレスの箇所はお好きなアドレスにしてください)
$ ssh ~/.ssh
$ ssh-keygen -t rsa -b 4096 -C "hogehoge@gmail.com" -f ansible-sample -m PEM
これで、ansible-sample
という名前の秘密鍵と公開鍵のセットができていると思います。
ユーザーごとに公開鍵を追加するタスクは下記のようになっていますのでroles/user/public_keys
に公開鍵を追加しましょう。
ユーザーごとにname.key.pub
としてそれぞれ置いておきたいですが
今回は、先ほど作った鍵をそれぞれのユーザーのものとして作成しておきましょう。
- name: Add keys of admin users
authorized_key:
user: '{{ item.name }}'
key: "{{ lookup('file', 'roles/user/public_keys/'+ item.name + '.key.pub') }}"
with_items: '{{ admin_users }}'
$ ls roles/user/public_keys
を実行した時に、
admin1.key.pub admin2.key.pub developer1.key.pub
のように出力されていれば大丈夫です。
これでグループの追加と、admin1
, admin2
とdeveloper1
というユーザーを追加するrolesができました。
それでは実行する前に、local.yml
に作成したroleを追加しましょう。
- name: Playbook for web server
hosts: local
become: yes
remote_user: vagrant
vars_files: vars.yml
roles: // ここから追加箇所
- user
準備できましたので実行しましょう。
$ ansible-playbook -i hosts local.yml
PLAY [PlayBook for web server] ***********************************************************************************************************************************************************************************************************************************************
TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [vagrant]
TASK [user : Add groups] *****************************************************************************************************************************************************************************************************************************************************
ok: [vagrant] => (item={'name': 'admin'})
ok: [vagrant] => (item={'name': 'developer'})
TASK [user : Add admin users] ************************************************************************************************************************************************************************************************************************************************
ok: [vagrant] => (item={'name': 'admin1', 'password': 'password'})
ok: [vagrant] => (item={'name': 'admin2', 'password': 'password'})
TASK [user : Add keys of admin users] ****************************************************************************************************************************************************************************************************************************************
changed: [vagrant] => (item={'name': 'admin1', 'password': 'password'})
changed: [vagrant] => (item={'name': 'admin2', 'password': 'password'})
TASK [user : Add permissions to admin] ***************************************************************************************************************************************************************************************************************************************
ok: [vagrant]
TASK [user : Add developer users] ********************************************************************************************************************************************************************************************************************************************
ok: [vagrant] => (item={'name': 'developer1', 'password': 'password'})
TASK [user : Add keys of developer users] ************************************************************************************************************************************************************************************************************************************
changed: [vagrant] => (item={'name': 'developer1', 'password': 'password'})
PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
vagrant : ok=7 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
okと出力されているので成功です。
グループとユーザーが作成できました。
Gitの追加
こちらは必須ではないですが追加しておきましょう。
まずはGit用のrolesの追加です。
$ mkdir -p roles/git/tasks
- name: Install git
yum: // yum moduleを利用
name: git
state: present
lock_timeout: 180
それでは作成したroleをlocal.yml
に例のごとく追加しましょう。
- name: Playbook for web server
hosts: local
become: yes
remote_user: vagrant
vars_files: vars.yml
roles:
- user
- git // ここから追加箇所
実行しましょう。
$ ansible-playbook -i hosts local.yml
Rubyの追加
それでは続いてRubyのrolesを作成して、アプリケーションが動く環境を作りましょう!
まずはディレクトリをtask用とtemplate用を作成しておきましょう。
$ mkdir -p roles/ruby/tasks
$ mkdir roles/ruby/templates
続いてmain.yml
を作成していきます。
- name: Install packages
yum:
name: '{{ item }}'
state: latest
lock_timeout: 180
with_items:
- openssl-devel
- sqlite-devel
- gcc
- gcc-c++
- readline-devel
- mysql
- mysql-devel
- libselinux-python
- name: Install rbenv
git:
repo: https://github.com/sstephenson/rbenv.git
dest: /usr/local/rbenv
- name: Edit bashrc
template:
src: roles/ruby/templates/rbenv_system.sh.j2
dest: /etc/profile.d/rbenv.sh
owner: '{{ app_user }}'
group: '{{ app_group }}'
- name: Install ruby-build
git:
repo: https://github.com/sstephenson/ruby-build.git
dest: /usr/local/rbenv/plugins/ruby-build
- name: Install Ruby
shell: bash -lc "CONFIGURE_OPTS="--disable-install-rdoc" rbenv install -s {{ ruby_version }}"
- name: Set default Ruby version
shell: bash -lc "rbenv global {{ ruby_version }} && rbenv rehash"
- name: Install bundler and so on
shell: bash -lc "gem install {{ item }}"
with_items:
- rbenv-rehash
- bundler
- rails
だんだん読めてきましたか?
基本的にはmoduleを利用しているので不明な箇所はリファレンスを確認して記述パターンを理解していくと良いと思います。
ここでapp_user
とapp_group
とruby_version
は変数を参照しているので追加しましょう。
app_user: developer1 // 追加箇所
app_group: developer // 追加箇所
ruby_version: 2.5.3 // 追加箇所
group_list:
- { name: 'admin' }
- { name: 'developer' }
admin_users:
- { name: 'admin1', password: 'password' }
- { name: 'admin2', password: 'password' }
developer_users:
- { name: 'developer1', password: 'password' }
taskの中で、roles/ruby/templates/rbenv_system.sh.j2
を参照している箇所があるのでそのファイルも作成しておきます。
主にrbenvを使えるようにする設定ですね。
それをユーザー共通の箇所に置いています。
export RBENV_ROOT="/usr/local/rbenv"
export PATH="${RBENV_ROOT}/bin:${PATH}"
eval "$(rbenv init -)"
それではlocal.yml
に作成したroleを追加します。
- name: Playbook for web server
hosts: local
become: yes
remote_user: vagrant
vars_files: vars.yml
roles:
- user
- git
- ruby // 追加箇所
実行しましょう!
$ ansible-playbook -i hosts local.yml
Ruby環境ができました。
Node.jsの追加
最後のセクションです。
Node.js
を追加していきましょう。
まずはディレクトリの作成です。
$ mkdir -p roles/nodejs/tasks
タスクを書いていきましょう!
- name: Setup nodejs8.x
shell: curl -sL https://rpm.nodesource.com/setup_8.x | sudo -E bash -
- name: Installing latest version of node.js
yum:
name: nodejs
state: latest
lock_timeout: 180
- name: Install yarn package
get_url: url="https://dl.yarnpkg.com/rpm/yarn.repo" dest=/etc/yum.repos.d/yarn.repo
- name: Installing yarn
yum:
name: yarn
state: latest
lock_timeout: 180
作成したroleを追加します。
- name: Playbook for web server
hosts: local
become: yes
remote_user: vagrant
vars_files: vars.yml
roles:
- user
- git
- ruby
- nodejs // 追加箇所
実行しましょう。
$ ansible-playbook -i hosts local.yml
成功すれば完了です!
追加したRoleが動作しているかを確認
まずは、追加したユーザーでSSHできるかどうかを確認しましょう。
~/.ssh/config
で、Userをadmin1
に変更し、IdentityFileを作成した秘密鍵に変更しましょう。(ansible-sample
)
Host vagrant
HostName 127.0.0.1
User admin1
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile ~/.ssh/ansible-sample
IdentitiesOnly yes
LogLevel FATAL
SSHしてみましょう!
$ ssh vagrant
[admin1@localhost ~]$
作成したユーザーでSSHできました。
~/.ssh/config
のUserを変更しadmin2
でもdeveloper1
でもSSHしてみてください。
続いて、追加したGitとRubyとNode.jsが入っているか確認しましょう。
$ ssh vagrant
Gitの確認
[admin1@localhost ~]$ git --version
git version 1.8.3.1
Rubyの確認
[admin1@localhost ~]$ ruby -v
ruby 2.5.3p105 (2018-10-18 revision 65156) [x86_64-linux]
Node.jsの確認
[admin1@localhost ~]$ node -v
v8.16.0
ちゃんとインストールされていますね。
もしCommand not found
などが出力された場合、改めて手順を確認してみてください
これでRailsを動かすための環境が作れました。
まとめ
お疲れ様でした!
Ansibleを利用して、Rails環境を構築できました。
この手順を応用すればいろいろな環境ができますし、環境を変更する時もコードをベースとして変更が可能になります。