mcpField
A
azure-networking

azure-networking

github.com/bagelholeクラウド・DevOps1.2k316 回インストール23 週間前に更新
リポジトリ

azure-networking について

Azure のネットワーク設計と運用を支援するスキルです。仮想ネットワークから本番向けの Hub-Spoke 構成まで、Azure CLI と Terraform の例やトラブルシューティングを扱います。

主な機能

  1. 01VNet、サブネット、NSG の作成
  2. 02VNet ピアリングの設定
  3. 03プライベートエンドポイントの構成
  4. 04Azure Firewall と Application Gateway の導入
  5. 05Terraform 設定例と問題解決

活用シーン

  1. 01Azure ワークロードのネットワーク基盤設計
  2. 02VNet と NSG による環境分離
  3. 03オンプレミスネットワークと Azure の接続
  4. 04PaaS サービスへのプライベート接続

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill azure-networking

インストール後、Claude Code で/azure-networkingを入力して読み込まれたか確認します。

詳細

Azure ネットワーク

VNet、サブネット、NSG、VNet ピアリング、プライベートエンドポイント、Azure Firewall、Application Gateway など、Azure のネットワークインフラストラクチャを設計、実装します。本番環境向けのハブ&スポークトポロジにおける az CLI コマンドと Terraform 構成の両方を扱います。

使用するタイミング

  • Azure ワークロードのネットワーク基盤を設計するとき。
  • VNet と NSG を使用して環境を分離するとき。
  • VPN または ExpressRoute 経由でオンプレミスネットワークを Azure に接続するとき。
  • プライベートエンドポイント経由で PaaS サービスへのプライベート接続が必要なとき。
  • Azure Firewall で集中型の送信トラフィックフィルタリングを実装するとき。
  • Application Gateway でロードバランシングまたはアプリケーション層ルーティングを設定するとき。

前提条件

# Install Azure CLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Login and set subscription
az login
az account set --subscription "my-subscription-id"

# Register required providers
az provider register --namespace Microsoft.Network

# Create resource group
az group create --name networking-rg --location eastus

VNet とサブネットの作成

ハブ VNet
# Create hub VNet for shared services
az network vnet create \
  --resource-group networking-rg \
  --name hub-vnet \
  --address-prefix 10.0.0.0/16 \
  --location eastus \
  --tags environment=prod role=hub

# Add subnets to hub
az network vnet subnet create \
  --resource-group networking-rg \
  --vnet-name hub-vnet \
  --name AzureFirewallSubnet \
  --address-prefix 10.0.1.0/26

az network vnet subnet create \
  --resource-group networking-rg \
  --vnet-name hub-vnet \
  --name GatewaySubnet \
  --address-prefix 10.0.2.0/27

az network vnet subnet create \
  --resource-group networking-rg \
  --vnet-name hub-vnet \
  --name SharedServicesSubnet \
  --address-prefix 10.0.3.0/24

az network vnet subnet create \
  --resource-group networking-rg \
  --vnet-name hub-vnet \
  --name AzureBastionSubnet \
  --address-prefix 10.0.4.0/26
スポーク VNet
# Create spoke VNet for application workloads
az network vnet create \
  --resource-group networking-rg \
  --name spoke-prod-vnet \
  --address-prefix 10.1.0.0/16 \
  --location eastus \
  --tags environment=prod role=spoke

az network vnet subnet create \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --name web-subnet \
  --address-prefix 10.1.1.0/24

az network vnet subnet create \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --name app-subnet \
  --address-prefix 10.1.2.0/24

az network vnet subnet create \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --name data-subnet \
  --address-prefix 10.1.3.0/24 \
  --private-endpoint-network-policies Enabled

# List all subnets in a VNet
az network vnet subnet list \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --output table

ネットワークセキュリティグループ

# Create NSG for web tier
az network nsg create \
  --resource-group networking-rg \
  --name web-nsg \
  --tags tier=web

# Allow HTTPS from internet
az network nsg rule create \
  --resource-group networking-rg \
  --nsg-name web-nsg \
  --name AllowHTTPS \
  --priority 100 \
  --direction Inbound \
  --access Allow \
  --protocol Tcp \
  --source-address-prefixes Internet \
  --destination-port-ranges 443

# Allow HTTP for redirect
az network nsg rule create \
  --resource-group networking-rg \
  --nsg-name web-nsg \
  --name AllowHTTP \
  --priority 110 \
  --direction Inbound \
  --access Allow \
  --protocol Tcp \
  --source-address-prefixes Internet \
  --destination-port-ranges 80

# Deny all other inbound traffic
az network nsg rule create \
  --resource-group networking-rg \
  --nsg-name web-nsg \
  --name DenyAllInbound \
  --priority 4096 \
  --direction Inbound \
  --access Deny \
  --protocol '*' \
  --source-address-prefixes '*' \
  --destination-port-ranges '*'

# Create NSG for app tier -- only allow from web subnet
az network nsg create \
  --resource-group networking-rg \
  --name app-nsg

az network nsg rule create \
  --resource-group networking-rg \
  --nsg-name app-nsg \
  --name AllowFromWeb \
  --priority 100 \
  --direction Inbound \
  --access Allow \
  --protocol Tcp \
  --source-address-prefixes 10.1.1.0/24 \
  --destination-port-ranges 8080

# Create NSG for data tier -- only allow from app subnet
az network nsg create \
  --resource-group networking-rg \
  --name data-nsg

az network nsg rule create \
  --resource-group networking-rg \
  --nsg-name data-nsg \
  --name AllowSQLFromApp \
  --priority 100 \
  --direction Inbound \
  --access Allow \
  --protocol Tcp \
  --source-address-prefixes 10.1.2.0/24 \
  --destination-port-ranges 1433

# Associate NSG with subnet
az network vnet subnet update \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --name web-subnet \
  --network-security-group web-nsg

az network vnet subnet update \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --name app-subnet \
  --network-security-group app-nsg

az network vnet subnet update \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --name data-subnet \
  --network-security-group data-nsg

# View effective NSG rules
az network nic list-effective-nsg \
  --resource-group networking-rg \
  --name myvm-nic \
  --output table

VNet ピアリング

# Peer hub to spoke
az network vnet peering create \
  --resource-group networking-rg \
  --name hub-to-spoke-prod \
  --vnet-name hub-vnet \
  --remote-vnet spoke-prod-vnet \
  --allow-vnet-access \
  --allow-forwarded-traffic \
  --allow-gateway-transit

# Peer spoke to hub
az network vnet peering create \
  --resource-group networking-rg \
  --name spoke-prod-to-hub \
  --vnet-name spoke-prod-vnet \
  --remote-vnet hub-vnet \
  --allow-vnet-access \
  --allow-forwarded-traffic \
  --use-remote-gateways false

# Verify peering status
az network vnet peering list \
  --resource-group networking-rg \
  --vnet-name hub-vnet \
  --output table

プライベートエンドポイント

# Create private endpoint for Azure SQL
az network private-endpoint create \
  --resource-group networking-rg \
  --name sql-private-endpoint \
  --vnet-name spoke-prod-vnet \
  --subnet data-subnet \
  --private-connection-resource-id "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Sql/servers/myserver" \
  --group-id sqlServer \
  --connection-name sql-connection

# Create private DNS zone for SQL
az network private-dns zone create \
  --resource-group networking-rg \
  --name privatelink.database.windows.net

# Link DNS zone to VNet
az network private-dns link vnet create \
  --resource-group networking-rg \
  --zone-name privatelink.database.windows.net \
  --name spoke-dns-link \
  --virtual-network spoke-prod-vnet \
  --registration-enabled false

# Create DNS record for the private endpoint
az network private-endpoint dns-zone-group create \
  --resource-group networking-rg \
  --endpoint-name sql-private-endpoint \
  --name sql-dns-group \
  --private-dns-zone privatelink.database.windows.net \
  --zone-name privatelink.database.windows.net

# Create private endpoint for Storage Account
az network private-endpoint create \
  --resource-group networking-rg \
  --name storage-private-endpoint \
  --vnet-name spoke-prod-vnet \
  --subnet data-subnet \
  --private-connection-resource-id "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/mystorageacct" \
  --group-id blob \
  --connection-name storage-blob-connection

# Create private endpoint for Key Vault
az network private-endpoint create \
  --resource-group networking-rg \
  --name kv-private-endpoint \
  --vnet-name spoke-prod-vnet \
  --subnet app-subnet \
  --private-connection-resource-id "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.KeyVault/vaults/myvault" \
  --group-id vault \
  --connection-name kv-connection

Azure Firewall

# Create public IP for firewall
az network public-ip create \
  --resource-group networking-rg \
  --name fw-public-ip \
  --sku Standard \
  --allocation-method Static

# Create Azure Firewall
az network firewall create \
  --resource-group networking-rg \
  --name hub-firewall \
  --location eastus \
  --sku AZFW_VNet \
  --tier Standard

# Configure firewall IP
az network firewall ip-config create \
  --resource-group networking-rg \
  --firewall-name hub-firewall \
  --name fw-ipconfig \
  --public-ip-address fw-public-ip \
  --vnet-name hub-vnet

# Get firewall private IP for route tables
FW_PRIVATE_IP=$(az network firewall show \
  --resource-group networking-rg \
  --name hub-firewall \
  --query "ipConfigurations[0].privateIpAddress" \
  --output tsv)

# Create application rule allowing web traffic
az network firewall application-rule create \
  --resource-group networking-rg \
  --firewall-name hub-firewall \
  --collection-name AllowWeb \
  --name AllowGoogle \
  --protocols Https=443 Http=80 \
  --source-addresses 10.1.0.0/16 \
  --target-fqdns "*.google.com" "*.microsoft.com" \
  --action Allow \
  --priority 100

# Create network rule for DNS
az network firewall network-rule create \
  --resource-group networking-rg \
  --firewall-name hub-firewall \
  --collection-name AllowDNS \
  --name AllowDNS \
  --protocols UDP \
  --source-addresses 10.1.0.0/16 \
  --destination-addresses 168.63.129.16 \
  --destination-ports 53 \
  --action Allow \
  --priority 200

# Create route table to send traffic through firewall
az network route-table create \
  --resource-group networking-rg \
  --name spoke-route-table

az network route-table route create \
  --resource-group networking-rg \
  --route-table-name spoke-route-table \
  --name default-to-firewall \
  --address-prefix 0.0.0.0/0 \
  --next-hop-type VirtualAppliance \
  --next-hop-ip-address "$FW_PRIVATE_IP"

# Associate route table with spoke subnet
az network vnet subnet update \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --name app-subnet \
  --route-table spoke-route-table

WAF を備えた Application Gateway

# Create public IP
az network public-ip create \
  --resource-group networking-rg \
  --name appgw-public-ip \
  --sku Standard \
  --allocation-method Static

# Create Application Gateway subnet
az network vnet subnet create \
  --resource-group networking-rg \
  --vnet-name spoke-prod-vnet \
  --name AppGatewaySubnet \
  --address-prefix 10.1.10.0/24

# Create Application Gateway with WAF v2
az network application-gateway create \
  --resource-group networking-rg \
  --name myapp-appgw \
  --location eastus \
  --sku WAF_v2 \
  --capacity 2 \
  --vnet-name spoke-prod-vnet \
  --subnet AppGatewaySubnet \
  --public-ip-address appgw-public-ip \
  --http-settings-port 80 \
  --http-settings-protocol Http \
  --frontend-port 443 \
  --servers 10.1.2.4 10.1.2.5

# Enable WAF policy
az network application-gateway waf-policy create \
  --resource-group networking-rg \
  --name myapp-waf-policy

az network application-gateway waf-policy managed-rule rule-set add \
  --resource-group networking-rg \
  --policy-name myapp-waf-policy \
  --type OWASP \
  --version 3.2

Terraform 構成

resource "azurerm_virtual_network" "hub" {
  name                = "hub-vnet"
  location            = azurerm_resource_group.networking.location
  resource_group_name = azurerm_resource_group.networking.name
  address_space       = ["10.0.0.0/16"]
  tags                = var.tags
}

resource "azurerm_subnet" "firewall" {
  name                 = "AzureFirewallSubnet"
  resource_group_name  = azurerm_resource_group.networking.name
  virtual_network_name = azurerm_virtual_network.hub.name
  address_prefixes     = ["10.0.1.0/26"]
}

resource "azurerm_virtual_network" "spoke" {
  name                = "spoke-prod-vnet"
  location            = azurerm_resource_group.networking.location
  resource_group_name = azurerm_resource_group.networking.name
  address_space       = ["10.1.0.0/16"]
  tags                = var.tags
}

resource "azurerm_subnet" "web" {
  name                 = "web-subnet"
  resource_group_name  = azurerm_resource_group.networking.name
  virtual_network_name = azurerm_virtual_network.spoke.name
  address_prefixes     = ["10.1.1.0/24"]
}

resource "azurerm_network_security_group" "web" {
  name                = "web-nsg"
  location            = azurerm_resource_group.networking.location
  resource_group_name = azurerm_resource_group.networking.name

  security_rule {
    name                       = "AllowHTTPS"
    priority                   = 100
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "443"
    source_address_prefix      = "Internet"
    destination_address_prefix = "*"
  }

  security_rule {
    name                       = "DenyAllInbound"
    priority                   = 4096
    direction                  = "Inbound"
    access                     = "Deny"
    protocol                   = "*"
    source_port_range          = "*"
    destination_port_range     = "*"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }

  tags = var.tags
}

resource "azurerm_subnet_network_security_group_association" "web" {
  subnet_id                 = azurerm_subnet.web.id
  network_security_group_id = azurerm_network_security_group.web.id
}

resource "azurerm_virtual_network_peering" "hub_to_spoke" {
  name                      = "hub-to-spoke"
  resource_group_name       = azurerm_resource_group.networking.name
  virtual_network_name      = azurerm_virtual_network.hub.name
  remote_virtual_network_id = azurerm_virtual_network.spoke.id
  allow_forwarded_traffic   = true
  allow_gateway_transit     = true
}

resource "azurerm_virtual_network_peering" "spoke_to_hub" {
  name                      = "spoke-to-hub"
  resource_group_name       = azurerm_resource_group.networking.name
  virtual_network_name      = azurerm_virtual_network.spoke.name
  remote_virtual_network_id = azurerm_virtual_network.hub.id
  allow_forwarded_traffic   = true
  use_remote_gateways       = false
}

resource "azurerm_private_endpoint" "sql" {
  name                = "sql-private-endpoint"
  location            = azurerm_resource_group.networking.location
  resource_group_name = azurerm_resource_group.networking.name
  subnet_id           = azurerm_subnet.data.id

  private_service_connection {
    name                           = "sql-connection"
    private_connection_resource_id = azurerm_mssql_server.main.id
    subresource_names              = ["sqlServer"]
    is_manual_connection           = false
  }

  private_dns_zone_group {
    name                 = "sql-dns-group"
    private_dns_zone_ids = [azurerm_private_dns_zone.sql.id]
  }
}

トラブルシューティング

症状原因解決策
VM がインターネットに接続できないNSG が送信をブロックしている、またはルートがないaz network nic list-effective-nsg で NSG ルールを確認し、ルートテーブルを検証します
VNet ピアリングが Disconnected と表示されるピアリングが一方向のみ作成されている両方向(ハブからスポーク、およびスポークからハブ)でピアリングを作成します
プライベートエンドポイントの DNS 名前解決ができないプライベート DNS ゾーンが VNet にリンクされていないaz network private-dns link vnet create で DNS ゾーンをリンクします
NSG ルールが反映されない優先度の高いルールによって上書きされているaz network nsg rule list でルールを一覧表示し、優先順位を確認します
Application Gateway の正常性プローブが失敗するバックエンドプールのサーバーに到達できないNSG で AppGateway サブネットからのトラフィックが許可されていることを確認します
Azure Firewall が正当なトラフィックをブロックするアプリケーションルールまたはネットワークルールがないLog Analytics でファイアウォールのログを確認し、適切なルールを追加します
VNet 間の通信に失敗するピアリングが設定されていない、またはルートがないピアリングの状態と allow-vnet-access が有効になっていることを確認します
リージョン間のレイテンシーが高いトラフィックが想定外の経路を通っているaz network watcher next-hop を使用してルーティングを診断します

関連スキル

  • azure-vms -- VM のネットワークインターフェイスと NSG の構成。
  • azure-aks -- Azure CNI による AKS の VNet 統合。
  • azure-sql -- データベースアクセス用のプライベートエンドポイント構成。
  • terraform-azure -- Terraform によるネットワークインフラストラクチャのプロビジョニング。
  • azure-functions -- Premium プランの関数向け VNet 統合。

コメント