Colorless Green Ideas

インフラエンジニアとして勉強したこと

jinja2+Markdownによる再利用性の高い運用手順書

要約

  • 再利用性の高い運用手順書を作成するため、手順のモジュール化およびテンプレート化を試みた。
  • 1つの作業に対応する手順書を生成する際は、jinja2テンプレートに環境変数から取得したパラメータを埋め込み、Markdownファイルとして出力するスクリプトを実行する。
  • 各手順はディレクトリごとにモジュール化されており、再利用する際はjinja2のincludeで読み込む。
  • 何らかのCI/CDプロセスと組み合わせることで、Markdownファイルからスクリーンショットを埋め込んだpdfファイルを自動生成するなど、より実践的な手順書の生成も可能。

はじめに

システムの運用管理において、業務の標準化の観点から運用手順書の作成は欠かせません。そのため、運用手順書の作成・管理のプロセスを効率化することには重要な意義があると考えられます。

運用手順書の作成・管理においては、特に下記のような課題が散見されます。

  • 陳腐化:システムの構成が変わったが、関連する運用手順書の洗い出しおよびそれを更新する時間が捻出できずそのままになってしまう。結果、特定の作業者への属人化や現場判断での読み替えの常態化など、システムの信頼性に対するリスクが生じる。
  • バージョン管理:運用手順書の更新の際、いつ誰がどのような意図で変更を加えたかが可視化されない。そのため、ローカルにコピーした運用手順書が古い版であることに気が付かずそのまま手順を実行してしまうなど、システムの信頼性に対するリスクが生じる。
  • 既存手順の二重管理:運用手順書を作成する際、既存手順と重複する記載をした場合、その既存手順に変更が必要になった場合に合わせて変更する手間が生じる。しかし単純にハイパーリンクなどで参照させた場合、作業時に作業者がそのリンクを辿らなければならない。結果、特に時間的制約が厳しい作業においては、作業ミスを誘発する要因となり、システムの信頼性に対するリスクが生じる。
  • 手順とパラメータの混在:システムへの変更作業の安全性を検証するには、手順の妥当性とパラメータの妥当性とは別個に確認されなければならない。ここでパラメータとは、例えば作業対象ホストのような個々の変更作業に紐づく情報を指す。もし手順とパラメータを別個に管理する方法が無い場合、その運用手順書は変更作業の度にパラメータが埋め込まれた形で作成されるか、またはパラメータを全く含めない汎用的な記載方法で作成されるかしかない。この場合、前者はコピペミスなどの手順作成ミスを誘発し、後者はパラメータの考慮不足による作業ミスを誘発する。結果、システムの信頼性に対するリスクが生じる。

また運用手順書の作成には下記のような媒体が利用されますが、いずれも上記の課題全てに対する単純な解決手段は提供しません。

  • エクセル・・・陳腐化、バージョン管理、既存手順の二重管理の課題
  • Word・・・陳腐化、バージョン管理、既存手順の二重管理の課題
  • Wikiページ・・・既存手順の二重管理、手順とパラメータの混在の課題
  • その他メモ書き・・・陳腐化、既存手順の二重管理、手順とパラメータの混在の課題

本記事では、上記の各課題を解決可能な運用手順書について、jinja2+Markdownの組み合わせで実現する方法を述べます。

運用手順書リポジトリの概要

各種運用手順書をまとめたものとして、下記のようなディレクトリ構成でリポジトリを作成します。

ここでtest01およびtest02は、各種作業手順のモジュールとして1つのディレクトリにまとめられています。

.
├── header.md.j2
├── link_md.py
├── test01
│   ├── main.md.j2
│   ├── map.md.j2
│   └── parameters.yml
└── test02
    ├── main.md.j2
    ├── map.md.j2
    └── parameters.yml

各種ファイルの役割は下記の通りです。

  • header.md.j2:運用手順書のヘッダ情報に対応するjinja2テンプレート。
# {{ operation_name }}
- 作業の目的:{{ purpose }}
- 作業所要時間:{{ time }}
- 禁止事項:{{ forbidden_matter }}
  • link_md.py:作業手順に相当するjinja2テンプレートおよびパラメータに相当する環境変数を読み込み、パラメータを埋め込んだ運用手順書をMarkdownファイルとして生成するスクリプト
import os
import yaml
from jinja2 import Environment, FileSystemLoader

with open(os.environ["MANUAL_NAME"] + "/parameters.yml") as yml:
    parameter_keys = yaml.safe_load(yml)

parameters = {
    "MANUAL_NAME": os.environ["MANUAL_NAME"],
    "OPERATOR": os.environ["OPERATOR"]
}

for key in parameter_keys["parameters"]:
    parameters[key] = os.environ[key]

template = Environment(loader=FileSystemLoader(".")).get_template(os.environ["MANUAL_NAME"] + "/map.md.j2")

print(str(template.render(parameters)))
  • main.md.j2:モジュール化された作業手順の内容に対応するjinja2テンプレート。
## test01
The test parameter is {{ test }}
## test02
The test parameter is {{ test }}
  • map.md.j2:header.md.j2とモジュール化された作業手順を紐づけるjinja2テンプレート。このようなテンプレートを使うことで、容易に各作業手順の再利用が可能になる。
{% with operation_name = "operation_name01", purpose = "purpose01", time = "time01", forbidden_matter = "forbidden_matter01" %}
{% include "header.md.j2" %}
{% endwith %}
- 作業者:{{ OPERATOR }}

{% with  test = TEST %}
{% include "%s/main.md.j2" % MANUAL_NAME %}
{% endwith %}
{% with operation_name = "operation_name01", purpose = "purpose01", time = "time01", forbidden_matter = "forbidden_matter01" %}
{% include "header.md.j2" %}
{% endwith %}
- 作業者:{{ OPERATOR }}

{% with  test = TEST01 %}
{% include "test01/main.md.j2" %}
{% endwith %}

{% with  test = TEST02 %}
{% include "test02/main.md.j2" %}
{% endwith %}
  • parameters.yml:その作業手順において必要になるパラメータをまとめたもの
---
parameters:
  - TEST
---
parameters:
  - TEST01
  - TEST02

運用手順書の生成

以上を踏まえた上で、下記のようなコマンドを実行することで、1つの作業に対応する運用手順書のMarkdownテキストが生成されます。

vagrant@mgmt01:~/workdir/ops_document_builder$ export MANUAL_NAME=test01 OPERATOR=operator01 TEST=aaa; python3 link_md.py

# operation_name01
- 作業の目的:purpose01
- 作業所要時間:time01
- 禁止事項:forbidden_matter01

- 作業者:operator01


## test01
The test parameter is aaa
vagrant@mgmt01:~/workdir/ops_document_builder$ export MANUAL_NAME=test02 OPERATOR=operator01 TEST01=aaa TEST02=bbb; python3 link_md.py

# operation_name01
- 作業の目的:purpose01
- 作業所要時間:time01
- 禁止事項:forbidden_matter01

- 作業者:operator01


## test01
The test parameter is aaa



## test02
The test parameter is bbb

評価

上記のjinja2+Markdownによる運用手順書の作成方法が、先述の課題を容易に解決できることを確認します。

  • 陳腐化:1つの運用手順書リポジトリに情報が集約されており、かつモジュール化が容易なため、より少ないコストで関連する運用手順書の更新可能になっている。これにより、陳腐化の課題を解決している。
  • バージョン管理:全てテキストベースであるため、gitなどの既存のツールで容易にバージョン管理が可能になっている。これにより、バージョン管理の課題を解決している。
  • 既存手順の二重管理:新規手順作成時および既存手順更改時のいずれのタイミングでもモジュール化が容易であるため、より少ないコストで二重管理の状態を解消可能になっている。これにより、既存手順の二重管理の課題を解決している。
  • 手順とパラメータの混在:この運用手順書の作成方法では、手順を作成するタイミングとパラメータを埋め込むタイミングが明示的に分かれている。これにより、手順とパラメータの混在の課題を解決している。

今後の展望

上記のコマンド実行部分をCI/CDプロセスに乗せることで、続けてMarkdownからpdfを生成するなどより実践的な使い方も可能になると考えられます。

特にスクリーンショットが必要な運用手順書の場合、pdfへの画像埋め込みは重要です。