Azure の VNet と Subnet と SecurityGroup の基本動作

  • Terraform
  • VNet
  • SecurityGroup
  • スポンサーリンク

    Azure の VNet と Subnet と SecurityGroup の基本動作を確認していて、分かったこと、気づいたことを簡単に整理したいと思います。

    Azure Virtual Network

    インフラ構築は Terraform で

    私はよく Terraform を使ってクラウドのインフラを作成しています。理由は3つあります。

    • GitHub でインフラをコード管理できる。(再利用できる)
    • 対象のリソースにどんなオプションがあるのか簡単に調べることができる。
    • AWS,Azure,GCP,OCI どのクラウドでも使える。

    terraform で Virtual Network

    Resource Group と Virtual Network を作成します。特にオプション等は指定しません。

    # Create a resource group
    resource "azurerm_resource_group" "test01" {
      name     = "atsushi.koizumi.test01"
      location = "East US"
      tags = {
        "Owner" = "koizumi",
        "Env"   = "test01"
      }
    }
    
    # Create a virtual network within the resource group
    resource "azurerm_virtual_network" "test01" {
      name                = "test01"
      resource_group_name = azurerm_resource_group.test01.name
      location            = azurerm_resource_group.test01.location
      address_space       = ["10.7.0.0/16"]
      tags = {
        "Owner" = "koizumi",
        "Env"   = "test01"
      }
    }

    Azure Virtual Network の tfstate

    これによって作成された Virtual Network の tfstate の内容がこちらです。

    {
      "mode": "managed",
      "type": "azurerm_virtual_network",
      "name": "test01",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "address_space": [
              "10.0.0.0/16"
            ],
            "bgp_community": "",
            "ddos_protection_plan": [],
            "dns_servers": null,
            "guid": "9ed10097-efb5-49c6-a06e-14577966f6e0",
            "id": "/subscriptions/xxx/resourceGroups/atsushi.koizumi.test01/providers/Microsoft.Network/virtualNetworks/test01",
            "location": "eastus",
            "name": "test01",
            "resource_group_name": "atsushi.koizumi.test01",
            "subnet": [],
            "tags": {
              "Env": "test01",
              "Owner": "koizumi"
            },
            "timeouts": null,
            "vm_protection_enabled": false
          },
          "private": "xxxx=",
          "dependencies": [
            "azurerm_resource_group.test01"
          ]
        }
      ]
    }

    これから分かることは以下です。

    • bgp_community はデフォルトで設定なし。
    • ddos_protection_plan はデフォルトで設定なし。
    • dns_servers はデフォルトで null になる。
    • guid が勝手に振られている。
    • subnet はデフォルトで設定なし。
    • timeouts はデフォルトで null になる。
    • vm_protection_enabled はデフォルトで false になる。

    これらのオプションの効果をそれぞれネットやポータル画面で簡単に調べてみました。

    bgp_community は難しいネットワークの設定のようですので、通常は設定なしでいいでしょう。ddos_protection_plan と vm_protection_enabled はセキュリティ水準に合わせて設定するものでしょう。有料サービスですから検証環境では不要ですね。

    dns_servers は DNS を自分で立てていれば、ip address を指定できます。Virtual Network に対する各アクション(作成、読込、変更、削除)のタイムアウト時間を設定するものです。

    検証環境を作る時に、Virtual Network で気をつけることは、基本的に address space を複数作るかどうか、くらいですね。

    Azure Subnet

    続いて、Virtual Network に Subnet を作っていきたいと思います。

    main.tf に以下の内容を追記

    # Create 2 Subnets within the virtual network
    resource "azurerm_subnet" "subnet01" {
      name                 = "subnet01"
      virtual_network_name = azurerm_virtual_network.vnet01.name
      resource_group_name  = azurerm_resource_group.test01.name
      address_prefixes     = ["10.7.1.0/24"]
    }
    resource "azurerm_subnet" "subnet02" {
      name                 = "subnet02"
      virtual_network_name = azurerm_virtual_network.vnet01.name
      resource_group_name  = azurerm_resource_group.test01.name
      address_prefixes     = ["10.7.2.0/24"]
    }

    Azure Subnet の tsftate

    これによって作成された Subnet の tfstate の内容がこちらです。

    {
      "mode": "managed",
      "type": "azurerm_subnet",
      "name": "subnet01",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "address_prefix": "10.7.1.0/24",
            "address_prefixes": [
              "10.7.1.0/24"
            ],
            "delegation": [],
            "enforce_private_link_endpoint_network_policies": false,
            "enforce_private_link_service_network_policies": false,
            "id": "/subscriptions/xxx/resourceGroups/atsushi.koizumi.test01/providers/Microsoft.Network/virtualNetworks/vnet01/subnets/subnet01",
            "name": "subnet01",
            "resource_group_name": "atsushi.koizumi.test01",
            "service_endpoints": null,
            "timeouts": null,
            "virtual_network_name": "vnet01"
          },
          "private": "xxx=",
          "dependencies": [
            "azurerm_resource_group.test01",
            "azurerm_virtual_network.vnet01"
          ]
        }
      ]
    }

    これから分かることは以下です。

    • delegation はデフォルトで設定なし。
    • enforce_private_link_endpoint_network_policies デフォルトで false。
    • enforce_private_link_service_network_policies はデフォルトで false。
    • service_endpoints はデフォルトで false。

    これらのオプションについて調べてみました。

    結論から言うと、全て「service_endpoints」のプライベートリンクに関する一連のオプションのようです。

    azure-subnet-01-01

    例えば、Azure Storage, Azure SQL Database, Azure Key Vault などのサービスと Virtual Machine が通信する際、「service_endpoints」を通して通信することが可能です。

    その際に、プライベートリンクと NSG(Network Security Group)で通信する、大きく2種類の方法があります。

    Azure のバックボーンを使ってセキュアに通信するのがプライベートリンクで、外部のインターネット経由で接続するのが NSG(Network Security Group)を使った通信です。

    セキュリティや通信速度を考慮するならば、基本的にはストレージやDBとの接続はプライベートリンクを使用するのが望ましいですね。いずれ、Virtual Machine とストレージ、DBを絡めた環境を作るときは試してみたいと思います。

    Azure SecurityGroup

    続いては、SecurityGroup の設定っです。今回はインバウンドアウトバウンドのルールの追加は行わず、Subnet への設定方法と、デフォルトで作成した場合にどのような設定になっているのかを確認したいと思います。

    main.tf に以下の内容を追記

    # Create 2 SecurityGroups
    resource "azurerm_network_security_group" "sg01" {
      name                = "sg01"
      location            = azurerm_resource_group.test01.location
      resource_group_name = azurerm_resource_group.test01.name
      tags = {
        "Owner" = "koizumi",
        "Env"   = "test01"
      }
    }
    resource "azurerm_network_security_group" "sg02" {
      name                = "sg02"
      location            = azurerm_resource_group.test01.location
      resource_group_name = azurerm_resource_group.test01.name
      tags = {
        "Owner" = "koizumi",
        "Env"   = "test01"
      }
    }
    
    # Associates a Network Security Group with a Subnet 
    resource "azurerm_subnet_network_security_group_association" "sg01" {
      subnet_id                 = azurerm_subnet.subnet01.id
      network_security_group_id = azurerm_network_security_group.sg01.id
    }
    resource "azurerm_subnet_network_security_group_association" "sg02" {
      subnet_id                 = azurerm_subnet.subnet02.id
      network_security_group_id = azurerm_network_security_group.sg02.id
    }

    Azure SecurityGroup の tfstate

    これによって作成された SecurityGroup の tfstate の内容がこちらです。

    {
      "mode": "managed",
      "type": "azurerm_network_security_group",
      "name": "sg01",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "/subscriptions/xxx/resourceGroups/atsushi.koizumi.test01/providers/Microsoft.Network/networkSecurityGroups/sg01",
            "location": "eastus",
            "name": "sg01",
            "resource_group_name": "atsushi.koizumi.test01",
            "security_rule": [],
            "tags": {
              "Env": "test01",
              "Owner": "koizumi"
            },
            "timeouts": null
          },
          "private": "xxx=",
          "dependencies": [
            "azurerm_resource_group.test01"
          ]
        }
      ]
    }

    SecurityGroup Association がこちらです。

    {
      "mode": "managed",
      "type": "azurerm_subnet_network_security_group_association",
      "name": "sg01",
      "provider": "provider[\"registry.terraform.io/hashicorp/azurerm\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "id": "/subscriptions/xxx/resourceGroups/atsushi.koizumi.test01/providers/Microsoft.Network/virtualNetworks/vnet01/subnets/subnet01",
            "network_security_group_id": "/subscriptions/xxx/resourceGroups/atsushi.koizumi.test01/providers/Microsoft.Network/networkSecurityGroups/sg01",
            "subnet_id": "/subscriptions/xxx/resourceGroups/atsushi.koizumi.test01/providers/Microsoft.Network/virtualNetworks/vnet01/subnets/subnet01",
            "timeouts": null
          },
          "private": "xxx=",
          "dependencies": [
            "azurerm_network_security_group.sg01",
            "azurerm_resource_group.test01",
            "azurerm_subnet.subnet01"
          ]
        }
      ]
    }

    これから分かることは、SecurityGroup の作成において、デフォルトで設定されるオプションは、ほとんどないということです。

    ただ1点、デフォルトで security_rule が作成されていることを除いて。それをコンソールで確認してみました。

    デフォルトの security_rule

    azure-subnet-01-02

    Inbound security rules

    デフォルトで、VirtualNetwork と AzureLoadBalancer からの通信は許可されており、それ以外の通信は拒否されています。

    Outbound security rules

    デフォルトで、VirtualNetwork への通信と、Internet への通信が許可されています。

    AWS と Azure の違い - SecurityGroup -

    これまでは、AWS と Azure の違いはあまり感じていませんでしたが、このネットワークについての考え方は両者で大きく異なりました。

    Azure の SecurityGroup で Outbound security rules のデフォルト設定を見たとき、「えっ!? デフォルトで Internet への通信が許可しちゃってるんですか!?」と衝撃を覚えました。

    そうなんです。Azure ではそうなんです。

    Azureは「外部への通信は少なからず発生するものであり、セキュリティを考慮して外部通信を全部ブロックするのであればもっと他の措置が必須だよ。」という考え方が根底にあります。

    これはAWSの考え方とは逆です。面白いですね〜。私は Azure の方が好きです。簡単なので。

    とまあ、今回は以上です。次回は作成した Subnet に Virtual Machine を構築したいと思います。

  • Terraform
  • VNet
  • SecurityGroup
  • スポンサーリンク