クイックスタート: Terraform を使用して Front Door Standard/Premium プロファイルを作成する

このクイックスタートでは、Terraform を使用して Front Door プロファイルを作成し、Web エンドポイントの高可用性を設定する方法を説明します。

Note

Web ワークロードの場合は、新たな DDoS 攻撃から保護するために Azure DDoS 保護Web アプリケーション ファイアウォールを利用することを強くお勧めします。 もう 1 つのオプションは、Web アプリケーション ファイアウォールと共に Azure Front Door を使用することです。 Azure Front Door は、ネットワーク レベルの DDoS 攻撃に対するプラットフォーム レベルの保護を提供します。 詳細については、Azure サービスのセキュリティ ベースラインに関するページを参照してください。

この記事では、次のことについて説明します。

前提条件

Terraform コードを実装する

注意

この記事のサンプル コードは、Azure Terraform GitHub リポジトリにあります。 Terraform の現在および以前のバージョンのテスト結果を含むログ ファイルを表示できます。

Terraform を使用して Azure リソースを管理する方法を示すその他の記事とサンプル コードを参照してください

  1. サンプルの Terraform コードをテストするディレクトリを作成し、それを現在のディレクトリにします。

  2. providers.tf という名前のファイルを作成し、次のコードを挿入します。

    terraform {
      required_version = ">=1.0"
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    provider "azurerm" {
      features {}
    }
    
  3. main.tf という名前のファイルを作成し、次のコードを挿入します。

    resource "random_pet" "rg-name" {
      prefix = var.resource_group_name_prefix
    }
    
    resource "azurerm_resource_group" "rg" {
      name     = random_pet.rg-name.id
      location = var.resource_group_location
    }
    
    resource "random_id" "front_door_endpoint_name" {
      byte_length = 8
    }
    
    locals {
      front_door_profile_name      = "MyFrontDoor"
      front_door_endpoint_name     = "afd-${lower(random_id.front_door_endpoint_name.hex)}"
      front_door_origin_group_name = "MyOriginGroup"
      front_door_origin_name       = "MyAppServiceOrigin"
      front_door_route_name        = "MyRoute"
    }
    
    resource "azurerm_cdn_frontdoor_profile" "my_front_door" {
      name                = local.front_door_profile_name
      resource_group_name = azurerm_resource_group.rg.name
      sku_name            = var.front_door_sku_name
    }
    
    resource "azurerm_cdn_frontdoor_endpoint" "my_endpoint" {
      name                     = local.front_door_endpoint_name
      cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.my_front_door.id
    }
    
    resource "azurerm_cdn_frontdoor_origin_group" "my_origin_group" {
      name                     = local.front_door_origin_group_name
      cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.my_front_door.id
      session_affinity_enabled = true
    
      load_balancing {
        sample_size                 = 4
        successful_samples_required = 3
      }
    
      health_probe {
        path                = "/"
        request_type        = "HEAD"
        protocol            = "Https"
        interval_in_seconds = 100
      }
    }
    
    resource "azurerm_cdn_frontdoor_origin" "my_app_service_origin" {
      name                          = local.front_door_origin_name
      cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.my_origin_group.id
    
      enabled                        = true
      host_name                      = azurerm_windows_web_app.app.default_hostname
      http_port                      = 80
      https_port                     = 443
      origin_host_header             = azurerm_windows_web_app.app.default_hostname
      priority                       = 1
      weight                         = 1000
      certificate_name_check_enabled = true
    }
    
    resource "azurerm_cdn_frontdoor_route" "my_route" {
      name                          = local.front_door_route_name
      cdn_frontdoor_endpoint_id     = azurerm_cdn_frontdoor_endpoint.my_endpoint.id
      cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.my_origin_group.id
      cdn_frontdoor_origin_ids      = [azurerm_cdn_frontdoor_origin.my_app_service_origin.id]
    
      supported_protocols    = ["Http", "Https"]
      patterns_to_match      = ["/*"]
      forwarding_protocol    = "HttpsOnly"
      link_to_default_domain = true
      https_redirect_enabled = true
    }
    
  4. app-service.tf という名前のファイルを作成し、次のコードを挿入します。

    resource "random_id" "app_name" {
      byte_length = 8
    }
    
    locals {
      app_name              = "myapp-${lower(random_id.app_name.hex)}"
      app_service_plan_name = "AppServicePlan"
    }
    
    resource "azurerm_service_plan" "app_service_plan" {
      name                = local.app_service_plan_name
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    
      sku_name     = var.app_service_plan_sku_name
      os_type      = "Windows"
      worker_count = var.app_service_plan_capacity
    }
    
    resource "azurerm_windows_web_app" "app" {
      name                = local.app_name
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      service_plan_id     = azurerm_service_plan.app_service_plan.id
    
      https_only = true
    
      site_config {
        ftps_state          = "Disabled"
        minimum_tls_version = "1.2"
        ip_restriction {
          service_tag               = "AzureFrontDoor.Backend"
          ip_address                = null
          virtual_network_subnet_id = null
          action                    = "Allow"
          priority                  = 100
          headers {
            x_azure_fdid      = [azurerm_cdn_frontdoor_profile.my_front_door.resource_guid]
            x_fd_health_probe = []
            x_forwarded_for   = []
            x_forwarded_host  = []
          }
          name = "Allow traffic from Front Door"
        }
      }
    }
    
  5. variables.tf という名前のファイルを作成し、次のコードを挿入します。

    variable "resource_group_location" {
      type        = string
      description = "Location for all resources."
      default     = "eastus"
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
      default     = "rg"
    }
    
    variable "app_service_plan_sku_name" {
      type        = string
      description = "The SKU for the plan. Possible values include: B1, B2, B3, D1, F1, I1, I2, I3, I1v2, I2v2, I3v2, I4v2, I5v2, I6v2, P1v2, P2v2, P3v2, P0v3, P1v3, P2v3, P3v3, P1mv3, P2mv3, P3mv3, P4mv3, P5mv3, S1, S2, S3, SHARED, EP1, EP2, EP3, WS1, WS2, WS3, Y1."
      default     = "S1"
      validation {
        condition     = contains(["B1", "B2", "B3", "D1", "F1", "I1", "I2", "I3", "I1v2", "I2v2", "I3v2", "I4v2", "I5v2", "I6v2", "P1v2", "P2v2", "P3v2", "P0v3", "P1v3", "P2v3", "P3v3", "P1mv3", "P2mv3", "P3mv3", "P4mv3", "P5mv3", "S1", "S2", "S3", "SHARED", "EP1", "EP2", "EP3", "WS1", "WS2", "WS3", "Y1"], var.app_service_plan_sku_name)
        error_message = "The SKU value must be one of the following: B1, B2, B3, D1, F1, I1, I2, I3, I1v2, I2v2, I3v2, I4v2, I5v2, I6v2, P1v2, P2v2, P3v2, P0v3, P1v3, P2v3, P3v3, P1mv3, P2mv3, P3mv3, P4mv3, P5mv3, S1, S2, S3, SHARED, EP1, EP2, EP3, WS1, WS2, WS3, Y1."
      }
    }
    
    variable "app_service_plan_capacity" {
      type        = number
      description = "The number of Workers (instances) to be allocated."
      default     = 1
    }
    
    variable "front_door_sku_name" {
      type        = string
      description = "The SKU for the Front Door profile. Possible values include: Standard_AzureFrontDoor, Premium_AzureFrontDoor"
      default     = "Standard_AzureFrontDoor"
      validation {
        condition     = contains(["Standard_AzureFrontDoor", "Premium_AzureFrontDoor"], var.front_door_sku_name)
        error_message = "The SKU value must be one of the following: Standard_AzureFrontDoor, Premium_AzureFrontDoor."
      }
    }
    
  6. outputs.tf という名前のファイルを作成し、次のコードを挿入します。

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    
    output "frontDoorEndpointHostName" {
      value = azurerm_cdn_frontdoor_endpoint.my_endpoint.host_name
    }
    

Terraform を初期化する

terraform init を実行して、Terraform のデプロイを初期化します。 このコマンドによって、Azure リソースを管理するために必要な Azure プロバイダーがダウンロードされます。

terraform init -upgrade

重要なポイント:

  • -upgrade パラメーターは、必要なプロバイダー プラグインを、構成のバージョン制約に準拠する最新バージョンにアップグレードします。

Terraform 実行プランを作成する

terraform plan を実行して、実行プランを作成します。

terraform plan -out main.tfplan

重要なポイント:

  • terraform plan コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認できます。
  • 省略可能な -out パラメーターを使用すると、プランの出力ファイルを指定できます。 -out パラメーターを使用すると、レビューしたプランが適用内容とまったく同じであることが確実になります。

Terraform 実行プランを適用する

terraform apply を実行して、クラウド インフラストラクチャに実行プランを適用します。

terraform apply main.tfplan

重要なポイント:

  • terraform apply コマンドの例は、以前に terraform plan -out main.tfplan が実行されたことを前提としています。
  • -out パラメーターに別のファイル名を指定した場合は、terraform apply の呼び出しで同じファイル名を使用します。
  • -out パラメーターを使用しなかった場合は、パラメーターを指定せずに terraform apply を呼び出します。

結果を確認する

  1. Front Door エンドポイントを取得する:

    terraform output -raw frontDoorEndpointHostName
    
  2. エンドポイントをブラウザーに貼り付けます。

    エンドポイントへの正常な接続のスクリーンショット。

リソースをクリーンアップする

Terraform を使用して作成したリソースが不要になった場合は、次の手順を実行します。

  1. terraform plan を実行して、destroy フラグを指定します。

    terraform plan -destroy -out main.destroy.tfplan
    

    重要なポイント:

    • terraform plan コマンドは、実行プランを作成しますが、実行はしません。 代わりに、構成ファイルに指定された構成を作成するために必要なアクションを決定します。 このパターンを使用すると、実際のリソースに変更を加える前に、実行プランが自分の想定と一致しているかどうかを確認できます。
    • 省略可能な -out パラメーターを使用すると、プランの出力ファイルを指定できます。 -out パラメーターを使用すると、レビューしたプランが適用内容とまったく同じであることが確実になります。
  2. terraform apply を実行して、実行プランを適用します。

    terraform apply main.destroy.tfplan
    

Azure での Terraform のトラブルシューティング

Azure で Terraform を使用する場合の一般的な問題のトラブルシューティング

次のステップ