AlmaLinux 9 総合ガイド 第12章

第12章: 自動化とスクリプト作成


12.1 この章で解説する主要な技術・概念

Linuxサーバー運用において、手作業による設定やメンテナンスはヒューマンエラーが起こりやすく、大規模になるほど管理が複雑になります。自動化スクリプト作成を推進することで、作業を効率化し、環境の一貫性を保ち、人的ミスを減らすことが可能です。本章では、以下のトピックを深掘りし、AlmaLinux 9での高度な運用自動化手法を学びます。

  1. シェルスクリプトの高度な書き方
  • 関数、条件分岐、配列、エラー処理、デバッグ
  1. タスクの自動化 (cron, systemd timers, systemd-run)
  • 定期実行やイベントドリブン実行のベストプラクティス
  1. 構成管理ツール (Ansible, Puppet, Chef など) の概要
  • エージェントレス/エージェント型の違い、長所・短所
  1. Ansibleを使った実践的な運用例
  • Playbookの設計、Roles、Inventory管理、Vault(機密情報の暗号化)
  1. SSHキー管理とセキュリティ
  • パスワードレス運用時のリスクと対策、Authorized Keysの一括管理
  1. 自動化のユースケース
  • サーバー初期設定、パッケージアップデート、バックアップ、サービス起動・停止、CI/CDとの連携

12.2 シェルスクリプトの高度な書き方

12.2.1 関数とモジュール化

#!/bin/bash

function backup_dir() {
  local src=$1
  local dest=$2
  rsync -av --delete "$src" "$dest"
}

function main() {
  backup_dir "/var/www" "/backup/www"
  backup_dir "/home" "/backup/home"
}

main
  • 関数化しておくと再利用・テスト・保守が楽になる
  • local で変数スコープを限定し、グローバル汚染を防ぐ

12.2.2 条件分岐と配列

# 配列
servers=("web01" "web02" "db01")
for srv in "${servers[@]}"; do
  echo "Deploying to $srv..."
  # ssh $srv ...
done

# 条件分岐
if [ "$1" == "start" ]; then
  systemctl start myapp
elif [ "$1" == "stop" ]; then
  systemctl stop myapp
else
  echo "Usage: $0 {start|stop}"
fi
  • 文字列比較[ "x" == "y" ]や数値比較[ num -gt 0 ]などさまざまな条件式を使う

12.2.3 エラー処理とデバッグ

set -euo pipefail
trap 'echo "Error on line $LINENO"' ERR
  • -e: コマンドが失敗したらスクリプトを即終了
  • -u: 未定義変数の参照でエラー
  • -o pipefail: パイプ内のいずれかのコマンドが失敗したらスクリプトをエラー扱い
  • trap '...' ERR: エラー時にライン番号などの情報を表示
# デバッグモード
bash -x myscript.sh
  • 各行実行前にコマンドを表示してくれるため、ロジックの追跡が容易

12.2.4 スクリプト管理とリファクタリング

  • リポジトリ管理: Gitなどのバージョン管理システムを導入し、レビューやロールバックを容易に
  • ドキュメンテーション: スクリプト冒頭に概要や引数の説明、想定する実行環境などをコメントで残す
  • テンプレート化: よく使うスクリプト構造(ロギング、引数解析、trap設定など)をテンプレ化し、プロジェクト全体で共通化

12.3 タスクの自動化 (cron, systemd timers, systemd-run)

12.3.1 cronの高度な活用

  • cronは指定日時・周期でスクリプトを実行する仕組み
  • /etc/crontab, /var/spool/cron/$USER, /etc/cron.d/ など複数の配置先がある
  • MAILTO= 変数を活用すると、実行結果やエラーがメールで通知される

時間指定の工夫

# 例: 毎日深夜3:15に実行
15 3 * * * /usr/local/bin/backup_script.sh

# 例: 平日のみ(月~金)、2時間ごと
0 */2 * * 1-5 /usr/local/bin/report_script.sh
  • crontab.guruなどを使って日付指定を可視化し、複雑なパターンでもミスを減らす

12.3.2 systemd timersの利点

  • systemd timers はcronの代わりにsystemdユニットとして動作
  • OnCalendar= で時間指定し、ログやリソース制御がsystemdに統合できる

例: /etc/systemd/system/db_backup.service

[Unit]
Description=Database Backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/db_backup.sh

例: /etc/systemd/system/db_backup.timer

[Unit]
Description=Run DB Backup every day at 03:15

[Timer]
OnCalendar=*-*-* 03:15:00
Unit=db_backup.service

[Install]
WantedBy=timers.target
sudo systemctl enable db_backup.timer
sudo systemctl start db_backup.timer
  • systemctl list-timers でタイマー一覧が確認できる

12.3.3 systemd-runによる動的実行

sudo systemd-run --on-active=5 /usr/local/bin/cleanup_script.sh
  • --on-active オプションで今から5秒後にワンショットのsystemdサービスとして実行
  • ロギングやリソース制御(systemd slice)を適用しやすい

12.4 構成管理ツールの概要

12.4.1 エージェントレス vs エージェント型

  • エージェントレス (Ansible): SSHでターゲットに接続し、Playbookを実行。セットアップが簡単だが、ターゲットがSSHアクセス可能である必要がある。
  • エージェント型 (Puppet, Chef, Salt): 各ターゲットにエージェントが常駐し、マスターサーバーと通信して設定を適用。リアルタイムに監視・設定が可能。

12.4.2 PuppetやChefの基本

  • Puppet: manifest を記述し、Master-Client通信で定期的に設定を適用。
  • Chef: cookbook でレシピを定義し、Chef Serverがクライアントに配信する仕組み。Rubyベースで柔軟だが学習コストあり。
  • SaltStack: YAMLベースのステートファイルで管理し、エージェントかエージェントレスの両運用が可能。

注意: 大規模環境ではPuppetやChefが一時期主流だったが、近年はAnsibleやSaltStackがよりシンプルな運用で人気。


12.5 Ansibleによる実践的運用例

12.5.1 Ansibleの基本構成

sudo dnf install ansible
  • Inventory: ターゲットホスト一覧 (/etc/ansible/hosts など)
  • Playbook: YAML形式でタスクを記述
  • Roles: Playbookの機能をディレクトリ構成ごとに分割し、再利用性を高める

例: hostsファイル

[webservers]
192.168.10.101
192.168.10.102

[dbservers]

192.168.10.201

12.5.2 シンプルなPlaybook例

---
- name: Install Apache and start service
  hosts: webservers
  become: true  # sudo権限
  tasks:
    - name: Install Apache
      dnf:
        name: httpd
        state: present

    - name: Enable and start Apache
      systemd:
        name: httpd
        enabled: true
        state: started
ansible-playbook -i hosts site.yml
  • become: true でsudoを使ってroot権限でタスクを実行
  • dnfモジュールsystemdモジュールなど、Ansibleは多くのモジュールを標準搭載

12.5.3 Rolesとディレクトリ構成

ディレクトリ例:

site.yml
roles/
  webserver/
    tasks/main.yml
    handlers/main.yml
    templates/
    files/
  dbserver/
    tasks/main.yml
    ...
inventories/
  production
  staging
  • ansible-galaxy init webserver で雛形を作成可能
  • roles/webserver/tasks/main.yml でWebサーバー関連のタスクをまとめ、Playbookでは- role: webserver として呼び出すだけ

12.5.4 Ansible Vaultで機密情報の暗号化

ansible-vault create secrets.yml
# パスワード設定し、YAMLファイルを暗号化して保管

ansible-vault edit secrets.yml
ansible-playbook -i hosts site.yml --ask-vault-pass
  • DBパスワードやAPIキーを暗号化し、Gitリポジトリに安全にコミット可能

12.6 SSHキー管理とセキュリティ

12.6.1 パスワードレスSSHとリスク

  • Ansibleや自動化スクリプトはSSH鍵認証を前提とすることが多い
  • ssh-copy-id でターゲットに公開鍵を設置し、~/.ssh/authorized_keys に追記
  • キーの紛失や漏洩に備えて定期的に鍵をローテーションする、秘密鍵をパスフレーズ付きで暗号化しておくなどの対策が必要

12.6.2 大規模環境での鍵管理

  • ldapやADと連携して公開鍵を管理する仕組みを構築
  • エージェント型構成管理 (Puppet, Chef) で鍵配布を集中管理
  • バスワードレスは楽だが、踏み台サーバー経由で鍵が盗まれないようにport knockingVPNなど多層防御を検討

12.7 自動化のユースケース

12.7.1 サーバー初期設定

  1. OSインストール直後にネットワーク設定、ホスト名変更、セキュリティ強化(firewall, selinuxポリシー)をAnsibleシェルスクリプトで一括適用
  2. ユーザーアカウント作成、sudoers設定、SSH鍵配置など

12.7.2 パッケージアップデートとバックアップ

  • dnf updatecronやsystemd timerで定期実行し、ログをメール通知
  • rsynctarスクリプトでバックアップを夜間に実施し、rcloneでクラウド転送

12.7.3 サービス起動・停止やデプロイ

  • CI/CDパイプライン (GitLab CI, Jenkins など) からAnsible Playbookを呼び出し、新バージョンのアプリをデプロイ
  • システム障害時の自動フェイルオーバー (Pacemaker, Keepalived) と組み合わせ、復旧手順を自動化

12.8 学習のまとめ

  1. シェルスクリプトの高度な書き方: 関数や配列、エラー処理を活用し、管理しやすく堅牢なスクリプトを実装。デバッグモードやtrapを使って開発・保守性を高める。
  2. タスクの自動化 (cron, systemd timers, systemd-run): 定期実行やワンショットの自動化を行い、スクリプトとの連携で反復作業を省力化。システムd経由でのリソース制御やロギングも視野に。
  3. 構成管理ツール: エージェントレスのAnsibleをはじめ、PuppetやChefなどのエージェント型ツールも含めて、大規模環境ではテンプレート化と自動適用を活用。
  4. Ansible運用: インベントリ、Playbook、Rolesを正しく使い分け、Vaultで秘密情報を保護する。デプロイやサーバー初期設定、パッケージ管理など幅広いタスクを一元化。
  5. SSHキー管理とセキュリティ: パスワードレス運用は便利だがリスクもあるので、鍵ローテーションや多層防御を検討。
  6. ユースケース: サーバー初期設定、バックアップ、デプロイ、障害対応など、実運用の多くを自動化し、安定稼働と工数削減を両立。

次章へのつながり

次の章(第13章)では、AlmaLinux 9でのコンテナ化(Docker/Podman)や仮想化(KVM, libvirt)にフォーカスし、モダンなアプリケーション運用やテスト環境の構築を効率化する技術を深掘りします。自動化と組み合わせることで、スケーラブルかつ柔軟なインフラを実現できるでしょう。