From b7d0d3fd2cd9e68efc975a71a23a25a5bed9624c Mon Sep 17 00:00:00 2001 From: John Downs Date: Fri, 25 Nov 2022 19:28:32 +1300 Subject: [PATCH] Add quickstart --- .../front-door.tf | 73 ++++ .../images/diagram.png | Bin 0 -> 52692 bytes .../outputs.tf | 3 + .../providers.tf | 20 ++ .../readme.md | 330 ++++++++++++++++++ .../resource-group.tf | 12 + .../storage-account.tf | 24 ++ .../variables.tf | 29 ++ 8 files changed, 491 insertions(+) create mode 100644 quickstart/101-front-door-premium-storage-blobs-private-link/front-door.tf create mode 100644 quickstart/101-front-door-premium-storage-blobs-private-link/images/diagram.png create mode 100644 quickstart/101-front-door-premium-storage-blobs-private-link/outputs.tf create mode 100644 quickstart/101-front-door-premium-storage-blobs-private-link/providers.tf create mode 100644 quickstart/101-front-door-premium-storage-blobs-private-link/readme.md create mode 100644 quickstart/101-front-door-premium-storage-blobs-private-link/resource-group.tf create mode 100644 quickstart/101-front-door-premium-storage-blobs-private-link/storage-account.tf create mode 100644 quickstart/101-front-door-premium-storage-blobs-private-link/variables.tf diff --git a/quickstart/101-front-door-premium-storage-blobs-private-link/front-door.tf b/quickstart/101-front-door-premium-storage-blobs-private-link/front-door.tf new file mode 100644 index 00000000..1b475946 --- /dev/null +++ b/quickstart/101-front-door-premium-storage-blobs-private-link/front-door.tf @@ -0,0 +1,73 @@ +locals { + front_door_profile_name = "MyFrontDoor" + front_door_sku_name = "Premium_AzureFrontDoor" // Must be premium for Private Link support. + front_door_endpoint_name = "afd-${lower(random_id.front_door_endpoint_name.hex)}" + front_door_origin_group_name = "MyOriginGroup" + front_door_origin_name = "MyBlobContainerOrigin" + front_door_route_name = "MyRoute" + front_door_origin_path = "/${var.storage_account_blob_container_name}" // The path to the blob container. +} + +resource "azurerm_cdn_frontdoor_profile" "my_front_door" { + name = local.front_door_profile_name + resource_group_name = azurerm_resource_group.my_resource_group.name + sku_name = local.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_blob_container_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_storage_account.my_storage_account.primary_blob_host + http_port = 80 + https_port = 443 + origin_host_header = azurerm_storage_account.my_storage_account.primary_blob_host + priority = 1 + weight = 1000 + certificate_name_check_enabled = true + + private_link { + private_link_target_id = azurerm_storage_account.my_storage_account.id + target_type = "blob" + request_message = "Request access for Azure Front Door Private Link origin" + location = var.front_door_private_link_location + } +} + +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_blob_container_origin.id] + + supported_protocols = ["Http", "Https"] + patterns_to_match = ["/*"] + forwarding_protocol = "HttpsOnly" + link_to_default_domain = true + https_redirect_enabled = true + cdn_frontdoor_origin_path = local.front_door_origin_path +} diff --git a/quickstart/101-front-door-premium-storage-blobs-private-link/images/diagram.png b/quickstart/101-front-door-premium-storage-blobs-private-link/images/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..79c505e44cccd8a36225284cde1292fdeb6a9655 GIT binary patch literal 52692 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îsWR*D@(} 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 w1A~f~8QO9m@Wt1$opaI>h(I;Vst01(}UssI20 literal 0 HcmV?d00001 diff --git a/quickstart/101-front-door-premium-storage-blobs-private-link/outputs.tf b/quickstart/101-front-door-premium-storage-blobs-private-link/outputs.tf new file mode 100644 index 00000000..3642fe18 --- /dev/null +++ b/quickstart/101-front-door-premium-storage-blobs-private-link/outputs.tf @@ -0,0 +1,3 @@ +output "frontDoorEndpointHostName" { + value = azurerm_cdn_frontdoor_endpoint.my_endpoint.host_name +} diff --git a/quickstart/101-front-door-premium-storage-blobs-private-link/providers.tf b/quickstart/101-front-door-premium-storage-blobs-private-link/providers.tf new file mode 100644 index 00000000..c8990b6e --- /dev/null +++ b/quickstart/101-front-door-premium-storage-blobs-private-link/providers.tf @@ -0,0 +1,20 @@ +# Configure the Azure provider +terraform { + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 3.27.0" + } + + random = { + source = "hashicorp/random" + version = "~> 3.4.3" + } + } + + required_version = ">= 1.1.0" +} + +provider "azurerm" { + features {} +} diff --git a/quickstart/101-front-door-premium-storage-blobs-private-link/readme.md b/quickstart/101-front-door-premium-storage-blobs-private-link/readme.md new file mode 100644 index 00000000..78bfc359 --- /dev/null +++ b/quickstart/101-front-door-premium-storage-blobs-private-link/readme.md @@ -0,0 +1,330 @@ +# Azure Front Door Premium with blob origin and Private Link + +This template deploys an [Azure Front Door Premium profile](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/cdn_frontdoor_profile) with an Azure Storage blob container origin, using a private endpoint to access the storage account. + +## Architecture + +![Architecture diagram showing traffic flowing through Front Door to the storage account.](images/diagram.png) + +The data flows through the solution are: + +1. The client establishes a connection to Azure Front Door by using a custom domain name. The client's connection terminates at a nearby Front Door point of presence (PoP). +1. The Front Door web application firewall (WAF) scans the request. If the WAF determines the request's risk level is too high, it blocks the request and Front Door returns an HTTP 403 error response. +1. If the Front Door PoP's cache contains a valid response for this request, Front Door returns the response immediately. +1. Otherwise, the PoP sends the request to the origin storage account, wherever it is in the world, by using Microsoft's backbone network. The PoP connects to the storage account by using a separate, long-lived, TCP connection. In this scenario, Private Link is used to securely connect to the storage account. +1. The storage account sends a response to the Front Door PoP. +1. When the PoP receives the response, it stores it in its cache for subsequent requests. +1. The PoP returns the response to the client. +1. Any requests directly to the storage account through the internet are blocked by the Azure Storage firewall. + +## Resources + +| Terraform Resource Type | Description | +| - | - | +| `azurerm_resource_group` | The resource group for all the deployed resources.| +| `azurerm_cdn_frontdoor_profile` | The Front Door profile. | +| `azurerm_cdn_frontdoor_endpoint` | The Front Door endpoint. | +| `azurerm_cdn_frontdoor_origin_group` | The Front Door origin group. | +| `azurerm_cdn_frontdoor_origin` | The Front Door origin, which refers to the storage account. | +| `azurerm_cdn_frontdoor_route` | The Front Door route. | +| `azurerm_storage_account` | The Azure Storage account. | +| `azurerm_storage_container` | The blob container within the Azure Storage account. | +| `random_id` | Two random identifier generators to generate a unique Front Door endpoint resource name and storage account name. | + +## Variables + +| Name | Description | Default Value | +|-|-|-| +| `location` | The location for all the deployed resources. | `westus3` | +| `front_door_private_link_location` | The location that the Private Link connection will terminate in when connecting to the origin. This must be one of the [locations in which Private Link origins are available for Front Door](https://learn.microsoft.com/azure/frontdoor/private-link#region-availability). | `westus3` | +| `resource_group_name` | The name of the resource group. | `FrontDoor` | +| `storage_account_tier` | The tier of the storage account. | `Standard` | +| `storage_account_replication_type` | The level of replication to be configured for the storage account. | `LRS` | +| `storage_account_blob_container_name` | The name of the blob contianer. | `mycontainer` | + +## Example + +```bash +$ terraform plan -out main.tfplan + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # azurerm_cdn_frontdoor_endpoint.my_endpoint will be created + + resource "azurerm_cdn_frontdoor_endpoint" "my_endpoint" { + + cdn_frontdoor_profile_id = (known after apply) + + enabled = true + + host_name = (known after apply) + + id = (known after apply) + + name = (known after apply) + } + + # azurerm_cdn_frontdoor_origin.my_blob_container_origin will be created + + resource "azurerm_cdn_frontdoor_origin" "my_blob_container_origin" { + + cdn_frontdoor_origin_group_id = (known after apply) + + certificate_name_check_enabled = true + + enabled = true + + health_probes_enabled = (known after apply) + + host_name = (known after apply) + + http_port = 80 + + https_port = 443 + + id = (known after apply) + + name = "MyBlobContainerOrigin" + + origin_host_header = (known after apply) + + priority = 1 + + weight = 1000 + + + private_link { + + location = "westus3" + + private_link_target_id = (known after apply) + + request_message = "Request access for Azure Front Door Private Link origin" + + target_type = "blob" + } + } + + # azurerm_cdn_frontdoor_origin_group.my_origin_group will be created + + resource "azurerm_cdn_frontdoor_origin_group" "my_origin_group" { + + cdn_frontdoor_profile_id = (known after apply) + + id = (known after apply) + + name = "MyOriginGroup" + + restore_traffic_time_to_healed_or_new_endpoint_in_minutes = 10 + + session_affinity_enabled = true + + + health_probe { + + interval_in_seconds = 100 + + path = "/" + + protocol = "Https" + + request_type = "HEAD" + } + + + load_balancing { + + additional_latency_in_milliseconds = 50 + + sample_size = 4 + + successful_samples_required = 3 + } + } + + # azurerm_cdn_frontdoor_profile.my_front_door will be created + + resource "azurerm_cdn_frontdoor_profile" "my_front_door" { + + id = (known after apply) + + name = "MyFrontDoor" + + resource_group_name = "FrontDoor" + + resource_guid = (known after apply) + + response_timeout_seconds = 120 + + sku_name = "Premium_AzureFrontDoor" + } + + # azurerm_cdn_frontdoor_route.my_route will be created + + resource "azurerm_cdn_frontdoor_route" "my_route" { + + cdn_frontdoor_endpoint_id = (known after apply) + + cdn_frontdoor_origin_group_id = (known after apply) + + cdn_frontdoor_origin_ids = (known after apply) + + enabled = true + + forwarding_protocol = "HttpsOnly" + + https_redirect_enabled = true + + id = (known after apply) + + link_to_default_domain = true + + name = "MyRoute" + + patterns_to_match = [ + + "/*", + ] + + supported_protocols = [ + + "Http", + + "Https", + ] + } + + # azurerm_resource_group.my_resource_group will be created + + resource "azurerm_resource_group" "my_resource_group" { + + id = (known after apply) + + location = "westus3" + + name = "FrontDoor" + } + + # azurerm_storage_account.my_storage_account will be created + + resource "azurerm_storage_account" "my_storage_account" { + + access_tier = (known after apply) + + account_kind = "StorageV2" + + account_replication_type = "LRS" + + account_tier = "Standard" + + allow_nested_items_to_be_public = true + + cross_tenant_replication_enabled = true + + default_to_oauth_authentication = false + + enable_https_traffic_only = true + + id = (known after apply) + + infrastructure_encryption_enabled = false + + is_hns_enabled = false + + large_file_share_enabled = (known after apply) + + location = "westus3" + + min_tls_version = "TLS1_2" + + name = (known after apply) + + nfsv3_enabled = false + + primary_access_key = (sensitive value) + + primary_blob_connection_string = (sensitive value) + + primary_blob_endpoint = (known after apply) + + primary_blob_host = (known after apply) + + primary_connection_string = (sensitive value) + + primary_dfs_endpoint = (known after apply) + + primary_dfs_host = (known after apply) + + primary_file_endpoint = (known after apply) + + primary_file_host = (known after apply) + + primary_location = (known after apply) + + primary_queue_endpoint = (known after apply) + + primary_queue_host = (known after apply) + + primary_table_endpoint = (known after apply) + + primary_table_host = (known after apply) + + primary_web_endpoint = (known after apply) + + primary_web_host = (known after apply) + + public_network_access_enabled = false + + queue_encryption_key_type = "Service" + + resource_group_name = "FrontDoor" + + secondary_access_key = (sensitive value) + + secondary_blob_connection_string = (sensitive value) + + secondary_blob_endpoint = (known after apply) + + secondary_blob_host = (known after apply) + + secondary_connection_string = (sensitive value) + + secondary_dfs_endpoint = (known after apply) + + secondary_dfs_host = (known after apply) + + secondary_file_endpoint = (known after apply) + + secondary_file_host = (known after apply) + + secondary_location = (known after apply) + + secondary_queue_endpoint = (known after apply) + + secondary_queue_host = (known after apply) + + secondary_table_endpoint = (known after apply) + + secondary_table_host = (known after apply) + + secondary_web_endpoint = (known after apply) + + secondary_web_host = (known after apply) + + shared_access_key_enabled = true + + table_encryption_key_type = "Service" + + + blob_properties { + + change_feed_enabled = (known after apply) + + change_feed_retention_in_days = (known after apply) + + default_service_version = (known after apply) + + last_access_time_enabled = (known after apply) + + versioning_enabled = (known after apply) + + + container_delete_retention_policy { + + days = (known after apply) + } + + + cors_rule { + + allowed_headers = (known after apply) + + allowed_methods = (known after apply) + + allowed_origins = (known after apply) + + exposed_headers = (known after apply) + + max_age_in_seconds = (known after apply) + } + + + delete_retention_policy { + + days = (known after apply) + } + } + + + network_rules { + + bypass = (known after apply) + + default_action = "Deny" + + ip_rules = (known after apply) + + virtual_network_subnet_ids = (known after apply) + } + + + queue_properties { + + cors_rule { + + allowed_headers = (known after apply) + + allowed_methods = (known after apply) + + allowed_origins = (known after apply) + + exposed_headers = (known after apply) + + max_age_in_seconds = (known after apply) + } + + + hour_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + + + logging { + + delete = (known after apply) + + read = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + + write = (known after apply) + } + + + minute_metrics { + + enabled = (known after apply) + + include_apis = (known after apply) + + retention_policy_days = (known after apply) + + version = (known after apply) + } + } + + + routing { + + choice = (known after apply) + + publish_internet_endpoints = (known after apply) + + publish_microsoft_endpoints = (known after apply) + } + + + share_properties { + + cors_rule { + + allowed_headers = (known after apply) + + allowed_methods = (known after apply) + + allowed_origins = (known after apply) + + exposed_headers = (known after apply) + + max_age_in_seconds = (known after apply) + } + + + retention_policy { + + days = (known after apply) + } + + + smb { + + authentication_types = (known after apply) + + channel_encryption_type = (known after apply) + + kerberos_ticket_encryption_type = (known after apply) + + multichannel_enabled = (known after apply) + + versions = (known after apply) + } + } + } + + # azurerm_storage_container.my_storage_container will be created + + resource "azurerm_storage_container" "my_storage_container" { + + container_access_type = "blob" + + has_immutability_policy = (known after apply) + + has_legal_hold = (known after apply) + + id = (known after apply) + + metadata = (known after apply) + + name = "mycontainer" + + resource_manager_id = (known after apply) + + storage_account_name = (known after apply) + } + + # random_id.front_door_endpoint_name will be created + + resource "random_id" "front_door_endpoint_name" { + + b64_std = (known after apply) + + b64_url = (known after apply) + + byte_length = 8 + + dec = (known after apply) + + hex = (known after apply) + + id = (known after apply) + } + + # random_id.storage_account_name will be created + + resource "random_id" "storage_account_name" { + + b64_std = (known after apply) + + b64_url = (known after apply) + + byte_length = 8 + + dec = (known after apply) + + hex = (known after apply) + + id = (known after apply) + } + +Plan: 10 to add, 0 to change, 0 to destroy. + +Changes to Outputs: + + frontDoorEndpointHostName = (known after apply) +``` diff --git a/quickstart/101-front-door-premium-storage-blobs-private-link/resource-group.tf b/quickstart/101-front-door-premium-storage-blobs-private-link/resource-group.tf new file mode 100644 index 00000000..0a52e7a6 --- /dev/null +++ b/quickstart/101-front-door-premium-storage-blobs-private-link/resource-group.tf @@ -0,0 +1,12 @@ +resource "azurerm_resource_group" "my_resource_group" { + name = var.resource_group_name + location = var.location +} + +resource "random_id" "storage_account_name" { + byte_length = 8 +} + +resource "random_id" "front_door_endpoint_name" { + byte_length = 8 +} diff --git a/quickstart/101-front-door-premium-storage-blobs-private-link/storage-account.tf b/quickstart/101-front-door-premium-storage-blobs-private-link/storage-account.tf new file mode 100644 index 00000000..ac9d87fb --- /dev/null +++ b/quickstart/101-front-door-premium-storage-blobs-private-link/storage-account.tf @@ -0,0 +1,24 @@ +locals { + storage_account_name = "stor${lower(random_id.storage_account_name.hex)}" +} +resource "azurerm_storage_account" "my_storage_account" { + name = local.storage_account_name + resource_group_name = azurerm_resource_group.my_resource_group.name + location = var.location + account_kind = "StorageV2" + account_tier = var.storage_account_tier + account_replication_type = var.storage_account_replication_type + enable_https_traffic_only = true + public_network_access_enabled = false + min_tls_version = "TLS1_2" + + network_rules { + default_action = "Deny" + } +} + +resource "azurerm_storage_container" "my_storage_container" { + name = var.storage_account_blob_container_name + storage_account_name = azurerm_storage_account.my_storage_account.name + container_access_type = "blob" +} diff --git a/quickstart/101-front-door-premium-storage-blobs-private-link/variables.tf b/quickstart/101-front-door-premium-storage-blobs-private-link/variables.tf new file mode 100644 index 00000000..60677e6c --- /dev/null +++ b/quickstart/101-front-door-premium-storage-blobs-private-link/variables.tf @@ -0,0 +1,29 @@ +variable "location" { + type = string + default = "westus3" +} + +variable "front_door_private_link_location" { + type = string + default = "westus3" +} + +variable "resource_group_name" { + type = string + default = "FrontDoor" +} + +variable "storage_account_tier" { + type = string + default = "Standard" +} + +variable "storage_account_replication_type" { + type = string + default = "LRS" +} + +variable "storage_account_blob_container_name" { + type = string + default = "mycontainer" +} \ No newline at end of file