AnsibleでWEBアプリケーション環境構築チュートリアル

今回はAnsibleでWEBアプリケーション環境を構築してみましょう。

Ansibleをまだ触ったことがない方はこちらの記事でまずは全体感を掴んで見てください。

【入門】 Ansibleとは? 手を動かして入門

手順の確認

今回はRubyOnRailsで作ったサービスを動かすための環境を作りましょう。

そのために最低限下記の手順を実行する必要があります。

  1. Linuxユーザーを追加
  2. Gitの追加
  3. Rubyの追加
  4. Node.jsの追加
  5. 追加したRoleが動作しているかを確認

実際にアプリケーションを構築するときに使えるような構成になっていますので一緒に作っていきましょう。

環境構築

まずは、環境構築をしていきます。

今回はVagrantで環境を作っていきましょう。

Vagrantについてはこちらの記事を参考にしてください。

【入門】 Vagrantとは? 仮想サーバーを立ててみる

vagrant up で仮想サーバーを立ててssh vagrantで接続できるようになっているところまで進めてみましょう。

Ansibeを実装

動作環境は作成できたので、実際に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

ここまでで1度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を書いていくときには、公式のドキュメントを参考に書いていきます。

参考 DocumentationAnsible

例えば今回、userというmoduleを使っていますがこちらを参考に
どんなmoduleなのか、どんなパラメーターが使えるのかを確認して進める形です。

参考 user_moduleAnsible

ここで簡単にAnsibleの用語の説明です。

コメントで基本を説明しているので理解してみてください。

このあたりがわかっていればあとはmodule次第なので他でも応用できます。

- name: Add groups // タスク単位の説明。ここではグループを追加するという意味。
  group: // module。ここではgroupというmoduleを使っている。
    name: '{{ item.name }}' // ループ処理の一つの値からデータを取得。ここではname。
  with_items: '{{ group_list }}' // with_itemsを使うとループ処理ができる。

admin_usersgroup_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.ymlvars.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, admin2developer1というユーザーを追加する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_userapp_groupruby_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を使えるようにする設定ですね。

メモ
rbenvはRubyのバージョンを管理するツールです。

それをユーザー共通の箇所に置いています。

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環境を構築できました。

この手順を応用すればいろいろな環境ができますし、環境を変更する時もコードをベースとして変更が可能になります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です