はじめに
検証でAzure環境とAWS環境をVPN接続した環境が必要となり、以下記事を参考に環境を構築しようとしました。
最低限のコストで、必要な時に作ったり消したりを気軽にできるよう、テンプレート化してみたという記事です。

上記記事の完全体はアクティブ-アクティブ構成かつ2つのトンネルで構成されていますが、今回はアクティブ-アクティブを無効にしてトンネルを1つだけ構成してます。段階的には成長期です。
一時的な検証用途なので、最低限の構成でつながればいいやという思想です。イメージはこんな感じ。
概要図
テンプレート
テンプレートは3つ用意しています。これはリソース構築後に払い出される値が必要なリソースがあるためです。
例えば、AWS側のカスタマーゲートウェイにAzureのパブリックIPが必要である、とか。
作成の大まかな流れは以下の通りです。
Step | 作業項目 | 備考 |
Step1:【Azure】NW基盤作成 | ①VNet・サブネットの作成 ②Virtual Network Gateway用パブリックIPの作成 |
対応テンプレート: azure_network_resource.json |
Step2:【AWS】VPNリソース作成 | ①VPC作成 ②カスタマーゲートウェイ作成 ③仮想ネットワークゲートウェイ作成 ④VPN接続作成 ⑤ルート伝搬の有効化 |
対応テンプレート:aws_vpn_resource.yaml |
Step3:【Azure】VPNリソース作成 | ①Local Network Gateway作成 ②Virtual Network Gateway作成 ③VPN接続作成 |
対応テンプレート:azure_vpn_resource.json |
Step1 :【Azure】NW基盤作成
指定しているパラメータ
パラメータ名 | デフォルト値 | 備考 |
vnetName | VNet1 | 作成するVNetの名前 |
vnetAddressPrefix | 10.1.0.0/16 | 作成するVNetのCIDR範囲 |
subnet1Prefix | 10.1.0.0/24 | GatewaySubnetのCIDR範囲 |
vpnpipName | VNet1GWpip | パブリックIPの名前 |
コード
ファイル名:azure_network_resource.json
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.6.18.56646", "templateHash": "10806234693722113459" } }, "parameters": { "vnetName": { "type": "string", "metadata": { "description": "VNet Name" }, "defaultValue": "VNet1" }, "vnetAddressPrefix": { "type": "string", "metadata": { "description": "VNet CIDR range" }, "defaultValue": "10.1.0.0/16" }, "subnet1Prefix": { "type": "string", "metadata": { "description": "Gateway Subnet CIDR range" }, "defaultValue": "10.1.0.0/24" }, "vpnpipName": { "type": "string", "metadata": { "description": "Public IP Name" }, "defaultValue": "VNet1GWpip" } }, "resources": [ { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2024-05-01", "name": "[parameters('vnetName')]", "location": "[resourceGroup().location]", "properties": { "addressSpace": { "addressPrefixes": [ "[parameters('vnetAddressPrefix')]" ] }, "subnets": [ { "name": "GatewaySubnet", "properties": { "addressPrefix": "[parameters('subnet1Prefix')]" } } ] } }, { "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2024-05-01", "name": "[parameters('vpnpipName')]", "location": "[resourceGroup().location]", "sku": { "name": "Standard", "tier": "Regional" }, "properties": { "publicIPAllocationMethod": "Static", "idleTimeoutInMinutes": 4 } } ] }
Step2:【AWS】VPNリソース作成
指定しているパラメータ
パラメータ名 | デフォルト値 | 備考 |
myVPCName | VPC1 | 作成するVPCの名前 |
myVPCCIDR | 10.2.0.0/16 | 作成するVPCのCIDR範囲 |
VGWName | AzureGW | 仮想ネットワークゲートウェイの名前 |
CGWName | ToAzureInstance0 | カスタマーゲートウェイの名前 |
VPNConnectionName | ToAzureConnection | VPN接続の名前 |
CustomBGPASN | 65000 | Azure側GatewayのASN |
azurepip | なし | Step1で作成したパブリックIPを指定 |
コード
ファイル名:aws_vpn_resource.yaml
AWSTemplateFormatVersion: '2010-09-09' Description: Create a Virtual Private Gateway and Customer Gateway Parameters: myVPCName: Type: String Default: "VPC1" # VPCの名前 myVPCCIDR: Type: String Default: "10.2.0.0/16" # VPCのCIDR範囲 VGWName: Type: String Default: "AzureGW" # 仮想ネットワークゲートウェイのリソース名 CGWName: Type: String Default: "ToAzureInstance0" # カスタムネットワークゲートウェイのリソース名 VPNConnectionName: Type: String Default: "ToAzureConnection" # VPN接続の名前 CustomBGPASN: Type: Number Default: 65000 # 任意のASNを入力 azurepip: # スタック作成時にAzure側のパブリックIPを入力する。 Type: String Resources: # VPCの作成 myVPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref myVPCCIDR Tags: - Key: Name Value: !Ref myVPCName MyVpcDefaultRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref myVPC # 仮想プライベートゲートウェイの作成 VirtualPrivateGateway: Type: AWS::EC2::VPNGateway Properties: Type: ipsec.1 Tags: - Key: Name Value: !Ref VGWName # 仮想プライベートゲートウェイをVPCにアタッチ VPCGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref myVPC VpnGatewayId: !Ref VirtualPrivateGateway # カスタマーゲートウェイの作成 CustomerGateway: Type: AWS::EC2::CustomerGateway Properties: BgpAsn: !Ref CustomBGPASN IpAddress: !Ref azurepip # カスタマーゲートウェイのパブリックIPアドレス Type: ipsec.1 Tags: - Key: Name Value: !Ref CGWName # VPN接続の作成 VPNConnection: Type: AWS::EC2::VPNConnection Properties: Type: ipsec.1 CustomerGatewayId: !Ref CustomerGateway VpnGatewayId: !Ref VirtualPrivateGateway StaticRoutesOnly: false # 動的ルーティングとする。 Tags: - Key: Name Value: !Ref VPNConnectionName VpnTunnelOptionsSpecifications: - TunnelInsideCidr: "169.254.21.0/30" # トンネル1の内部IPv4 CIDR - TunnelInsideCidr: "169.254.22.0/30" # トンネル2の内部IPv4 CIDR # ルート伝搬の有効化 EnableRoutePropagation: Type: AWS::EC2::VPNGatewayRoutePropagation Properties: RouteTableIds: - !Ref MyVpcDefaultRouteTable VpnGatewayId: !Ref VirtualPrivateGateway DependsOn: VPCGatewayAttachment Outputs: VirtualPrivateGatewayId: Description: "The ID of the Virtual Private Gateway" Value: !Ref VirtualPrivateGateway CustomerGatewayId: Description: "The ID of the Customer Gateway" Value: !Ref CustomerGateway VPNConnectionId: Description: "The ID of the VPN Connection" Value: !Ref VPNConnection
Step3:【Azure】VPNリソース作成
指定しているパラメータ
パラメータ名 | デフォルト値 | 備考 |
myVNet | VNet1 | Step1で作成したVNetの名前 |
publicIpName |
VNet1GWpip
|
Step1で作成したパブリックIPの名前 |
localNetworkGatewayName
|
lngw_test
|
Local Network Gatewayの名前 |
asn
|
64512 | AWS側のASN |
bgpPeeringAddress
|
169.254.21.1 | Local Network GatewayのピアIP |
customBgpIpAddress
|
169.254.21.2 | Virtual Network GatewayのピアIP |
virtualNetworkGatewayName
|
vngw_test
|
Virtual Network Gatewayの名前 |
vngwasn
|
65000 | Azure側のASN |
gatewaySku
|
VpnGw1
|
VPN GatewayのSKUを指定 |
virtualNetworkConnectionName
|
AWSTunnel1toAzureInstance0
|
VPN接続の名前 |
gatewayIpAddress
|
なし
|
Step2で作成したVPN接続(トンネル1)のパブリックIPを指定 |
PreSharedKey
|
なし
|
Step2で作成したVPN接続の事前共有鍵を指定 |
コード
ファイル名:aws_vpn_resource.yaml
{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "myVNet": { "type": "string", "metadata": { "description": "VNet Name" }, "defaultValue": "VNet1" }, "publicIpName": { "type": "string", "metadata": { "description": "PublicIPAddress Name" }, "defaultValue": "VNet1GWpip" }, "localNetworkGatewayName": { "type": "string", "metadata": { "description": "LocalNetworkGateway Name" }, "defaultValue": "lngw_test" }, "asn": { "type": "int", "metadata": { "description": "Autonomous System Number (ASN) for BGP" }, "defaultValue": 64512 }, "bgpPeeringAddress": { "type": "string", "metadata": { "description": "BGP peering address for LocalNetworkGateway" }, "defaultValue": "169.254.21.1" }, "customBgpIpAddress": { "type": "string", "metadata": { "description": "BGP peering address for VirtualNetworkGateway" }, "defaultValue": "169.254.21.2" }, "virtualNetworkGatewayName": { "type": "string", "metadata": { "description": "Name of the virtual network gateway" }, "defaultValue": "vngw_test" }, "vngwasn": { "type": "int", "metadata": { "description": "Autonomous System Number (ASN) for BGP" }, "defaultValue": 65000 }, "gatewaySku": { "type": "string", "metadata": { "description": "SKU for the virtual network gateway" }, "defaultValue": "VpnGw1", "allowedValues": [ "Basic", "VpnGw1", "VpnGw2", "VpnGw3", "VpnGw4", "VpnGw5" ] }, "virtualNetworkConnectionName": { "type": "string", "metadata": { "description": "Name of the VPN Connection" }, "defaultValue": "AWSTunnel1toAzureInstance0" }, "gatewayIpAddress": { "type": "string", "metadata": { "description": "AWS Public IP Address" } }, "PreSharedKey": { "type": "string", "metadata": { "description": "Pre-SharedKey" } } }, "resources": [ { "type": "Microsoft.Network/localNetworkGateways", "apiVersion": "2024-05-01", "name": "[parameters('localNetworkGatewayName')]", "location": "[resourceGroup().location]", "properties": { "gatewayIpAddress": "[parameters('gatewayIpAddress')]", "bgpSettings": { "asn": "[parameters('asn')]", "bgpPeeringAddress": "[parameters('bgpPeeringAddress')]" } } }, { "type": "Microsoft.Network/virtualNetworkGateways", "apiVersion": "2024-05-01", "name": "[parameters('virtualNetworkGatewayName')]", "location": "[resourceGroup().location]", "properties": { "ipConfigurations": [ { "name": "vnetGatewayConfig", "properties": { "privateIPAllocationMethod": "Dynamic", "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('myVNet'), 'GatewaySubnet')]" }, "publicIPAddress": { "id": "[resourceId('Microsoft.Network/publicIPAddresses', parameters('publicIpName'))]" } } } ], "gatewayType": "Vpn", "vpnType": "RouteBased", "enableBgp": true, "activeActive": false, "sku": { "name": "[parameters('gatewaySku')]", "tier": "[parameters('gatewaySku')]" }, "bgpSettings": { "asn": "[parameters('vngwasn')]", "bgpPeeringAddresses": [ { "ipconfigurationId": "[resourceId('Microsoft.Network/virtualNetworkGateways/ipConfigurations', parameters('virtualNetworkGatewayName'), 'vnetGatewayConfig')]", "customBgpIpAddresses": [ "[parameters('customBgpIpAddress')]" ] } ] } } }, { "type": "Microsoft.Network/connections", "apiVersion": "2024-05-01", "name": "[parameters('virtualNetworkConnectionName')]", "location": "[resourceGroup().location]", "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworkGateways', parameters('virtualNetworkGatewayName'))]", "[resourceId('Microsoft.Network/localNetworkGateways', parameters('localNetworkGatewayName'))]" ], "properties": { "virtualNetworkGateway1": { "id": "[resourceId('Microsoft.Network/virtualNetworkGateways', parameters('virtualNetworkGatewayName'))]" }, "localNetworkGateway2": { "id": "[resourceId('Microsoft.Network/localNetworkGateways', parameters('localNetworkGatewayName'))]" }, "connectionType": "IPsec", "sharedKey": "[parameters('PreSharedKey')]", "enableBgp": true } } ], "outputs": { "localNetworkGatewayId": { "type": "string", "value": "[resourceId('Microsoft.Network/localNetworkGateways', parameters('localNetworkGatewayName'))]" }, "VirtualNetworkGatewayId": { "type": "string", "value": "[resourceId('Microsoft.Network/localNetworkGateways', parameters('localNetworkGatewayName'))]" } } }
手順
ここからは上記テンプレートを用いた簡単な構築手順を記載します。なお、細かい画面遷移等は手順を省いていますのでご了承ください。
なお、Azure CLIがインストールされていることが前提となります。インストール手順は以下参照です。

リソース構築手順
①Azure CLIを使うため以下コマンドでAzureにログインします。
az login
②Azure側にリソースグループがない場合は以下コマンドでリソースグループを作成して下さい。
az group create --name <リソースグループ名> --location japaneast
③以下コマンドでAzureリソース(NW関連)をデプロイします。
az deployment group create --resource-group <リソースグループ名> --template-file azure_network_resource.json
④AWSコンソール画面のCloudFormationよりスタックを作成してください。
テンプレートファイルを読み込ませます。
パラメータとして③で確認したAzure側のパブリックIPアドレスを入力します。
その他はデフォ設定のままスタックを送信すればOKです。
⑤CloudFormationが正常終了したら、VPN接続画面でトンネルのパブリックIPを確認します。
ダウンロードしたファイル内に事前共有鍵が書かれてるので、後ほど使います。
⑦最後に以下コマンドでAzureリソース(VPN関連)をデプロイします。
gatewayIpAddressで⑤で確認したパブリックIPを、PreSharedKeyで⑥で確認した事前共有鍵を指定します。
az deployment group create --resource-group <リソースグループ名> --template-file azure_vpn_resource.json --parameters gatewayIpAddress=<⑤で確認したパブリックIP> PreSharedKey=<⑥で確認した事前共有鍵>
➇以下のようになってれば、つながってるはずです。
※Azure上で仮想VM、AWS上でEC2をたて、疎通できることを確認しました。
【Azure側】
【AWS側】
リソース削除手順
【Azure】
リソースグループを削除することで作成したリソースが全部消えます。以下コマンドを実行ください。
az group delete --name <リソースグループ名>
【AWS】
CloudFormationのスタックを削除することで作成したリソースが全部消えます。
おわりに
以上、AWSとAzureをVPN接続してみた、でした。本当に接続するとこだけしか作ってませんが。。
ちなみに構築全体流すので大体40分くらいかかります。※AzureのVPNリソース作成が30分超かかる。
コンセプトとしてはAzure、AWSに何もない状態で0から作るってことと手数をできるだけ少なくってことを意識しました。
とはいえ、AzureとAWSという異なるプラットフォームから値を引っ張ってくる必要があるので1つのテンプレートにおさめるのは難しく、手順も何ステップかに分かれてるのでもう少し工夫できないかなあと思っているところです。
余裕がでてくればそのうち冒頭のMicrosoft記事の完全体を作れるように…したいところです。