はじめに 検証でAzure環境とAWS環境をVPN接続した環境が必要となり、以下記事を参考に環境を構築しようとしました。 最低限のコストで、必要な時に作ったり消したりを気軽にできるよう、テンプレート化してみたという記事です。 チュートリアル - ポータルを使用して Azure と アマゾン ウェブ サービス (AWS) 間の BGP 対応接続を構成する - Azure VPN Gateway このチュートリアルでは、アクティブ/アクティブ VPN Gateway と AWS 上の 2 つのサイト間接続を使用して Azure と AWS を接続する方法について説明します。 learn.microsoft.com 上記記事の完全体はアクティブ-アクティブ構成かつ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 CLI は、Windows、macOS、および Linux 環境にインストールできます。 Docker コンテナーおよび Azure Cloud Shell でも実行できます。 learn.microsoft.com リソース構築手順 ①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 デプロイ後、作成したパブリックIPのアドレスを控えます。 ④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記事の完全体を作れるように…したいところです。