Azure Front DoorはCDN(Contents Delivery Network)を提供するマネージドサービスです。Azure Front Doorでルーティングエンジンを使用すると、URL, 送信元のデバイス種別, 地域に応じて、任意のHTTPヘッダーを付与したりキャッシュ有無を変更したり柔軟な制御ができます。
前提
公式ドキュメント
参考になる公式ドキュメントを以下に示します。
事前設定
「Azure Front Door 基本操作」で紹介したFront Doorが設定済の状態とします。
変数DNS_NAMEと変数FRONT_DOOR_NAMEは重複しない一位な値に変更ください。
DNS_NAME="gokatei01"
FRONT_DOOR_NAME="fr-gokatei01"
az group create --name MyResourceGroup --location japaneast
az network vnet create \
--resource-group MyResourceGroup \
--name MyVnet \
--address-prefix 172.16.0.0/16
az network vnet subnet create \
--resource-group MyResourceGroup \
--name MySubnet \
--vnet-name MyVnet \
--address-prefixes 172.16.1.0/24
az network public-ip create \
--resource-group MyResourceGroup \
--name MyPublicIp \
--dns-name ${DNS_NAME} \
--sku Standard
az network nsg create \
--resource-group MyResourceGroup \
--name MyNsg \
--location japaneast
az network nsg rule create \
--resource-group MyResourceGroup \
--nsg-name MyNsg \
--name seq100 \
--priority 100 \
--destination-port-ranges 22 80 \
--access Allow \
--protocol Tcp
az vm create \
--resource-group MyResourceGroup \
--name linux010 \
--image UbuntuLTS \
--size Standard_B1s \
--admin-username azureuser \
--ssh-key-values ~/.ssh/authorized_keys \
--vnet-name MyVnet \
--subnet MySubnet \
--public-ip-address MyPublicIp \
--nsg MyNsg
az vm run-command invoke \
--resource-group MyResourceGroup \
--name linux010 \
--command-id RunShellScript \
--scripts @/dev/stdin << 'EOF'
#!/bin/bash
apt-get -y install nginx
echo "this is ${HOSTNAME}" > /var/www/html/index.html
echo "OK" > /var/www/html/image.png
EOF
az network front-door create \
--resource-group MyResourceGroup \
--name ${FRONT_DOOR_NAME} \
--backend-address ${DNS_NAME}.japaneast.cloudapp.azure.com
az network front-door probe update \
--resource-group MyResourceGroup \
--front-door-name ${FRONT_DOOR_NAME} \
--name DefaultProbeSettings \
--protocol http
HTTPヘッダーの書き換え例
ルールエンジンの編集
HTTPレスポンスヘッダーにContent-Security-Policyを付与するルールを作成します。
az network front-door rules-engine rule create \ --resource-group MyResourceGroup \ --front-door-name fr-gokatei01 \ --rules-engine-name MyRuleEngine \ --name rule010 \ --priority 10 \ --match-processing-behavior Continue \ --action-type ResponseHeader \ --header-action Append \ --header-name Content-Security-Policy \ --header-value "script-src 'self' https://xxxx.xxxx.com."
作成したルール(MyRuleEngine)をルーティング規則(DefaultRoutingRule)に適用します。
az network front-door routing-rule update \ --resource-group MyResourceGroup \ --front-door-name fr-gokatei01 \ --name DefaultRoutingRule \ --rules-engine MyRuleEngine
動作確認
HTTPレスポンスヘッダーにContent-Security-Policyが付与されている事を確認します。
admin@mac19 ~ % curl -I http://fr-gokatei01.azurefd.net HTTP/1.1 200 OK Content-Length: 17 Content-Type: text/html Last-Modified: Fri, 06 May 2022 13:46:08 GMT Accept-Ranges: bytes ETag: "627526a0-11" X-Cache: CONFIG_NOCACHE Content-Security-Policy: script-src 'self' https://xxxx.xxxx.com. X-Azure-Ref: 03jB1YgAAAAD/j7dZMbIsS684M5raud4rVFlPMDFFREdFMjMxOABlZTc1ZjQ3YS1kYWEzLTQ1MjMtYTM0ZS05OTk5YWNmN2E5MTc= Date: Fri, 06 May 2022 14:29:50 GMT
キャッシュ有無の変更
ルールエンジンのアクションの編集
ルールエンジンはHTTPヘッダーの書き換えだけでなく、ルーティング(振り分け先のバックエンドプールやキャッシュ有無)を変更する事もできます。
現在(2022年5月)時点ではaz network front-door rules-engine rule createコマンドでルーティングを変更する事はできません。近い将来に改修される可能性は高いと思いますが、以下のような回避策を用いて操作します。
- az network front-door rules-engine rule createコマンドでダミーのHTTPヘッダー書き換えルール作成
- az network front-door rules-engine rule action addコマンドでルーティング変更のルール作成
- az network front-door rules-engine rule action removeコマンドでダミーのHTTPヘッダー書き換えルール削除
後の操作で削除しますが、ダミーのHTTPヘッダー書き換えルールを作成します。
az network front-door rules-engine rule create \ --resource-group MyResourceGroup \ --front-door-name fr-gokatei01 \ --rules-engine-name MyRuleEngine \ --name rule020 \ --priority 20 \ --match-processing-behavior Continue \ --action-type ResponseHeader \ --header-action Delete \ --header-name Dummy
キャッシュを有用にするルーティングを設定します。キャッシュ保持期間は3分とします。
az network front-door rules-engine rule action add \ --resource-group MyResourceGroup \ --front-door-name fr-gokatei01 \ --rules-engine-name MyRuleEngine \ --name rule020 \ --action-type ForwardRouteOverride \ --backend-pool DefaultBackendPool \ --caching Enabled \ --cache-duration PT3M
ダミーのHTTPヘッダー書き換えルールを削除します。
az network front-door rules-engine rule action remove \ --resource-group MyResourceGroup \ --front-door-name fr-gokatei01 \ --rules-engine-name MyRuleEngine \ --name rule020 \ --index 0 \ --action-type ResponseHeader
ここまでの操作で想定通りのルールになっている事を確認します。responseHeaderActionsが空配列で、routeConfigurationOverrideがキャッシュ有効の設定になっている事を確認します。
$ az network front-door rules-engine rule show \
--resource-group MyResourceGroup \
--front-door-name fr-gokatei01 \
--rules-engine-name MyRuleEngine \
--name rule020
{
"action": {
"name": null,
"requestHeaderActions": [],
"responseHeaderActions": [],
"routeConfigurationOverride": {
"backendPool": {
"id": "/subscriptions/2e2f81a9-b030-410f-9784-c582580c932e/resourceGroups/MyResourceGroup/providers/Microsoft.Network/Frontdoors/fr-gokatei01/backendPools/DefaultBackendPool",
"resourceGroup": "MyResourceGroup"
},
"cacheConfiguration": {
"cacheDuration": "0:03:00",
"dynamicCompression": "Enabled",
"queryParameterStripDirective": "StripAll",
"queryParameters": null
},
"customForwardingPath": null,
"forwardingProtocol": "MatchRequest",
"odataType": "#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration"
}
},
"matchConditions": [],
"matchProcessingBehavior": "Continue",
"name": "rule020",
"priority": 20
}
ルールエンジンの条件の編集
「Azure Front Door 基本操作」で紹介したURL patternの例では、前方一致による条件一致しか指定できませんでした。しかし、ルールエンジンを使用すれば柔軟な条件一致を定義する事ができます。
以下にaz network front-door rules-engine rule condition addのヘルプを転載します。「モバイルか否か」「RequestBodyに基づく条件一致」「後方一致」など様々な指定方法が可能な事が分かります。
$ az network front-door rules-engine rule condition add -h
Please let us know how we are doing: https://aka.ms/azureclihats
admin@mac19 doc % az network front-door rules-engine rule condition add -h
This command is from the following extension: front-door
Command
az network front-door rules-engine rule condition add : Add a match condition to a Rules Engine
rule.
Arguments
--front-door-name -f [Required] : Name of the Front Door.
--name -n [Required] : Name of the rule.
--resource-group -g [Required] : Name of resource group. You can configure the default group
using `az configure --defaults group=<name>`.
--rules-engine-name -r [Required] : Name of the Rules Engine.
Match Condition Arguments
--match-values : Space-separated list of values to match against.
--match-variable : Name of the match condition. Allowed values: IsMobile,
PostArgs, QueryString, RemoteAddr, RequestBody,
RequestFilename, RequestFilenameExtension, RequestHeader,
RequestMethod, RequestPath, RequestScheme, RequestUri.
--negate-condition : Applies "Not" to the operator. Allowed values: false, true.
--operator : Operator of the match condition. Allowed values: Any,
BeginsWith, Contains, EndsWith, Equal, GeoMatch,
GreaterThan, GreaterThanOrEqual, IPMatch, LessThan,
LessThanOrEqual.
--selector : Optional selector for the match condition variable.
--transforms : Space-separated list of transforms to apply. Allowed
values: Lowercase, RemoveNulls, Trim, Uppercase, UrlDecode,
UrlEncode.
末尾がpngで終わるURLのみに条件を絞り込むならば、以下のように記述します。
az network front-door rules-engine rule condition add \ --resource-group MyResourceGroup \ --front-door-name fr-gokatei01 \ --rules-engine-name MyRuleEngine \ --name rule020 \ --match-variable RequestUri \ --operator EndsWith \ --match-values png
動作確認
手元の端末から10秒間隔でpngファイルへアクセスするようなCLI操作をします。
admin@mac19 ~ % while true ; do curl -s -I http://fr-gokatei01.azurefd.net/image.png | grep ^HTTP sleep 10 done
仮想マシンへsshでログインします。アクセスログを確認すると、10秒間隔ではなくキャッシュ保持切れになる3分間隔でアクセスが発生している事が分かります。なお、以下出力の場合はCDNサーバは2台構成のようで、それぞれのサーバが3分間隔のアクセスになります。
azureuser@linux010:~$ tail -f /var/log/nginx/access.log | grep png 147.243.196.245 - - [06/May/2022:15:01:42 +0000] "GET /image.png HTTP/1.1" 200 3 "-" "curl/7.77.0" 147.243.196.204 - - [06/May/2022:15:02:02 +0000] "GET /image.png HTTP/1.1" 200 3 "-" "curl/7.77.0" 147.243.196.245 - - [06/May/2022:15:05:04 +0000] "GET /image.png HTTP/1.1" 200 3 "-" "curl/7.77.0" 147.243.196.204 - - [06/May/2022:15:05:14 +0000] "GET /image.png HTTP/1.1" 200 3 "-" "curl/7.77.0" 147.243.196.245 - - [06/May/2022:15:08:07 +0000] "GET /image.png HTTP/1.1" 200 3 "-" "curl/7.77.0" 147.243.196.204 - - [06/May/2022:15:08:27 +0000] "GET /image.png HTTP/1.1" 200 3 "-" "curl/7.77.0" 147.243.196.245 - - [06/May/2022:15:11:10 +0000] "GET /image.png HTTP/1.1" 200 3 "-" "curl/7.77.0" 147.243.196.204 - - [06/May/2022:15:11:40 +0000] "GET /image.png HTTP/1.1" 200 3 "-" "curl/7.77.0"
