Salta ai contenuti

Distribuzione

Tutti i file Terraform si trovano nella directory terraform/. Clonare il repository e distribuire direttamente:

Terminal window
git clone https://github.com/f5-sales-demo/cdn-simulator.git
cd cdn-simulator/terraform
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars with your Azure subscription ID and origin server

La directory terraform contiene 9 file che seguono lo standard Risorse demo:

  • versions.tf — Vincoli di versione per Terraform e provider (azurerm ~> 4.0, azuread ~> 3.0)
  • providers.tf — Configurazione dei provider Azure RM e Azure AD
  • data.tf — Origini dati Azure AD per la risoluzione automatica del deployer
  • locals.tf — Risoluzione del deployer, denominazione delle risorse Azure Cloud Adoption Framework, tag standard
  • main.tf — Gruppo di risorse (denominato rg-cdn-simulator-{environment}-{deployer})
  • variables.tf — Tutte le variabili di input (3 obbligatorie, 8 facoltative)
  • network.tf — VNet (10.100.0.0/16), subnet, IP pubblico, NSG (porte 22/80/443), NIC
  • vm.tf — VM Ubuntu 24.04 con cloud-init tramite templatefile()
  • outputs.tf — 17 output (15 standard + 2 specifici per componente)

variables.tf definisce 11 variabili di input organizzate nelle sezioni Generale, Calcolo e Specifiche per Componente. L’identificatore deployer viene risolto automaticamente dall’account Azure AD — è sufficiente impostare subscription_id, origin_server e origin_host:

# ---------------------------------------------------------
# General
# ---------------------------------------------------------
variable "subscription_id" {
description = "Azure subscription ID"
type = string
}
variable "deployer" {
description = "Override for deployer identifier (auto-resolved from Azure AD if empty). Required for service principal or managed identity authentication."
type = string
default = ""
}
variable "location" {
description = "Azure region for all resources"
type = string
default = "eastus2"
}
variable "environment" {
description = "Environment label used in resource group naming and tags"
type = string
default = "lab"
}
variable "tags" {
description = "Additional tags merged with standard tags (component, environment, deployer, managed_by)"
type = map(string)
default = {}
}
# ---------------------------------------------------------
# Compute
# ---------------------------------------------------------
variable "vm_size" {
description = "Azure VM size — F-series compute-optimized recommended (F4s_v2 for lab, F16s_v2 for load testing, F32s_v2 for production)"
type = string
default = "Standard_F4s_v2"
}
variable "admin_username" {
description = "SSH admin username for the VM"
type = string
default = "azureuser"
}
variable "ssh_public_key_path" {
description = "Path to the SSH public key file"
type = string
default = "~/.ssh/id_ed25519.pub"
}
variable "disk_size_gb" {
description = "OS disk size in GB"
type = number
default = 30
}
# ---------------------------------------------------------
# Component-Specific
# ---------------------------------------------------------
variable "origin_server" {
description = "Origin server URL for cache miss forwarding (e.g., an HTTPS VIP or a direct HTTP origin IP)"
type = string
}
variable "origin_host" {
description = "Origin server host:port for NGINX upstream (no scheme). Use IP:443 for HTTPS or IP:80 for HTTP."
type = string
}

network.tf crea VNet, subnet, IP pubblico, NSG (porte 22/80/443) e NIC:

resource "azurerm_virtual_network" "main" {
name = local.name.virtual_network
address_space = ["10.100.0.0/16"]
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
tags = azurerm_resource_group.main.tags
}
resource "azurerm_subnet" "main" {
name = local.name.subnet
resource_group_name = azurerm_resource_group.main.name
virtual_network_name = azurerm_virtual_network.main.name
address_prefixes = ["10.100.1.0/24"]
}
resource "azurerm_public_ip" "main" {
name = local.name.public_ip
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
allocation_method = "Static"
sku = "Standard"
tags = azurerm_resource_group.main.tags
}
resource "azurerm_network_security_group" "main" {
name = local.name.nsg
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
security_rule {
name = "AllowHTTP"
priority = 100
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "AllowHTTPS"
priority = 110
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "443"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "AllowSSH"
priority = 120
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "*"
destination_address_prefix = "*"
}
tags = azurerm_resource_group.main.tags
}
resource "azurerm_network_interface" "main" {
name = local.name.network_interface
location = azurerm_resource_group.main.location
resource_group_name = azurerm_resource_group.main.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.main.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.main.id
}
tags = azurerm_resource_group.main.tags
}
resource "azurerm_network_interface_security_group_association" "main" {
network_interface_id = azurerm_network_interface.main.id
network_security_group_id = azurerm_network_security_group.main.id
}

vm.tf crea la VM Ubuntu 24.04. Il percorso della chiave pubblica SSH viene espanso tramite pathexpand() per gestire ~. Il template cloud-init riceve le variabili origin_server e origin_host:

resource "azurerm_linux_virtual_machine" "main" {
name = local.name.virtual_machine
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
size = var.vm_size
admin_username = var.admin_username
disable_password_authentication = true
admin_ssh_key {
username = var.admin_username
public_key = file(pathexpand(var.ssh_public_key_path))
}
network_interface_ids = [azurerm_network_interface.main.id]
os_disk {
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
disk_size_gb = var.disk_size_gb
}
source_image_reference {
publisher = "Canonical"
offer = "ubuntu-24_04-lts"
sku = "server"
version = "latest"
}
custom_data = base64encode(templatefile("${path.module}/cloud-init.yaml", {
origin_server = var.origin_server
origin_host = var.origin_host
}))
boot_diagnostics {}
tags = azurerm_resource_group.main.tags
}

cloud-init.yaml esegue il provisioning della VM con ottimizzazione del kernel, limiti systemd, NGINX con configurazione ottimizzata per le prestazioni, zona chiavi cache da 128 MB, pool keepalive upstream, compressione gzip e oltre 67 intestazioni di vendor CDN. Una libreria helper condivisa (/usr/local/lib/cloud-init-helpers.sh) fornisce logica di retry e registrazione dei progressi in /var/log/cloud-init-progress.log.

Il cloud-init utilizza variabili template Terraform: ${origin_server} e ${origin_host} per la configurazione upstream. Le variabili NGINX come ${request_id} vengono escape come $${request_id} nel templatefile di Terraform.

#cloud-config
package_update: true
package_upgrade: true
bootcmd:
- mkdir -p /var/cache/nginx/cdn
- chown www-data:www-data /var/cache/nginx/cdn 2>/dev/null || true
packages:
- nginx
- irqbalance
write_files:
# ── Kernel tuning ──────────────────────────────────────────────
- path: /etc/sysctl.d/99-cdn-tuning.conf
content: |
net.core.somaxconn = 262144
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65535
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_max_tw_buckets = 8000000
fs.file-max = 8388608
vm.swappiness = 10
# ── Systemd override for NGINX file descriptor limits ──────────
- path: /etc/systemd/system/nginx.service.d/override.conf
content: |
[Service]
LimitNOFILE=262144
LimitNPROC=262144
# ── OS-level limits for www-data (NGINX worker user) ───────────
- path: /etc/security/limits.d/99-nginx.conf
content: |
www-data soft nofile 262144
www-data hard nofile 262144
# ── NGINX main config ──────────────────────────────────────────
- path: /etc/nginx/nginx.conf
content: |
user www-data;
worker_processes auto;
worker_rlimit_nofile 262144;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
use epoll;
worker_connections 32768;
multi_accept on;
accept_mutex off;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
server_tokens off;
client_max_body_size 50m;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format cdn '$remote_addr [$time_local] "$request" $status $body_bytes_sent $upstream_cache_status $request_time';
access_log /var/log/nginx/access.log cdn;
keepalive_timeout 65;
keepalive_requests 100000;
proxy_buffering on;
proxy_buffer_size 16k;
proxy_buffers 128 16k;
proxy_busy_buffers_size 256k;
gzip on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_vary on;
gzip_proxied any;
gzip_types text/plain text/css text/javascript text/xml
application/json application/javascript application/xml
application/xml+rss application/atom+xml
application/ld+json application/manifest+json
image/svg+xml;
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
include /etc/nginx/conf.d/*.conf;
}
# ── CDN edge proxy config ──────────────────────────────────────
- path: /etc/nginx/conf.d/cdn-edge.conf
content: |
proxy_cache_path /var/cache/nginx/cdn
levels=1:2
keys_zone=cdn_cache:128m
max_size=25g
inactive=24h
use_temp_path=off;
upstream origin_backend {
server ${origin_host};
keepalive 1024;
keepalive_timeout 60s;
keepalive_requests 100000;
}
map $request_id $cdn_ray_id {
default "$${request_id}-SJC";
}
map $request_id $cdn_azure_ref {
default "0$${request_id}AAAAAA";
}
map $request_id $cdn_amz_cf_id {
default "E1$${request_id}==";
}
map $http_user_agent $is_mobile {
default "false";
"~*Mobile|Android|iPhone|iPod|BlackBerry|Opera Mini|IEMobile" "true";
}
map $http_user_agent $is_tablet {
default "false";
"~*iPad|Android(?!.*Mobile)|Tablet|Kindle|PlayBook" "true";
}
map $http_user_agent $is_desktop {
default "true";
"~*Mobile|Android|iPhone|iPod|BlackBerry|Opera Mini|IEMobile|iPad|Tablet|Kindle|PlayBook" "false";
}
server {
listen 80 reuseport;
server_name _;
location /health {
access_log off;
return 200 '{"status":"healthy","component":"cdn-edge","engine":"nginx","vendor_profiles":["akamai","cloudflare","cloudfront","fastly","azure-front-door"]}';
add_header Content-Type application/json;
}
location / {
proxy_pass https://origin_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_ssl_server_name on;
proxy_ssl_name csd.bankexample.com;
proxy_ssl_verify off;
proxy_read_timeout 180s;
proxy_connect_timeout 10s;
proxy_send_timeout 15s;
# Standard
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Via "1.1 cdn-simulator";
proxy_set_header Forwarded "for=$remote_addr;proto=$scheme;host=$host";
proxy_set_header CDN-Loop "cdn-simulator";
# Akamai
proxy_set_header True-Client-IP $remote_addr;
proxy_set_header X-Akamai-Edgescape "georegion=263,country_code=US,region_code=CA,city=SANJOSE,dma=807,pmsa=7400,msa=7362,areacode=408,county=SANTACLARA,fips=06085,lat=37.3353,long=-121.8938,timezone=PST,zip=95113-95196,continent=NA,throughput=vhigh,bw=5000,network=att.net,asnum=7018,network_type=broadband";
proxy_set_header X-Akamai-Device-Characteristics "brand_name=Generic;model_name=Browser;is_mobile=$is_mobile;is_tablet=$is_tablet;is_wireless_device=$is_mobile;device_os=Linux;device_os_version=1.0;resolution_width=1920;resolution_height=1080";
proxy_set_header X-Akamai-Request-ID $request_id;
# Cloudflare
proxy_set_header CF-Connecting-IP $remote_addr;
proxy_set_header CF-IPCountry "US";
proxy_set_header cf-ipcity "San Jose";
proxy_set_header cf-ipcontinent "NA";
proxy_set_header cf-iplatitude "37.3353";
proxy_set_header cf-iplongitude "-121.8938";
proxy_set_header cf-region "California";
proxy_set_header cf-region-code "CA";
proxy_set_header cf-metro-code "807";
proxy_set_header cf-postal-code "95113";
proxy_set_header cf-timezone "America/Los_Angeles";
proxy_set_header Cf-Ray $cdn_ray_id;
proxy_set_header CF-Visitor '{"scheme":"https"}';
proxy_set_header cf-bot-score "85";
proxy_set_header cf-verified-bot "false";
proxy_set_header cf-ja3-hash "e7d705a3286e19ea42f587b344ee6865";
proxy_set_header cf-ja4 "t13d1516h2_8daaf6152771_b0da82dd1658";
# CloudFront
proxy_set_header CloudFront-Viewer-Address "$remote_addr:$remote_port";
proxy_set_header CloudFront-Viewer-Country "US";
proxy_set_header CloudFront-Viewer-Country-Name "United States";
proxy_set_header CloudFront-Viewer-Country-Region "CA";
proxy_set_header CloudFront-Viewer-Country-Region-Name "California";
proxy_set_header CloudFront-Viewer-City "San Jose";
proxy_set_header CloudFront-Viewer-Postal-Code "95113";
proxy_set_header CloudFront-Viewer-Latitude "37.33530";
proxy_set_header CloudFront-Viewer-Longitude "-121.89300";
proxy_set_header CloudFront-Viewer-Time-Zone "America/Los_Angeles";
proxy_set_header CloudFront-Viewer-Metro-Code "807";
proxy_set_header CloudFront-Viewer-ASN "7018";
proxy_set_header CloudFront-Viewer-Http-Version "2.0";
proxy_set_header CloudFront-Forwarded-Proto "https";
proxy_set_header CloudFront-Viewer-TLS "TLSv1.3:TLS_AES_128_GCM_SHA256:sessionResumed";
proxy_set_header CloudFront-Viewer-JA3-Fingerprint "e7d705a3286e19ea42f587b344ee6865";
proxy_set_header CloudFront-Is-Desktop-Viewer $is_desktop;
proxy_set_header CloudFront-Is-Mobile-Viewer $is_mobile;
proxy_set_header CloudFront-Is-Tablet-Viewer $is_tablet;
proxy_set_header CloudFront-Is-SmartTV-Viewer "false";
proxy_set_header X-Amz-Cf-Id $cdn_amz_cf_id;
# Fastly
proxy_set_header Fastly-Client-IP $remote_addr;
proxy_set_header Fastly-SSL "1";
proxy_set_header Fastly-Client "1";
proxy_set_header Fastly-FF "cache-sjc3120-SJC";
proxy_set_header X-Geo-Country-Code "US";
proxy_set_header X-Geo-Country-Code3 "USA";
proxy_set_header X-Geo-Country-Name "United States";
proxy_set_header X-Geo-City "San Jose";
proxy_set_header X-Geo-Region "CA";
proxy_set_header X-Geo-Continent-Code "NA";
proxy_set_header X-Geo-Latitude "37.3353";
proxy_set_header X-Geo-Longitude "-121.8938";
proxy_set_header X-Geo-Postal-Code "95113";
proxy_set_header X-Geo-Metro-Code "807";
proxy_set_header X-Geo-ASN "7018";
proxy_set_header X-Geo-Conn-Speed "broadband";
proxy_set_header X-Geo-Conn-Type "wired";
# Azure Front Door
proxy_set_header X-Azure-ClientIP $remote_addr;
proxy_set_header X-Azure-SocketIP $remote_addr;
proxy_set_header X-Azure-Ref $cdn_azure_ref;
proxy_set_header X-Azure-FDID "a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1";
proxy_set_header X-Azure-RequestChain "hops=1";
# Cache
proxy_set_header Host csd.bankexample.com;
proxy_cache cdn_cache;
proxy_cache_methods GET HEAD;
proxy_cache_valid 200 301 302 4h;
proxy_cache_valid 404 1m;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_lock on;
proxy_cache_lock_age 3s;
proxy_cache_lock_timeout 3s;
proxy_cache_background_update on;
proxy_cache_use_stale updating error timeout http_500 http_502 http_503 http_504;
proxy_ignore_headers Set-Cookie Cache-Control Expires Vary;
proxy_hide_header X-Cache-Status;
proxy_hide_header Vary;
add_header X-Cache-Status $upstream_cache_status always;
add_header X-CDN-Edge "cdn-simulator" always;
add_header X-CDN-POP "SJC" always;
add_header X-Served-By "cache-sjc3120-SJC" always;
add_header X-Request-ID $request_id always;
}
}
- path: /etc/nginx/conf.d/default.conf
content: ""
- path: /usr/local/lib/cloud-init-helpers.sh
permissions: "0644"
content: |
#!/bin/sh
PROGRESS_LOG="/var/log/cloud-init-progress.log"
log_phase() {
_phase="$1"; shift
_msg="$${*:-started}"
_ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
printf '[%s] [%s] %s\n' "$_ts" "$_phase" "$_msg" | tee -a "$PROGRESS_LOG" >&2
}
retry_cmd() {
_max="$1"; _base="$2"; shift 2
_attempt=1
while [ "$_attempt" -le "$_max" ]; do
if "$@"; then return 0; fi
if [ "$_attempt" -lt "$_max" ]; then
_wait=$(( _base * _attempt ))
log_phase "retry" "attempt $_attempt/$_max failed ($1) — retrying in $${_wait}s"
sleep "$_wait"
fi
_attempt=$(( _attempt + 1 ))
done
log_phase "retry" "FAILED after $_max attempts: $1"
return 1
}
runcmd:
- |
. /usr/local/lib/cloud-init-helpers.sh
log_phase "init" "cdn-simulator provisioning started"
- sysctl -p /etc/sysctl.d/99-cdn-tuning.conf || exit 1
- systemctl daemon-reload
- rm -f /etc/nginx/sites-enabled/default
- chown -R www-data:www-data /var/cache/nginx/cdn
- nginx -t || exit 1
- systemctl enable nginx
- systemctl restart nginx
- systemctl enable irqbalance
- systemctl start irqbalance
- |
. /usr/local/lib/cloud-init-helpers.sh
NIC=$(ip -o link show | awk -F': ' '/state UP/{print $2}' | grep -v lo | head -1)
if [ -n "$NIC" ]; then
log_phase "nic" "configuring RPS/RFS for $NIC"
echo 65536 > /proc/sys/net/core/rps_sock_flow_entries 2>/dev/null || true
for i in $(seq 0 $(($(nproc)-1))); do
echo 8192 > /sys/class/net/$NIC/queues/rx-$i/rps_flow_cnt 2>/dev/null || true
done
else
log_phase "nic" "no active NIC found — skipping RPS/RFS"
fi
- |
. /usr/local/lib/cloud-init-helpers.sh
log_phase "complete" "cdn-simulator provisioned"

outputs.tf espone 17 output seguendo lo standard Risorse demo — 15 output standard condivisi da tutte le risorse demo (deployer, public_ip, private_ip, ssh_command, resource_group_name, vm_name, nsg_name, vnet_name, subnet_id, component, environment, resource_group_id, vm_id, nsg_id, location) più 2 output specifici per componente (edge_url, health_check_url):

# ---------------------------------------------------------
# Standard Outputs (present in every demo resource)
# ---------------------------------------------------------
output "deployer" {
description = "Resolved deployer identifier"
value = local.deployer
}
output "resource_group_name" {
description = "Name of the resource group"
value = azurerm_resource_group.main.name
}
output "resource_group_id" {
description = "Resource ID of the resource group"
value = azurerm_resource_group.main.id
}
output "location" {
description = "Azure region"
value = azurerm_resource_group.main.location
}
output "public_ip" {
description = "Public IP address of the VM"
value = azurerm_public_ip.main.ip_address
}
output "private_ip" {
description = "Private IP address of the VM"
value = azurerm_network_interface.main.private_ip_address
}
output "ssh_command" {
description = "SSH command to connect to the VM"
value = "ssh ${var.admin_username}@${azurerm_public_ip.main.ip_address}"
}
output "vm_name" {
description = "Name of the virtual machine"
value = azurerm_linux_virtual_machine.main.name
}
output "vm_id" {
description = "Resource ID of the virtual machine"
value = azurerm_linux_virtual_machine.main.id
}
output "nsg_name" {
description = "Name of the network security group"
value = azurerm_network_security_group.main.name
}
output "nsg_id" {
description = "Resource ID of the network security group"
value = azurerm_network_security_group.main.id
}
output "vnet_name" {
description = "Name of the virtual network"
value = azurerm_virtual_network.main.name
}
output "subnet_id" {
description = "Resource ID of the subnet"
value = azurerm_subnet.main.id
}
output "component" {
description = "Component name"
value = local.component
}
output "environment" {
description = "Environment label"
value = var.environment
}
# ---------------------------------------------------------
# Component-Specific Outputs
# ---------------------------------------------------------
output "edge_url" {
description = "HTTP URL of the CDN edge node"
value = "http://${azurerm_public_ip.main.ip_address}"
}
output "health_check_url" {
description = "Health check endpoint"
value = "http://${azurerm_public_ip.main.ip_address}/health"
}

Copiare terraform.tfvars.example in terraform.tfvars e inserire i propri valori. Il file .gitignore esclude terraform.tfvars per evitare il commit delle credenziali:

# Copy this file to terraform.tfvars and fill in your values.
# terraform.tfvars is gitignored — never commit real credentials.
# --- Required ---
subscription_id = "00000000-0000-0000-0000-000000000000"
origin_server = "http://your-origin-ip"
origin_host = "your-origin-ip:80"
# --- Optional overrides (defaults shown) ---
# deployer = "" # auto-resolved from Azure AD
# location = "eastus2"
# environment = "lab"
# vm_size = "Standard_F4s_v2"
# disk_size_gb = 30
# admin_username = "azureuser"
# ssh_public_key_path = "~/.ssh/id_ed25519.pub"
# tags = {}
Terminal window
# Initialize Terraform
terraform init
# Review the plan
terraform plan
# Apply
terraform apply

Terraform restituisce l’IP pubblico, il comando SSH e l’URL edge al termine della distribuzione.

Le VM F-series ottimizzate per il calcolo sono consigliate per questo carico di lavoro NGINX proxy vincolato alla CPU. Il valore predefinito Standard_F4s_v2 (4 vCPU, 8 GiB) è adatto per laboratori e demo. Sovrascrivere la variabile vm_size per scenari di test di carico o benchmarking in produzione. L’ottimizzazione del kernel cloud-init e la configurazione NGINX si adattano automaticamente al numero di vCPU (worker_processes auto).

Al termine di terraform apply, attendere 2-3 minuti affinché cloud-init completi l’installazione e la configurazione di NGINX. Verificare l’endpoint di salute:

Terminal window
curl -s "http://$(terraform output -raw public_ip)/health" | jq .

Risposta attesa:

{
"status": "healthy",
"component": "cdn-edge",
"engine": "nginx",
"vendor_profiles": [
"akamai",
"cloudflare",
"cloudfront",
"fastly",
"azure-front-door"
]
}

Il simulatore CDN richiede un server di origine distribuito. Utilizzare gli output Terraform del server di origine per popolare le variabili richieste:

Terminal window
cd ../origin-server/terraform
origin_ip=$(terraform output -raw public_ip)
cd ../../cdn-simulator/terraform
cat > terraform.tfvars <<EOF
subscription_id = "your-subscription-id"
origin_server = "http://${origin_ip}"
origin_host = "${origin_ip}:80"
EOF
Variabile obbligatoriaOrigineFormato
origin_serverOutput public_ip del server di originehttp://<ip> (includere lo schema)
origin_hostOutput public_ip del server di origine<ip>:80 (senza schema, includere la porta)

Procedere con Configurazione NGINX per le opzioni di personalizzazione o con Verifica per il test della cache.