はじめに
仕事でGitHubを使い出したんですが、Push後に既存のJenkins上にあるjobを実行をしたい。でもJenkinsサーバーはVPN上、どうやって繋ぐんだろう。
ってのを調べて解決したので記事に残しときます。
ポイントは3つ
- GitHub上で秘密鍵などのシークレット情報はどうやって管理するんだろう?
- VPNはどうやって張ったらいいんだろう?
- GitHub ActionからどうやってJenkinsのJobを呼ぶんだろう?
GitHubでのシークレット情報の管理
GitHubでは、リポジトリのsettins > secretからシークレット情報が保存できます。(リポジトリ管理者限定)
例えば EncodedVPNSettings
という名前のsecuret情報を登録した場合、 secrets.EncodedVPNSettings
を環境変数に設定することで、secret情報が使えるようになります。
- name: Install Open VPN
run: sudo apt-get install openvpn
- name: Decode setting file
env:
ENC_SETTING: ${{ secrets.EncodedVPNSettings }}
詳細は公式マニュアルを見るのが一番分かりやすいです。暗号化されたシークレットの作成と保存
VPNの貼り方
こんなライブラリもありましたが、もっとシンプルな方法を紹介。
openvpnで使う設定ファイル一式を丸ごとsecretに保存する
GitHub Actions上では以下のような処理を実行していきます。
- tarで固めてbase64 encodingした設定ファイルをsecret情報に保存
- openvpnをインストール
- secret情報のbase64 encodingされたtarファイルをbase64デコードして一旦保存
- tarファイルを解凍して利用する
注意としては、secretはechoだとうまく参照できないです。secret情報は表示が*に変わるようになっているからと思われます。
なので、pythonでファイルに書き込むなどする必要があります。
以下サンプルでは EncodedVPNSettings
という名前で設定ファイルをsecretに登録しています。
- name: Install Open VPN
run: sudo apt-get install openvpn
- name: Decode setting file
env:
ENC_SETTING: ${{ secrets.EncodedVPNSettings }}
run: |
import os
import subprocess
import base64
code=os.environ.get('ENC_SETTING')
with open("tmp.tar.gz", 'w') as f:
f.write(base64.b64decode(code))
shell: python
- name: Umcompress file
run: |
ls
tar xvzf tmp.tar.gz
圧縮はこんな感じにスクリプトを用意してもいいかも
if [ $# -ne 1 ]; then
echo "$0 vpnpath"
exit 0
fi
TOP=${1}
cd ${TOP}
tar czf .tmp.tar.gz *
echo "EncodedVPNSettings"
cat .tmp.tar.gz | base64
rm .tmp.tar.gz
cd - > /dev/null
GitHub ActionからのJenkins jobの呼び方
GitHub Actionsから何か特別なことをするわけではなく、Jenkins job側で、外部実行可能な設定を行います。
Jenkins jobのconfigure、Build TriggersでTrigger builds remotelyを選び、Authentication Tokenを設定します。
その後は JENKINS_URL/view/GitHub/job/JOBSNAME/buildWithParameters?token=TOKEN_NAME
をcurlなどで実行すればOK。
GitHub Actionsで利用する際は、このAuthentication Tokenをsecretで登録しましょう。以下サンプルではTokenNameという名前で登録しています。
- name: Call jenkins job
env:
TOKEN_NAME: ${{ secrets.TokenName }}
run: |
curl -gv --insecure http://localhost/view/GitHub/job/JOBSNAME/buildWithParameters?token=${TOKEN_NAME}
GitHub Actionsコードサンプル
以下をrepositoryに設定した上で使用します。
secret key | value |
---|---|
EncodedVPNSettings | tarで圧縮してbase64 encodingしたopenvpnの設定ファイル (+利用する鍵・証明書) |
TokenName | jenkinsで設定したAutentication Token |
jenkinsはovervpnホストにあるsample_jobsという名前のjobの例です。
name: github_actions
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Clone code
uses: actions/checkout@v2
- name: Install Open VPN
run: sudo apt-get install openvpn
- name: Decode setting file
env:
ENC_SETTING: ${{ secrets.EncodedVPNSettings }}
run: |
import os
import subprocess
import base64
code=os.environ.get('ENC_SETTING')
with open("tmp.tar.gz", 'w') as f:
f.write(base64.b64decode(code))
shell: python
- name: Umcompress file
run: |
ls
tar xvzf tmp.tar.gz
- name: Connect
run: |
CONF=`ls *.ovpn`
sudo -b openvpn --config ${CONF}
- name: Call jenkins job
env:
TOKEN_NAME: ${{ secrets.TokenName }}
run: |
curl -gv --insecure https://overvpn/view/GitHub/job/sample_jobs/buildWithParameters?token=${TOKEN_NAME}
- name: kill vpn
if: always()
run: sudo killall openvpn