JenkinsでCI環境構築~Ansible版~

CIとは

実はよく分かっていません。たぶん開発→テスト→デプロイのスピードを上げましょう的な話だと思います。
そして今回は次のイメージの環境を構築します。

イメージ図

補足しますと、どこかしらで開発した成果物をGitHubにプッシュした際、自分のホストに対しても自動でデプロイされる環境を構築したいです。

Jenkinsとは

自動デプロイツールです。要は開発環境でコードを書いてそれをGitHubにプッシュしたとして、GitGubからJenkinsサーバにイベント通知が飛びそこから、ターゲットになる別のホスト(例えば本番環境)に対してデプロイされるというもの。
主目的はGitHubの冗長をローカルに自動でとれたら便利だなぁということです。

Jenkinsサーバ構築

という訳で構築していきます。今回はAnsibleを利用します。その内Dockerでリプレースしたいです。

$ tree .
.
|-- ansible.cfg
|-- hosts
|-- roles
|   `-- jenkins-server
|       |-- files
|       |   `-- jenkins.j2
|       `-- tasks
|           `-- main.yml
`-- start.yml

まずはインベントリファイルを編集する。

[jenkins-server]
localhost

[jenkins-server:vars]
token_name=
token_value=
job_name=
jenkins_user=admin
jenkins_serv=
jenkins_port=8080
nini=
name_space=
ultrahook_user=centos
ultrahook_api=
payload_url="http://{{ nini }}.{{ name_space }}.ultrahook.com/"
forward_url="http://{{ jenkins_user }}:{{ token_value }}@{{ jenkins_serv }}:{{ jenkins_port }}/job/{{ job_name }}/buildWithParameters?token={{ token_name }}"
  • hosts
    • token_name/value:Jenkinsで作るAPIトークン(後述)
    • job_name:Jenkinsで作るジョブ名
    • jenkins_user:ジョブを動かすユーザ
    • jenkins_serv/port:JenkinsホストIP/Port
    • nini:ultrahookで使う任意の文字列(後述)
    • name_space: ultrahookで使うNameSpace(後述)
    • ultrahook_user:バックアップホスト上で動くユーザ
    • ultrahook_api:発行されたAPIトークン(後述)

次にプレイブック群を編集する。

- hosts: jenkins-server
  connection: local
  roles:
    - jenkins-server
- name: "OpenJDK Install"
  yum:
    name: "{{ item.name }}"
    state: "{{ item.state }}"
  with_items:
      - { name: 'java', state: 'latest' }
      - { name: 'git', state: 'latest' }
      - { name: 'wget', state: 'latest' }

- name: "Public Key Import"
  shell: "wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo; rpm --import http://jenkins-ci.org/redhat/jenkins-ci.org.key"

- name: "Jenkins Install"
  yum:
    name: jenkins
    state: latest

- name: "Jenkins Started & Enabled"
  systemd:
    name: jenkins
    state: started
    enabled: yes

- name: "Install Ruby for ultrahook"
  yum:
    name: ruby
    state: present

- name: "Install Package of Ruby for ultrahook"
  yum:
    name: ruby-devel
    state: present

- name: "Install gcc for ultrahook"
  yum:
    name: gcc
    state: present

- name: "Install ultrahook"
  shell: |
    gem install ultrahook
    echo "api_key: {{ ultrahook_api }}" > /home/{{ ultrahook_user }}/.ultrahook


- name: "Debug Payload URL, Login Pass"
  command: cat /var/lib/jenkins/secrets/initialAdminPassword
  register: login_pass

- debug:
    msg: "{{ item }}"
  with_items:
    - "{{ login_pass.stdout_lines }}"
    - "{{ payload_url }}"
    - "{{ forward_url }}"
  • main.yml
    • 1~9:諸パッケージDL
    • 10~22:jenkinsインストール
    • 24~42:ultrahookインストール(後述)
    • 45~54:jenkins初期パス、ペイロードURL(後述)標準出力

プレイブック実行

# cp -r * /etc/ansible/
$ cd /etc/ansible/
$ ansible-playbook -i hosts start.yml

Jenkins設定

とりあえず推奨プラグインとか諸々のインストールを行う。

APIトークン

GitHubとJenkinsを紐づける際のトークンを作成する。
「 Jenkinsの管理>ユーザーの管理>設定>APIトークン」でトークン作成。
※トークン名とトークンIDを控えておく。

CSRF無効化

「Jenkinsの管理>グローバルセキュリティの設定>CSRF Protection
」でCSRF対策を無効化にする。

GiThub連携用プラグイン

「Jenkinsの管理>プラグインの管理」で「Conditional BuildStep」をインストールする。
今回はmasterブランチにプッシュが発生した場合にジョブを動かしたいので、条件分岐を行うためのプラグインを導入する必要がある。

ジョブ作成

General

項目内容
ビルドのパラメータ化タイプ   :文字列
名前    :payload
デフォルト値:none
古いビルドの破棄適当に良い感じで

ソースコード管理

なし

ビルド・トリガ

項目内容
リモートからビルド上で作成したトークン名

ビルド

項目内容
ビルド手順の追加Conditional step (single)
Run?Regular expression match
Expression.*”ref”:”refs\/heads\/master”.*
Label${ENV,var=”payload”}
Builderシェルの実行

シェルの内容(例:自分の場合)

#!/bin/bash -xe
ssh-keyscan -t rsa 【バックアップホストIP】 >> ~/.ssh/known_hosts
ssh -i /var/lib/jenkins/.ssh/private.pem centos@【バックアップホストIP】 "cd /home/centos/work; if [[ ! -d /home/centos/work/【リポジトリ名】 ]]; then mkdir 【リポジトリ名】; cd 【リポジトリ名】; git init; fi; cd 【リポジトリ名】; git pull https://github.com/【GitHubユーザ名】/【リポジトリ名】.git"

Ultrahook

GitHubの設定の前にultrahookの解説。
こいつはグローバルドメインをプライベートドメインにフォワーディングしてくれる代物。
例えばバックアップを置きたい自分のホストがプライベートアドレスしか割り振れない場合、通常webhook(後述)のターゲットに出来ないが、ultrahookでフォワーディングすることで、Jenkinsから別セグメントのローカルホストへ接続することが出来るようになる。便利だけどセキュリティは若干甘くなることを考慮しておかないといけない……

まずはUltrahookにアカウントを登録し、APIトークンを発行してもらう。
そして以下のコマンドを打つ。

$ echo "api_key: {api_key}" > ~/.ultrahook
※今はプレイブック在中

$ ultrahook 【任意】 【jenkins向けURL】

すると次の様にフォワーディングされる。

http://【任意】.【NameSpace】.ultrahook.com

【jenkins向けURL】
になっているはず!

jenkins向けURLの作り方について

http://【jenkinsホストIP:ポート番号】

GitHub設定

ペイロードURL

「Settings>Webhooks」で次のように設定する。

http://【jenkinsユーザ名】:【apiトークン】@【任意】.【namespace】.ultrahook.com/job/【ジョブ名】/buildWithParameters?token=【apiトークン名】

おわり

以上で設定完了。
実際に適当なホストからマスターブランチに対してプッシュしてみて、直後にバックアップホストでもプルが走れば成功です。

コメントを残す

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

CAPTCHA