6
9

More than 5 years have passed since last update.

AnsibleでRedmineをCentOSにインストール

Posted at

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_useransible_ssh_passにリモートサーバのユーザとパスワードを設定する。

2. プレイブック

/root/ansible/redmine.yml

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

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

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

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.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

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

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

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

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

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の文法チェック

完了後、「http://リモートサーバIPアドレス/redmine」で接続する。

6
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
9