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トークン名】
おわり
以上で設定完了。
実際に適当なホストからマスターブランチに対してプッシュしてみて、直後にバックアップホストでもプルが走れば成功です。