Apache設定を「プログラミング」する:mod_macro「Use」とテンプレート活用の具体例

2025-05-26

mod_macroは、Apache HTTP Serverの設定ファイル内でマクロを定義し、それを使用するためのモジュールです。これにより、繰り返し登場する設定ブロックをテンプレート化し、より簡潔で管理しやすい設定ファイルを作成できます。

「Use」ディレクティブは、定義済みのマクロを呼び出して展開するために使用されます。

どのような時に役立つか?

例えば、複数のバーチャルホスト(Virtual Host)がほぼ同じ設定を持っている場合を考えてみてください。それぞれのバーチャルホストに対して、DocumentRootErrorLogCustomLogなどのディレクティブを毎回記述するのは手間がかかり、ミスも発生しやすくなります。

mod_macroを使えば、これらの共通する設定をマクロとして一度定義し、Useディレクティブを使って必要な箇所でそのマクロを呼び出すことができます。

Useディレクティブの構文と動作

Useディレクティブの基本的な構文は以下の通りです。

Use name [value1 valueN]
  • [value1 valueN]: マクロの定義で指定されたパラメーターに対応する値を指定します。マクロ定義で指定されたパラメーターの数と、Useで渡す引数の数は一致させる必要があります。
  • name: 呼び出すマクロの名前を指定します。この名前は、<Macro>ディレクティブで定義されたものと一致する必要があります。

Useディレクティブが実行されると、以下の処理が行われます。

  1. 指定されたマクロ(name)が検索されます。
  2. Useディレクティブで渡された値(value1など)が、マクロ定義で対応するパラメーターに置き換えられます。
  3. 展開された設定ブロックが、あたかもそこに直接記述されたかのようにApacheによって処理されます。

具体例

バーチャルホストを定義するマクロの例を見てみましょう。

まず、<Macro>ディレクティブを使ってマクロを定義します。

<Macro VHost $name $domain $docroot>
    <VirtualHost *:80>
        ServerName $domain
        ServerAlias www.$domain
        DocumentRoot "/var/www/vhosts/$docroot"
        ErrorLog "/var/log/httpd/$name.error_log"
        CustomLog "/var/log/httpd/$name.access_log" combined
    </VirtualHost>
</Macro>

このマクロはVHostという名前で、$name$domain$docrootという3つのパラメーターを受け取ります。

次に、このマクロをUseディレクティブで呼び出します。

Use VHost example example.com example_site
Use VHost myapp myapp.net myapp_site

上記のUseディレクティブは、Apacheの起動時に以下のように展開されて処理されます。

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot "/var/www/vhosts/example_site"
    ErrorLog "/var/log/httpd/example.error_log"
    CustomLog "/var/log/httpd/example.access_log" combined
</VirtualHost>

<VirtualHost *:80>
    ServerName myapp.net
    ServerAlias www.myapp.net
    DocumentRoot "/var/www/vhosts/myapp_site"
    ErrorLog "/var/log/httpd/myapp.error_log"
    CustomLog "/var/log/httpd/myapp.access_log" combined
</VirtualHost>

このように、Useディレクティブを使うことで、複数の類似した設定ブロックを簡潔に記述し、設定ファイルの可読性と保守性を高めることができます。

注意点

  • 展開はApache起動時: マクロはApacheの起動時に展開されます。動的にマクロの内容が変化するわけではありません。
  • 再帰の検出: マクロの展開が無限ループにならないように、mod_macroは再帰的なマクロ展開を検出してエラーを出力します。
  • パラメーターの命名規則: パラメーター名には、他のディレクティブとの衝突を避けるために$%@などのプレフィックスを付けるのが推奨されます。
  • 引数の数の一致: Useで渡す引数の数は、マクロ定義のパラメーターの数と完全に一致させる必要があります。


mod_macroはApacheの設定を簡潔にする強力なツールですが、その性質上、設定ミスが発生しやすい部分でもあります。特にUseディレクティブはマクロの展開を担うため、エラーの原因となることがよくあります。

マクロが定義されていない、またはUseの前に定義されていない

エラー例
[macro:error] Use of undefined macro 'MyVHost'

原因
Useディレクティブで呼び出そうとしているマクロ(この例ではMyVHost)が、Apacheの設定ファイル内で<Macro>ディレクティブによって定義されていないか、Useディレクティブより後の行で定義されている場合に発生します。Apacheは設定ファイルを上から順に読み込むため、マクロはUseされる前に定義されている必要があります。

トラブルシューティング

  • マクロ定義の確認
    httpd.confやインクルードされている設定ファイル内で、Useしているマクロ名と一致する<Macro>ディレクティブが正しく記述されているかを確認します。

引数の数がマクロ定義と一致しない

エラー例
[macro:error] Macro 'MyMacro' invoked with 2 arguments, but defined with 3 arguments.

原因
Useディレクティブで渡す引数の数(パラメーターの数)が、<Macro>ディレクティブで定義されたパラメーターの数と異なる場合に発生します。

トラブルシューティング

  • Useディレクティブの確認
    Useディレクティブで、マクロ定義で指定された数と同じ数の引数が渡されているかを確認します。

    例:

    # マクロ定義 (3つの引数)
    <Macro MyVHost $domain $docroot $logname>
        ServerName $domain
        DocumentRoot "/var/www/$docroot"
        ErrorLog "/var/log/httpd/$logname.error_log"
    </Macro>
    
    # 正しいUse (3つの引数)
    Use MyVHost example.com public_html example
    
    # 誤ったUse (2つの引数) -> エラー
    Use MyVHost example.com public_html
    
  • マクロ定義の確認
    <Macro>ディレクティブを見て、いくつのパラメーター($param1 $param2など)が定義されているかを確認します。

パラメーター名の衝突、または意図しない置換

警告例
[macro:warn] Parameter '$name' in macro 'MyMacro' is shadowed by a global define. (または類似の警告)

原因
mod_macroのパラメーター名が、Apacheの他のディレクティブ(例: Define)や他のマクロのパラメーター名と衝突している場合に発生する可能性があります。また、mod_macroはテキスト置換を行うため、意図しない文字列が置換されてしまい、結果的に設定エラーになることもあります。

トラブルシューティング

  • UndefMacroの使用
    マクロの使用が終わったら、UndefMacroディレクティブを使ってマクロの定義を解除することを検討します。これにより、大規模な設定ファイルで変数名の衝突を避けるのに役立ちます。
  • パラメーター名のプレフィックス
    パラメーター名には、$%@などのシグナル(記号)を付けることが強く推奨されます。これにより、一般的なディレクティブ名との衝突を避けることができます。公式ドキュメントでも推奨されています。 例: $nameではなく${name}のようにブレースで囲むことで、より明確な置換範囲を指定できます。

マクロ内で許可されないディレクティブの使用

エラー例
[core:crit] [pid 12345:tid 67890] (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80 (直接的なmod_macroのエラーメッセージではないが、マクロ展開の結果として発生)

原因
mod_macro自体はディレクティブの構文を深くチェックするわけではありません。マクロが展開された結果として、Apacheが認識できないディレクティブや、コンテキスト(server configVirtualHostDirectoryなど)が正しくないディレクティブが含まれてしまうと、Apacheの構文チェックでエラーが発生します。例えば、<Macro>内でListenディレクティブを定義し、それを複数回Useすると、同じポートを複数回リッスンしようとして「Address already in use」のようなエラーが出ることがあります。

トラブルシューティング

  • マクロの出力確認 (デバッグ)
    複雑なマクロの場合、実際にどのように展開されているかを確認するのが難しいことがあります。一時的にマクロ内の内容をコメントアウトし、手動で展開後の内容を直接設定ファイルに記述してみて、それが動作するかどうかをテストする方法も有効です。
  • エラーログの確認
    Apacheのエラーログ(通常、/var/log/httpd/error_log/var/log/apache2/error.log)を確認します。マクロ展開後の最終的な設定に問題がある場合、ここに詳細なエラーメッセージが出力されます。

mod_macroモジュールがロードされていない

エラー例
[core:error] Invalid command 'Macro', perhaps misspelled or defined by a module not included in the server configuration [core:error] Invalid command 'Use', perhaps misspelled or defined by a module not included in the server configuration

原因
mod_macroを使用するためには、Apacheの設定でこのモジュールがロードされている必要があります。

トラブルシューティング

  • モジュールファイルの存在確認
    modules/mod_macro.soファイルがApacheのモジュールディレクトリに実際に存在するかを確認します。
  • モジュールのロード確認
    httpd.confまたは対応するconf.d/内のファイルで、LoadModule macro_module modules/mod_macro.soという行がコメントアウトされておらず、正しく記述されているかを確認します。

全体的なトラブルシューティングのヒント

  • 公式ドキュメントの参照
    mod_macroの公式ドキュメント(Apache HTTP Server Version 2.4 - mod_macro)は、最も正確で詳細な情報源です。
  • 小さなステップで変更
    複雑なマクロを作成する際は、少しずつ変更を加えてはテストする(configtestとリロード/再起動)ことを繰り返すのが効果的です。
  • Apacheエラーログの確認
    ほとんどの問題はエラーログに詳細な情報が出力されます。エラーログのパスはhttpd.confErrorLogディレクティブで確認できます。
  • apachectl configtestの活用
    これが最も基本的なツールです。設定変更後は常に実行し、エラーメッセージを注意深く読みましょう。


mod_macroは、Apacheの設定ファイル内で繰り返し現れるパターンを抽象化し、再利用可能にするためのモジュールです。特に、複数の仮想ホスト(Virtual Host)やディレクトリに似た設定を適用する場合に非常に便利です。

ここでは、いくつかの一般的なシナリオにおけるUseディレクティブの使用例を示します。

例1: 複数の仮想ホストを簡潔に定義する

最も一般的なmod_macroのユースケースです。Webサイトごとに類似した設定(ドキュメントルート、ログファイルなど)を持つ場合に役立ちます。

マクロ定義 (/etc/httpd/conf.d/vhosts_macro.conf など):

# mod_macro モジュールがロードされていることを確認
# LoadModule macro_module modules/mod_macro.so

# VHost マクロの定義
# $name: サイトの識別名 (ログファイル名などに使用)
# $domain: ドメイン名 (ServerName, ServerAlias に使用)
# $docroot: ドキュメントルートのパス
<Macro VHost $name $domain $docroot>
    <VirtualHost *:80>
        ServerName $domain
        ServerAlias www.$domain

        # ドキュメントルートのパス
        DocumentRoot "/var/www/html/$docroot"

        # エラーログとアクセスログ
        ErrorLog "/var/log/httpd/$name.error_log"
        CustomLog "/var/log/httpd/$name.access_log" combined

        # ディレクトリ設定 (例: AllowOverride All)
        <Directory "/var/www/html/$docroot">
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
    </VirtualHost>

    # HTTPS (ポート443) の場合も同様に定義することが多い
    <VirtualHost *:443>
        ServerName $domain
        ServerAlias www.$domain
        DocumentRoot "/var/www/html/$docroot"

        ErrorLog "/var/log/httpd/$name.ssl_error_log"
        CustomLog "/var/log/httpd/$name.ssl_access_log" combined

        # SSL/TLS 設定 (実際にはもっと多くの設定が必要)
        SSLEngine on
        SSLCertificateFile "/etc/pki/tls/certs/$name.crt"
        SSLCertificateKeyFile "/etc/pki/tls/private/$name.key"

        <Directory "/var/www/html/$docroot">
            Options Indexes FollowSymLinks
            AllowOverride All
            Require all granted
        </Directory>
    </VirtualHost>
</Macro>

マクロの使用 (httpd.conf または別の設定ファイル):

# マクロ定義ファイルをインクルード (必要に応じて)
IncludeOptional conf.d/vhosts_macro.conf

# サイトA の設定
# Use VHost [name] [domain] [docroot]
Use VHost example_site example.com example_site_root

# サイトB の設定
Use VHost blog_site blog.example.org blog_root

# サイトC の設定
Use VHost project_app app.example.net project_app_root

解説
Useディレクティブは、<Macro VHost ...>で定義されたマクロを呼び出します。各Use行で指定された3つの引数(example_site, example.com, example_site_rootなど)が、マクロ内の$name, $domain, $docrootにそれぞれ置換され、展開された<VirtualHost>ブロックがApacheによって処理されます。これにより、新しいサイトを追加する際に、Useディレクティブを1行追加するだけで済むようになります。

例2: 特定のディレクトリに対する共通のアクセス制限を適用する

複数の管理用ディレクトリやプライベートなコンテンツディレクトリに同じ認証やアクセス制限を適用する場合に便利です。

マクロ定義 (/etc/httpd/conf.d/access_macro.conf など):

# ProtectedDir マクロの定義
# $path: 保護対象のディレクトリパス
# $group: アクセスを許可するグループ名
<Macro ProtectedDir $path $group>
    <Directory "$path">
        AuthType Basic
        AuthName "Restricted Area"
        AuthUserFile "/etc/httpd/conf.d/.htpasswd"
        Require group $group
    </Directory>
</Macro>

# IPアドレスで制限するマクロの定義
# $path: 制限対象のディレクトリパス
# $ip_address: 許可するIPアドレスまたはCIDR
<Macro RestrictByIP $path $ip_address>
    <Directory "$path">
        Order deny,allow
        Deny from all
        Allow from $ip_address
    </Directory>
</Macro>

マクロの使用 (httpd.conf または別の設定ファイル):

IncludeOptional conf.d/access_macro.conf

# 管理者のみがアクセスできるディレクトリ
Use ProtectedDir "/var/www/html/admin" admin_users

# 開発者のみがアクセスできるディレクトリ
Use ProtectedDir "/var/www/html/dev" dev_users

# 特定のIPアドレスからのみアクセスできるディレクトリ
Use RestrictByIP "/var/www/html/private" "192.168.1.0/24"

# 複数のIPアドレスを許可する場合(引用符で囲む)
Use RestrictByIP "/var/www/html/public_api" "10.0.0.0/8 172.16.0.0/16"

解説
ProtectedDirマクロは、指定されたディレクトリに対して基本的な認証を適用します。RestrictByIPマクロは、特定のIPアドレス範囲からのアクセスのみを許可します。このように、共通のセキュリティポリシーをマクロ化し、複数の場所に簡単に適用できます。

例3: RewriteRule の共通パターンを抽象化する

Apacheのmod_rewriteは非常に強力ですが、複雑なルールは記述が冗長になりがちです。共通のRewriteルールパターンをマクロ化することで、可読性を向上させることができます。

マクロ定義 (/etc/httpd/conf.d/rewrite_macro.conf など):

# HTTP から HTTPS へのリダイレクトを強制するマクロ
# $domain: 強制するドメイン名
<Macro ForceHTTPS $domain>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteCond %{HTTP_HOST} ^(?:www\.)?$domain$ [NC]
    RewriteRule ^(.*)$ https://$domain$1 [R=301,L]
</Macro>

# 特定の旧URLから新URLへのリダイレクトマクロ
# $old_path: 旧パス
# $new_path: 新パス
<Macro RedirectOldURL $old_path $new_path>
    RewriteEngine On
    RewriteRule ^$old_path/?$ $new_path [R=301,L]
</Macro>

マクロの使用 (VirtualHost内、またはhttpd.confの適切な場所):

IncludeOptional conf.d/rewrite_macro.conf

<VirtualHost *:80>
    ServerName myapp.com
    ServerAlias www.myapp.com
    DocumentRoot "/var/www/html/myapp"

    # このサイトでHTTPSを強制
    Use ForceHTTPS myapp.com

    # 古いブログ記事のURLを新しいURLにリダイレクト
    Use RedirectOldURL /old-blog-post /new-article
    Use RedirectOldURL /legacy-page /modern-content
</VirtualHost>

解説
ForceHTTPSマクロは、HTTPリクエストをHTTPSに自動的にリダイレクトする一般的なパターンをカプセル化します。RedirectOldURLマクロは、サイトのリニューアルなどで多数の旧URLを新URLにリダイレクトする必要がある場合に、ルールを簡潔に記述できます。

重要なヒント

  • デバッグ: マクロが期待通りに動作しない場合は、apachectl configtestを実行して構文エラーがないか確認し、Apacheのエラーログを詳しくチェックしてください。場合によっては、マクロ内の内容を一時的に直接記述してテストし、展開後の形を確認するのも有効です。
  • パラメーターの命名: パラメーター名(例: $name)は、他の設定ディレクティブとの衝突を避けるために、$%@などの記号を先頭に付けることが推奨されます。また、${name}のようにブレースで囲むことで、置換の範囲を明確にできます。
  • 定義と使用の順序: マクロは、Useされるよりも前に定義されている必要があります。通常は、専用のマクロ定義ファイルをIncludeディレクティブで設定ファイルの冒頭に近い場所で読み込むのが良いプラクティスです。
  • モジュールのロード: mod_macroを使用する前に、LoadModule macro_module modules/mod_macro.soがApacheの設定ファイルで有効になっていることを確認してください。


mod_macroはApache内部でのマクロ展開を行いますが、より柔軟な設定管理や自動化を目指す場合、外部ツールや他のApache機能と組み合わせる方法が一般的です。

Include ディレクティブと変数 (Define) の組み合わせ

mod_macroと似たアプローチですが、よりシンプルなケースで利用できます。Apache 2.4以降で導入されたDefineディレクティブを使うことで、設定ファイル内で変数を定義し、それをIncludeするファイル内で利用できます。

特徴

  • 適用範囲
    グローバルな設定や、VirtualHostDirectoryなどのブロック全体をインクルードするのに適しています。
  • 柔軟性
    Includeするファイルの内容は完全に静的であるため、複雑な条件分岐などには向いていません。
  • シンプルさ
    mod_macroのようなマクロ構文を学習する必要がなく、より直感的に利用できます。

コード例

httpd.conf またはメインの設定ファイル

# 変数の定義
Define DOCROOT_BASE "/var/www/html"
Define LOG_BASE "/var/log/httpd"

# サイトAの設定をインクルード
Define SITENAME "example_site"
Define DOMAIN "example.com"
Define SITE_DIR "example_root"
IncludeOptional conf.d/vhost_template.conf

# サイトBの設定をインクルード
Define SITENAME "blog_site"
Define DOMAIN "blog.example.org"
Define SITE_DIR "blog_root"
IncludeOptional conf.d/vhost_template.conf

conf.d/vhost_template.conf (テンプレートファイル)

<VirtualHost *:80>
    ServerName ${DOMAIN}
    ServerAlias www.${DOMAIN}
    DocumentRoot "${DOCROOT_BASE}/${SITE_DIR}"
    ErrorLog "${LOG_BASE}/${SITENAME}.error_log"
    CustomLog "${LOG_BASE}/${SITENAME}.access_log" combined

    <Directory "${DOCROOT_BASE}/${SITE_DIR}">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

解説
Defineで変数を定義し、IncludeOptionalでテンプレートファイルを読み込みます。テンプレートファイル内では${VARIABLE_NAME}形式で変数を使用します。これはmod_macroが導入される前から存在した概念で、Apacheの基本的な機能の一部です。

動的な仮想ホスト (mod_vhost_alias)

多数の類似した仮想ホストを、個別に設定ファイルを作成せずに動的に生成したい場合に非常に強力です。

特徴

  • 制限
    設定の柔軟性はmod_macroやテンプレートエンジンに比べて低く、全てのディレクティブを動的にすることはできません。
  • 自動化
    ドキュメントルートやログファイルのパスをドメイン名に基づいて自動的に決定できます。
  • 大規模環境向け
    数十、数百といった仮想ホストを管理するのに適しています。

コード例

# mod_vhost_alias モジュールがロードされていることを確認
# LoadModule vhost_alias_module modules/mod_vhost_alias.so

# ドキュメントルートのベースディレクトリ
# 例えば、example.com は /var/www/vhosts/example.com にマッピング
VirtualDocumentRoot "/var/www/vhosts/%0"
VirtualDocumentRootUserDir disabled

# エラーログとアクセスログもドメイン名に基づいて生成
ErrorLog "/var/log/httpd/%0.error_log"
CustomLog "/var/log/httpd/%0.access_log" combined

<Directory "/var/www/vhosts/*">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

解説
VirtualDocumentRoot %0は、リクエストされたホスト名全体(例: www.example.com)をドキュメントルートのパスに利用します。これにより、/var/www/vhosts/www.example.comといったディレクトリを自動的に参照するようになります。%0以外にも、ドメインの各部分(%1, %2など)を使用することも可能です。

外部のテンプレートエンジン / 設定管理ツール

最も柔軟で、大規模なインフラストラクチャやCI/CDパイプラインで利用される方法です。Apacheの設定ファイル自体をテンプレートとして扱い、RubyのERB、PythonのJinja2、Goのtext/templateなど、汎用的なテンプレートエンジンを用いて生成します。

ツール例

  • 専用のスクリプト
    PythonやPerlなどのスクリプト言語で、独自のロジックに基づいて設定ファイルを生成するスクリプトを作成します。
  • Make, Bashスクリプト
    シンプルなケースでは、sedawkenvsubstなどのコマンドラインツールとシェルスクリプトを組み合わせて設定ファイルを生成することも可能です。
  • Ansible, Puppet, Chef, SaltStack
    これらは構成管理ツールであり、Apacheの設定ファイルをテンプレートとして管理し、複数のサーバーにデプロイするのに最適です。

特徴

  • 複雑性の増加
    外部ツールを導入する学習コストや、ツールの管理・運用が必要になります。
  • バージョン管理
    テンプレート自体をバージョン管理システムで管理することで、設定の変更履歴を追跡しやすくなります。
  • 集中管理
    一元化されたテンプレートとデータから複数のサーバーの設定を生成・デプロイできます。
  • 最大限の柔軟性
    プログラミング言語の全ての機能(条件分岐、ループ、外部データソースからの取得など)を組み合わせて設定を生成できます。

コード例 (Ansible + Jinja2 テンプレートの概念)

templates/httpd.conf.j2 (Jinja2 テンプレートファイル)

# This is the main Apache HTTP server configuration file
# Managed by Ansible - DO NOT EDIT MANUALLY

ServerRoot "/etc/httpd"
Listen {{ apache_http_port }}

Include conf.modules.d/*.conf
User {{ apache_user }}
Group {{ apache_group }}

# ... 他のグローバル設定 ...

{% for site in sites %}
<VirtualHost *:{{ apache_http_port }}>
    ServerName {{ site.domain }}
    ServerAlias www.{{ site.domain }}
    DocumentRoot "{{ apache_docroot_base }}/{{ site.docroot_dir }}"
    ErrorLog "{{ apache_log_base }}/{{ site.name }}.error_log"
    CustomLog "{{ apache_log_base }}/{{ site.name }}.access_log" combined

    <Directory "{{ apache_docroot_base }}/{{ site.docroot_dir }}">
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    {% if site.ssl_enabled %}
    # HTTPS 設定 (簡易版)
    SSLEngine on
    SSLCertificateFile "/etc/pki/tls/certs/{{ site.name }}.crt"
    SSLCertificateKeyFile "/etc/pki/tls/private/{{ site.name }}.key"
    {% endif %}

</VirtualHost>
{% endfor %}

vars/main.yml (Ansible 変数ファイル)

apache_http_port: 80
apache_user: apache
apache_group: apache
apache_docroot_base: /var/www/html
apache_log_base: /var/log/httpd

sites:
  - name: example_site
    domain: example.com
    docroot_dir: example_site_root
    ssl_enabled: true
  - name: blog_site
    domain: blog.example.org
    docroot_dir: blog_root
    ssl_enabled: false
  - name: project_app
    domain: app.example.net
    docroot_dir: project_app_root
    ssl_enabled: true

解説
Ansibleがvars/main.ymlで定義されたsitesリストをループ処理し、httpd.conf.j2テンプレートをレンダリングして最終的なhttpd.confファイルを生成します。これにより、Apacheの設定ファイル自体は静的なファイルでありながら、その内容は外部のデータとロジックによって動的に生成されるため、非常に柔軟な管理が可能になります。

代替方法利点欠点
Include + Definemod_macroよりシンプル、Apache標準機能条件分岐や繰り返しができない、設定項目が多いと冗長になりやすい
mod_vhost_alias多数の仮想ホストの動的な自動生成、手動設定の削減設定の柔軟性が低い、特定のパターンにしか適用できない
外部のテンプレートエンジン最大限の柔軟性、プログラミングロジックの適用、一元的な設定管理、バージョン管理との親和性外部ツールの学習と運用コスト、Apache起動前にファイル生成が必要