今回は Azure の App Service と Azure DB for MySQL フレキシブル サーバーで WordPress を実行する環境を整備したのでまとめてみます。利用する SKU にもよりますが、関連するコンポーネントへのアクセスをセキュアにすることもできるので、なるべくセキュリティも考慮した構成にしてみます。
全体構成
今回利用するコンポーネントは次のとおりです。
- App Service (B プラン以上)
- Azure Database for MySQL フレキシブル サーバー
- 仮想ネットワーク
- Key Vault
- Storage Account

App Service
WordPress をホストするための App Service です。WordPress を実行するランタイムの PHP は現行で 7.4 と 8 系がサポートされていますが、2022 年 11 月 28 日に 7.4 のサポートが終了します。また、次期 PHP 8 系は Windows でサポートされないことが明示されているため、ランタイムの実行 OS 環境には Linux を選択する必要があります。
マイクロソフト、スクリプト言語「PHP 8.0」以降の正式サポートを中止 – ZDNet Japan
従来の Windows OS ベース App Service では MySQL in App という機能でローカル データベースを実行することができましたが、この機能は Linux に対応していないため、Linux ベースの場合は別途データベースを用意しなければいけません。
App Service は共用インフラでホストする無料プランもありますが、それだとスペックが心もとないので上位のプラン (Basic) を採用しています。また、ステージング スロットは Basic では利用できません。これも実際の運用環境には物足りないレベルですが、検証用途や小規模な環境であれば十分なリソースを確保できます。
Basic 以上の場合はホスト OS が占有となるため、他の利用者の影響も受けにくいです。また、(www のホスト名のみですが) マネージド証明書が利用できるため、証明書や SSL の運用も比較的簡単に済ませることができます。上位プランへの変更は簡単なので、スケーリングにも対応しやすいです。
Azure Database for MySQL フレキシブル サーバー
Azure で MySQL データベースを利用できる PaaS です。従来は最小の利用料でも単一のサーバー分 (ほぼ VM 一台分の料金) がかかってしまっていたため、PostgreSQL や MySQL は利用に躊躇したのですが、フレキシブル サーバーが提供され始めたので、小規模構成でも利用できる選択肢が増えました。
フレキシブル サーバーは一番小規模な構成でも仮想ネットワーク統合できるため、セキュリティを意識した環境でも利用を検討できます。
仮想ネットワーク
コンポーネント間の通信をプライベートにするため、経由用の仮想ネットワークを用意します。プライベート アクセス用の機能としては、プライベート エンドポイント、サービス エンドポイント、仮想ネットワーク統合があります。それぞれの機能で使い所が違うため構成するときは注意が必要ですが、PaaS でもプライベートなアクセスを実現できるので使いこなせればかなり役に立ちます。
App Service の仮想ネットワーク統合は無料のプランではできないため、上位のプランを選択する必要があります。
Key Vault
シークレットや接続文字列などを格納しておくための Key Vault です。基本的には App Service の起動時に読み込むだけなので頻繁にアクセスはしませんが、こちらもサービス エンドポイントでアクセス元をプライベートに制限することができます。
ストレージ アカウント
これは必須ではありませんが、WordPress のプラグインで画像などのメディア ファイルを格納する先として利用します。このストレージはパブリック アクセスを無効にすると、利用者がアクセスできなくなるため制限はかけていません。
Windows Azure Storage for WordPress – WordPress プラグイン | WordPress.org 日本語
プライベート DNS ゾーン
仮想ネットワーク統合した MySQL フレキシブル サーバーの名前解決をするために利用する DNS ゾーンです。仮想ネットワーク統合した場合はパブリックな名前解決ができなくなるので、このリソースを利用できるよう構成する必要があります。
ソースコード
今回は ARM テンプレートを作成して次のリポジトリで公開しています。
GitHub – sny0421/azure-webapp-linux-wordpress
また、WordPress のソースも wp-config.php に少し手を加えているため、次のリポジトリで公開しています。データベースの情報などを環境変数から読み込むように設定しています。
GitHub – sny0421/azure-webapp-linux-wordpress-code
デプロイに成功すると、次のようなリソースが作成されます。

少しハマったところ
Key Vault のアクセス制限
Key Vault はパブリックなアクセスを制限するため、サービス エンドポイントで接続元の仮想ネットワークを指定しています。Bicep ファイルから抜粋しますが、ネットワーク ACL の他にパブリック ネットワーク アクセスを指定するプロパティがあります。インターネットからのアクセスを制限したいので、publicNetworkAccess は Disabled にしたいところですが、今回は接続元が仮想ネットワーク統合した App Service でサービス エンドポイントを経由した接続になるので、パブリックなアクセスは許可しておく必要があります。プライベート エンドポイントの場合はこの限りではありませんが、同じような構成でも設定に注意がいるところです。
networkAcls: {
bypass: 'AzureServices'
defaultAction: 'Deny'
ipRules: []
virtualNetworkRules: [
{
id: virtual_network::subnet_webapp.id
ignoreMissingVnetServiceEndpoint: false
}
]
}
publicNetworkAccess: 'Enabled'
Key Vault からシークレットの読み出し
App Service で環境変数として Key Vault に保存したシークレットを読み込みます。これも抜粋ですが、AppSettings の設定に環境変数を指定できます。Key Vault の名前とシークレットを指定することでシークレットの呼び出しを行えるようにしています。
指定のフォーマットは次のとおりです。もしくはシークレットの URI を指定することでも可能です。
@Microsoft.KeyVault(VaultName=${Key Vault 名};SecretName=${シークレット名})
Bicep の記述は次のとおりです。
resource site_config_appsettings 'config' = {
name: 'appsettings'
properties: {
SC_MYSQL: '@Microsoft.KeyVault(VaultName=${key_vault_name};SecretName=${key_vault::key_vault_secret_sc_mysql.name})'
DATABASE_HOST: '${mysql_flexible_server_name}.mysql.database.azure.com'
DATABASE_NAME: db_name
DATABASE_USERNAME: db_username
DATABASE_PASSWORD: '@Microsoft.KeyVault(VaultName=${key_vault_name};SecretName=${key_vault::key_vault_secret_db_password.name})'
}
}
また、App Service が Key Vault にアクセスできるよう、マネージド ID でアクセス権も付与しておく必要があります。App Service のリソース宣言内で identity プロパティ配下に SystemAssigned を指定しておきます。
resource app_service_site 'Microsoft.Web/sites@2021-03-01' = {
name: app_service_site_name
location: region
kind: 'app,linux'
identity: {
type: 'SystemAssigned'
}
...
}
Key Vault 側の accessPolicies 配下で、objectId に App Service のオブジェクト ID を指定すれば OK です。
accessPolicies: [
{
tenantId: subscription().tenantId
objectId: app_service_site.identity.principalId
permissions: {
secrets: [
'get'
]
}
}
]
まとめ
今回は App Service で Linux ベースの WordPress を実行する構成をテンプレート化しました。若干動きが安定しない部分があるため、気が向いたら改良したいと思います。
また、今回の構成だと最小でも月 3000 円程度の課金が発生します。従来は無料でも実行できましたが、仮想ネットワーク統合をしない無料プランの場合でも 1500 円弱になります。
Linux ベースの機能拡張を願うのも一つの手ですが、コンテナーでの構成なども考えた方が良いかもしれません。もちろんコンテナー化する場合はコンテナーの実行環境を管理する手間も考える必要があるので、それらを考慮して App Service でのスケーリングなどで済ますのも十分有効な選択肢です。
コメント