オンプレミスでChatOps！の環境（Mattermost と Gitlab と Jenkins）を自動で構築する 

# オンプレミスでChatOps！の環境（Mattermost と Gitlab と Jenkins）を自動で構築する 

## 0.はじめに
本記事では、[前回記事：オンプレミスでChatOps！ Mattermost と Gitlab と Jenkins を 連携する](
http://qiita.com/tbuchi888/items/fa02a10728999520e1a0)の
各OSS（Mattermost と Gitlab と Jenkins）環境を自動で構成、インストールする
Ansibleのplaybook とVagrantfile について掲載します。
検証環境等でのデモ、素振り用などに限定してお使いください。
<img width="860" alt="chatops_main01.png" src="https://qiita-image-store.s3.amazonaws.com/0/117986/07f8d4bb-6aec-1821-8441-378d5ae451d6.png">
なお、インストール完了後の各OSSの設定については以下の過去記事を参考にしていただければと思います。

+ [オンプレミスでChatOps！ Mattermost と Gitlab と Jenkins を 連携する](
http://qiita.com/tbuchi888/items/fa02a10728999520e1a0)

+ [CentOS6にJenkins2.2をAnsibleでインストールしてブラウザからJenkins2にログインするまで](http://qiita.com/tbuchi888/items/3c65cb4757225b09f08f)

また、ソースコード一式は以下github上へ上げています。
https://github.com/tbuchi888/vagrant-ansible-gitlab-mattermost-jenkins-for-chatops


## 1.環境
インターネットに接続された以下の環境で検証しました。
各種バージョンは検証当時（2016/09/01時点）のものなので、最新ではない可能性があります。

|サーバー種別|項目|詳細|Note|
|:-:|:-:|:-:|:-:|
|HOST　Server|OS|OSX Yosemite||
||Hypervisor|Virtualbox5.14||
||building tool|Vagrant1.8.5||
|||Ansible 2.1.0 update:2016/04/20|yum_repositoryモジュールを使うため2.1以降のバージョンを利用|
|Gitlab / Mattermost Server|OS|CentOS6.8|The Box of Vagrant is [geerlingguy/centos6](https://atlas.hashicorp.com/geerlingguy/boxes/centos6)(*1)|
||Host name|mygitlab|Change your environment(*2)|
||IPaddress|192.168.33.131|Change your environment(*2)|
||Code managemnt tool|GitlabCE ver.8.11.2||
||Chat tool|Mattermost ver.3.30|on GitlabCE|
|Jenkins2 Server|OS|CentOS6.8|The Box of Vagrant is [geerlingguy/centos6](https://atlas.hashicorp.com/geerlingguy/boxes/centos6)(*1)|
||Host name|myjenkins|Change your environment(*2)|
||IPaddress|192.168.33.132|Change your environment(*2)|
||CI Tool|Jenkins ver.2.19||

Note!
- *1: VagrantのBoxファイルは`atlas.hashicorp.com`上の[geerlingguy/centos6](https://atlas.hashicorp.com/geerlingguy/boxes/centos6) を利用していますが、ご自身の環境に応じて`conf-vbox-guestvm.yml`のbox名を適宜変更してください。
- *2: ご自身の環境に応じて`conf-vbox-guestvm.yml`及び `/etc/hosts`のホスト名、IPアドレスを適宜変更してください。
Vagrant（Ansible provisioner）を利用しない場合は、Ansibleのインベントリファイル`hosts.yml`についても同様に変更してください。

## 2.使い方
### 2.1 共通
今回作成するVM(または対象サーバ)2台分のホスト名を名前解決できるようにします。
例えば`sudo vi /etc/hosts`などで

```
192.168.33.131  mygitlab
192.168.33.132  myjenkins
```

また、ホストサーバまたはAnsible実行サーバ上の適当なディレクトリ上で、
Github上からコード一式をクローンします。
（または、後述の3.各種コードより新規にファイルを作成してください。）

```
git clone https://github.com/tbuchi888/vagrant-ansible-gitlab-mattermost-jenkins-for-chatops.git
cd vagrant-ansible-gitlab-mattermost-jenkins-for-chatops
```

### 2.2 VagrantでVMごとまるっと構築する場合
VMのホスト環境として、Vagrant と Virtualbox、Ansible(ver.2.1以降)の環境があり、Ansible provisionerが利用できる場合（OSXやLinux系など）は

```
vagrant up
```

### 2.3 AnsibleでOSS部分のみ構築する場合
Ansibleがインストールされたマシンから以下を実行します。

```
ansible-playbook -i hosts.yml -l gitlab install_gitlab_mattermost_without_proxy.yml -v
ansible-playbook -i hosts.yml -l jenkins install_jenkins_without_proxy.yml -v
```

## 3.各種コード
以下のGithub上と同じものです。
https://github.com/tbuchi888/vagrant-ansible-gitlab-mattermost-jenkins-for-chatops

|種別|ファイル名|内容|
|:-:|:-:|:-:|
|Vagrant|conf-vbox-guestvm.yml|VM情報やプロビジョニング情報を外部YMLファイルとして定義したもの|
||Vagrantfile|VM情報やプロビジョニング情報を外部YMLファイルから取込む形へVagrantfileをカスタマイズしたもの|
|Ansible|hosts.yml|インベントリファイル Vagrant(Ansible provisioner)を利用する場合は不要|
||install_gitlab_mattermost_without_proxy.yml|Gitlab及びMattermostをインストールするプレイブック|
||install_jenkins_without_proxy.yml|Jenkins2をインストールするプレイブック|

###　3.1.Vagrant関連

VM情報やプロビジョニング情報を外部YMLファイルとして定義したもの

``` conf-vbox-guestvm.yml
---
centos_base: &CENT_BASE
    box:                     geerlingguy/centos6
    os_type:                 linux

guestvm:
  - name:                    mygitlab
    ipaddress:               192.168.33.131
    ansible_playbook:        install_gitlab_mattermost_without_proxy.yml
    << : *CENT_BASE

  - name:                    myjenkins
    ipaddress:               192.168.33.132
    ansible_playbook:        install_jenkins_without_proxy.yml
    << : *CENT_BASE
```

Vagrantfile(上記YMLファイルを取り込むようにカスタムしたもの)

```　Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

require 'yaml'

# Rreading of guestVM configuration for the YML format file.
setting = YAML.load_file('conf-vbox-guestvm.yml')

# Set the hash variable
arr_guestvm_h = setting['guestvm']

# Define Vagrant ver.
VAGRANTFILE_API_VERSION = '2'

# Define Vagrantfile
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  # Use host's(macbook) proxy and dns   
  config.vm.provider "virtualbox" do |vb|
    vb.customize ["modifyvm", :id, "--natdnsproxy1", "on"]
    vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"]
  end

  # Define the settings for each guest OS and VM
  arr_guestvm_h.each do |guestvm|

    config.vm.define guestvm['name'] do |server|

      # Define guest OS setting
      server.vm.hostname              = guestvm['name']

      # Define box for vsphere
      server.vm.box                   = guestvm['box']

      if guestvm.has_key?('box_url') && !guestvm['box_url'].nil?
        server.vm.box_url             = guestvm['box_url']
      end

      if guestvm.has_key?('ipaddress') && !guestvm['ipaddress'].nil?
        server.vm.network               'private_network', ip: guestvm['ipaddress']
      end

      if guestvm.has_key?('os_type') && guestvm['os_type'] == 'linux'
#        server.vm.communicator        = :ssh
#        server.ssh.insert_key         = false
#        server.ssh.private_key_path   = '~/.ssh/id_rsa'
        if guestvm.has_key?('os_username') && !guestvm['os_username'] .nil?
          server.ssh.username         = guestvm['os_username']
          if guestvm.has_key?('os_password') && !guestvm['os_password']
            server.ssh.password       = guestvm['os_password']
          end
        end
      end
      if guestvm.has_key?('os_type') && guestvm['os_type'] == 'windows'
        server.vm.communicator        = :winrm
        server.vm.guest               = :windows
        if guestvm.has_key?('os_username') && !guestvm['os_username'].nil? 
          server.winrm.username       = guestvm['os_username']
          if guestvm.has_key?('os_password') && !guestvm['os_password'].nil?
            server.winrm.password     = guestvm['os_password']
          else
            puts "Input  #{guestvm['name']} #{guestvm['os_username']} ospassword:\n"
            server.winrm.password     = STDIN.noecho(&:gets).chop
          end
        end
      end

      # provisioning guest vm with ansible
      if guestvm.has_key?('ansible_playbook') && !guestvm['ansible_playbook'].nil?
        server.vm.provision "ansible" do |ansible|
          ansible.playbook            = guestvm['ansible_playbook']
          if guestvm.has_key?('ansible_inventory_path')  && !guestvm['ansible_inventory_path'].nil?
            ansible.inventory_path    = guestvm['ansible_inventory_path']
            ansible.limit             = guestvm['name']
          end
        end
      end
    end
  end
end
```

### 3.2.Ansible関連

インベントリファイル
*(VagrantのAnsible provisionerを利用する場合は不要)*

``` hosts.yml
[gitlab]
mygitlab
[jenkins]
myjenkins

[all:vars]
ansible_user=vagrant
ansible_password=vagrant
```

Gitlab及びMattermost

``` install_gitlab_mattermost_without_proxy.yml
---
# Setting the destination inventory host
- hosts: all
  become: yes
  become_method: sudo
  become_user: root
  
# Don't gather hosts facts for performance
  gather_facts: no

# Setting the task
  tasks:
    - name: yum install
      yum: name={{item.name}} state={{item.state}}
      register: yum_result
      with_items:
        - name: '*' 
          state: latest
        - name: openssh-server 
          state: latest
        - name: curl 
          state: latest
        - name: postfix 
          state: latest
    - debug: var=yum_result.results

    - name: postfix        should have been running
      service: name=postfix state=started enabled=yes 

    - name: lokkit -s http -s ssh 
      command: lokkit -s http -s ssh -p 8080:tcp
      register: cmd_result
    - name: command STDOUT 
      debug: var=cmd_result.stdout_lines

    - name: shell curl gitlab script.rpm.sh
      shell: curl -s https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash
      register: shell_result
    - name: command STDOUT 
      debug: var=shell_result.stdout_lines

    - name: gitlab-ce      should have been installed(latest)
      yum: name=gitlab-ce state=latest

    - name: command gitlab-ctl
      shell: gitlab-ctl reconfigure
      register: cmd_result
    - name: command STDOUT 
      debug: var=cmd_result.stdout_lines

# for Mattermost 
# mattermost_external_url 'http://mattermost.example.com'
    - name: enable mattermost on port 9999
      replace: dest=/etc/gitlab/gitlab.rb regexp='^# mattermost_external_url \'http\://mattermost\.example\.com\'$' replace='mattermost_external_url \'http://{{inventory_hostname}}:9999\''

    - name: command gitlab-ctl
      shell: gitlab-ctl reconfigure
      register: cmd_result
    - name: command STDOUT 
      debug: var=cmd_result.stdout_lines

    - name: lokkit -p 9999:tcp for mattermost
      command: lokkit -p 9999:tcp
      register: cmd_result
    - debug: var=cmd_result.stdout_lines

# Reference information
    - name: This is initial Password for root of Gitlab
      debug: msg="The initial password of the root account is `5iveL!fe`."
```

Jenkins

``` install_jenkins_without_proxy.yml
---
# Please use the OS of centOS6 and RHEL6. Also, please use in an environment that does not care about the HTTP_PROXY.
# yum_repository module you can use in Ansible version 2.1 or higher. 
# In the case of Ansible version 2.0 or less, and then comment out the yumrepo block, 
# please remove the comment "download jenkins.repo" and "rpm import jenkins-ci.org.key".

- hosts: all
  become: yes
  become_method: sudo
  become_user: root
  gather_facts: no

# Setting the task
  tasks:
    - name: Add jenkins repo
      yum_repository: 
        name: jenkins
        description: jenkins yum repo
        baseurl: http://pkg.jenkins-ci.org/redhat
        gpgcheck: yes
        gpgkey: http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

#      - name: download jenkins.repo
#        get_url: url=http://pkg.jenkins-ci.org/redhat/jenkins.repo dest=/etc/yum.repos.d/jenkins.repo
#
#      - name: rpm import jenkins-ci.org.key
#        command: rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key
#        register: raw_result
#      - debug: var=raw_result.stdout_lines

    - name: yum install
      yum: name={{item.name}} state={{item.state}}
      register: yum_result
      with_items:
        - name: '*' 
          state: latest
        - name: openssh-server 
          state: latest
        - name: java-1.8.0-openjdk 
          state: latest
        - name: jenkins
          state: latest
    - debug: var=yum_result.results

    - name: jenkins should have been running
      service: name=jenkins state=started enabled=yes

    - name: lokkit -p 8080:tcp
      command: lokkit -p 8080:tcp
      register: cmd_result
    - debug: var=cmd_result.stdout_lines

#    - name: cat initialAdminPassword for Unlock Jenkins
#      command: cat /var/lib/jenkins/secrets/initialAdminPassword
#      register: cmd_result
#    - name: this is initialAdminPassword for Unlock Jenkins
#      debug: var=cmd_result.stdout_lines
```

以上