オンプレミスのWordPressをAzureのPaaS環境へ移行(クラウドシフト)
この記事では、オンプレミスのWordPressサーバをMicrosoft AzureのWebAppにクラウドシフトした際のつまずきや苦労したポイントを紹介します。
プロジェクトの目的
もともとオンプレミス環境に公開Webサーバがあり、LinuxサーバにWordPressとMySQLをインストールして運用していました。環境をクラウドへ移行し、本来業務にもっと注力するという目的から今回のプロジェクトを開始しました。Azureは他の目的で利用しており、AWSやGCP等の比較は行っていません。またコストの観点から、極力VMは採用せず、クラウドリフトよりもクラウドシフト(PaaS/SaaSを採用)を心がけました。
オンプレミスの構成(移行前)
- ネットワーク: Juniper SRX
-
サーバ:
- OS:Ubuntu 22.04
- ミドルウェア:PHP version 5
- Webアプリ:WordPress
- データベース:MariaDB 10.6.18
- 構成:サンドボックス1台とプロダクション2台
Azureの構成(移行後)
-
共通部分
- Virtual network gateway
- Application gateway
- Key vault
-
サンドボックス
- App Service
- Azure Database for MySQL flexible server
- Storage account
- 冗長構成なし
-
プロダクション
- App Service
- Azure Database for MySQL flexible server
- Storage account
- 冗長構成あり
-
その他
- バックアップ(ARMテンプレート、アクセスログ、Webコンテンツ、DBデータ)
- CIS Benchmarkを適用
コスト比較
オンプレミスとAzureでの運用コストを比較すると、Azure環境ではリソースの柔軟なスケーリングが可能となり、コスト効率が向上しました。特に、ピーク時にのみリソースを拡張することで、無駄な費用を削減できるようになりました。詳細なコスト分析は、近日中に更新予定です。
リソースごとの特徴や苦労した点
-
Virtual network gateway
-
特徴:
オンプレミスのSRXとIPsecトンネルを構成し、eBGPを使って経路交換をしています。インターネットとの境界はオンプレミス側に設けているため、Firewallの機能は移行していません。Azureの内部では全ての通信をプライベートIPで実現したかったため、デフォルトルートをSRXからAzureに向けて広報しています -
苦労した点:
- IPsecは双方のパラメータを一致させる必要がありますが、Azure上の設定名とSRX上の設定名が異なり、合わせるのに苦労しました
- Azure PortalからSRX用の設定をダウンロードできますが、そのままでは動作しませんでした
- デフォルトルートをオンプレミス側から受信している為、全てのリソースのプライベートエンドポイントを設定する必要がありました。一方、AzureのリソースはPublic IPで通信するのがデフォルトです。これによりトラブルシューティングの際、リソースの問題なのか?ネットワークの問題なのか?に悩むシーンが多かったです。
-
特徴:
-
Application gateway
-
特徴:
当初は利用するつもりがありませんでしたが、TLS/SSLのパラメータを調整するため、プロジェクトの途中で追加しました。具体的には、HTTPSのレスポンスヘッダーを書き換えるためですが、これはQualysとVeracodeの脆弱性スキャンにパスするためです。 -
苦労した点:
- 設定箇所が多いにもかかわらず、動作が遅く(設定を適用してからAzure側での処理が完了するまで約11分かかる)、初めて扱うリソースで挙動を確認するため、設定と検証を繰り返す必要があり非常にストレスフルかつ時間を要しました
- TLSのエンドポイントについて、設定のパターンが多く、ベストプラクティスを知るのに苦労しました
- 最終的に「TLSで受けてTLSで流す(End to end TLS)」の構成にしました
- カスタムドメインを利用する際の制限事項に気付くのにかなりの時間を要しました。(クライアントから要求されるFQDNと証明書のCNがマッチしている必要があります。)
- Webの表示速度が非常に遅く、原因を探るのに苦労しました(最終的にはSession Affinityを追加して改善しました)
- バックエンド(今回はWebApp)のレスポンスヘッダーのRewriteは可能ですが、AppGW自身が生成するレスポンス(404や502等)のレスポンスヘッダーはRewriteできません
- 例えば、バックエンドのnginxのVersionは秘匿できますが、AppGwのVersionは秘匿できません
-
特徴:
-
Key vault
-
特徴:
こちらも当初利用するつもりがありませんでしたが、以下を格納するためにプロジェクトの途中で追加しました- Storage accountを暗号化するためのCustomer-managed key
- SSH公開鍵
- TLS証明書
-
苦労した点:
- Key vaultにLet's encryptで発行したTLS証明書を格納する際、フォーマットを変換する必要がありました。(.pemから.pfxへ変換)
bash: 変換コマンドopenssl pkcs12 -export -out fullchain.pfx -inkey privkey.pem -in fullchain.pem
- TLS証明書にAppGWからアクセスする際の権限(IAM)をPortalで設定できませんでした
- TLS証明書をAppGWに取り込む際、Portalで実施できませんでした
Powershell: 証明書をAppGwにインポートするコマンド$certname = "cert name" # Key Vault上の証明書名 $appgwname = "appgw name" # AppGWのリソース名 $rgname = "resouce group name" # リソースグループ名 $vaultname = "kv-cmn-kv-prd-eu-1" # Key Vaultのリソース名 $appgw = Get-AzApplicationGateway -Name $appgwname -ResourceGroupName $rgname Set-AzApplicationGatewayIdentity -ApplicationGateway $appgw -UserAssignedIdentityId "/subscriptions/[Subscription ID]/resourceGroups/[Resource Group Name]/providers/Microsoft.ManagedIdentity/userAssignedIdentities/[Managed Identity]" $secret = Get-AzKeyVaultSecret -VaultName $vaultname -Name $certname $secretId = $secret.Id.Replace($secret.Version, "") Add-AzApplicationGatewaySslCertificate -KeyVaultSecretId $secretId - ApplicationGateway $appgw -Name $secret.Name Set-AzApplicationGateway -ApplicationGateway $appgw
-
-
App Service
-
特徴:
全てプライベートIPで運用。 -
苦労した点:
- パブリックIPを無効化できず、Vnetとの紐付けに苦労。
- AppGWでヘッダー調整が必要。
-
特徴:
-
Azure Database for MySQL flexible server
-
特徴:
WordPressのバックエンドに利用。MariaDBからMySQLへの移行。 -
苦労した点:
- テーブル名の小文字変換が必要。
- UNIQUE KEYをPRIMARY KEYに置換。
-
特徴:
-
Storage account
(近日更新予定) -
バックアップ
(近日更新予定) -
CIS Benchmark
(近日更新予定)
今後取り組みたいこと
-
証明書の自動更新:
- 手動更新を自動化するためのApp Service Managed Certificateの活用を検討中。
- 構成見直しやAzureの新機能に期待。
-
バックアップタスクのAzure Functions化:
- オンプレのシェルスクリプトからの移行を目指し、Azure Functionsの導入を検討。
最後に
App ServiceをプライベートIP環境のみで運用するハードルは依然高いですが、Microsoftの設計思想に合わせた構成を心がけています。Azureの学習を重ね、新しい機能を活用して理想に近づけたいと考えています。