AzureのPaaSやパブリックIPに割り当てられるグローバルアドレスのIPレンジは不定期で更新されます。
最新のIPレンジは以下のサイトからxml形式でダウンロードすることが可能です。
Microsoft Azure Datacenter IP Ranges
例えばこのIPレンジを使って、NSG設定とか、社内LAN環境のExpressRouteルーティング設定をしているとかの場合、いちいちダウンロードして更新チェックするのはとても手間です。
東日本リージョンもしくは西日本リージョンのIPレンジが変更された場合にSlack通知させる仕組みを作りました。
前提
概要イメージ図
FunctionsはIP Rangeが書かれたXMLファイルをダウンロードして、指定されたリージョンだけに加工します。
AutomationはFunctionsから取得したIP RangeをBlobに加工して、前日分と差分がないか確認します。
差分があれば、変更点をSlackに通知します。
ローカルPC上でFunctionsの実行環境が整っていること
まとめた記事を書いたので参考にしてください。事前インストールの章ですね。
Azure FunctionsをJava + VS Codeで試してみた(Maven for Java編)
課金確認専用ユーザ作成
以下記事を参考に課金用サービスプリンシパルを作成します。
Azureの課金系REST APIをcurlで実行する方法
Azure Functions実装
それでは早速Functionsから実装していきます。
コードは以下に配置しています。
git clone
- git cloneでリポジトリを持ってくる。
git clone https://github.com/shingo-kawahara/Azure-IpRange-Api-Sample.git
pom.xml修正
- pom.xmlを開いて、2箇所修正します。
- functionAppName: これはFunction Appの名前になります。
- functionResourceGroup: これはFunction Appが配置されるリソースグループ名です。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<azure.functions.maven.plugin.version>1.0.0-beta-7</azure.functions.maven.plugin.version>
<azure.functions.java.library.version>1.0.0-beta-5</azure.functions.java.library.version>
<functionAppName>azure-iprange-api-sample</functionAppName>
<functionAppRegion>japaneast</functionAppRegion>
<stagingDirectory>${project.build.directory}/azure-functions/${functionAppName}</stagingDirectory>
<functionResourceGroup>azure-iprange-api-sample-grp</functionResourceGroup>
</properties>
local.settings.json配置
- 新規ファイル作成する。
- ローカルPCでテストするとき、もしネットワーク上にProxyサーバがいる場合は、このファイルにIDとパスワードを設定します。
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"AzureWebJobsDashboard": "",
"FUNCTIONS_WORKER_RUNTIME": "java",
"proxyHost": "Your Proxy HostName",
"proxyPort": "Your Proxy Port",
"proxyUser": "Your Proxy UserName",
"ProxyPass": "Your Proxy Password"
}
}
ローカルテスト
- 以下コマンドを実行して、ビルドとローカル実行をします。
mvn clean package
mvn azure-functions:run
- Webブラウザを開いて、以下のURLを入力します。
http://localhost:7071/api/iprange?region=japaneast
- 指定したリージョンのIPアドレス一覧が表示されたらOKです。
デプロイ
- 以下コマンドを実行して、Azure上にデプロイします。
az login
mvn azure-functions:deploy
Functions Key取得
テスト
- Webブラウザを開いて、以下のURLを入力します。ローカル実行と比べて、Functions Keyを追加で付与しています。
https://azure-iprange-api-sample.azurewebsites.net/api/iprange?code=[Functions Key]®ion=japanwest
- 指定したリージョンのIPアドレス一覧が表示されたらOKです。
Blob Storage作成
- IPレンジ情報を格納するBlob Storageを作成しておきます。コンテナーまで作っておいてください。
Azure Automation実装
Functions APIの実行は、Automationにさせることにします。
ここはなんでもよくて、オンプレからcronとかで定期実行してもよいです。
Automationアカウントの作成手順は割愛します。
- Runbookの種類は「PowerShell」で、以下のように作成します。
- 更新チェックをするために、ストレージアカウントに事前事後ファイルを配置することにしています。
Param(
[parameter(Mandatory=$True)]
[string]$functionsKey,
[parameter(Mandatory=$True)]
[string]$resourceGroup,
[parameter(Mandatory=$True)]
[string]$storageAccountName,
[parameter(Mandatory=$True)]
[String]$ContainerName
)
$Conn = Get-AutomationConnection -Name AzureRunAsConnection
Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationID $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint
Set-AzureRmCurrentStorageAccount -ResourceGroupName $resourceGroup -StorageAccountName $storageAccountName
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
foreach( $region in "japaneast","japanwest" )
{
Write-Output "Start Get Blob List $region"
$ErrorActionPreference = "silentlycontinue"
$BlobList = Get-AzureStorageBlob -Container $ContainerName -Blob $region-bef.txt
$ErrorActionPreference = "continue"
Write-Output "Start Get Iprange $region"
$IpRange = Invoke-WebRequest -Uri "https://azure-iprange-api-sample/api/iprange" -Method GET -Body @{code="$functionsKey";region="$region"} -UseBasicParsing | select -ExpandProperty Content
if ( [string]::IsNullOrEmpty($BlobList) ) {
Write-Output "Start Create Before File $region"
$IpRange | Out-File C:\$region-bef.txt
Set-AzureStorageBlobContent -File C:\$region-bef.txt -Container $ContainerName
} else {
Write-Output "Start Create After File $region"
$IpRange | Out-File C:\$region-aft.txt
Get-AzureStorageBlobContent -Container $ContainerName -Blob $region-bef.txt -Destination "C:\" -Force
$bef = Get-Content C:\$region-bef.txt
$aft = Get-Content C:\$region-aft.txt
Compare-Object $bef $aft > C:\$region-cmp.txt
$msg = Get-Content C:\$region-cmp.txt
if ( -not([string]::IsNullOrEmpty($msg)) ) {
$output = $msg -join "`n"
$pretext = "$region" + " リージョンのIPRangeが更新されました"
$enc = [System.Text.Encoding]::GetEncoding('ISO-8859-1')
$utf8Bytes = [System.Text.Encoding]::UTF8.GetBytes($pretext)
$payload = @{
username = "Azure Automation"
icon_emoji = ":azure:"
channel = "#channel"
attachments = @(
@{
pretext = $enc.GetString($utf8Bytes);
text = $output
}
)
}
Write-Output "Start Slack Notify $region"
Invoke-RestMethod -Uri "https://hooks.slack.com/services/[Slack Incoming Webhook ID]" -Method Post -Body (ConvertTo-Json $payload)
Set-AzureStorageBlobContent -File C:\$region-aft.txt -Container $ContainerName -Blob $region-bef.txt -Force
}
}
}
まとめ
今回は通知だけですが、ARMTemplateやAnsibleといったIaCの仕組みと一緒に活用するのがよさそう。