購入した書籍「インフラCI実践ガイド」を試した際のメモの続きです。
第7章のCIのパイプラインとなります。CIを行うためのパイプラインについての解説になります。第7章もボリュームがあるので前半と後半に分けます。今回は前半です。
7.1 パイプラインとは
パイプラインとは関連するジョブ(タスク)を連結して一連のフローとして流すための機能です。
7.1.1 パイプラインの役割
パイプラインとジョブネットやジョブワークフローとの違いについてです。
インフラCIは、人間が作業を行うことで環境に蓄積されてしますズレを抑制し、システムの品質や効率を上げるための手法です。
インフラCIを行うためにはプロジェクトメンバーにルール、ツールなどを遵守してもらう必要があります。
このプラクティスをメンバーに対して強制する方法がパイプラインの役割です。
7.1.2 インプットとアウトプット
インフラCIにおいて、入出力のインターフェースになるのがVCSやレビューシステムです。
7.1.3 パイプラインの注意点
インフラCIをデザインする担当者は、パイプラインを利用するメンバーの利便性を考える必要があります。パイプラインを作る際の注意点について解説してます。
メンバーが意義を感じられる
適用範囲を限定する
ブランチを用いた開発では変更部分のみに適用され、それ以外ではすべてのファイルに適用されるように作ってます。
軽微な問題を先に検知する
パイプラインでは必要なジョブを漏れなく実施することが重要ですが、それと同じくらいに「軽さ」が重視されます。
パイプラインが重くなってくるとメンバーは小さな変更ではなく大きな変更をまとめて流そうとします。これではせっかくIaCのベストプラクティスを実践しようしても効果が薄れてしまいます。
こうした事態を避けるには、パイプラインは簡単で素早く実行できるタスクを先に行い、時間がかかるタスクは後半へ回すことが良いとされています。
7.2 パイプラインを使った変更要求への対応
演習を通じて構成定義ファイルの変更とパイプラインを実行しています。
課題としてCMSのコンテンツのバックアップをする設定を行う要求があったというパターンで見ていきます。
7.2.1 バックアップの有効化
Ketchupには標準でバックアップ機能が準備されています。
設定ファイルでbackup enableをtrueに設定すると。ketchupが起動したタイミングでバックアップが作成されるようになります。
Ansibleのロールの中に設定ファイルを配置するテンプレートがあるので修正します。
変更作業の実施
テンプレートのファイル内のketchup bacupをtrueに変更したらpushします。
[root@infraci infraci]# cd ~/ketchup-vagrant-ansible/
[root@infraci ketchup-vagrant-ansible]# vim roles/ketchup/templates/config.json.j2
[root@infraci ketchup-vagrant-ansible]# git commit -a -m "enabled backup that was requested from app team"
[master 2a3cc15] enabled backup that was requested from app team
1 file changed, 1 insertion(+), 1 deletion(-)
[root@infraci ketchup-vagrant-ansible]# git push
Username for 'http://192.168.33.10': root
Password for 'http://root@192.168.33.10':
Counting objects: 11, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 524 bytes | 0 bytes/s, done.
Total 6 (delta 4), reused 0 (delta 0)
To http://192.168.33.10/root/ketchup-vagrant-ansible.git
dc91521..2a3cc15 master -> master
パイプラインが走っていることが確認できます
パイプラインが12分くらいかかって遅かったの書籍にあるgitlabとgitlab-runnerのメモリを上げてみました(デフォルトではどちらも2GB)
config.vm.define "gitlab" do |machine|
machine.vm.hostname = "gitlab"
machine.vm.network "private_network", ip: "192.168.33.10"
machine.vm.network "forwarded_port", guest: 80, host: 8080
machine.vm.provider "virtualbox" do |vbox|
vbox.cpus = 2
vbox.memory = 6144
end
end
config.vm.define "gitlab-runner" do |machine|
machine.vm.hostname = "gitlab-runner"
machine.vm.network "private_network", ip: "192.168.33.11"
machine.vm.network "forwarded_port", guest: 80, host: 8081
machine.vm.provider "virtualbox" do |vbox|
vbox.cpus = 2
vbox.memory = 8192
end
end
バックアップの確認
本当にバックアップが行われているか確認してみます。
[root@infraci ketchup-vagrant-ansible]# cd ~/vagrant/infraci/
[root@infraci infraci]# vagrant ssh test-ketchup
Last login: Sun Jun 28 12:29:15 2020 from 192.168.33.1
[vagrant@test-ketchup ~]$
[vagrant@test-ketchup ~]$
[vagrant@test-ketchup ~]$ sudo -i
[root@test-ketchup ~]# cat /opt/ketchup/config.json
{
"bindext": true,
"port": 80,
"data_dir": "app-contents/contents/data",
"bolt": {
"path": ""
},
"backup": {
"enabled": true
},
"themes": {
"path": "themes",
"registry_url": "http://themes.ketchuphq.com/registry.json"
}
}
[root@test-ketchup ~]# ls -al /opt/ketchup/app-contents/contents/data/backups/
total 4
drwx------. 2 root root 33 Jun 28 12:29 .
drwxr-xr-x. 6 root root 106 Jun 28 12:29 ..
-rwx------. 1 root root 3946 Jun 28 12:29 20200628-122916.bak
7.2.2 確かめられたこと、確かめられていないこと
今回のパイプラインで確認できたこと
→バックアップの設定をしても「バックアップ設定を実施する前のテスト」はパスできたという点
確認できなかったこと
→投入したバックアップの設定がただしく動作しているかどうかという点
7.2.3 テストを追加する
パイプラインにテストを追加する前に、現在どのように構成されているかを理解します。
Gitlabではプロジェクトのルートディレクトリに「.gitlab-ci.yml」というファイルを配置するとこれが読み込まれてパイプラインが起動します。
ステージと変更対象の確認
「.gitlab-ci.yml」の内容を確認してみます。
[root@infraci ketchup-vagrant-ansible]# head -n 10 ./.gitlab-ci.yml
---
stages:
- lint
- unit_prepare
- unit_test
- int_deploy
- int_test
variables:
CONTAINER_IMAGE: c7-systemd
stagesの部分についてです。パイプラインではステージという名前でジョブの実行順序を定義します。
演習では5つのステージが準備されています。
実行順序 | ステージ | 実行ジョブ | 実行される内容 |
1 | lint | Lint_Check_Master Lint_Check_Branches | Masterに対する全ファイルの規約準拠チェック Branchに対する全ファイルの規約準拠チェック |
2 | unit_prepare | Unit_Package | ユニットテスト用のコンテナイメージ作成 |
3 | unit_test | Ketchup_Unit_Test Ketchup_Nginx_Unit_Test | Ketchup設定に関するユニットテスト Nginx設定に関するユニットテスト |
4 | int_deploy | Ketchup_Int_Deploy | テスト環境にシステム一式をデプロイ |
5 | int_test | Ketchup_Nginx_Int_Test | テスト環境にデプロイされた環境へインテグレーションテストを実行 |
ユニットテストの動作
演習環境のユニットテストの動きについて確認します。
etchup_Unit_Test:
stage: unit_test
variables:
TARGET_APP: ketchup
services:
- name: ${CONTAINER_IMAGE_PATH}
alias: ${TARGET_APP}
entrypoint: ["/sbin/init"]
script:
- export CONTAINER_NAME="`hostname`-`echo ${CONTAINER_IMAGE_PATH}|sed -e 's/\//__/g' -e 's/\:[1-9a-z]\+//g'`-0"
- docker exec ${CONTAINER_NAME} /bin/bash -c "ansible-playbook -i ./tests/inventory -l ${TARGET_APP} ./${TARGET_APP}.yml"
- docker exec ${CONTAINER_NAME} /bin/bash -c "cd ./tests; ansible-playbook -i ./inventory ./${TARGET_APP}_test.yml -vv"
tags:
- docker
unit_prepareでユニットテスト用のイメージが作成。変更がされた構成定義ファイルをすべてイメージ内にコピーし、これらの実行のために必要な各種パッケージをインストールしています。
unit_testではこのイメージから起動したコンテナ内でテストを実行します。
テストにコンテナを利用している部分がポイントとなります。
テストコードの追加
ketchupの起動時に作成されるバックアップファイルの有無をチェックして、存在する→OK、存在しない→NG、というテストを追加します。
具体的には以下のような条件をテストします。
①「/opt/ketchup/app-contents/contents/data/backups/」に「英数字8桁-英数字6桁.bak」というファイルが生成される
②このファイルが1つだけ存在をOK(過去のバックアップなどの2つ以上のファイルが残っていたらNG)
③テスト実行時の10分前までに作成されたファイルでなければNG
実際にユニットテストのファイルに上記のテストを記載してGitにpushしてパイプラインが動いて、結果が成功することを確認します。
[root@infraci ~]# cd ~/ketchup-vagrant-ansible/
[root@infraci ketchup-vagrant-ansible]# vim roles/ketchup/tasks/unit_test.yml
- name: Count the number of backup files
shell: find {{ ketchup_home }}/{{ ketchup_data_dir }}/backups -type f -mmin -10 | grep -e '[0-9]\{8\}-[0-9]\{6\}.bak' | wc -l
register: test_backup_file_num
- name: Check th number of backup file is 1
assert:
that:
- ( test_backup_file_num.stdout | int ) == 1
msg: "Ketchup backup file is not exist or remaining old file"
[root@infraci ketchup-vagrant-ansible]# git commit -a -m "add unit test for backup config"
[root@infraci ketchup-vagrant-ansible]# git push
Username for 'http://192.168.33.10': root
Password for 'http://root@192.168.33.10':
テストコードの記載にミスがあって3回目でようやくクリアできました。
追加したテストコードの効果
他のチームメンバーが勘違いしてバックアップを無効にした場合を想定しています。もう一度バックアップを無効にします。
[root@infraci ~]# cd ~/ketchup-vagrant-ansible/
[root@infraci ketchup-vagrant-ansible]# vim roles/ketchup/templates/config.json.j2
(略)
"backup": {
"enabled": false
},
[root@infraci ketchup-vagrant-ansible]# git commit -a -m "Undo the backup config"
[root@infraci ketchup-vagrant-ansible]# git push
バックアップを無効のまま、パイプラインを実行すると、正しくバックアップファイルのユニットテストの部分でエラーになっていました。
今回のケースは実際の現場では結構あって、誰かがわからないまま変更している、というのを防ぐことができます。
誰がファイルを更新したかもgit使っているので簡単です。
[root@infraci ketchup-vagrant-ansible]# git blame aafd21fb2cd783e2c8350bb694310277cb5d4613 roles/ketchup/tasks/unit_test.yml
(略)
df80aabe (spchildren 2018-02-26 03:02:41 +0900 86) wait_for:
df80aabe (spchildren 2018-02-26 03:02:41 +0900 87) port: "{{ ketchup_port }}"
df80aabe (spchildren 2018-02-26 03:02:41 +0900 88) msg: "ketchup is not active."
df80aabe (spchildren 2018-02-26 03:02:41 +0900 89)
5b9815e8 (root 2020-06-25 06:42:50 +0900 90) - name: Count the number of backup files
45acf213 (root 2020-06-25 06:56:30 +0900 91) shell: find {{ ketchup_home }}/{{ ketchup_data_dir }}/backups -type f -mmin -10 | grep -e '[0-9]\{8\}-[0-9]
5b9815e8 (root 2020-06-25 06:42:50 +0900 92) register: test_backup_file_num
5b9815e8 (root 2020-06-25 06:42:50 +0900 93)
5b9815e8 (root 2020-06-25 06:42:50 +0900 94) - name: Check th number of backup file is 1
5b9815e8 (root 2020-06-25 06:42:50 +0900 95) assert:
5b9815e8 (root 2020-06-25 06:42:50 +0900 96) that:
aafd21fb (root 2020-06-25 07:17:52 +0900 97) - ( test_backup_file_num.stdout | int ) == 1
5b9815e8 (root 2020-06-25 06:42:50 +0900 98) msg: "Ketchup backup file is not exist or remaining old file"
5b9815e8 (root 2020-06-25 06:42:50 +0900 99)
df80aabe (spchildren 2018-02-26 03:02:41 +0900 100) become: True
上の変更履歴を見ると誰が、いつ、どこを修正したかも一目瞭然ですね。
記載ミスで「grep -e ‘[0-9]{8}-[0-9]」と「test_backup_file_num.stdout | int ) == 1」の部分を修正しています。
今回は結構長くなりましたが、次回も引き続きCIの部分の後半です。
今回は以上となります。
コメント