Ansibleを理解するため、仮想サーバへRedmineをインストールするPlaybookを作成、その内容をまとめました。
環境
ソフトウェア | バージョン |
---|---|
OS(ローカル、リモート) | CentOS 7.5 |
Redmine | Redmine 3.4 |
データベース | PostgreSQL 9.2.24 |
Webサーバ | Apache 2.4.6 |
Ruby | 2.4.4 |
ローカル側ファイル構成
/root/ansible
|-- group_vars # グループで使用する変数を定義
| `-- test-servers
|-- hosts # インベントリファイル
|-- redmine.yml # コマンド実行時に指定するプレイブック
`-- roles
|-- apache # Apache設定用role
| |-- tasks
| | `-- main.yml
| `-- templates
| `-- redmine.conf
|-- common # 共通role(OSの設定等)
| `-- tasks
| `-- main.yml
|-- postgresql # PostgreSQL設定用role
| |-- files
| | `-- pg_hba.conf.diff
| `-- tasks
| `-- main.yml
|-- redmine # Redmine設定用role
| |-- tasks
| | `-- main.yml
| `-- templates
| |-- configuration.yml
| `-- database.yml
`-- ruby # Ruby設定用role
`-- tasks
`-- main.yml
各ファイルの内容
1. インベントリファイル
/root/ansible/hosts
[test-servers]
192.168.11.51
[test-servers:vars]
ansible_user=root
ansible_ssh_pass=P@ssw0rd
-
ansible_user
、ansible_ssh_pass
にリモートサーバのユーザとパスワードを設定する。
2. プレイブック
/root/ansible/redmine.yml
---
- hosts: test-servers
pre_tasks:
- name: Start message
debug: msg="Redmineのインストールを開始します。"
- name: Create directory on the local side
local_action:
module: file
path: "{{ local_work }}"
state: directory
mode: 0777
- name: Create directory on the remote side
file:
path: "{{ remote_work }}"
state: directory
mode: 0777
roles:
- common
- ruby
- postgresql
- redmine
- apache
post_tasks:
- name: Delete directory on the remote side
file:
path: "{{ remote_work }}"
state: absent
- name: End message
debug: msg="Redmineのインストールが完了しました。"
-
pre_tasks
でローカル、リモート側にワークディレクトリを作成する。 -
post_tasks
でリモート側のワークディレクトリを削除する。
3. グループの変数定義
/root/ansible/group_vars/test-servers
ruby_download_url: https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.4.tar.gz
ruby_version: ruby-2.4.4
redmine_svn_url: https://svn.redmine.org/redmine/branches/3.4-stable
db_user: redmine
db_pass: redmine
db_pass_md5: md5c5a58b543b1cad88fa10f629c0e535c1
local_work: /tmp/ansible_work
remote_work: /tmp/ansible_work
- PostgreSQLのパスワードとなる
db_pass
,db_pass_md5
は、任意のパスワードに変更する。 -
db_pass_md5
は、パスワードを暗号化した内容。'str["md5"] + md5[ password + username ]'の形で、コマンドではecho "md5$(echo -n 'redmineredmine' | md5sum)"
により作成する。
4. 共通role
/root/ansible/roles/common/tasks/main.yml
---
# SELinuxを無効にする
- name: Disable SELinux
selinux: state=disabled
register: result_selinux
- block:
# サーバを再起動する
- name: Restart the server
shell: sleep 2 && shutdown -r now
async: 1
poll: 0
ignore_errors: true
# サーバの起動を待つ
- name: Wait for server startup
local_action: wait_for host={{ inventory_hostname }} port=22 state=started delay=10
when: result_selinux.reboot_required
# ファイアウォールのhttpポートを許可する
- name: Allow firewall http port
firewalld:
service: http
permanent: true
state: enabled
immediate: yes
# パッケージのインストール
# インストール済みのパッケージを更新する
- name: Update installed packages
yum:
name: '*'
state: latest
# 開発ツールのインストール
- name: Install development tools
yum:
name: "@Development Tools"
state: present
# RubyとPassengerに必要なパッケージのインストール
- name: Install necessary packages for Ruby and Passenger
yum:
name:
- openssl-devel
- readline-devel
- zlib-devel
- curl-devel
- libyaml-devel
- libffi-devel
- mysql-devel
state: present
# PostgreSQLに必要なパッケージのインストール
- name: Install necessary packages for PostgreSQL
yum:
name:
- postgresql-server
- postgresql-devel
- python-psycopg2
state: present
# Apacheに必要なパッケージのインストール
- name: Install necessary packages for Apache
yum:
name:
- httpd
- httpd-devel
state: present
# ImageMagick・日本語フォントのインストール
- name: Installation of ImageMagick, Japanese font
yum:
name:
- ImageMagick
- ImageMagick-devel
- ipa-pgothic-fonts
state: present
- 「/etc/sysconfig/selinux」の変更ではなく、
selinux
モジュールにより、SELinuxを無効化する。 - SELinuxの変更により、再起動が必要かどうかは、結果の
reboot_required
で判定する。 -
mysql-devel
は、Rubyのパッケージ管理ツール「bundler」のインストール時に必要。 - PostgreSQLの
python-psycopg2
は、ansibleでPostgreSQLのモジュール実行に必要。
5. Ruby設定用role
/root/ansible/roles/ruby/tasks/main.yml
---
# Rubyのインストールを確認する
- name: Confirm installation of Ruby
stat:
path: /usr/local/bin/ruby
register: ruby_state
- block:
# ソースコードをダウンロードする
- name: Download the source code
get_url:
url: "{{ ruby_download_url }}"
dest: "{{ remote_work }}/{{ ruby_version }}.tar.gz"
register: result_get_url
# ダウンロードファイルを確認する
- name: Check the download file
stat:
path: "{{ result_get_url.dest }}"
register: archive_file_state
# ダウンロードファイルを解凍する
- name: Unzip the download file
unarchive:
src: "{{ result_get_url.dest }}"
dest: "{{ remote_work }}"
remote_src: yes
when: archive_file_state.stat.exists
# Rubyのコンパイル・インストール
- name: Compiling and installing Ruby
command: >
{{ item }}
chdir={{ remote_work }}/{{ ruby_version }}/
with_items:
- 'autoconf'
- './configure --disable-install-doc'
- 'make'
- 'make install'
# bundlerのインストール
- name: Install bundler
gem:
name: bundler
state: present
include_doc: no
user_install: false
when: not ruby_state.stat.exists
- Rubyのソースは
curl
コマンドではなく、get_url
モジュールでダウンロードする。 -
unarchive
モジュールでリモート側のファイルを解凍を行う場合remote_src: yes
の指定が必要。 -
gem
モジュールでuser_install: false
指定しないと~/.gemへインストールされる。
6. PostgreSQL設定用role
/root/ansible/roles/postgresql/tasks/main.yml
---
# PostgreSQLの設定
# initdbが実行されたか確認する
- name: Check if initdb has been executed
find:
paths: /var/lib/pgsql/data
patterns: "*"
register: result_find
- block:
# データベースクラスタを新規作成する
- name: Create a new database cluster
command: postgresql-setup initdb
# pg_hba.conf ファイルのバックアップ
- name: Back up pg_hba.conf
fetch:
src: /var/lib/pgsql/data/pg_hba.conf
dest: "{{ local_work }}"
# 差分ファイルをコピーする
- name: Copy the difference file in pg_hba.conf
copy:
src: pg_hba.conf.diff
dest: "{{ remote_work }}"
# 差分ファイルを反映する
- name: Reflect difference file in pg_hba.conf
shell: patch -t /var/lib/pgsql/data/pg_hba.conf < {{ remote_work }}/pg_hba.conf.diff
# PostgreSQLのサービスを起動する
- name: Start PostgreSQL service
systemd:
name: postgresql.service
state: started
enabled: True
# ユーザーを追加する
- name: Add PostgreSQL user
postgresql_user:
name: "{{ db_user }}"
password: "{{ db_pass_md5 }}"
state: present
become: yes
become_method: su
become_user: postgres
# データベースを作成する
- name : Create a database
postgresql_db:
name: redmine
encoding: UTF-8
lc_collate: ja_JP.UTF-8
lc_ctype: ja_JP.UTF-8
template: template0
owner: "{{ db_user }}"
state: present
become: yes
become_method: su
become_user: postgres
when: result_find.matched == 0
/root/ansible/roles/postgresql/files/pg_hba.conf.diff
*** pg_hba.conf.original 2018-10-19 00:00:00.000000000 +0900
--- pg_hba.conf 2018-10-19 00:00:00.000000000 +0900
***************
*** 71,76 ****
--- 71,78 ----
# "host" records. In that case you will also need to make PostgreSQL
# listen on a non-local interface via the listen_addresses
# configuration parameter, or via the -i or -h command line switches.
+ host redmine redmine 127.0.0.1/32 md5
+ host redmine redmine ::1/128 md5
- 修正前のpg_hba.confを、ローカル環境へバックアップする。
- pg_hba.confへのレコードの追加を
blockinfile
モジュールではなく、patch
コマンドで行う。事前にdiffコマンドで差分ファイルを作成する必要がある。
7. Redmine設定用role
/root/ansible/roles/redmine/tasks/main.yml
---
# Redmineのダウンロード
- name: Download Redmine
subversion:
repo: "{{ redmine_svn_url }}"
dest: /var/lib/redmine
# database.ymlを作成
- name: Create database.yml
template:
src: database.yml
dest: /var/lib/redmine/config/database.yml
force: no
# configuration.ymlを作成
- name: Create configuration.yml
template:
src: configuration.yml
dest: /var/lib/redmine/config/configuration.yml
force: no
# gemパッケージをインストール
- name: Install gem package
bundler:
gem_path: vendor/bundle
state: present
chdir: /var/lib/redmine
register: result_bundler
# セッション改ざん防止用秘密鍵を作成する
- name: Create a secret key for preventing session tampering
command: bundle exec rake generate_secret_token
args:
chdir: /var/lib/redmine
when: result_bundler.changed
# データベースのテーブルを作成する
- name: Create a database table
command: bundle exec rake db:migrate
args:
chdir: /var/lib/redmine
environment:
RAILS_ENV: production
when: result_bundler.changed
# デフォルトデータを登録する
- name: Register default data
command: bundle exec rake redmine:load_default_data
args:
chdir: /var/lib/redmine
environment:
RAILS_ENV: production
REDMINE_LANG: ja
when: result_bundler.changed
/root/ansible/roles/redmine/templates/configuration.yml
production:
email_delivery:
delivery_method: :smtp
smtp_settings:
address: "localhost"
port: 25
domain: "{{ ansible_fqdn }}"
rmagick_font_path: /usr/share/fonts/ipa-pgothic/ipagp.ttf
/root/ansible/roles/redmine/templates/database.yml
production:
adapter: postgresql
database: redmine
host: localhost
username: redmine
password: "{{db_pass}}"
encoding: utf8
- database.yml,configuration.ymlは、
template
モジュールにより、変数の値を設定したファイルを作成する。 - configuration.ymlの
{{ ansible_fqdn }}
により、"localhost.localdomain"が設定される。
8. Apache設定用role
/root/ansible/roles/apache/tasks/main.yml
---
# Passengerのインストールを確認する
- name: Confirm Passenger installation
command: gem list
register: gem_list
changed_when: false
args:
chdir: /var/lib/redmine
- block:
# Passengerのインストール
- name: Install Passenger
gem:
name: passenger
state: present
include_doc: no
user_install: false
# PassengerのApache用モジュールのインストール
- name: Install Passenger's Apache module
command: passenger-install-apache2-module --auto --languages ruby
args:
chdir: /var/lib/redmine
when: "'passenger' not in gem_list.stdout"
# Apache用設定内容の確認
- name: Confirm setting contents for Apache
command: passenger-install-apache2-module --snippet
register: result_passenger_snippet
changed_when: false
args:
chdir: /var/lib/redmine
# redmine.confの作成
- name: Create redmine.conf
template:
src: redmine.conf
dest: /etc/httpd/conf.d/redmine.conf
# RedmineフォルダをApacheユーザの所有に変更する
- name: Change Redmine folder to owned by Apache user
file:
path: /var/lib/redmine
owner: apache
group: apache
recurse: true
# httpdのサービスを起動する
- name: Start the service of httpd
systemd:
name: httpd.service
state: started
enabled: True
/root/ansible/roles/apache/templates/redmine.conf
<Directory "/var/lib/redmine/public">
Require all granted
</Directory>
Alias /redmine /var/lib/redmine/public
<Location /redmine>
PassengerBaseURI /redmine
PassengerAppRoot /var/lib/redmine
</Location>
{{ result_passenger_snippet.stdout }}
PassengerMaxPoolSize 20
PassengerMaxInstancesPerApp 4
PassengerPoolIdleTime 864000
PassengerStatThrottleRate 10
Header always unset "X-Powered-By"
Header always unset "X-Runtime"
- redmine.confは、
template
モジュールにより、passenger-install-apache2-module --snippet
で出力した内容を反映する。
コマンドの実行
# cd /root/ansible
# ansible-playbook -i hosts redmine.yml --syntax-check
playbook: redmine.yml
# ansible-playbook -i hosts redmine.yml
事前に--syntax-check
でPlaybookの文法チェック