[入門]AnsibleでWordPressの構築をIaC化する

はじめに

はじめまして!TechBullコミュニティメンバーのいわき(@IwaTech1222)と申します!現在、安達さん(@adachin0817)のメンティーとして課題を進めており、学んだ内容をアウトプットしたいため、本記事をもって初ブログとさせていただきます。今回は、タイトルにある通り、AnsibleでWordPressの構築をインフラコード化するまでの流れを書いてみました。

自己紹介

初ブログということで簡単に自己紹介させていただきます。1999年生まれで今年でエンジニア歴4年目のインフラエンジニアです。ヘルプデスク、オンプレミスを1年ずつ経験しており、今年からAWSでデータ分析基盤の設計構築の案件に参画しています。TechBullに参加するまでは、AWSの案件に参画できるように主に資格の勉強をしていました。実際参画できて、次のステップとしてWeb系に行きたいということもあり、何か手を動かした方が思っていた時に、ちょうどエンジニア向けYouTubeメディアのTECH WORLDさん(@tech_world18))で安達さんのことを知り、TechBullに参加させていただきました。

Ansibleについて

サーバー構成管理やアプリケーションのデプロイを自動化するツールです。エージェントレスで動作し、対象サーバーには SSH 接続するだけで操作が可能です。Pythonで実装されており、シンプルな構文と豊富なモジュールが特徴です。構成の再現性・保守性を高めるために、IaCを実現する代表的なツールの一つです。

開発環境

  • macOS 15.3
  • Multipass 1.15.1+mac
  • Visual Studio Code 1.99
  • Ubuntu 24.04
  • Ansible 2.18.5

本環境のディレクトリ構成

Ansibleのインストール

コントロールノードのMacにHomebrewでAnsibleをインストールする

Ansible使用前の事前準備

Ansibleはターゲットノードに対して、SSHで接続を行います。そのため、事前に手動で以下2点を設定します。

  1. ターゲットノードへ接続するためのユーザ作成
  2. SSH公開鍵認証の設定

まず、Multipassで立ててターゲットノードにログイン

1. ターゲットノードへ接続するためのユーザ作成

  • ユーザの作成

新規ユーザmentaを作成し、作成されているか確認をする。

  • /etc/sudoersの設定
    ユーザmentaでパスワードなしで全てのコマンドを実行できる設定をする。
    ※文字化け・画面崩れ防止のため、設定前にターミナルの種類をxtermに設定する。

2. SSH公開鍵認証の設定

  • ターミナルに戻り、ssh認証鍵を作成する

  • 以下のような出力がされるので、鍵ファイル名をwp-server、パスワードを設定せずにエンターを押下する。

接続先情報をconfigに設定

  • リモートホストのssh鍵設定と公開鍵配置

リモートホスト側に後で先ほど作成したターミナル側の公開鍵の設定をするので、中身を控えておく。

  • リモートホストにSSH接続し、sshd_configの設定

  • リモートホストにターミナル側の公開鍵配置

ユーザmentaにスイッチし、ターミナル環境で作成した公開鍵を配置する。
※スイッチ前にユーザmentaのホームディレクトリが作成されていないため、作成し、所有者・所有グループを設定する。

上述の設定を反映させるため、sshdサービスを再起動する。

  • リモートホストへssh接続

ターミナル環境に戻り、sshのconfigに設定したホスト名でリモートホストにSSH接続できることを確認する。

AnsibleでWordpress環境構築の自動化

上述より、Ansibleを利用できる状態ができました。いよいよAnsibleでのWordpressの環境構築に入ります。
その前にAnsibleを利用する時に出てくるキーワードを以下に整理いたします。

  • コントロールノード
    • 処理の指示を出すノード(本環境ではMac)。
  • ターゲットノード
    • 処理の対象となるノード(本環境ではMultipassで作成した仮想サーバ(WordPress環境))。
  • インベントリ
    • ターゲットノードをリストして記載するファイル。
  • プレイブック
    • ターゲットノード側で実行したい処理の流れを記載するファイル。
  • モジュール
    • コマンドラインやプレイブックから呼び出せる処理の単位、プレイブック内でモジュールを指定することで、処理をターゲットノードで実行可能。
  • タスク
    • ターゲットノードに実行させる1つ1つの具体的な操作のこと。プレイブック内で上から順に実行され、冪等性(べきとうせい)がある。
      ※冪等性:同じ処理を何回実行しても、結果が変わらないこと
  • プレイ
    • ターゲットノードグループごとに行うタスクのまとまりのこと。
  • ロール
    • プレイブックの記載を分割するためのコンポーネント。1つのプレイブックで多くのタスクを記載すると管理が難しく、可読性が悪くなるため、ロールでプレイブック内のタスクを分割できる。
ansible.cfg(設定ファイル)の作成

Anisbleの設定ファイル”ansible.cfg”をansibleディレクトリ直下に作成・設定します。設定内容は以下になります。

  • [defaults]
    • Ansibleのデフォルト設定のセクション。このセクションに記載された内容は全てのプレイブックのデフォルトで適用される。
  • become = true
    • 全タスクでsudoを使う設定。
  • interpreter_python  = /usr/bin/python3.12

    • ターゲットノード上で使用するPythonインタープリタ。AnsibleではターゲットノードでPythonで書かれたモジュールを実行するため、この設定が必要。

  • inventory = ~/git/menta/ansible/inventory.ini

    • ターゲットノードを記載した一覧のインベントリファイルの場所を指定。

  • private_key_file = ~/.ssh/wp-server

    • SSH接続に使う秘密鍵の指定。

  • retry_files_enabled = False

    • 再試行ファイル(.retryファイル)が作成されないための設定。プレイブックの実行に失敗した場合、カレントディレクトリに自動的に再試行ファイルが作成されるが、カレントディレクトリが散らかってしまうので、Falseに設定。

  • log_path = ~/.ansible/ansible.log

    • Ansible実行時のログファイルの保存先を指定

  • host_key_checking = False

    • SSHのホストキー確認を無効化する。

  • gathering = smart

    • ファクト収集(setupモジュールによるターゲット情報取得)のモードを指定。smartはデフォルトで、必要な時だけファクトを収集し、可能ならキャッシュを使うモード。

inventory.iniの作成

ターゲットノードを記載するinventort.iniを作成します。設定内容は以下になります。

wp_serversというホストグループ名を指定します。プレイブック内でこのグループを指定するとグループに属しているターゲットノードに対してタスクが実行されます。その下にSSH接続するターゲットノードのホスト名とユーザ名を指定します。

playbook.yml(プレイブック)の作成

WordPress環境を構築するためのプレイブックを作成します。プレイブックはYAML形式で記述します。ターゲットノードに対して実行するタスクを分割したロールについては後述いたします。

hostsでインベントリファイルに記載されたホストグループを指定し、そのグループに属するホストに対してこちらのプレイブックに記載した内容を実行します。rolesで各ターゲットノードごとに実行するロールを指定します。

各ロールの作成

ロールを利用するには、Ansibleが認識できるディレクトリ構造を作成し、ファイルを配置する必要があります。
ディレクトリ配下のファイルは固定で”main.yml”が読み込まれる仕様になっています。
以下にAnsibleが認識できるディレクトリの種類をまとめます。

  • defaultディレクトリ
    • 変数の初期値を定義したYAMLファイルを配置するディレクトリです。例としては、ミドルウェアやOSの設定テンプレートに使用するデフォルト値などです。後述のvarsディレクトリ内に定義する変数との違いは、優先順位です。defaultディレクトリで定義した変数は一番優先度が低いため、varsディレクトリで同じ変数を定義していた場合、varsディレクトリの方で宣言した値で上書きされるので注意が必要です。
  • filesディレクトリ
    • copyモジュールなどのファイル操作関連のモジュールでターゲットノードに転送するファイルを配置するディレクトリです。このディレクトリにはmain.ymlを作成する必要がありません。
  • handlersディレクトリ
    • tasksディレクトリのmain.yml内でnotifyディレクティブで定義されたタスク名に紐づいたタスク名を呼び出すことができます。
  • tasksディレクトリ
    • このディレクトリ配下にmain.ymlを配置し、ターゲットノードに対するタスクを定義します。
  • templatesディレクトリ
    • templateモジュールで利用する、テンプレートファイルを配置するディレクトリです。filesディレクトリと同様にmain.ymlを作成する必要はなく、Jinja2形式のテンプレートを配置します。filesディレクトリとの使い分けとしては、templatesディレクトリ配下に作成したファイル内でvarsディレクトリなどで定義した変数を参照することができますが、filesディレクトリに配置したファイル内では変数の参照ができないので、変数を参照させたい場合に有効です。
usersロール

usersロールで手動で作成したmentaユーザ、グループ、SSH鍵認証の設定をします。usersロールのディレクトリ構成は以下になります。

各ディレクトリ配下のファイルは以下になります。

  • roles/users/tasks/main.yml

ユーザの作成、公開鍵の配置、sudoersの配置をしています。ユーザ作成のタスクでupdate_passwordをon_createに設定することで作成済みのユーザに対してはパスワードを設定しないため、事前に手動で作成したユーザのパスワードとの差分をなくすことができます。

loopの中で利用する変数はリスト形式である必要があります。後述するvarsディレクトリ配下のmain.ymlで定義した変数はマッピング形式であるため、dict2itemsフィルタを使用することでマッピング形式で定義した変数をリスト形式に変換して利用します。

  • roles/users/templates/menta_sudoers.j2
    varsディレクトリ配下のman.ymlで定義したユーザに対してパスワードなしでsudoを実行できる権限を付与します。

  • roles/users/vars/main.yml

こちらで作成するユーザの各パラメータを設定しています。パスワードについては、lookupで環境変数を読み込む形にしています。

nginxロール

Nginxのインストールと設定ファイルの作成をします。nginxロールのディレクトリ構成は以下です。

各ディレクトリ配下のファイルは以下になります。

  • roles/nginx/tasks/main.yml

上記のタスクでは、Nginxのインストールと設定ファイル、https化するための証明書と秘密鍵の配置をしております。https化するにはmkcertをローカルにインストール後、証明書と秘密鍵を作成する流れになります。後述するVirtual Hostの設定ファイル内でこれらの証明書と秘密鍵のパラメータを設定します。

  • roles/nginx/templates/wp.techbull.cloud.conf.j2

上記のVirtual Hostの設定ファイルにてWordPressのサイトをHTTPS化しています。80番ポートへのアクセス時はHTTPでのアクセスはHTTPSへリダイレクトするようにしています。443番ポートの設定箇所では、証明書と秘密鍵の設定、マジック変数”inventory_hostname”を使用してドキュメントルートやログのパスを指定しております。

マジック変数とはAnsibleがあらかじめ定義している変数になります。inventory_hostnameはinventory.iniに記載したホスト名を参照しています。マジック変数を使用することで、複数のサーバを管理しやすく、コードの可読性が上がります。PHPリクエストは php8.3-fpmに対して、UNIXドメインソケット経由でアクセスします。

  • roles/nginx/handlers/main.yml

先に記載したタスク内でnotifyでNginxを再起動する設定をしています。notifyはあるタスクで変更があった場合だけ、後で特定の処理(ハンドラー)を実行するという仕組みで、タスク内でVirtual Hostの設定ファイルに変更が入った場合をトリガーに上記のハンドラーとしてNginxの再起動を実行するようにしております。

  • roles/nginx/files/nginx.conf

上記はNginx全体の挙動について定義した設定ファイルになります。細かいパラメータの解説は割愛させていただきますが、ファイル内では先に記述したVirtual Hostの設定ファイルを異なり、変数を参照しておりません。そのため、filesディレクトリに配置して、タスク内でcopyモジュールでターゲットノードにコピーをしています。

phpロール

PHPのインストールと設定ファイルの作成をします。phpロールのディレクトリ構成は以下です。

各ディレクトリ配下のファイルは以下になります。

  • roles/php/tasks/main.yml

上記タスクでは、PHP8.3、PHP8.3-FPMのインストールと関連するモジュールのインストールとPHP-FPMの設定ファイル www.conf を配置をしております。notifyにより、www.confに変更があった場合はハンドラによってPHP-FPMを再起動をします。

  • roles/php/handlers/main.yml

先に書いた通り、www.confに変更があった場合、PHP8.3-FPMを再起動するハンドラの設定になります。

  • roles/php/files/www.conf

詳細な解説は割愛させていただきますが、PHPの実行ユーザ、グループをNginxの実行ユーザ(先に記述したNginxの設定ファイルnginx.conf内のuserで指定したユーザ)と一致させる必要があります。また、NginxとPHPはUNIXドメインソケット経由で接続を行うため、上記www.conf内のlistenとVirtual Hostの設定ファイル内のfastcgi_passの値についても一致させる必要があります。

mysqlロール

MySQLのインストールと設定ファイルの作成をします。mysqlロールのディレクトリ構成は以下です。

各ディレクトリ配下のファイルは以下になります。

  • roles/mysql/tasks/main.yml

上記タスクで、MySQL8.0と関連モジュールのインストール、各種設定ファイルの配置、Wordpress用のユーザとDB作成、そのユーザに対する権限を設定しています。また、rootユーザーの認証方式をmysql_native_passwordをしています。MySQL8.0以降では、デフォルトの認証方式が従来のmysql_native_passwordからcaching_sha2_passwordに変更されたようです。

WordPressではcaching_sha2_passwordに対応していない場合があるみたいなので、WordPress環境では互換性を保つためにrootユーザーの認証プラグインをmysql_native_password に明示的に変更することが推奨されているそうです。ちなみにmysql_native_passwordは、MySQL 5.x 系までの標準的な認証方式のようで、クライアントがパスワードをハッシュ化してサーバーに送信し、サーバー側でも同じハッシュを使って認証を行う仕組みのようです。

  • roles/mysql/templates/root_my.cnf.j2

MySQLクライアント用の設定ファイルになります。この設定ファイルがあることで、コマンド実行時に自動でこの認証情報が使われます。パスワードは環境変数を定義した.env.ymlに記載してプレイブックを実行したときに読み込まれるようにします。また、こちらのファイルはタスク内でパーミッションを0600に設定する必要があります(そうしないと、MySQLはこのファイルを無視するため)。

  • roles/mysql/handlers/main.yml

タスク内でmysqld_custom.cnfに変更があった場合、 MySQLを再起動するハンドラの設定になります。

  • roles/mysql/files/mysqld_custom.cnf

MySQLクライアントとサーバの文字コードとログ、ソケットファイルなどを指定する カスタム設定ファイルになります。

  • roles/mysql/vars/main.yml

WordpressDB用のユーザ作成に必要な変数を定義しています。パスワードについてはlookupで.env.yml内に定義したパスワードを参照しています。

wordpressロール

WordPressのインストールと設定ファイルの作成をします。wordpressロールのディレクトリ構成は以下です。

各ディレクトリ配下のファイルは以下になります。

  • roles/wordpress/tasks/main.yml

上記タスクでWordpressのダウンロードと展開、展開後、Virtual Hostの設定ファイルで設定したドキュメントルートへの展開したファイルの同期、各ファイルに対して、所有者・パーミッションを設定しています。こちらのタスク内でもドキュメントルートを指定する際は、マジック変数”inventory_hostname”を使用しています。Wordpressの設定ファイルのwp-config.phpに変更がある場合、ハンドラーでNginx、PHP-FPM、MySQLを再起動をするようにしています。

  • roles/wordpress/templates/wp-config.php.j2

詳細は割愛させていただきますが、こちらのWordpressの設定ファイルでは、データベースへの接続情報、テーブルプレフィックス、デバッグモード、Wordpressの起動設定を設定しております。

  • roles/wordpress/handlers/main.yml

先にも述べた通り、タスク内でwp-config.phpに変更があった場合のハンドラとしてNginx、PHP-FPM、MySQLを再起動します。

各ロールの作成まで完了しましたら、inventory.iniとplaybook.ymlが格納されているディレクトリへ移動し、プレイブックを実行して、Wordpress環境を自動構築します。

実行完了後、https://wp.techbull.cloudにアクセスします。初回のユーザやパスワードを設定し、ダッシュボードが表示されることを確認して完了になります。

まとめ

本記事では、WordPress環境の構築をAnsibleで自動化してみました。プレイブックを実行すれば、タスクの内容とボリュームにもよりますが、数十秒で環境構築できる点で、短時間で効率的に構築ができることがわかりました。

またコードの可読性をあげられるように他のAnsible変数やモジュールなどがたくさんあるので、これらを使用して環境構築することで、よりAnsibleへの理解を深めていきたいと思います。ここまで読んでいただきありがとうございました。

(参考)
書籍:https://book.impress.co.jp/books/1122101189

告知

6/4にTechBull主催のLT会があります!僕も参加しますので、ぜひ皆さん参加お待ちしております!

2025/6/4 TechBull LT&交流会 #2 がDatadogオフィスで開催されます!

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール