この記事は Ansible 2 Advent Calendar 2019 20日目の記事になります。
この記事ではAnsible PlaybookのCI/CDパイプラインを設計する際に検討すべきポイントについて解説します。
この記事で書くこと
- CI/CDパイプラインを構成する要素
- CI/CDパイプラインの要素のコストの計算方法
この記事で書かないこと
- CI/CDパイプラインのフローの設計方法
- 特定のツールの使い方
用語の定義
パイプラインの用語の定義は組織やプロジェクトによって定義が異なることが多いため最初は用語の定義からはじめます。
各用語についての詳細な説明は細かく解説すると長くなるので省きます。分からない場合はGoogle等で調べてください。
パイプラインの要素
CI/CDパイプラインで利用する技術的要素を以下の通りと定義します。
Coding Standard
- コーディング規約のチェック
- lint
License Analysis
- システムを運用または販売する上でライセンスに違反しているコードやライブラリが含まれていないかチェックする
SAST(Static Application Security Testing)
- コード(またはバイナリ)に脆弱性が含まれているかチェックする
- Secret detection(秘密鍵、クラウドのペアキー等がコードに含まれているかチェックする)
DAST(Dynamic application security testing)
- ランタイムシステムへHTTPリクエスト等を送信し脆弱性をチェックする
Hardening testing
- 弱性を減らすことでシステムのセキュリティ堅牢にする
- 必要のないパッケージの削除
- ウィルス対策ソフトのインストール
- 不要なユーザアカウントやデーモンを停止
- etc
SCA(Software Composition Analysis)
- システムに脆弱性があるライブラリが含まれていないかチェックする
Penetration testing(侵入テスト)
- システムを攻撃しネットワークの脆弱性をチェックする
Smoke testing
- システムが稼働するか最低限のチェックをする
Monitorning
- システムの監視とアラート
Thread intelligence
- 脅威情報のチェック
ツールのスコア
パイプラインのステージで利用するツールを選定する上での「コストの見積もり」に使う指針です。コストが高いものは実装しないなどの方針を決めるのに役に立ちます。
統合性
CI/CDパイプラインに組み込みやすいツールかどうか。例えばSASTはパイプラインに組み込む事が容易ですが、一方でランタイムシステムが必要なDASTは組み込むのが難しいと言う特性があります。
A: 組み込みやすい
.
.
.
F: 組み込みにくい
網羅性
ツールの検査結果がどの程度の範囲を網羅しているか。
例えばSASTで検出される脆弱性はランタイムシステムが無いので表面的なもので漏れが発生する可能性があります。一方DASTで検出される脆弱性はランタイムシステム内で実行されるため信頼性も高くなる傾向にあります。
ただしDASTでも 検査項目にない項目は検出されない ので注意が必要です。
A: 検査結果の信用度が高い
.
.
.
F: 検査結果の信用度が低い
速度
ツールの実行速度。SASTは実行速度が速く、DASTやHardening testingはランタイムシステムが必要になるため実行速度が遅くなる傾向にあります。
A: 処理速度が速い
.
.
.
F: 処理速度が遅い
閾値
ツールの結果のノイズの多さ。
Secret detectionはほぼ100%の精度で脆弱性を検出し、結果にノイズが入る事はないと考えられます。またThread intelligenceは(通常は)検出結果が多くノイズも多いため脆弱性に対応する順番を精査し処理していく必要があります。
A: ノイズが少ない
.
.
.
F: ノイズが多い
パイプラインの処理の流れ
パイプラインの処理の流れを以下の図の通りとします。
Ansible Playbook CI/CDパイプラインのステージの構成項目
以下は基本的な構成要素としてパイプラインに含んだ方が良い考えられる項目です。
基本項目(なるべく実装する)
- Secret detection
- 変数を変えてPlaybookを実行する
- 冪等性のチェック
- ansible-playbookコマンドのログ情報の収集
アドバンスト(余裕があれば実装した方が良い)
- ansible-playbook実行時のリアルタイムのログ出力
- Ansibleのバージョンの違いでPlaybookを実行する
- lint
- Hardening testing(ウィルス対策ソフトの導入、等々)
環境によって実装した方が良い
- ローカルでのansible-playbookコマンドの実行1
- SCA(Software Composition Analysis)
- Penetration testing(侵入テスト)
- Monitoring(システムの監視とアラート)
実装する必要がない
- Smoke testing(システムが稼働するのか最低限のチェック)
実際には判断できない可能性も大いにあるのですが、通常は「ansible-playbookコマンドが成功したか失敗したか」で判断できるものと考えられます。
チェックリストを作成する
上記を踏まえてCI/CDパイプラインを作成するためのチェックリストを作成します。今回は「 Ansible Playbookを利用してVMを構成管理する 」と言うシナリオを考えます。Playbookを適用する対象がネットワーク機器、Windowsシステム等だとチェックリストの内容も変わってきます。
検査ツールに関しては適当に表に埋めているだけですので「この検査ツールがベスト」と言う意味ではありません。
環境によって適切なツールを選択します。
大分類 | 小分類 | 検査ツール | ランタイム | 統合性 | 網羅性 | 速度 | 閾値 | その他 |
---|---|---|---|---|---|---|---|---|
SAST | lint | ansible-lint | X | A | A | A | F | [ANSIBLE0002][ANSIBLE0011]のみ採用 |
Secret detection | Yelp/detect-secrets | X | A | A | A | A | 必ず実装する | |
DAST | - | - | - | - | - | - | - | - |
SCA | パッケージの脆弱性検査 | Vuls | ◯ | F | A | F | F | VulsのVMのアップデートは3時間に一回 |
Penetration testing | 侵入テスト | AWSインフラ担当が行う | - | - | - | - | - | - |
Monitoring | Metrix | AWSインフラ担当が行う | - | - | - | - | - | 事前にVMへPrometheusをインストールしておく |
Tracing | AWSインフラ担当が行う | - | - | - | - | - | 事前にVMへOpentracingをインストールしておく | |
Logging | AWSインフラ担当が行う | - | - | - | - | - | 事前にVMへELKをインストールしておく | |
Ansible Playbook | 変数を変えてPlaybookを実行 | Tesfinfra | ◯ | F | B | D | A | 並列処理で対応する |
冪等性 | Tesfinfra | ◯ | F | A | F | A | Playbookを2回実行する・並列処理で対応する | |
Hardening testing | yum update | Testinfra | ◯ | A | A | B | A | Ansile Playbookで処理する |
SSHポートを閉じる | AWSインフラ担当が行う | - | - | - | - | - | - | |
不必要なパッケージの削除 | Testinfra | ◯ | A | F | B | A | Ansile Playbookで処理する |
最後に
最初から全ての項目をCI/CDパイプラインに含めるのは作業量的に無理という場合は作成した表を元に優先順位を決めます。
先ずは最重要項目をチェックするCI/CDパイプラインを組み、その後余力でパイプラインを拡張していくのが良いと思われます。
また、チームやプロジェクトによって用語の定義、検査項目の優先順位、ツールの選定方法は当然ながら変わってきますのでこの記事はあくまでAnsible PlaybookのCI/CDパイプラインの設計方法の手法の1つとして参考にしていただけると幸いです。
参考リンク
- Security in CI/CD Pipelines: Tips for DevOps Engineers | SideShare
- CI/CD Best Practices for Your DevOps Journey | SlideShare
- Make your Ansible playbooks maintainable, flexible, and scalable | SlideShare
-
ansible-playbook コマンドをネットワーク経由ではなくVMやコンテナ等で直接実行すると言う意味 ↩