プロジェクト

全般

プロフィール

RedmineをAnsibleでインストールする

CentOS 7.1にRedmine 3.1をインストール(Unicorn & Nginx)

CentOS 7.1を最小限インストールしただけの環境に、Redmine 3.1を構築する手順をAnsibleで作成します。

https://github.com/torutk/ansible-centos7_redmine

最低限の作業をrootアカウントでSSH接続(パスワード認証)し、専用の管理アカウントを作成します。
以降は、管理アカウントでSSH接続(公開鍵認証)し、構築します。

  • RDBMSは、CentOS 7標準搭載のMariaDB
  • Rackサーバーは、gemでインストールするUnicorn
  • Webサーバーは、別途インストールするNginx
  • メールサーバーは、localhostのSMTP(postfix想定)

farendさんの設定 を参考に(真似ながら)作成していきます。

Ansibleの準備

構築対象マシン

Ansibleで構築する対象マシンには、Python 2.6以上およびSSHで接続できる環境が必要です。CentOS 7.1は最小限インストール(minimal)で要件を満たしています。
今回は、KVM仮想ゲストにCentOS 7.1をminimalインストールし、rootアカウントとDHCPでIPアドレスを取得する設定がされた状態のマシンを用意しました。

Ansible実行マシン

構築対象マシンにリモートから接続して設定を行うAnsible実行マシンには、Ansibleが必要です。
CentOS 7ではAnsibleは標準パッケージに含まれていないので、epelリポジトリからansibleパッケージをインストールします。これだけです。

Ansible実行マシン上にplaybookの基点ディレクトリを用意

~$ mkdir -p work/ansible/centos71_redmine
~$ cd work/ansible/centos71_redmine
centos71_redmine$ 

インベントリを作成

言葉は難しいですが、構築対象マシンの情報(IPアドレスなりホスト名なり)を書いたファイルです。
ホスト名(DNS名またはドメインなしの名前)を記載し、IPアドレス解決はAnsible実行マシンの名前解決にゆだねるのが一番よさそうです。

/etc/hosts に構築対象マシンのIPアドレスとホスト名を記載(DNS未登録時)

192.168.1.15  bigoncia

centos71_redmine$ vi hosts

[redmine-servers]
bigoncia
  • 今回は1台ですが、今後複数台を対象とするときにまとめて扱えるようグループ"redmine-servers"を定義しておきます。

まずは動作確認

ここでAnsbile実行マシンから構築対象マシンにrootでSSH接続(パスワード認証)しコマンドを実行できることを確認しておきます。

centos71_redmine$ ansible -i hosts -u root -k -m command -a "date" all
SSH password: ********                                               <-- パスワードを手入力
bigoncia | success | rc=0 >>
Sun Nov 15 12:45:15 JST 2015
  • インベントリファイルを-iオプションで指定
  • rootアカウントでSSH接続するよう-uオプションで指定
  • SSH接続のパスワードをコマンド入力するよう-kオプションで指定(未指定時は公開鍵認証を使う)
  • Ansibleで実行するモジュールを-mオプションで指定し、モジュールに渡すコマンドラインを-aオプションで指定

初めてSSH接続するときは、ホストのフィンガープリントの検査でエラーとなるので、先に手動でSSH接続するか、ansible.cfg(または環境変数ANSIBLE_SSH_ARGS)にフィンガープリントの検査をしないよう設定を追記します。(前者を推奨)

playbookのディレクトリ構成

playbookは、1つのファイルにすべてをべた書きすることもできますが、「ベストプラクティス」ディレクトリ構成が推奨されています。
ここでは、構造は準拠しつつファイルを少し変更しています。

centos71_redmine
  +-- group_vars/
  |     +-- redmine-servers
  +-- hosts
  +-- site.yml
  +-- roles/
        +-- system/
        |     +-- tasks/
        |           +-- main.yml
  • group_varsの下には、インベントリ(hosts)で定義したホストのグループごとの設定(変数定義)を記述します
  • hostsはインベントリを記述します
  • site.ymlは全体のplaybookです
  • rolesはロール用ディレクトリでこの中にロール毎にタスクを定義します

site.yumの定義

centos71_redmine
  +-- site.yml
---
- hosts: redmine-servers
  roles:
   - { role: admin, when: ansible_ssh_user == 'root' }  # rootでSSH接続したときにのみ作業する設定
  - system      # OSの設定
  - mariadb     # RDBMSのインストールと設定、Redmine接続アカウントの作成
  - ruby        # ruby 2.2のインストール(CentOS標準ではなく)
  - redmine     # redmine 3.1.2のインストールと設定
  - unicorn     # unicorn のインストールと設定
  - nginx       # nginx のインストールと設定

  post_tasks:
    - name: 完了
      debug:
        msg='インストールが完了しました。http://ホスト名/ にアクセスして下さい。'

adminロールの定義

rootアカウントで作業が必要な最小限の設定を行うロールです。

  • 管理アカウントの作成
  • 公開鍵の登録

adminロールのタスク定義ファイルの配置

centos71_redmine
  +-- group_vars/
  |     +-- redmine-servers
  +-- roles/
        +-- admin/
              +-- tasks/
                    +-- main.yml

管理アカウントの名前とパスワード(ハッシュ)を定義

redmine-serversに次の記述をします。

# Linux管理アカウント
admin_user: admin
admin_password: $6$rounds=656000$.jE2cyz5uLj.olXB$YSzWzHezRTJd/5mUqOypddnUmMTAQOq7QF4fEDss15mrdp66vaDebw/PouemQkBTg2npkGyFWXdvOPiA.jmrK/
  • 管理作業で使うアカウントのユーザー名とパスワードを変数定義します。
    パスワードはsha512ハッシュで作成します。作成はPythonのワンライナーです。
    centos71_redmine$ python -c "from passlib.hash import sha512_crypt; print sha512_crypt.encrypt('admin-password')" 
    $6$rounds=656000$.jE2cyz5uLj.olXB$YSzW ...
    

    pythonのpasslibモジュールがないときは、pip install passlibでインストールします。

管理アカウントの作成

Linuxのユーザーとして管理アカウントを作成し、sudoでroot権限実行できるよう設定します。

main.ymlには次の記述をします。

- name: 管理アカウントの作成
  user:
    name: "{{ admin_user }}" 
    group: wheel
    password: "{{ admin_password }}" 

- name: 管理アカウントの公開鍵を登録
  authorized_key:
    user: "{{ admin_user }}" 
    key: "{{ lookup('file', '/home/' + admin_user + '/.ssh/id_rsa.pub') }}" 

- name: パスワードありで %wheel がsudo出来る設定をコメントアウト
  lineinfile:
    dest: /etc/sudoers
    regexp: '^(%wheel\s+ALL=\(ALL\)\s+ALL)'
    line: '# \1'
    backrefs: yes
    state: present

- name: パスワードなしで %wheel がsudo出来る設定のコメントアウトを解除
  lineinfile:
    dest: /etc/sudoers
    regexp: '^#\s*(%wheel\s+ALL=\(ALL\)\s+NOPASSWD:\s+ALL)'
    line: '\1'
    backrefs: yes
    state: present

admin_userに定義した管理ユーザーはAnsible実行マシンに予め作成しておき、またそのユーザーの公開鍵を所定の場所(~/.ssh/)に生成しておきます。

# useradd admin
# su - admin
~$ ssh-keygen
  :
~$ ls .ssh
id_rsa.pub  id_rsa

(参考)CentOS 7.1をインストールしたときに設けられる/etc/sudersは、%wheelについて次の設定となっています。

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL

## Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL

systemロールの定義

OS初期インストール後に行うOSの設定に関するタスクとして、ホスト名の設定、ファイアウォールの設定、追加パッケージのインストールなどを実行します。

systemロールのタスク定義ファイルの配置

定義ファイル

centos71_redmine
  +-- roles/
        +-- system/
              +-- tasks/
                    +-- main.yml

ホスト名の設定

main.ymlには次の記述をします。

- name: ホスト名の設定
  hostname: name={{ inventory_hostname }}

  • インベントリに記載したホスト名を、変数inventry_hostnameで引けるので、それをhostnameモジュールを実行して構築対象マシンに設定
  • rootでSSH接続したときにのみ実行する想定なので、sudo等の設定は未記載

ファイアウォールの設定

Redmineで使用する80ポート(http)、443ポート(https)、8282ポート(unicorn)を許可するよう設定します。

main.ymlには次の記述をします。


- name: firewalldでHTTPを許可
  firewalld: service=http zone=public permanent=true state=enabled immediate=true

- name: firewalldでHTTPSを許可
  firewalld: service=https zone=public permanent=true state=enabled immediate=true

- name: firewalldでポート8282を許可
  firewalld: port=8282/tcp zone=public permanent=true state=enabled immediate=true

追加パッケージのインストールとサービス起動

後でrubyのgemをインストールする際、ネイティブビルドをするために必要な開発パッケージ一式をインストールします。
また、仮想ゲストを外部からシャットダウンする際に必要なacpidのインストールとサービス起動設定をします。

main.ymlには次の記述をします。


- name: パッケージの追加インストール
  yum: name="{{ item }}" 
  with_items:
    - acpid
    - '@Development Tools'

- name: acpidサービスの自動起動設定と起動
  service: name=acpid enabled=yes state=started

mariadbロールの定義

MariaDBのパッケージインストール、設定、データベース接続アカウントの設定を行います。

mariadbロールのタスク定義ファイルの配置

定義ファイル

centos71_redmine
  +-- roles/
        +-- mariadb/
              +-- tasks/
              |     +-- main.yml
              +-- templates/
                    +-- server.cnf.j2
                    +-- mysql-clients.cnf.j2

パッケージのインストール、設定ファイル、自動起動設定

- name: MariaDBのインストール
  yum: name="{{ item }}" 
  with_items:
    - mariadb-server
    - mariadb-devel

- name: MySQL-pythonのインストール(Ansibleが使用)
  yum: name='MySQL-python'

- name: /etc/my.cnf.d/server.cnfを作成
  template: src={{ item }}.j2 dest=/etc/my.cnf.d/{{ item }} owner=root group=root mode=0644
  with_items:
    - server.cnf
    - mysql-clients.cnf

- name: MariaDB 起動・自動起動設定
  service: name=mariadb state=started enabled=yes

MariaDBのrootパスワード変更、redmineデータベース作成、redmineアカウント作成

- name: rootパスワード設定
  mysql_user: 
    name=root
    host={{ item }}
    password={{ mariadb_root_password }}
    login_user=root
    login_password={{ mariadb_root_password }}
    check_implicit_admin=yes
  with_items:
    - 127.0.0.1
    - ::1
    - localhost
  register:
    result
  ignore_errors: true

- name: エラー処理
  fail: msg="初期rootユーザーおよび指定したrootユーザーともに接続に失敗しました。MariaDBがインストール直後の状態でもRedmine設定状態でもありません。Redmineのインストールを中止します。MariaDBをアンインストールして再度playbookを実行してください。" 
  when: result.failed is defined

- name: 匿名ユーザー削除
  mysql_user:
    name=''
    state=absent
    login_user=root
    login_password={{ mariadb_root_password }}

- name: リモートからのrootログイン を禁止
  mysql_user:
    name=root
    host={{ ansible_fqdn }}
    state=absent
    login_user=root
    login_password={{ mariadb_root_password }}

- name: testデータベース削除
  mysql_db:
    name=test
    state=absent
    login_user=root
    login_password={{ mariadb_root_password }}

- name: Redmine用データベース作成
  mysql_db:
    name=redmine
    login_user=root
    login_password={{ mariadb_root_password }}

- name: Redmine用ユーザー作成
  mysql_user:
    name=redmine
    password={{ mariadb_redmine_password }}
    priv=redmine.*:ALL
    login_user=root
    login_password={{ mariadb_root_password }}

環境構築メモ

Cygwin上でAnsibleを実行する

Cygwin上でAnsibleを実行する場合、すこし制約があるのでその設定を記述します。

-kオプションでパスワードをコマンドライン環境から指定する場合、sshpassコマンドが必要

SSH接続のパスワードをansibleを-kオプション付きで実行し、コマンド入力で与えるには、sshpassコマンドがマシンに入っている必要があります。Cygwinにはsshpassはないので別途インストールします。

work$ wget "http://sourceforge.net/projects/sshpass/files/latest/download?source=files" -O sshpass.tar.gz
work$ tar xzf sshpass.tar.gz
work$ cd sshpass-1.05
sshpass-1.05$ ./configure
  :
sshpass-1.05$ make
  :
sshpass-1.05$ make install
  :

/usr/local/bin/sshpass が生成されていればOK。

参考情報

世の中のAnsible事例

Ansible playbook

スライド資料

Cygwinでの設定

クリップボードから画像を追加 (サイズの上限: 1 GB)