इसे छोड़कर कंटेंट पर जाएं

तैनात करें

सभी Terraform फ़ाइलें terraform/ निर्देशिका में हैं। रिपॉज़िटरी क्लोन करें और सीधे तैनात करें:

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

Terraform कॉन्फ़िगरेशन

Section titled “Terraform कॉन्फ़िगरेशन”

Terraform फ़ाइल संरचना

Section titled “Terraform फ़ाइल संरचना”

terraform निर्देशिका में डेमो संसाधन मानक के अनुसार 9 फ़ाइलें हैं:

  • versions.tf — Terraform और प्रोवाइडर संस्करण बाधाएं (azurerm ~> 4.0, azuread ~> 3.0)
  • providers.tf — Azure RM और Azure AD प्रोवाइडर कॉन्फ़िगरेशन
  • data.tf — तैनाती करने वाले की ऑटो-रिज़ॉल्यूशन के लिए Azure AD डेटा स्रोत
  • locals.tf — तैनाती करने वाले का रिज़ॉल्यूशन, Azure Cloud Adoption Framework संसाधन नामकरण, मानक टैग
  • main.tf — संसाधन समूह (नाम rg-cdn-simulator-{environment}-{deployer})
  • variables.tf — सभी इनपुट वेरिएबल (3 आवश्यक, 8 वैकल्पिक)
  • network.tf — VNet (10.100.0.0/16), सबनेट, सार्वजनिक IP, NSG (पोर्ट 22/80/443), NIC
  • vm.tf — templatefile() के माध्यम से cloud-init के साथ Ubuntu 24.04 VM
  • outputs.tf — 17 आउटपुट (15 मानक + 2 घटक-विशिष्ट)

variables.tf सामान्य, कंप्यूट, और घटक-विशिष्ट अनुभागों में व्यवस्थित 11 इनपुट वेरिएबल परिभाषित करता है। deployer पहचानकर्ता आपके Azure AD खाते से स्वतः-रिज़ॉल्व होता है — आपको केवल subscription_id, origin_server, और 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
}

नेटवर्क अवसंरचना

Section titled “नेटवर्क अवसंरचना”

network.tf VNet, सबनेट, सार्वजनिक IP, NSG (पोर्ट 22/80/443), और 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
}

Cloud-Init के साथ वर्चुअल मशीन

Section titled “Cloud-Init के साथ वर्चुअल मशीन”

vm.tf Ubuntu 24.04 VM बनाता है। SSH सार्वजनिक कुंजी पथ को ~ संभालने के लिए pathexpand() के माध्यम से विस्तारित किया जाता है। Cloud-init टेम्पलेट को origin_server और 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 VM को कर्नेल ट्यूनिंग, systemd सीमाएं, परफ़ॉर्मेंस-अनुकूलित कॉन्फ़िगरेशन के साथ NGINX, 128 MB कैश कुंजी ज़ोन, अपस्ट्रीम keepalive पूल, gzip संपीड़न, और 67+ CDN वेंडर हेडर के साथ प्रावधानित करता है। एक साझा हेल्पर लाइब्रेरी (/usr/local/lib/cloud-init-helpers.sh) पुनः प्रयास तर्क और /var/log/cloud-init-progress.log में प्रगति लॉगिंग प्रदान करती है।

cloud-init Terraform टेम्पलेट वेरिएबल का उपयोग करता है: अपस्ट्रीम कॉन्फ़िगरेशन के लिए ${origin_server} और ${origin_host}। NGINX वेरिएबल जैसे ${request_id} को Terraform templatefile में $${request_id} के रूप में एस्केप किया जाता है।

#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 डेमो संसाधन मानक के अनुसार 17 आउटपुट प्रदर्शित करता है — 15 मानक आउटपुट जो सभी डेमो संसाधनों द्वारा साझा किए जाते हैं (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) और 2 घटक-विशिष्ट आउटपुट (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"
}

उदाहरण वेरिएबल फ़ाइल

Section titled “उदाहरण वेरिएबल फ़ाइल”

terraform.tfvars.example को terraform.tfvars में कॉपी करें और अपने मान भरें। .gitignore क्रेडेंशियल कमिट होने से रोकने के लिए terraform.tfvars को बाहर रखता है:

# 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 सार्वजनिक IP, SSH कमांड और एज URL आउटपुट करता है।

F-series कंप्यूट-अनुकूलित VM इस CPU-बाउंड NGINX प्रॉक्सी वर्कलोड के लिए अनुशंसित हैं। डिफ़ॉल्ट Standard_F4s_v2 (4 vCPU, 8 GiB) लैब और डेमो उपयोग के लिए उपयुक्त है। लोड टेस्टिंग या प्रोडक्शन बेंचमार्किंग परिदृश्यों के लिए vm_size वेरिएबल को ओवरराइड करें। Cloud-init कर्नेल ट्यूनिंग और NGINX कॉन्फ़िग vCPU काउंट के साथ स्वचालित रूप से स्केल होते हैं (worker_processes auto)।

terraform apply पूर्ण होने के बाद, cloud-init को NGINX इंस्टॉल और कॉन्फ़िगर करने के लिए 2-3 मिनट प्रतीक्षा करें। हेल्थ एंडपॉइंट सत्यापित करें:

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

अपेक्षित प्रतिक्रिया:

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

अपस्ट्रीम घटकों से वायरिंग

Section titled “अपस्ट्रीम घटकों से वायरिंग”

CDN सिम्युलेटर को एक तैनात ऑरिजिन सर्वर की आवश्यकता है। आवश्यक वेरिएबल भरने के लिए ऑरिजिन सर्वर के terraform आउटपुट का उपयोग करें:

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
आवश्यक वेरिएबलस्रोतप्रारूप
origin_serverऑरिजिन सर्वर public_ip आउटपुटhttp://<ip> (स्कीम सहित)
origin_hostऑरिजिन सर्वर public_ip आउटपुट<ip>:80 (कोई स्कीम नहीं, पोर्ट सहित)

अनुकूलन विकल्पों के लिए NGINX कॉन्फ़िगरेशन या कैश परीक्षण के लिए सत्यापित करें पर जाएं।