この記事は [富士通クラウドテクノロジーズ Advent Calendar 2017]
(https://qiita.com/advent-calendar/2017/fjct)の17日目の記事です。
16日目は@clutterさんの「OK, Google. サーバーをスペックアップして」でした。
最近はやりの音声アシスタントをサーバのスペックアップに使うという発想面白くていいですね。
今回私はgitlab-ciとansibleでgolangのデプロイ環境を整えるお話をしたいと思います。
gitlab-ciとは
- gitlab バージョン8以降にデフォルトで付いているCIツールです。
- 特別な設定が不要で、リポジトリに
.gitlab-ci.yml
を追加するだけで利用できます。
デプロイ環境の概要
- gitlabにpushするとgitlab runnerが動き出します。
- gitlab runnerがデプロイのため以下の動作をするように
.gitlab-ci
を作成します。- ソースをビルドしgitlab上に保存
- ビルドでできたバイナリをvmへ転送
- AnsibleでVMにinit.dでサービス登録
ディレクトリ構成
gitlab.com/UminoShohei05/go-gitlabci
├── .gitlab-ci.yml
├── ansible
│ ├── inventories
│ └── roles
└── server/
-
.gitlab-ci
はビルドからAnsibleの実行まで行うジョブが定義されています。 -
ansible
にはgoのバイナリをserviceとして登録するplay-bookが入っています。 -
server
にはHelloWorld!を返すだけのgo+echoでできたAPIが入っています。 - OSはCentos6.7で試しています。
やってみる
まずはビルドジョブの作成
build_job
ではserver/
にあるソースをビルドし、できたバイナリをgitlab上に保存します。
ビルドジョブは以下のようになります。
build_job:
image: golang:1.8
stage: build
script:
- mkdir -p $GOPATH/src/gitlab.com/UminoShohei05/go-gitlabci/server
- mv $CI_PROJECT_DIR/server/* $GOPATH/src/gitlab.com/UminoShohei05/go-gitlabci/server
- cd $GOPATH/src/gitlab.com/UminoShohei05/go-gitlabci/server/
- go get -u github.com/golang/dep/cmd/dep
- dep ensure
- go build -o test-api
- cp test-api $CI_PROJECT_DIR
artifacts:
paths:
- test-api
ジョブの内容を解説していきます。
image
使いたいdockerイメージを指定します。
script
実行したい命令を記述していきます。
今回はビルドするため一度GOPATHに移動し、ビルドでできた成果物をartifacts
で使うために$CI_PROJECT_DIR
にコピーしています。
$CI_PROJECT_DIR
は、CI実行時にリポジトリがクローンされるディレクトリを表しています。
これはPredefined variablesというCI上で使うために元から定義されている変数で、詳細はこちらで確認することができます。
artifacts
ジョブの中で作成した成果物などをpath
で指定してgitlab上に保存できます。
path
は$CI_PROJECT_DIRからの相対パスとなっています。
今回artifacts
ではpath
のみ指定していますが、成果物の名前を変更したり、保存期間を指定することもできます。(何も指定しないと無限に残り続けます)
保存されたartifactsは画像のようにgitlab上からzip形式でダウンロードすることもできます。
デプロイジョブの作成
deploy_job
ではbuild_job
でできたバイナリのサーバへの転送と、Ansibleを使いバイナリをinit.dでサーバにサービス登録します。
デプロイジョブは以下のようになります。
deploy_job:
image: webdevops/ansible
stage: deploy
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client git -y )'
- eval $(ssh-agent -s)
- echo "$SSH_KEY" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan $SERVER_IP >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script:
- scp test-api root@$SERVER_IP:/opt/api/bin/release
- cd ansible
- ansible-playbook -i inventories/production.yaml deploy-api.yaml
before script
script
を実行する前の準備を記述していきます。
今回のデプロイジョブではscpやAnsibleでSSH keyを使うためssh-agentへの鍵の登録を行い、known_hostsへホストの登録をしています。
また、SSH keyはリポジトリに入れることが憚られるため、gitlabのSecret variablesという機能を使い参照できるようにしています。
画像のようにgitlab上でKeyとValueを入れ登録すると、CI上で$Key
で参照することができます。
APIのアクセスキーやシークレットキーの登録などもこちらで行うと安全に使えます。
script
scpコマンドを見てもらうとわかるように、前のジョブでartifacts
に保存したtest-api
をそのまま使っています。このように前のジョブの成果物を引き継ぎたい時にartifacts
は便利です。
デプロイのジョブは最後にserviceにtest-apiを登録するansibleを流して終了です。
Ansibleの内容については今回使ったリポジトリを貼っておくので、こちらで確認をしてみてください。
動作確認
さいごに
今回はデプロイをするだけの簡単なgitlab-ciですが、実際に仕事で使うにはbuildの前にlintやtestを追加するとより良いと思います。
また、今回は最低限の機能しか使っていませんが、指定されたブランチのpush時のみジョブを指定するonly
やジョブの障害時や失敗した場合に実行されるジョブを定義するwhen
など様々な機能があります。
一方で、gitlab-ciはpassphraseのついたssh keyが使えなかったり、パラメータを取るようなジョブの場合は向いていなかったりもします。
個人的にはgitlab-ciの機能面だけでなく、設定いらずで管理するツールも増えない部分にメリットを感じているので、gitlab-ciをこれからもっと使っていきたいなと思います。
あしたは@cooの「ニフクラの物理ネットワークを支える人たち」です。宜しくお願いします!