Azure Functionsで送信IPアドレスを固定したい話
今回は、 Azure Functionsで送信IPアドレスを固定する という、業務要件に対応したときの話を書きます。
この記事は アイソルートAdventCalendar2020 18日目の記事です。
こんにちは。
クラウドソリューショングループのimai.kです。
昨日はide.tさんの 【Swift】TableViewに配置したUISwitchのindexPath.rowを取得する でした。
iOS初心者から業務で開発している方まで幅広く役に立つ記事だったのではないでしょうか!
目次
- 今回の構成
- Azure Functionsで関数を作成する
- 仮想ネットワークを作成する
- NAT用のインスタンスを作成する
- 関数をVNet統合する
- Webサーバーを用意する
- 送信IPが固定されているか試す
- 最後に
Let’s begin
では、早速進めましょう!
今回の構成
Azure Functionsを利用したシステム構築を行う際、WebサーバーにAzure Functionsからアクセスするとき、
Webサーバー側の制約として、呼び出し元のIPアドレスを固定しないといけない、ということがよくあると思います。
しかし、Azure FunctionsのIPアドレスをマネージドサービスだけで実現することができませんでした。
(Azure NAT Gatewayと組み合わせることで実現可能かと試しましたが、2020年10月時点では上手くできませんでした。)
(2021/8/15 追記 : 現在はPremiumプランのFunctionsでNAT Gatewayを組み合わせることで実現可能です。)
そこで今回は以下のような構成で、Azure Functionsの送信IPアドレスを固定するアプローチを取りました。
Azure Functionsで関数を作成する
まずは、Azure PortalからAzure Functionsの関数アプリを作成しましょう。
プランはPremiumもしくはApp Serviceプランにしてください。
以下のような設定値になっていればOKです。
仮想ネットワークを作成する
仮想ネットワークを作成しましょう。
ここでは、東日本リージョンでサブネットを2つ(subnet1, subnet2)作成しておきます。
以下のような設定値になっていればOKです。
NAT用のインスタンスを作成する
Azure Functionsがインターネットアクセスするときに経由するNAT用のインスタンスを用意します。
今回は簡単のためにSSHのポートを開放しておきます。OSはUbuntu 18.04を使います。
また、NAT用インスタンスは先ほど作成したサブネットの2つめ(subnet2)に配置しておきます。
以下のような設定値になっていればOKです。
NAT用インスタンスが出来上がったら、SSHして以下のコマンドを実行します。
root@nat:~# echo "net.ipv4.ip_forward = 1" | tee -a /etc/sysctl.conf root@nat:~# systemctl restart systemd-networkd.service root@nat:~# apt update -y root@nat:~# apt autoremove -y root@nat:~# apt install -y firewalld root@nat:~# systemctl enable firewalld root@nat:~# systemctl start firewalld.service root@nat:~# firewall-cmd --set-default-zone=external root@nat:~# firewall-cmd --reload
関数をVNet統合する
VNet統合の前段階として、ルートテーブルを作成してサブネットにアタッチします。
ルートテーブルのネクストホップIPアドレスは、subnet1におけるNAT用インスタンスのプライベートIPアドレスを設定してください。
作成したルートテーブルをサブネット(subnet1)にアタッチします。
また、NAT用インスタンスの受信ポートの規則(ネットワークセキュリティグループ)に以下を加えます。
Azure Functionsを先ほど作成した仮想ネットワークに接続します。
関数アプリのネットワークからVNet統合を選択し、設定を行います。
以下のように設定できればOKです。
Azure Functionsの全ての送信トラフィックが仮想ネットワーク(subnet1)にルーティングされるように設定します。
関数アプリの構成から以下のアプリケーション設定を追加します。
Webサーバーを用意する
Azure FunctionsからアクセスするWebサーバーを用意します。
NAT用インスタンスとは別の仮想ネットワークを作成し、以下の要領でWebサーバー用のインスタンスを作成しましょう。
また、ネットワークセキュリティグループの設定で、インターネットからの80番ポートアクセスも許可してください。
Webサーバー用のインスタンスが作成できたら、SSHしてApacheをインストールします。
root@webserver:~# apt update -y root@webserver:~# apt autoremove -y root@webserver:~# apt install -y apache2
ついでに、アクセスログを出力しておきましょう。
root@webserver:~# tail -f /var/log/apache2/access.log
送信IPが固定されているか試す
では、WebサーバーにHTTPリクエストを実行するAzure Functionsの関数を、トリガーをHTTP triggerに、Authorization LevelをAnonymousにして作成してください。
今回は、C#で処理を書いてみます。
#r "Newtonsoft.Json" using System.Net; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Primitives; using Newtonsoft.Json; using System; using System.Text; using System.Net.Http; using System.Net.Http.Headers; public static async Task Run(HttpRequest req, ILogger log) { var apimUrl = " http://{WebサーバーのパブリックIPアドレス}/"; HttpClient Client = new HttpClient(); var response = Client.PostAsync(apimUrl, new StringContent("")).Result; return new OkObjectResult("Success"); }
Azure Functionsの「コードとテスト」から実行するか、
関数のURLを叩いてみましょう。
Webサーバー側のアクセスログに、NAT用インスタンスのパブリックIPアドレスが表示されれば成功です。
最後に
以上のようにすればAzure Functionsの送信IPアドレスを固定することができますが、
AWSのLambdaやGCPのCloud Functionsではマネージドサービスの組み合わせにより実現できます。
Microsoft Azureでも可能になると嬉しいです。
また、実運用においてはネットワークセキュリティグループの設定を適切に行う必要があるため、ご注意ください。
明日の記事はmaruoka.nさんによる 【ローコード】勤怠管理アプリを1日で作成です、お楽しみに!