実践ネット自動化スクリプト集

現場で使えるPythonネットワーク自動化:コンフィグの自動Gitバージョン管理

Tags: Python, ネットワーク自動化, コンフィグ管理, Git, バックアップ, Netmiko

はじめに

システムやインフラの運用において、ネットワーク機器の設定ファイル(コンフィグ)は非常に重要な資産です。これらのコンフィグがどのように変更されたか、誰がいつ変更したかといった履歴を正確に把握することは、障害発生時の原因究明や復旧作業、あるいは設定ドリフト(意図しない設定変更)の検出において不可欠です。

しかし、手動で各機器にログインしてコンフィグを取得し、ファイルとして管理するのは非常に手間がかかります。特に管理対象機器が多い場合や、頻繁に設定変更が行われる環境では、手動管理は非現実的です。

開発の世界では、ソースコードのバージョン管理にGitが広く利用されています。Gitの強力な変更履歴管理、差分表示、ブランチ機能などは、ネットワークコンフィグの管理にも非常に有効です。Pythonを用いることで、このGitによるバージョン管理プロセスを自動化し、ネットワークコンフィグの信頼性と運用効率を大幅に向上させることができます。

この記事では、Pythonとネットワーク機器操作ライブラリ、そしてGit操作ライブラリを組み合わせ、ネットワーク機器のコンフィグを定期的に取得してGitリポジトリに自動でコミット・プッシュするスクリプトの実装方法について解説します。

なぜネットワークコンフィグをGitでバージョン管理するのか

ネットワークコンフィグをGitでバージョン管理するメリットは多岐にわたります。

  1. 変更履歴の明確化: いつ、誰(またはどのプロセス)が、どのような変更を行ったかがGitのコミットログで明確に記録されます。これにより、設定変更に起因する問題発生時の原因特定が容易になります。
  2. 容易なロールバック: 過去の任意の時点のコンフィグを容易に取得できます。設定ミスや意図しない挙動が発生した場合に、直前の安定稼働していた状態のコンフィグに戻すことが迅速に行えます。
  3. 差分の可視化: Gitの差分(Diff)機能を使うことで、特定のコミット間やブランチ間の設定変更内容を視覚的に確認できます。手動では見落としがちな微細な変更も把握できます。
  4. 設定ドリフトの検出: 定期的にコンフィグを取得してGitリポジトリと比較することで、オペレーターによる手動での設定変更など、自動化プロセスを介さずに発生した設定ドリフトを検出できます。Gitの差分を確認すれば、具体的にどの部分が変更されたかを確認可能です。
  5. チームでの共同作業: Gitリポジトリを共有することで、複数のエンジニアがネットワークコンフィグの履歴を共有し、協調して作業を進めることが容易になります。
  6. IaC(Infrastructure as Code)の基礎: コンフィグファイルをコードとして扱い、バージョン管理下に置くことは、ネットワークのIaCを実現する上での基本的なステップとなります。

これらのメリットを享受するためには、コンフィグを定期的に、かつ確実に取得し、Gitに記録する仕組みが必要です。Pythonは、ネットワーク機器との通信やファイル操作、外部コマンド実行など、必要な機能を容易に実現できるため、この自動化に適しています。

Pythonを使ったコンフィグ自動取得の実装

ネットワーク機器からコンフィグを取得するために、PythonのライブラリであるNetmikoを使用します。Netmikoは、SSH経由でネットワーク機器に接続し、コマンドを実行してその結果を取得することに特化しています。様々なベンダーの機器に対応しており、機器固有のプロンプトやページャー(--More--など)の処理を自動で行ってくれるため、非常に便利です。

ここでは、Netmikoを使った単一機器からのコンフィグ取得の基本を示します。複数機器への適用は、リストやファイルから機器情報を読み込んでループ処理を行うことで実現できます。

import os
from netmiko import ConnectHandler
from getpass import getpass # 例として対話的なパスワード入力を示しますが、本番では安全な方法を使用してください

# 機器接続情報 (実際にはファイルや環境変数から読み込むことが推奨されます)
device = {
    'device_type': 'cisco_ios', # 機器のタイプに合わせて変更 (例: juniper_junos, arista_eos)
    'host': '192.168.1.1',      # 機器のIPアドレスまたはホスト名
    'username': 'admin',        # 接続ユーザー名
    'password': getpass('Enter password: '), # セキュアな方法で取得
    'secret': getpass('Enter enable password: '), # 特権EXECモードへのパスワード (必要な場合)
    'port': 22,                 # SSHポート (通常は22)
}

# コンフィグ取得コマンド
# 機器のベンダーやOSによって異なります。一般的なコマンド例です。
command = 'show running-config'

try:
    print(f"Connecting to {device['host']}...")
    # Netmikoで機器に接続
    with ConnectHandler(**device) as net_connect:
        print("Connection successful.")

        # 特権EXECモードに移行 (必要な場合)
        if device.get('secret'):
             net_connect.enable()

        # コマンドを実行して結果を取得
        output = net_connect.send_command(command)
        print("Command executed successfully.")

        # 取得したコンフィグを表示 (またはファイルに保存)
        print("\n--- Running Config ---")
        print(output)
        print("--------------------")

        # コンフィグをファイルに保存する場合
        config_dir = './configs'
        if not os.path.exists(config_dir):
            os.makedirs(config_dir)
        filename = f"{config_dir}/{device['host']}.cfg"
        with open(filename, 'w') as f:
            f.write(output)
        print(f"Configuration saved to {filename}")


except Exception as e:
    print(f"An error occurred: {e}")

実行環境と依存関係:

このスクリプトは、指定された機器に接続し、show running-configコマンドを実行して、その結果を指定したディレクトリに機器名.cfgとして保存します。エラーハンドリングとして、接続エラーやコマンド実行エラーが発生した場合の基本的なtry...exceptブロックを含めています。

Gitリポジトリでのバージョン管理自動化

次に、取得したコンフィグファイルをGitリポジトリに追加し、コミット、そしてリモートリポジトリにプッシュする処理を自動化します。PythonからGitコマンドを実行する方法はいくつかありますが、ここではGitPythonライブラリを使用します。GitPythonはGitリポジトリをPythonオブジェクトとして操作できるため、subprocessで直接Gitコマンドを叩くよりも直感的でエラー処理なども容易になります。

まず、コンフィグファイルを保存するためのローカルGitリポジトリを用意します。

# コンフィグ保存用のディレクトリを作成 (上記のPythonスクリプトで作成する場合もあります)
mkdir configs
cd configs

# Gitリポジトリとして初期化
git init

# リモートリポジトリを追加 (例: GitHub, GitLab, Bitbucketなど)
# git remote add origin <リモートリポジトリのURL>

# 初回のコミットとプッシュ (手動で行っておくと後が楽です)
# touch README.md # 必要に応じて
# git add .
# git commit -m "Initial commit"
# git push -u origin main # mainブランチの場合

次に、取得したコンフィグファイルをGitリポジトリにコミット・プッシュするPythonコードです。上記のコンフィグ取得スクリプトと組み合わせて使用します。

import os
from git import Repo # GitPythonライブラリを使用

# Gitリポジトリのパス
repo_path = './configs' # 上記で作成したローカルリポジトリのパス

# コミットメッセージの生成
# 実行日時や自動化スクリプトによるものであることを明記すると良いでしょう
import datetime
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
commit_message = f"Automated config backup at {timestamp}"

try:
    # ローカルリポジトリを開く
    repo = Repo(repo_path)

    # Gitの状態を確認 (変更があるか)
    # ステージングエリアに追加されていない変更や、コミットされていない変更を確認
    # status = repo.git.status()
    # print("Git Status before add:\n", status) # デバッグ用

    # 変更されたファイルをステージングエリアに追加
    # ここではコンフィグディレクトリ内の全ての変更を追加します
    repo.git.add(A=True) # '-A'オプションで全ての変更(追加、修正、削除)をステージ

    # ステージングエリアに変更があるか確認
    # repo.index.diff(repo.head.commit) でコミット済みとの差分
    # repo.index.diff(None) でステージングエリアとの差分
    # git.add(A=True) の後なので、repo.index.diff(None) はステージングエリアとの差分を確認
    # より正確には、add A=True の後に diff --cached を確認するのが良いかもしれません
    # GitPythonでは、index.diff(repo.head.commit) でステージングエリアにある差分を確認できます
    if repo.index.diff(repo.head.commit):
        # 変更があればコミット
        print("Changes detected. Committing...")
        repo.index.commit(commit_message)
        print("Commit successful.")

        # リモートリポジトリにプッシュ
        # リモート名 'origin'、ブランチ名 'main' の例です
        print("Pushing to remote repository...")
        origin = repo.remote(name='origin')
        origin.push()
        print("Push successful.")
    else:
        print("No changes detected. Skipping commit and push.")

except Exception as e:
    print(f"An error occurred during Git operations: {e}")

実行環境と依存関係:

このスクリプトは、指定されたローカルリポジトリパスを開き、コンフィグディレクトリ内の全ての変更(Netmikoで取得・保存された新しいコンフィグや更新されたコンフィグ)をステージングエリアに追加します。変更が存在する場合にのみコミットを行い、リモートリポジトリにプッシュします。これにより、コンフィグの変更がない場合は無駄なコミットが発生しないようになります(ある程度の冪等性)。

スクリプトの統合と実践的な考慮点

上記のコンフィグ取得部分とGit操作部分を統合することで、定期的にネットワーク機器のコンフィグを取得し、自動でバージョン管理するスクリプトが完成します。

全体のスクリプトの構造としては、以下のような流れになります。

  1. 対象となるネットワーク機器のリストを読み込む(ファイル、DBなどから)。
  2. 各機器に対して、Netmikoを使ってコンフィグを取得し、ファイルに保存する。
  3. コンフィグファイルが保存されているディレクトリでGitPythonを使って、変更をコミット・プッシュする。
  4. 各ステップでエラーハンドリングを行い、失敗した機器やGit操作があればログに記録するなどの処理を追加する。

実践的な考慮点:

まとめ

この記事では、PythonのNetmikoGitPythonライブラリを活用し、ネットワーク機器のコンフィグを自動で取得してGitでバージョン管理する基本的な手法を解説しました。

ネットワークコンフィグの自動バージョン管理は、変更履歴の追跡、容易なロールバック、設定ドリフト検出など、多くのメリットをもたらし、運用効率と信頼性を向上させます。開発分野で培われたGitによる管理手法をネットワーク運用に取り入れることは、ネットワークのIaCを推進する上でも有効なステップです。

ここで紹介したスクリプトはあくまで基本形です。実際の現場で利用するには、認証情報の安全な管理、堅牢なエラーハンドリング、機器リストの柔軟な管理、定期実行の設定、そして大規模環境へのスケーリングなど、様々な要素を考慮し、改良を加えていく必要があります。

ぜひ、この記事を参考に、Pythonを使ったネットワークコンフィグの自動バージョン管理に挑戦してみてください。これにより、日々の運用業務が効率化され、より付加価値の高い業務に時間を割くことができるようになるでしょう。