From b06f1e89ae26590bb0a477c21ad4a94e3c6388dc Mon Sep 17 00:00:00 2001 From: Jon Cahill-Torre Date: Mon, 17 Feb 2025 12:16:35 +0000 Subject: [PATCH 1/3] docs: transfer N4A docs --- .github/workflows/linkchecker.yml | 2 +- config/_default/config.toml | 2 + .../logging-analysis-azure-storage.md | 48 + .../logging-analysis-logs-analytics.md | 30 + .../logging-config-access-logs.md | 39 + .../logging-config-error-logs.md | 19 + .../nginxaas-azure/logging-limitations.md | 8 + .../nginxaas-azure/ncu-description.md | 11 + .../nginxaas-azure/ssl-tls-prerequisites.md | 21 + .../nginxaas-azure/terraform-prerequisites.md | 9 + .../nginxaas-azure/terraform-resources.md | 6 + .../controlling-access-by-geoip.md | 2 +- content/nginxaas-azure/_index.md | 10 + content/nginxaas-azure/app-protect/_index.md | 8 + .../app-protect/configure-waf.md | 106 + .../nginxaas-azure/app-protect/disable-waf.md | 24 + .../app-protect/enable-logging.md | 188 ++ .../nginxaas-azure/app-protect/enable-waf.md | 30 + content/nginxaas-azure/billing/_index.md | 9 + content/nginxaas-azure/billing/overview.md | 78 + .../billing/usage-and-cost-estimator.md | 145 ++ .../changelog-archive/_index.md | 9 + .../changelog-archive/changelog-2022.md | 105 + .../changelog-archive/changelog-2023.md | 315 +++ content/nginxaas-azure/changelog.md | 295 +++ content/nginxaas-azure/client-tools/_index.md | 10 + content/nginxaas-azure/client-tools/cli.md | 31 + content/nginxaas-azure/client-tools/sdk.md | 55 + .../nginxaas-azure/client-tools/templates.md | 46 + .../nginxaas-azure/client-tools/terraform.md | 45 + content/nginxaas-azure/faq.md | 254 ++ .../nginxaas-azure/getting-started/_index.md | 9 + .../create-deployment/_index.md | 8 + .../create-deployment/deploy-azure-cli.md | 146 ++ .../create-deployment/deploy-azure-portal.md | 88 + .../create-deployment/deploy-terraform.md | 41 + .../managed-identity-portal.md | 83 + .../nginx-configuration/_index.md | 8 + .../nginx-configuration-azure-cli.md | 226 ++ .../nginx-configuration-portal.md | 163 ++ .../nginx-configurations-terraform.md | 82 + .../nginx-configuration/overview.md | 970 +++++++ .../getting-started/prerequisites.md | 23 + .../ssl-tls-certificates/_index.md | 8 + .../ssl-tls-certificates/overview.md | 320 +++ .../ssl-tls-certificates-azure-cli.md | 104 + .../ssl-tls-certificates-portal.md | 95 + .../ssl-tls-certificates-terraform.md | 40 + content/nginxaas-azure/known-issues.md | 193 ++ content/nginxaas-azure/monitoring/_index.md | 8 + .../monitoring/configure-alerts.md | 61 + .../monitoring/enable-logging/_index.md | 8 + .../enable-logging/logging-using-cli.md | 70 + .../enable-logging/logging-using-portal.md | 84 + .../enable-logging/logging-using-terraform.md | 62 + .../monitoring/enable-monitoring.md | 146 ++ .../monitoring/metrics-catalog.md | 302 +++ content/nginxaas-azure/overview/_index.md | 8 + .../overview/feature-comparison.md | 69 + content/nginxaas-azure/overview/overview.md | 67 + content/nginxaas-azure/quickstart/_index.md | 8 + .../quickstart/basic-caching.md | 23 + content/nginxaas-azure/quickstart/geoip2.md | 59 + .../quickstart/hosting-static-content.md | 65 + .../quickstart/loadbalancer-kubernetes.md | 377 +++ .../nginxaas-azure/quickstart/njs-support.md | 41 + .../quickstart/rate-limiting.md | 29 + content/nginxaas-azure/quickstart/recreate.md | 65 + .../quickstart/runtime-state-sharing.md | 114 + content/nginxaas-azure/quickstart/scaling.md | 135 + .../quickstart/security-controls/_index.md | 9 + .../security-controls/auth-basic.md | 36 + .../security-controls/certificates.md | 199 ++ .../quickstart/security-controls/jwt.md | 77 + .../quickstart/security-controls/oidc.md | 171 ++ .../private-link-to-upstreams.md | 232 ++ .../securing-upstream-traffic.md | 122 + .../quickstart/upgrade-channels.md | 42 + .../nginxaas-azure/troubleshooting/_index.md | 8 + .../troubleshooting/migrate-from-standard.md | 51 + .../troubleshooting/troubleshooting.md | 53 + layouts/index.html | 4 +- layouts/shortcodes/golden-star.html | 1 + layouts/shortcodes/icon-warning.html | 1 + .../add-ca-as-protected-file.png | Bin 0 -> 50006 bytes static/nginxaas-azure/alert-logic.png | Bin 0 -> 53989 bytes static/nginxaas-azure/alert-select-signal.png | Bin 0 -> 100426 bytes static/nginxaas-azure/auth-basic-htpasswd.png | Bin 0 -> 105601 bytes .../azure-metrics-nginxaas.certificates.png | Bin 0 -> 36582 bytes static/nginxaas-azure/create-case.png | Bin 0 -> 28119 bytes .../nginxaas-azure/css/cost-calculator_v2.css | 236 ++ static/nginxaas-azure/deployment-complete.png | Bin 0 -> 74095 bytes static/nginxaas-azure/diagnostic-settings.png | Bin 0 -> 59283 bytes static/nginxaas-azure/faq-ip-location-one.png | Bin 0 -> 150294 bytes static/nginxaas-azure/faq-ip-location-two.png | Bin 0 -> 137156 bytes .../nginxaas-azure/js/cost-calculator_v2.js | 488 ++++ .../nginxaas-azure/log-analytics-security.png | Bin 0 -> 265361 bytes static/nginxaas-azure/n4a-architecture.png | Bin 0 -> 134405 bytes .../n4a-data-plane-architecture.svg | 2304 +++++++++++++++++ static/nginxaas-azure/new-case.png | Bin 0 -> 37477 bytes static/nginxaas-azure/properties.png | Bin 0 -> 92734 bytes static/nginxaas-azure/raise-ticket.png | Bin 0 -> 72400 bytes .../security-diagnostic-setting.png | Bin 0 -> 177173 bytes static/nginxaas-azure/test-deployment.png | Bin 0 -> 51486 bytes static/nginxaas-azure/validation-error.png | Bin 0 -> 72632 bytes 105 files changed, 10398 insertions(+), 4 deletions(-) create mode 100644 content/includes/nginxaas-azure/logging-analysis-azure-storage.md create mode 100644 content/includes/nginxaas-azure/logging-analysis-logs-analytics.md create mode 100644 content/includes/nginxaas-azure/logging-config-access-logs.md create mode 100644 content/includes/nginxaas-azure/logging-config-error-logs.md create mode 100644 content/includes/nginxaas-azure/logging-limitations.md create mode 100644 content/includes/nginxaas-azure/ncu-description.md create mode 100644 content/includes/nginxaas-azure/ssl-tls-prerequisites.md create mode 100644 content/includes/nginxaas-azure/terraform-prerequisites.md create mode 100644 content/includes/nginxaas-azure/terraform-resources.md create mode 100644 content/nginxaas-azure/_index.md create mode 100644 content/nginxaas-azure/app-protect/_index.md create mode 100644 content/nginxaas-azure/app-protect/configure-waf.md create mode 100644 content/nginxaas-azure/app-protect/disable-waf.md create mode 100644 content/nginxaas-azure/app-protect/enable-logging.md create mode 100644 content/nginxaas-azure/app-protect/enable-waf.md create mode 100644 content/nginxaas-azure/billing/_index.md create mode 100644 content/nginxaas-azure/billing/overview.md create mode 100644 content/nginxaas-azure/billing/usage-and-cost-estimator.md create mode 100644 content/nginxaas-azure/changelog-archive/_index.md create mode 100644 content/nginxaas-azure/changelog-archive/changelog-2022.md create mode 100644 content/nginxaas-azure/changelog-archive/changelog-2023.md create mode 100644 content/nginxaas-azure/changelog.md create mode 100644 content/nginxaas-azure/client-tools/_index.md create mode 100644 content/nginxaas-azure/client-tools/cli.md create mode 100644 content/nginxaas-azure/client-tools/sdk.md create mode 100644 content/nginxaas-azure/client-tools/templates.md create mode 100644 content/nginxaas-azure/client-tools/terraform.md create mode 100644 content/nginxaas-azure/faq.md create mode 100644 content/nginxaas-azure/getting-started/_index.md create mode 100644 content/nginxaas-azure/getting-started/create-deployment/_index.md create mode 100644 content/nginxaas-azure/getting-started/create-deployment/deploy-azure-cli.md create mode 100644 content/nginxaas-azure/getting-started/create-deployment/deploy-azure-portal.md create mode 100644 content/nginxaas-azure/getting-started/create-deployment/deploy-terraform.md create mode 100644 content/nginxaas-azure/getting-started/managed-identity-portal.md create mode 100644 content/nginxaas-azure/getting-started/nginx-configuration/_index.md create mode 100644 content/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-azure-cli.md create mode 100644 content/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md create mode 100644 content/nginxaas-azure/getting-started/nginx-configuration/nginx-configurations-terraform.md create mode 100644 content/nginxaas-azure/getting-started/nginx-configuration/overview.md create mode 100644 content/nginxaas-azure/getting-started/prerequisites.md create mode 100644 content/nginxaas-azure/getting-started/ssl-tls-certificates/_index.md create mode 100644 content/nginxaas-azure/getting-started/ssl-tls-certificates/overview.md create mode 100644 content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-azure-cli.md create mode 100644 content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md create mode 100644 content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-terraform.md create mode 100644 content/nginxaas-azure/known-issues.md create mode 100644 content/nginxaas-azure/monitoring/_index.md create mode 100644 content/nginxaas-azure/monitoring/configure-alerts.md create mode 100644 content/nginxaas-azure/monitoring/enable-logging/_index.md create mode 100644 content/nginxaas-azure/monitoring/enable-logging/logging-using-cli.md create mode 100644 content/nginxaas-azure/monitoring/enable-logging/logging-using-portal.md create mode 100644 content/nginxaas-azure/monitoring/enable-logging/logging-using-terraform.md create mode 100644 content/nginxaas-azure/monitoring/enable-monitoring.md create mode 100644 content/nginxaas-azure/monitoring/metrics-catalog.md create mode 100644 content/nginxaas-azure/overview/_index.md create mode 100644 content/nginxaas-azure/overview/feature-comparison.md create mode 100644 content/nginxaas-azure/overview/overview.md create mode 100644 content/nginxaas-azure/quickstart/_index.md create mode 100644 content/nginxaas-azure/quickstart/basic-caching.md create mode 100644 content/nginxaas-azure/quickstart/geoip2.md create mode 100644 content/nginxaas-azure/quickstart/hosting-static-content.md create mode 100644 content/nginxaas-azure/quickstart/loadbalancer-kubernetes.md create mode 100644 content/nginxaas-azure/quickstart/njs-support.md create mode 100644 content/nginxaas-azure/quickstart/rate-limiting.md create mode 100644 content/nginxaas-azure/quickstart/recreate.md create mode 100644 content/nginxaas-azure/quickstart/runtime-state-sharing.md create mode 100644 content/nginxaas-azure/quickstart/scaling.md create mode 100644 content/nginxaas-azure/quickstart/security-controls/_index.md create mode 100644 content/nginxaas-azure/quickstart/security-controls/auth-basic.md create mode 100644 content/nginxaas-azure/quickstart/security-controls/certificates.md create mode 100644 content/nginxaas-azure/quickstart/security-controls/jwt.md create mode 100644 content/nginxaas-azure/quickstart/security-controls/oidc.md create mode 100644 content/nginxaas-azure/quickstart/security-controls/private-link-to-upstreams.md create mode 100644 content/nginxaas-azure/quickstart/security-controls/securing-upstream-traffic.md create mode 100644 content/nginxaas-azure/quickstart/upgrade-channels.md create mode 100644 content/nginxaas-azure/troubleshooting/_index.md create mode 100644 content/nginxaas-azure/troubleshooting/migrate-from-standard.md create mode 100644 content/nginxaas-azure/troubleshooting/troubleshooting.md create mode 100644 layouts/shortcodes/golden-star.html create mode 100644 layouts/shortcodes/icon-warning.html create mode 100644 static/nginxaas-azure/add-ca-as-protected-file.png create mode 100644 static/nginxaas-azure/alert-logic.png create mode 100644 static/nginxaas-azure/alert-select-signal.png create mode 100644 static/nginxaas-azure/auth-basic-htpasswd.png create mode 100644 static/nginxaas-azure/azure-metrics-nginxaas.certificates.png create mode 100644 static/nginxaas-azure/create-case.png create mode 100644 static/nginxaas-azure/css/cost-calculator_v2.css create mode 100644 static/nginxaas-azure/deployment-complete.png create mode 100644 static/nginxaas-azure/diagnostic-settings.png create mode 100644 static/nginxaas-azure/faq-ip-location-one.png create mode 100644 static/nginxaas-azure/faq-ip-location-two.png create mode 100644 static/nginxaas-azure/js/cost-calculator_v2.js create mode 100644 static/nginxaas-azure/log-analytics-security.png create mode 100644 static/nginxaas-azure/n4a-architecture.png create mode 100644 static/nginxaas-azure/n4a-data-plane-architecture.svg create mode 100644 static/nginxaas-azure/new-case.png create mode 100644 static/nginxaas-azure/properties.png create mode 100644 static/nginxaas-azure/raise-ticket.png create mode 100644 static/nginxaas-azure/security-diagnostic-setting.png create mode 100644 static/nginxaas-azure/test-deployment.png create mode 100644 static/nginxaas-azure/validation-error.png diff --git a/.github/workflows/linkchecker.yml b/.github/workflows/linkchecker.yml index 030dac8e8..23b14112d 100644 --- a/.github/workflows/linkchecker.yml +++ b/.github/workflows/linkchecker.yml @@ -72,7 +72,7 @@ jobs: uses: azure/login@a65d910e8af852a8061c627c456678983e180302 # v2.2.0 with: creds: ${{secrets.AZURE_CREDENTIALS_DOCS}} - + - name: Retrieve secrets from Keyvault if: env.isProduction != 'true' id: keyvault diff --git a/config/_default/config.toml b/config/_default/config.toml index b2d667272..c7e20c100 100644 --- a/config/_default/config.toml +++ b/config/_default/config.toml @@ -16,7 +16,9 @@ enableGitInfo = true ngf = '/nginx-gateway-fabric/:sections[1:]/:filename' nim = '/nginx-instance-manager/:sections[1:]/:filename' nms = '/nginx-management-suite/:sections[1:]/:filename' + unit = '/nginx-unit/:sections[1:]/:filename' agent = '/nginx-agent/:sections[1:]/:filename' + nginxaas = '/nginxaas/azure/:sections[1:]/:filename' [caches] [caches.modules] diff --git a/content/includes/nginxaas-azure/logging-analysis-azure-storage.md b/content/includes/nginxaas-azure/logging-analysis-azure-storage.md new file mode 100644 index 000000000..67bc3f358 --- /dev/null +++ b/content/includes/nginxaas-azure/logging-analysis-azure-storage.md @@ -0,0 +1,48 @@ +--- +docs: "DOCS-000" +--- + +If the diagnostic setting destination details included a storage account, logs show up in the storage container "insights-logs-nginxlogs" with the following format: `resourceID=//y=/m=/d=
/h=/PT1H.json` + +{{}} +| **Attribute** | **Description** | +|-----------------------------|-----------------| +| `` | The resourceID of the NGINXaaS deployment in upper case.| +| `` | The four-digit year when the log batch was generated.| +| `` | The two-digit month when the log batch was generated.| +| `
` | The two-digit day when the log batch was generated.| +| `` | The two-digit hour value that indicates the starting hour for the log batch, in 24 hour UTC format| +{{}} + +{{}}It can take up to 90 minutes after adding diagnostic settings for logs to appear in the provided Azure Storage container.{{}} + +Each log event in the "PT1H.json" file is written in a new line delimited JSON text format. The properties that show up in each log line are described in the [Top Level Common Schema](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/resource-logs-schema#top-level-common-schema) documentation. + +For instance, an access log event logging to a particular file path will have attributes similar to this example: + +```yaml +{ + "category": "NginxLogs", + "location": "westcentralus", + "operationName": "NGINX.NGINXPLUS/NGINXDEPLOYMENTS/LOG", + "properties": { + "message": "172.92.129.50 - \"-\" [18/Jan/2024:17:59:00 +0000] \"GET / HTTP/1.1\" 200 11232 \"-\" \"curl/8.4.0\" \"-\" \"20.69.58.179\" sn=\"localhost\" rt=0.000 ua=\"-\" us=\"-\" ut=\"-\" ul=\"-\" cs=\"-\" ", + "filePath": "/var/log/nginx/access.log" + }, + "resourceId": "/SUBSCRIPTIONS/FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF/RESOURCEGROUPS/RESOURCEGROUP1/PROVIDERS/NGINX.NGINXPLUS/NGINXDEPLOYMENTS/TEST1", + "time": "2024-01-18T17:59:00.363956795Z" +} +``` + +If [syslog-based](#logging-to-syslog) logs are used, the log event entry has different **properties** sub-fields: + +```yaml +#... +"properties": { + "message": "172.92.129.50 - - [16/Jan/2024:18:00:00 +0000] \"GET / HTTP/1.1\" 200 11232 \"-\" \"curl/8.4.0\"", + "tag": "nginx", + "severity": "info", + "facility": "local7" + }, +#... +``` diff --git a/content/includes/nginxaas-azure/logging-analysis-logs-analytics.md b/content/includes/nginxaas-azure/logging-analysis-logs-analytics.md new file mode 100644 index 000000000..8809a824d --- /dev/null +++ b/content/includes/nginxaas-azure/logging-analysis-logs-analytics.md @@ -0,0 +1,30 @@ +--- +docs: "DOCS-000" +--- + +If the diagnostic setting destination details included a Logs Analytics workspace, logs show up in the table "NGXOperationLogs" with the following non-standard attributes: + +{{}} +| **Attribute** | **Description** | +|-----------------------------|-----------------| +| **Location** | The location of the NGINXaaS resource.| +| **Message** | The generated NGINX log line. | +| **FilePath** | The path to which NGINX logs were configured to be logged to if the nginx config used file-based logs. | +| **Tag** | The tag with which NGINX logs were generated if syslog-based log configuration is used. By default this is nginx | +| **Facility** | The syslog facility with which NGINX logs were generated if syslog-based log configuration is used. | +| **Severity** | The syslog severity with which NGINX logs were generated if syslog-based log configuration is used. | + +{{}} + +Using a [KQL](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/), a custom query can be run to view the logs: + +``` +NGXOperationLogs +| where Location contains "eastus" +``` + +For more information on the standard attributes that appear in Logs Analytics,see the [Standard columns in Azure Monitor Logs](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/log-standard-columns) documentation. + +For more information on using [KQL](https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/) see [Queries in Log Analytics](https://learn.microsoft.com/en-us/azure/azure-monitor/logs/queries?tabs=groupby). + +{{}}It can take up to 90 minutes after adding diagnostic settings for logs to appear in the provided Logs Analytics Workspace.{{}} diff --git a/content/includes/nginxaas-azure/logging-config-access-logs.md b/content/includes/nginxaas-azure/logging-config-access-logs.md new file mode 100644 index 000000000..01fba8215 --- /dev/null +++ b/content/includes/nginxaas-azure/logging-config-access-logs.md @@ -0,0 +1,39 @@ +--- +docs: "DOCS-000" +--- + +NGINX access logs are disabled by default. You can enable access logs by adding **access_log** directives to your NGINX configuration to specify the location of the logs and formats. The log path should always be configured to be inside **/var/log/nginx**. + +```nginx +http { + log_format myfmt '$remote_addr - $remote_user [$time_local] ' + '"$request" $status $body_bytes_sent ' + '"$http_referer" "$http_user_agent" "$gzip_ratio"'; + + access_log /var/log/nginx/nginx-access.log myfmt; + # ... +} +``` + +{{}} The **$time_local** variable includes the date and time for each log. It helps with ordering logs after export. {{}} + +To explicitly disable access logs, apply the following config: + +```nginx +http { + access_log off; +} +``` + +or + +```nginx +http { + access_log /dev/null; +} +``` + +To learn more about how to specify `access__log` in different configuration levels and their effect, see [access_log](https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log) + +{{}}Unless you use **syslog**, keep NGINX logs in the **/var/log/nginx** directory. Otherwise, you may lose data from your logs. +{{}} diff --git a/content/includes/nginxaas-azure/logging-config-error-logs.md b/content/includes/nginxaas-azure/logging-config-error-logs.md new file mode 100644 index 000000000..c27d8ace8 --- /dev/null +++ b/content/includes/nginxaas-azure/logging-config-error-logs.md @@ -0,0 +1,19 @@ +--- +docs: "DOCS-000" +--- + +By default, NGINXaaS for Azure puts the error log at **/var/log/nginx/error.log**. It includes messages with severity **error** and above. + +While you should configure log files in the **/var/log/nginx** directory, you can change the filename and severity level. For example, the following line in the NGINX configuration sends errors to the `nginx-error.log` file, and limits messages to a severity level of **emerg**: + +```nginx +error_log /var/log/nginx/nginx-error.log emerg; +``` + +Alternatively, you can disable error logs completely with the following line: + +```nginx +error_log /dev/null; +``` + +To learn more about how to specify `error_log` in different configuration levels, see the documentation of the [error_log](https://nginx.org/en/docs/ngx_core_module.html?#error_log) directive. diff --git a/content/includes/nginxaas-azure/logging-limitations.md b/content/includes/nginxaas-azure/logging-limitations.md new file mode 100644 index 000000000..a6b636d66 --- /dev/null +++ b/content/includes/nginxaas-azure/logging-limitations.md @@ -0,0 +1,8 @@ +--- +docs: "DOCS-000" +--- + +1. File-based logs must be configured to use the path **/var/log/nginx**. +1. The **gzip** parameter for the **access_log** directive is not supported, and uploading a config with this parameter will cause an error. +1. Logging **error_log** to a cyclic memory buffer using the **memory:** prefix is not allowed and will cause a config upload error. +1. Egress Networking charges apply for traffic sent from the NGINX deployment to a syslog server present in a different VNet. diff --git a/content/includes/nginxaas-azure/ncu-description.md b/content/includes/nginxaas-azure/ncu-description.md new file mode 100644 index 000000000..138b593e6 --- /dev/null +++ b/content/includes/nginxaas-azure/ncu-description.md @@ -0,0 +1,11 @@ +--- +docs: "DOCS-1476" +--- + +An NGINX Capacity Unit (NCU) quantifies the capacity of an NGINX instance based on the underlying compute resources. This abstraction allows you to specify the desired capacity in NCUs without having to consider the regional hardware differences. + +An NGINX Capacity Unit consists of the following parameters: + +* CPU: an NCU provides 20 [Azure Compute Units](https://learn.microsoft.com/en-us/azure/virtual-machines/acu) (ACUs) +* Bandwidth: an NCU provides 60 Mbps of network throughput +* Concurrent connections: an NCU provides 400 concurrent connections. This performance is not guaranteed when NGINX App Protect WAF is used with NGINXaaS diff --git a/content/includes/nginxaas-azure/ssl-tls-prerequisites.md b/content/includes/nginxaas-azure/ssl-tls-prerequisites.md new file mode 100644 index 000000000..68849fbf5 --- /dev/null +++ b/content/includes/nginxaas-azure/ssl-tls-prerequisites.md @@ -0,0 +1,21 @@ +--- +docs: "DOCS-000" +--- + +- AKV to store certificates that you want to add to the deployment. + +- A user or system assigned identity associated with your NGINXaaS deployment. Ensure that your managed identity (MI) has read access to secrets stored in AKV: + + - If using Azure RBAC for AKV, ensure that your MI has [Key Vault Secrets User](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#key-vault-secrets-user) or higher permissions. + + - If using Access Policies for AKV, ensure that your MI has *GET secrets* or higher permissions. + +- In addition to the MI permissions, if using the Azure portal to manage certificates, ensure that you have read access to list certificates inside the Key Vault: + + - If using Azure RBAC for AKV, ensure that you have [Key Vault Reader](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#key-vault-reader) or higher permissions. + + - If using Access Policies for AKV, ensure that you have *LIST certificates* or higher permissions. + + - If public access is disabled on your key vault, [configure Network Security Perimeter]({{< relref "/nginxaas-azure/quickstart/security-controls/certificates.md#configure-network-security-perimeter-nsp" >}}) and add an inbound access rule to allow your client IP address. + +- If you're unfamiliar with Azure Key Vault, check out the [Azure Key Vault concepts](https://docs.microsoft.com/en-us/azure/key-vault/general/basic-concepts) documentation from Microsoft. \ No newline at end of file diff --git a/content/includes/nginxaas-azure/terraform-prerequisites.md b/content/includes/nginxaas-azure/terraform-prerequisites.md new file mode 100644 index 000000000..b529c9b65 --- /dev/null +++ b/content/includes/nginxaas-azure/terraform-prerequisites.md @@ -0,0 +1,9 @@ +--- +docs: "DOCS-000" +--- + +- Confirm that you meet the [NGINXaaS Prerequisites]({{< relref "/nginxaas-azure/getting-started/prerequisites.md" >}}). +- [Authenticate Terraform to Azure](https://learn.microsoft.com/en-us/azure/developer/terraform/authenticate-to-azure) +- [Install Terraform](https://learn.hashicorp.com/tutorials/terraform/install) + +{{< caution >}} The examples in the NGINXaaS for Azure Snippets GitHub repository use the prerequisites module [available in the same repository](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/prerequisites). {{< /caution >}} diff --git a/content/includes/nginxaas-azure/terraform-resources.md b/content/includes/nginxaas-azure/terraform-resources.md new file mode 100644 index 000000000..727740cc4 --- /dev/null +++ b/content/includes/nginxaas-azure/terraform-resources.md @@ -0,0 +1,6 @@ +--- +docs: "DOCS-000" +--- + +- [NGINXaaS Managed Identity Documentation]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) +- [NGINXaaS Azure Monitor Documentation]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}) \ No newline at end of file diff --git a/content/nginx/admin-guide/security-controls/controlling-access-by-geoip.md b/content/nginx/admin-guide/security-controls/controlling-access-by-geoip.md index 8f5ebbd58..b31691588 100644 --- a/content/nginx/admin-guide/security-controls/controlling-access-by-geoip.md +++ b/content/nginx/admin-guide/security-controls/controlling-access-by-geoip.md @@ -392,7 +392,7 @@ In this example, the IP address will be checked in the `GeoLite2-Country.mmdb` d ## More Info -- [GeoIP2 Dynamic Module Installation Instructions]({{< relref "geoip2.md" >}}) +- [GeoIP2 Dynamic Module Installation Instructions]({{< relref "/nginx/admin-guide/dynamic-modules/geoip2.md" >}}) - [MaxMind GeoIP2 Databases](https://www.maxmind.com/en/geoip2-databases) diff --git a/content/nginxaas-azure/_index.md b/content/nginxaas-azure/_index.md new file mode 100644 index 000000000..b77d7286e --- /dev/null +++ b/content/nginxaas-azure/_index.md @@ -0,0 +1,10 @@ +--- +title: "NGINXaaS for Azure" +description: | + NGINX as a Service for Azure is an IaaS offering that is tightly integrated into Microsoft Azure public cloud and its ecosystem, making applications fast, efficient, and reliable with full lifecycle management of advanced NGINX traffic services. +linkTitle: "NGINXaaS for Azure" +menu: docs +url: /nginxaas/azure/ +cascade: + logo: NGINX-for-Azure-icon.svg +--- \ No newline at end of file diff --git a/content/nginxaas-azure/app-protect/_index.md b/content/nginxaas-azure/app-protect/_index.md new file mode 100644 index 000000000..1829a1e8e --- /dev/null +++ b/content/nginxaas-azure/app-protect/_index.md @@ -0,0 +1,8 @@ +--- +title: NGINX App Protect WAF (Preview) +weight: 200 +url: /nginxaas/azure/app-protect/ +menu: + docs: + parent: NGINXaaS for Azure +--- diff --git a/content/nginxaas-azure/app-protect/configure-waf.md b/content/nginxaas-azure/app-protect/configure-waf.md new file mode 100644 index 000000000..32c24aea1 --- /dev/null +++ b/content/nginxaas-azure/app-protect/configure-waf.md @@ -0,0 +1,106 @@ +--- +title: "Configure App Protect WAF" +weight: 300 +categories: ["tasks"] +toc: true +--- + +## Overview + +This guide explains how to configure the F5 NGINX App Protect WAF security features. + +## Configure + +To use NGINX App Protect apply the following changes to the NGINX config file. + +1. Load the NGINX App Protect WAF module on the main context: + +```nginx +load_module modules/ngx_http_app_protect_module.so; +``` + +2. Set the enforcer address: + +```nginx +app_protect_enforcer_address 127.0.0.1:50000; +``` + +{{}} The app_protect_enforcer_address directive is a required directive for Nginx App Protect to work and must match 127.0.0.1:50000{{}} + + +3. Enable NGINX App Protect WAF with the `app_protect_enable` directives in the appropriate scope. The `app_protect_enable` directive may be set in the `http`, `server`, and `location` contexts. + +It is recommended to have a basic policy enabled in the `http` or `server` context to process malicious requests in a more complete manner. + +```nginx +app_protect_enable on; +``` + +4. Configure the path of the pre-compiled policy file to the `app_protect_policy_file` directive. You can find the list of supported policies and their paths under the [Precompiled Policies](#precompiled-policies) section. + +```nginx +app_protect_policy_file /etc/app_protect/conf/NginxDefaultPolicy.json; +``` + +Sample Config with App Protect configured: + +```nginx +user nginx; +worker_processes auto; +worker_rlimit_nofile 8192; +pid /run/nginx/nginx.pid; + +load_module modules/ngx_http_app_protect_module.so; + +events { + worker_connections 4000; +} + +error_log /var/log/nginx/error.log debug; + +http { + access_log off; + server_tokens ""; + + app_protect_enforcer_address 127.0.0.1:50000; + + server { + listen 80 default_server; + + location / { + app_protect_enable on; + app_protect_policy_file /etc/app_protect/conf/NginxDefaultPolicy.tgz; + proxy_pass http://127.0.0.1:80/proxy/$request_uri; + } + + location /proxy { + default_type text/html; + return 200 "Hello World\n"; + } + } +} +``` + +## Precompiled Policies + +NGINXaaS for Azure ships with the two reference policies (Default and Strict) supported in NGINX App Protect. These policies are supported in both the blocking and transparent enforcement modes. +For more information on these policies refer the NGINX App Protect [configuration guide](https://docs.nginx.com/nginx-app-protect-waf/v5/configuration-guide/configuration/). + +The following table shows the path to the precompiled policy file that needs to be used with the `app_protect_policy_file` directive: + +{{}} + | Policy | Enforcement Mode | Path | + |---------------------------- | ---------------------------- | -------------------------------------------- | + | Default | Strict | /etc/app_protect/conf/NginxDefaultPolicy.json | + | Default | Transparent | /etc/app_protect/conf/NginxDefaultPolicy_transparent.json | + | Strict | Strict | /etc/app_protect/conf/NginxStrictPolicy.json | + | Strict | Transparent | /etc/app_protect/conf/NginxStrictPolicy_transparent.json | +{{}} + +To view the contents of the available security policies, navigate to the azure portal and select the **Security Policies** tab in the App Protect section. + +{{}}Custom policies are not supported at this time.{{}} + +## What's next + +[Enable App Protect WAF Logs]({{< relref "/nginxaas-azure/app-protect/enable-logging.md" >}}) diff --git a/content/nginxaas-azure/app-protect/disable-waf.md b/content/nginxaas-azure/app-protect/disable-waf.md new file mode 100644 index 000000000..7c9823bec --- /dev/null +++ b/content/nginxaas-azure/app-protect/disable-waf.md @@ -0,0 +1,24 @@ +--- +title: "Disable App Protect WAF" +weight: 400 +categories: ["tasks"] +toc: true +--- + +## Overview +This guide explains how to disable F5 NGINX App Protect WAF on an NGINX as a Service for Azure (NGINXaaS) deployment. + +## Before you start +You must remove the WAF directives from your NGINX config file before attempting to disable WAF. + +## Disable App Protect WAF + +### Using the Microsoft Azure Portal + +Access the [Microsoft Azure portal](https://portal.azure.com) + +1. Go to your NGINXaaS for Azure deployment. + +2. Select NGINX app protect in the left menu. + +3. Select **Disable**. diff --git a/content/nginxaas-azure/app-protect/enable-logging.md b/content/nginxaas-azure/app-protect/enable-logging.md new file mode 100644 index 000000000..f1da8766a --- /dev/null +++ b/content/nginxaas-azure/app-protect/enable-logging.md @@ -0,0 +1,188 @@ +--- +title: "Enable App Protect WAF Logs" +weight: 300 +categories: ["tasks"] +toc: true +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) supports exporting NGINX App Protect logs to an Azure Storage account or to a Log Analytics workspace. + +## Setting up operational logs + +NGINX App Protect operational logs are sent to the NGINX error logs. See [Enable NGINX Logs]({{< relref "/nginxaas-azure/monitoring/enable-logging/">}}) to configure error logs. + +## Setting up security logs + +1. Enable the NGINX Security Logs category in **Diagnostic Settings**. For more information on logging, see [Enable NGINX Logs]({{< relref "/nginxaas-azure/monitoring/enable-logging/">}}). + +{{< img src="nginxaas-azure/security-diagnostic-setting.png" alt="Screenshot of the NGINXaaS WAF security logs diagnostic settings" >}} + +2. Update your NGINX configuration to enable security logs in an http/server/location context. + +```nginx +app_protect_security_log_enable on; +``` + +3. Configure the log configuration path and destination to the `app_protect_security_log` directive. More information on supported log configurations and destination can be found in the following sections. +```nginx +app_protect_security_log "/etc/app_protect/conf/log_all.json" syslog:server=localhost:5140; +``` + +Sample NGINX config with security logs enabled: + +```nginx +user nginx; +worker_processes auto; +worker_rlimit_nofile 8192; +pid /run/nginx/nginx.pid; + +load_module modules/ngx_http_app_protect_module.so; + +events { + worker_connections 4000; +} + +error_log /var/log/nginx/error.log debug; + +http { + access_log off; + server_tokens ""; + + app_protect_enforcer_address 127.0.0.1:50000; + + server { + listen 80 default_server; + + location / { + app_protect_enable on; + app_protect_policy_file /etc/app_protect/conf/NginxDefaultPolicy.tgz; + app_protect_security_log_enable on; + app_protect_security_log "/etc/app_protect/conf/log_all.tgz" syslog:server=localhost:5140; + proxy_pass http://127.0.0.1:80/proxy/$request_uri; + } + + location /proxy { + default_type text/html; + return 200 "Hello World\n"; + } + } +} +``` + +You can find more details on these directives in the [Security log](https://docs.nginx.com/nginx-app-protect-waf/v5/logging-overview/security-log/) documentation. + +### Log Configuration + +NGINXaaS for Azure ships with several pre-compiled log configuration bundles. More details on these logging bundles can be found in the [Security log](https://docs.nginx.com/nginx-app-protect-waf/v5/logging-overview/security-log/) documentation. + +The following table shows the path to the log configuration file that needs to be used with the app_protect_security_log directive: + + {{}} + | Profile | Path | + |---------------------------- | -------------------------------------------- | + | log_default | /etc/app_protect/conf/log_default.json | + | log_all | /etc/app_protect/conf/log_all.json | + | log_illegal | /etc/app_protect/conf/log_illegal.json | + | log_blocked | /etc/app_protect/conf/log_blocked.json | + | log_grpc_all | /etc/app_protect/conf/log_grpc_all.json | + | log_grpc_illegal | /etc/app_protect/conf/log_grpc_illegal.json | + | log_grpc_blocked | /etc/app_protect/conf/log_grpc_blocked.json | + {{}} + +To view the contents of the available log configuration, navigate to the azure portal and select the Log Configurations tab in the App Protect section. + +### Logging Destinations + +1. Logging to NGINXaaS syslog (Recommended) + +NGINXaaS for Azure supports a local syslog server running on port 5140. Syslogs forwarded to this destination are sent to the sink configured in the **Diagnostic Setting** section. + +```nginx +app_protect_security_log "/etc/app_protect/conf/log_all.json" syslog:server=localhost:5140; +``` + +{{}} When using a NGINXaaS syslog destination, the syslog server destination needs to match localhost:5140. Configuring log directives to other syslog locations will result in an error in the NGINX config. +{{}} + +2. File Logging + +NGINXaaS for Azure supports logging to a file path. Any logs written under `/var/log/app_protect` will be sent to the sink configured in **Diagnostic Setting**. + +```nginx +app_protect_security_log "/etc/app_protect/conf/log_all.json" /var/log/app_protect/security.log; +``` + +{{}}When using a file destination, the configured path for nginx security logs has to be within `/var/log/app_protect`. Configuring log directives to other file locations will result in an error in the NGINX config. +{{}} + + +## Analyzing NGINX security logs in Azure Log Analytics workspaces. + +If the diagnostic setting destination details included a Logs Analytics workspace, logs appear in the "NGXSecurityLogs" table with the following columns: + +{{}} +| **Attribute** | **Description** | +|-----------------------------|-----------------| +| **Location** | The location of the NGINXaaS resource.| +| **Message** | The generated NGINX security log line. | +| **FilePath** | The path to which NGINX security logs are configured to be logged to if the nginx config uses file-based logs. | +| **Tag** | The tag with which NGINX security logs are generated if syslog-based log configuration is used. | +| **Facility** | The syslog facility that generates the NGINX security logs if syslog-based log configuration is being used. | +| **Severity** | The syslog severity with which NGINX security logs were generated if syslog-based log configuration is used. | +{{}} + +To view the raw data in the NGINX security log, run the following KQL query: +``` +NGXSecurityLogs +| extend JSONLog = extract(@"json_log\s*=\s*""({.*?})""", 1, Message) +| extend Log = parse_json(replace_string(JSONLog, '""', '"')) +| project Log +``` + +{{< img src="nginxaas-azure/log-analytics-security.png" alt="Screenshot showing NGINX security logs in the Logs Analytics Workspace" >}} + +The following sample queries will help you get started with creating visualizations based on security logs. + +Blocked requests by IP + +``` +NGXSecurityLogs +| extend JSONLog = extract(@"json_log\s*=\s*""({.*?})""", 1, Message) +| extend Log = parse_json(replace_string(JSONLog, '""', '"')) +| where Log.enforcementAction == "block" +| project ClientIP = tostring(Log.clientIp), TimeGenerated +| summarize count() by ClientIP, bin(TimeGenerated, 1m) +| render timechart +``` + +Blocked requests by URL + +``` +NGXSecurityLogs +| extend JSONLog = extract(@"json_log\s*=\s*""({.*?})""", 1, Message) +| extend Log = parse_json(replace_string(JSONLog, '""', '"')) +| where Log.enforcementAction == "block" +| project URL = tostring(Log.url), TimeGenerated +| summarize count() by URL, bin(TimeGenerated, 1m) +| render timechart +``` + +Top matched rules + +``` +NGXSecurityLogs +| extend JSONLog = extract(@"json_log\s*=\s*""({.*?})""", 1, Message) +| extend Log = parse_json(replace_string(JSONLog, '""', '"')) +| where Log.enforcementAction == "block" +| project attackType = Log.enforcementState.attackType, TimeGenerated +| mv-expand attackType +| project attackName = tostring(attackType.name), TimeGenerated +| summarize count() by attackName, bin(TimeGenerated, 1m) +| render timechart +``` + +To add a visualization to a dashboard, select the **Pin to dashboard** icon in the top right of the log analytics workspace. + +{{}}It can take up to 90 minutes after adding diagnostic settings for logs to appear in the provided Logs Analytics Workspace.{{}} diff --git a/content/nginxaas-azure/app-protect/enable-waf.md b/content/nginxaas-azure/app-protect/enable-waf.md new file mode 100644 index 000000000..9fda33c54 --- /dev/null +++ b/content/nginxaas-azure/app-protect/enable-waf.md @@ -0,0 +1,30 @@ +--- +title: "Enable App Protect WAF" +weight: 200 +categories: ["tasks"] +toc: true +--- + +## Overview + +This guide explains how to enable F5 NGINX App Protect WAF on a F5 NGINX as a Service for Azure (NGINXaaS) deployment. [F5 NGINX App Protect WAF](https://docs.nginx.com/nginx-app-protect-waf/v5) provides web application firewall (WAF) security protection for your web applications, including OWASP Top 10; response inspection; Meta characters check; HTTP protocol compliance; evasion techniques; disallowed file types; JSON & XML well-formedness; sensitive parameters & Data Guard. + +## Before you start +- NGINX App Protect WAF can only be enabled on NGINXaaS for Azure deployments with the **Standard v2** [plan]({{< relref "/nginxaas-azure/billing/overview.md" >}}) + +## Enable NGINX App Protect (Preview) +NGINX App Protect is disabled by default and needs to be explicitly enabled on an NGINXaaS deployment. Follow these steps: + +### Using the Microsoft Azure Portal + +Access the [Microsoft Azure portal](https://portal.azure.com) + +1. Go to your NGINXaaS for Azure deployment. + +2. Select NGINX app protect in the left menu. + +3. Select **Enable App Protect**. + +## What's next + +[Configure App Protect WAF]({{< relref "/nginxaas-azure/app-protect/configure-waf.md" >}}) diff --git a/content/nginxaas-azure/billing/_index.md b/content/nginxaas-azure/billing/_index.md new file mode 100644 index 000000000..a6fbefc39 --- /dev/null +++ b/content/nginxaas-azure/billing/_index.md @@ -0,0 +1,9 @@ +--- +title: Marketplace billing +weight: 400 +draft: false +url: /nginxaas/azure/billing/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/billing/overview.md b/content/nginxaas-azure/billing/overview.md new file mode 100644 index 000000000..bc084d772 --- /dev/null +++ b/content/nginxaas-azure/billing/overview.md @@ -0,0 +1,78 @@ +--- +title: "Billing overview" +weight: 100 +categories: ["concepts"] +toc: true +docs: "DOCS-885" +--- + +## Pricing plans + +F5 NGINX as a Service for Azure (NGINXaaS) provides two pricing plans. + +### Standard V2 plan + +The Standard V2 plan is designed for production workloads offering a [99.95% uptime SLA](https://www.f5.com/pdf/customer-support/eusa-sla.pdf), high availability through active-active deployments, redundancy, autoscaling, lossless rolling upgrades, and more. Choosing the Standard V2 plan will result in billing based on metered consumption of NGINX Capacity Units (NCU). + +When using the Standard V2 plan, NGINXaaS is a consumption-based service, metered hourly, and billed monthly in NGINX Capacity Units (NCUs). + +The SKU for the Standard V2 pricing plan is `standardv2_Monthly`. + +The Standard V2 plan allows for configuration of NGINX App Protect WAF and a higher number of listen ports. + + +### Basic plan + +The Basic plan is ideal for those who are just starting out, as it's intended for early-stage trials, development work, and testing. Please note that it doesn't provide service level agreement (SLA) guarantees, and it lacks both redundancy options and the capability to scale resources as needed. + +When using the Basic plan, each NGINXaaS deployment is billed at the rate specified on the [Azure Marketplace Offer](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/f5-networks.f5-nginx-for-azure?tab=Overview). + +The SKU for the Basic pricing plan is `basic_Monthly`. + +{{< note >}}The costs for your plan will appear on the Azure Portal Cost Analysis page and the Azure Consumption APIs. There may be a 24h delay before usage is visible.{{< /note >}} + + +### Standard plan (deprecated) + +The Standard plan is comparable to the Standard V2 plan except that it doesn't support some features like NGINX App Protect WAF. + +The SKU to use for the Standard pricing plan is `standard_Monthly`. + +{{< note >}} Standard plan is now deprecated in favor of Standard V2 plan.{{< /note >}} + + +## NGINX Capacity Unit (NCU) + +{{< include "/nginxaas-azure/ncu-description.md" >}} + +Each NCU provisioned (not consumed) is billed at the rate specified on the [Azure Marketplace Offer](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/f5-networks.f5-nginx-for-azure?tab=Overview). The minimum usage interval is 1 hour, and the maximum provisioned NCU size is billed for that hour. + +*Billing Example 1*: "I provisioned a 20 NCU NGINXaaS deployment in East US 2 at 9:04AM and then deleted it at 10:45AM." + +* The hourly rate in East US 2 is `$0.03/NCU/hour`. +* 9:00 hour: `20 NCU·hour` +* 10:00 hour: `20 NCU·hour` +* Total NCU·hours: `40 NCU·hour` +* Total: `40 NCU·hour * $0.03/NCU/hour = $1.20`. + +*Billing Example 2*: "I provisioned a 40 NCU NGINXaaS deployment in West Europe at 9:34AM. At 10:04AM I resized it to 20 NCUs. I then deleted it at 11:45AM." + +* The hourly rate in West Europe is `$0.05/NCU/hour`. +* 9:00 hour: `40 NCU·hour` +* 10:00 hour: `40 NCU·hour` +* 11:00 hour: `20 NCU·hour` +* Total NCU·hours: `100 NCU·hour` +* Total: `100 NCU·hours * 0.05$/NCU/hour = $5.00`. + +{{< note >}}Further guidance: +* For how many NCUs should you provision and how to scale to match workload, see the [Scaling Guidance]({{< relref "/nginxaas-azure/quickstart/scaling.md" >}}) +* To learn more about metrics related to NCUs, see the [NGINXaaS Statistics namespace]({{< relref "/nginxaas-azure/monitoring/metrics-catalog.md#nginxaas-statistics" >}}) +{{< /note >}} + + +## Bandwidth + +The standard Azure [networking](https://azure.microsoft.com/en-us/pricing/details/virtual-network/) and [bandwidth](https://azure.microsoft.com/en-us/pricing/details/bandwidth/) charges apply to NGINX deployments. + +{{< note >}}The management traffic for NGINX instances is billed as a `Virtual Network Peering - Intra-Region Egress` charge. This charge includes the data for shipping metrics and logs. The cost for shipping metrics data is approximately $0.03/month. If you enable NGINX logging the cost increases by roughly $0.005 per GB of logs NGINX generates. To estimate this, multiply the number of requests by the average log line size of the access_log format you have configured. +{{< /note >}} diff --git a/content/nginxaas-azure/billing/usage-and-cost-estimator.md b/content/nginxaas-azure/billing/usage-and-cost-estimator.md new file mode 100644 index 000000000..875082ffd --- /dev/null +++ b/content/nginxaas-azure/billing/usage-and-cost-estimator.md @@ -0,0 +1,145 @@ +--- +title: "Usage and cost estimator" +weight: 200 +categories: ["concepts"] +toc: true +docs: "DOCS-1474" +--- + +{{< raw-html >}} + + +
+

+ Cost Estimation for Standard V2 Plan + +

+
+
+
+

1. Estimate NCU Usage

+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ +
+
+
+
+

+ 2. Estimate Monthly Cost +

+
+ + +
+
+ + + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ Total Monthly Payment + -- +
+ The standard Azure networking and bandwidth charges apply to NGINX deployments. +
+
+ Show calculations +
+
+

+ hours * (( NCUs * per NCU per hour) + additional listen ports * ) = +
+

+
+
+ + + + + + + +
RegionTierCost per NCU/hr
+
+
+
+
+
+
+
+
+ +{{< /raw-html >}} diff --git a/content/nginxaas-azure/changelog-archive/_index.md b/content/nginxaas-azure/changelog-archive/_index.md new file mode 100644 index 000000000..005902602 --- /dev/null +++ b/content/nginxaas-azure/changelog-archive/_index.md @@ -0,0 +1,9 @@ +--- +title: Changelog archive +weight: 950 +draft: false +url: /nginxaas/azure/changelog-archive/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/changelog-archive/changelog-2022.md b/content/nginxaas-azure/changelog-archive/changelog-2022.md new file mode 100644 index 000000000..121869243 --- /dev/null +++ b/content/nginxaas-azure/changelog-archive/changelog-2022.md @@ -0,0 +1,105 @@ +--- +title: "2022" +weight: 200 +toc: true +--- + +Learn about the updates, new features, and resolved bugs in F5 NGINX as a Service for Azure during the year 2022. + +To see the latest changes, visit the [Changelog]({{< relref "/nginxaas-azure/changelog" >}}) page. + +To see a list of currently active issues, visit the [Known issues]({{< relref "/nginxaas-azure/known-issues.md" >}}) page. + +## December 14, 2022 + +- {{% icon-resolved %}} **New customer deployments are now functional.** + + We have rolled out a fix that addresses the issue, and new customers or existing customers in a new region can create deployments. + +## December 7, 2022 + +- {{% icon-resolved %}} **System Assigned Managed Identitiy can now be used with a deployment.** + + Users can now leverage System Assigned Managed Identities with their deployment. The lifecycle of the identity is tied to the lifecycle of the corresponding deployment. See [Managed Identity Types](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview#managed-identity-types) for more information. + +## November 29, 2022 + +- {{% icon-resolved %}} **Absolute paths may now be used with the `js_import` directive.** + + NGINXaaS for Azure has new restrictions on file paths for certificate files, njs files, etc. See the [NGINX Filesystem Restrictions table]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/#nginx-filesystem-restrictions" >}}) for more information. Existing configurations will not be affected unless they need to be updated. + +## November 22, 2022 + +- {{% icon-feature %}} **Logging support is now available** + + Please visit the [Logging Support]({{< relref "/nginxaas-azure/monitoring/enable-logging/" >}}) documentation for more information on exporting NGINX logs with NGINXaaS for Azure. + +- {{% icon-resolved %}} **NGINXaaS for Azure ARM API schema supports previously unused fields `protectedFiles` and `logging`.** + +## November 14, 2022 + +- {{% icon-feature %}} NGINX deployment can be configured to send [metrics-based alerts]({{< relref "/nginxaas-azure/monitoring/configure-alerts.md" >}}). + +## November 7, 2022 + +- {{% icon-feature %}} New deployments utilize [Availability Zones](https://learn.microsoft.com/en-us/azure/reliability/availability-zones-overview) to ensure data planes are highly available. +- {{% icon-feature %}} Files containing sensitive data can be uploaded as a "Protected File", see: [NGINX Configuration]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) + +## October 24, 2022 + +- {{% icon-feature %}} __NGINXaaS for Azure is now generally available in more regions__ + + NGINXaaS for Azure is now available in the following additional regions: + + - West US 2 + - East US + - Central US + - North Central US + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of supported regions. + +## October 11, 2022 + +- {{% icon-resolved %}} **Resolved known njs filepath issues** + + Affecting new deployments only, two njs files in different subdirectories may share the same filename. For example: + ``` + js_path "njs"; + js_import d1 as d1/test.js; + js_import d2 as d2/test.js; + ``` + +## October 5, 2022 + +- {{% icon-feature %}} __Updated the error returned when a certificate cannot be applied to the NGINX Configuration__ + + This change improves the readability of some errors that may be returned when a certificate cannot be applied. + +## September 22, 2022 + +- {{% icon-feature %}} **NGINX configurations have default logging directives** + + Added default `access_log` and `error_log` to NGINX configurations in preparation for upcoming logging features. Requires a config push to be applied. + +- {{% icon-feature %}} **Improved likelihood of deployment success** +- {{% icon-feature %}} **Improved performance and reliability of backend services** +- {{% icon-resolved %}} **Fixed bug where NGINX version appeared empty** + +## July 21, 2022 + +- {{% icon-feature %}} **Basic caching is now supported** + + For more information on caching with NGINXaaS for Azure, please visit the [Basic Caching]({{< relref "/nginxaas-azure/quickstart/basic-caching.md" >}}) documentation. + +- {{% icon-feature %}} **Rate Limiting is now supported** + + For information on rate limiting with NGINXaaS for Azure, please visit the [Rate Limiting]({{< relref "/nginxaas-azure/quickstart/rate-limiting.md" >}}) documentation. + + +## May 24, 2022 + +### Welcome to the NGINXaaS Public Preview + +NGINXaaS for Azure is now available for public preview. Give it a try! If you find any issues please let us know by [raising a support ticket]({{< relref "/nginxaas-azure/troubleshooting/troubleshooting.md" >}}). + +Visit the [Known issues]({{< relref "/nginxaas-azure/known-issues.md" >}}) section to learn about the issues present in this release. diff --git a/content/nginxaas-azure/changelog-archive/changelog-2023.md b/content/nginxaas-azure/changelog-archive/changelog-2023.md new file mode 100644 index 000000000..44573249c --- /dev/null +++ b/content/nginxaas-azure/changelog-archive/changelog-2023.md @@ -0,0 +1,315 @@ +--- +title: "2023" +weight: 100 +toc: true +--- + +Learn about the updates, new features, and resolved bugs in F5 NGINX as a Service for Azure during the year 2023. + +To see the latest changes, visit the [Changelog]({{< relref "/nginxaas-azure/changelog" >}}) page. + +To see a list of currently active issues, visit the [Known issues]({{< relref "/nginxaas-azure/known-issues.md" >}}) page. + +## December 19, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports new metrics** + + NGINXaaS now supports the following metrics derived from NGINX Plus statistics introduced in + + API version 8: + - SSL statistics for each HTTP upstream and stream upstream + - SSL statistics for each HTTP server zone and stream server zone + - Extended statistics for SSL endpoint + + API version 9: + - Per-worker connection statistics including accepted, dropped, active and idle connections, total and current requests + + For a complete catalog of metrics, see the [Metrics Catalog]({{< relref "/nginxaas-azure/monitoring/metrics-catalog.md">}}). + +## December 6, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports NGINX config dry-run** + + NGINXaaS now supports the NGINX config dry-run. See the [Config Validation]({{< relref "/nginxaas-azure/getting-started/nginx-configuration#nginx-configuration-validation" >}}) documentation for instructions on how to use it. + + +## November 2, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports the Image-Filter dynamic module** + + NGINXaaS now supports the [Image-Filter](http://nginx.org/en/docs/http/ngx_http_image_filter_module.html) dynamic module. For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in Japan East. + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of regions where NGINXaaS for Azure is available. + +## October 31, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports HTTP/3 and QUIC.** + + NGINXaaS can now serve client requests through HTTP/3 connections. NGINX only supports HTTP/3 on the client side and does not support HTTP/3 to upstreams. NGINXaaS utilizes the [OpenSSL](https://openssl.org/) library; however, the OpenSSL compatibility layer it uses does not support [early data](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data). + + + ```nginx + http { + server { + # for better compatibility it's recommended + # to use the same port for http/3 and https + listen 443 quic reuseport; + listen 443 ssl; + ssl_certificate /etc/nginx/foo.pem; + ssl_certificate_key /etc/nginx/foo.key; + # ... + } + } + ``` + + To get started using HTTP/3 and NGINXaaS: + + - Update the [network security group](https://docs.microsoft.com/en-us/azure/virtual-network/tutorial-filter-network-traffic#create-security-rules) associated with the NGINXaaS deployment’s subnet to allow inbound traffic for HTTP/3 UDP ports in the NGINX configuration. + See our [FAQ]({{< relref "/nginxaas-azure/faq" >}}), for limits on how many unique ports may be specified in a configuration and a list of restricted ports. + + - Additionally, add a [Managed Identity]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) to your deployment and create [SSL/TLS Certificates]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/" >}}). For more information on using NGINX with HTTP/3, see the [HTTP/3 module](https://nginx.org/en/docs/http/ngx_http_v3_module.html). + +## October 25, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in North Europe. + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of regions where NGINXaaS for Azure is available. + +## October 15, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure supports new dynamic modules** + + NGINXaaS now supports the [OpenTelemetry](https://nginx.org/en/docs/ngx_otel_module.html) and [XSLT](https://nginx.org/en/docs/http/ngx_http_xslt_module.html) modules. + +## October 11, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports smaller deployments** + + You can now create or scale deployments to a capacity of 10 NCUs, ideal for small workloads. + +## October 9, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure maximum capacity increased** + + The maximum capacity of NGINXaaS for Azure has been increased from 160 NCUs to **500 NCUs** under the **Standard** plan. Existing deployments can also benefit from this new limit if users choose to scale up. + + To adjust capacity, refer to [Adjusting Capacity]({{< relref "/nginxaas-azure/quickstart/scaling.md#adjusting-capacity" >}}). + + To learn more about capacity restrictions, refer to [Capacity Restrictions]({{< relref "/nginxaas-azure/quickstart/scaling.md#capacity-restrictions" >}}). + +## September 13, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports serving static content** + + An NGINXaaS deployment can now serve static content. See [Hosting Static Content]({{< relref "/nginxaas-azure/quickstart/hosting-static-content.md" >}}) for details. + +## August 23, 2023 + +- {{% icon-resolved %}} **NGINXaaS for Azure now supports attaching a Public IP from a Public IP prefix** + + In the Microsoft Azure portal, you can [create a static public IP address from an IP prefix](https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/create-public-ip-prefix-portal?tabs=create-default#create-a-static-public-ip-address-from-a-prefix). This release of NGINXaaS introduces support for attaching public IP addresses associated with a public IP prefix to your NGINXaaS deployments. + +## Aug 7, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now deploys with a default configuration** + + NGINXaaS new deployments will now include a default configuration, providing a smoother setup experience compared to the previous empty configuration. + + To learn more about configuration, refer to [Upload an NGINX Configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md" >}}). + + - {{% icon-feature %}} **NGINXaaS for Azure now supports more directives** + + NGINXaaS now supports new directives. For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +## July 27, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports higher capacity** + + NGINXaaS for Azure allowed users to create deployments with a maximum capacity of 80 NCUs under the **Standard** plan. A recent change now allows users to deploy up to **160 NCUs**. Existing NGINXaaS deployments should also scale up to 160 NCUs. + + To adjust capacity, refer [Adjusting Capacity]({{< relref "/nginxaas-azure/quickstart/scaling.md#adjusting-capacity" >}}). + + To learn more about capacity restrictions, refer to [Capacity Restrictions]({{< relref "/nginxaas-azure/quickstart/scaling.md#capacity-restrictions" >}}). + +## July 13, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure automatically rotates SSL/TLS certificates** + + NGINXaaS for Azure now automatically retrieves renewed certificates from Azure Key Vault and applies them to your NGINX deployment. To learn more about this new feature, refer to [Certificate Rotation]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/overview.md#certificate-rotation" >}}). + +## July 7, 2023 + +- {{% icon-feature %}} **Improve compatibility with Azure Key Vault certificates generated through merging from an external provider** (e.g. [keyvault-acmebot](https://github.com/shibayan/keyvault-acmebot)) + + Key Vault's certificate merge command puts the server certificate as the last certificate in the generated PFX but NGINX requires that it be the first one in the generated PEM. NGINXaaS will dynamically reorder the certificates to be in chain order with the server certificate first. + +- {{% icon-feature %}} **Support NGINX `log_not_found` directive ([docs](http://nginx.org/en/docs/http/ngx_http_core_module.html#log_not_found))** + +## June 29, 2023 + +- {{% icon-feature %}} **NGINXaaS can now proxy and load balance UDP traffic.** + + To configure NGINX to handle UDP traffic, specify the [`stream`](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#stream) directive in your NGINX configuration. + + ```nginx + stream { + server { + listen 53 udp; + # ... + } + # ... + } + ``` + + To learn more about load balancing UDP traffic with NGINX, see [TCP and UDP Load Balancing](https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/). + +## June 21, 2023 + +- {{% icon-resolved %}} **NGINXaaS for Azure accepts configurations larger than 60kB** + + An NGINXaaS deployment can now accept configurations larger than 60kB. + +## June 6, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure supports new directives** + + NGINXaaS now allows the `ssl_preread` directive and most directives from the `ngx_http_fastcgi_module` module. For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +## May 31, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in the following additional regions: + + - West US 3 + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of supported regions. + +## May 17, 2023 + +- {{% icon-feature %}} **NGINXaaS can now proxy and load balance TCP traffic.** + + To configure NGINX to handle TCP traffic, specify the [`stream`](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#stream) directive in your NGINX configuration. + + ```nginx + stream { + server { + listen 12345; + # ... + } + # ... + } + ``` + + To learn more about load balancing TCP traffic with NGINX, see [TCP and UDP Load Balancing](https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/). + +## May 1, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure supports passing traffic to gRPC servers.** + + NGINXaaS can now be configured as a gateway for gRPC services. Refer to NGINX's [gRPC module](https://nginx.org/en/docs/http/ngx_http_grpc_module.html) for more information. + +## April 26, 2023 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports HTTP/2.** + + NGINXaaS can now serve client requests through HTTP/2 connections. NGINX only supports HTTP/2 on the client side and does not support HTTP/2 to upstreams. + + ```nginx + http { + server { + listen 443 ssl http2; + + ssl_certificate server.crt; + ssl_certificate_key server.key; + # ... + } + } + ``` + + To get started using HTTP/2 and NGINXaaS, add a [Managed Identity]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) to your deployment and create [SSL/TLS Certificates]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/" >}}). For more information on using NGINX with HTTP/2, see the [HTTP/2 module](https://nginx.org/en/docs/http/ngx_http_v2_module.html). + +- {{% icon-resolved %}} NGINXaaS can now serve static files with the `error_page` directive. + +## April 17, 2023 + +- {{% icon-feature %}} **NGINXaaS can now support NGINX configurations to secure HTTP traffic between NGINX and upstreams** + + NGINXaaS now accepts NGINX directives to secure traffic between NGINX and upstream using SSL/TLS certificates. + + Refer to [Securing Upstream Traffic]({{< relref "/nginxaas-azure/quickstart/security-controls/securing-upstream-traffic.md">}}) for more details on how to configure NGINXaaS with these directives. + +## April 7, 2023 + +- {{% icon-feature %}} **NGINX configurations may now listen on ports other than 80 and 443.** + + NGINXaaS now accepts requests on ports in addition to 80 and 443. Inbound ports are specified in the NGINX configuration using the [`listen`](https://nginx.org/en/docs/http/ngx_http_core_module.html#listen) directive. + + NGINXaas can be configured to accept requests on up to 5 unique ports. + + ```nginx + http { + server { + listen 8080; + # ... + } + } + ``` + + Update the [network security group's inbound security rules](https://docs.microsoft.com/en-us/azure/virtual-network/tutorial-filter-network-traffic#create-security-rules) associated with the NGINXaaS deployment's subnet to allow inbound traffic for all listen ports in the NGINX configuration. + + See our [FAQ]({{< relref "/nginxaas-azure/faq" >}}), for limits on how many unique ports may be specified in a configuration and a list of restricted ports. + + +## March 16, 2023 + +- {{% icon-resolved %}} Deployment configuration now succeeds after adding a managed identity. + + After adding a managed identity to a deployment, the deployment transitions from an **Accepted** state to a **Succeeded** state only after the operation to add the managed identity succeeds. The user can then proceed to configure the deployment. + + +## February 21, 2023 + +- {{% icon-feature %}} **Directives `auth_jwt_key_file` and `auth_jwt_require` are now supported.** + + Refer to the [`auth_jwt_key_file`](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_key_file) and [`auth_jwt_require`](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_require) documentation for more information on using these directives. + + - {{% icon-resolved %}} **PKCS12 certificates may now be added to your NGINXaaS deployment.** + + Previously, NGINXaaS only accepted PEM formatted certificates. Now, both PEM and PKCS12 certificates are supported. + + - {{% icon-resolved %}} **State files may now be used with the `keyval_zone` directive.** + + For information on storing the state of a key-value database with a state file, see [`keyval_zone`](https://nginx.org/en/docs/http/ngx_http_keyval_module.html#keyval_zone)'s documentation. + + +## January 11, 2023 + +- {{% icon-feature %}} **NGINXaaS is generally available** + + We are pleased to announce the general availability of NGINX as a Service (NGINXaaS), a first-party-like experience as a service co-developed by Microsoft and NGINX and tightly integrated into the [Azure](https://azure.microsoft.com/) ecosystem. + + NGINXaaS, powered by [NGINX Plus](https://www.nginx.com/products/nginx/), is a fully managed service that removes the burden of deploying your own NGINX Plus cluster, installing libraries, upgrading, and managing it. + + NGINXaaS simplifies the process of moving your [existing NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration#add-nginx-configuration" >}}) to the Azure cloud. Once your configurations are moved to Azure, [securely manage SSL/TLS certificates and keys stored in Azure Key Vault and reference them within your NGINX configurations]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md" >}}). You can [watch your application's traffic in real time]({{< relref "/nginxaas-azure/monitoring/enable-monitoring" >}}) with Azure monitoring and alerts, and scale your deployment to fit your needs, maximizing cost efficiency. + You can create, update, and delete your NGINXaaS deployment using the [Azure Resource Manager]({{< relref "/nginxaas-azure/client-tools/templates.md" >}}), the [Azure SDK]({{< relref "/nginxaas-azure/client-tools/sdk" >}}), [CLI]({{< relref "/nginxaas-azure/getting-started/create-deployment/deploy-azure-cli.md" >}}), and [Terraform]({{< relref "/nginxaas-azure/getting-started/create-deployment/deploy-terraform.md" >}}) in addition to the [Azure portal]({{< relref "/nginxaas-azure/getting-started/create-deployment/" >}}). + + Our new "Standard" plan is ready for production workloads. + + To learn more, refer to the following NGINXaaS documentation: + + - [NGINXaaS for Azure overview]({{< relref "/nginxaas-azure/overview/overview.md" >}}) + - [NGINXaaS, NGINX Plus, and NGINX Open Source feature comparison]({{< relref "/nginxaas-azure/overview/feature-comparison.md" >}}) + - [NGINXaaS billing details]({{< relref "/nginxaas-azure/billing/overview.md" >}}) + +## January 10, 2023 + +- {{% icon-resolved %}} **Special parameters in `map` and `geo` directives are now supported.** + +- {{% icon-resolved %}} **The `match` directive is now supported.** \ No newline at end of file diff --git a/content/nginxaas-azure/changelog.md b/content/nginxaas-azure/changelog.md new file mode 100644 index 000000000..62174e020 --- /dev/null +++ b/content/nginxaas-azure/changelog.md @@ -0,0 +1,295 @@ +--- +title: "Changelog" +weight: 900 +toc: true +docs: "DOCS-870" +--- + +Learn about the latest updates, new features, and resolved bugs in F5 NGINX as a Service for Azure. + +To see a list of currently active issues, visit the [Known issues]({{< relref "/nginxaas-azure/known-issues.md" >}}) page. + +To review older entries, visit the [Changelog archive]({{< relref "/nginxaas-azure/changelog-archive" >}}) section. + +## Feb 10, 2025 + +- {{% icon-feature %}} **NGINXaaS Load Balancer for Kubernetes is now Generally Available** + + NGINXaaS can now be used as an external load balancer to route traffic to workloads running in your Azure Kubernetes Cluster. To learn how to set it up, see the [Quickstart Guide]({{< relref "/nginxaas-azure/quickstart/loadbalancer-kubernetes.md">}}). + +## January 23, 2025 + +- {{< icon-feature >}} **In-place SKU Migration from Standard to Standard V2** + + You can now migrate NGINXaaS for Azure from the Standard plan to the Standard V2 plan without redeploying. We recommend upgrading to the Standard V2 plan to access features like NGINX App Protect WAF and more listen ports. The Standard plan will be retired soon. For migration details, see [migrate from standard]({{< relref "/nginxaas-azure/troubleshooting/migrate-from-standard.md">}}). + +## December 17, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure can integrate with Azure Network Security Perimeter** + + NGINXaaS can now integrate with [Azure Network Security Perimeter](https://learn.microsoft.com/en-us/azure/private-link/network-security-perimeter-concepts). This integration allows users to set up access rules, so their NGINXaaS deployment can retrieve certificates from Azure Key Vault, while blocking all other public access to the key vault. For more information, please refer to the [Configure Network Security Perimeter]({{< relref "/nginxaas-azure/quickstart/security-controls/certificates.md#configure-network-security-perimeter-nsp" >}}) documentation. + +## December 3, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports the GeoIP2 dynamic module** + + NGINXaaS now supports the [GeoIP2](https://github.com/leev/ngx_http_geoip2_module) dynamic module. For more information, see [GeoIP2 quickstart]({{< relref "/nginxaas-azure/quickstart/geoip2.md">}}). For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/#configuration-directives-list" >}}). + +## November 18, 2024 + +- {{% icon-resolved %}} **Consumed NCUs metric more accurately accounts for concurrent connections** + + The consumed NCUs metric now uses the `system.worker_connections` metric to more accurately determine the number of concurrent connections used by NGINX. Previously NGINXaaS was underreporting the number of concurrent connections used by NGINX, improperly omitting connections to upstreams. + + Users may notice an increase in their deployments' consumed NCUs if their deployments are handling a large number of connections. This fix will help to make autoscaling more responsive to changes in incoming traffic. Customers using autoscaling may notice that their deployments scale out if the number of concurrent connections increases significantly. + +## November 8, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now improves visibility and management of protected files** + + Users can now view the file paths and associated metadata of protected files added to the NGINX configuration of an NGINXaaS deployment, while the file contents remain confidential. Users can also overwrite an existing protected file with new file contents or resubmit it without having to provide the file contents again. + + For more details on protected files, refer to the [Add an NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#add-an-nginx-configuration" >}}) section. + +## October 23, 2024 + +- {{% icon-feature %}} **NGINXaaS Load Balancer for Kubernetes preview release** + + You can now use NGINXaaS as an external load balancer to direct traffic into Kubernetes. For details, see the [quickstart]({{< relref "/nginxaas-azure/quickstart/loadbalancer-kubernetes.md" >}}). + +## October 10, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in the following additional regions: + + - Brazil South + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of regions where NGINXaaS for Azure is available. + +## September 18, 2024 + +- {{% icon-feature %}} **NGINXaaS is now running NGINX Plus Release 32 (R32) in the Stable Upgrade Channel** + + NGINXaaS for Azure deployments using the **Stable** [Upgrade Channel]({{< relref "/nginxaas-azure/quickstart/upgrade-channels.md" >}}) have now been automatically upgraded to [NGINX Plus Release 32 (R32)](https://docs.nginx.com/nginx/releases/#nginxplusrelease-32-r32). This upgrade also includes updates to the following NGINX Plus modules: + - nginx-plus-module-headers-more + - nginx-plus-module-image-filter + - nginx-plus-module-lua + - nginx-plus-module-ndk + - nginx-plus-module-njs + - nginx-plus-module-otel + - nginx-plus-module-xslt + + For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +## September 13, 2024 + +- {{< icon-warning >}} **Standard plan retirement** + +NGINXaaS for Azure now supports the [Standard V2](https://docs.nginx.com/nginxaas/azure/billing/overview) plan. We encourage you to use the Standard V2 plan for all new NGINXaaS deployments from now on to take advantage of additional features like NGINX App Protect WAF and a higher number of listen ports. The Standard V2 plan follows a similar pricing model as the Standard plan. + +{{}}The Standard plan will be deprecated and will not be available for new deployments starting November 1, 2024.{{}} + +Your current deployments on the Standard plan will continue to function but won't include any of the new features we've introduced in the Standard V2 plan. Additionally, we intend to phase out the Standard plan in the future. When this happens, we will offer a migration path to the Standard V2 plan for existing NGINXaaS deployments on the Standard plan. + +- **Recommended action:** + + Update your automation scripts to use the Standard V2 plan. The SKU for the Standard V2 pricing plan is `standardv2_Monthly`. + +If you have any questions or concerns, please [contact us](https://portal.azure.com/#view/Microsoft_Azure_Support/HelpAndSupportBlade/~/overview). + +## Aug 29, 2024 + +- {{% icon-feature %}} **The backend subnet of an NGINXaaS deployment can now be updated** + +An NGINXaaS deployment can now be gracefully updated to a new subnet with zero downtime. Currently, this capability is available through ARM templates or the Azure CLI. Support through other client tools is coming soon. + +## Aug 22, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports NGINX App Protect WAF in Preview** + + NGINXaaS now supports [NGINX App Protect WAF](https://docs.nginx.com/nginx-app-protect-waf/v5) in Preview as part of the [Standard v2 plan]({{< relref "/nginxaas-azure/billing/overview.md#standard-v2-plan">}}). For more information, see [enable WAF]({{< relref "/nginxaas-azure/app-protect/enable-waf.md">}}). + +## Aug 16, 2024 + +- {{% icon-feature %}} **Notification on update to deployments using the Stable Upgrade Channel** + + NGINXaaS for Azure deployments using the **Stable** [Upgrade Channel]({{< relref "/nginxaas-azure/quickstart/upgrade-channels.md" >}}) will be updated to [NGINX Plus Release 32 (R32)](https://docs.nginx.com/nginx/releases/#nginxplusrelease-32-r32) during the week of September 16-22, 2024. This will also include updates to the following NGINX Plus modules: + - nginx-plus-module-headers-more + - nginx-plus-module-image-filter + - nginx-plus-module-lua + - nginx-plus-module-ndk + - nginx-plus-module-njs + - nginx-plus-module-otel + - nginx-plus-module-xslt + + Please review the [NGINX Plus Release 32 (R32)](https://docs.nginx.com/nginx/releases/#nginxplusrelease-32-r32) Release Notes carefully. If you have any concerns, it's recommended to validate your configuration against NGINX Plus R32 by setting up a test deployment using the **Preview** [Upgrade Channel]({{< relref "/nginxaas-azure/quickstart/upgrade-channels.md" >}}). See [these instructions]({{< relref "/nginxaas-azure/quickstart/recreate.md" >}}) on how to set up a deployment similar to your current one. + + If you have any questions or concerns, please [contact us]({{< relref "troubleshooting/troubleshooting.md" >}}). + +## July 30, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in the following additional regions: + + - Central India + - South India + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of regions where NGINXaaS for Azure is available. + +## July 23, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in the following additional regions: + + - Germany West Central + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of regions where NGINXaaS for Azure is available. + +## July 10, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in the following additional regions: + + - Southeast Asia + - Sweden Central + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of regions where NGINXaaS for Azure is available. + +## June 28, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports the Lua dynamic module** + + NGINXaaS now supports the [Lua](https://github.com/openresty/lua-nginx-module) dynamic module `v0.10.25`. The `lua_capture_error_log` directive is not supported at this time. For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +## June 18, 2024 + +- {{% icon-feature %}} **NGINXaaS now supports NGINX Plus Release 31 (R31)** + + NGINXaaS now supports [NGINX Plus Release 31 (R31)](https://docs.nginx.com/nginx/releases/#nginxplusrelease-31-r31). For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +## June 17, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports the Headers-More dynamic module** + + NGINXaaS now supports the [Headers-More](https://github.com/openresty/headers-more-nginx-module) dynamic module. For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +## June 6, 2024 + +- {{% icon-feature %}} **Notification on update to deployments using the Stable Upgrade Channel** + + NGINXaaS for Azure deployments using the **Stable** [Upgrade Channel]({{< relref "/nginxaas-azure/quickstart/upgrade-channels.md" >}}) will be updated to [NGINX Plus Release 31 (R31)](https://docs.nginx.com/nginx/releases/#nginxplusrelease-31-r31) during the week of June 17-23, 2024. This will also include updates to the following NGINX Plus modules: + + - nginx-plus-module-headers-more + - nginx-plus-module-image-filter + - nginx-plus-module-lua + - nginx-plus-module-ndk + - nginx-plus-module-njs + - nginx-plus-module-otel + - nginx-plus-module-xslt + + Please review the [NGINX Plus Release 31 (R31)](https://docs.nginx.com/nginx/releases/#nginxplusrelease-31-r31) Release Notes carefully. If you have any concerns, it's recommended to validate your configuration against NGINX Plus R31 by setting up a test deployment using the **Preview** [Upgrade Channel]({{< relref "/nginxaas-azure/quickstart/upgrade-channels.md" >}}). See [these instructions]({{< relref "/nginxaas-azure/quickstart/recreate.md" >}}) on how to set up a deployment similar to your current one. + + If you have any questions or concerns, please [contact us]({{< relref "troubleshooting/troubleshooting.md" >}}). + +## May 20, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports a Basic plan for dev/test purposes** + + For trial, development and testing purposes without SLA guarantees, redundancy or scaling, NGINXaaS provides the ability to choose a Basic plan deployment. For more information, see [pricing plans]({{< ref "billing/overview.md#pricing-plans">}}). + +## April 18, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports runtime state sharing** + + NGINXaaS instances can now synchronize shared memory zones when configured to enable [Runtime State Sharing](https://docs.nginx.com/nginx/admin-guide/high-availability/zone_sync/). + + This feature allows for some data to be shared between NGINXaaS instances including: + + - [Sticky‑learn session persistence](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky_learn) + - [Rate limiting](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone) + - [Key‑value store](https://nginx.org/en/docs/http/ngx_http_keyval_module.html#keyval_zone) + + [Runtime State Sharing](https://docs.nginx.com/nginx/admin-guide/high-availability/zone_sync/) enables NGINXaaS to be configured for use cases such as [OIDC](https://github.com/nginxinc/nginx-openid-connect) and [SAML](https://github.com/nginxinc/nginx-saml) authentication. + + Refer to [Runtime State Sharing with NGINXaaS for Azure]({{< relref "/nginxaas-azure/quickstart/runtime-state-sharing.md" >}}) for the configuration guide. + +- {{% icon-feature %}} **NGINXaaS for Azure now supports metrics from stream zone_sync statistics** + + For a complete catalog of metrics, see the [Metrics Catalog]({{< relref "/nginxaas-azure/monitoring/metrics-catalog.md">}}). + +## April 9, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure supports autoscaling and Upgrade Channels on all client tools** + + In addition to the Azure Portal and the ARM API version `2024-01-01-preview`, you can now use all other client tools, such as the Azure CLI or Terraform, to enable autoscaling or specify an Upgrade Channel. + + For more information on autoscaling, see the [Autoscaling documentation]({{< relref "/nginxaas-azure/quickstart/scaling.md#autoscaling">}}). + For more information on Upgrade Channels, see [Upgrade Channels]({{< relref "/nginxaas-azure/quickstart/upgrade-channels.md" >}}). + +- {{% icon-feature %}} **NGINXaaS for Azure can now accept a system assigned and a user assigned managed identity** + + NGINXaaS for Azure now allows using a system assigned managed identity and a user assigned managed identity at the same time per deployment. This provides flexibility in assigning role permissions for integrations that NGINXaaS for Azure require. + +## March 21, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports Upgrade Channels** + + An Upgrade Channels lets you control the frequency at which your NGINXaaS deployment receives upgrades for NGINX Plus and its related modules. For more information, see [Upgrade Channels]({{< relref "/nginxaas-azure/quickstart/upgrade-channels.md" >}}). + +## March 20, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports autoscaling** + + Enable autoscaling to automatically adjust the size of your deployment based on the traffic requirements. Autoscaling can be enabled in the Azure Portal or the ARM API version `2024-01-01-preview`, with other client tools coming soon. + + For more information on autoscaling, see the [Autoscaling documentation]({{< relref "/nginxaas-azure/quickstart/scaling.md#autoscaling">}}). + +## March 13, 2024 + +- {{% icon-resolved %}} **Fixed a known issue causing Terraform to show an error while trying to manage configuration of a new deployment (ID-891)** + + NGINXaaS for Azure now requires users to take an explicit action to create a default NGINX configuration with a deployment. We have added the "Apply default NGINX configuration" field in the [updated deployment creation workflow]({{< relref "/nginxaas-azure/getting-started/create-deployment/deploy-azure-portal.md#networking-tab" >}}) in the Azure portal. For other client tools like Terraform, NGINXaaS for Azure now requires users to explicitly create an NGINX configuration. + +## March 5, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure now supports configuring NGINX Plus as a mail proxy server** + + Enhance your email service’s efficiency by utilizing NGINX Plus as a mail proxy for IMAP, POP3, and SMTP protocols, streamlining configuration for mail servers and external services. + + Please note that NGINXaaS does not support outbound connections on port 25, and an alternative port should be used for SMTP. Additionally, ensure network connectivity from the NGINXaaS deployment to both the mail server and authentication server to support proper mail authentication. + + For a complete list of allowed directives, see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +- {{% icon-feature %}} **NGINXaaS for Azure now supports resolver statistics metrics** + + For a complete catalog of metrics, see the [Metrics Catalog]({{< relref "/nginxaas-azure/monitoring/metrics-catalog.md">}}). + +## February 15, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in the following additional regions: + + - Japan West + - Korea South + - Korea Central + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of regions where NGINXaaS for Azure is available. + +## February 8, 2024 + +- {{% icon-feature %}} ****NGINXaaS for Azure now supports [Diagnostic settings in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/diagnostic-settings) to send NGINX logs to different destinations**** + + An NGINXaaS deployment now supports adding Diagnostic Settings to export NGINX logs. See [Enable NGINX Logs]({{< relref "/nginxaas-azure/monitoring/enable-logging/" >}}) for more details. + +## January 22, 2024 + +- {{% icon-feature %}} **NGINXaaS for Azure is now generally available in more regions** + + NGINXaaS for Azure is now available in Canada Central. + + See the [Supported Regions]({{< relref "/nginxaas-azure/overview/overview.md#supported-regions" >}}) documentation for the full list of regions where NGINXaaS for Azure is available. diff --git a/content/nginxaas-azure/client-tools/_index.md b/content/nginxaas-azure/client-tools/_index.md new file mode 100644 index 000000000..5861b0207 --- /dev/null +++ b/content/nginxaas-azure/client-tools/_index.md @@ -0,0 +1,10 @@ +--- +title: Client tools +weight: 500 +draft: false +toc: true +url: /nginxaas/azure/client-tools/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/client-tools/cli.md b/content/nginxaas-azure/client-tools/cli.md new file mode 100644 index 000000000..5a321b8aa --- /dev/null +++ b/content/nginxaas-azure/client-tools/cli.md @@ -0,0 +1,31 @@ +--- +title: "Azure CLI" +weight: 900 +description: "Learn how to setup the Azure CLI to manage NGINXaaS for Azure." +categories: ["platform-management"] +toc: true +docs: "DOCS-1234" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) deployments can be managed using the [Azure CLI](https://learn.microsoft.com/en-us/cli/azure/). This document outlines how to install the CLI tool including the NGINX extension. + +## Prerequisites + +- Install Azure CLI version 2.67.0 or greater: [Azure CLI Installation](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli)) +- Log into your Azure account through the CLI: [Azure CLI Authentication](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli). + +## Install NGINXaaS extension + +In order to install and manage your NGINXaaaS deployments using the Azure CLI, you will need to install the `nginx` extension: + +```bash +az extension add --name nginx --allow-preview true +``` + +## Update NGINXaaS extension + +Ensure you are running the latest version of the `nginx` CLI extension to take advantage of the latest capabilities available on your NGINXaaS deployments: + +```bash +az extension update --name nginx --allow-preview true +``` diff --git a/content/nginxaas-azure/client-tools/sdk.md b/content/nginxaas-azure/client-tools/sdk.md new file mode 100644 index 000000000..9c99d8f6b --- /dev/null +++ b/content/nginxaas-azure/client-tools/sdk.md @@ -0,0 +1,55 @@ +--- +title: "Azure SDK" +weight: 300 +description: "Learn how to use the Python Azure Management SDK to manage NGINXaaS for Azure deployments." +categories: ["platform-management"] +toc: true +docs: "DOCS-1095" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) deployments can be managed using the multi-language SDK. This document outlines common workflows using the Python SDK. You can find example code to manage NGINXaaS deployments and related objects in the NGINXaaS GitHub repository, [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/sdk/python/). + +## Prerequisites + +- [NGINXaaS Prerequisites]({{< relref "/nginxaas-azure/getting-started/prerequisites.md" >}}) +- Install Azure Identity package - [azure-identity](https://pypi.org/project/azure-identity/) +- Install the NGINX SDK - [azure-mgmt-nginx](https://pypi.org/project/azure-mgmt-nginx/) +- See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/sdk/python/deployments/) for an example script to create prerequisite resources. + +## Workflows + +- For a complete list of NGINXaaS SDK documentation, see the [Azure NGINXaaS SDK Documentation](https://learn.microsoft.com/en-us/python/api/overview/azure/mgmt-nginx-readme) +- [Azure Authentication SDK Documentation](https://learn.microsoft.com/en-us/azure/developer/python/sdk/authentication-overview) + +### Create or update a deployment + +For example scripts to create or update deployment resources, see [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/sdk/python/deployments/) + +- [Azure SDK Deployment Create or Update Documentation](https://learn.microsoft.com/en-us/python/api/azure-mgmt-nginx/azure.mgmt.nginx.operations.deploymentsoperations?view=azure-python#azure-mgmt-nginx-operations-deploymentsoperations-begin-create-or-update) +- [Azure SDK Deployment Delete Documentation](https://learn.microsoft.com/en-us/python/api/azure-mgmt-nginx/azure.mgmt.nginx.operations.deploymentsoperations?view=azure-python#azure-mgmt-nginx-operations-deploymentsoperations-begin-delete) +- [NGINXaaS Managed Identity Documentation]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) +- [NGINXaaS Azure Monitor Documentation]({{< relref "/nginxaas-azure/monitoring/enable-monitoring/" >}}) + +### Create or update a certificate + +Create or update a certificate under a deployment. This references an existing certificate in an Azure Key Vault and makes it available to the NGINX configuration. See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/sdk/python/certificates/) for example scripts to create or update deployment certificate resources. + +- [Azure SDK Certificate Create or Update Documentation](https://learn.microsoft.com/en-us/python/api/azure-mgmt-nginx/azure.mgmt.nginx.operations.certificatesoperations?view=azure-python#azure-mgmt-nginx-operations-certificatesoperations-begin-create-or-update) +- [Azure SDK Certificate Delete Documentation](https://learn.microsoft.com/en-us/python/api/azure-mgmt-nginx/azure.mgmt.nginx.operations.configurationsoperations?view=azure-python#azure-mgmt-nginx-operations-configurationsoperations-begin-delete) +- [NGINXaaS Certificates Documentation]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md" >}}) +- [Azure SDK Key Vault Documentation](https://learn.microsoft.com/en-us/python/api/overview/azure/key-vault) + +### Create or update a configuration + +Create or update the default configuration for a deployment using a gzipped archive based on the NGINXaaS documentation below. See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/sdk/python/configurations/) for example scripts to create or update deployment configuration resources. + +- [Azure SDK Configuration Create or Update Documentation](https://learn.microsoft.com/en-us/python/api/azure-mgmt-nginx/azure.mgmt.nginx.operations.configurationsoperations?view=azure-python#azure-mgmt-nginx-operations-configurationsoperations-begin-create-or-update) +- [NGINXaaS GZIP Configuration Documentation]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#upload-gzip-nginx-configuration" >}}) + +## Additional Docs + +- [Python Azure SDK Overview](https://learn.microsoft.com/en-us/python/api/overview/azure/nginx) +- [Java Azure SDK Overview](https://learn.microsoft.com/en-us/java/api/overview/azure/nginx) +- [JavaScript Azure SDK Overview](https://learn.microsoft.com/en-us/javascript/api/overview/azure/nginx) +- [Go Azure SDK Documentation](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/nginx/armnginx) +- [.NET Azure SDK Overview (Preview)](https://learn.microsoft.com/en-us/dotnet/api/overview/azure/nginx?view=azure-dotnet-preview) diff --git a/content/nginxaas-azure/client-tools/templates.md b/content/nginxaas-azure/client-tools/templates.md new file mode 100644 index 000000000..361119999 --- /dev/null +++ b/content/nginxaas-azure/client-tools/templates.md @@ -0,0 +1,46 @@ +--- +title: "Azure Resource Manager templates" +weight: 100 +description: "Learn how to use Azure Resource Manager (ARM) JSON and Bicep templates to manage NGINXaaS for Azure." +categories: ["platform-management"] +toc: true +docs: "DOCS-1097" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) deployments can be managed using the ARM API or the Azure CLI with ARM template deployments using JSON or Bicep formats. These deployments can be made locally or in a continuous integration pipeline. This document outlines common workflows using the ARM API. You can find example code to manage NGINXaaS deployments and related objects in the NGINXaaS GitHub repository, [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets). + +## Prerequisites + +- [NGINXaaS Prerequisites]({{< relref "/nginxaas-azure/getting-started/prerequisites.md" >}}) +- [Azure CLI Installation](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) +- You need to be logged in to your Azure account through the CLI if you are using that for template deployment, see [Azure CLI Authentication](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli) +- See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/arm-templates/deployments/prerequisites) for an example template to create the prerequisite resources. + +## Workflows + +### Create or update a deployment + +See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/arm-templates/deployments/create-or-update) for an example template to create or update deployment resources. + +- [NGINXaaS Managed Identity Documentation]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) +- [NGINXaaS Azure Monitor Documentation]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}) + +### Create or update a certificate + +Create or update a certificate under a deployment. This references an existing certificate in an Azure Key Vault and makes it available to the NGINX configuration. See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/arm-templates/certificates/create-or-update) for an example template to create or update certificate resources. + +- [NGINXaaS Certificates Documentation]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md" >}}) +- [ARM Template Key Vault Documentation](https://learn.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults) + +### Create or update a configuration + +Create or update the default configuration for a deployment using a gzipped archive based on the NGINXaaS documentation below. See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/arm-templates/configuration) for an example template to create or update configuration resources. + +- [NGINXaaS GZIP Configuration Documentation]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#upload-gzip-nginx-configuration" >}}) + +## Additional Docs + +If you are new to Azure Resource Manager templates, see: + +- [Azure JSON Templates Overview](https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/overview) +- [Azure Bicep Templates Overview](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview) diff --git a/content/nginxaas-azure/client-tools/terraform.md b/content/nginxaas-azure/client-tools/terraform.md new file mode 100644 index 000000000..bc84df03d --- /dev/null +++ b/content/nginxaas-azure/client-tools/terraform.md @@ -0,0 +1,45 @@ +--- +title: "Terraform" +weight: 400 +description: "Learn how to use the Terraform to manage NGINXaaS for Azure." +categories: ["platform-management"] +toc: true +docs: "DOCS-1472" +draft: true +--- + +F5 NGINX as a Service for Azure (NGINXaaS) deployments can be managed using Terraform. This document outlines common Terraform workflows for NGINXaaS. + +## Prerequisites + +- [NGINXaaS Prerequisites]({{< relref "/nginxaas-azure/getting-started/prerequisites.md" >}}) +- [Authenticate Terraform to Azure](https://learn.microsoft.com/en-us/azure/developer/terraform/authenticate-to-azure) +- [Install Terraform](https://developer.hashicorp.com/terraform/downloads) + +## Workflows + +### Create or update a deployment + +See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/deployments/create-or-update) for an example to create or update deployment resources. + +- [NGINXaaS Managed Identity Documentation]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) +- [NGINXaaS Azure Monitor Documentation]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}) + +### Create or update a certificate + +Upload a self-signed certificate created in Azure Key Vault to a deployment. See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/certificates) for an example to create or update certificate resources. + +- [NGINXaaS Certificates Documentation]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md" >}}) + +### Create or update a configuration + +Upload an example multi-file NGINX configuration to a deployment. See [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/configurations) for an example to create or update configurations resources. + +- [NGINXaaS Configuration Documentation]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md" >}}) + +## Additional Docs + +- [Managing an NGINXaaS for Azure deployment](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nginx_deployment) +- [Managing an NGINXaaS for Azure deployment configuration](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nginx_configuration) +- [Managing an NGINXaaS for Azure deployment certificate](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nginx_certificate) +- If you are new to Terraform, see [Terraform Overview](https://www.terraform.io/) diff --git a/content/nginxaas-azure/faq.md b/content/nginxaas-azure/faq.md new file mode 100644 index 000000000..56e427307 --- /dev/null +++ b/content/nginxaas-azure/faq.md @@ -0,0 +1,254 @@ +--- +title: "Frequently Asked Questions" +weight: 800 +categories: ["concepts"] +toc: true +docs: "DOCS-881" +--- + +Common questions about F5 NGINX as a Service for Azure (NGINXaaS). + +### Is NGINXaaS available in my subscription or in F5 subscription? +- Your NGINXaaS deployment resource is visible to you under your subscription. The underlying compute resources of your deployment, which are managed by NGINX on your behalf, are not visible in your subscription. + +### Is NGINXaaS active-active? What is the architecture of NGINXaaS? +- NGINXaaS is deployed as an active-active pattern for high availability. To learn more, see the [user guide]({{< relref "/nginxaas-azure/overview/overview.md#architecture" >}}). + +### In which Azure regions is NGINXaaS currently supported? +- We are constantly adding support for new regions. You can find the updated list of supported regions in the [NGINXaaS documentation]({{< relref "/nginxaas-azure/overview/overview.md" >}}). + +### My servers are located in different geographies, can NGINXaaS load balance for these upstream servers? +- Yes, NGINXaaS can load balance even if upstream servers are located in different geography as long as no networking limitations are mentioned in the [Known Issues]({{< relref "known-issues.md" >}}). + +### How do I analyze traffic statistics for NGINXaaS? +- NGINXaaS is integrated with [Azure monitoring](https://learn.microsoft.com/en-us/azure/azure-monitor/overview). NGINXaaS publishes [traffic statistics]({{< relref "/nginxaas-azure/monitoring/metrics-catalog.md" >}}) in Azure monitoring. Customers can analyze the traffic statistics by following the steps mentioned in the [NGINXaaS Monitoring]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}) documentation. + +### When should I scale my deployment? +- Consider requesting additional NCUs if the number of consumed NCUs is over 70% of the number of provisioned NCUs. Consider reducing the number of requested NCUs when the number of consumed NCUs is under 60% of the number of provisioned NCUs. For more information on observing the consumed and provisioned NCUs in your deployment, see the [Scaling documentation]({{< relref "/nginxaas-azure/quickstart/scaling.md#metrics" >}}). + +- Alternatively, [enable autoscaling]({{< relref "/nginxaas-azure/quickstart/scaling.md#autoscaling" >}}) to let the system automatically scale your deployment for you. + +### I am an NGINX Plus customer; how can I switch to NGINXaaS? +- In NGINX Plus, customers SSH into the NGINX Plus system, store their certificates in some kind of storage and configure the network and subnet to connect to NGINX Plus. + +- For NGINXaaS, customers store their certificates in the Azure key vault and configure NGINXaaS in the same VNet or peer to the VNet in which NGINXaaS is deployed. + +### How does NGINXaaS react to a workload/traffic spike? +- You can monitor the NCUs consumed by looking at the metrics tab of NGINXaaS. To learn about the NCUs consumed, choose NGINXaaS statistics and select "NCU consumed." If the NCU consumed is close to the requested NCUs, we encourage you to scale your system and increase the NCU units. You can manually scale from your base NCUs (For example, 10) to up to 500 NCUs by selecting the NGINXaaS scaling tab. + +- Currently, we support scaling in 10 NCU intervals (10, 20, 30, and so on). + +- Alternatively, you can enable autoscaling, and NGINXaaS will automatically scale your deployment based on the consumption of NCUs. + +- See the [Scaling Guidance]({{< relref "/nginxaas-azure/quickstart/scaling.md" >}}) documentation for more information. + +### What types and formats of certificates are supported in NGINXaaS? +- NGINXaaS supports self-signed certificates, Domain Validated (DV) certificates, Organization Validated (OV) certificates, and Extended Validation (EV) certificates. + +- Currently, NGINXaaS supports PEM and PKCS12 format certificates. + +- See the [SSL/TLS Certificates documentation]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md" >}}) to learn how to change certificates. + +### Does NGINXaaS support layer 4 load balancing? +- Yes, NGINXaaS currently supports layer 4 TCP and HTTP layer 7 load balancing. + +### Does NGINXaaS support IP v6? +- No, NGINXaaS does not support IPv6 yet. + +### What protocols do NGINXaaS support? + +- At this time, we support the following protocols: + + - HTTPS + - HTTP + - HTTP/2 + - HTTP/3 + - TCP + - QUIC + - IMAP + - POP3 + - SMTP + +### Does NGINXaaS support multiple public IPs, a mix of public and private IPs? + +- NGINXaaS supports one public or private IP per deployment. NGINXaaS doesn't support a mix of public and private IPs at this time. + +### Can I change the IP address used for an NGINXaaS deployment to be public or private? + +- You cannot change the IP address associated with an NGINXaaS deployment from public to private, or from private to public. + +### How large should I make the subnet for NGINXaaS? + +- The minimum subnet size is `/27` and is sufficient for a single NGINXaaS deployment even at large scales. Multiple NGINXaaS deployments can be placed in a single delegated subnet, along with other resources. When doing so, a larger subnet, e.g. a `/24`, is recommended. + +### Can I deploy more than one NGINXaaS to a single subnet? +- Yes, however, every deployment in the subnet will share the address space (range of IP addresses that resources can use within the VNet), so ensure the subnet is adequately sized to scale the deployments. + +### How long does it take to deploy NGINXaaS? +- Typically you can deploy NGINXaaS in under 5 minutes. + +### Any downtime in the periodic updates? +- There's no downtime during updates to NGINXaaS. + +### Does changing the capacity of NGINXaaS result in any downtime? +- No, there's no downtime while an NGINXaaS deployment changes capacity. + +### How is my application safe at the time of disaster? Any method for disaster recovery? +- In any Azure region with more than one availability zone, NGINXaaS provides cross-zone replication for disaster recovery. See [Architecture]({{< relref "/nginxaas-azure/overview/overview.md#architecture" >}}) for more details. + +### Can I configure the TLS policy to control TLS protocol versions? +- Yes. You can overwrite the NGINX default protocol to configure the desired TLS/SSL policy. Read more about the procedure in the [Module ngx_http_ssl_module](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols) documentation. + +### How many TLS/SSL certificates does NGINXaaS support? +- NGINXaaS supports up to 100 TLS/SSL certificates. + +### Does NGINXaaS natively integrate with Azure Key Vault? +- Yes, NGINXaaS natively integrates with Azure Key Vault, so you can bring your own certificates and manage them in a centralized location. You can learn more about adding certificates in Azure Key Vault in the [SSL/TLS Certificates documentation]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md" >}}). + +### Can I deploy any other resources in the NGINXaaS subnet? +- Yes, the subnet can contain other resources and is not dedicated to the NGINXaaS for Azure resources; ensure the subnet size is adequate to scale the NGINXaaS deployment. + +### Are NSG (Network Security Group) supported on the NGINXaaS? +- Yes, an NSG is required in the subnet where NGINXaaS will be deployed to ensure that the deployment is secured and inbound connections are allowed to the ports the NGINX service listens to. + +### Can I restrict access to NGINXaaS based on various criteria, such as IP addresses, domain names, and HTTP headers? +- Yes, you can restrict access to NGINXaaS by defining restriction rules at the Network Security Group level or using NGINX's access control list. To learn more, see the [NGINX module ngx_http_access_module](http://nginx.org/en/docs/http/ngx_http_access_module.html) documentation. + +### What are the supported networking services of NGINXaaS? +- NGINX currently supports VNet, and VPN gateway if they do not have limitations. Known limitations can be found in the [Known Issues]({{< relref "known-issues.md" >}}). + +### Does NGINXaaS support end-to-end encryption from client to the upstream server? +- Yes, NGINXaaS supports end-to-end encryption from client to upstream server. + +### What types of logs does NGINXaaS provide? +- NGINXaaS supports the following [two types of logs]({{< relref "/nginxaas-azure/monitoring/enable-logging/">}}). + +- Access Log: To troubleshoot server issues, analyze web traffic patterns and monitor server performance. For more details, please see the [Module ngx_http_log_module](https://nginx.org/en/docs/http/ngx_http_log_module.html?&_ga=2.80762515.545098740.1677716889-256521444.1670450998#access_log) documentation. + +- Error Log: To capture, troubleshoot and identify issues that may occur during the server's operations, such as 400 bad requests, 401 unauthorized, 500 internal server errors, etc. For more details, please see the [Core functionality](https://nginx.org/en/docs/ngx_core_module.html?&_ga=2.8347062.545098740.1677716889-256521444.1670450998#error_log) documentation. + +### What is the retention policy for the above logs? How long are the logs stored? Where are they stored? +- NGINXaaS logs are stored in customer’s storage. Customers can custom define the retention policy. Customers can configure the storage by following the steps outlined in the [NGINXaaS Logging]({{< relref "/nginxaas-azure/monitoring/enable-logging/">}}) documentation. + +### Can I set up an alert with NGINXaaS? +- You can set up an alert with NGINXaaS by following the steps outlined in the [Configure Alerts]({{< relref "/nginxaas-azure/monitoring/configure-alerts.md">}}) documentation. + +### Is request tracing supported in NGINXaaS? +- Yes, see the [Application Performance Management with NGINX Variables](https://www.nginx.com/blog/application-tracing-nginx-plus/) documentation to learn more about tracing. + +### Can I select my desired instance type for NGINXaaS deployment? +- No; NGINXaaS will deploy the right resources to ensure you get the right price-to-performance ratio. + +### Can I migrate from on-prem NGINX+ to NGINXaaS on Azure? +- Yes, you can bring your own configurations or create a new configuration in the cloud. See the [NGINXaaS Deployment]({{< relref "/nginxaas-azure/getting-started/create-deployment/">}}) documentation for more details. + +### Can I associate multiple certificates for the same domain? +- Yes, the "ssl_certificate" directive can be specified multiple times to load certificates of different types. To learn more, see the [Module ngx_http_ssl_module](http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) documentation. + +### What types of redirects does the NGINXaaS support? +- In addition to HTTP to HTTPS, HTTPS to HTTP, and HTTP to HTTP, NGINXaaS provides the ability to create new rules for redirecting. See [How to Create NGINX Rewrite Rules | NGINX](https://www.nginx.com/blog/creating-nginx-rewrite-rules/) for more details. + +### What content types does NGINXaaS support for the message body for upstream/NGINXaaS error status code responses? +- Customers can use any type of response message, including the following: + + - text/plain + - text/css + - text/html + - application/javascript + - application/json + +### Where do I find the NGINXaaS IP (Internet Protocol) address? +- Once you successfully deploy NGINXaaS, you can double-click on NGINXaaS in the Azure portal; you can see both public and private IP addresses, as shown in the following screenshot: + +{{< img src="nginxaas-azure/faq-ip-location-one.png" alt="IP location one" >}} + +{{< img src="nginxaas-azure/faq-ip-location-two.png" alt="IP location two" >}} + +### Does my deployment IP change over time? +- The NGINXaaS deployment IP doesn't change over time. + +### Does NGINXaaS support autoscaling? +- Yes; NGINXaaS supports autoscaling as well as manual scaling. Refer to the [Scaling Guidance]({{< relref "/nginxaas-azure/quickstart/scaling.md#autoscaling" >}}) for more information. + +### How can I manually start/stop NGINXaaS? +- Currently, we can't manually start/stop NGINXaaS. You have the option to delete the deployment and re-deploy at a future date. + +### Can I change the virtual network or subnet for an existing NGINXaaS? +- If the existing NGINXaaS deployment is using a public IP address, you can change the backend virtual network or subnet. Please make sure that the subnet is delegated to `NGINX.NGINXPLUS/nginxDeployments` before creating a deployment in it. To delegate a subnet to an Azure service, see [Delegate a subnet to an Azure service](https://learn.microsoft.com/en-us/azure/virtual-network/manage-subnet-delegation?source=recommendations#delegate-a-subnet-to-an-azure-service). + +- If the existing NGINXaaS deployment is using a private IP address, you can only change the backend subnet. You cannot change the backend virtual network because the frontend and backend subnets must be in the same virtual network. + +### How do I configure HTTPS listeners for .com and .net sites? +- NGINXaaS is a Layer 7 HTTP protocol. To configure .com and .net servers, refer to the server name in the server block within the HTTP context. To learn more, and see examples, follow the instructions in the [NGINX Configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#nginx-configuration-validation" >}}) documentation. + +### If I remove/delete an NGINXaaS deployment, what will happen to the eNICs that were associated with it? +- When you remove or delete an NGINXaaS deployment, the associated eNICs will automatically be deleted. + +### What are the specific permissions that NGINXaaS for Azure needs? + +- The specific permissions required to deploy NGINXaaS are: + + - microsoft.network/publicIPAddresses/join/action + + - nginx.nginxplus/nginxDeployments/Write + + - microsoft.network/virtualNetworks/subnets/join/action + + - nginx.nginxplus/nginxDeployments/configurations/Write + + - nginx.nginxplus/nginxDeployments/certificates/Write + +- Additionally, if you are creating the Virtual Network or IP address resources that NGINXaaS for Azure will be using, then you probably also want those permissions as well. + +- Note that assigning the managed identity permissions normally requires an “Owner” role. + +### Can I reference my upstream servers by internal DNS hostname? + +- Yes. If your DNS nameservers are configured in the same VNet as your deployment, then you can use those DNS nameservers to resolve the hostname of the upstream servers referenced in your NGINX configuration. + +### Will updates to my virtual network's DNS settings automatically apply to my NGINXaaS deployment? + +No, changes to a virtual network's DNS settings will not be applied automatically to your NGINXaaS deployment. To ensure DNS settings are applied, you must add any custom DNS servers to the VNET's DNS settings before creating an NGINXaaS deployment. As a workaround for existing deployments, we recommend using the [`resolver` directive](https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver) to explicitly specify your name server(s) and the [`resolve` parameter](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#resolve) to automatically re-resolve the domain name of the server without restarting NGINX. + +For example, + +```nginx +resolver 10.0.0.2 valid=10s; +upstream backends { + zone backends 64k; + server backends.example.com:8080 resolve; +} + +server { + location / { + proxy_pass http://backends; + } +} +``` + +### Does changing the `worker_connections` in the NGINX config have any effect? +- No. While changing the value of the directive in the config is allowed, the change is not applied to the underlying NGINX resource of your deployment. + +### What ports can my deployment listen on? + +- Due to port restrictions on Azure Load Balancer health probes, ports `19`, `21`, `70`, and `119` are not allowed. The NGINXaaS deployment can listen on all other ports. We limit the maximum listen ports in the NGINX configuration to 5 on the Basic and current Standard (v1) plan. Configurations that specify over 5 unique ports are rejected. With the Standard V2 plan, we allow users to listen on more than 5 ports. The first five ports under this plan come at no extra cost and there are charges for each additional port utilized. + +### How often does my deployment get billed? + +- NGINXaaS is [billed monthly]({{< relref "/nginxaas-azure/billing/overview.md" >}}) based on hourly consumption. + +### Why do the metrics show more connections and requests than I was expecting? + +- The NGINX agent periodically gathers connection and request statistics using an internal HTTP request. An Azure service health probe checks for status using a TCP connection for each listen port in the NGINX configuration, incrementing the connection count for each port. This contributes to minimal traffic and should not affect these metrics significantly. + +### Can I use an existing subnet to create my deployment? + +- You can use an existing subnet to create a deployment. Please make sure that the subnet is delegated to `NGINX.NGINXPLUS/nginxDeployments` before creating a deployment in it. To delegate a subnet to an Azure service, see [Delegate a subnet to an Azure service](https://learn.microsoft.com/en-us/azure/virtual-network/manage-subnet-delegation?source=recommendations#delegate-a-subnet-to-an-azure-service). + +### Will my deployment detect a new version of my certificate and apply it? + +- NGINXaaS supports certificate rotation. See the [Certificate Rotation documentation]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/overview.md#certificate-rotation" >}}) to learn more. + +### Why are some of my deployment's metrics intermittently missing in Azure monitor? + +- This may indicate that the deployment's underlying compute resources are being exhausted. Monitor the `system.cpu` metric to see the deployment's CPU utilization. If it's nearing 100%, consider increasing the deployment's NCU capacity. See the [Scaling Guidance]({{< relref "/nginxaas-azure/quickstart/scaling.md" >}}) documentation for more information. diff --git a/content/nginxaas-azure/getting-started/_index.md b/content/nginxaas-azure/getting-started/_index.md new file mode 100644 index 000000000..e3770eb81 --- /dev/null +++ b/content/nginxaas-azure/getting-started/_index.md @@ -0,0 +1,9 @@ +--- +title: Getting started +weight: 200 +draft: false +url: /nginxaas/azure/getting-started/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/getting-started/create-deployment/_index.md b/content/nginxaas-azure/getting-started/create-deployment/_index.md new file mode 100644 index 000000000..9dfdcd9ce --- /dev/null +++ b/content/nginxaas-azure/getting-started/create-deployment/_index.md @@ -0,0 +1,8 @@ +--- +title: Create a deployment +weight: 200 +url: /nginxaas/azure/getting-started/create-deployment/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/getting-started/create-deployment/deploy-azure-cli.md b/content/nginxaas-azure/getting-started/create-deployment/deploy-azure-cli.md new file mode 100644 index 000000000..55a1153e3 --- /dev/null +++ b/content/nginxaas-azure/getting-started/create-deployment/deploy-azure-cli.md @@ -0,0 +1,146 @@ +--- +title: "Deploy using the Azure CLI" +weight: 200 +categories: ["tasks"] +toc: true +--- + +## Overview + +The Azure CLI has an extension to be used for management of F5 NGINX as a Service for Azure (NGINXaaS) deployments whether that be locally or in continuous integration pipelines. This document links you to information around basic NGINXaaS extension usage. + +## Prerequisites + +- Install [Azure CLI with NGINXaaS extension]({{< relref "/nginxaas-azure/client-tools/cli.md" >}}) + +## Create a deployment + +To create an NGINXaaS for Azure resource use the `az nginx deployment create` command: + +```bash +az nginx deployment create --deployment-name + --resource-group + [--auto-upgrade-profile] + [--enable-diagnostics {0, 1, f, false, n, no, t, true, y, yes}] + [--identity] + [--location] + [--logging] + [--network-profile] + [--no-wait {0, 1, f, false, n, no, t, true, y, yes}] + [--scaling-properties] + [--sku] + [--tags] + [--user-profile] +``` + +### Examples + +- Create a deployment with public IP: + + ```bash + az nginx deployment create --name myDeployment --resource-group \ + myResourceGroup --location eastus2 --sku name="standardv2_Monthly" \ + --network-profile front-end-ip-configuration="{public-ip-addresses:[{id:/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/publicIPAddresses/myPublicIP}]}" \ + network-interface-configuration="{subnet-id:/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVNet/subnets/mySubnet}" + ``` + +- Create a deployment with private IP: + + ```bash + az nginx deployment create --name myDeployment --resource-group \ + myResourceGroup --location eastus2 --sku \ + name="standardv2_Monthly" --network-profile \ + front-end-ip-configuration="{private-ip-addresses:[{private-ip-allocation-method:Static,subnet-id:/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVNet/subnets/mySubnet,private-ip-address:10.0.0.2}]}" \ + network-interface-configuration="{subnet-id:/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVNet/subnets/mySubnet}" + ``` + + ```bash + az nginx deployment create --name myDeployment --resource-group \ + myResourceGroup --location eastus2 --sku \ + name="standardv2_Monthly" --network-profile \ + front-end-ip-configuration="{private-ip-addresses:[{private-ip-allocation-method:Dynamic,subnet-id:/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVNet/subnets/mySubnet,private-ip-address:10.0.0.2}]}" \ + network-interface-configuration="{subnet-id:/subscriptions/mySubscription/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVNet/subnets/mySubnet}" + ``` + +- Create a deployment with managed identity, storage account and scaling: + + ```bash + az nginx deployment create --deployment-name myDeployment --resource-group \ + myResourceGroup --location eastus2 --sku name=standardv2_Monthly \ + --network-profile \ + network-interface-configuration='{subnet-id:/subscriptions/subscriptionId/resourcegroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/vnet-azclitest/subnets/mySubnet}' \ + front-end-ip-configuration='{public-ip-addresses:[{id:/subscriptions/subscriptionId/resourceGroups/myResourceGroup/providers/Microsoft.Network/publicIPAddresses/myPublicIP}]}' \ + --identity '{"type":"UserAssigned","userAssignedIdentities":{"/subscriptions/subscriptionId/resourcegroups/myResourceGroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myManagedIdentity":{}}}' \ + --logging storage-account='{"account-name":"myStorageAccount","container-name":"myContainer"}' \ + --scaling-properties capacity=10 + ``` + +See the [Azure CLI Deployment Create Documentation](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment#az-nginx-deployment-create) for more details on the required and optional parameters. + +## Update a deployment + +To update an NGINXaaS for Azure resource use the `az nginx deployment update` command: + +```bash +az nginx deployment update [--add] + [--auto-upgrade-profile] + [--deployment-name] + [--enable-diagnostics {0, 1, f, false, n, no, t, true, y, yes}] + [--force-string {0, 1, f, false, n, no, t, true, y, yes}] + [--identity] + [--ids] + [--location] + [--logging] + [--network-profile] + [--no-wait {0, 1, f, false, n, no, t, true, y, yes}] + [--remove] + [--resource-group] + [--scaling-properties] + [--set] + [--sku] + [--subscription] + [--tags] + [--user-profile] +``` + +### Example + +- Update tags and enable diagnostics support for a deployment: + + ```bash + az nginx deployment update --name myDeployment --resource-group \ + myResourceGroup --location eastus2 --tags tag1="value1" \ + tag2="value2" --enable-diagnostics + ``` + +See the [Azure CLI Deployment Update Documentation](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment#az-nginx-deployment-update) for more details on the required and optional parameters. + + +## Delete a deployment + +Use the `az nginx deployment delete` command to delete an NGINXaaS for Azure resource: + +```bash +az nginx deployment delete [--deployment-name] + [--ids] + [--no-wait {0, 1, f, false, n, no, t, true, y, yes}] + [--resource-group] + [--subscription] + [--yes] +``` + +### Example + +- Delete a deployment: + + ```bash + az nginx deployment delete --name myDeployment \ + --resource-group myResourceGroup + ``` + +See the [Azure CLI Deployment Delete Documentation](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment#az-nginx-deployment-delete) for more details on the required and optional parameters. + +## Additional resources + +- [Azure CLI Public IP Documentation](https://learn.microsoft.com/en-us/cli/azure/network/public-ip) +- [Azure CLI Storage Container Documentation](https://learn.microsoft.com/en-us/cli/azure/storage/container) diff --git a/content/nginxaas-azure/getting-started/create-deployment/deploy-azure-portal.md b/content/nginxaas-azure/getting-started/create-deployment/deploy-azure-portal.md new file mode 100644 index 000000000..2827d670e --- /dev/null +++ b/content/nginxaas-azure/getting-started/create-deployment/deploy-azure-portal.md @@ -0,0 +1,88 @@ +--- +title: "Deploy using the Azure portal" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-878" +--- + +## Overview + +This guide explains how to deploy F5 NGINX as a Service for Azure (NGINXaaS) using [Microsoft Azure portal](https://azure.microsoft.com/en-us/get-started/azure-portal). The deployment process involves creating a new deployment, configuring the deployment, and testing the deployment. + +## Find the NGINX as a Service for Azure offer in the Azure portal + +You can start the NGINXaaS deployment process by visiting the [Create NGINXaaS](https://portal.azure.com/#create/f5-networks.f5-nginx-for-azure) page or finding the NGINXaaS service in the Azure portal: + +1. [Sign in](https://portal.azure.com/) to the Azure portal with your Azure account. +1. Use the search field to find "NGINXaaS" in the Azure Portal. In the Services results, select **NGINXaaS**. +1. Select **+ Create** on the **NGINXaaS** page to start the deployment process. + +## Create a deployment + +### Basics tab + +1. On the Create NGINXaaS Deployment **Basics** page, provide the following information: + + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Subscription | Select the appropriate Azure subscription that you have access to.| + | Resource group | Specify whether you want to create a new resource group or use an existing one.
For more information, see [Azure Resource Group overview](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/overview). | + | Name | Provide a unique name for your deployment. | + | Region | Select the region you want to deploy to. | + | Pricing Plan | Select the Standard V2 plan. For more information, see [Pricing Plans]({{< ref "/nginxaas-azure/billing/overview.md#pricing-plans">}}) | + | Scaling | Select Manual to set the capacity of your deployment in NCUs or select Autoscale to automatically adjust the capacity of your deployment. Learn more about NCUs in [Scaling Guidance]({{< relref "/nginxaas-azure/quickstart/scaling.md" >}}). | + | Email | Provide an email address that can be notified about service alerts, maintenance data and activity reports. | + | Upgrade Channel | Select the desired upgrade channel for your deployment. For more information, see [Upgrade Channels]({{< relref "/nginxaas-azure/quickstart/upgrade-channels.md" >}}). | + + {{
}} + +1. Next, select **Networking**. + +### Networking tab + +1. On the Create NGINXaaS Deployment **Networking** page, provide the following information: + + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Virtual Network | A virtual network is required for communication between the resources you create.
You can create a new virtual network or use an existing one (for an existing one see note below).
Additionally, you can peer a new virtual network with existing ones (in any region) to create network access from NGINXaaS for Azure to your upstream servers. To peer the virtual network with another see [Create, change, or delete a virtual network peering](https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-manage-peering).| + | Subnet | If you select an existing virtual network, you can select the existing subnet to be used. Before creating a deployment, the existing subnet needs to be delegated to `NGINX.NGINXPLUS/nginxDeployments`. To delegate a subnet to an Azure service, see [Delegate a subnet to an Azure service](https://learn.microsoft.com/en-us/azure/virtual-network/manage-subnet-delegation?source=recommendations#delegate-a-subnet-to-an-azure-service).

Otherwise, if you have chosen to create a new virtual network, a new subnet will be selected by default.

The minimum subnet size is `/27` and is sufficient for a single NGINXaaS deployment even at large scales. Multiple NGINXaaS deployments can be placed in a single delegated subnet, along with other resources. When doing so a larger subnet, e.g. a `/24`, is recommended. | + | Allow NGINX access to Virtual Network | Confirm that you allow:
- Registration of the NGINX provider to your Azure subscription.
- Delegation of the subnet to the NGINX provider.| + | IP address | Set the IP address (public or private) that the service listens to for requests:

If you select a public IP address:
- Create a new public IP or use an existing one (for an existing one see the note below).
- Set the resource name for your public IP address.
Newly created public IPs are [zone-redundant in supported regions](https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/public-ip-addresses#availability-zone).

If you select a private IP address:
- Provide a static IP address from the same subnet range set previously. | + | Inbound port rules | Select `None` to disallow inbound access on any port, or choose to allow traffic from one of these common http(s) ports.

**Note:** This option is only available when specifying a new virtual network as part of the create workflow. If you select an existing virtual network which is associated with a subnet and Network Security Group (NSG), you will need to edit the Inbound security rules to add access for the specific ports you want to allow (for example, ports 80 and 443).| + | Apply default NGINX configuration | Confirm that you want your NGINXaaS deployment to be bootstrapped with a default NGINX configuration and a browsable splash page. | + {{
}} + +1. Next, select **Tags**. + +### Tags tab + +1. Add custom tags for the new NGINXaaS Deployment. Each tag consists of a **name** and **value**. + +1. After adding the tags, select **Next: Review+Create** + +### Review + create tab + +1. On the Review + create tab, your configuration is validated. You can review the selections made in the previous screens. + +1. After validation has succeeded and you've reviewed the terms, select **Create** for Azure to start the deployment. + +1. After the deployment finishes, select the NGINX deployment from the list (with "Type: NGINXaaS") to view information about the deployed resource. + + ![Resource Deployment Completed page showing the available deployments and the new NGINXaaS type deployment in the Deployment details section.](/nginxaas-azure/deployment-complete.png) + + +## Test your deployment + +1. To test your deployment, you can go to the IP address noted on the overview page. The default NGINX welcome screen should load. + + {{}}You will not see the default NGINX welcome screen if you unchecked "Apply default NGINX configuration" in the [Networking Tab screen]({{< relref "create-deployment.md#networking-tab" >}}) above. You can proceed with providing your own NGINX configuration as outlined in the [NGINX configuration]({{< relref "nginx-configuration.md#networking-tab" >}}) section.{{}} + + ![NGINXaaS Overview page showing the IP address of the deployment in the Essentials section.](/nginxaas-azure/test-deployment.png) + + +## What's next + +[Assign Managed Identities]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) diff --git a/content/nginxaas-azure/getting-started/create-deployment/deploy-terraform.md b/content/nginxaas-azure/getting-started/create-deployment/deploy-terraform.md new file mode 100644 index 000000000..07d5275a7 --- /dev/null +++ b/content/nginxaas-azure/getting-started/create-deployment/deploy-terraform.md @@ -0,0 +1,41 @@ +--- +title: "Deploy using Terraform" +weight: 300 +categories: ["tasks"] +toc: true +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) deployments can be managed using Terraform. This document outlines common Terraform workflows for NGINXaaS. + +## Prerequisites + +{{< include "/nginxaas-azure/terraform-prerequisites.md" >}} + +## Create a deployment + +You can find examples of Terraform configurations in the [NGINXaaS for Azure Snippets GitHub repository](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/deployments/create-or-update) + +To create a deployment, use the following Terraform commands: + + ```bash + terraform init + terraform plan + terraform apply --auto-approve + ``` + +## Delete a deployment + +Once the deployment is no longer needed, run the following to clean up the deployment and related resources: + + ```bash + terraform destroy --auto-approve + ``` + +## Additional resources + +- If you're just starting with Terraform, you can learn more on their [official website](https://www.terraform.io/). +- [Terraform NGINX deployment documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nginx_deployment) + +{{< include "/nginxaas-azure/terraform-resources.md" >}} \ No newline at end of file diff --git a/content/nginxaas-azure/getting-started/managed-identity-portal.md b/content/nginxaas-azure/getting-started/managed-identity-portal.md new file mode 100644 index 000000000..8f3d190f2 --- /dev/null +++ b/content/nginxaas-azure/getting-started/managed-identity-portal.md @@ -0,0 +1,83 @@ +--- +title: "Assign Managed Identities" +weight: 300 +categories: ["tasks"] +toc: true +docs: "DOCS-872" +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) leverages a user assigned and a system assigned managed identity for some of its integrations with Azure, such as: + +- Azure Key Vault (AKV): fetch SSL/TLS certificates from AKV to your NGINXaaS deployment, so that they can be referenced by your NGINX configuration. + +- Azure Monitor: publish metrics from your NGINX deployment to Azure Monitor. + +- Azure Storage: export logs from your NGINX deployment to Azure Blob Storage Container. + +## Prerequisites + +- A user assigned or a system assigned managed identity. If you are unfamiliar with managed identities for Azure resources, refer to the [Managed Identity documentation](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview) from Microsoft. + +- Owner access on the resource group or subscription to assign the managed identity to the NGINX deployment. + +## Adding a user assigned managed identity + +1. Go to your NGINXaaS for Azure deployment. + +2. Select **Identity** in the left menu, select the **User Assigned** tab, and select **Add**. + +3. Select the appropriate **subscription** and **user assigned managed identity**, then select **Add**. + +
+ {{}}NGINXaaS supports adding a system assigned managed identity and a user assigned managed identity. Adding more than one user assigned managed identity is not supported.{{}} + +4. The added user assigned managed identity will show up in the main table. + +## Removing a user assigned managed identity + +1. Select the managed identity you want to remove from the list and then select **Remove**. + +2. Confirm the operation by selecting **Yes** on the confirmation prompt. + +## Adding a system assigned managed identity + +1. Go to your NGINXaaS for Azure deployment. + +2. Select **Identity** in the left menu, select the **System Assigned** tab, and then toggle the Status to **On**. + +3. Select **Save**. + +3. To confirm the operation, select **Yes** on the confirmation prompt. + + {{}}NGINXaaS supports using only one type of managed identity per deployment at a time. User assigned and system assigned identities cannot be present simultaneously.{{}} + +4. To provide the role assignments necessary for the deployment, Select **Azure Role Assignments** under Permissions. + +5. Select **Add Role Assignments** + +6. On the **Add role assignment (Preview)** panel, select the appropriate **Scope** and **Role**. Then select **Save**. + +7. The system assigned managed identity will be shown as enabled on the main Identity page. + +## Removing a system assigned managed identity + +1. Select **Identity** in the left menu, then select the **System assigned** tab. + +2. Toggle the Status to **Off** and select **Save**. + +3. Confirm the operation by selecting **Yes** on the confirmation prompt. + +{{}}Removing a Managed Identity from an NGINX deployment has the following effects: + +- If the NGINX deployment uses any SSL/TLS certificates, then any updates to the deployment (including deployment properties, certificates, and configuration) will result in a failure. If the configuration is updated not to use any certificates, then those requests will succeed. + +- If publishing metrics is enabled for the NGINX deployment, then the metrics will no longer be published to Azure Monitor for this deployment until a Managed Identity is added. + +- If logging is enabled for the NGINX deployment, then the logs will no longer be exported to the Azure Blob Storage Container for this deployment until a Managed Identity is added.{{}} + + +## What's next + +[Add SSL/TLS Certificates]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md" >}}) diff --git a/content/nginxaas-azure/getting-started/nginx-configuration/_index.md b/content/nginxaas-azure/getting-started/nginx-configuration/_index.md new file mode 100644 index 000000000..c0c2f4c34 --- /dev/null +++ b/content/nginxaas-azure/getting-started/nginx-configuration/_index.md @@ -0,0 +1,8 @@ +--- +title: Upload an NGINX configuration +weight: 500 +url: /nginxaas/azure/getting-started/nginx-configuration/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-azure-cli.md b/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-azure-cli.md new file mode 100644 index 000000000..ad52dbd28 --- /dev/null +++ b/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-azure-cli.md @@ -0,0 +1,226 @@ +--- +title: "Upload using the Azure CLI" +weight: 200 +categories: ["tasks"] +toc: true +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) configurations can be managed using the Azure CLI. This document outlines common Azure CLI workflows to validate, create, and update NGINX configurations. + +## Prerequisites + +- Install [Azure CLI with NGINXaaS extension]({{< relref "/nginxaas-azure/client-tools/cli.md" >}}) + +- If the NGINX configuration requires SSL/TLS certificates, then a managed identity and integration with Azure Key Vault is required. + +- A contributor role is required to apply the configuration to the deployment. + +## Create a configuration + +To create a new NGINX configuration, use the `az nginx deployment configuration create` command: + +```bash +az nginx deployment configuration create --configuration-name + --deployment-name + --resource-group + [--files] + [--location] + [--no-wait {0, 1, f, false, n, no, t, true, y, yes}] + [--package] + [--protected-files] + [--root-file] +``` + +### Validate your configuration + +You can use the `analyze` command to validate your configuration before submitting it to the deployment: + +```bash +az nginx deployment configuration analyze --deployment-name $DEPLOYMENT_NAME \ + --resource-group $RESOURCE_GROUP --root-file /etc/nginx/nginx.conf \ + --name default --files "$FILES_CONTENT" +```` + +### Examples + +- Create a single file configuration: + + ```bash + az nginx deployment configuration create --name default \ + --deployment-name myDeployment --resource-group myResourceGroup \ + --root-file /etc/nginx/nginx.conf \ + --files "[{content:'aHR0cCB7CiAgICB1cHN0cmVhbSBhcHAgewogICAgICAgIHpvbmUgYXBw \ + IDY0azsKICAgICAgICBsZWFzdF9jb25uOwogICAgICAgIHNlcnZlciAxMC4wLjEuNDo4 \ + MDAwOwogICAgfQoKICAgIHNlcnZlciB7CiAgICAgICAgbGlzdGVuIDgwOwogICAgICAg \ + IHNlcnZlcl9uYW1lICouZXhhbXBsZS5jb207CgogICAgICAgIGxvY2F0aW9uIC8gewog \ + ICAgICAgICAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgJGhvc3Q7CiAgICAgICAgICAg \ + IHByb3h5X3NldF9oZWFkZXIgWC1SZWFsLUlQICRyZW1vdGVfYWRkcjsKICAgICAgICAg \ + ICAgcHJveHlfc2V0X2hlYWRlciBYLVByb3h5LUFwcCBhcHA7CiAgICAgICAgICAgIHBy \ + b3h5X3NldF9oZWFkZXIgR2l0aHViLVJ1bi1JZCAwMDAwMDA7CiAgICAgICAgICAgIHBy \ + b3h5X2J1ZmZlcmluZyBvbjsKICAgICAgICAgICAgcHJveHlfYnVmZmVyX3NpemUgNGs7 \ + CiAgICAgICAgICAgIHByb3h5X2J1ZmZlcnMgOCA4azsKICAgICAgICAgICAgcHJveHlf \ + cmVhZF90aW1lb3V0IDYwczsKICAgICAgICAgICAgcHJveHlfcGFzcyBodHRwOi8vYXBw \ + OwogICAgICAgICAgICBoZWFsdGhfY2hlY2s7CiAgICAgICAgfQogICAgICAgIAogICAg \ + fQp9',virtual-path:'/etc/nginx/nginx.conf'}]" + ``` + +- Create a multiple file configuration: + + ```bash + az nginx deployment configuration create --name default \ + --deployment-name myDeployment --resource-group myResourceGroup \ + --root-file /etc/nginx/nginx.conf \ + --files "[{'content':'aHR0cCB7CiAgICB1cHN0cmVhbSBhcHAgewogICAgICAgIHpvbmUg \ + YXBwIDY0azsKICAgICAgICBsZWFzdF9jb25uOwogICAgICAgIHNlcnZlciAxMC4wLjEu \ + NDo4MDAwOwogICAgfQoKICAgIHNlcnZlciB7CiAgICAgICAgbGlzdGVuIDgwOwogICAg \ + ICAgIHNlcnZlcl9uYW1lICouZXhhbXBsZS5jb207CgogICAgICAgIGxvY2F0aW9uIC8g \ + ewogICAgICAgICAgICBpbmNsdWRlIC9ldGMvbmdpbngvY29uZi5kL3Byb3h5LmNvbmY7 \ + CiAgICAgICAgICAgIHByb3h5X3Bhc3MgaHR0cDovL2FwcDsKICAgICAgICAgICAgaGVh \ + bHRoX2NoZWNrOwogICAgICAgIH0KICAgICAgICAKICAgIH0KfQ==', \ + 'virtual-path':'/etc/nginx/nginx.conf'}, \ + {'content':'cHJveHlfc2V0X2hlYWRlciBIb3N0ICRob3N0Owpwcm94eV9zZXRfaGVhZGVy \ + IFgtUmVhbC1JUCAkcmVtb3RlX2FkZHI7CnByb3h5X3NldF9oZWFkZXIgWC1Qcm94eS1B \ + cHAgYXBwOwpwcm94eV9zZXRfaGVhZGVyIEdpdGh1Yi1SdW4tSWQgMDAwMDAwOwpwcm94 \ + eV9idWZmZXJpbmcgb247CnByb3h5X2J1ZmZlcl9zaXplIDRrOwpwcm94eV9idWZmZXJz \ + IDggOGs7CnByb3h5X3JlYWRfdGltZW91dCA2MHM7', \ + 'virtual-path':'/etc/nginx/conf.d/proxy.conf'}]" + ``` + +- Upload package with config files: + + ```bash + $ tar -czf nginx.tar.gz nginx + $ tar -tzf nginx.tar.gz + nginx/ + nginx/nginx.conf + nginx/njs.js + nginx/servers + nginx/servers/ + nginx/servers/server1.conf + nginx/servers/server2.conf + ``` + + Where `nginx` is a directory with the following structure: + + ```bash + $ tree nginx + nginx + ├── nginx.conf + ├── njs.js + └── servers + ├── server1.conf + └── server2.conf + + 1 directory, 4 files + ``` + + Encode your tar.gz file and create your NGINXaaS configuration + + ```bash + TAR_DATA=$(base64 -i nginx.tar.gz) + az nginx deployment configuration create --deployment-name myDeployment \ + --resource-group myResourceGroup --root-file nginx.conf --name default \ + --package data="$TAR_DATA" + ``` + +- Multiple file configuration with protected files: + + ```bash + az nginx deployment configuration create --name default \ + --deployment-name 0102242023test --resource-group azclitest-geo \ + --root-file /etc/nginx/nginx.conf \ + --files "[{'content':'aHR0cCB7CiAgICB1cHN0cmVhbSBhcHAgewogICAgICAgIHpvbmUg \ + YXBwIDY0azsKICAgICAgICBsZWFzdF9jb25uOwogICAgICAgIHNlcnZlciAxMC4wLjEu \ + NDo4MDAwOwogICAgfQoKICAgIHNlcnZlciB7CiAgICAgICAgbGlzdGVuIDgwOwogICAg \ + ICAgIHNlcnZlcl9uYW1lICouZXhhbXBsZS5jb207CgogICAgICAgIGxvY2F0aW9uIC8g \ + ewogICAgICAgICAgICBpbmNsdWRlIC9ldGMvbmdpbngvY29uZi5kL3Byb3h5LmNvbmY7 \ + CiAgICAgICAgICAgIHByb3h5X3Bhc3MgaHR0cDovL2FwcDsKICAgICAgICAgICAgaGVh \ + bHRoX2NoZWNrOwogICAgICAgIH0KICAgICAgICAKICAgIH0KfQ==', \ + 'virtual-path':'/etc/nginx/nginx.conf'}, \ + {'content':'cHJveHlfc2V0X2hlYWRlciBIb3N0ICRob3N0Owpwcm94eV9zZXRfaGVhZGVy \ + IFgtUmVhbC1JUCAkcmVtb3RlX2FkZHI7CnByb3h5X3NldF9oZWFkZXIgWC1Qcm94eS1B \ + cHAgYXBwOwpwcm94eV9zZXRfaGVhZGVyIEdpdGh1Yi1SdW4tSWQgMDAwMDAwOwpwcm94 \ + eV9idWZmZXJpbmcgb247CnByb3h5X2J1ZmZlcl9zaXplIDRrOwpwcm94eV9idWZmZXJz \ + IDggOGs7CnByb3h5X3JlYWRfdGltZW91dCA2MHM7', \ + 'virtual-path':'/etc/nginx/conf.d/proxy.conf'}]" \ + --protected-files "[{'content':'aHR0cCB7CiAgICB1cHN0cmVhbSBhcHAgewogICAgICAgIHpvbmUg \ + YXBwIDY0azsKICAgICAgICBsZWFzdF9jb25uOwogICAgICAgIHNlcnZlciAxMC4wLjEu \ + NDo4MDAwOwogICAgfQoKICAgIHNlcnZlciB7CiAgICAgICAgbGlzdGVuIDgwOwogICAg \ + ICAgIHNlcnZlcl9uYW1lICouZXhhbXBsZS5jb207CgogICAgICAgIGxvY2F0aW9uIC8g \ + ewogICAgICAgICAgICBpbmNsdWRlIC9ldGMvbmdpbngvY29uZi5kL3Byb3h5LmNvbmY7 \ + CiAgICAgICAgICAgIHByb3h5X3Bhc3MgaHR0cDovL2FwcDsKICAgICAgICAgICAgaGVh \ + bHRoX2NoZWNrOwogICAgICAgIH0KICAgICAgICAKICAgIH0KfQ==', \ + 'virtual-path':'/etc/nginx/nginxprot.conf'}, \ + {'content':'cHJveHlfc2V0X2hlYWRlciBIb3N0ICRob3N0Owpwcm94eV9zZXRfaGVhZGVy \ + IFgtUmVhbC1JUCAkcmVtb3RlX2FkZHI7CnByb3h5X3NldF9oZWFkZXIgWC1Qcm94eS1B \ + cHAgYXBwOwpwcm94eV9zZXRfaGVhZGVyIEdpdGh1Yi1SdW4tSWQgMDAwMDAwOwpwcm94 \ + eV9idWZmZXJpbmcgb247CnByb3h5X2J1ZmZlcl9zaXplIDRrOwpwcm94eV9idWZmZXJz \ + IDggOGs7CnByb3h5X3JlYWRfdGltZW91dCA2MHM7', \ + 'virtual-path':'/etc/nginx/conf.d/proxyprot.conf'}]" + ``` + +See the [Azure CLI Configuration Create Documentation](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment/configuration?view=azure-cli-latest#az-nginx-deployment-configuration-create) for more details on the available parameters. + + + +## Update a configuration + +Update a configuration for a deployment using a gzipped archive. + +Use the `az nginx deployment configuration update` command to update an existing NGINX configuration: + +```bash +az nginx deployment configuration update [--add] + [--configuration-name] + [--deployment-name] + [--files] + [--force-string {0, 1, f, false, n, no, t, true, y, yes}] + [--ids] + [--location] + [--no-wait {0, 1, f, false, n, no, t, true, y, yes}] + [--remove] + [--resource-group] + [--root-file] + [--set] + [--subscription] +``` + +### Example + +- Update content of the first file in a configuration: + + ```bash + az nginx deployment configuration update --name default \ + --deployment-name myDeployment --resource-group myResourceGroup \ + --files [0].content="aHR0cCB7CiAgICB1cHN0cmVhbSBhcHAgewogICAgICAgIHpvbmUg \ + YXBwIDY0azsKICAgICAgICBsZWFzdF9jb25uOwogICAgICAgIHNlcnZlciAxMC4wLjEu \ + NDo4MDAwOwogICAgfQoKICAgIHNlcnZlciB7CiAgICAgICAgbGlzdGVuIDgwOwogICAg \ + ICAgIHNlcnZlcl9uYW1lICouZXhhbXBsZS5jb207CgogICAgICAgIGxvY2F0aW9uIC8g \ + ewogICAgICAgICAgICBwcm94eV9zZXRfaGVhZGVyIEhvc3QgJGhvc3Q7CiAgICAgICAg \ + ICAgIHByb3h5X3NldF9oZWFkZXIgWC1SZWFsLUlQICRyZW1vdGVfYWRkcjsKICAgICAg \ + ICAgICAgcHJveHlfc2V0X2hlYWRlciBYLVByb3h5LUFwcCBhcHA7CiAgICAgICAgICAg \ + IHByb3h5X3NldF9oZWFkZXIgR2l0aHViLVJ1bi1JZCAwMDAwMDA7CiAgICAgICAgICAg \ + IHByb3h5X2J1ZmZlcmluZyBvbjsKICAgICAgICAgICAgcHJveHlfYnVmZmVyX3NpemUg \ + NGs7CiAgICAgICAgICAgIHByb3h5X2J1ZmZlcnMgOCA4azsKICAgICAgICAgICAgcHJv \ + eHlfcmVhZF90aW1lb3V0IDYwczsKICAgICAgICAgICAgcHJveHlfcGFzcyBodHRwOi8v \ + YXBwOwogICAgICAgICAgICBoZWFsdGhfY2hlY2s7CiAgICAgICAgfQogICAgICAgIAog \ + ICAgfQp9" + ``` + +See the [Azure CLI Configuration Update Documentation](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment/configuration?view=azure-cli-latest#az-nginx-deployment-configuration-update) for more details on the available parameters. + + +{{< tip >}} + +See the [NGINX connfiguration overview]({{< relref "overview.md" >}}) topic +to learn more about: + +- [NGINX configuration automation workflows]({{< relref "overview.md#nginx-configuration-automation-workflows" >}}) +- [NGINX filesystem restrictions]({{< relref "overview.md#nginx-filesystem-restrictions" >}}) +- [Disallowed configuration directives]({{< relref "overview.md#disallowed-configuration-directives" >}}) +- [Directives that cannot be overridden]({{< relref "overview.md#directives-that-cannot-be-overridden" >}}) +- [Configuration directives list]({{< relref "overview.md#configuration-directives-list" >}}) + +{{< /tip >}} diff --git a/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md b/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md new file mode 100644 index 000000000..f11e4bac2 --- /dev/null +++ b/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md @@ -0,0 +1,163 @@ +--- +title: "Upload using the Azure portal" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-873" +--- + +An NGINX configuration can be applied to the deployment using the Azure portal in two different ways: + +- Create a new NGINX configuration from scratch or by pasting it in the Azure portal editor. +- Upload a gzip compressed tar archive containing your NGINX configuration. + +As part of applying your NGINX configuration, the service validates the configuration for syntax and compatibility with F5 NGINX as a Service for Azure (NGINXaaS). The use of certain directives and parameters is not allowed to ensure the NGINX configuration’s compatibility with IaaS deployment model in Azure. Validation errors are reported in the editor for you to correct. For more information, check the [NGINX Configuration Validation]({{< relref "nginx-configuration.md#nginx-configuration-validation" >}}) section. + +## Prerequisites + +- If the NGINX configuration requires SSL/TLS certificates, then a managed identity and integration with Azure Key Vault is required. + +- A contributor role is required to apply the configuration to the deployment. + +## Add an NGINX configuration + +1. Go to your NGINXaaS for Azure deployment. + +1. Select **NGINX configuration** in the left menu and you will see the default configuration that NGINXaaS provides. + + {{}}If you don't see the default configuration, it's likely the deployment was created through a client tool other than the portal (For example, Terraform), or the "Apply default NGINX configuration" was unchecked during the deployment creation process in the portal. You can still proceed with the steps below to provide your own NGINX configuration for the deployment.{{}} + +1. Select {{< fa "fa fa-plus">}}**New File** to add a file path, then **Confirm**. + + {{}} + | Property | Description | + | -------- | ----------- | + | File path | Each NGINX configuration file can be uniquely identified by a file path (for example, nginx.conf or /etc/nginx/nginx.conf) to align with the intended NGINX configuration file structure. | + | Root file | The root file is the main NGINX configuration file.
  • The first file created will be the root file by default. You can designate a different root file if you have more than a single configuration file in your deployment.
  • The root file is designated with a {{< golden-star >}} icon on the portal.
| + | Protected File | Indicates that the file may contain sensitive data such as passwords or represent an ssl/tls certificate.
  • To protect a file, enable the **Protected** {{}} toggle button.
  • You cannot access the file contents of a protected file saved to the NGINX configuration, but you can view its metadata, such as the SHA-256 hash of the file contents.
  • You can provide new contents for an existing protected file using the **Overwrite** link or resubmit it without having to provide the file contents again.
  • To modify the file path of a protected file or convert it to a regular file, delete the original file and create a new one.
  • A protected file is designated with a {{}} icon on the portal.
| + {{
}} + + {{}}If specifying an absolute file path, see the [NGINX Filesystem Restrictions table]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/#nginx-filesystem-restrictions" >}}) for the allowed directories the file can be written to.{{}} + +1. Provide your NGINX configuration in the configuration file. + +1. Files like SSL/TLS certificates can be added as well. However, we reccommend using Azure Key Vault to store your certificates. See [Add SSL/TLS certificates]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/overview.md#add-ssltls-certificates">}}) for more information. + +1. Select **Submit** to apply the new configuration. + +{{}}We currently only support more than 5 unique listen ports on the Standard V2 plan. NGINX configurations that specify more than 5 ports on other plans will be rejected. For more information on listen port limitations, see our [FAQ]({{< relref "/nginxaas-azure/faq" >}}).{{}} + +### NGINX configuration validation + +NGINX configuration is validated real-time to check for syntax and compatibility with the service. Validation errors are reported in the editor for you to correct. + +For example, if you create/update an NGINX config with a particular directive that is not allowed, the service will analyse your NGINX config and provide real-time feedback. + +![NGINX Configuration validation error](/nginxaas-azure/validation-error.png) + + +The editing experience consists of a single view for both editing and validation + +- If the config is invalid, then any errors are highlighted in-place in the config editor. Hover over the highlighted errors to learn more about them or check the problems section at the bottom. Corrections can be made in the same panel. + +- If the config is valid, then a green check mark appears next to NGINXaaS Analyzer at the bottom indicating that you can submit the config to deploy it. + +## Upload a GZIP NGINX configuration + +Given the example gzipped archive, + +```bash +$ tar -czf nginx.tar.gz nginx +$ tar -tzf nginx.tar.gz +nginx/ +nginx/nginx.conf +nginx/njs.js +nginx/servers +nginx/servers/ +nginx/servers/server1.conf +nginx/servers/server2.conf +``` + +where `nginx` is a directory with the following structure, + +```bash +$ tree nginx +nginx +├── nginx.conf +├── njs.js +└── servers + ├── server1.conf + └── server2.conf + +1 directory, 4 files +``` + +`nginx.tar.gz` can be uploaded using the following portal workflow. + +Before continuing, ensure the file paths in the archive match the includes in the NGINX config. +For example, + +```nginx +http { + include nginx/servers/server1.conf; + js_import nginx/njs.js; + # ... +} +``` + +1. Go to your NGINXaaS for Azure deployment. + +1. Select **NGINX configuration** from the left menu. + +1. Select **Upload config package**. + +1. Drag and drop or browse for the new gzip compressed archive file to upload. + +1. Specify the root file. + + {{}}Uploading a new file will replace all existing NGINX configuration files in your deployment. You must acknowledge this step before you proceed to upload.{{}} + +1. Select **Upload**. + +## Update an NGINX configuration + +1. Go to your NGINXaaS for Azure deployment. + +1. Select **NGINX configuration** in the left menu. + +1. Select the configuration file you want to update from the File path list. + +1. Make the necessary updates to the configuration. + + - You can also update the file path and/or assign the file as root. + +1. (Optional) Select any other configuration files to make additional updates. + +1. Submit your changes. + +## Delete NGINX configuration Files + +1. Go to your NGINXaaS for Azure deployment. + +1. Select **NGINX configuration** in the left menu. + +1. Select the configuration file you want to delete from the File path list. + +1. Select the delete icon {{< fa "fa fa-trash">}}. + +1. Confirm your action to delete the configuration file. + + {{}}Only non-root configuration files can be deleted.{{}} + +{{< tip >}} + +See the [NGINX connfiguration overview]({{< relref "overview.md" >}}) topic +to learn more about: + +- [NGINX configuration automation workflows]({{< relref "overview.md#nginx-configuration-automation-workflows" >}}) +- [NGINX filesystem restrictions]({{< relref "overview.md#nginx-filesystem-restrictions" >}}) +- [Disallowed configuration directives]({{< relref "overview.md#disallowed-configuration-directives" >}}) +- [Directives that cannot be overridden]({{< relref "overview.md#directives-that-cannot-be-overridden" >}}) +- [Configuration directives list]({{< relref "overview.md#configuration-directives-list" >}}) + +{{< /tip >}} diff --git a/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configurations-terraform.md b/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configurations-terraform.md new file mode 100644 index 000000000..661bc74b7 --- /dev/null +++ b/content/nginxaas-azure/getting-started/nginx-configuration/nginx-configurations-terraform.md @@ -0,0 +1,82 @@ +--- +title: "Upload using Terraform" +weight: 300 +categories: ["tasks"] +toc: true +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) configurations can be managed using Terraform. This document outlines common Terraform workflows for NGINXaaS. + +## Prerequisites + +{{< include "/nginxaas-azure/terraform-prerequisites.md" >}} + +## Upload an NGINX configuration + +You can find examples of Terraform configurations in the [NGINXaaS for Azure Snippets GitHub repository](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/configurations) + +To create a deployment and add a configuration, run the following commands: + + ```bash + terraform init + terraform plan + terraform apply --auto-approve + ``` + +## Manage an NGINX configuration + +NGINX configuration files are uploaded and returned as base64 encoded data. We recommend using git or other version control systems to view human-readable differences between configuration files during `terraform plan`. Alternatively, you can decode the file contents to view the whole file. For example, + +```bash +$ terraform plan +... +- config_file { + - content = "aHR0cCB7CiAgICBzZXJ2ZXIgewogICAgICAgIGxvY2F0aW9uIC8gewogICAgICAgICAgICByZXR1cm4gMjAwICJIZWxsbyI7CiAgICAgICAgfQogICAgfQoK" -> null + - virtual_path = "nginx.conf" -> null + } ++ config_file { + + content = "aHR0cCB7CiAgICBzZXJ2ZXIgewogICAgICAgIGxvY2F0aW9uIC8gewogICAgICAgICAgICByZXR1cm4gMjAwICJIZWxsbyBXb3JsZCEiOwogICAgICAgIH0KICAgIH0KfQoK" + + virtual_path = "nginx.conf" + } +... +``` + +``` +$ echo aHR0cCB7CiAgICBzZXJ2ZXIgewogICAgICAgIGxvY2F0aW9uIC8gewogICAgICAgICAgICByZXR1cm4gMjAwICJIZWxsbyBXb3JsZCEiOwogICAgICAgIH0KICAgIH0KfQoK | base64 --decode +http { + server { + location / { + return 200 "Hello World!"; + } + } +} +``` + +## Delete a deployment + +Once the deployment is no longer needed, run the following to clean up the deployment and related resources: + + ```bash + terraform destroy --auto-approve + ``` + +## Additional resources + +- [Terraform NGINX configuration documentation](https://registry.terraform.io/providers/hashicorp/azurerm/3.97.0/docs/resources/nginx_configuration) + +{{< include "/nginxaas-azure/terraform-resources.md" >}} + +{{< tip >}} + +See the [NGINX connfiguration overview]({{< relref "overview.md" >}}) topic +to learn more about: + +- [NGINX configuration automation workflows]({{< relref "overview.md#nginx-configuration-automation-workflows" >}}) +- [NGINX filesystem restrictions]({{< relref "overview.md#nginx-filesystem-restrictions" >}}) +- [Disallowed configuration directives]({{< relref "overview.md#disallowed-configuration-directives" >}}) +- [Directives that cannot be overridden]({{< relref "overview.md#directives-that-cannot-be-overridden" >}}) +- [Configuration directives list]({{< relref "overview.md#configuration-directives-list" >}}) + +{{< /tip >}} diff --git a/content/nginxaas-azure/getting-started/nginx-configuration/overview.md b/content/nginxaas-azure/getting-started/nginx-configuration/overview.md new file mode 100644 index 000000000..ef33b79c9 --- /dev/null +++ b/content/nginxaas-azure/getting-started/nginx-configuration/overview.md @@ -0,0 +1,970 @@ +--- +title: "Overview" +weight: 50 +categories: ["tasks"] +toc: true +--- + +This document provides details about using NGINX configuration files with your +F5 NGINX as a Service for Azure deployment, restrictions, and available directives. + +## NGINX configuration common user workflows + +NGINX configurations can be uploaded to your NGINXaaS for Azure deployment using the Azure portal, Azure CLI, or Terraform. The following documents provide detailed steps on how to upload NGINX configurations: + +- [Upload using the Azure portal]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md" >}}) +- [Upload using the Azure CLI]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-azure-cli" >}}) +- [Upload using Terraform]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configurations-terraform.md" >}}) + +The topics below provide information on NGINX configuration restrictions and directives that are supported by NGINXaaS for Azure when using any of the above workflows. + +## NGINX configuration automation workflows + +NGINX configurations stored in GitHub can be applied to existing NGINXaaS for Azure deployments using custom GitHub Action workflows. See [NGINXaaS for Azure Deployment Action](https://github.com/nginxinc/nginx-for-azure-deploy-action) for documentation and examples on how to incorporate these workflows in your GitHub Actions CI/CD pipelines. + +## NGINX filesystem restrictions +NGINXaaS for Azure places restrictions on the instance's filesystem; only a specific set of directories are allowed to be read from and written to. Below is a table describing what directories the NGINX worker process can read and write to and what directories files can be written to. These files include certificate files and any files uploaded to the deployment, excluding NGINX configuration files. + + {{}} + | Allowed Directory | NGINX worker process can read/write to | Files can be written to | + |------------------ | ----------------- | ----------------- | + | /etc/nginx | | ✓ | + | /opt | ✓ | ✓ | + | /srv | ✓ | ✓ | + | /tmp | ✓ | | + | /var/cache/nginx | ✓ | | + | /var/www | ✓ | ✓ | +{{}} + +Attempts to access other directories will be denied and result in a `5xx` error. + +## Disallowed configuration directives +Some directives are not supported because of specific limitations. If you include one of these directives in your NGINX configuration, you'll get an error. + + {{}} + | Disallowed Directive | Reason | + |------------------ | ----------------- | + | ssl_engine | No hardware SSL accelerator is available. | + | debug_points | NGINXaaS does not provide access to NGINX processes for debugging. | + | fastcgi_bind
grpc_bind
memcached_bind
proxy_bind
scgi_bind
uwsgi_bind | Source IP specification for active-active deployments is not allowed. | + | quic_bpf | QUIC connection migration is not currently supported for active-active deployments. | + +{{
}} + +You may find that a few directives are not listed here as either allowed or disallowed. Our team is working on getting these directives supported soon. + +## Directives that cannot be overridden +Some directives cannot be overridden by the user provided configuration. + + {{}} + | Persistent Directive | Value | Reason | + |------------------ | ----------------------- | -----------------| + | `user` | `nginx` | The `nginx` user has the correct permissions for accessing certificates, policy files and other auxfiles. | + | `worker_processes` | `auto` | Set to `auto` to automatically set `worker_processes` to the number of CPU cores. | + | `worker_connections` |
  • standard plan `4000`
  • basic plan `3000`
| To ensure reasonable performance of the NGINXaaS deployment for standard plan the `worker_connections` is fixed at 400/NCU; for basic plan this is set lower. | + | `pid` | `/run/nginx/nginx.pid` | Set to this value to allow NGINXaaS to automatically manage the NGINX master process. | + | `daemon` | `on` | Automatically set to `on` to allow NGINXaaS to manage the NGINX master process. | + | `master_process` | `on` | This directive is intended for NGINX developers. | + | `worker_cpu_affinity` | `auto` | The value `auto` allows binding worker processes automatically to available CPUs based on the current capacity of the deployment. | + +{{
}} + +## Configuration directives list + +
+Alphabetical index of directives + +NGINXaaS for Azure supports a limited set of NGINX directives. + +[absolute_redirect](https://nginx.org/en/docs/http/ngx_http_core_module.html#absolute_redirect)\ +[accept_mutex](https://nginx.org/en/docs/ngx_core_module.html#accept_mutex)\ +[accept_mutex_delay](https://nginx.org/en/docs/ngx_core_module.html#accept_mutex_delay)\ +[access_log (ngx_http_log_module)](https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log)\ +[access_log (ngx_stream_log_module)](https://nginx.org/en/docs/stream/ngx_stream_log_module.html#access_log)\ +[add_after_body](https://nginx.org/en/docs/http/ngx_http_addition_module.html#add_after_body)\ +[add_before_body](https://nginx.org/en/docs/http/ngx_http_addition_module.html#add_before_body)\ +[add_header](https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header)\ +[add_trailer](https://nginx.org/en/docs/http/ngx_http_headers_module.html#add_trailer)\ +[addition_types](https://nginx.org/en/docs/http/ngx_http_addition_module.html#addition_types)\ +[aio](https://nginx.org/en/docs/http/ngx_http_core_module.html#aio)\ +[aio_write](https://nginx.org/en/docs/http/ngx_http_core_module.html#aio_write)\ +[alias](https://nginx.org/en/docs/http/ngx_http_core_module.html#alias)\ +[allow (ngx_http_access_module)](https://nginx.org/en/docs/http/ngx_http_access_module.html#allow)\ +[allow (ngx_stream_access_module)](https://nginx.org/en/docs/stream/ngx_stream_access_module.html#allow)\ +[ancient_browser](https://nginx.org/en/docs/http/ngx_http_browser_module.html#ancient_browser)\ +[ancient_browser_value](https://nginx.org/en/docs/http/ngx_http_browser_module.html#ancient_browser_value)\ +[auth_basic](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic)\ +[auth_basic_user_file](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic_user_file)\ +[auth_delay](https://nginx.org/en/docs/http/ngx_http_core_module.html#auth_delay)\ +[auth_http](https://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#auth_http)\ +[auth_http_header](https://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#auth_http_header)\ +[auth_http_pass_client_cert](https://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#auth_http_pass_client_cert)\ +[auth_http_timeout](https://nginx.org/en/docs/mail/ngx_mail_auth_http_module.html#auth_http_timeout)\ +[auth_jwt](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt)\ +[auth_jwt_claim_set](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_claim_set)\ +[auth_jwt_header_set](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_header_set)\ +[auth_jwt_key_cache](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_key_cache)\ +[auth_jwt_key_file](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_key_file)\ +[auth_jwt_key_request](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_key_request)\ +[auth_jwt_leeway](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_leeway)\ +[auth_jwt_require](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_require)\ +[auth_jwt_type](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_type)\ +[auth_request](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html#auth_request)\ +[auth_request_set](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html#auth_request_set)\ +[autoindex](https://nginx.org/en/docs/http/ngx_http_autoindex_module.html#autoindex)\ +[autoindex_exact_size](https://nginx.org/en/docs/http/ngx_http_autoindex_module.html#autoindex_exact_size)\ +[autoindex_format](https://nginx.org/en/docs/http/ngx_http_autoindex_module.html#autoindex_format)\ +[autoindex_localtime](https://nginx.org/en/docs/http/ngx_http_autoindex_module.html#autoindex_localtime)\ +[break](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#break)\ +[connect_timeout](https://nginx.org/en/docs/ngx_mgmt_module.html#connect_timeout)\ +[charset](https://nginx.org/en/docs/http/ngx_http_charset_module.html#charset)\ +[charset_map](https://nginx.org/en/docs/http/ngx_http_charset_module.html#charset_map)\ +[charset_types](https://nginx.org/en/docs/http/ngx_http_charset_module.html#charset_types)\ +[chunked_transfer_encoding](https://nginx.org/en/docs/http/ngx_http_core_module.html#chunked_transfer_encoding)\ +[client_body_buffer_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size)\ +[client_body_in_file_only](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_in_file_only)\ +[client_body_in_single_buffer](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_in_single_buffer)\ +[client_body_temp_path](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_temp_path)\ +[client_body_timeout](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout)\ +[client_header_buffer_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_buffer_size)\ +[client_header_timeout](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout)\ +[client_max_body_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size)\ +[connection_pool_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#connection_pool_size)\ +[create_full_put_path](https://nginx.org/en/docs/http/ngx_http_dav_module.html#create_full_put_path)\ +[daemon](https://nginx.org/en/docs/ngx_core_module.html#daemon)\ +[dav_access](https://nginx.org/en/docs/http/ngx_http_dav_module.html#dav_access)\ +[dav_methods](https://nginx.org/en/docs/http/ngx_http_dav_module.html#dav_methods)\ +[debug_connection](https://nginx.org/en/docs/ngx_core_module.html#debug_connection)\ +[default_type](https://nginx.org/en/docs/http/ngx_http_core_module.html#default_type)\ +[deny (ngx_http_access_module)](https://nginx.org/en/docs/http/ngx_http_access_module.html#deny)\ +[deny (ngx_stream_access_module)](https://nginx.org/en/docs/stream/ngx_stream_access_module.html#deny)\ +[directio](https://nginx.org/en/docs/http/ngx_http_core_module.html#directio)\ +[directio_alignment](https://nginx.org/en/docs/http/ngx_http_core_module.html#directio_alignment)\ +[disable_symlinks](https://nginx.org/en/docs/http/ngx_http_core_module.html#disable_symlinks)\ +[empty_gif](https://nginx.org/en/docs/http/ngx_http_empty_gif_module.html#empty_gif)\ +[env](https://nginx.org/en/docs/ngx_core_module.html#env)\ +[error_log](https://nginx.org/en/docs/ngx_core_module.html#error_log)\ +[error_page](https://nginx.org/en/docs/http/ngx_http_core_module.html#error_page)\ +[etag](https://nginx.org/en/docs/http/ngx_http_core_module.html#etag)\ +[events](https://nginx.org/en/docs/ngx_core_module.html#events)\ +[expires](https://nginx.org/en/docs/http/ngx_http_headers_module.html#expires)\ +[f4f](https://nginx.org/en/docs/http/ngx_http_f4f_module.html#f4f)\ +[f4f_buffer_size](https://nginx.org/en/docs/http/ngx_http_f4f_module.html#f4f_buffer_size)\ +[fastcgi_buffer_size](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffer_size)\ +[fastcgi_buffering](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffering)\ +[fastcgi_buffers](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_buffers)\ +[fastcgi_busy_buffers_size](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_busy_buffers_size)\ +[fastcgi_cache](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache)\ +[fastcgi_cache_background_update](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_background_update)\ +[fastcgi_cache_bypass](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_bypass)\ +[fastcgi_cache_key](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_key)\ +[fastcgi_cache_lock](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_lock)\ +[fastcgi_cache_lock_age](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_lock_age)\ +[fastcgi_cache_lock_timeout](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_lock_timeout)\ +[fastcgi_cache_max_range_offset](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_max_range_offset)\ +[fastcgi_cache_methods](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_methods)\ +[fastcgi_cache_min_uses](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_min_uses)\ +[fastcgi_cache_path](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_path)\ +[fastcgi_cache_revalidate](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_revalidate)\ +[fastcgi_cache_use_stale](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_use_stale)\ +[fastcgi_cache_valid](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_cache_valid)\ +[fastcgi_catch_stderr](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_catch_stderr)\ +[fastcgi_connect_timeout](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_connect_timeout)\ +[fastcgi_force_ranges](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_force_ranges)\ +[fastcgi_hide_header](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_hide_header)\ +[fastcgi_ignore_client_abort](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_ignore_client_abort)\ +[fastcgi_ignore_headers](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_ignore_headers)\ +[fastcgi_index](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_index)\ +[fastcgi_intercept_errors](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_intercept_errors)\ +[fastcgi_keep_conn](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_keep_conn)\ +[fastcgi_limit_rate](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_limit_rate)\ +[fastcgi_max_temp_file_size](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_max_temp_file_size)\ +[fastcgi_next_upstream](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_next_upstream)\ +[fastcgi_next_upstream_timeout](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_next_upstream_timeout)\ +[fastcgi_next_upstream_tries](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_next_upstream_tries)\ +[fastcgi_no_cache](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_no_cache)\ +[fastcgi_param](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param)\ +[fastcgi_pass](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass)\ +[fastcgi_pass_header](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass_header)\ +[fastcgi_pass_request_body](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass_request_body)\ +[fastcgi_pass_request_headers](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass_request_headers)\ +[fastcgi_read_timeout](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_read_timeout)\ +[fastcgi_request_buffering](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_request_buffering)\ +[fastcgi_send_lowat](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_send_lowat)\ +[fastcgi_send_timeout](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_send_timeout)\ +[fastcgi_socket_keepalive](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_socket_keepalive)\ +[fastcgi_split_path_info](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info)\ +[fastcgi_store](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_store)\ +[fastcgi_store_access](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_store_access)\ +[fastcgi_temp_file_write_size](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_temp_file_write_size)\ +[fastcgi_temp_path](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_temp_path)\ +[flv](https://nginx.org/en/docs/http/ngx_http_flv_module.html#flv)\ +[geo (ngx_http_geo_module)](https://nginx.org/en/docs/http/ngx_http_geo_module.html#geo)\ +[geo (ngx_stream_geo_module)](https://nginx.org/en/docs/stream/ngx_stream_geo_module.html#geo)\ +[grpc_buffer_size](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_buffer_size)\ +[grpc_connect_timeout](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_connect_timeout)\ +[grpc_hide_header](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_hide_header)\ +[grpc_ignore_headers](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ignore_headers)\ +[grpc_intercept_errors](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_intercept_errors)\ +[grpc_next_upstream](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_next_upstream)\ +[grpc_next_upstream_timeout](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_next_upstream_timeout)\ +[grpc_next_upstream_tries](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_next_upstream_tries)\ +[grpc_pass](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_pass)\ +[grpc_pass_header](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_pass_header)\ +[grpc_read_timeout](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_read_timeout)\ +[grpc_send_timeout](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_send_timeout)\ +[grpc_set_header](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_set_header)\ +[grpc_socket_keepalive](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_socket_keepalive)\ +[grpc_ssl_certificate](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_certificate)\ +[grpc_ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_certificate_key)\ +[grpc_ssl_ciphers](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_ciphers)\ +[grpc_ssl_conf_command](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_conf_command)\ +[grpc_ssl_crl](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_crl)\ +[grpc_ssl_name](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_name)\ +[grpc_ssl_password_file](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_password_file)\ +[grpc_ssl_protocols](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_protocols)\ +[grpc_ssl_server_name](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_server_name)\ +[grpc_ssl_session_reuse](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_session_reuse)\ +[grpc_ssl_trusted_certificate](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_trusted_certificate)\ +[grpc_ssl_verify](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_verify)\ +[grpc_ssl_verify_depth](https://nginx.org/en/docs/http/ngx_http_grpc_module.html#grpc_ssl_verify_depth)\ +[gunzip](https://nginx.org/en/docs/http/ngx_http_gunzip_module.html#gunzip)\ +[gunzip_buffers](https://nginx.org/en/docs/http/ngx_http_gunzip_module.html#gunzip_buffers)\ +[gzip](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip)\ +[gzip_buffers](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_buffers)\ +[gzip_comp_level](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_comp_level)\ +[gzip_disable](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_disable)\ +[gzip_http_version](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_http_version)\ +[gzip_min_length](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_min_length)\ +[gzip_proxied](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_proxied)\ +[gzip_static](https://nginx.org/en/docs/http/ngx_http_gzip_static_module.html#gzip_static)\ +[gzip_types](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_types)\ +[gzip_vary](https://nginx.org/en/docs/http/ngx_http_gzip_module.html#gzip_vary)\ +[hash (ngx_http_upstream_module)](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#hash)\ +[hash (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#hash)\ +[health_check (ngx_http_upstream_hc_module)](https://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#health_check)\ +[health_check (ngx_stream_upstream_hc_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_hc_module.html#health_check)\ +[health_check_timeout](https://nginx.org/en/docs/stream/ngx_stream_upstream_hc_module.html#health_check_timeout)\ +[hls](https://nginx.org/en/docs/http/ngx_http_hls_module.html#hls)\ +[hls_buffers](https://nginx.org/en/docs/http/ngx_http_hls_module.html#hls_buffers)\ +[hls_forward_args](https://nginx.org/en/docs/http/ngx_http_hls_module.html#hls_forward_args)\ +[hls_fragment](https://nginx.org/en/docs/http/ngx_http_hls_module.html#hls_fragment)\ +[hls_mp4_buffer_size](https://nginx.org/en/docs/http/ngx_http_hls_module.html#hls_mp4_buffer_size)\ +[hls_mp4_max_buffer_size](https://nginx.org/en/docs/http/ngx_http_hls_module.html#hls_mp4_max_buffer_size)\ +[http](https://nginx.org/en/docs/http/ngx_http_core_module.html#http)\ +[http2_body_preread_size](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_body_preread_size)\ +[http2_chunk_size](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_chunk_size)\ +[http2_idle_timeout](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_idle_timeout)\ +[http2_max_concurrent_pushes](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_concurrent_pushes)\ +[http2_max_concurrent_streams](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_concurrent_streams)\ +[http2_max_field_size](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_field_size)\ +[http2_max_header_size](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_header_size)\ +[http2_max_requests](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_requests)\ +[http2_push](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_push)\ +[http2_push_preload](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_push_preload)\ +[http2_recv_buffer_size](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_recv_buffer_size)\ +[http2_recv_timeout](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_recv_timeout)\ +[http3](http://nginx.org/en/docs/http/ngx_http_v3_module.html#http3)\ +[http3_hq](http://nginx.org/en/docs/http/ngx_http_v3_module.html#http3_hq)\ +[http3_max_concurrent_streams](http://nginx.org/en/docs/http/ngx_http_v3_module.html#http3_max_concurrent_streams)\ +[http3_stream_buffer_size](http://nginx.org/en/docs/http/ngx_http_v3_module.html#http3_stream_buffer_size)\ +[if](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if)\ +[if_modified_since](https://nginx.org/en/docs/http/ngx_http_core_module.html#if_modified_since)\ +[ignore_invalid_headers](https://nginx.org/en/docs/http/ngx_http_core_module.html#ignore_invalid_headers)\ +[image_filter](http://nginx.org/en/docs/http/ngx_http_image_filter_module.html#image_filter)\ +[image_filter_buffer](http://nginx.org/en/docs/http/ngx_http_image_filter_module.html#image_filter_buffer)\ +[image_filter_interlace](http://nginx.org/en/docs/http/ngx_http_image_filter_module.html#image_filter_interlace)\ +[image_filter_jpeg_quality](http://nginx.org/en/docs/http/ngx_http_image_filter_module.html#image_filter_jpeg_quality)\ +[image_filter_sharpen](http://nginx.org/en/docs/http/ngx_http_image_filter_module.html#image_filter_sharpen)\ +[image_filter_transparency](http://nginx.org/en/docs/http/ngx_http_image_filter_module.html#image_filter_transparency)\ +[image_filter_webp_quality](http://nginx.org/en/docs/http/ngx_http_image_filter_module.html#image_filter_webp_quality)\ +[imap_auth](https://nginx.org/en/docs/mail/ngx_mail_imap_module.html#imap_auth)\ +[imap_capabilities](https://nginx.org/en/docs/mail/ngx_mail_imap_module.html#imap_capabilities)\ +[imap_client_buffer](https://nginx.org/en/docs/mail/ngx_mail_imap_module.html#imap_client_buffer)\ +[include](https://nginx.org/en/docs/ngx_core_module.html#include)\ +[index](https://nginx.org/en/docs/http/ngx_http_index_module.html#index)\ +[internal](https://nginx.org/en/docs/http/ngx_http_core_module.html#internal)\ +[internal_redirect](http://nginx.org/en/docs/http/ngx_http_internal_redirect_module.html#internal_redirect)\ +[ip_hash](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash)\ +[js_access (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_access)\ +[js_body_filter](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_body_filter)\ +[js_content](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_content)\ +[js_fetch_buffer_size (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_fetch_buffer_size)\ +[js_fetch_buffer_size (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_fetch_buffer_size)\ +[js_fetch_ciphers (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_fetch_ciphers)\ +[js_fetch_ciphers (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_fetch_ciphers)\ +[js_fetch_max_response_buffer_size (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_fetch_max_response_buffer_size)\ +[js_fetch_max_response_buffer_size (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_fetch_max_response_buffer_size)\ +[js_fetch_protocols (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_fetch_protocols)\ +[js_fetch_protocols (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_fetch_protocols)\ +[js_fetch_timeout (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_fetch_timeout)\ +[js_fetch_timeout (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_fetch_timeout)\ +[js_fetch_trusted_certificate (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_fetch_trusted_certificate)\ +[js_fetch_trusted_certificate (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_fetch_trusted_certificate)\ +[js_fetch_verify (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_fetch_verify)\ +[js_fetch_verify (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_fetch_verify)\ +[js_fetch_verify_depth (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_fetch_verify_depth)\ +[js_fetch_verify_depth (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_fetch_verify_depth)\ +[js_filter (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_filter)\ +[js_header_filter](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_header_filter)\ +[js_import (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_import)\ +[js_import (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_import)\ +[js_include (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_include)\ +[js_include (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_include)\ +[js_path (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_path)\ +[js_path (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_path)\ +[js_periodic (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_periodic)\ +[js_periodic (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_periodic)\ +[js_preload_object (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_preload_object)\ +[js_preload_object (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_preload_object)\ +[js_preread (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_preread)\ +[js_set (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_set)\ +[js_set (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_set)\ +[js_var (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_var)\ +[js_var (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_var)\ +[js_shared_dict_zone (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_shared_dict_zone)\ +[js_var (ngx_http_js_module)](https://nginx.org/en/docs/http/ngx_http_js_module.html#js_var)\ +[js_var (ngx_stream_js_module)](https://nginx.org/en/docs/stream/ngx_stream_js_module.html#js_var)\ +[keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive)\ +[keepalive_disable](https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_disable)\ +[keepalive_requests (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_requests)\ +[keepalive_time (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_time)\ +[keepalive_timeout (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout)\ +[keyval (ngx_http_keyval_module)](https://nginx.org/en/docs/http/ngx_http_keyval_module.html#keyval)\ +[keyval (ngx_stream_keyval_module)](https://nginx.org/en/docs/stream/ngx_stream_keyval_module.html#keyval)\ +[keyval_zone (ngx_http_keyval_module)](https://nginx.org/en/docs/http/ngx_http_keyval_module.html#keyval_zone)\ +[keyval_zone (ngx_stream_keyval_module)](https://nginx.org/en/docs/stream/ngx_stream_keyval_module.html#keyval_zone)\ +[large_client_header_buffers](https://nginx.org/en/docs/http/ngx_http_core_module.html#large_client_header_buffers)\ +[least_conn (ngx_http_upstream_module)](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#least_conn)\ +[least_conn (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#least_conn)\ +[least_time (ngx_http_upstream_module)](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#least_time)\ +[least_time (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#least_time)\ +[limit_conn (ngx_http_limit_conn_module)](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn)\ +[limit_conn (ngx_stream_limit_conn_module)](https://nginx.org/en/docs/stream/ngx_stream_limit_conn_module.html#limit_conn)\ +[limit_conn_dry_run (ngx_http_limit_conn_module)](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_dry_run)\ +[limit_conn_dry_run (ngx_stream_limit_conn_module)](https://nginx.org/en/docs/stream/ngx_stream_limit_conn_module.html#limit_conn_dry_run)\ +[limit_conn_log_level (ngx_http_limit_conn_module)](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_log_level)\ +[limit_conn_log_level (ngx_stream_limit_conn_module)](https://nginx.org/en/docs/stream/ngx_stream_limit_conn_module.html#limit_conn_log_level)\ +[limit_conn_status](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_status)\ +[limit_conn_zone (ngx_http_limit_conn_module)](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_conn_zone)\ +[limit_conn_zone (ngx_stream_limit_conn_module)](https://nginx.org/en/docs/stream/ngx_stream_limit_conn_module.html#limit_conn_zone)\ +[limit_except](https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_except)\ +[limit_rate](https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate)\ +[limit_rate_after](https://nginx.org/en/docs/http/ngx_http_core_module.html#limit_rate_after)\ +[limit_req](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req)\ +[limit_req_dry_run](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_dry_run)\ +[limit_req_log_level](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_log_level)\ +[limit_req_status](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_status)\ +[limit_req_zone](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone)\ +[limit_zone](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html#limit_zone)\ +[lingering_close](https://nginx.org/en/docs/http/ngx_http_core_module.html#lingering_close)\ +[lingering_time](https://nginx.org/en/docs/http/ngx_http_core_module.html#lingering_time)\ +[lingering_timeout](https://nginx.org/en/docs/http/ngx_http_core_module.html#lingering_timeout)\ +[listen (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#listen)\ +[listen (ngx_mail_core_module)](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#listen)\ +[load_module](https://nginx.org/en/docs/ngx_core_module.html#load_module)\ +[location](https://nginx.org/en/docs/http/ngx_http_core_module.html#location)\ +[lock_file](http://nginx.org/en/docs/ngx_core_module.html#lock_file)\ +[log_format (ngx_http_log_module)](https://nginx.org/en/docs/http/ngx_http_log_module.html#log_format)\ +[log_format (ngx_stream_log_module)](https://nginx.org/en/docs/stream/ngx_stream_log_module.html#log_format)\ +[log_not_found](https://nginx.org/en/docs/http/ngx_http_core_module.html#log_not_found)\ +[log_subrequest](https://nginx.org/en/docs/http/ngx_http_core_module.html#log_subrequest)\ +[mail](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#mail)\ +[map (ngx_http_map_module)](https://nginx.org/en/docs/http/ngx_http_map_module.html#map)\ +[map (ngx_stream_map_module)](https://nginx.org/en/docs/stream/ngx_stream_map_module.html#map)\ +[map_hash_bucket_size (ngx_http_map_module)](https://nginx.org/en/docs/http/ngx_http_map_module.html#map_hash_bucket_size)\ +[map_hash_bucket_size (ngx_stream_map_module)](https://nginx.org/en/docs/stream/ngx_stream_map_module.html#map_hash_bucket_size)\ +[map_hash_max_size (ngx_http_map_module)](https://nginx.org/en/docs/http/ngx_http_map_module.html#map_hash_max_size)\ +[map_hash_max_size (ngx_stream_map_module)](https://nginx.org/en/docs/stream/ngx_stream_map_module.html#map_hash_max_size)\ +[master_process](https://nginx.org/en/docs/ngx_core_module.html#master_process)\ +[match (ngx_http_upstream_hc_module)](https://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#match)\ +[match (ngx_stream_upstream_hc_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_hc_module.html#match)\ +[max_errors](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#max_errors)\ +[max_ranges](https://nginx.org/en/docs/http/ngx_http_core_module.html#max_ranges)\ +[memcached_buffer_size](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_buffer_size)\ +[memcached_connect_timeout](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_connect_timeout)\ +[memcached_gzip_flag](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_gzip_flag)\ +[memcached_next_upstream](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_next_upstream)\ +[memcached_next_upstream_timeout](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_next_upstream_timeout)\ +[memcached_next_upstream_tries](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_next_upstream_tries)\ +[memcached_pass](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_pass)\ +[memcached_read_timeout](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_read_timeout)\ +[memcached_send_timeout](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_send_timeout)\ +[memcached_socket_keepalive](https://nginx.org/en/docs/http/ngx_http_memcached_module.html#memcached_socket_keepalive)\ +[merge_slashes](https://nginx.org/en/docs/http/ngx_http_core_module.html#merge_slashes)\ +[mgmt](https://nginx.org/en/docs/ngx_mgmt_module.html#mgmt)\ +[min_delete_depth](https://nginx.org/en/docs/http/ngx_http_dav_module.html#min_delete_depth)\ +[mirror](https://nginx.org/en/docs/http/ngx_http_mirror_module.html#mirror)\ +[mirror_request_body](https://nginx.org/en/docs/http/ngx_http_mirror_module.html#mirror_request_body)\ +[modern_browser](https://nginx.org/en/docs/http/ngx_http_browser_module.html#modern_browser)\ +[modern_browser_value](https://nginx.org/en/docs/http/ngx_http_browser_module.html#modern_browser_value)\ +[more_clear_headers](https://github.com/openresty/headers-more-nginx-module?tab=readme-ov-file#more_clear_headers)\ +[more_clear_input_headers](https://github.com/openresty/headers-more-nginx-module?tab=readme-ov-file#more_clear_input_headers)\ +[more_set_headers](https://github.com/openresty/headers-more-nginx-module?tab=readme-ov-file#more_set_headers)\ +[more_set_input_headers](https://github.com/openresty/headers-more-nginx-module?tab=readme-ov-file#more_set_input_headers)\ +[mp4](https://nginx.org/en/docs/http/ngx_http_mp4_module.html#mp4)\ +[mp4_buffer_size](https://nginx.org/en/docs/http/ngx_http_mp4_module.html#mp4_buffer_size)\ +[mp4_limit_rate](https://nginx.org/en/docs/http/ngx_http_mp4_module.html#mp4_limit_rate)\ +[mp4_limit_rate_after](https://nginx.org/en/docs/http/ngx_http_mp4_module.html#mp4_limit_rate_after)\ +[mp4_max_buffer_size](https://nginx.org/en/docs/http/ngx_http_mp4_module.html#mp4_max_buffer_size)\ +[mp4_start_key_frame](https://nginx.org/en/docs/http/ngx_http_mp4_module.html#mp4_start_key_frame)\ +[mqtt](https://nginx.org/en/docs/stream/ngx_stream_mqtt_filter_module.html#mqtt)\ +[mqtt_rewrite_buffer_size](https://nginx.org/en/docs/stream/ngx_stream_mqtt_filter_module.html#mqtt_rewrite_buffer_size)\ +[mqtt_set_connect](https://nginx.org/en/docs/stream/ngx_stream_mqtt_filter_module.html#mqtt_set_connect)\ +[msie_padding](https://nginx.org/en/docs/http/ngx_http_core_module.html#msie_padding)\ +[msie_refresh](https://nginx.org/en/docs/http/ngx_http_core_module.html#msie_refresh)\ +[multi_accept](https://nginx.org/en/docs/ngx_core_module.html#multi_accept)\ +[ntlm](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#ntlm)\ +[open_file_cache](https://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache)\ +[open_file_cache_errors](https://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache_errors)\ +[open_file_cache_min_uses](https://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache_min_uses)\ +[open_file_cache_valid](https://nginx.org/en/docs/http/ngx_http_core_module.html#open_file_cache_valid)\ +[open_log_file_cache (ngx_http_log_module)](https://nginx.org/en/docs/http/ngx_http_log_module.html#open_log_file_cache)\ +[open_log_file_cache (ngx_stream_log_module)](https://nginx.org/en/docs/stream/ngx_stream_log_module.html#open_log_file_cache)\ +[otel_exporter](https://nginx.org/en/docs/ngx_otel_module.html#otel_exporter)\ +[otel_service_name](https://nginx.org/en/docs/ngx_otel_module.html#otel_service_name)\ +[otel_trace](https://nginx.org/en/docs/ngx_otel_module.html#otel_trace)\ +[otel_trace_context](https://nginx.org/en/docs/ngx_otel_module.html#otel_trace_context)\ +[otel_span_name](https://nginx.org/en/docs/ngx_otel_module.html#otel_span_name)\ +[otel_span_attr](https://nginx.org/en/docs/ngx_otel_module.html#otel_span_attr)\ +[output_buffers](https://nginx.org/en/docs/http/ngx_http_core_module.html#output_buffers)\ +[override_charset](https://nginx.org/en/docs/http/ngx_http_charset_module.html#override_charset)\ +[pass](https://nginx.org/en/docs/stream/ngx_stream_pass_module.html#pass)\ +[pid](https://nginx.org/en/docs/ngx_core_module.html#pid)\ +[pop3_auth](https://nginx.org/en/docs/mail/ngx_mail_pop3_module.html#pop3_auth)\ +[pop3_capabilities](https://nginx.org/en/docs/mail/ngx_mail_pop3_module.html#pop3_capabilities)\ +[port_in_redirect](https://nginx.org/en/docs/http/ngx_http_core_module.html#port_in_redirect)\ +[postpone_output](https://nginx.org/en/docs/http/ngx_http_core_module.html#postpone_output)\ +[preread_buffer_size (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#preread_buffer_size)\ +[preread_timeout (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#preread_timeout)\ +[protocol](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#protocol)\ +[proxy_buffer](https://nginx.org/en/docs/mail/ngx_mail_proxy_module.html#proxy_buffer)\ +[proxy_buffer_size (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffer_size)\ +[proxy_buffer_size (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_buffer_size)\ +[proxy_buffering](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering)\ +[proxy_buffers](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers)\ +[proxy_busy_buffers_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_busy_buffers_size)\ +[proxy_cache](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache)\ +[proxy_cache_background_update](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_background_update)\ +[proxy_cache_bypass](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_bypass)\ +[proxy_cache_convert_head](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_convert_head)\ +[proxy_cache_key](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_key)\ +[proxy_cache_lock](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_lock)\ +[proxy_cache_lock_age](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_lock_age)\ +[proxy_cache_lock_timeout](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_lock_timeout)\ +[proxy_cache_max_range_offset](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_max_range_offset)\ +[proxy_cache_methods](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_methods)\ +[proxy_cache_min_uses](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_min_uses)\ +[proxy_cache_path](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_path)\ +[proxy_cache_purge](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_purge)\ +[proxy_cache_revalidate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_revalidate)\ +[proxy_cache_use_stale](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_use_stale)\ +[proxy_cache_valid](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cache_valid)\ +[proxy_connect_timeout (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout)\ +[proxy_connect_timeout (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_connect_timeout)\ +[proxy_cookie_domain](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_domain)\ +[proxy_cookie_flags](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_flags)\ +[proxy_cookie_path](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_cookie_path)\ +[proxy_download_rate (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_download_rate)\ +[proxy_force_ranges](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_force_ranges)\ +[proxy_half_close (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_half_close)\ +[proxy_headers_hash_bucket_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_bucket_size)\ +[proxy_headers_hash_max_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_headers_hash_max_size)\ +[proxy_hide_header](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header)\ +[proxy_http_version](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version)\ +[proxy_ignore_client_abort](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_client_abort)\ +[proxy_ignore_headers](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ignore_headers)\ +[proxy_intercept_errors](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_intercept_errors)\ +[proxy_limit_rate](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_limit_rate)\ +[proxy_max_temp_file_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_max_temp_file_size)\ +[proxy_method](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_method)\ +[proxy_next_upstream (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream)\ +[proxy_next_upstream (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream)\ +[proxy_next_upstream_timeout (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream_timeout)\ +[proxy_next_upstream_timeout (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_timeout)\ +[proxy_next_upstream_tries (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream_tries)\ +[proxy_next_upstream_tries (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_next_upstream_tries)\ +[proxy_no_cache](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_no_cache)\ +[proxy_pass (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass)\ +[proxy_pass (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_pass)\ +[proxy_pass_error_message](https://nginx.org/en/docs/mail/ngx_mail_proxy_module.html#proxy_pass_error_message)\ +[proxy_pass_header](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_header)\ +[proxy_pass_request_body](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_body)\ +[proxy_pass_request_headers](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_headers)\ +[proxy_protocol (ngx_mail_proxy_module)](https://nginx.org/en/docs/mail/ngx_mail_proxy_module.html#proxy_protocol)\ +[proxy_protocol (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_protocol)\ +[proxy_protocol_timeout (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#proxy_protocol_timeout)\ +[proxy_read_timeout](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout)\ +[proxy_redirect](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect)\ +[proxy_requests (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_requests)\ +[proxy_request_buffering](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_request_buffering)\ +[proxy_responses (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_responses)\ +[proxy_send_lowat](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_lowat)\ +[proxy_send_timeout](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout)\ +[proxy_session_drop (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_session_drop)\ +[proxy_set_body](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_body)\ +[proxy_set_header](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_set_header)\ +[proxy_smtp_auth](https://nginx.org/en/docs/mail/ngx_mail_proxy_module.html#proxy_smtp_auth)\ +[proxy_socket_keepalive (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_socket_keepalive)\ +[proxy_socket_keepalive (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_socket_keepalive)\ +[proxy_ssl (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl)\ +[proxy_ssl_certificate (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate)\ +[proxy_ssl_certificate (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_certificate)\ +[proxy_ssl_certificate_key (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_certificate_key)\ +[proxy_ssl_certificate_key (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_certificate_key)\ +[proxy_ssl_ciphers (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_ciphers)\ +[proxy_ssl_ciphers (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_ciphers)\ +[proxy_ssl_conf_command (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_conf_command)\ +[proxy_ssl_conf_command (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_conf_command)\ +[proxy_ssl_crl (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_crl)\ +[proxy_ssl_crl (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_crl)\ +[proxy_ssl_name (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_name)\ +[proxy_ssl_name (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_name)\ +[proxy_ssl_password_file (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_password_file)\ +[proxy_ssl_password_file (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_password_file)\ +[proxy_ssl_protocols (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_protocols)\ +[proxy_ssl_protocols (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_protocols)\ +[proxy_ssl_server_name (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_server_name)\ +[proxy_ssl_server_name (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_server_name)\ +[proxy_ssl_session_reuse (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_session_reuse)\ +[proxy_ssl_session_reuse (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_session_reuse)\ +[proxy_ssl_trusted_certificate (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_trusted_certificate)\ +[proxy_ssl_trusted_certificate (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_trusted_certificate)\ +[proxy_ssl_verify (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify)\ +[proxy_ssl_verify (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_verify)\ +[proxy_ssl_verify_depth (ngx_http_proxy_module)](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify_depth)\ +[proxy_ssl_verify_depth (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_ssl_verify_depth)\ +[proxy_store](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_store)\ +[proxy_store_access](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_store_access)\ +[proxy_temp_file_write_size](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_temp_file_write_size)\ +[proxy_temp_path](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_temp_path)\ +[proxy_timeout (ngx_mail_proxy_module)](https://nginx.org/en/docs/mail/ngx_mail_proxy_module.html#proxy_timeout)\ +[proxy_timeout (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_timeout)\ +[proxy_upload_rate (ngx_stream_proxy_module)](https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html#proxy_upload_rate)\ +[queue](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#queue)\ +[quic_active_connection_id_limit](http://nginx.org/en/docs/http/ngx_http_v3_module.html#quic_active_connection_id_limit)\ +[quic_gso](http://nginx.org/en/docs/http/ngx_http_v3_module.html#quic_gso)\ +[quic_host_key](http://nginx.org/en/docs/http/ngx_http_v3_module.html#quic_host_key)\ +[quic_retry](http://nginx.org/en/docs/http/ngx_http_v3_module.html#quic_retry)\ +[random (ngx_http_upstream_module)](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#random)\ +[random (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#random)\ +[random_index](https://nginx.org/en/docs/http/ngx_http_random_index_module.html#random_index)\ +[read_ahead](https://nginx.org/en/docs/http/ngx_http_core_module.html#read_ahead)\ +[read_timeout](https://nginx.org/en/docs/ngx_mgmt_module.html#read_timeout)\ +[real_ip_header](https://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_header)\ +[real_ip_recursive](https://nginx.org/en/docs/http/ngx_http_realip_module.html#real_ip_recursive)\ +[recursive_error_pages](https://nginx.org/en/docs/http/ngx_http_core_module.html#recursive_error_pages)\ +[referer_hash_bucket_size](https://nginx.org/en/docs/http/ngx_http_referer_module.html#referer_hash_bucket_size)\ +[referer_hash_max_size](https://nginx.org/en/docs/http/ngx_http_referer_module.html#referer_hash_max_size)\ +[request_pool_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#request_pool_size)\ +[reset_timedout_connection](https://nginx.org/en/docs/http/ngx_http_core_module.html#reset_timedout_connection)\ +[resolver (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver)\ +[resolver (ngx_mail_core_module)](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#resolver)\ +[resolver (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#resolver)\ +[resolver (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#resolver)\ +[resolver (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#resolver)\ +[resolver_timeout (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#resolver_timeout)\ +[resolver_timeout (ngx_mail_core_module)](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#resolver_timeout)\ +[resolver_timeout (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#resolver_timeout)\ +[resolver_timeout (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#resolver_timeout)\ +[resolver_timeout (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#resolver_timeout)\ +[return (ngx_http_rewrite_module)](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#return)\ +[return (ngx_stream_return_module)](https://nginx.org/en/docs/stream/ngx_stream_return_module.html#return)\ +[rewrite](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite)\ +[rewrite_log](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite_log)\ +[root](https://nginx.org/en/docs/http/ngx_http_core_module.html#root)\ +[satisfy](https://nginx.org/en/docs/http/ngx_http_core_module.html#satisfy)\ +[scgi_buffer_size](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_buffer_size)\ +[scgi_buffering](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_buffering)\ +[scgi_buffers](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_buffers)\ +[scgi_busy_buffers_size](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_busy_buffers_size)\ +[scgi_cache](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache)\ +[scgi_cache_background_update](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_background_update)\ +[scgi_cache_bypass](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_bypass)\ +[scgi_cache_key](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_key)\ +[scgi_cache_lock](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_lock)\ +[scgi_cache_lock_age](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_lock_age)\ +[scgi_cache_lock_timeout](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_lock_timeout)\ +[scgi_cache_max_range_offset](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_max_range_offset)\ +[scgi_cache_methods](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_methods)\ +[scgi_cache_min_uses](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_min_uses)\ +[scgi_cache_path](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_path)\ +[scgi_cache_purge](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_purge)\ +[scgi_cache_revalidate](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_revalidate)\ +[scgi_cache_use_stale](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_use_stale)\ +[scgi_cache_valid](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_cache_valid)\ +[scgi_connect_timeout](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_connect_timeout)\ +[scgi_force_ranges](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_force_ranges)\ +[scgi_hide_header](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_hide_header)\ +[scgi_ignore_client_abort](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_ignore_client_abort)\ +[scgi_ignore_headers](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_ignore_headers)\ +[scgi_intercept_errors](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_intercept_errors)\ +[scgi_limit_rate](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_limit_rate)\ +[scgi_max_temp_file_size](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_max_temp_file_size)\ +[scgi_next_upstream](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_next_upstream)\ +[scgi_next_upstream_timeout](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_next_upstream_timeout)\ +[scgi_next_upstream_tries](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_next_upstream_tries)\ +[scgi_no_cache](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_no_cache)\ +[scgi_param](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_param)\ +[scgi_pass](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_pass)\ +[scgi_pass_header](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_pass_header)\ +[scgi_pass_request_body](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_pass_request_body)\ +[scgi_pass_request_headers](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_pass_request_headers)\ +[scgi_read_timeout](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_read_timeout)\ +[scgi_request_buffering](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_request_buffering)\ +[scgi_send_timeout](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_send_timeout)\ +[scgi_socket_keepalive](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_socket_keepalive)\ +[scgi_store](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_store)\ +[scgi_store_access](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_store_access)\ +[scgi_temp_file_write_size](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_temp_file_write_size)\ +[scgi_temp_path](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_temp_path)\ +[secure_link](https://nginx.org/en/docs/http/ngx_http_secure_link_module.html#secure_link)\ +[secure_link_md5](https://nginx.org/en/docs/http/ngx_http_secure_link_module.html#secure_link_md5)\ +[secure_link_secret](https://nginx.org/en/docs/http/ngx_http_secure_link_module.html#secure_link_secret)\ +[send_lowat](https://nginx.org/en/docs/http/ngx_http_core_module.html#send_lowat)\ +[send_timeout (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout)\ +[send_timeout (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#send_timeout)\ +[sendfile](https://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile)\ +[sendfile_max_chunk](https://nginx.org/en/docs/http/ngx_http_core_module.html#sendfile_max_chunk)\ +[server (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#server)\ +[server (ngx_mail_core_module)](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#server)\ +[server (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#server)\ +[server (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#server)\ +[server_name (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name)\ +[server_name (ngx_mail_core_module)](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#server_name)\ +[server_name (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#server_name)\ +[server_name_in_redirect](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_name_in_redirect)\ +[server_tokens](https://nginx.org/en/docs/http/ngx_http_core_module.html#server_tokens)\ +[session_log](https://nginx.org/en/docs/http/ngx_http_session_log_module.html#session_log)\ +[session_log_format](https://nginx.org/en/docs/http/ngx_http_session_log_module.html#session_log_format)\ +[session_log_zone](https://nginx.org/en/docs/http/ngx_http_session_log_module.html#session_log_zone)\ +[set (ngx_http_rewrite_module)](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#set)\ +[set (ngx_stream_set_module)](https://nginx.org/en/docs/stream/ngx_stream_set_module.html#set)\ +[set_real_ip_from (ngx_http_realip_module)](https://nginx.org/en/docs/http/ngx_http_realip_module.html#set_real_ip_from)\ +[set_real_ip_from (ngx_mail_realip_module)](https://nginx.org/en/docs/mail/ngx_mail_realip_module.html#set_real_ip_from)\ +[set_real_ip_from (ngx_stream_realip_module)](https://nginx.org/en/docs/stream/ngx_stream_realip_module.html#set_real_ip_from)\ +[slice](https://nginx.org/en/docs/http/ngx_http_slice_module.html#slice)\ +[smtp_auth](https://nginx.org/en/docs/mail/ngx_mail_smtp_module.html#smtp_auth)\ +[smtp_capabilities](https://nginx.org/en/docs/mail/ngx_mail_smtp_module.html#smtp_capabilities)\ +[smtp_client_buffer](https://nginx.org/en/docs/mail/ngx_mail_smtp_module.html#smtp_client_buffer)\ +[smtp_greeting_delay](https://nginx.org/en/docs/mail/ngx_mail_smtp_module.html#smtp_greeting_delay)\ +[source_charset](https://nginx.org/en/docs/http/ngx_http_charset_module.html#source_charset) +[spdy_chunk_size](https://nginx.org/en/docs/http/ngx_http_spdy_module.html#spdy_chunk_size)\ +[spdy_headers_comp](https://nginx.org/en/docs/http/ngx_http_spdy_module.html#spdy_headers_comp)\ +[split_clients (ngx_http_split_clients_module)](https://nginx.org/en/docs/http/ngx_http_split_clients_module.html#split_clients)\ +[split_clients (ngx_stream_split_clients_module)](https://nginx.org/en/docs/stream/ngx_stream_split_clients_module.html#split_clients)\ +[ssi](https://nginx.org/en/docs/http/ngx_http_ssi_module.html#ssi)\ +[ssi_last_modified](https://nginx.org/en/docs/http/ngx_http_ssi_module.html#ssi_last_modified)\ +[ssi_min_file_chunk](https://nginx.org/en/docs/http/ngx_http_ssi_module.html#ssi_min_file_chunk)\ +[ssi_silent_errors](https://nginx.org/en/docs/http/ngx_http_ssi_module.html#ssi_silent_errors)\ +[ssi_types](https://nginx.org/en/docs/http/ngx_http_ssi_module.html#ssi_types)\ +[ssi_value_length](https://nginx.org/en/docs/http/ngx_http_ssi_module.html#ssi_value_length)\ +[ssl (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl)\ +[ssl (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl)\ +[ssl (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl)\ +[ssl_buffer_size](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_buffer_size)\ +[ssl_certificate (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate)\ +[ssl_certificate (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_certificate)\ +[ssl_certificate (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_certificate)\ +[ssl_certificate (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_certificate)\ +[ssl_certificate_key (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key)\ +[ssl_certificate_key (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_certificate_key)\ +[ssl_certificate_key (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_certificate_key)\ +[ssl_certificate_key (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_certificate_key)\ +[ssl_ciphers (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ciphers)\ +[ssl_ciphers (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_ciphers)\ +[ssl_ciphers (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_ciphers)\ +[ssl_client_certificate (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_client_certificate)\ +[ssl_client_certificate (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_client_certificate)\ +[ssl_client_certificate (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_client_certificate)\ +[ssl_conf_command (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_conf_command)\ +[ssl_conf_command (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_conf_command)\ +[ssl_conf_command (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_conf_command)\ +[ssl_crl (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_crl)\ +[ssl_crl (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_crl)\ +[ssl_crl (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_crl)\ +[ssl_dhparam (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam)\ +[ssl_dhparam (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_dhparam)\ +[ssl_early_data](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_early_data)\ +[ssl_ecdh_curve (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ecdh_curve)\ +[ssl_ecdh_curve (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_ecdh_curve)\ +[ssl_ecdh_curve (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_ecdh_curve)\ +[ssl_handshake_timeout](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_handshake_timeout)\ +[ssl_name](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_name)\ +[ssl_ocsp](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ocsp)\ +[ssl_ocsp_cache](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ocsp_cache)\ +[ssl_ocsp_responder](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_ocsp_responder)\ +[ssl_password_file (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_password_file)\ +[ssl_password_file (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_password_file)\ +[ssl_password_file (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_password_file)\ +[ssl_prefer_server_ciphers (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers)\ +[ssl_prefer_server_ciphers (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_prefer_server_ciphers)\ +[ssl_prefer_server_ciphers (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_prefer_server_ciphers)\ +[ssl_preread (ngx_stream_ssl_preread_module)](http://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html#var_ssl_preread_protocol)\ +[ssl_protocols (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_protocols)\ +[ssl_protocols (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_protocols)\ +[ssl_protocols (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_protocols)\ +[ssl_protocols (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_protocols)\ +[ssl_reject_handshake](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_reject_handshake)\ +[ssl_server_name](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_server_name)\ +[ssl_session_cache (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache)\ +[ssl_session_cache (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_session_cache)\ +[ssl_session_cache (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_session_cache)\ +[ssl_session_ticket_key (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_ticket_key)\ +[ssl_session_ticket_key (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_session_ticket_key)\ +[ssl_session_ticket_key (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_session_ticket_key)\ +[ssl_session_tickets (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_tickets)\ +[ssl_session_tickets (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_session_tickets)\ +[ssl_session_tickets (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_session_tickets)\ +[ssl_session_timeout (ngx_http_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_session_timeout)\ +[ssl_session_timeout (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_session_timeout)\ +[ssl_session_timeout (ngx_stream_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_timeout)\ +[ssl_stapling](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling)\ +[ssl_stapling_file](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling_file)\ +[ssl_stapling_responder](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling_responder)\ +[ssl_stapling_verify](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling_verify)\ +[ssl_trusted_certificate (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_trusted_certificate)\ +[ssl_trusted_certificate (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_trusted_certificate)\ +[ssl_trusted_certificate (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_trusted_certificate)\ +[ssl_trusted_certificate (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_trusted_certificate)\ +[ssl_verify](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_verify)\ +[ssl_verify_client (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_client)\ +[ssl_verify_client (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_verify_client)\ +[ssl_verify_client (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_verify_client)\ +[ssl_verify_depth (ngx_http_ssl_module)](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_verify_depth)\ +[ssl_verify_depth (ngx_mail_ssl_module)](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#ssl_verify_depth)\ +[ssl_verify_depth (ngx_stream_ssl_module)](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html#ssl_verify_depth)\ +[ssl_verify_depth (ngx_mgmt_module)](https://nginx.org/en/docs/ngx_mgmt_module.html#ssl_verify_depth)\ +[starttls](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html#starttls)\ +[state (ngx_http_upstream_module)](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#state)\ +[status_zone (ngx_http_api_module)](https://nginx.org/en/docs/http/ngx_http_api_module.html#status_zone)\ +[sticky](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky)\ +[sticky_cookie_insert](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky_cookie_insert)\ +[stream (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#stream)\ +[stub_status](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html#stub_status)\ +[sub_filter](https://nginx.org/en/docs/http/ngx_http_sub_module.html#sub_filter)\ +[sub_filter_last_modified](https://nginx.org/en/docs/http/ngx_http_sub_module.html#sub_filter_last_modified)\ +[sub_filter_once](https://nginx.org/en/docs/http/ngx_http_sub_module.html#sub_filter_once)\ +[sub_filter_types](https://nginx.org/en/docs/http/ngx_http_sub_module.html#sub_filter_types)\ +[subrequest_output_buffer_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#subrequest_output_buffer_size)\ +[tcp_nodelay (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nodelay)\ +[tcp_nodelay (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#tcp_nodelay)\ +[tcp_nopush](https://nginx.org/en/docs/http/ngx_http_core_module.html#tcp_nopush)\ +[thread_pool](https://nginx.org/en/docs/ngx_core_module.html#thread_pool)\ +[timeout](https://nginx.org/en/docs/mail/ngx_mail_core_module.html#timeout)\ +[timer_resolution](https://nginx.org/en/docs/ngx_core_module.html#timer_resolution)\ +[try_files](https://nginx.org/en/docs/http/ngx_http_core_module.html#try_files)\ +[types](https://nginx.org/en/docs/http/ngx_http_core_module.html#types)\ +[types_hash_bucket_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#types_hash_bucket_size)\ +[types_hash_max_size](https://nginx.org/en/docs/http/ngx_http_core_module.html#types_hash_max_size)\ +[underscores_in_headers](https://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers)\ +[uninitialized_variable_warn](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#uninitialized_variable_warn)\ +[upstream (ngx_http_upstream_module)](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream)\ +[upstream (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#upstream)\ +[upstream_conf](https://nginx.org/en/docs/http/ngx_http_upstream_conf_module.html#upstream_conf)\ +[usage_report](https://nginx.org/en/docs/ngx_mgmt_module.html#usage_report)\ +[use](https://nginx.org/en/docs/ngx_core_module.html#use)\ +[user](https://nginx.org/en/docs/ngx_core_module.html#user)\ +[userid](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid)\ +[userid_domain](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid_domain)\ +[userid_expires](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid_expires)\ +[userid_flags](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid_flags)\ +[userid_mark](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid_mark)\ +[userid_name](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid_name)\ +[userid_p3p](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid_p3p)\ +[userid_path](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid_path)\ +[userid_service](https://nginx.org/en/docs/http/ngx_http_userid_module.html#userid_service)\ +[uuid_file](https://nginx.org/en/docs/ngx_mgmt_module.html#uuid_file)\ +[uwsgi_buffer_size](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_buffer_size)\ +[uwsgi_buffering](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_buffering)\ +[uwsgi_buffers](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_buffers)\ +[uwsgi_busy_buffers_size](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_busy_buffers_size)\ +[uwsgi_cache](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache)\ +[uwsgi_cache_background_update](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_background_update)\ +[uwsgi_cache_bypass](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_bypass)\ +[uwsgi_cache_key](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_key)\ +[uwsgi_cache_lock](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_lock)\ +[uwsgi_cache_lock_age](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_lock_age)\ +[uwsgi_cache_lock_timeout](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_lock_timeout)\ +[uwsgi_cache_max_range_offset](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_max_range_offset)\ +[uwsgi_cache_methods](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_methods)\ +[uwsgi_cache_min_uses](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_min_uses)\ +[uwsgi_cache_path](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_path)\ +[uwsgi_cache_purge](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_purge)\ +[uwsgi_cache_revalidate](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_revalidate)\ +[uwsgi_cache_use_stale](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_use_stale)\ +[uwsgi_cache_valid](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_cache_valid)\ +[uwsgi_connect_timeout](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_connect_timeout)\ +[uwsgi_force_ranges](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_force_ranges)\ +[uwsgi_hide_header](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_hide_header)\ +[uwsgi_ignore_client_abort](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ignore_client_abort)\ +[uwsgi_ignore_headers](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ignore_headers)\ +[uwsgi_intercept_errors](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_intercept_errors)\ +[uwsgi_limit_rate](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_limit_rate)\ +[uwsgi_max_temp_file_size](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_max_temp_file_size)\ +[uwsgi_modifier1](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_modifier1)\ +[uwsgi_modifier2](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_modifier2)\ +[uwsgi_next_upstream](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_next_upstream)\ +[uwsgi_next_upstream_timeout](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_next_upstream_timeout)\ +[uwsgi_next_upstream_tries](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_next_upstream_tries)\ +[uwsgi_no_cache](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_no_cache)\ +[uwsgi_param](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_param)\ +[uwsgi_pass](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_pass)\ +[uwsgi_pass_header](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_pass_header)\ +[uwsgi_pass_request_body](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_pass_request_body)\ +[uwsgi_pass_request_headers](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_pass_request_headers)\ +[uwsgi_read_timeout](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_read_timeout)\ +[uwsgi_request_buffering](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_request_buffering)\ +[uwsgi_send_timeout](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_send_timeout)\ +[uwsgi_socket_keepalive](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_socket_keepalive)\ +[uwsgi_ssl_certificate](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_certificate)\ +[uwsgi_ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_certificate_key)\ +[uwsgi_ssl_conf_command](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_conf_command)\ +[uwsgi_ssl_crl](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_crl)\ +[uwsgi_ssl_name](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_name)\ +[uwsgi_ssl_password_file](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_password_file)\ +[uwsgi_ssl_protocols](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_protocols)\ +[uwsgi_ssl_server_name](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_server_name)\ +[uwsgi_ssl_session_reuse](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_session_reuse)\ +[uwsgi_ssl_trusted_certificate](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_trusted_certificate)\ +[uwsgi_ssl_verify](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_verify)\ +[uwsgi_ssl_verify_depth](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_ssl_verify_depth)\ +[uwsgi_store](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_store)\ +[uwsgi_store_access](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_store_access)\ +[uwsgi_temp_file_write_size](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_temp_file_write_size)\ +[uwsgi_temp_path](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_temp_path)\ +[valid_referers](https://nginx.org/en/docs/http/ngx_http_referer_module.html#valid_referers)\ +[variables_hash_bucket_size (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#variables_hash_bucket_size)\ +[variables_hash_bucket_size (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#variables_hash_bucket_size)\ +[variables_hash_max_size (ngx_http_core_module)](https://nginx.org/en/docs/http/ngx_http_core_module.html#variables_hash_max_size)\ +[variables_hash_max_size (ngx_stream_core_module)](https://nginx.org/en/docs/stream/ngx_stream_core_module.html#variables_hash_max_size)\ +[worker_aio_requests](https://nginx.org/en/docs/ngx_core_module.html#worker_aio_requests)\ +[worker_connections](https://nginx.org/en/docs/ngx_core_module.html#worker_connections)\ +[worker_cpu_affinity](https://nginx.org/en/docs/ngx_core_module.html#worker_cpu_affinity)\ +[worker_priority](https://nginx.org/en/docs/ngx_core_module.html#worker_priority)\ +[worker_processes](https://nginx.org/en/docs/ngx_core_module.html#worker_processes)\ +[worker_rlimit_core](https://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_core)\ +[worker_rlimit_nofile](https://nginx.org/en/docs/ngx_core_module.html#worker_rlimit_nofile)\ +[worker_shutdown_timeout](https://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout)\ +[working_directory](https://nginx.org/en/docs/ngx_core_module.html#working_directory)\ +[xclient](https://nginx.org/en/docs/mail/ngx_mail_proxy_module.html#xclient)\ +[xml_entities](https://nginx.org/en/docs/http/ngx_http_xslt_module.html#xml_entities)\ +[xslt_last_modified](https://nginx.org/en/docs/http/ngx_http_xslt_module.html#xslt_last_modified)\ +[xslt_param](https://nginx.org/en/docs/http/ngx_http_xslt_module.html#xslt_param)\ +[xslt_string_param](http://nginx.org/en/docs/http/ngx_http_xslt_module.html#xslt_string_param)\ +[xslt_stylesheet](https://nginx.org/en/docs/http/ngx_http_xslt_module.html#xslt_stylesheet)\ +[xslt_types](https://nginx.org/en/docs/http/ngx_http_xslt_module.html#xslt_types)\ +[zone (ngx_http_upstream_module)](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#zone)\ +[zone (ngx_stream_upstream_module)](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#zone)\ +[zone_sync](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync)\ +[zone_sync_buffers](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_buffers)\ +[zone_sync_connect_retry_interval](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_connect_retry_interval)\ +[zone_sync_connect_timeout](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_connect_timeout)\ +[zone_sync_interval](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_interval)\ +[zone_sync_recv_buffer_size](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_recv_buffer_size)\ +[zone_sync_server](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_server)\ +[zone_sync_ssl](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl)\ +[zone_sync_ssl_certificate](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_certificate)\ +[zone_sync_ssl_certificate_key](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_certificate_key)\ +[zone_sync_ssl_ciphers](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_ciphers)\ +[zone_sync_ssl_conf_command](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_conf_command)\ +[zone_sync_ssl_crl](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_crl)\ +[zone_sync_ssl_name](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_name)\ +[zone_sync_ssl_password_file](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_password_file)\ +[zone_sync_ssl_protocols](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_protocols)\ +[zone_sync_ssl_server_name](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_server_name)\ +[zone_sync_ssl_trusted_certificate](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_trusted_certificate)\ +[zone_sync_ssl_verify](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_verify)\ +[zone_sync_ssl_verify_depth](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_ssl_verify_depth)\ +[zone_sync_timeout](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html#zone_sync_timeout) +
+ +
+Lua dynamic module directives + +[lua_load_resty_core](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_load_resty_core)\ +[lua_use_default_type](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_use_default_type)\ +[lua_malloc_trim](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_malloc_trim)\ +[lua_code_cache](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_code_cache)\ +[lua_thread_cache_max_entries](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_thread_cache_max_entries)\ +[lua_regex_cache_max_entries](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_regex_cache_max_entries)\ +[lua_regex_match_limit](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_regex_match_limit)\ +[lua_package_path](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_package_path)\ +[lua_package_cpath](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_package_cpath)\ +[init_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#init_by_lua)\ +[init_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#init_by_lua_block)\ +[init_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#init_by_lua_file)\ +[init_worker_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#init_worker_by_lua)\ +[init_worker_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#init_worker_by_lua_block)\ +[init_worker_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#init_worker_by_lua_file)\ +[exit_worker_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#exit_worker_by_lua_block)\ +[exit_worker_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#exit_worker_by_lua_file)\ +[set_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#set_by_lua)\ +[set_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#set_by_lua_block)\ +[set_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#set_by_lua_file)\ +[content_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#content_by_lua)\ +[content_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#content_by_lua_block)\ +[content_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#content_by_lua_file)\ +[server_rewrite_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#server_rewrite_by_lua_block)\ +[server_rewrite_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#server_rewrite_by_lua_file)\ +[rewrite_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#rewrite_by_lua)\ +[rewrite_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#rewrite_by_lua_block)\ +[rewrite_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#rewrite_by_lua_file)\ +[access_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#access_by_lua)\ +[access_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#access_by_lua_block)\ +[access_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#access_by_lua_file)\ +[header_filter_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#header_filter_by_lua)\ +[header_filter_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#header_filter_by_lua_block)\ +[header_filter_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#header_filter_by_lua_file)\ +[body_filter_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#body_filter_by_lua)\ +[body_filter_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#body_filter_by_lua_block)\ +[body_filter_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#body_filter_by_lua_file)\ +[log_by_lua](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#log_by_lua)\ +[log_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#log_by_lua_block)\ +[log_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#log_by_lua_file)\ +[balancer_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#balancer_by_lua_block)\ +[balancer_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#balancer_by_lua_file)\ +[lua_need_request_body](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_need_request_body)\ +[ssl_client_hello_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#ssl_client_hello_by_lua_block)\ +[ssl_client_hello_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#ssl_client_hello_by_lua_file)\ +[ssl_certificate_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#ssl_certificate_by_lua_block)\ +[ssl_certificate_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#ssl_certificate_by_lua_file)\ +[ssl_session_fetch_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#ssl_session_fetch_by_lua_block)\ +[ssl_session_fetch_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#ssl_session_fetch_by_lua_file)\ +[ssl_session_store_by_lua_block](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#ssl_session_store_by_lua_block)\ +[ssl_session_store_by_lua_file](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#ssl_session_store_by_lua_file)\ +[lua_shared_dict](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_shared_dict)\ +[lua_socket_connect_timeout](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_socket_connect_timeout)\ +[lua_socket_send_timeout](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_socket_send_timeout)\ +[lua_socket_send_lowat](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_socket_send_lowat)\ +[lua_socket_read_timeout](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_socket_read_timeout)\ +[lua_socket_buffer_size](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_socket_buffer_size)\ +[lua_socket_pool_size](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_socket_pool_size)\ +[lua_socket_keepalive_timeout](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_socket_keepalive_timeout)\ +[lua_socket_log_errors](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_socket_log_errors)\ +[lua_ssl_ciphers](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_ssl_ciphers)\ +[lua_ssl_crl](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_ssl_crl)\ +[lua_ssl_protocols](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_ssl_protocols)\ +[lua_ssl_trusted_certificate](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_ssl_trusted_certificate)\ +[lua_ssl_verify_depth](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_ssl_verify_depth)\ +[lua_ssl_conf_command](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_ssl_conf_command)\ +[lua_http10_buffering](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_http10_buffering)\ +[rewrite_by_lua_no_postpone](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#rewrite_by_lua_no_postpone)\ +[access_by_lua_no_postpone](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#access_by_lua_no_postpone)\ +[lua_transform_underscores_in_response_headers](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_transform_underscores_in_response_headers)\ +[lua_check_client_abort](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_check_client_abort)\ +[lua_max_pending_timers](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_max_pending_timers)\ +[lua_max_running_timers](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_max_running_timers)\ +[lua_sa_restart](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_sa_restart)\ +[lua_worker_thread_vm_pool_size](https://github.com/openresty/lua-nginx-module?tab=readme-ov-file#lua_worker_thread_vm_pool_size) +
+ + +
+GeoIP2 dynamic module directives + +[geoip2 (ngx_http_geo2_module)](https://github.com/leev/ngx_http_geoip2_module#user-content-download-maxmind-geolite2-database-optional)\ +[geoip2 (ngx_stream_geo2_module)](https://github.com/leev/ngx_http_geoip2_module#user-content-download-maxmind-geolite2-database-optional)\ +[geoip2_proxy (ngx_http_geo2_module)](https://github.com/leev/ngx_http_geoip2_module#user-content-download-maxmind-geolite2-database-optional)\ +[geoip2_proxy_recursive (ngx_http_geo2_module)](https://github.com/leev/ngx_http_geoip2_module#user-content-download-maxmind-geolite2-database-optional)\ +
diff --git a/content/nginxaas-azure/getting-started/prerequisites.md b/content/nginxaas-azure/getting-started/prerequisites.md new file mode 100644 index 000000000..7c582dc47 --- /dev/null +++ b/content/nginxaas-azure/getting-started/prerequisites.md @@ -0,0 +1,23 @@ +--- +title: "Prerequisites" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-880" +--- + +Before you deploy F5 NGINX as a Service for Azure (NGINXaaS) you need to meet the following prerequisites: + +- An Azure account with an active subscription (if you don’t have one, [create an account for free](https://azure.microsoft.com/free/?WT.mc_id=A261C142F)). + +- [Confirm that you have the appropriate access](https://docs.microsoft.com/en-us/azure/role-based-access-control/check-access) before starting the setup: + + - The simplest approach is to use Azure’s built-in [Owner](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#owner) role on either a specific resource group or the subscription. + + - It's possible to complete a limited setup with the built-in [Contributor](https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#contributor) role. + +For specific permissions check the [NGINXaaS for Azure Frequently Asked Questions]({{< relref "/nginxaas-azure/faq" >}}). + +## What's next + +[Create a Deployment]({{< relref "/nginxaas-azure/getting-started/create-deployment/" >}}) diff --git a/content/nginxaas-azure/getting-started/ssl-tls-certificates/_index.md b/content/nginxaas-azure/getting-started/ssl-tls-certificates/_index.md new file mode 100644 index 000000000..1064e0730 --- /dev/null +++ b/content/nginxaas-azure/getting-started/ssl-tls-certificates/_index.md @@ -0,0 +1,8 @@ +--- +title: "Add SSL-TLS certificates" +weight: 400 +url: /nginxaas/azure/getting-started/ssl-tls-certificates/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/getting-started/ssl-tls-certificates/overview.md b/content/nginxaas-azure/getting-started/ssl-tls-certificates/overview.md new file mode 100644 index 000000000..291e7c214 --- /dev/null +++ b/content/nginxaas-azure/getting-started/ssl-tls-certificates/overview.md @@ -0,0 +1,320 @@ +--- +title: "Overview" +weight: 50 +categories: ["tasks"] +toc: true +--- + +F5 NGINX as a Service for Azure (NGINXaaS) enables customers to secure traffic by adding SSL/TLS certificates to a deployment. NGINXaaS can fetch certificates directly from Azure Key Vault, rotate certificates, and provide observability on the status of your certificates. + +This document provides details about using SSL/TLS certificates with your F5 NGINX as a Service for Azure deployment. + +## Add SSL/TLS certificates + +Add a certificate from an Azure Key Vault to your NGINXaaS deployment using your preferred client tool: + +* [Add certificates using the Azure portal]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md">}}) +* [Add certificates using the Azure CLI]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-azure-cli.md">}}) +* [Add certificates using Terraform]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-terraform.md">}}) + +### Add SSL/TLS certificates bundled with NGINXaaS configuration + +You can also add your certificate as a file to your NGINX configuration filesystem; refer to [Upload an NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview.md">}}) to learn about the different options. Although this is a quick method for adding SSL/TLS certificates to your NGINXaaS deployment, we recommend adding certificates through Azure Key Vault (AKV) for enhanced security, certificate rotation, and monitoring. + +Once a certificate has been added, update your NGINX configuration to reference your SSL/TLS certificate and key file paths. + +```nginx +http { + server { + listen 443 ssl; + ssl_certificate /etc/nginx/certs/mycert.cert; + ssl_certificate_key /etc/nginx/certs/mycert.key; + # ... + } +} +``` + +## Certificate rotation + +NGINXaaS for Azure regularly polls the AKV to check if the certificate has been updated. If an updated certificate is found, it is automatically rotated on the deployment within 4 hours. Any change to the NGINX configuration will trigger all SSL/TLS certificates to be rotated immediately. + +For Azure client tools, such as the Azure CLI or Azure Resource Manager, the certificate is referenced from AKV using its Key Vault secret identifier. If the secret identifier specifies a version, NGINXaaS will not rotate the certificate. To enable certificate rotation, ensure the secret id does not contain a version, for example, `https://myvault.vault.azure.net/secrets/mysecret`. Certificates added using the Azure Portal will automatically be rotated. + +{{}}If any of your SSL/TLS certificates or your NGINX configuration has issues, the certificates will not be rotated.{{}} + +## Monitor certificates + +To view the status of your SSL/TLS certificates, [enable monitoring]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}) for your NGINXaaS deployment and navigate to the **Metrics** tab in the Azure portal. View the `nginxaas.certificates` metric under the `nginxaas statistics` metric namespace. The `nginxaas.certificates` metric allows you to filter by certificate name and the status of the certificate. The status dimension reports the health of your certificates through the following values: + + {{}} + + | Status | Description | + | ------------- | ------------- | + | `active` | The certificate was successfully fetched from AKV. | + | `unauthorized`| Azure returned a 401/403 error when fetching the certificate from AKV, which usually indicates an issue with the deployment's [Managed Identity]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}). | + | `not found` | Azure returned a 404 error when fetching the certificate from AKV. | + | `incompatible`| An error occurred while fetching or processing the certificate from AKV.

The possible reasons include:

  • Error while downloading certificate and key
  • Missing content type in certificate
  • Missing content in certificate
  • Unrecognized content type, certificate not in PEM or PKCS12 format
| + + {{
}} + + ![Interface screenshot showing the Azure metric nginxaas.certificates](/nginxaas-azure/azure-metrics-nginxaas.certificates.png) + +## Common certificate errors + +The following section describes common errors you might encounter while adding SSL/TLS certificates to your NGINXaaS deployment and how to resolve them. + +#### Error code: `ForbiddenByRbac` + +**Description:** The [Managed Identity]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) associated with the NGINXaaS deployment does not have permissions to fetch certificates from key vault. This error is returned when the key vault's permission model is set to [Azure role-based access control](https://learn.microsoft.com/en-us/azure/role-based-access-control/overview?WT.mc_id=Portal-Microsoft_Azure_KeyVault). + +**Resolution:** Assign the [Key Vault Secrets User](https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#key-vault-secrets-user) role to the managed identity associated with your NGINXaaS deployment. + +
+Create a role assignment - Azure CLI + +1. Get the principal ID of the user or system assigned managed identity. + + - **User assigned managed identity** + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `MI_NAME`: the name of the managed identity + - `MI_RESOURCE_GROUP`: the name of the resource group the managed identity is in + ```bash + mi_principal_id=$(az identity show --name $MI_NAME \ + --resource-group $MI_RESOURCE_GROUP \ + --query principalId --output tsv) + ``` + + - **System assigned managed identity** + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `DEP_NAME`: the name of the NGINXaaS deployment + - `DEP_RESOURCE_GROUP`: the name of the resource group the NGINXaaS deployment is in + ```bash + mi_principal_id=$(az nginx deployment show --name $DEP_NAME \ + --resource-group $DEP_RESOURCE_GROUP \ + --query identity.principalId --output tsv) + ``` +1. Get the resource ID of the key vault. + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `KV_NAME`: the name of the key vault + - `KV_RESOURCE_GROUP`: the name of the resource group the key vault is in + ```bash + key_vault_id=$(az keyvault show --name $KV_NAME \ + --resource-group $KV_RESOURCE_GROUP \ + --query id --output tsv) + ``` +1. Create the role assignment. + ```bash + az role assignment create --assignee $mi_principal_id \ + --role "Key Vault Secrets User" \ + --scope $key_vault_id + ``` +
+ +#### Error code: `AccessDenied` + +**Description:** The [Managed Identity]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) associated with the NGINXaaS deployment has not been assigned to an access policy on the key vault. This error is returned when the key vault's permission model is set to [Vault access policy](https://learn.microsoft.com/en-us/azure/key-vault/general/assign-access-policy?WT.mc_id=Portal-Microsoft_Azure_KeyVault&tabs=azure-portal). + +**Resolution:** Assign an access policy to the managed identity associated with your NGINXaaS deployment with *Get secrets* permissions or higher. If you are using the Azure portal, assign an additional access policy to your user with *List certificates* permissions or higher. + +
+Create an access policy - Azure CLI + +1. Get the principal ID of the user or system assigned managed identity. + + - **User assigned managed identity** + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `MI_NAME`: the name of the managed identity + - `MI_RESOURCE_GROUP`: the name of the resource group the managed identity is in + ```bash + mi_principal_id=$(az identity show --name $MI_NAME \ + --resource-group $MI_RESOURCE_GROUP \ + --query principalId --output tsv) + ``` + + - **System assigned managed identity** + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `DEP_NAME`: the name of the NGINXaaS deployment + - `DEP_RESOURCE_GROUP`: the name of the resource group the NGINXaaS deployment is in + ```bash + mi_principal_id=$(az nginx deployment show --name $DEP_NAME \ + --resource-group $DEP_RESOURCE_GROUP \ + --query identity.principalId --output tsv) + ``` + +1. Create the access policy. + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `KV_NAME`: the name of the key vault + - `KV_RESOURCE_GROUP`: the name of the resource group the key vault is in + ```bash + az keyvault set-policy --name $KV_NAME \ + --resource-group $KV_RESOURCE_GROUP \ + --object-id $mi_principal_id \ + --secret-permissions get + ``` +
+ +#### Error code: `ForbiddenByFirewall` + +**Description:** The key vault's firewall is enabled and NGINXaaS is not authorized to fetch certificates. + +**Resolution:** [Configure Network Security Perimeter]({{< relref "/nginxaas-azure/quickstart/security-controls/certificates.md#configure-network-security-perimeter-nsp" >}}) to allow the subscription of the NGINXaaS deployment to access the key vault. + +
+Create a network security perimeter - Azure CLI + +1. Create a network security perimeter. + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `NSP_NAME`: the name of the network security perimeter + - `NSP_RESOURCE_GROUP`: the name of the resource group the network security perimeter will be in + ```bash + az network perimeter create --name $NSP_NAME --resource-group $NSP_RESOURCE_GROUP + ``` +1. Create a profile for the network security perimeter. + + Please ensure the following environment variable is set before copying the below Azure CLI command. + - `PROFILE_NAME`: the name of the network security perimeter profile + ```bash + az network perimeter profile create --name $PROFILE_NAME \ + --resource-group $NSP_RESOURCE_GROUP \ + --perimeter-name $NSP_NAME + ``` +1. Get the resource ID of the key vault. + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `KV_NAME`: the name of the key vault + - `KV_RESOURCE_GROUP`: the name of the resource group the key vault is in + ```bash + key_vault_id=$(az keyvault show --name $KV_NAME \ + --resource-group $KV_RESOURCE_GROUP \ + --query id --output tsv) + ``` +1. Get the resource ID of the network security profile. + ```bash + nsp_profile_id=$(az network perimeter profile show --name $PROFILE_NAME \ + --resource-group $NSP_RESOURCE_GROUP \ + --perimeter-name $NSP_NAME --query id --output tsv) + ``` +1. Associate the key vault with the network security perimeter + ```bash + az network perimeter association create --name key-vault-association \ + --perimeter-name $NSP_NAME \ + --resource-group $NSP_RESOURCE_GROUP \ + --private-link-resource "{id:$key_vault_id}" \ + --profile "{id:$nsp_profile_id}" + ``` +1. Add an inbound access rule to allow the NGINXaaS deployment's subscription. + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `RULE_NAME`: the name of the access rule + - `DEP_SUBSCRIPTION_ID`: the subscription ID of the NGINXaaS deployment + ```bash + az network perimeter profile access-rule create --name $RULE_NAME \ + --profile-name $PROFILE_NAME \ + --perimeter-name $NSP_NAME \ + --resource-group $NSP_RESOURCE_GROUP \ + --subscriptions [0].id="/subscriptions/$DEP_SUBSCRIPTION_ID" + ``` +
+ +#### Error code: `AnotherOperationInProgress` + +**Description:** Another operation on this, or a dependent resource, is in progress. + +**Resolution:** Retry the operation after the current operation reaches a terminal state. + +#### Error code: `SecretNotFound` + +**Description:** The certificate's key vault secret ID was not found in the key vault. + +**Resolution:** Ensure the specified key vault secret ID exists and has the correct format, for example, `https://myvault.vault.azure.net/secrets/abcd/v1`. + +#### Error code: `CertificateInUse` + +**Description:** The certificate being deleted or modified is referenced in the NGINX configuration. The attempted modification would prevent the NGINX config from being applied. + +**Resolution:** Remove references to the certificate in the NGINX config, or add a new certificate resource to the NGINXaaS deployment with the modified certificate and key paths. + +#### Error code: `ForbiddenByPolicy` + +**Description:** The [Managed Identity]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) associated with the NGINXaaS deployment does not have permissions to fetch certificates from key vault. This error is returned when the key vault's permission model is set to [Vault access policy](https://learn.microsoft.com/en-us/azure/key-vault/general/assign-access-policy?WT.mc_id=Portal-Microsoft_Azure_KeyVault&tabs=azure-portal). + +**Resolution:** Assign an access policy to the managed identity associated with your NGINXaaS deployment with *Get secrets* permissions or higher. If you are using the Azure portal, assign an additional access policy to your user with *List certificates* permissions or higher. + +
+Create an access policy - Azure CLI + +1. Get the principal ID of the user or system assigned managed identity. + + - **User assigned managed identity** + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `MI_NAME`: the name of the managed identity + - `MI_RESOURCE_GROUP`: the name of the resource group the managed identity is in + ```bash + mi_principal_id=$(az identity show --name $MI_NAME \ + --resource-group $MI_RESOURCE_GROUP \ + --query principalId --output tsv) + ``` + + - **System assigned managed identity** + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `DEP_NAME`: the name of the NGINXaaS deployment + - `DEP_RESOURCE_GROUP`: the name of the resource group the NGINXaaS deployment is in + ```bash + mi_principal_id=$(az nginx deployment show --name $DEP_NAME \ + --resource-group $DEP_RESOURCE_GROUP \ + --query identity.principalId --output tsv) + ``` + +1. Create the access policy. + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `KV_NAME`: the name of the key vault + - `KV_RESOURCE_GROUP`: the name of the resource group the key vault is in + ```bash + az keyvault set-policy --name $KV_NAME \ + --resource-group $KV_RESOURCE_GROUP \ + --object-id $mi_principal_id \ + --secret-permissions get + ``` +
+ +#### Error code: `DuplicateFilePathError` + +**Description:** A file already exists on the instance's filesystem with the certificate or key's file path. + +**Resolution:** Rename the certificate or key path, so there are no collisions with existing certificate and NGINX config file paths. + +#### Error code: `SecretDisabled` + +**Description:** The certificate is set to disabled in the key vault. + +**Resolution:** Enable the certificate in the key vault. + +
+Enable a certificate in key vault - Azure CLI + +1. Get the resource ID of the certificate. + + Please ensure the following environment variables are set before copying the below Azure CLI command. + - `CERT_NAME`: the name of the certificate + - `KV_NAME`: the name of the key vault + ```bash + certificate_id=$(az keyvault certificate show --name $CERT_NAME \ + --vault-name $KV_NAME \ + --query id --output tsv) + ``` + +1. Enable the certificate. + ```bash + az keyvault certificate set-attributes --enabled true --id $certificate_id + ``` +
diff --git a/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-azure-cli.md b/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-azure-cli.md new file mode 100644 index 000000000..ca75ce437 --- /dev/null +++ b/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-azure-cli.md @@ -0,0 +1,104 @@ +--- +title: "Add certificates using the Azure CLI" +weight: 200 +categories: ["tasks"] +toc: true +--- + +You can use Azure Key Vault (AKV) to store SSL/TLS certificates and keys to use in your F5 NGINX as a Service for Azure (NGINXaaS) configuration. + +### Prerequisites + +{{< include "/nginxaas-azure/ssl-tls-prerequisites.md" >}} + +- Install [Azure CLI with NGINXaaS extension]({{< relref "/nginxaas-azure/client-tools/cli.md" >}}) + +## Create a certificate + +Create a certificate under a deployment. This references an existing certificate in an Azure Key Vault and makes it available to NGINX configuration + +To create a certificate, use the `az nginx deployment certificate create` command: + +```bash +az nginx deployment certificate create --certificate-name + --deployment-name + --resource-group + [--certificate-path] + [--key-path] + [--key-vault-secret-id] + [--location] + [--no-wait {0, 1, f, false, n, no, t, true, y, yes}] +``` + +### Example + +- Create a certificate with a certificate path, key path, and key vault secret ID: + + ```bash + az nginx deployment certificate create --certificate-name myCertificate \ + --deployment-name myDeployment --resource-group myResourceGroup \ + --certificate-path /etc/nginx/test.cert --key-path /etc/nginx/test.key \ + --key-vault-secret-id keyVaultSecretId + ``` + +See [Azure CLI Certificate Create Documentation](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment/certificate#az-nginx-deployment-certificate-create) for more details on the available parameters. + +## Update a certificate + +To update a certificate, use the `az nginx deployment certificate update` command: + +```bash +az nginx deployment certificate update [--add] + [--certificate-name] + [--certificate-path] + [--deployment-name] + [--force-string {0, 1, f, false, n, no, t, true, y, yes}] + [--ids] + [--key-path] + [--key-vault-secret-id] + [--location] + [--no-wait {0, 1, f, false, n, no, t, true, y, yes}] + [--remove] + [--resource-group] + [--set] + [--subscription] +``` + +### Example + +- Update the certificate virtual path, key virtual path and certificate: + + ```bash + az nginx deployment certificate update --certificate-name myCertificate \ + --deployment-name myDeployment --resource-group myResourceGroup \ + --certificate-path /etc/nginx/testupdated.cert \ + --key-path /etc/nginx/testupdated.key \ + --key-vault-secret-id newKeyVaultSecretId + ``` + +See [Azure CLI Certificate Create Documentation](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment/certificate#az-nginx-deployment-certificate-update) for more details on the available parameters. + +## Delete a certificate + +To delete a certificate, use the `az nginx deployment certificate delete` command: + +```bash +az nginx deployment certificate delete [--certificate-name] + [--deployment-name] + [--ids] + [--no-wait {0, 1, f, false, n, no, t, true, y, yes}] + [--resource-group] + [--subscription] + [--yes] +``` + +### Example + +- Delete a certificate: + + ```bash + az nginx deployment certificate delete --certificate-name myCertificate \ + --deployment-name myDeployment --resource-group myResourceGroup + ``` + +See [Azure CLI Certificate Delete Documentation](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment/certificate#az-nginx-deployment-certificate-delete) for more details on the available parameters. diff --git a/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md b/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md new file mode 100644 index 000000000..bdfdd1a8e --- /dev/null +++ b/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md @@ -0,0 +1,95 @@ +--- +title: "Add certificates using the Azure portal" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-875" +--- + +## Overview + +You can manage SSL/TSL certificates for F5 NGINX as a Service for Azure (NGINXaaS) using the Azure portal. + +## Prerequisites + +{{< include "/nginxaas-azure/ssl-tls-prerequisites.md" >}} + +### Adding an SSL/TLS certificate + +Before you begin, refer Azure documentation to [Import a certificate to your Key Vault](https://learn.microsoft.com/en-us/azure/key-vault/certificates/tutorial-import-certificate?tabs=azure-portal#import-a-certificate-to-your-key-vault). + +1. Go to your NGINXaaS for Azure deployment. + +1. Select **NGINX certificates** in the left menu. + +1. Select {{< fa "plus">}}**Add certificate**. + +1. Provide the required information: + + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Name | A unique name for the certificate. | + | Certificate path | This path can match one or more `ssl_certificate` directive file arguments in your NGINX configuration.
The certificate path must be unique within the same deployment. | + | Key path | This path can match one or more `ssl_certificate_key` directive file arguments in your NGINX configuration.
The key path must be unique within the same deployment.
The key path and certificate path can be the same within the certificate. | + {{
}} + + - The **Select certificate** button will take you to a new screen where you will need to provide the following information: + + {{}} + | Field | Description | + |----------------------- | ---------------------------- | + | Key vault | Select from the available key vaults. | + | Certificate | Select the certificate you want to add from the previously selected key vault. | + {{}} + + If you need to create a new key vault or certificate, you can do so by selecting **Create new key vault** or **Create new** under the **Key Vault** and **Certificate** fields, respectively. + + {{}}If specifying an absolute file path as the `Certificate path` or `Key path`, see the [NGINX Filesystem Restrictions table]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/#nginx-filesystem-restrictions" >}}) for the allowed directories the file can be written to.{{}} + + {{}}A certificate added to an NGINXaaS for Azure deployment using the Azure Portal refers to an unversioned Azure Key Vault (AKV) secret identifier. To add a certificate with a versioned AKV secret identifier, follow the documented steps with alternative [Client tools]({{< relref "/nginxaas-azure/client-tools/_index.md" >}}) for NGINXaaS for Azure.{{}} + +1. Select **Add certificate**. + +1. Repeat the same steps to add as many certificates as needed. + +1. Now you can [provide an NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md" >}}) that references the certificate you just added by the **path** value. + +### View certificate details + +1. Go to your NGINXaaS for Azure deployment and select **NGINX certificates** in the left menu. + +1. Select the name of the certificate from the list. + +1. View the certificate details, including the certificate path, key path, thumbprint, and the certificate's status. + This view will also show in a red box any errors that occurred during the certificate fetch process. + +### Edit an SSL/TLS certificate + +1. Go to your NGINXaaS for Azure deployment and select **NGINX certificates** in the left menu. + +1. Select the checkbox next to the certificate you want to edit. + +1. Select {{< fa "pencil">}} **Edit**. + +1. Update the Name, Certificate path, Key path fields as needed. + +1. Use the **Select certificate** option to update the Key vault, and Certificate fields as needed. + +1. Select **Update**. + +### Delete an SSL/TLS certificate + +1. Go to your NGINXaaS for Azure deployment and select **NGINX certificates** in the left menu. + +1. Select the checkbox next to the certificate you want to delete. + +1. Select {{< fa "trash">}}**Delete**. + +1. Confirm the delete action. + +{{}}Deleting a TLS/SSL certificate currently in-use by the NGINXaaS for Azure deployment will cause an error.{{}} + +## What's next + +[Upload an NGINX Configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md" >}}) diff --git a/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-terraform.md b/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-terraform.md new file mode 100644 index 000000000..3a4b61329 --- /dev/null +++ b/content/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-terraform.md @@ -0,0 +1,40 @@ +--- +title: "Add certificates using Terraform" +weight: 300 +categories: ["tasks"] +toc: true +--- + +## Overview + +You can manage SSL/TSL certificates for F5 NGINX as a Service for Azure (NGINXaaS) using Terraform. + +## Prerequisites + +{{< include "/nginxaas-azure/terraform-prerequisites.md" >}} + +## Upload and manage a certificate + +You can find examples of Terraform configurations in the [NGINXaaS for Azure Snippets GitHub repository](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/certificates) + +To create a deployment, add a certificate, and use it in a configuration, run the following commands: + + ```bash + terraform init + terraform plan + terraform apply --auto-approve + ``` + +## Delete a deployment + +Once the deployment is no longer needed, run the following to clean up the deployment and related resources: + + ```bash + terraform destroy --auto-approve + ``` + +## Additional resources + +- [Terraform NGINX certificate documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/nginx_certificate) + +{{< include "/nginxaas-azure/terraform-resources.md" >}} \ No newline at end of file diff --git a/content/nginxaas-azure/known-issues.md b/content/nginxaas-azure/known-issues.md new file mode 100644 index 000000000..d84808867 --- /dev/null +++ b/content/nginxaas-azure/known-issues.md @@ -0,0 +1,193 @@ +--- +title: "Known issues" +weight: 1000 +toc: true +docs: "DOCS-871" +--- + +List of known issues in the latest release of F5 NGINX as a Service for Azure (NGINXaaS). + +### {{% icon-bug %}} Terraform fails to apply due to validation errors, but creates "Failed" resources in Azure (ID-4424) + +Some validation errors are caught later in the creation process, and can leave behind "Failed" resources in Azure. An example initial failure might look like: + +```shell +$ terraform apply + +│ Error: creating Nginx Deployment (Subscription: "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" +│ Resource Group Name: "XXXXXXXX" +│ Nginx Deployment Name: "XXXXXXXX"): polling after DeploymentsCreateOrUpdate: polling failed: the Azure API returned the following +│ error: +│ +│ Status: "Failed" +│ Code: "NginxSaaSError" +│ Message: "{\"Content\":\"{\\\"error\\\":{\\\"code\\\":\\\"CapacityOutOfRange\\\",\\\"message\\\":\\\"The deployment's capacity must +│ be between 10 and 500 inclusive for marketplace plan standard. For more information about setting capacity see +│ https://docs.nginx.com/nginxaas/azure/quickstart/scaling/.\\\"}}\\n\",\"StatusCode\":400}" +``` + +The error message describes how to fix the vailidation problem. In the Azure portal, you'll be able to see your NGINXaaS, but it will have a "Failed" status. Future **terraform apply** will fail with **Error: A resource with the ID "..." already exists**. + + +**Workaround**: manually delete the "Failed" resource in Azure portal before re-running **terraform apply**. **terraform import** will not work. + +### {{% icon-bug %}} Changing IP addresses in `listen` directives fails with "cannot reload nginx: timed out waiting for config to reload" (ID-4366) + +NGINXaaS uses NGINX's ["change configuration" feature](https://nginx.org/en/docs/control.html#reconfiguration) to update the configuration gracefully without dropping traffic. This starts new workers on the new configuration before shutting down the old workers on the old config. Some kinds of `listen` changes can block new workers from starting up. If you're changing from listening on all IPs to one (for example `listen 1234` -> `listen 127.0.0.1:1234` or vice versa), the config will fail to apply because the old workers and the new workers have an IP conflict. + +**Workaround**: Change the port as well as the IP address to avoid the conflict, and then make a second config change back to the desired port. + +### {{% icon-bug %}} Deploying NGINXaaS and Diagnostic Settings for NGINXaaS using a ARM Bicep or JSON template shows an error (ID-4326) + +While using a single template deployment to deploy both, a NGINXaaS instance and a diagnostic setting for the NGINXaaS instance, +you will see a validation error similar to: + +``` +{"code": "InvalidTemplateDeployment", "message": "The template deployment 'example' is not valid according to the validation procedure. The tracking id is '650afc1e-50d6-476c-bf94-9fc35ffeedd6'. See inner errors for details."} + +Inner Errors: +{"code": "OpenAPISpecValidationFailedForTemplateDeploymentResources", "message": "One or more resources in template deployment preflight validation request failed during OpenApi spec (swagger) validation. Please check error details for the resource identifiers."} + +Inner Errors: +{"code": "HttpPayloadAPISpecValidationFailed", "target": "/subscriptions/ee920d60-90f3-4a92-b5e7-bb284c3a6ce2/resourceGroups/testenv-1b791f58-workload/providers/NGINX.NGINXPLUS/nginxDeployments/myDeployment/providers/Microsoft.Insights/diagnosticSettings/myLoggingSetting", "message": "Failed during request payload validation against the API specification"} + +``` + +**Workaround**: Deploy your NGINXaaS instance and your diagnostic setting in separate templates. + +### {{% icon-bug %}} Not all NGINX Plus directives and use-cases are supported in NGINXaaS (ID-4331) + +NGINXaaS currently does not support all NGINX Plus directives and use-cases. We are continually adding new NGINX Plus capabilities into NGINXaaS to close the gap in functionality. You can follow the updates to the supported use-cases by visiting the [Changelog]({{< relref "./changelog.md" >}}). For a comprehensive list of currently allowed directives, please see the [Configuration Directives List]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#configuration-directives-list" >}}). + +### {{% icon-bug %}} Terraform errors using `package_data` (ID-2752) + +Specifying a configuration using a `tar.gz` file and the `package_data` directive fails. + +```text +│ Error: Insufficient config_file blocks +│ +│ on main.tf line 105, in resource "azurerm_nginx_configuration" "example": +│ 105: resource "azurerm_nginx_configuration" "example" { +│ +│ At least 1 "config_file" blocks are required. +``` + +**Workaround:** Extract the files from your `tar.gz` and use the `config_file` directive instead of `package_data` + +### {{% icon-bug %}} Deployment responsiveness takes approximately 5-10 seconds. (ID-872) + +When creating a new deployment or exposing a new port for traffic, there might be a lag time of 5-10 seconds, during which the Azure Load Balancer does not recognize the new ports, thus preventing making new connections to the NGINX deployment. + +**Workaround:** Wait 10 seconds to make requests or make multiple requests to the instance with low connect timeout times after creating a new deployment or exposing a new port to the deployment for the first 10 seconds after the deployment reaches the Completed state. + +### {{% icon-bug %}} NGINXaaS for Azure charges do not render correctly in the Azure Portal cost center. (ID-1660) + +NGINXaaS for Azure resources appear with a random suffix, and clicking the link does not lead to the NGINXaaS for Azure resource overview page. The charge details show "Unassigned" for all fields, but the charge amount is accurate. + +### {{% icon-bug %}} Configuration update will not succeed with a failed certificate. (ID-1545) + +If a configuration update request uses a certificate that is in failed `provisioningState`, the configuration update is rejected. + +**Workaround:** Update the referenced certificate before updating the configuration. Make sure the certificate provisioning is successful and retry the configuration update. + +### {{% icon-bug %}} Known networking limitations (ID-625) + +- NGINXaaS deployments cannot access [Private Endpoints](https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview) behind network security groups for private links. Attempts to do so will fail silently. +- NGINXaaS deployments cannot access [Private Endpoints](https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview) in a globally peered VNET. Attempts to do so will fail silently. +- The resource group which contains the public IP resource attached to NGINXaaS deployment cannot be moved across subscriptions. Attempts to do so will result in a validation error. +- Creating an NGINXaaS deployment in a dual-stack subnet is not supported. Attempts to do so will result in a validation error. +- NGINXaaS deployments cannot be created with an IPv6 Public IP address. Attempts to do so will result in a validation error. +- [Network security group](https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview) (NSG) flow logs will not be available for IP traffic flowing through an NGINXaaS deployment attached to a customer delegated subnet. Flow logs for other resources on the same subnet will be available as normal. + +### {{% icon-bug %}} Deployment locked when updating mutliple certificates at once. (ID-767) + +Attaching multiple certificates to a deployment quickly will result in a deployment conflict and error with a "409" status code. Certificates are a sub-resource of the deployment, and a user cannot attach multiple certificates to a deployment simultaneously. This issue is more likely to occur when attempting to configure multiple certificates using client tools such as Terraform and ARM templates. + +**Workaround:** If you want to add multiple certificates to a deployment, configure resource dependencies between the certificate resources, which will cause them to be added to the deployment one at a time. + +**Terraform:** + +Use [depends_on](https://developer.hashicorp.com/terraform/language/meta-arguments/depends_on) to add a dependency between certificate resources: + +{{< highlight hcl "linenos=false,hl_lines=16" >}} +resource "azurerm_nginx_certificate" "cert1" { + name = "examplecert" + nginx_deployment_id = azurerm_nginx_deployment.test.id + key_virtual_path = "/src/cert/soservermekey.key" + certificate_virtual_path = "/src/cert/server.cert" + key_vault_secret_id = azurerm_key_vault_certificate.test.secret_id +} + +resource "azurerm_nginx_certificate" "cert2" { + name = "examplecert" + nginx_deployment_id = azurerm_nginx_deployment.test.id + key_virtual_path = "/src/cert/soservermekey.key" + certificate_virtual_path = "/src/cert/server.cert" + key_vault_secret_id = azurerm_key_vault_certificate.test.secret_id + + depends_on = [azurerm_nginx_certificate.cert1] +} +{{< / highlight >}} + +**ARM Template** + +Use [dependsOn](https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/resource-dependency) to add a dependency between certificate resources: + +{{< highlight json "linenos=false,hl_lines=21" >}} +{ + "type": "NGINX.NGINXPLUS/nginxDeployments/certificates", + "apiVersion": "2021-05-01-preview", + "name": "[concat(parameters('nginxDeploymentName'), '/', 'cert1')]", + "properties": { + "certificateVirtualPath": "[parameters('certificateVirtualPath')]", + "keyVirtualPath": "[parameters('keyVirtualPath')]", + "keyVaultSecretId": "[parameters('keyVaultSecretId')]" + } +} + +{ + "type": "NGINX.NGINXPLUS/nginxDeployments/certificates", + "apiVersion": "2021-05-01-preview", + "name": "[concat(parameters('nginxDeploymentName'), '/', 'cert2')]", + "properties": { + "certificateVirtualPath": "[parameters('certificateVirtualPath')]", + "keyVirtualPath": "[parameters('keyVirtualPath')]", + "keyVaultSecretId": "[parameters('keyVaultSecretId')]" + } + "dependsOn": ["cert1"] +} +{{< / highlight >}} + +**Bicep Template** + +Use [dependsOn](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/resource-dependencies) to add a dependency between certificate resources: + +{{< highlight bicep "linenos=false,hl_lines=17" >}} +resource cert1 'NGINX.NGINXPLUS/nginxDeployments/certificates@2021-05-01-preview' = { + name: '${nginxDeploymentName}/cert1' + properties: { + certificateVirtualPath: certificateVirtualPath + keyVirtualPath: keyVirtualPath + keyVaultSecretId: keyVaultSecretId + } +} + +resource cert2 'NGINX.NGINXPLUS/nginxDeployments/certificates@2021-05-01-preview' = { + name: '${nginxDeploymentName}/cert2' + properties: { + certificateVirtualPath: certificateVirtualPath + keyVirtualPath: keyVirtualPath + keyVaultSecretId: keyVaultSecretId + } + dependsOn: [cert1] +} +{{< / highlight >}} + +### {{% icon-bug %}} Terraform errors around capacity for Basic plan deployments (ID-4880) + +Basic plans have no capacity, but older versions of [`azurerm`](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs) do not handle that well. You may see errors like: + +- `azurerm_nginx_deployment` falsely detecting capacity changes from 0 to 20 +- `UnsupportedOnBasicPlan: The Basic plan does not support scaling.` errors when running `terraform apply` + +**Solution** Upgrade `azurerm` to version v3.116.0 or higher. diff --git a/content/nginxaas-azure/monitoring/_index.md b/content/nginxaas-azure/monitoring/_index.md new file mode 100644 index 000000000..62c0bb746 --- /dev/null +++ b/content/nginxaas-azure/monitoring/_index.md @@ -0,0 +1,8 @@ +--- +title: Logging and monitoring +weight: 300 +url: /nginxaas/azure/monitoring/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/monitoring/configure-alerts.md b/content/nginxaas-azure/monitoring/configure-alerts.md new file mode 100644 index 000000000..a4266da23 --- /dev/null +++ b/content/nginxaas-azure/monitoring/configure-alerts.md @@ -0,0 +1,61 @@ +--- +title: "Configure alerts" +weight: 300 +categories: ["tasks"] +toc: true +draft: false +docs: "DOCS-985" +--- + +## Overview + +{{}}F5 NGINX as a Service for Azure (NGINXaaS) publishes custom metrics to Azure Monitor. To learn more about how to create and manage metrics-based alert rules, refer to the [Alerts section in Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/alerts-create-new-alert-rule?tabs=metric) documentation from Microsoft. {{}} + +This guide explains how to create and configure metrics-based alerts for your NGINXaaS for Azure deployment using Azure Monitor. + + +## Prerequisites + +- Setup is complete for [NGINXaaS for Azure deployment]({{< relref "/nginxaas-azure/getting-started/create-deployment/" >}}). + +- To complete this setup, you must be an owner or user access administrator for the NGINX deployment resource. + +- To enable metrics, see [Enable Monitoring]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}). + +{{}} See [Azure monitor overview](https://docs.microsoft.com/en-us/azure/azure-monitor/overview) documentation to familiarize with Azure Monitor. {{}} + +## Create metrics-based alerts for proactive monitoring. + +1. Go to your NGINXaaS for Azure deployment. + +2. Select **Alerts** in the left menu. + +3. In the **Create** menu, select **Alert rule**. + +4. Select the **Scope** tab, and choose NGINX deployment as the scope of the alert. + +{{}} The scope is auto-selected as NGINX deployment. {{}} + +5. In the **Conditions** tab, select a **Signal name**, for example, "nginx.http.request.count". + + ![Screenshot of the Conditions tab showing how to select a Signal name from the list](/nginxaas-azure/alert-select-signal.png) + +6. Define the **alert logic** such as: + + - Set the threshold and average as per your requirements. + - Set the frequency to evaluate alerts as per your requirements. + + ![Screenshot of the alert logic page showing how to set the threshold and frequency](/nginxaas-azure/alert-logic.png) + +7. Define the **actions**: + + - Create an **action group** for future reference. See the [Configure basic action group settings](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/action-groups) section. + - Define the **notification settings**: whom to notify when the alert is triggered. See the [Configure notifications](https://learn.microsoft.com/en-us/azure/azure-monitor/alerts/action-groups) section. + - (Optional) Define an action to be performed when the alert is triggered, such as a runbook or azure function. + +8. Fill out the details of the alert: + + - Specify the **severity** of the alert, and the name of the rule. + - In the **advanced options** tab, you can turn on "Enable alert upon creation" and "Automatically resolve alerts". + +{{}} [Standard Azure alert charges will apply](https://azure.microsoft.com/en-us/pricing/details/monitor/).{{}} \ No newline at end of file diff --git a/content/nginxaas-azure/monitoring/enable-logging/_index.md b/content/nginxaas-azure/monitoring/enable-logging/_index.md new file mode 100644 index 000000000..958a7c611 --- /dev/null +++ b/content/nginxaas-azure/monitoring/enable-logging/_index.md @@ -0,0 +1,8 @@ +--- +title: Enable NGINX logs +weight: 300 +url: /nginxaas/azure/monitoring/enable-logging/ +menu: + docs: + parent: NGINXaaS for Azure +--- diff --git a/content/nginxaas-azure/monitoring/enable-logging/logging-using-cli.md b/content/nginxaas-azure/monitoring/enable-logging/logging-using-cli.md new file mode 100644 index 000000000..8a8f3a96b --- /dev/null +++ b/content/nginxaas-azure/monitoring/enable-logging/logging-using-cli.md @@ -0,0 +1,70 @@ +--- +title: "Enable NGINX logs using CLI" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-1369" +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) supports integrating Azure Diagnostic Settings to collect NGINX error and access logs. + +{{}} +Enabling logs using the **NGINX Logs** blade on your NGINXaaS deployment is now deprecated. This feature will be removed in an upcoming update. If you have issues accessing your NGINX logs using the deprecated method, please follow the steps in this guide to access your NGINX logs. +{{}} + +## Configuring NGINX logs collection using diagnostic settings + +### Prerequisites + +- A valid NGINX configuration with log directives enabled. NGINX logs can be configured using [error_log](#setting-up-error-logs) and [access_log](#setting-up-access-logs) directives. + +- A system-assigned managed identity. +{{}}The system-assigned managed identity does not need any role assignments to enable the logging functionality described in this section. You will need to make sure that the managed identity has the appropriate role assignments to access other resources that it is attached to (for example, certificates stored in Azure Key Vault). +{{}} + +- User must be an owner or user access administrator for the NGINX deployment resource. + + ### Adding diagnostic settings + +Diagnostic settings for the NGINXaaS deployment resource can be managed using the Azure monitor diagnostic settings [commands](https://learn.microsoft.com/en-us/cli/azure/monitor/diagnostic-settings?view=azure-cli-latest). + +To add diagnostic settings to export NGINX logs to a storage account for an NGINXaaS deployment, the following command can be used: +```shell + az monitor diagnostic-settings create --resource --logs "[{category:NginxLogs,enabled:true,retention-policy:{enabled:false,days:0}}]" --name --storage-account +``` + +{{}}Due to limitations imposed by Azure, if the destination chosen is an Azure Storage account, the resource has to be in the same region as the NGINXaaS deployment resource. +{{}} + +To use a logs analytics workspace as the export destination, use the following command: +```shell + az monitor diagnostic-settings create --resource --logs "[{category:NginxLogs,enabled:true,retention-policy:{enabled:false,days:0}}]" --name --workspace + +``` + +To view the supported log categories for an NGINXaaS resource, use the following command: +```shell +az monitor diagnostic-settings list --resource +``` + +### Analyzing NGINX logs in Azure Storage + +{{< include "/nginxaas-azure/logging-analysis-azure-storage.md" >}} + +### Analyzing NGINX logs in Azure Log Analytics workspaces + +{{< include "/nginxaas-azure/logging-analysis-logs-analytics.md" >}} + +## Setting up error logs + +{{< include "/nginxaas-azure/logging-config-error-logs.md" >}} + +## Setting up access logs + +{{< include "/nginxaas-azure/logging-config-access-logs.md" >}} + +## Limitations + +{{< include "/nginxaas-azure/logging-limitations.md" >}} diff --git a/content/nginxaas-azure/monitoring/enable-logging/logging-using-portal.md b/content/nginxaas-azure/monitoring/enable-logging/logging-using-portal.md new file mode 100644 index 000000000..4887de353 --- /dev/null +++ b/content/nginxaas-azure/monitoring/enable-logging/logging-using-portal.md @@ -0,0 +1,84 @@ +--- +title: "Enable NGINX logs using Azure Portal" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-1369" +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) supports integrating Azure Diagnostic Settings to collect NGINX error and access logs. + +{{}} +Enabling logs using the **NGINX Logs** blade on your NGINXaaS deployment is now deprecated. This feature will be removed in an upcoming update. If you have issues accessing your NGINX logs using the deprecated method, please follow the steps in this guide to access your NGINX logs. +{{}} + +## Configuring NGINX logs collection using diagnostic settings + +### Prerequisites + +- A valid NGINX configuration with log directives enabled. NGINX logs can be configured using [error_log](#setting-up-error-logs) and [access_log](#setting-up-access-logs) directives. + +- A system-assigned managed identity. + +{{}}The system-assigned managed identity does not need any role assignments to enable the logging functionality described in this section. You will need to make sure that the managed identity has the appropriate role assignments to access other resources that it is attached to (for example, certificates stored in Azure Key Vault). +{{}} + +- User must be an owner or user access administrator for the NGINX deployment resource. + + ### Adding diagnostic settings + +1. Go to your NGINXaaS for Azure deployment. + +1. Select **Diagnostic Settings** in the left menu. + +1. Select **Add diagnostic setting**. + +1. Choose the **NGINX Logs** option and complete the details on the form, including the **Diagnostic setting name**. + +{{}}You will need to configure the system-assigned managed identity in order to see and select the **NGINX Logs** option. +{{}} + +1. Select preferred **Destination details**. + + ![Screenshot of the Diagnostic Settings configuration page](/nginxaas-azure/diagnostic-settings.png) + +For more information about diagnostic settings destinations, please see the [Diagnostic Settings Destinations](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/diagnostic-settings#destinations) documentation. + +{{}}Due to limitations imposed by Azure, if the destination chosen is an Azure Storage account, the resource has to be in the same region as the NGINXaaS deployment resource. +{{}} + +{{}}If you are a Terraform user, please refer to [examples](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/deployments/with-diagnostic-setting-logging) provided to setup diagnostic settings for your NGINXaaS deployment{{}} + +### Analyzing NGINX logs in Azure Storage + +{{< include "/nginxaas-azure/logging-analysis-azure-storage.md" >}} + +### Analyzing NGINX logs in Azure Log Analytics workspaces + +{{< include "/nginxaas-azure/logging-analysis-logs-analytics.md" >}} + +### Disable NGINX logs collection + +1. Go to your NGINXaaS for Azure deployment. + +1. Select **Diagnostic Settings** in the left menu. + +1. Edit the previously added Diagnostic Settings. + +1. Select **Delete**. + +{{}}It can take up to 90 minutes after removing the diagnostic settings for logs to stop publishing to the diagnostic destinations.{{}} + +## Setting up error logs + +{{< include "/nginxaas-azure/logging-config-error-logs.md" >}} + +## Setting up access logs + +{{< include "/nginxaas-azure/logging-config-access-logs.md" >}} + +## Limitations + +{{< include "/nginxaas-azure/logging-limitations.md" >}} diff --git a/content/nginxaas-azure/monitoring/enable-logging/logging-using-terraform.md b/content/nginxaas-azure/monitoring/enable-logging/logging-using-terraform.md new file mode 100644 index 000000000..796cede23 --- /dev/null +++ b/content/nginxaas-azure/monitoring/enable-logging/logging-using-terraform.md @@ -0,0 +1,62 @@ +--- +title: "Enable NGINX logs using Terraform" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-1369" +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) supports integrating Azure Diagnostic Settings to collect NGINX error and access logs. + +{{}} +Enabling logs using the **NGINX Logs** blade on your NGINXaaS deployment is now deprecated. This feature will be removed in an upcoming update. If you have issues accessing your NGINX logs using the deprecated method, please follow the steps in this guide to access your NGINX logs. +{{}} + +## Configuring NGINX logs collection using diagnostic settings + +### Prerequisites + +- A valid NGINX configuration with log directives enabled. NGINX logs can be configured using [error_log](#setting-up-error-logs) and [access_log](#setting-up-access-logs) directives. + +- A system-assigned managed identity. +{{}}The system-assigned managed identity does not need any role assignments to enable the logging functionality described in this section. You will need to make sure that the managed identity has the appropriate role assignments to access other resources that it is attached to (for example, certificates stored in Azure Key Vault). +{{}} + +- User must be an owner or user access administrator for the NGINX deployment resource. + + ### Adding diagnostic settings + +To setup diagnostic settings to enable logging to a storage account for your NGINXaaS deployment, please refer to [examples](https://github.com/nginxinc/nginxaas-for-azure-snippets/tree/main/terraform/deployments/with-diagnostic-setting-logging) provided. + +Once the terraform configurations provided in the repository above are used, the following commands can be used to update the deployment. + +```shell +terraform init +terraform plan -var="storage_account_resource_group=myresourcegroup" -var="storage_account_name=myaccountname" -out=plan.cache +terraform apply plan.cache +``` + +{{}}Due to limitations imposed by Azure, if the destination chosen is an Azure Storage account, the resource has to be in the same region as the NGINXaaS deployment resource. +{{}} + +### Analyzing NGINX logs in Azure Storage + +{{< include "/nginxaas-azure/logging-analysis-azure-storage.md" >}} + +### Analyzing NGINX logs in Azure Log Analytics workspaces + +{{< include "/nginxaas-azure/logging-analysis-logs-analytics.md" >}} + +## Setting up error logs + +{{< include "/nginxaas-azure/logging-config-error-logs.md" >}} + +## Setting up access logs + +{{< include "/nginxaas-azure/logging-config-access-logs.md" >}} + +## Limitations + +{{< include "/nginxaas-azure/logging-limitations.md" >}} diff --git a/content/nginxaas-azure/monitoring/enable-monitoring.md b/content/nginxaas-azure/monitoring/enable-monitoring.md new file mode 100644 index 000000000..5d601a70b --- /dev/null +++ b/content/nginxaas-azure/monitoring/enable-monitoring.md @@ -0,0 +1,146 @@ +--- +title: "Enable monitoring" +weight: 200 +categories: ["tasks"] +toc: true +docs: "DOCS-876" +--- + +Monitoring your application's performance is crucial for maintaining its reliability and efficiency. F5 NGINX as a Service for Azure (NGINXaaS) seamlessly integrates with Azure Monitor, allowing you to collect, correlate, and analyze metrics for a thorough understanding of your application's health and behavior. With Azure Monitor, you gain access to a wealth of information regarding your application's operations. You can: + +- Review Metrics: Examine the performance data collected from your application. +- Correlate Data: Connect different data points to gain insights into application performance trends. +- Analyze Performance: Dive deep into metrics to gain a comprehensive understanding of how your application operates. +- Create Alerts: Set up proactive monitoring by configuring alerts that notify you of potential issues before they escalate. + +{{}}NGINXaaS for Azure publishes *custom* metrics to Azure Monitor. To learn about the differences between standard and custom metrics, refer to the [Custom metrics in Azure Monitor overview](https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/metrics-custom-overview) documentation from Microsoft. Azure Monitor custom metrics are currently in public preview.{{}} + + +### Prerequisites + +- A user assigned managed identity or a system assigned managed identity with `Monitoring Metrics Publisher` role. + +{{}} When a user assigned managed identity or a system assigned managed identity is added to the deployment through portal, this role is automatically added.{{}} + +- User must be an owner or user access administrator for NGINX deployment resource to complete this set up. + +- If you're unfamiliar with Azure Monitor, refer to the [Azure monitor overview](https://docs.microsoft.com/en-us/azure/azure-monitor/overview) documentation from Microsoft. + +## Enable monitoring + +1. Log in to the Azure portal and navigate to your NGINXaaS for Azure deployment. +2. In the navigation pane under **Settings**, select the **NGINX monitoring** section. +3. Turn on the **Send metrics to Azure Monitor** setting. + +## View metrics with Azure Monitor metrics explorer + +1. In the navigation pane under **Monitoring**, select the **Metrics** section to access the Azure Monitor metrics explorer for your NGINXaaS deployment. +2. Refer to the [Azure Monitor metrics explorer](https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/metrics-getting-started) documentation from Microsoft to learn how you can create queries. + +{{}}Many of NGINX Plus's advanced statistics need to be enabled in the "nginx.conf" file before they will appear in the metrics explorer, for example "plus.http.request.bytes_*". Refer to [Gathering Data to Appear in Statistics](https://docs.nginx.com/nginx/admin-guide/monitoring/live-activity-monitoring/#gathering-data-to-appear-in-statistics) to learn more.{{}} + +## Retrieve metrics through Azure Monitor API + +This section shows you how to effectively discover, gather and analyze NGINXaaS metrics through the Azure Monitor API. + +{{}}Refer to [Authenticate Azure Monitor requests](https://learn.microsoft.com/en-us/azure/azure-monitor/essentials/rest-api-walkthrough?tabs=portal#authenticate-azure-monitor-requests) for instructions on authenticating your API requests against the Azure Monitor API endpoint.{{}} + +1. **Retrieve metric namespaces:** Each metric belongs to a category, or "namespace", which groups similar types of metrics together. We recommend listing all namespaces for NGINXaaS to locate the metrics you're interested in. The following `curl` example shows how to retrieve all metrics namespaces on your NGINXaaS deployment: + + ```bash + curl --request GET --header "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions/12345678-abcd-98765432-abcdef012345/resourceGroups/my-nginx-rg/providers/NGINX.NGINXPLUS/nginxDeployments/my-nginx-dep/providers/microsoft.insights/metricNamespaces?api-version=2024-02-01" + ``` + + The following JSON shows an example response body: + + ```json + { + "value": [ + ... + { + "id": "/subscriptions/12345678-abcd-98765432-abcdef012345/resourceGroups/my-nginx-rg/providers/NGINX.NGINXPLUS/nginxDeployments/my-nginx-dep/providers/microsoft.insights/metricNamespaces/NGINX Connections Statistics", + "name": "nginx connections statistics", + "type": "Microsoft.Insights/metricNamespaces", + "classification": "Custom", + "properties": { + "metricNamespaceName": "nginx connections statistics" + } + }, + ... + ] + } + ``` + +2. **Retrieve metric definitions:** Metrics definitions give you insights into the various metrics available for NGINXaaS within a namespace and what they represent. The following `curl` example shows how to retrieve all metrics definitions within the `nginx connections statistics` namespace for your NGINXaaS deployment: + + ```bash + curl --request GET --header "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions/12345678-abcd-98765432-abcdef012345/resourceGroups/my-nginx-rg/providers/NGINX.NGINXPLUS/nginxDeployments/my-nginx-dep/providers/microsoft.insights/metricDefinitions?metricnamespace=nginx%20connections%20statistics&api-version=2024-02-01" + ``` + + The following JSON shows an example response body: + + ```json + { + "value": [ + ... + { + "id": "/subscriptions/12345678-abcd-98765432-abcdef012345/resourceGroups/my-nginx-rg/providers/NGINX.NGINXPLUS/nginxDeployments/my-nginx-dep/providers/microsoft.insights/metricdefinitions/Nginx Connections Statistics/nginx.conn.current", + "resourceId": "/subscriptions/12345678-abcd-98765432-abcdef012345/resourceGroups/my-nginx-rg/providers/NGINX.NGINXPLUS/nginxDeployments/my-nginx-deployment", + "namespace": "NGINX Connections Statistics", + "name": { + "value": "nginx.conn.current", + "localizedValue": "nginx.conn.current" + }, + ... + }, + ... + ] + } + ``` + +3. **Metric values:** Finally, you can obtain the actual metric values which represent real-time or historical data points that tell you how your NGINXaaS is performing. The following `curl` example shows how to retrieve the value of metric `nginx.conn.current` within the `nginx connections statistics` namespace over a 10-minute time window averaged over 5 minute intervals: + + ```bash + curl --request GET --header "Authorization: Bearer $TOKEN" "https://management.azure.com/subscriptions/12345678-abcd-98765432-abcdef012345/resourceGroups/my-nginx-rg/providers/NGINX.NGINXPLUS/nginxDeployments/my-nginx-dep/providers/microsoft.insights/metrics?metricnamespace=nginx%20connections%20statistics&metricnames=nginx.conn.current×pan=2024-03-27T20:00:00Z/2024-03-27T20:10:00Z&aggregation=Average&interval=PT5M&api-version=2024-02-01" + ``` + + The following JSON shows an example response body: + + ```json + { + "cost": 9, + "timespan": "2024-03-27T20:00:00Z/2024-03-27T20:10:00Z", + "interval": "PT5M", + "value": [ + { + "id": "/subscriptions/12345678-abcd-98765432-abcdef012345/resourceGroups/my-nginx-rg/providers/NGINX.NGINXPLUS/nginxDeployments/my-nginx-dep/providers/Microsoft.Insights/metrics/nginx.conn.current", + "type": "Microsoft.Insights/metrics", + "name": { + "value": "nginx.conn.current", + "localizedValue": "nginx.conn.current" + }, + "unit": "Unspecified", + "timeseries": [ + { + "metadatavalues": [], + "data": [ + { + "timeStamp": "2024-03-27T20:00:00Z", + "average": 4 + }, + { + "timeStamp": "2024-03-27T20:05:00Z", + "average": 4 + } + ] + } + ], + "errorCode": "Success" + } + ], + "namespace": "nginx connections statistics", + "resourceregion": "eastus2" + } + ``` + +{{}} Refer to the [Metrics Catalog]({{< relref "/nginxaas-azure/monitoring/metrics-catalog.md" >}}) for a listing of available namespaces and metrics.{{}} diff --git a/content/nginxaas-azure/monitoring/metrics-catalog.md b/content/nginxaas-azure/monitoring/metrics-catalog.md new file mode 100644 index 000000000..5dee06577 --- /dev/null +++ b/content/nginxaas-azure/monitoring/metrics-catalog.md @@ -0,0 +1,302 @@ +--- +title: "Metrics catalog" +weight: 400 +categories: ["concepts"] +toc: false +docs: "DOCS-877" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) provides a rich set of metrics that you can use to monitor the health and performance of your NGINXaaS deployment. This document provides a catalog of the metrics that are available for monitoring NGINXaaS for Azure in Azure Monitor. + +## Available metrics + +- [NGINXaaS Statistics](#nginxaas-statistics) +- [NGINX connections statistics](#nginx-connections-statistics) +- [NGINX requests and response statistics](#nginx-requests-and-response-statistics) +- [NGINX SSL Statistics](#nginx-ssl-statistics) +- [NGINX Cache Statistics](#nginx-cache-statistics) +- [NGINX Worker Statistics](#nginx-worker-statistics) +- [NGINX Upstream Statistics](#nginx-upstream-statistics) +- [NGINX System Statistics](#nginx-system-statistics) +- [NGINX Stream Statistics](#nginx-stream-statistics) +- [NGINX Resolver Statistics](#nginx-resolver-statistics) + +## Metrics + +The following metrics are reported on by NGINXaaS for Azure in Azure Monitor. +The metrics are categorized by the namespace used in Azure Monitor. The dimensions allow you to filter or split your queries in Azure Monitor providing you with a granular view over the metrics reported + +### NGINXaaS statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +| --------------------- | -------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| ncu.provisioned | | count | The number of successfully provisioned NCUs during the aggregation interval. During scaling events, this may lag behind `ncu.requested` as the system works to achieve the request. Available for Standard plan deployments. | deployment | +| ncu.requested | | count | The requested number of NCUs during the aggregation interval. Describes the goal state of the system. Available for Standard plan deployments. | deployment | +| ncu.consumed | | count | The estimated number of NCUs used to handle the current traffic. This may burst above the `ncu.provisioned`. This can be used to guide scaling out or in to match your workload. See [Scaling Guidance]({{< relref "/nginxaas-azure/quickstart/scaling.md#iterative-approach" >}}) for details. Available for Standard plan deployments. | deployment | +| system.worker_connections | pid process_name | count | The number of nginx worker connections used on the dataplane. This metric is one of the factors which determines the deployment's consumed NCU value. | deployment | +| nginxaas.certificates | name status | count | The number of certificates added to the NGINXaaS deployment dimensioned by the name of the certificate and its status. Refer to [Certificate Health]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/overview.md#monitor-certificates" >}}) to learn more about the status dimension. | deployment | +| nginxaas.maxmind | status | count | The status of any MaxMind license in use for downloading geoip2 databases. Refer to [License Health]({{< relref "/nginxaas-azure/quickstart/geoip2.md#monitoring" >}}) to learn more about the status dimension. | deployment | + +{{}} + +### NGINX connections statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|------------------------------|----------------|----------|---------------------------------------------------------------------------------------------------------------|-----------------| +| nginx.conn.accepted | build version | count | Accepted Connections The total number of accepted client connections during the aggregation interval. | deployment | +| nginx.conn.dropped | build version | count | Dropped Connections The total number of dropped client connections during the aggregation interval. | deployment | +| nginx.conn.active | build version | avg | Active Connections The average number of active client connections during the aggregation interval. | deployment | +| nginx.conn.idle | build version | avg | Idle Connections The average number of idle client connections during the aggregation interval. | deployment | +| nginx.conn.current | build version | avg | Current Connections The average number of active and idle client connections during the aggregation interval. | deployment | + +{{}} + +### NGINX requests and response statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|----------------------------------------|-----------------------------|-------|-----------------------------------------------------------------------------------------------------------------------------|---------------| +| nginx.http.request.count | build version | count | HTTP Requests The total number of HTTP requests during the aggregation interval. | deployment | +| nginx.http.request.current | build version | avg | Current Requests The average number of current requests during the aggregation interval. | deployment | +| nginx.http.limit_conns.passed | build version limit_conn_zone | count | Limit Conn Zone Passed HTTP Connections The total number of connections that were neither limited nor accounted as limited during the aggregation interval. | limit conn zone | +| nginx.http.limit_conns.rejected | build version limit_conn_zone | count | Limit Conn Zone Rejected HTTP Connections The total number of connections that were rejected during the aggregation interval. | limit conn zone | +| nginx.http.limit_conns.rejected_dry_run| build version limit_conn_zone | count | Limit Conn Zone Rejected HTTP Connections In The Dry Run Mode The total number of connections accounted as rejected in the dry run mode during the aggregation interval. | limit conn zone | +| nginx.http.limit_reqs.passed | build version limit_req_zone | count | Limit Req Zone Passed HTTP Requests Rate The total number of requests that were neither limited nor accounted as limited during the aggregation interval. | limit req zone | +| nginx.http.limit_reqs.delayed | build version limit_req_zone | count | Limit Req Zone Delayed HTTP Requests Rate The total number of requests that were delayed during the aggregation interval. | limit req zone | +| nginx.http.limit_reqs.rejected | build version limit_req_zone | count | Limit Req Zone Rejected HTTP Requests Rate The total number of requests that were rejected during the aggregation interval. | limit req zone | +| nginx.http.limit_reqs.delayed_dry_run | build version limit_req_zone | count | Limit Req Zone Delayed HTTP Requests Rate In The Dry Run Mode The total number of requests accounted as delayed in the dry run mode during the aggregation interval. | limit req zone | +| nginx.http.limit_reqs.rejected_dry_run | build version limit_req_zone | count | Limit Req Zone Rejected HTTP Requests Rate In The Dry Run Mode The total number of requests accounted as rejected in the dry run mode during the aggregation interval. | limit req zone | +| plus.http.request.count | build version server_zone | count | Server Zone HTTP Requests The total number of HTTP requests during the aggregation interval. | server zone | +| plus.http.response.count | build version server_zone | count | Server Zone HTTP Responses The total number of HTTP responses during the aggregation interval. | server zone | +| plus.http.status.1xx | build version server_zone | count | Server Zone HTTP 1xx Responses The total number of HTTP responses with a 1xx status code during the aggregation interval. | server zone | +| plus.http.status.2xx | build version server_zone | count | Server Zone HTTP 2xx Responses The total number of HTTP responses with a 2xx status code during the aggregation interval. | server zone | +| plus.http.status.3xx | build version server_zone | count | Server Zone HTTP 3xx Responses The total number of HTTP responses with a 3xx status code during the aggregation interval. | server zone | +| plus.http.status.4xx | build version server_zone | count | Server Zone HTTP 4xx Responses The total number of HTTP responses with a 4xx status code during the aggregation interval. | server zone | +| plus.http.status.5xx | build version server_zone | count | Server Zone HTTP 5xx Responses The total number of HTTP responses with a 5xx status code during the aggregation interval. | server zone | +| plus.http.status.processing | build version server_zone | avg | Server Zone Status Processing The number of client requests that are currently being processed. | server zone | +| plus.http.request.bytes_rcvd | build version server_zone | count | Server Zone Bytes Received The total number of bytes received from clients during the aggregation interval. | server zone | +| plus.http.request.bytes_sent | build version server_zone | count | Server Zone Bytes Sent The total number of bytes sent to clients during the aggregation interval. | server zone | +| plus.http.request.count | build version location_zone | count | Location Zone HTTP Requests The total number of HTTP requests during the aggregation interval. | location zone | +| plus.http.response.count | build version location_zone | count | Location Zone HTTP Responses The total number of HTTP responses in the aggregation interval. | location zone | +| plus.http.status.1xx | build version location_zone | count | Location Zone HTTP 1xx Responses The total number of HTTP responses with a 1xx status code during the aggregation interval. | location zone | +| plus.http.status.2xx | build version location_zone | count | Location Zone HTTP 2xx Responses The total number of HTTP responses with a 2xx status code during the aggregation interval. | location zone | +| plus.http.status.3xx | build version location_zone | count | Location Zone HTTP 3xx Responses The total number of HTTP responses with a 3xx status code during the aggregation interval. | location zone | +| plus.http.status.4xx | build version location_zone | count | Location Zone HTTP 4xx Responses The total number of HTTP responses with a 4xx status code during the aggregation interval. | location zone | +| plus.http.status.5xx | build version location_zone | count | Location Zone HTTP 5xx Responses The total number of HTTP responses with a 5xx status code during the aggregation interval. | location zone | +| plus.http.request.bytes_rcvd | build version location_zone | count | Location Zone Bytes Received The total number of bytes received from clients during the aggregation interval. | location zone | +| plus.http.request.bytes_sent | build version location_zone | count | Location Zone Bytes Sent The total number of bytes sent to clients during the aggregation interval. | location zone | + +{{}} + +### NGINX SSL statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|----------------------------------------|-----------------------------|-------|-----------------------------------------------------------------------------------------------------------------------------|---------------| +| plus.ssl.failed | build version | count | The total number of failed SSL handshakes during the aggregation interval. | deployment | +| plus.ssl.handshakes | build version | count |The total number of successful SSL handshakes during the aggregation interval. | deployment | +| plus.ssl.reuses | build version | count |The total number of session reuses during SSL handshakes in the aggregation interval. | deployment | +| plus.ssl.no_common_protocol | build version | avg |The number of SSL handshakes failed because of no common protocol during the aggregation interval. | deployment | +| plus.ssl.no_common_cipher | build version | avg |The number of SSL handshakes failed because of no shared cipher during the aggregation interval. | deployment | +| plus.ssl.handshake_timeout | build version | avg | The number of SSL handshakes failed because of a timeout during the aggregation interval. | deployment | +| plus.ssl.peer_rejected_cert | build version | avg |The number of failed SSL handshakes when nginx presented the certificate to the client but it was rejected with a corresponding alert message during the aggregation interval. | deployment | +| plus.ssl.verify_failures.no_cert | build version | avg | SSL certificate verification errors - a client did not provide the required certificate during the aggregation interval. | deployment | +| plus.ssl.verify_failures.expired_cert | build version | avg |SSL certificate verification errors - an expired or not yet valid certificate was presented by a client during the aggregation interval. | deployment | +| plus.ssl.verify_failures.revoked_cert | build version | avg |SSL certificate verification errors - a revoked certificate was presented by a client during the aggregation interval. | deployment | +| plus.ssl.verify_failures.hostname_mismatch | build version | avg |SSL certificate verification errors - server's certificate doesn't match the hostname during the aggregation interval. | deployment| +| plus.ssl.verify_failures.other | build version | avg | SSL certificate verification errors - other SSL certificate verification errors during the aggregation interval. | deployment | +| plus.http.ssl.handshakes | build version server_zone | count |The total number of successful SSL handshakes during the aggregation interval. | server zone | +| plus.http.ssl.handshakes.failed | build version server_zone | count | The total number of failed SSL handshakes during the aggregation interval. | server zone | +| plus.http.ssl.session.reuses | build version server_zone | count |The total number of session reuses during SSL handshakes in the aggregation interval. | server zone | +| plus.http.ssl.no_common_protocol | build version server_zone | avg |The number of SSL handshakes failed because of no common protocol during the aggregation interval. | server zone | +| plus.http.ssl.no_common_cipher | build version server_zone | avg |The number of SSL handshakes failed because of no shared cipher during the aggregation interval. | server zone | +| plus.http.ssl.handshake_timeout | build version server_zone | avg | The number of SSL handshakes failed because of a timeout during the aggregation interval. | server zone | +| plus.http.ssl.peer_rejected_cert | build version server_zone | avg |The number of failed SSL handshakes when nginx presented the certificate to the client but it was rejected with a corresponding alert message during the aggregation interval. | server zone | +| plus.http.ssl.verify_failures.no_cert | build version server_zone | avg | SSL certificate verification errors - a client did not provide the required certificate during the aggregation interval. | server zone | +| plus.http.ssl.verify_failures.expired_cert | build version server_zone | avg |SSL certificate verification errors - an expired or not yet valid certificate was presented by a client during the aggregation interval. | server zone | +| plus.http.ssl.verify_failures.revoked_cert | build version server_zone | avg |SSL certificate verification errors - a revoked certificate was presented by a client during the aggregation interval. | server zone | +| plus.http.ssl.verify_failures.other | build version server_zone | avg | SSL certificate verification errors - other SSL certificate verification errors during the aggregation interval. | server zone | + +{{}} + +### NGINX cache statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|----------------------------------------|-----------------------------|-------|-----------------------------------------------------------------------------------------------------------------------------|---------------| +| plus.cache.hit.ratio | build version cache_zone | avg | Cache Hit Ratio The average ratio of cache hits to misses during the aggregation interval. | cache zone | + +{{}} + +### NGINX worker statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|----------------------------------------|-----------------------------|-------|-----------------------------------------------------------------------------------------------------------------------------|---------------| +| plus.worker.conn.accepted| build version worker_id | count |The total number of client connections accepted by the worker process during the aggregation interval. | worker | +| plus.worker.conn.dropped| build version worker_id | count |The total number of client connections dropped by the worker process during the aggregation interval. | worker | +| plus.worker.conn.active| build version worker_id | avg| The current number of active client connections that are currently being handled by the worker process during the aggregation interval. | worker | +| plus.worker.conn.idle| build version worker_id | avg|The number of idle client connections that are currently being handled by the worker process during the aggregation interval. | worker | +| plus.worker.http.request.total | build version worker_id | count | The total number of client requests received by the worker process during the aggregation interval. | worker | +| plus.worker.http.request.current | build version worker_id | avg| The current number of client requests that are currently being processed by the worker process during the aggregation interval. | worker| + +{{}} + +### NGINX upstream statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|-----------------------------------|-----------------------------|-------|-----------------------------------------------------------------------------------------------------------------------------|---------------| +| plus.http.upstream.peers.conn.active | build version upstream peer.address peer.name | avg | Upstream Server Active Connections The average number of active client connections during the aggregation interval. | upstream server | +| plus.http.upstream.peers.request.count | build version upstream peer.address peer.name | count | Upstream Server HTTP Requests The total number of HTTP requests during the aggregation interval. | upstream server | +| plus.http.upstream.peers.response.count | build version upstream peer.address peer.name | count | Upstream Server HTTP Responses The total number of HTTP responses during the aggregation interval. | upstream server | +| plus.http.upstream.peers.status.1xx | build version upstream peer.address peer.name | count | Upstream Server HTTP 1xx Responses The total number of HTTP responses with a 1xx status code during the aggregation interval. | upstream server | +| plus.http.upstream.peers.status.2xx | build version upstream peer.address peer.name | count | Upstream Server HTTP 2xx Responses The total number of HTTP responses with a 2xx status code during the aggregation interval. | upstream server | +| plus.http.upstream.peers.status.3xx | build version upstream peer.address peer.name | count | Upstream Server HTTP 3xx Responses The total number of HTTP responses with a 3xx status code during the aggregation interval. | upstream server | +| plus.http.upstream.peers.status.4xx | build version upstream peer.address peer.name | count | Upstream Server HTTP 4xx Responses The total number of HTTP responses with a 4xx status code during the aggregation interval. | upstream server | +| plus.http.upstream.peers.status.5xx | build version upstream peer.address peer.name | count | Upstream Server HTTP 5xx Responses The total number of HTTP responses with a 5xx status code during the aggregation interval. | upstream server | +| plus.http.upstream.peers.request.bytes_sent | build version upstream peer.address peer.name | count | | upstream server | +| plus.http.upstream.peers.request.bytes_rcvd | build version upstream peer.address peer.name | count | | upstream server | +| plus.http.upstream.peers.state.up | build version upstream peer.address peer.name | boolean | Upstream Server State Up Current state of upstream servers in deployment. If all upstream servers in the deployment are up, then the value will be 1. If any upstream server is not up, then the value will be 0. | upstream peer | +| plus.http.upstream.peers.state.draining | build version upstream peer.address peer.name | boolean | Upstream Server State Draining Current state of upstream servers in deployment. If any of the upstream servers in the deployment are draining, then the value will be 1. If no upstream server is draining, then the value will be 0. | upstream peer | +| plus.http.upstream.peers.state.down | build version upstream peer.address peer.name | boolean | Upstream Server State Down Current state of upstream servers in deployment. If any of the upstream servers in the deployment are down, then the value will be 1. If no upstream server is down, then the value will be 0. | upstream peer | +| plus.http.upstream.peers.state.unavail | build version upstream peer.address peer.name | boolean | Upstream Server State Unavailable Current state of upstream servers in deployment. If any of the upstream servers in the deployment are unavailable, then the value will be 1. If no upstream server is unavailable, then the value will be 0. | upstream peer | +| plus.http.upstream.peers.state.checking | build version upstream peer.address peer.name | boolean | Upstream Server State Check Current state of upstream servers in deployment. If any of the upstream servers in the deployment is being checked then the value will be 1. If no upstream server is being checked then the value will be 0. | upstream peer | +| plus.http.upstream.peers.state.unhealthy | build version upstream peer.address peer.name | boolean | Upstream Server State Unhealthy Current state of upstream servers in deployment. If any of the upstream servers in the deployment are unhealthy then the value will be 1. If no upstream server is unhealthy then the value will be 0. | upstream peer | +| plus.http.upstream.peers.fails | build version upstream peer.address peer.name | count | Upstream Server Fails The total number of unsuccessful attempts to communicate with the server during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.unavail | build version upstream peer.address peer.name | count | Upstream Server Unavailable The number of times the server became unavailable for client requests (state “unavail”) due to the number of unsuccessful attempts reaching the [max_fails](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#max_fails) threshold during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.health_checks.checks | build version upstream peer.address peer.name | count | Upstream Server Health Checks The total number of [health check](https://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#health_check) requests made during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.health_checks.fails | build version upstream peer.address peer.name | count | Upstream Server Health Checks Fails The number of failed health checks during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.health_checks.unhealthy | build version upstream peer.address peer.name | count | Upstream Server Health Checks Unhealthy How many times the server became unhealthy (state “unhealthy”) during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.health_checks.last_passed | build version upstream peer.address peer.name | boolean | Upstream Server Health Checks Last Pass last_passed (boolean) indicating if the last health check request was successful and passed [tests](https://nginx.org/en/docs/http/ngx_http_upstream_hc_module.html#match). | upstream peer | +| plus.http.upstream.peers.downstart | build version upstream peer.address peer.name | timestamp | Upstream Server Downstart The time when the server became “unavail”, “checking”, or “unhealthy”, as a UTC timestamp. | upstream peer | +| plus.http.upstream.peers.response.time | build version upstream peer.address peer.name | avg | Upstream Server Response Time The average time to get the [full response](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#var_upstream_response_time) from the server during the aggregation interval. | upstream server | +| plus.http.upstream.peers.header.time | build version upstream peer.address peer.name | avg | Upstream Server Header Time The average time to get the [response header](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#var_upstream_header_time) from the server | upstream server | +| plus.http.upstream.zombies | build version | avg | Upstream Zombies The current number of servers removed from the group but still processing active client requests | deployment | +| plus.http.upstream.keepalives | build version | avg | Upstream Keepalive Connections The current number of idle [keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) connections | deployment | +| plus.http.upstream.queue.maxsize | build version | avg | Upstream Queue Max Size The maximum number of requests that can be in the queue at the same time | deployment | +| plus.http.upstream.queue.overflows | build version | sum | Upstream Queue Overflows The total number of requests rejected due to the queue overflow | deployment | +| plus.http.upstream.queue.size | build version | avg | Upstream Queue Size The current number of requests in the queue | deployment | +| plus.http.upstream.peers.ssl.handshakes | build version upstream peer.address peer.name | count | The total number of successful SSL handshakes during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.handshakes.failed | build version upstream peer.address peer.name | count |The total number of failed SSL handshakes during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.session.reuses | build version upstream peer.address peer.name | count |The total number of session reuses during SSL handshake in the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.no_common_protocol | build version upstream peer.address peer.name | avg | The number of SSL handshakes failed because of no common protocol during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.handshake_timeout | build version upstream peer.address peer.name | avg |The number of SSL handshakes failed because of a timeout during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.peer_rejected_cert | build version upstream peer.address peer.name | avg | The number of failed SSL handshakes when nginx presented the certificate to the client but it was rejected with a corresponding alert message during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.verify_failures.expired_cert | build version upstream peer.address peer.name | avg | SSL certificate verification errors - an expired or not yet valid certificate was presented by a client during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.verify_failures.revoked_cert | build version upstream peer.address peer.name | avg | SSL certificate verification errors - a revoked certificate was presented by a client during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.verify_failures.hostname_mismatch | build version upstream peer.address peer.name | avg | SSL certificate verification errors - server's certificate doesn't match the hostname during the aggregation interval. | upstream peer | +| plus.http.upstream.peers.ssl.verify_failures.other | build version upstream peer.address peer.name | avg |SSL certificate verification errors - other SSL certificate verification errors during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.handshakes | build version upstream peer.address peer.name | count |The total number of successful SSL handshakes during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.handshakes.failed | build version upstream peer.address peer.name | count | The total number of failed SSL handshakes during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.session.reuses | build version upstream peer.address peer.name | count | The total number of session reuses during SSL handshake in the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.no_common_protocol | build version upstream peer.address peer.name | avg | The number of SSL handshakes failed because of no common protocol during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.handshake_timeout | build version upstream peer.address peer.name | avg | The number of SSL handshakes failed because of a timeout during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.peer_rejected_cert | build version upstream peer.address peer.name | avg | The number of failed SSL handshakes when nginx presented the certificate to the client but it was rejected with a corresponding alert message during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.verify_failures.expired_cert | build version upstream peer.address peer.name | avg | SSL certificate verification errors - an expired or not yet valid certificate was presented by a client during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.verify_failures.revoked_cert | build version upstream peer.address peer.name | avg | SSL certificate verification errors - a revoked certificate was presented by a client during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.verify_failures.hostname_mismatch | build version upstream peer.address peer.name | avg | SSL certificate verification errors - server's certificate doesn't match the hostname during the aggregation interval. | upstream peer | +| plus.stream.upstream.peers.ssl.verify_failures.other | build version upstream peer.address peer.name | avg | SSL certificate verification errors - other SSL certificate verification errors during the aggregation interval. | upstream peer | + +{{}} + +### NGINX system statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|----------------------------------------|-----------------------------|-------|-----------------------------------------------------------------------------------------------------------------------------|---------------| +| system.cpu| | count | System CPU Utilization. | deployment | +| system.interface.bytes_rcvd| interface | count | System Interface Bytes Received. | deployment | +| system.interface.bytes_sent| interface | count | System Interface Bytes Sent. | deployment | +| system.interface.packets_rcvd| interface | count | System Interface Packets Received. | deployment | +| system.interface.packets_sent| interface | count | System Interface Packets Sent. | deployment | +| system.interface.total_bytes| interface | count | System Interface Total Bytes, sum of bytes_sent and bytes_rcvd. | deployment | +| system.interface.egress_throughput| interface | count | System Interface Egress Throughput, i.e. bytes sent per second| deployment | + +{{}} + +### NGINX stream statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|----------------------------------------|-----------------------------|-------|-----------------------------------------------------------------------------------------------------------------------------|---------------| +| plus.stream.limit_conns.passed | build, version, limit_conn_zone | count | The total number of connections that were neither limited nor accounted as limited. | limit conn zone | +| plus.stream.limit_conns.rejected | build, version, limit_conn_zone | count | The total number of connections that were rejected. | limit conn zone | +| plus.stream.limit_conns.rejected_dry_run | build, version, limit_conn_zone | count | The total number of connections accounted as rejected in the dry run mode. | limit conn zone | +| plus.stream.request.bytes_rcvd | build, version, server_zone | count | The total number of bytes received from clients. | server zone | +| plus.stream.request.bytes_sent | build, version, server_zone | count | The total number of bytes sent to clients. | server zone | +| plus.stream.status.2xx | build, version, server_zone | count | The total number of sessions completed with status codes “2xx”. | server zone | +| plus.stream.status.4xx | build, version, server_zone | count | The total number of sessions completed with status codes “4xx”. | server zone | +| plus.stream.status.5xx | build, version, server_zone | count | The total number of sessions completed with status codes “5xx”. | server zone | +| plus.stream.status.connections | build, version, server_zone | avg | The total number of connections accepted from clients. | server zone | +| plus.stream.status.discarded | build, version, server_zone | avg | The total number of connections completed without creating a session. | server zone | +| plus.stream.status.processing | build, version, server_zone | avg | The number of client connections that are currently being processed. | server zone | +| plus.stream.upstream.peers.conn.active | build, version, upstream, peer.address, peer.name | avg | The current number of connections. | upstream peer | +| plus.stream.upstream.peers.downstart | build, version, upstream, peer.address, peer.name | timestamp | The time when the server became “unavail”, “checking”, or “unhealthy”, in the ISO 8601 format with millisecond resolution. | upstream peer | +| plus.stream.upstream.peers.downtime | build, version, upstream, peer.address, peer.name | count | Total time the server was in the “unavail”, “checking”, and “unhealthy” states. | upstream peer | +| plus.stream.upstream.peers.fails | build, version, upstream, peer.address, peer.name | count | The total number of unsuccessful attempts to communicate with the server. | upstream peer | +| plus.stream.upstream.peers.health_checks.checks | build, version, upstream, peer.address, peer.name | count | The total number of health check requests made. | upstream peer | +| plus.stream.upstream.peers.health_checks.fails | build, version, upstream, peer.address, peer.name | count | The number of failed health checks. | upstream peer | +| plus.stream.upstream.peers.health_checks.last_passed | build, version, upstream, peer.address, peer.name | boolean | Boolean indicating whether the last health check request was successful and passed tests. | upstream peer | +| plus.stream.upstream.peers.health_checks.unhealthy | build, version, upstream, peer.address, peer.name | count | How many times the server became unhealthy (state “unhealthy”). | upstream peer | +| plus.stream.upstream.peers.request.bytes_rcvd | build, version, upstream, peer.address, peer.name | count | The total number of bytes received from this server. | upstream peer | +| plus.stream.upstream.peers.request.bytes_sent | build, version, upstream, peer.address, peer.name | count | The total number of bytes sent to this server. | upstream peer | +| plus.stream.upstream.peers.response.time | build, version, upstream, peer.address, peer.name | avg | The average time to receive the last byte of data. | upstream peer | +| plus.stream.upstream.peers.state.checking | build, version, upstream, peer.address, peer.name | boolean | Boolean indicating if any of the upstream servers are being checked. | upstream peer | +| plus.stream.upstream.peers.state.down | build, version, upstream, peer.address, peer.name | boolean | Boolean indicating if any of the upstream servers are down. | upstream peer | +| plus.stream.upstream.peers.state.draining | build, version, upstream, peer.address, peer.name | boolean | Boolean indicating if any of the upstream servers are draining. | upstream peer | +| plus.stream.upstream.peers.state.unavail | build, version, upstream, peer.address, peer.name | boolean | Boolean indicating if any of the upstream servers are unavailable. | upstream peer | +| plus.stream.upstream.peers.state.unhealthy | build, version, upstream, peer.address, peer.name | boolean | Boolean indicating if any of the upstream servers are unhealthy. | upstream peer | +| plus.stream.upstream.peers.state.up | build, version, upstream, peer.address, peer.name | boolean | Boolean indicating if all upstream servers are up. | upstream peer | +| plus.stream.upstream.peers.unavail | build, version, upstream, peer.address, peer.name | count | How many times the server became unavailable for client connections (state “unavail”) due to the number of unsuccessful attempts reaching the max_fails threshold. | upstream peer | +| plus.stream.upstream.zombies | build, version | avg | The current number of servers removed from the group but still processing active client connections. | deployment | +| plus.stream.ssl.handshakes| build version server_zone| count | The total number of successful SSL handshakes during the aggregation interval. | server zone| +| plus.stream.ssl.handshakes.failed | build version server_zone | count | SSL Handshakes Failed The total number of failed SSL handshakes during the aggregation interval. | server zone | +| plus.stream.ssl.session.reuses | build version server_zone | count | The total number of session reuses during SSL handshakes in the aggregation interval. | server zone | +| plus.stream.ssl.no_common_protocol | build version server_zone| avg |The number of SSL handshakes failed because of no common protocol during the aggregation interval. |server zone | +| plus.stream.ssl.no_common_cipher| build version server_zone | avg | The number of SSL handshakes failed because of no shared cipher during the aggregation interval. | server zone | +| plus.stream.ssl.handshake_timeout | build version server_zone | avg | The number of SSL handshakes failed because of a timeout during the aggregation interval. | server zone | +| plus.stream.ssl.peer_rejected_cert | build version server_zone | avg | The number of failed SSL handshakes when nginx presented the certificate to the client but it was rejected with a corresponding alert message during the aggregation interval. | server zone | +| plus.stream.ssl.verify_failures.no_cert | build version server_zone | avg |SSL certificate verification errors - a client did not provide the required certificate during the aggregation interval. |server zone | +| plus.stream.ssl.verify_failures.expired_cert | build version server_zone | avg |SSL certificate verification errors - an expired or not yet valid certificate was presented by a client during the aggregation interval. |server zone | +| plus.stream.ssl.verify_failures.revoked_cert | build version server_zone | avg |SSL certificate verification errors - a revoked certificate was presented by a client during the aggregation interval. |server zone | +| plus.stream.ssl.verify_failures.other | build version server_zone | avg |SSL certificate verification errors - other SSL certificate verification errors during the aggregation interval. | server zone | +| plus.stream.zone_sync.status.bytes_in | build, version | count | The number of bytes received by all nodes during the aggregation interval. | deployment | +| plus.stream.zone_sync.status.bytes_out | build, version | count | The number of bytes sent by all nodes during the aggregation interval. | deployment | +| plus.stream.zone_sync.status.msgs_in | build, version | count | The number of messages received by all nodes during the aggregation interval. | deployment | +| plus.stream.zone_sync.status.msgs_out | build, version | count | The number of messages sent by all nodes during the aggregation interval. | deployment | +| plus.stream.zone_sync.zones.records_pending | build, version, shared_memory_zone | avg | The average number of records that need to be sent to the cluster during the aggregation interval. | shared memory zone | +| plus.stream.zone_sync.zones.records_total | build, version, shared_memory_zone | avg | The average number of records stored in the shared memory zone by all nodes during the aggregation interval. | shared memory zone | + +{{}} + +### NGINX resolver statistics + +{{}} + +| **Metric** | **Dimensions** | **Type** | **Description** | **Roll-up per** | +|---------------------------------------|--------------------------------|----------|--------------------------------------------------------------------------------------------|-----------------| +| plus.resolvers.requests.name | build, version, resolver_zone | count | The number of requests to resolve names to addresses during the aggregation interval. | resolver zone | +| plus.resolvers.requests.srv | build, version, resolver_zone | count | The number of requests to resolve SRV records during the aggregation interval. | resolver zone | +| plus.resolvers.requests.addr | build, version, resolver_zone | count | The number of requests to resolve addresses to names during the aggregation interval. | resolver zone | +| plus.resolvers.responses.noerror | build, version, resolver_zone | count | The number of successful responses during the aggregation interval. | resolver zone | +| plus.resolvers.responses.formerr | build, version, resolver_zone | count | The number of FORMERR (Format error) responses during the aggregation interval. | resolver zone | +| plus.resolvers.responses.servfail | build, version, resolver_zone | count | The number of SERVFAIL (Server failure) responses during the aggregation interval. | resolver zone | +| plus.resolvers.responses.nxdomain | build, version, resolver_zone | count | The number of NXDOMAIN (Host not found) responses during the aggregation interval. | resolver zone | +| plus.resolvers.responses.notimp | build, version, resolver_zone | count | The number of NOTIMP (Unimplemented) responses during the aggregation interval. | resolver zone | +| plus.resolvers.responses.refused | build, version, resolver_zone | count | The number of REFUSED (Operation refused) responses during the aggregation interval. | resolver zone | +| plus.resolvers.responses.timedout | build, version, resolver_zone | count | The number of timed out requests during the aggregation interval. | resolver zone | +| plus.resolvers.responses.unknown | build, version, resolver_zone | count | The number of requests completed with an unknown error during the aggregation interval. | resolver zone | + +{{}} diff --git a/content/nginxaas-azure/overview/_index.md b/content/nginxaas-azure/overview/_index.md new file mode 100644 index 000000000..324e9b56b --- /dev/null +++ b/content/nginxaas-azure/overview/_index.md @@ -0,0 +1,8 @@ +--- +title: Overview +weight: 100 +url: /nginxaas/azure/overview/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/overview/feature-comparison.md b/content/nginxaas-azure/overview/feature-comparison.md new file mode 100644 index 000000000..a6ed48530 --- /dev/null +++ b/content/nginxaas-azure/overview/feature-comparison.md @@ -0,0 +1,69 @@ +--- +title: "Feature comparison" +weight: 300 +description: "Compare NGINXaaS for Azure with other NGINX offerings." +categories: ["concepts"] +toc: false +docs: "DOCS-1473" +--- + +{{}} + +|**Load Balancer**
   |**NGINX Open
Source** |**NGINX Plus
 ** |**F5 NGINXaaS
for Azure** | +|----------------------------------------|---------------------|---------------------|--------------------------| +|  [HTTP](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/) and [TCP/UDP](https://docs.nginx.com/nginx/admin-guide/load-balancer/tcp-udp-load-balancer/) support |{{}} |{{}} |{{}} | +|  [Layer 7 request routing](https://www.nginx.org/en/docs/http/ngx_http_core_module.html#location) |{{}} |{{}} |{{}} | +|  [Session persistence](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-load-balancer/#enabling-session-persistence) |{{}} |{{}} |{{}} | +|  [Active health checks](https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/) | |{{}} |{{}} | +|  [DNS service-discovery integration](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#service) | |{{}} |{{}} | +|**Content Cache** |**NGINX Open
Source** |**NGINX Plus
 ** |**NGINXaaS
for Azure** | +|  [Static and dynamic content caching](https://docs.nginx.com/nginx/admin-guide/content-cache/content-caching/)|{{}} |{{}} |{{}} | +|  [Cache-purging API](https://docs.nginx.com/nginx/admin-guide/content-cache/content-caching/#purging-content-from-the-cache) | |{{}} | | +|  MQTT protocol support for IOT devices | |{{}} |{{}} | +|**Web Server and Reverse Proxy** |**NGINX Open
Source** |**NGINX Plus
 ** |**NGINXaaS
for Azure** | +|  Origin server for static content |{{}} |{{}} |{{}} | +|  Reverse proxy: [HTTP](https://nginx.org/en/docs/http/ngx_http_proxy_module.html), [FastCGl](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html),
  [memcached](https://nginx.org/en/docs/http/ngx_http_memcached_module.html), [SCGI](https://nginx.org/en/docs/http/ngx_http_scgi_module.html), [uwsgi](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html) |{{}} | {{}} |{{}} | +|  [HTTP/2 gateway](https://www.nginx.org/en/docs/http/ngx_http_v2_module.html) |{{}} |{{}} |{{}} | +|  [gRPC proxy](https://nginx.org/en/docs/http/ngx_http_grpc_module.html) |{{}} |{{}} |{{}} | +|  [HTTP/2 server push](https://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_push) |{{}} |{{}} |{{}} | +|  [HTTP/3 over QUIC](https://nginx.org/en/docs/http/ngx_http_v3_module.html) |{{}} |{{}} |{{}} | +|**Security Controls** |**NGINX Open
Source** |**NGINX Plus
 ** |**NGINXaaS
for Azure** | +|  [HTTP basic authentication](https://www.nginx.org/en/docs/http/ngx_http_auth_basic_module.html) |{{}} |{{}} |{{}} | +|  [HTTP authentication subrequests](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html) |{{}} |{{}} |{{}} | +|  [IP address-based access control lists](https://nginx.org/en/docs/http/ngx_http_access_module.html) |{{}}|{{}} |{{}} | +|  [Rate limiting](https://blog.nginx.org/blog/rate-limiting-nginx) |{{}} |{{}} |{{}} | +|  Dual-stack RSA/ECC SSL/TLS offload |{{}} |{{}} |{{}} | +|  TLS 1.3 support |{{}} |{{}} |{{}} | +|  [JWT authentication](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html) | |{{}} |{{}} | +|  OpenID Connect single sign-on
  (SSO) | |{{}} |{{}} | +|  Internal redirect | |{{}} | | +|  NGINX as a SAML Service Provider | |{{}} |{{}} | +|  [NGINX App Protect WAF](https://www.f5.com/products/nginx/nginx-app-protect) (additional cost) | |{{}} |{{}} | +|  [NGINX App Protect DoS](https://www.f5.com/products/nginx/nginx-app-protect) (additional cost) | |{{}} | | +|**Monitoring** |**NGINX Open
Source** |**NGINX Plus
 ** |**NGINXaaS
for Azure** | +|  Export to [external monitoring tools](https://docs.nginx.com/nginx/admin-guide/monitoring/live-activity-monitoring/) |{{}} |{{}} |Export metrics to
Azure Monitor | +|  Built-in dashboard | |{{}} |[Azure Monitor](https://learn.microsoft.com/en-us/azure/azure-monitor/overview)
and [Azure Portal](https://azure.microsoft.com/en-us/get-started/azure-portal) | +|  [Extended status with 100+
  additional metrics](https://docs.nginx.com/nginx/admin-guide/monitoring/live-activity-monitoring/) | |{{}} |{{}} | +|  Native Open Telemetry Tracing | |{{}} | | +|**High Availability (HA)** |**NGINX Open
Source** |**NGINX Plus
 ** |**NGINXaaS
for Azure** | +|  [Active-active](https://docs.nginx.com/nginx/admin-guide/high-availability/) | |{{}} |{{}} | +|  [Active-passive](https://docs.nginx.com/nginx/admin-guide/high-availability/) | |{{}} | Not Applicable | +|  [Configuration synchronization
  across cluster](https://docs.nginx.com/nginx/admin-guide/high-availability/configuration-sharing/) | |{{}} |{{}} | +|  [State sharing](https://docs.nginx.com/nginx/admin-guide/high-availability/zone_sync/): sticky-learn session
  persistence, rate limiting, key-value
  stores | |{{}} |{{}} | +|**Programmability** |**NGINX Open
Source** |**NGINX Plus
 ** |**NGINXaaS
for Azure** | +|  [NGINX JavaScript module](https://www.f5.com/company/blog/nginx/harnessing-power-convenience-of-javascript-for-each-request-with-nginx-javascript-module) |{{}} |{{}} |{{}} | +|  [NGINX Plus API for dynamic
  reconfiguration](https://docs.nginx.com/nginx/admin-guide/load-balancer/dynamic-configuration-api/) | |{{}} | | +|  [Key-value store](https://nginx.org/en/docs/http/ngx_http_keyval_module.html) | |{{}} |{{}} | +|  Dynamic reconfiguration without
  process reloads | |{{}} | | +|**Streaming Media** |**NGINX Open
Source** |**NGINX Plus
 ** |**NGINXaaS
for Azure** | +|  Live streaming: RTMP, HLS, DASH |{{}} |{{}} |{{}} | +|  VOD: Flash (FLV), MP4 |{{}} |{{}} |{{}} | +|  Adaptive bitrate VOD: [HLS](https://nginx.org/en/docs/http/ngx_http_hls_module.html), [HDS](https://nginx.org/en/docs/http/ngx_http_f4f_module.html) | |{{}} | | +|  [MP4 bandwidth controls](https://nginx.org/en/docs/http/ngx_http_mp4_module.html) | |{{}} | | +|**Third-party ecosystem** |**NGINX Open
Source** |**NGINX Plus
 ** |**NGINXaaS
for Azure** | +|  [Ingress controller](https://www.f5.com/products/nginx/nginx-ingress-controller) |{{}} |{{}} | | +|  OpenShift Router |{{}} |{{}} | | +|  [Dynamic modules repository](https://www.f5.com/go/product/nginx-modules) | |{{}} |[Image-Filter](https://nginx.org/en/docs/http/ngx_http_image_filter_module.html)
[njs](https://nginx.org/en/docs/njs/)
[OpenTelemetry](https://nginx.org/en/docs/ngx_otel_module.html)
[XSLT](https://nginx.org/en/docs/http/ngx_http_xslt_module.html) | +|  Deployable as a service | | |Microsoft Azure | +|  [Commercial support](https://my.f5.com/manage/s/article/K000140156/) | |{{}} |{{}} | +{{
}} diff --git a/content/nginxaas-azure/overview/overview.md b/content/nginxaas-azure/overview/overview.md new file mode 100644 index 000000000..f3804c00d --- /dev/null +++ b/content/nginxaas-azure/overview/overview.md @@ -0,0 +1,67 @@ +--- +title: "Overview and architecture" +weight: 100 +categories: ["concepts"] +toc: true +docs: "DOCS-879" +--- + +## What Is F5 NGINX as a Service for Azure? + +NGINX as a Service for Azure is a service offering that is tightly integrated into Microsoft Azure public cloud and its ecosystem, making applications fast, efficient, and reliable with full lifecycle management of advanced NGINX traffic services. +NGINXaaS for Azure is available in the Azure Marketplace. + +NGINXaaS for Azure is powered by [NGINX Plus](https://www.nginx.com/products/nginx/), which extends NGINX Open Source with advanced functionality and provides customers with a complete application delivery solution. Initial use cases covered by NGINXaaS include L7 HTTP load balancing and reverse proxy which can be managed through various Azure management tools. +NGINXaaS allows you to provision distinct deployments as per your business or technical requirements. + +## Capabilities + +The key capabilities of NGINXaaS for Azure are: + +- Simplifies onboarding by leveraging NGINX as a service. +- Lowers operational overhead in running and optimizing NGINX. +- Simplifies NGINX deployments with fewer moving parts (edge routing is built into the service). +- Supports migration of existing NGINX configurations to the cloud with minimal effort. +- Integrates with the Azure ecosystem (Microsoft Entra, Azure Key Vault, and Azure Monitor). +- Addresses a wide range of deployment scenarios (HTTP reverse proxy, JWT authentication, etc). +- Adopts a consumption-based pricing to align infrastructure costs to actual usage by billing transactions using Azure. + +## Supported regions + +NGINXaaS for Azure is supported in the following regions: +{{< bootstrap-table "table table-striped table-bordered" >}} +| **North America** | **South America** | **Europe** | **Asia Pacific** | +|----------------------------------------------------------|--------------------------------------------|--------------------------------------------|-------------------------| +| West Central US
West US
East US 2
West US 2
West US 3
East US
Central US
North Central US
Canada Central | Brazil South | West Europe
North Europe
Sweden Central
Germany West Central | Australia East
Japan East
Korea Central
Southeast Asia
Central India
South India | +{{< /bootstrap-table >}} + + +## NGINXaaS architecture + +![The diagram illustrates the architecture of F5 NGINXaaS for Azure within a Microsoft Azure environment. It shows admins using Azure API/SDK, Azure Portal, Azure CLI, and Terraform to interact with the NGINX Plus component in the IaaS layer for edge routing. The diagram also depicts subnet delegation from the NGINX Plus component to a customer subscription, which includes Azure Key Vault, Azure Monitor, other Azure services, and multiple application servers (App Server 1, App Server 2, App Server N)](/nginxaas-azure/n4a-architecture.png) + +- Azure management tools (API, CLI, portal, terraform) work with NGINXaaS to create, update, and delete deployments +- Each NGINXaaS deployment has dedicated network and compute resources. There is no possibility of [noisy neighbor problems](https://learn.microsoft.com/en-us/azure/architecture/antipatterns/noisy-neighbor/noisy-neighbor) or data leakage between deployments + +### Redundancy + +With the Standard Plan, NGINXaaS uses the following redundancy features to keep your service available. + +- We run _at least_ two NGINX Plus instances for each deployment in an active-active pattern +- NGINX Plus is constantly monitored for health. Any unhealthy instances are replaced with new ones +- We use [Azure Availability Zones](https://learn.microsoft.com/en-us/azure/availability-zones/az-overview) + to protect your deployment from local failures within an Azure region. We balance NGINX instances across the possible availability zones in [supported regions](https://learn.microsoft.com/en-us/azure/availability-zones/az-overview#azure-regions-with-availability-zones) + +{{< note >}} If you are creating a public IP for your deployment, be sure to make them [zone redundant](https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) to get the best uptime. {{}} + +### Data plane traffic + +![The diagram illustrates the architecture of F5 NGINXaaS for Azure, showing end users accessing a public IP that routes through a network security group within a customer's Azure subscription. This leads to a delegated subnet in a virtual network, which connects to a zone-redundant load balancer within the NGINXaaS subscription. The load balancer distributes traffic across NGINX Plus instances in multiple availability zones, ensuring scalability and redundancy](/nginxaas-azure/n4a-data-plane-architecture.svg) + +NGINXaaS uses new Azure networking capabilities to keep end-user traffic private. Each NGINX Plus instance passes traffic to downstream services using an elastic network card (NIC) that exists inside your subscription. These NICs are injected into a delegated virtual network. A network security group controls traffic to your NGINX Plus instances. + +NGINX Plus instances are automatically upgraded to receive security patches and the latest stable NGINX Plus version. + +## What's next + +To get started, check the [NGINX as a Service for Azure prerequisites]({{< relref "/nginxaas-azure/getting-started/prerequisites.md" >}}) diff --git a/content/nginxaas-azure/quickstart/_index.md b/content/nginxaas-azure/quickstart/_index.md new file mode 100644 index 000000000..2698489ac --- /dev/null +++ b/content/nginxaas-azure/quickstart/_index.md @@ -0,0 +1,8 @@ +--- +title: Quickstart guides +weight: 600 +url: /nginxaas/azure/quickstart/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/quickstart/basic-caching.md b/content/nginxaas-azure/quickstart/basic-caching.md new file mode 100644 index 000000000..db27407d8 --- /dev/null +++ b/content/nginxaas-azure/quickstart/basic-caching.md @@ -0,0 +1,23 @@ +--- +title: "Enable content caching" +weight: 200 +categories: ["tasks"] +toc: true +docs: "DOCS-897" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) supports caching using the [ngx_http_proxy_module](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) module, improving performance by allowing content to be served from cache without having to contact upstream servers. For more information on caching with NGINX, see [NGINX Content Caching](https://docs.nginx.com/nginx/admin-guide/content-cache/content-caching/). + +## Configuring caching +```nginx +http { + # ... + proxy_cache_path /var/cache/nginx keys_zone=mycache:10m; +} +``` + +NGINXaaS for Azure only supports caching to `/var/cache/nginx`. This is because data at `/var/cache/nginx` will be stored in a separate [Temporary Disk](https://docs.microsoft.com/en-us/azure/virtual-machines/managed-disks-overview#temporary-disk). The size of the temporary disk is 4GB. + +## Limitations + +Currently, `proxy_cache_purge` might not work as expected because NGINXaaS [deploys multiple instances of NGINX Plus]({{< relref "/nginxaas-azure/overview/overview.md#architecture" >}}) for high availability. The `PURGE` request will be routed to a single instance, and only the matched values on that instance will be purged. diff --git a/content/nginxaas-azure/quickstart/geoip2.md b/content/nginxaas-azure/quickstart/geoip2.md new file mode 100644 index 000000000..f18b2a9f4 --- /dev/null +++ b/content/nginxaas-azure/quickstart/geoip2.md @@ -0,0 +1,59 @@ +--- +title: "GeoIP2" +weight: 700 +categories: ["tasks"] +toc: true +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) supports GeoIP2 using the [`ngx_http_geoip2_module` or `ngx_stream_geoip2_module`](https://github.com/leev/ngx_http_geoip2_module) dynamic modules, enabling NGINXaaS to implement various user differentiation strategies. For more information on GeoIP2 with NGINX, see [NGINX GeoIP2](https://docs.nginx.com/nginx/admin-guide/dynamic-modules/geoip2/). + +NGINXaaS uses your MaxMind license to download GeoIP2 databases, puts them in the right place before NGINX starts, and updates the databases daily to reduce your operational overhead. All GeoIP2 data is deleted once you stop using GeoIP2 or delete your deployment. MaxMind provides a variety of [databases](https://www.maxmind.com/en/geoip-databases), including a lower accuracy [free option](https://www.maxmind.com/en/geolite2/signup). NGINXaaS uses a modified form of [MaxMind's `geoipupdate`](https://github.com/maxmind/geoipupdate). + +## Configure + +To enable GeoIP2 you [update your NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview.md">}}) to include your MaxMind license and the relevant NGINX directives. + +1. Log into MaxMind and [generate a `GeoIP.conf`](https://dev.maxmind.com/geoip/updating-databases/#2-obtain-geoipconf-with-account-information) file. +2. Add the `GeoIP.conf` file to your NGINX configuration, using the exact path `/etc/nginx/GeoIP.conf`. The `GeoIP.conf` will be validated, and must include `AccountID`, `LicenseKey`, and `EditionIDs`. Other configuration options in `GeoIP.conf` are ignored. We recommend you enable the **Protected** {{}} toggle button to mark `GeoIP.conf` as a protected file, which will prevent the contents from being read via any Azure client tools. +3. Add the `load_module` directive - the modules are available at `modules/ngx_http_geoip2_module.so` or `modules/ngx_stream_geoip2_module.so`. +4. Add `geoip2` directives to your NGINX configuration as desired. The `EditionIDs` from your `GeoIP.conf` are available at `/usr/local/share/GeoIP` + +{{}}NGINXaaS for Azure currently only supports the database directory at the path `/usr/local/share/GeoIP`.{{}} + +There are many different ways to use the `geoip2` directives; For example: + +```nginx +load_module modules/ngx_http_geoip2_module.so; + +http { + # "GeoLite2-City" is one of the EditionIDs in /etc/nginx/GeoIP.conf + geoip2 /usr/local/share/GeoIP/GeoLite2-City.mmdb { + $geoip2_city_name city names en; + } + + server { + listen 80; + server_name localhost; + location / { + return 200 "Hello $geoip2_city_name"; + } + } +} +``` + +## Monitoring + +All licenses are [validated with MaxMind](https://dev.maxmind.com/license-key-validation-api/) when initially added to your deployment, but MaxMind licenses can expire or be manually revoked. + +To view the status of your MaxMind license, [enable monitoring]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}) for your NGINXaaS deployment and navigate to the Metrics tab. View the `nginxaas.maxmind` metric under the `nginxaas statistics` metric namespace. The `nginxaas.maxmind` metric reports the health of your license through the `status` dimension: + + {{}} + + | Status | Description | + | -------------- | ------------------------------------------------------------------------------------------ | + | `active` | The license is valid and in use to update GeoIP2 databases. | + | `unauthorized` | MaxMind returned an license error, which usually indicates an issue with the `GeoIP.conf`. | + + {{}} diff --git a/content/nginxaas-azure/quickstart/hosting-static-content.md b/content/nginxaas-azure/quickstart/hosting-static-content.md new file mode 100644 index 000000000..80ad24ec5 --- /dev/null +++ b/content/nginxaas-azure/quickstart/hosting-static-content.md @@ -0,0 +1,65 @@ +--- +title: "Hosting static content" +weight: 200 +categories: ["tasks"] +toc: true +docs: "DOCS-1344" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) supports hosting static content which allows users to serve static websites from their deployment. + +## Uploading static files as a tarball + +Follow the steps listed below to upload static content and relevant NGINX configuration using `tar`: + +1. Create an `nginx.conf` to configure your deployment to serve static content. The following is an example NGINX configuration: + +```nginx +http { + server { + listen 80; + location / { + root /srv; + index index.html; + } + } +} +``` + +2. Store your static files alongside the NGINX configuration. + +The following shows the structure of a directory containing an NGINX configuration and an `index.html` file that we will be served from the deployment. + +```bash +test-static-files $ tree . +. +├── nginx.conf +└── srv + └── index.html + +2 directories, 2 files +``` + +{{}}`index.html` is placed under the `srv` directory. When using `tar` to upload static content, the static content has to be placed under one of the allowed paths listed in the [NGINX Filesystem Restrictions table]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/#nginx-filesystem-restrictions" >}}).{{}} + +3. Create the tarball. + +```bash +test-static-files $ tar -cvzf /test.tar.gz * +``` + +4. Upload the tarball following instructions listed in the [NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#upload-gzip-nginx-configuration" >}}) documentation. + +5. After uploading the configuration, you should see the following files in your deployment: + - `nginx.conf` + - `srv/index.html` + +6. Browse to the deployment IP address, and you will see `index.html` being served from the deployment. + +## Uploading static files directly to the deployment + +You can also upload static files directly to the deployment. See [Adding NGINX Configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#add-nginx-configuration" >}}) to upload individual files to your deployment. Refer to the [NGINX Filesystem Restrictions table]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/#nginx-filesystem-restrictions" >}}) to see where files can be written to and read from. + +## Limitations + +NGINX Configuration payload larger than 3 MB is not supported. diff --git a/content/nginxaas-azure/quickstart/loadbalancer-kubernetes.md b/content/nginxaas-azure/quickstart/loadbalancer-kubernetes.md new file mode 100644 index 000000000..22e65d175 --- /dev/null +++ b/content/nginxaas-azure/quickstart/loadbalancer-kubernetes.md @@ -0,0 +1,377 @@ +--- +title: "NGINXaaS Load Balancer for Kubernetes" +weight: 250 +categories: ["tasks"] +toc: true +--- + +## Overview + +F5 NGINXaaS for Azure simplifies advanced Layer 4 and Layer 7 load balancing for Kubernetes clusters. With the NGINX Load Balancer for Kubernetes (NLK) feature, you can enable multi-cluster load balancing, failover, disaster recovery, and blue-green or canary deployments. + + + +```mermaid +flowchart TB + + Users[웃 Users] -.-> |GET '/tea' | NGINXaaS{NGINXaaS} + NGINXaaS -.-> P1 + NLK --> |Update upstream 'tea'| NGINXaaS + + subgraph AK[Azure Kubernetes Cluster] + TeaSvc{Tea svc} -.-> P2(Pod) + TeaSvc -.-> P1(Pod) + k8sapi[K8s API] --> |watch| NLK(NLK controller) + end + + style Users color:orange,stroke:orange,fill:#faefd9 + linkStyle 0,1 color:orange,stroke:orange + style NLK color:green,stroke:green,stroke-width:4px,fill:#d9fade + style NGINXaaS color:green,stroke:green,stroke-width:4px,fill:#d9fade + linkStyle 2 color:green,stroke:green + style AK fill:#9bb1de,color:# + style k8sapi color:#3075ff,stroke:#3075ff,stroke-width:4px + linkStyle 5 color:#3075ff,stroke:#3075ff + + accDescr: A diagram showing users sending GET requests to NGINXaaS, which proxies traffic to a Kubernetes-based service named "TeaSvc" running multiple pods in an Azure Kubernetes Cluster, with upstream configurations dynamically managed via an NLK controller watching the Kubernetes API. +``` + +The NLK controller monitors [Kubernetes Services](https://kubernetes.io/docs/concepts/services-networking/service/) and updates an [NGINX Upstream](https://nginx.org/en/docs/http/ngx_http_upstream_module.html) dynamically. NGINXaaS applies these updates immediately and keeps them in sync during scaling or upgrades. + +### Example use cases + +- You can use NGINXaaS for Azure to enforce rate limiting and application security with NGINX App Protect, then forward all accepted traffic to your Kubernetes applications. +- You can use NGINXaaS for Azure to receive traffic on `api.example.com` and route requests by URL path - for example, forwarding `/login` to a Kubernetes-based login service, `/graph` to a Kubernetes-hosted graph service, and `/process` to an application server on a standalone VM. + +## Getting Started + +This guide explains how to integrate NGINXaaS with an Azure Kubernetes Service (AKS) cluster. See [Advanced Configuration](#advanced-configuration) for options to customize the installation.. + +Before following the steps in this guide, you must: + +- Create an AKS cluster. +- Create an NGINXaaS deployment. See the [documentation]({{< relref "/nginxaas-azure/getting-started/create-deployment/deploy-azure-portal/" >}}) to deploy via the Azure portal. +- Ensure network connectivity between the subnet delegated to the NGINXaaS deployment and the subnet where AKS is deployed. For example, the AKS cluster and NGINXaaS deployment can run on the same Azure VNET or on peered VNETs. + +### Initial setup + +The steps in this section must be completed once for each new setup. We will install the NLK controller in the Kubernetes cluster and authorize that to send updates to the NGINXaaS deployment. + +1. Create an NGINXaaS data plane API key. +1. Look up the NGINXaaS data plane API endpoint. +1. Install the NLK controller. + +#### Create an NGINXaaS data plane API key + +{{}} +The data plane API key has the following requirements: +- The key should have an expiration date. The default expiration date is six months from the date of creation. The expiration date cannot be longer than two years from the date of creation. +- The key should be at least 12 characters long. +- The key requires three out of four of the following types of characters: + - lowercase characters. + - uppercase characters. + - symbols. + - numbers. + +A good example of an API key that will satisfy the requirements is UUIDv4. + +{{}} + +The data plane API key can be created using the Azure CLI or portal. + +##### Create an NGINXaaS data plane API key using the Azure portal + +1. Go to your NGINXaaS for Azure deployment. +1. Select **NGINXaaS Loadbalancer for Kubernetes** on the left blade. +1. Select **New API Key**. +1. Provide a name for the new API key in the right panel, and select an expiration date. +1. Select the **Add API Key** button. +1. Copy the value of the new API key. + +{{}} +Make sure to write down the key value in a safe location after creation, as you cannot retrieve it again. If you lose the generated value, delete the existing key and create a new one. +{{}} + +##### Create an NGINXaaS data plane API key using the Azure CLI + +Set shell variables about the name of the NGINXaaS you've already created: + +```bash +## Customize this to provide the details about my already created NGINXaaS deployment +nginxName=myNginx +nginxGroup=myNginxGroup +``` + +Generate a new random data plane API key: + +```bash +# Generate a new random key or specify a value for it. +keyName=myKey +keyValue=$(uuidgen --random) +``` + +Create the key for your NGINXaaS deployment: + +```bash +az nginx deployment api-key create --name $keyName --secret-text $keyValue --deployment-name $nginxName --resource-group $nginxGroup +``` + +#### NGINXaaS data plane API endpoint + +The data plane API endpoint can be retrieved using the Azure CLI or portal. + +##### View NGINXaaS data plane API endpoint using the Azure portal + +1. Go to your NGINXaaS for Azure deployment. +1. Select **NGINXaaS Loadbalancer for Kubernetes** on the left blade. +1. The data plane API endpoint associated with the deployment is available at the top of the screen. + +##### View NGINXaaS data plane API endpoint using the Azure CLI + +```bash +dataplaneAPIEndpoint=$(az nginx deployment show -g "$nginxGroup" -n "$nginxName" --query properties.dataplaneApiEndpoint -o tsv) +``` + +#### Install the NLK controller + +The NLK controller can be installed in your Kubernetes cluster using either Helm or the official [AKS Extension](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/f5-networks.f5-nginx-for-azure-aks-extension?tab=overview) available on the Azure Marketplace. + +##### Install the NLK controller using Helm + +Install the NLK controller using `helm install`. Be sure your kubectl context is pointed at the desired cluster. + +```bash +helm install nlk oci://registry-1.docker.io/nginxcharts/nginxaas-loadbalancer-kubernetes --version 1.0.0 \ + --set "nlk.dataplaneApiKey=${keyValue}" \ + --set "nlk.config.nginxHosts=${dataplaneAPIEndpoint}nplus" +``` + +##### Install the AKS Extension using the Azure CLI + +Install the NLK controller using `az k8s-extension`. + +```bash +## Customize this to provide the details about my already created AKS cluster +aksName=myCluster +aksGroup=myClusterGroup +az k8s-extension create \ + --name nlk \ + --extension-type "nginxinc.nginxaas-aks-extension" \ + --scope cluster \ + --cluster-name ${aksName} \ + --resource-group ${aksGroup} \ + --cluster-type managedClusters \ + --plan-name f5-nginx-for-azure-aks-extension \ + --plan-product f5-nginx-for-azure-aks-extension \ + --plan-publisher f5-networks \ + --release-namespace nlk \ + --config nlk.dataplaneApiKey=${keyValue} \ + --config nlk.config.nginxHosts=${dataplaneAPIEndpoint}nplus +``` + +##### Install the AKS Extension using the Azure portal + +You can also install the NLK controller AKS extension by navigating to [F5 NGINXaaS Loadbalancer for Kubernetes](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/f5-networks.f5-nginx-for-azure-aks-extension) in the Azure Marketplace and following the installation steps. + +- Select **Get it now**. +- Select **Continue** to proceed with the installation. +- On the **Basics** tab, provide the following information: + + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Subscription | Select the appropriate Azure subscription. | + | Resource group | Select the AKS cluster's resource group. | + {{}} + +- Select **Cluster Details**, and provide the AKS cluster name. You can select an existing AKS cluster or create a new one. +- Select **Application Details**, and provide the following information: + + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Cluster extension resource name | Provide a name for the NLK controller. | + | Installation namespace | Provide the AKS namespace for the NLK controller. | + | Allow minor version upgrades of extension | Select whether to allow the extension to be upgraded automatically to the latest minor version. | + | NGINXaaS Dataplane API Key | Provide the previously generated data plane API key value: `{keyValue}` | + | NGINXaaS Dataplane API Endpoint | Provide the previously retrieved data plane API endpoint value: `{dataplaneAPIEndpoint}nplus` | + {{}} + +- Select **Review + Create** to continue. +- Azure will validate the extension settings. This page will provide a summary of the provided information. Select **Create**. + +{{}} +The NGINXaaS data plane API that NLK uses is mounted at `${dataplaneAPIEndpoint}nplus`. For example, if the data plane API endpoint is `https://mynginx-75b3bf22a555.eastus2.nginxaas.net/` then the value for `nlk.config.nginxHosts` should be `https://mynginx-75b3bf22a555.eastus2.nginxaas.net/nplus`. +{{}} + +### Create an NGINX configuration with dynamic upstream + +You must define an [NGINX upstream](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream) that satisfies the following requirements for it to be managed by the NLK controller: + +- The upstream cannot have any servers listed in it specified via the `server` directive. The controller will manage the servers dynamically. +- The upstream must have a shared memory [zone](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#zone) defined. +- The upstream must have a [state](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#state) file declared. + +The following is an example NGINX Configuration that can be used: + +```nginx +http { + upstream my-service { + # NOTE: There are no servers defined here as they will be managed dynamically by the controller. + zone my-service 64K; # required + state /tmp/my-service.state; # required + } + + server { + listen 80; + location / { + proxy_pass http://my-service; + } + } +} +``` + +[Apply the NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/" >}}) to your deployment after making the required changes. + +### Create a Kubernetes Service + +Expose a Kubernetes `Service` to route traffic to your workload. The `Service` has the following requirements: + +- Add the annotation: `nginx.com/nginxaas: nginxaas` to mark the service to be monitored by NLK. +- Choose one of the following `Service` types: + - `NodePort`: To route external traffic into the cluster using a well defined port exposed on each AKS worker node. + - `ClusterIP`: To route traffic to pods directly if you are running an Azure Container Networking Interface (CNI) that lets you expose the pods on the Azure VNET. +- The port name must be formatted as `{{NGINX Context}}-{{NGINX upstream name}}`. For example: + - If the upstream is in the `http` context and named `my-service` then the name is `http-my-service` + - If the upstream is in the `stream` context and named `jet` then the port name is `stream-jet` + +The following example uses a service of type `NodePort`: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: my-service + annotations: + # Let the controller know to pay attention to this service. + # If you are connecting multiple controller the value can be used to distinguish them + nginx.com/nginxaas: nginxaas +spec: + # expose a port on the nodes + type: NodePort + ports: + - targetPort: http + protocol: TCP + # The port name helps connect to NGINXaaS. It must be prefixed with either `http-` or `stream-` + # and the rest of the name must match the name of an upstream in that context. + name: http-my-service + selector: + app: awesome +``` + +## Advanced Configuration + +### Controller Configuration + +| Helm Value | Description | Value | +|------------------------|----------------------------------------------------------|--------------------------------| +| `nlk.config.logLevel` | How verbose should the NLK controller logs be. | Possible values are `debug`, `info`, `warn`, `error`. Default: `info`. | +| `nlk.config.nginxHosts` | The NGINX Plus APIs to send upstream updates to. | Should be set to `{{dataplaneApiEndpoint}}nplus`.| +| `nlk.config.serviceAnnotationMatch` | The value to match on a Service's `nginx.com/nginxaas` annotation. Useful when configuring multiple NLK controllers to update separate NGINXaaS deployemnts. | Default: `nginxaas`. | +| `nlk.dataplaneApiKey` | The NGINXaaS data plane API key that will authorize the controller to talk to your NGINXaaS deployment. | | + +### Multiple AKS clusters + +A single NGINXaaS deployment can direct trafifc to multiple AKS clusters. Each AKS cluster needs its own copy of NLK installed and connected to NGINXaaS. + +```mermaid +flowchart TB + + TeaUsers[웃 Users] -.-> |GET /tea | NGINXaaS{NGINXaaS} + CoffeeUsers[웃 Users] -.-> |GET /coffee | NGINXaaS + NGINXaaS -.-> |GET /tea| E + H --> |Update upstream 'tea'| NGINXaaS + NGINXaaS -.-> |GET /coffee| K + M --> |Update upstream 'coffee'| NGINXaaS + + subgraph SG2[Azure Kubernetes Cluster 2] + k8sapi2[K8s API] --> |watch| M(NLK controller) + I{Coffee svc} -.-> J(Pod) + I -.-> K(Pod) + end + + subgraph SG1[Azure Kubernetes Cluster 1] + k8sapi1[K8s API] --> |watch| H(NLK controller) + D{Tea svc} -.-> E(Pod) + D -.-> F(Pod) + end + + + style TeaUsers color:red,stroke:red,fill:#faefd9 + linkStyle 0,2 color:red,stroke:red + style CoffeeUsers color:orange,stroke:orange,fill:#faefd9 + linkStyle 1,4 color:orange,stroke:orange + style NGINXaaS color:green,stroke:green,stroke-width:4px,fill:#d9fade + linkStyle 3,5 color:green,stroke:green + style SG1 fill:#9bb1de,color:# + style SG2 fill:#9bb1de,color:# + style k8sapi1 color:#3075ff,stroke:#3075ff,stroke-width:4px + style k8sapi2 color:#3075ff,stroke:#3075ff,stroke-width:4px + linkStyle 6,9 color:#3075ff,stroke:#3075ff + style H color:green,stroke:green,stroke-width:4px,fill:#d9fade + style M color:green,stroke:green,stroke-width:4px,fill:#d9fade + + accDescr:A diagram showing NGINXaaS directing separate user GET requests for `/tea` and `/coffee` to respective Kubernetes-based services "TeaSvc" and "CoffeeSvc" that are running in separate Azure Kubernetes Clusters. An NLK controller in each cluster is independently updating the NGINXaaS with dynamic upstream configuration. +``` + +{{}} +- Configuring multiple NLK controllers to update the same upstream isn't supported and will result in unpredictable behavior. +{{}} + +### Multiple NGINXaaS deployments + +Multiple NLK controllers can be installed in the same AKS cluster to update separate NGINXaaS deployments. + +Each NLK needs a unique helm release name and needs a unique helm value for `nlk.config.serviceAnnotationMatch`. Each NLK will only watch services that have the matching annotation. + +{{}} +- Consider using `helm` to install multiple NLK controllers on an AKS cluster. Installing multiple copies of the controller on the same AKS cluster is not supported via the [AKS Extension](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/f5-networks.f5-nginx-for-azure-aks-extension?tab=overview). +{{}} + +## Troubleshooting + +NGINXaaS Loadbalancer for Kubernetes and NGINXaaS continually monitor and attempt to repair in case of error. However, if upstreams are not populated as expected, here are a few things you can look for. + +### NLK controller logs + +The controller reports status information about the requests it is making to NGINXaaS. This is a good place to look to ensure that the controller has picked up your service and that it is communicating with NGINXaaS correctly. + +Run the following command to view the controller logs: `kubectl logs deployment/nlk-nginxaas-loadbalancer-kubernetes`. + +The logs can be made more verbose by setting the Helm value `nlk.config.logLevel` (see [Controller Configuration](#controller-configuration)). + +### Enable NGINX Upstream Update Logs + +NGINXaaS supports exporting dynamic upstream update logs to an Azure Storage account or to a Log Analytics workspace. + +To setup logging: +1. Select **Diagnostic settings** under **Monitoring**. +1. Select **Add diagnostic setting**. +1. On the following panel, provide a **Diagnostic setting name**. +1. Enable the **NGINX Upstream Update Logs** category. +1. Select a destination. + +For more information on logging, see [Enable NGINX Logs]({{< relref "/nginxaas-azure/monitoring/enable-logging/">}}). + +### Metrics + +NGINXaaS has the following metrics that are useful to monitor upstream health: + +- `plus.http.upstream.peers.state.up` -- does the peer report being healthy. +- `plus.http.upstream.peers.request.count` -- which peers are handling requests. + +See the [metrics catalog](../../monitoring/metrics-catalog) for the entire list of NGINXaaS metrics. diff --git a/content/nginxaas-azure/quickstart/njs-support.md b/content/nginxaas-azure/quickstart/njs-support.md new file mode 100644 index 000000000..c2bbe38a1 --- /dev/null +++ b/content/nginxaas-azure/quickstart/njs-support.md @@ -0,0 +1,41 @@ +--- +title: "Use the njs Scripting language" +weight: 400 +categories: ["tasks"] +toc: true +docs: "DOCS-874" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) supports the open-source [njs module](https://nginx.org/en/docs/http/ngx_http_js_module.html), allowing the extension of NGINX functionality with a subset of the Javascript language. + +## Upload NGINX configuration with njs + +Create an njs script file by uploading a gzipped tar file or create the script file in the editor. See [NGINX Configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md" >}}) for a step-by-step guide. + +{{}}If specifying an absolute file path as your njs script's `File path`, see the [NGINX Filesystem Restrictions table]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/#nginx-filesystem-restrictions" >}}) for the allowed directories the file can be written to.{{}} + +Switch between the language options to see syntax highlighting for NGINX configs or JavaScript. + +To use njs, enable the `ngx_http_js_module` module and specify the `js_import` directive with your njs file. + +```nginx +load_module modules/ngx_http_js_module.so; + +http { + js_import http.js; + + server { + location / { + js_content http.hello; + } + } +} +``` + +## njs validation + +NGINXaaS will not parse, evaluate, or run any provided njs scripts when validating the NGINX configuration. [Enable logging]({{< relref "/nginxaas-azure/monitoring/enable-logging/" >}}) to monitor errors caused by njs scripts. + +## "fs" module + +The njs [File System module](http://nginx.org/en/docs/njs/reference.html#njs_api_fs) provides operations with files. NGINXaaS only allows reading and writing from [specified directories]({{< relref "nginx-configuration.md#nginx-process-restrictions" >}}). diff --git a/content/nginxaas-azure/quickstart/rate-limiting.md b/content/nginxaas-azure/quickstart/rate-limiting.md new file mode 100644 index 000000000..0ef2405f9 --- /dev/null +++ b/content/nginxaas-azure/quickstart/rate-limiting.md @@ -0,0 +1,29 @@ +--- +title: "Enable rate limiting" +weight: 300 +categories: ["tasks"] +toc: true +docs: "DOCS-899" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) supports rate limiting using the [ngx_http_limit_req_module](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html) module to limit the processing rate of requests. For more information on rate limiting with NGINX, see [NGINX Limiting Access to Proxied HTTP Resources](https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/) and [Rate Limiting with NGINX and NGINX Plus](https://www.nginx.com/blog/rate-limiting-nginx/). + +## Configuring basic rate limiting + +```nginx +http { + #... + + limit_req_zone $binary_remote_addr zone=mylimit:10m rate=1r/s; + + server { + #... + + location /login/ { + limit_req zone=mylimit; + + } +} +``` + +{{}}As a prerequisite to using the `sync` parameter with `limit_req_zone` directive for rate limiting, enable [Runtime State Sharing with NGINXaaS for Azure]({{< relref "/nginxaas-azure/quickstart/runtime-state-sharing.md" >}}).{{}} diff --git a/content/nginxaas-azure/quickstart/recreate.md b/content/nginxaas-azure/quickstart/recreate.md new file mode 100644 index 000000000..8364638c7 --- /dev/null +++ b/content/nginxaas-azure/quickstart/recreate.md @@ -0,0 +1,65 @@ +--- +title: "Recreating a deployment" +weight: 500 +categories: ["tasks"] +toc: true +docs: "DOCS-1378" +--- + +Learn how to recreate an existing F5 NGINX as a Service for Azure (NGINXaaS) deployment using an Azure Resource Manager (ARM) template. + +There are two ways to replicate a current NGINXaaS for Azure deployment using ARM templates. You can either delete and recreate the deployment, or you can update the DNS to smoothly transition to the new deployment. + +## Prerequisites + +- [Azure CLI Installation](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) +- You need to be logged in to your Azure account through the CLI if you are using that for template deployment, see [Azure CLI Authentication](https://learn.microsoft.com/en-us/cli/azure/authenticate-azure-cli) + +## Export ARM template from existing deployment + +To export an ARM template for an existing deployment: + +1. Navigate to your existing NGINXaaS deployment. +1. Select **Export template** under **Automation** in the left menu. +1. Wait for the template to generate. +1. Select **Download**. + +## Delete and recreate strategy + +The simplest method to recreate a deployment is to delete the original deployment and then recreate it using the ARM template. + +The ARM template generated through the portal will include the VNET and public IP address used by the original deployment as dependencies. If you plan to change these with the new deployment these entries need to be modified in the template. + +To recreate the deployment: + +1. Export the template as instructed above. +1. Modify, if neccessary, and verify the data in the template for accuracy. +1. Delete the original deployment. +1. Use the exported ARM template to recreate the deployment using the Azure CLI: + +```bash +az deployment group create \ + --subscription= \ + --resource-group= \ + --template-file= +``` + +## DNS migration strategy + +If you control the DNS associated with the deployment's frontend and have flexibility of the IP address NGINXaaS uses you can recreate a deployment with no downtime. + +1. Export the template, as instructed above. +1. If you're using a public IP, create a new public IP resource. If you're using a private IP address, select a new IP address from your VNET. +1. Modify the ARM template to change the NGINXaaS deployment name and reference the new IP address. +1. Use the Azure CLI as above to create a new deployment. +1. Update DNS to refer to the new deployment's IP address. +1. Monitor metrics of the old deployment to watch for requests dropping off as clients use the new IP address from DNS. Note that depending on your DNS settings this could take from a few minutes to a few days. +1. Delete the old deployment. + +Remember to change your configuration on any firewall or Network Security Group associated with the deployment to allow access to your deployment's new IP address. + +## Further reading + +See the [Azure CLI Deployment Create](https://learn.microsoft.com/en-us/cli/azure/nginx/deployment#az-nginx-deployment-create) documentation for example commands to create deployment resources. + +You can find example code to manage NGINXaaS deployments and related objects in the NGINXaaS GitHub repository, [NGINXaaS Snippets](https://github.com/nginxinc/nginxaas-for-azure-snippets). diff --git a/content/nginxaas-azure/quickstart/runtime-state-sharing.md b/content/nginxaas-azure/quickstart/runtime-state-sharing.md new file mode 100644 index 000000000..99225e225 --- /dev/null +++ b/content/nginxaas-azure/quickstart/runtime-state-sharing.md @@ -0,0 +1,114 @@ +--- +title: "Runtime State Sharing" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-1499" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) supports runtime state sharing using the [Zone Synchronization module](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html) to synchronize shared memory zones across NGINXaaS instances. + +With runtime state sharing, NGINXaaS instances can share some state data between them, including: + +- [Sticky‑learn session persistence](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#sticky_learn) +- [Rate limiting](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html#limit_req_zone) +- [Key‑value store](https://nginx.org/en/docs/http/ngx_http_keyval_module.html#keyval_zone) + +{{}}`sync` parameter with a directive describing shared memory zones, cannot be added to an existing memory zone that was not configured to sync and cannot be removed from an existing memory zone that was configured to sync. To switch, consider removing the directive before reapplying it with the desired parameters.{{}} + +For information on enabling synchronization for rate limiting with NGINXaaS for Azure, please visit the [Rate Limiting]({{< relref "/nginxaas-azure/quickstart/rate-limiting.md" >}}) documentation. + +## Configuring runtime state sharing among NGINXaaS for Azure deployment cluster instances + +To enable runtime state sharing, edit the NGINXaaS deployment's NGINX configuration to create a server with the `zone_sync` directive in the top-level `stream` block. The `stream` `server` block containing the `zone_sync` directive should use a local resolver at `127.0.0.1:49153` and provide a `listen` directive with only a port for the TCP server. The chosen port should match the port used with `zone_sync_server` directive. NGINXaaS cluster instances should be identified using domain name `internal.nginxaas.nginx.com` and resolved using `resolve` parameter of the `zone_sync_server` directive. + +```nginx +stream { + resolver 127.0.0.1:49153 valid=20s; + + server { + listen 9000; # should match the port specified with zone_sync_server + + zone_sync; + zone_sync_server internal.nginxaas.nginx.com:9000 resolve; + } +} +``` + +{{}}To enhance security, set up security rules for both incoming and outgoing traffic in the virtual network linked to the NSG of the subnet hosting NGINXaaS for Azure deployment. These rules should limit TCP traffic to the `zone_sync_server` port.{{}} + +## Enable the SSL/TLS protocol for connections to another cluster instance of the NGINXaaS for Azure deployment + + To allow SSL connections between cluster instances, edit the NGINXaaS deployment's NGINX configuration to enable the `zone_sync_ssl` directive along with `zone_sync` directive in the top-level `stream` block. The `stream` `server` block containing the `zone_sync_ssl` directive should specify the `ssl` parameter with the `listen` directive for the TCP server. `ssl_certificate` and `ssl_certificate_key` directives can reference a Key Vault certificate attached to the deployment. + +```nginx +stream { + resolver 127.0.0.1:49153 valid=20s; + + server { + listen 9000 ssl; + + ssl_certificate /opt/ssl/server.crt; + ssl_certificate_key /opt/ssl/server.key; + + zone_sync; + zone_sync_server internal.nginxaas.nginx.com:9000 resolve; + zone_sync_ssl on; + } +} +``` + +## Enable verification of certificate of another cluster instance of the NGINXaaS for Azure deployment + +To enable verification of the cluster instance certificate edit the NGINXaaS deployment's NGINX configuration to enable the `zone_sync_ssl_verify` directive along with `zone_sync` directive in the top-level `stream` block and provide the `zone_sync_ssl_trusted_certificate` directive. `zone_sync_ssl_trusted_certificate` directive can reference a Key Vault certificate attached to the deployment. The `zone_sync_ssl_name` directive if used, should provide the `name` parameter as `internal.nginxaas.nginx.com`. + +```nginx +stream { + resolver 127.0.0.1:49153 valid=20s; + + server { + listen 9000 ssl; + + ssl_certificate /opt/ssl/server.crt; + ssl_certificate_key /opt/ssl/server.key; + + zone_sync; + zone_sync_server internal.nginxaas.nginx.com:9000 resolve; + + zone_sync_ssl on; + zone_sync_ssl_verify on; + zone_sync_ssl_trusted_certificate /opt/ssl/server_ca.pem; + } +} +``` + +## Set up certificate-based authentication across cluster instances of the NGINXaaS for Azure deployment + +To set up certificate-based authentication across the cluster instances edit the NGINXaaS deployment's NGINX configuration to enable the `ssl_verify_client` directive along with `zone_sync` directive in the top-level `stream` block and provide the `ssl_client_certificate` directive. `zone_sync_ssl_certificate`, `zone_sync_ssl_certificate_key` and `ssl_client_certificate` directives can reference a Key Vault certificate attached to the deployment. + +```nginx +stream { + resolver 127.0.0.1:49153 valid=20s; + + server { + listen 9000 ssl; + + ssl_certificate /opt/ssl/zone_sync.crt; + ssl_certificate_key /opt/ssl/zone_sync.key; + ssl_verify_client on; + ssl_client_certificate /opt/ssl/zone_sync_ca.pem; + + zone_sync; + zone_sync_server internal.nginxaas.nginx.com:9000 resolve; + + zone_sync_ssl on; + zone_sync_ssl_verify on; + zone_sync_ssl_trusted_certificate /opt/ssl/zone_sync_ca.pem; + + zone_sync_ssl_certificate /opt/ssl/zone_sync.crt; + zone_sync_ssl_certificate_key /opt/ssl/zone_sync.key; + } +} +``` + +Refer to [Runtime State Sharing](https://docs.nginx.com/nginx/admin-guide/high-availability/zone_sync/) for guidance on using other directives from the [Zone Synchronization module](https://nginx.org/en/docs/stream/ngx_stream_zone_sync_module.html) diff --git a/content/nginxaas-azure/quickstart/scaling.md b/content/nginxaas-azure/quickstart/scaling.md new file mode 100644 index 000000000..921380c52 --- /dev/null +++ b/content/nginxaas-azure/quickstart/scaling.md @@ -0,0 +1,135 @@ +--- +title: "Scaling guidance" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-989" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) supports manual and automatic scaling of your deployment, allowing you to adapt to application traffic demands while controlling cost. + +{{}}Scaling requires the Standard plan.{{}} + +An NGINXaaS deployment can be scaled out to increase the capacity (increasing the cost) or scaled in to decrease the capacity (reducing the cost). Capacity is measured in [NGINX Capacity Units (NCU)](#nginx-capacity-unit-ncu). + +In this document you will learn: + +* What an NGINX Capacity Unit (NCU) is +* How to manually scale your deployment +* How to enable autoscaling on your deployment +* What capacity restrictions apply for your Marketplace plan +* How to monitor capacity usage +* How to estimate the amount of capacity to provision + +## NGINX Capacity Unit (NCU) + +{{< include "/nginxaas-azure/ncu-description.md" >}} + +## Manual scaling + +To update the capacity of your deploymentv using the Azure Portal, + + 1. Select **NGINXaaS scaling** in the left menu. + 1. Select `Manual`. + 1. Set the desired number of NCUs. + 1. Click **Submit** to update your deployment. + +## Autoscaling + +With autoscaling enabled, the size of your NGINXaaS deployment will automatically adjust based on traffic requirements without the need to guess how many NCUs to provision. You must specify a minimum and maximum NCU count. NGINXaaS will maintain the size of the deployment ensuring the number of provisioned NCUs does not fall below the set minimum NCUs and does not grow beyond the maximum NCUs. Refer to the [Capacity Restrictions](#capacity-restrictions) when setting the minimum and maximum capacity. + +When creating a new NGINXaaS deployment with autoscaling enabled, the initial size of the deployment will match the minimum NCU count. + +To enable autoscaling using the Azure Portal, + + 1. Select **NGINXaaS scaling** in the left menu. + 1. Select `Autoscale`. + 1. Specify the minimum and maximum NCU count. + 1. Click **Submit** to enable NGINXaaS deployment autoscaling. + +### Scaling rules + +NGINXaaS automatically adjusts the number of NCUs based on "scaling rules." A scaling rule defines when to scale, what direction to scale, and how much to scale. NGINXaaS will evaluate the following scaling rules, in order, based on consumed and provisioned NCU metrics. + + - *Moderate Increase Rule*: Over the last 5 minutes, if the average consumed NCUs is greater than or equal to 70% of the average provisioned NCUs, increase capacity by 20%. + - *Urgent Increase Rule*: Over the last minute, if the number of consumed NCUs is greater than or equal to 85% of the number of provisioned NCUs, increase capacity by 20%. + - *Decrease Rule*: Over the last 10 minutes, if the average consumed NCUs is less than or equal to 60% of the average provisioned NCUs, decrease capacity by 10%. + +To avoid creating a loop between scaling rules, NGINXaaS will not apply a scaling rule if it predicts that doing so would immediately trigger an opposing rule. For example, if the the "Urgent Increase Rule" is triggered due to a sudden spike in traffic, but the new capacity will cause the "Decrease Rule" to trigger immediately after, the autoscaler will not increase capacity. This prevents the deployment's capacity from increasing and decreasing erratically. + +## Capacity restrictions + +The following table outlines constraints on the specified capacity based on the chosen Marketplace plan, including the minimum capacity required for a deployment to be highly available, the maximum capacity, and what value the capacity must be a multiple of. By default, an NGINXaaS for Azure deployment will be created with the corresponding minimum capacity. + +{{}} +| **Marketplace Plan** | **Minimum Capacity (NCUs)** | **Maximum Capacity (NCUs)** | **Multiple of** | +|------------------------------|-----------------------------|-----------------------------|----------------------------| +| Standard | 10 | 500 | 10 | +{{}} + +{{< note >}}If you need a higher maximum capacity, please [open a request](https://my.f5.com/manage/s/) and specify the Resource ID of your NGINXaaS deployment, the region, and the desired maximum capacity you wish to scale to.{{< /note >}} + +## Connection processing methods restrictions + +- NGINXaaS only supports the `epoll` connection processing method when using the `use` directive, as NGINXaaS is based on Linux. + +## Metrics + +NGINXaaS provides metrics for visibility of the current and historical capacity values. These metrics, in the `NGINXaaS Statistics` namespace, include: + +* NCUs Requested: `ncu.requested` -- how many NCUs have been requested using the API. This is the goal state of the system at that point in time. +* NCUs Provisioned: `ncu.provisioned` -- how many NCUs have been successfully provisioned by the service. + * This is the basis for [billing]({{< relref "/nginxaas-azure/billing/overview.md" >}}). + * This may differ from `ncu.requested` temporarily during scale-out/scale-in events or during automatic remediation for a hardware failure. +* NCUs Consumed: `ncu.consumed` -- how many NCUs the current workload is using. + * If this is under 60% of the provisioned capacity, consider scaling in to reduce costs. If this is over 70% of the provisioned capacity, consider scaling out; otherwise, requests may fail or take longer than expected. Alternatively, enable autoscaling, so your deployment can automatically scale based on the consumed and provisioned capacity. + * This value may burst higher than `ncu.requested` due to variation in provisioned hardware. You will still only be billed for the minimum of `ncu.requested` and `ncu.provisioned`. + +See the [Metrics Catalog]({{< relref "/nginxaas-azure/monitoring/metrics-catalog.md" >}}) for a reference of all metrics. + +{{< note >}}These metrics aren't visible unless enabled, see how to [Enable Monitoring]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}) for details.{{< /note >}} + +## Estimating how many NCUs to provision + +To calculate how many NCUs to provision, take the highest value across the parameters that make up an NCU: + +* CPU +* Bandwidth +* Concurrent connections + +Example 1: "I need to support 2,000 concurrent connections but only 4 Mbps of traffic. I need 52 ACUs." You would need `Max(52/20, 4/60, 2000/400)` = `Max(2.6, 0.07, 5)` = At least 5 NCUs. + +Example 2: "I don't know any of these yet!" Either start with the minimum and [adjust capacity](#adjusting-capacity) with the [iterative approach](#iterative-approach) described below, or [enable autoscaling](#autoscaling). + +In addition to the maximum capacity needed, we recommend adding a 10% to 20% buffer of additional NCUs to account for unexpected spikes in traffic. Monitor the [NCUs Consumed metric](#metrics) over time to determine your peak usage levels and adjust your requested capacity accordingly. + +### Iterative approach + +1. Make an estimate by either: + * using the [Usage and Cost Estimator]({{< relref "/nginxaas-azure/billing/usage-and-cost-estimator.md" >}}) + * compare to a [reference workload](#reference-workloads) +2. Observe the `ncu.consumed` [metric](#metrics) in Azure Monitor of your workload +3. Decide what headroom factor you wish to have +4. Multiply the headroom factor by the consumed NCUs to get the target NCUs. +5. [Adjust capacity](#adjusting-capacity) to the target NCUs +6. repeat from step 2 -- it is always good to check back after making a change + +*Example*: + +1. I am really unsure what size I needed so I just specified the default capacity, `20NCUs`. +2. I observe that my `ncu.consumed` is currently at `18NCUs`. +3. This is early morning, traffic. I think midday traffic could be 3x what it is now. +4. `18 * 3 = 54` is my target capacity. +5. I can see that I need to scale by multiples of 10 so I'm going to scale out to `60NCUs`. +6. At midday I can see that I overestimated the traffic I would be getting and it was still a busy day. We peaked at `41NCUs`, let me scale in to `50NCUs` to reduce my cost. + +### Reference workloads + +These reference workloads were all measured with a simplistic NGINX config proxying requests to an upstream. Keepalive between NGINX and upstream is enabled. Minimal request matching or manipulation is done. + +| **TLS?** | **Conn/s** | **Req/s** | **Response Size** | **Throughput** | **NCU** | +|:--------:|-----------:|----------:|------------------:|---------------:|--------:| +| no | 12830 | 13430 | 0KB | 23Mbps | 18.8 | +| no | 12080 | 13046 | 1KB | 125Mbps | 19 | +| no | 12215 | 12215 | 10KB | 953Mbps | 21 | +| no | 1960 | 1690 | 100KB | 1295Mbps | 23.6 | diff --git a/content/nginxaas-azure/quickstart/security-controls/_index.md b/content/nginxaas-azure/quickstart/security-controls/_index.md new file mode 100644 index 000000000..939fd72da --- /dev/null +++ b/content/nginxaas-azure/quickstart/security-controls/_index.md @@ -0,0 +1,9 @@ +--- +title: Security controls +weight: 500 +url: /nginxaas/azure/quicksart/security-controls/ +toc: true +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/quickstart/security-controls/auth-basic.md b/content/nginxaas-azure/quickstart/security-controls/auth-basic.md new file mode 100644 index 000000000..1c3542c7e --- /dev/null +++ b/content/nginxaas-azure/quickstart/security-controls/auth-basic.md @@ -0,0 +1,36 @@ +--- +title: Restricting access with HTTP basic authentication +weight: 100 +categories: [tasks] +toc: true +docs: "DOCS-990" +--- + +You can restrict access to resources by implementing username/password authentication using the "HTTP Basic Authentication" protocol. + +For more information on configuring HTTP Basic Authentication please refer to the [NGINX Plus Restricting Access with HTTP Basic Authentication](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/) documentation. + +## Uploading a password file + +F5 NGINX as a Service for Azure (NGINXaaS) accepts a file containing usernames and passwords using any of the password types specified in the [NGINX documentation](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic_user_file). The password file can be uploaded as a "protected file" when creating or updating your NGINX configuration to protect the file's contents from being read. The password file can alternatively be uploaded as a regular file. + +![Screenshot of the Azure portal showing the password file upload](/nginxaas-azure/auth-basic-htpasswd.png) + +## Configuring NGINX Plus for HTTP basic authentication + +Inside the location or server you are protecting, specify the [`auth_basic`](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic) directive giving a name to the password-protected area. Specify the [`auth_basic_user_file`](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html#auth_basic_user_file) directive referencing the password file. + +```nginx +location /protected { + auth_basic "Protected Area"; + auth_basic_user_file /opt/.htpasswd; +} +``` + +Submit the NGINX configuration to apply it. You should be prompted to log in when you access the protected location or server. + +{{}}The NGINX worker processes will open the password file. You must place the password file in a [directory the worker processes are allowed to read]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md#nginx-filesystem-restrictions" >}}) or else all authenticated requests will fail.{{}} + +- `/opt` +- `/srv` +- `/var/www` diff --git a/content/nginxaas-azure/quickstart/security-controls/certificates.md b/content/nginxaas-azure/quickstart/security-controls/certificates.md new file mode 100644 index 000000000..ff0a99319 --- /dev/null +++ b/content/nginxaas-azure/quickstart/security-controls/certificates.md @@ -0,0 +1,199 @@ +--- +title: "Use a certificate from Azure Key Vault" +weight: 50 +categories: ["tasks"] +toc: true +--- + +## Overview + +This tutorial walks through a complete example of using SSL/TLS certificates from Azure Key Vault in an F5 NGINX as a Service for Azure (NGINXaaS) deployment to secure traffic. In this guide, you will create all necessary resources to add a certificate to an NGINXaaS deployment using the [Azure portal](https://portal.azure.com/). + +## Create an Azure Key Vault (AKV) + +NGINXaaS enables customers to securely store SSL/TLS certificates in Azure Key Vault. If you do not have a key vault, follow these steps to create one: + +1. From the Azure portal menu, or from the **Home** page, select **Create a resource**. +1. In the Search box, enter **Key Vault** and select the **Key Vault** service. +1. Select **Create**. +1. On the Create a key vault **Basics** tab, provide the following information: + + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Subscription | Select the appropriate Azure subscription that you have access to. | + | Resource group | Specify whether you want to create a new resource group or use an existing one.
For more information, see [Azure Resource Group overview](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/overview). | + | Key vault name | Provide a unique name for your key vault. For this tutorial, we use `nginxaas-kv`. | + | Region | Select the region you want to deploy to. | + {{
}} + + For all other fields, you can leave them set to the default values. +1. Select **Review + Create** and then **Create**. + +## Create an NGINXaaS deployment + +If you do not have an NGINXaaS deployment, follow the steps in [Deploy using the Azure portal]({{< relref "/nginxaas-azure/getting-started/create-deployment/deploy-azure-portal.md" >}}). + +{{}} Your NGINXaaS deployment and your key vault must be in the same subscription. {{}} + +## Add an SSL/TLS certificate to your key vault + +Next, you can add an SSL/TLS certificate to your key vault by following [Azure's documentation to import an existing certificiate](https://learn.microsoft.com/en-us/azure/key-vault/certificates/tutorial-import-certificate?tabs=azure-portal), or you can generate a certificate. This tutorial will generate a self-signed certificate to quickly get started. + +1. Go to your key vault, `nginxaas-kv`. +1. Select **Certificates** in the left menu. +1. Select {{< fa "plus">}}**Generate/Import** and provide the following information: + + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Method of Certificate Creation | Select **Generate** | + | Certificate Name | Provide a unique name for your certificate. For this tutorial, we use `nginxaas-cert`. | + | Type of Certificate Authority (CA) | Select **Self-signed certificate**. | + | CN | Provide the IP address of your NGINXaaS deployment as the CN. For example, `CN=135.237.74.224` | + {{}} + + For all other fields, you can leave them set to the default values. + +1. Select **Create**. + +## Assign a managed identity to your NGINXaaS deployment + +In order for your NGINXaaS deployment to access your key vault, it must have an assinged managed idenity with the `Key Vault Secrets User` role. For more information, see [Assign Managed Identities]({{< relref "/nginxaas-azure/getting-started/managed-identity-portal.md" >}}) and [Prerequisites for adding SSL/TLS certificates]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md#prerequisites" >}}). + +1. Go to your NGINXaaS deployment. +1. Select **Identity** in the left menu. +1. Under **System assigned**, ensure the status is set to "On". + {{}} When you create a deployment through the Azure portal, a system-assigned managed identity is automatically enabled for your deployment. {{}} +1. Under **System assigned**, select **Azure role assignments**. +1. Select {{< fa "plus">}}**Add role assignment** and provide the following information: + + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Scope | Select **Key Vault**. | + | Subscription | Select the Azure subscription your key vault is in. | + | Resource | Select your key vault, `nginxaas-kv`. | + | Role | Select **Key Vault Secrets User**. | + {{}} + +1. Select **Save**. + +## Add your certificate to your NGINXaaS deployment + +Now, you can add your SSL/TLS certificate from your key vault to your NGINXaaS deployment. For more information, see [Add certificates using the Azure portal]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md">}}). + +1. Go to your NGINXaaS deployment. +1. Select **NGINX certificates** in the left menu. +1. Select {{< fa "plus">}}**Add certificate** and provide the following information: + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Name | A unique name for the certificate. For this tutorial, we use `my-cert`. | + | Certificate path | Set to `/etc/nginx/ssl/example.crt`. | + | Key path | Set to `/etc/nginx/ssl/example.key`. | + {{}} + +1. Select **Select certificate** and provide the following information: + + {{}} + | Field | Description | + |----------------------- | ---------------------------- | + | Key vault | Select `nginxaas-kv`. | + | Certificate | Select `nginxaas-cert`. | + {{}} + +1. Select **Add certificate**. + +## Reference your certificate in your NGINX configuration + +Once a certificate has been added to your NGINXaaS deployment, you can reference it in your NGINX configuration to secure traffic. Refer to [Upload an NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview.md">}}) to add and update NGINX configuration files to your NGINXaaS deployment. The following NGINX configurations show examples of different certificate use cases. + +### Use case 1: SSL/TLS termination + +NGINXaaS supports SSL/TLS termination by decrypting incoming encrypted traffic before forwarding it on to your upstream servers. + +```nginx +http { + upstream backend { + server backend1.example.com:8000; # replace with your backend server address and port + } + + server { + listen 443 ssl; + + ssl_certificate /etc/nginx/ssl/example.crt; # must match the Certificate path + ssl_certificate_key /etc/nginx/ssl/example.key; # must match the Key path + + location / { + proxy_pass http://backend; + } + } +} +``` + +For more information on using NGINX for SSL/TLS termination, see [NGINX SSL Termination](https://docs.nginx.com/nginx/admin-guide/security-controls/terminating-ssl-http/). + +### Use case 2: Securing traffic to upstream servers + +NGINXaaS supports backend encryption by encrypting traffic between your NGINXaaS deployment and your upstream servers. + +```nginx +http { + upstream backend { + server backend1.example.com:8443; # replace with your backend server address and port + } + + server { + listen 80; + + location / { + proxy_pass https://backend; + proxy_ssl_certificate /etc/nginx/ssl/client.crt; # must match the Certificate path + proxy_ssl_certificate_key /etc/nginx/ssl/client.key; # must match the Key path + } + } +} +``` + +For more information on using NGINX to secure traffic to upstream servers, refer to [Securing HTTP Traffic to Upstream Servers](https://docs.nginx.com/nginx/admin-guide/security-controls/securing-http-traffic-upstream/) and [Securing TCP Traffic to Upstream Servers](https://docs.nginx.com/nginx/admin-guide/security-controls/securing-tcp-traffic-upstream/). + +## Configure Network Security Perimeter (NSP) + +If you want to disable public access to your key vault, you can configure a [Network Security Perimeter (NSP)](https://learn.microsoft.com/en-us/azure/private-link/network-security-perimeter-concepts). This will allow you to configure access rules to allow NGINXaaS to fetch certificates from your key vault while ensuring all other public access is denied. + +{{}} Network Security Perimeter is currently in public preview. Refer to [Azure's NSP documentation](https://learn.microsoft.com/en-us/azure/private-link/network-security-perimeter-concepts) for details on its current capabilities. {{}} + +1. Follow [Azure's documentation on prerequisites](https://learn.microsoft.com/en-us/azure/private-link/create-network-security-perimeter-portal#prerequisites) to ensure you are registed to create an NSP. +1. In the Search box, enter **Network Security Perimeters** and select **Network Security Perimeters** from the search results. +1. Select {{< fa "plus">}}**Create**. +1. In the **Basics** tab, provide the following information: + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Subscription | Select the appropriate Azure subscription that you have access to. | + | Resource group | Specify whether you want to create a new resource group or use an existing one.
For more information, see [Azure Resource Group overview](https://docs.microsoft.com/en-us/azure/azure-resource-manager/management/overview). | + | Name | Provide a unique name for your network security perimeter. For this tutorial, we use `nginxaas-nsp`. | + | Region | Select the region you want to deploy to. Refer to any [regional limitations](https://learn.microsoft.com/en-us/azure/private-link/network-security-perimeter-concepts#regional-limitations) NSP has while in public preview. | + | Profile name | Leave the profile name as the default `defaultProfile`. | + {{
}} +1. In the **Resources** tab, select {{< fa "plus">}}**Add**. +1. Search for your key vault, `nginxaas-kv`, select it, and click **Select**. +1. In the **Inbound access rules** tab, select {{< fa "plus">}}**Add** and provide the following information: + {{}} + | Field | Description | + |---------------------------- | ---------------------------- | + | Rule Name | Set to `allow-nginxaas-deployment-sub`. | + | Source Type | Select **Subscriptions**. | + | Allowed sources | Select the subscription of your NGINXaaS deployment. | + {{}} +1. Select **Review + Create** and then **Create**. + +By default, the key vault will be associated to the NSP in [Learning mode](https://learn.microsoft.com/en-us/azure/private-link/network-security-perimeter-concepts#access-modes-in-network-security-perimeter). This means traffic will be evaluated first based on the NSP's access rules. If no rules apply, evaluation will fall back to the key vault's firewall configuration. To fully secure public access, it is reccommended to [transition to Enforced mode](https://learn.microsoft.com/en-us/azure/private-link/network-security-perimeter-transition#transition-to-enforced-mode-for-existing-resources). + +1. Go to resource `nginxaas-nsp`. +1. Select **Associated resources** in the left menu. +1. Select the `nginxaas-kv` resource association. +1. Select **Change access mode**, set to **Enforced**, and select **Apply**. + +{{}} If you are using the Azure portal to add certificates, you will also need to add an inbound access rule to allow your IP address, so the portal can list the certificates in your key vault. {{}} \ No newline at end of file diff --git a/content/nginxaas-azure/quickstart/security-controls/jwt.md b/content/nginxaas-azure/quickstart/security-controls/jwt.md new file mode 100644 index 000000000..24a6195b4 --- /dev/null +++ b/content/nginxaas-azure/quickstart/security-controls/jwt.md @@ -0,0 +1,77 @@ +--- +title: Setting up JWT authentication +weight: 200 +categories: [tasks] +toc: true +docs: "DOCS-1101" +--- + +F5 NGINX as a Service for Azure (NGINXaaS) provides the option to control access to your resources using JWT authentication. With JWT authentication, a client provides a JSON Web Token, and the token will be validated against a local key file or a remote service. This document will explain how to validate tokens using Microsoft Entra as the remote service. + +For more information on JWT authentication with NGINX+, please refer to [ngx_http_auth_jwt_module](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html) and [NGINX Plus Setting up JWT Authentication](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-jwt-authentication/). + +## Prerequisites + +- Set up a tenant, see [Quickstart: Set up a tenant](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-create-new-tenant). +- URL of the remote service (IdP). In this documentation, we are using Microsoft Entra Signing Keys URL: `https://login.microsoftonline.com/common/discovery/keys`. For more information, see [Signing key rollover in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/signing-key-rollover). + +## Configuring NGINX for JWT authentication + +1. To configure NGINX to use JWT for authentication, you will need to create a JWT that will be issued to a client. You can use your identity provider (IdP) or your own service to create JWTs. For testing purposes, you can create your own JWT, see [Get Microsoft Entra tokens for users by using MSAL](https://learn.microsoft.com/en-us/azure/databricks/dev-tools/app-aad-token) for details. If you wish to use your own local JSON Web Key (JWK) file for authentication, please upload it along with the NGINX configuration. Remember to respect the instance's filesystem restrictions and specify a location for the key file within one of the allowed directories. For details on uploading the configuration and file system restrictions, see [Upload an NGINX Configuration](https://docs.nginx.com/nginxaas/azure/getting-started/nginx-configuration/). + +2. Set up an NGINX `location` block that enables the JWT authentication and defines the authentication realm ("API" in the example) with the [auth_jwt](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt) directive. To verify the signature or decrypt the content of JWT, you will need to specify the JWT type using the [auth_jwt_type](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_type) directive, and provide the path to the corresponding JSON Web Key (JWK) file using the [auth_jwt_key_file](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_key_file) and/or [auth_jwt_key_request](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_key_request) directives. Specifying both directives simultaneously will allow you to specify more than one key source. If no directives are specified, JWS signature verification will be skipped. + +```nginx +server { + listen 80; + + location / { + auth_jwt "API"; + auth_jwt_key_file /srv/key.jwk; + auth_jwt_key_request /_jwks_uri; + } + + location = /_jwks_uri { + proxy_pass https://login.microsoftonline.com/common/discovery/keys; + subrequest_output_buffer_size 12k; + } +} +``` + +{{}} +When using the common Microsoft Entra signing keys you will need to increase the size of the subrequest output buffer as the key file will not fit in the default buffer. +If the buffer is not sized properly, requests will result in empty responses. If [error logging is enabled]({{< relref "/nginxaas-azure/monitoring/enable-logging/" >}}), you will see an error in the error log.{{}} + +Enabling JWT key caching is recommended to achieve optimal performance. This can be done with the [auth_jwt_key_cache](https://nginx.org/en/docs/http/ngx_http_auth_jwt_module.html#auth_jwt_key_cache) directive. Note that caching of keys obtained from variables is not supported. If you are using Microsoft Entra as an identity provider for JWT authentication, please be aware that [keys are rotated frequently](https://learn.microsoft.com/en-us/entra/identity-platform/signing-key-rollover), and it is recommended to take that into consideration before using it as a static file or caching the response from the subrequest. + +The full example of getting JWT authentication from a subrequest: + +```nginx +http { + upstream my_backend { + server 10.0.0.1; + server 10.0.0.2; + } + + server { + listen 80; + + location / { + auth_jwt "API"; + auth_jwt_key_file conf/key.jwk; + auth_jwt_key_request /_jwks_uri; + auth_jwt_key_cache 1h; + proxy_pass http://my_backend; + } + + location = /_jwks_uri { + internal; + proxy_method GET; + proxy_pass https://login.microsoftonline.com/common/discovery/keys; + subrequest_output_buffer_size 12k; + } + } +} +``` + +To learn more about configuring JWT in more complex scenarios such as claims validation, see [Arbitrary JWT Claims Validation](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-jwt-authentication/#arbitrary-jwt-claims-validation). diff --git a/content/nginxaas-azure/quickstart/security-controls/oidc.md b/content/nginxaas-azure/quickstart/security-controls/oidc.md new file mode 100644 index 000000000..eb4ebdd6c --- /dev/null +++ b/content/nginxaas-azure/quickstart/security-controls/oidc.md @@ -0,0 +1,171 @@ +--- +title: Set up OIDC authentication +weight: 300 +categories: ["tasks"] +toc: true +docs: "DOCS-1646" +--- + +## Overview + +Learn how to configure F5 NGINX as a Service (NGINXaaS) for Azure with OpenID Connect (OIDC) authentication. + +## Prerequisites + +1. Configure an NGINXaaS deployment with [SSL/TLS certificates]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/" >}}). + +2. Enable [Runtime State Sharing]({{< relref "/nginxaas-azure/quickstart/runtime-state-sharing.md" >}}) on the NGINXaaS deployment. + +3. [Configure the IdP](https://github.com/nginxinc/nginx-openid-connect/blob/main/README.md#configuring-your-idp). For example, you can [register a Microsoft Entra Web application](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) as the IdP. + + +## Configure NGINX as a Service for Azure with IdP + +Configuring NGINXaaS for Azure with OIDC is similar as [Configuring NGINX Plus](https://github.com/nginxinc/nginx-openid-connect/blob/main/README.md#configuring-nginx-plus) in [nginx-openid-connect](https://github.com/nginxinc/nginx-openid-connect) but it also has its own specific configurations that must be completed to work normally. + +1. If your IdP supports OpenID Connect Discovery (usually at the URI /.well-known/openid-configuration), use the `configure.sh` script in [nginx-openid-connect](https://github.com/nginxinc/nginx-openid-connect) to complete the configuration. Otherwise, follow [Configuring NGINX Plus](https://github.com/nginxinc/nginx-openid-connect/blob/main/README.md#configuring-nginx-plus) to complete the configuration. + +2. Configure NGINXaaS with specific configurations: + - `openid_connect_configuration.conf`: + + a. Set a proper timeout value for `map $host $zone_sync_leeway`. + + ```nginx + map $host $zone_sync_leeway { + # Specifies the maximum timeout for synchronizing ID tokens between cluster + # nodes when you use shared memory zone content sync. This option is only + # recommended for scenarios where cluster nodes can randomly process + # requests from user agents and there may be a situation where node "A" + # successfully received a token, and node "B" receives the next request in + # less than zone_sync_interval. + default 2000; # Time in milliseconds, e.g. (zone_sync_interval * 2 * 1000) + } + ``` + + b. Set a proper path for `proxy_cache_path`, see [Enable content caching]({{< relref "basic-caching.md" >}}). + + ```nginx + proxy_cache_path /var/cache/nginx/jwt levels=1 keys_zone=jwk:64k max_size=1m; + ``` + + c. Enable `sync` for the keyval memory zones and specify the state files to persist the current state across NGINX restarts. The state file paths are subject to [NGINX Filesystem Restrictions table]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/overview/#nginx-filesystem-restrictions" >}}) and must be placed in a directory accessible to the NGINX worker processes. + + ```nginx + keyval_zone zone=oidc_id_tokens:1M state=/opt/oidc_id_tokens.json timeout=1h sync; + keyval_zone zone=oidc_access_tokens:1M state=/opt/oidc_access_tokens.json timeout=1h sync; + keyval_zone zone=refresh_tokens:1M state=/opt/refresh_tokens.json timeout=8h sync; + keyval_zone zone=oidc_pkce:128K timeout=90s sync; # Temporary storage for PKCE code verifier. + ``` + + - `openid_connect.server_conf`: + + Remove the `location /api/` block, since NGINXaaS for Azure currently restricts access to the `api` directive. + ```nginx + location /api/ { + api write=on; + allow 127.0.0.1; # Only the NGINX host may call the NGINX Plus API + deny all; + access_log off; + } + ``` + + - Modify the root config file `nginx.conf` properly with `frontend.conf` content: + + a. Add `load_module modules/ngx_http_js_module.so;` near the top of the root config file, if it doesn't exist. + + b. Add `include conf.d/openid_connect_configuration.conf;` in the http block before the server block. + +
+ Example of nginx.conf using the localhost as a upstream server + + ```nginx + load_module modules/ngx_http_js_module.so; + + http { + + # This is the backend application we are protecting with OpenID Connect + upstream my_backend { + zone my_backend 64k; + # Reuse the localhost as a upstream server + # Modify to the real upstream server address if you have + server 127.0.0.1; + } + + # A local server block representing the upstream server for testing only + # Remove if you have the real upstream servers + server { + listen 80; + default_type text/html; + return 200 '

This is a site protected by OIDC!

\n'; + } + + # Custom log format to include the 'sub' claim in the REMOTE_USER field + log_format main_jwt '$remote_addr - $jwt_claim_sub [$time_local] "$request" $status ' + '$body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"'; + + # The frontend server - reverse proxy with OpenID Connect authentication + # + include conf.d/openid_connect_configuration.conf; + server { + include conf.d/openid_connect.server_conf; # Authorization code flow and Relying Party processing + error_log /var/log/nginx/error.log debug; # Reduce severity level as required + + listen 443 ssl; # Use SSL/TLS in production + ssl_certificate /etc/nginx/ssl/my-cert.crt; + ssl_certificate_key /etc/nginx/ssl/my-cert.key; + + location / { + # This site is protected with OpenID Connect + auth_jwt "" token=$session_jwt; + error_page 401 = @do_oidc_flow; + + #auth_jwt_key_file $oidc_jwt_keyfile; # Enable when using filename + auth_jwt_key_request /_jwks_uri; # Enable when using URL + + # Successfully authenticated users are proxied to the backend, + # with 'sub' claim passed as HTTP header + proxy_set_header username $jwt_claim_sub; + + # Bearer token is uses to authorize NGINX to access protected backend + #proxy_set_header Authorization "Bearer $access_token"; + + # Intercept and redirect "401 Unauthorized" proxied responses to nginx + # for processing with the error_page directive. Necessary if Access Token + # can expire before ID Token. + #proxy_intercept_errors on; + + proxy_pass http://my_backend; # The backend site/app + + access_log /var/log/nginx/access.log main_jwt; + } + } + } + + stream { + # Add localhost resolver for internal clustering hostname with resolver metrics collection + resolver 127.0.0.1:49153 valid=20s status_zone=stream_resolver_zone1; + + server { + listen 9000; + zone_sync; + zone_sync_server internal.nginxaas.nginx.com:9000 resolve; + } + } + ``` +
+ +3. Upload the NGINX configurations. See [Upload an NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/" >}}) for more details. + +4. In a web browser, open `https:///`. The browser will be redirected to the IdP server. After a successful login using the credentials of a user who has the authorization, the protected URI can be accessed. For example, using the `nginx.conf` in this guide, open `https:///` and complete the authentication. The browser will show: + + ```text + This is a site protected by OIDC! + ``` + +## Troubleshooting + +[Enable NGINX logs]({{< relref "/nginxaas-azure/monitoring/enable-logging/" >}}) and [Troubleshooting](https://github.com/nginxinc/nginx-openid-connect/tree/main?tab=readme-ov-file#troubleshooting) the OIDC issues. + +## Monitoring + +[Enable monitoring]({{< relref "/nginxaas-azure/monitoring/enable-monitoring.md" >}}), check [real time monitoring](https://github.com/nginxinc/nginx-openid-connect/blob/main/README.md#real-time-monitoring) to see how OIDC metrics are collected, and use "plus.http.*" metrics filtered with location_zone dimension in [NGINX requests and response statistics]({{< relref "/nginxaas-azure/monitoring/metrics-catalog.md#nginx-requests-and-response-statistics" >}}) to check the OIDC metrics. diff --git a/content/nginxaas-azure/quickstart/security-controls/private-link-to-upstreams.md b/content/nginxaas-azure/quickstart/security-controls/private-link-to-upstreams.md new file mode 100644 index 000000000..31c2a10ab --- /dev/null +++ b/content/nginxaas-azure/quickstart/security-controls/private-link-to-upstreams.md @@ -0,0 +1,232 @@ +--- +title: "Connect to upstreams with Azure Private Link" +weight: 400 +categories: ["tasks"] +toc: true +--- + +[Azure Private Link](https://learn.microsoft.com/en-us/azure/private-link/private-link-overview) eliminates exposure to the public internet by handling traffic over Microsoft's backbone network. This is especially useful if your NGINXaaS deployment and your upstreams are in different virtual networks. + +{{}}Depending on your use-case, we recommend using [virtual network peering](https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-peering-overview) instead of a Private Link service to maintain NGINX's load balancing capabilities.{{}} + +To set up a Private Link between your NGINXaaS deployment and your upstreams, you'll need two resources: + +- [Private Link service](https://learn.microsoft.com/en-us/azure/private-link/private-link-service-overview) +- [private endpoint](https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview) + +## Create a Private Link service + +A Private Link service is an Azure resource that enables Private Link access to your application. If your upstream is an Azure PaaS service (for example, Azure Storage), then you do not need a Private Link service. To create a Private Link service, + +1. Configure your upstream to run behind a Standard Load Balancer. +1. Add load balacing rules per upstream server port. +1. Create a Private Link service and attach it to the Standard Load Balancer. + +The following example demonstrates this process using an existing virtual machine as the upstream. + +
+Create a Private Link service - Azure CLI + +### Prerequisites + +- Resource Group +- Virtual Network +- Subnet +- Workload Virtual Machine + +Please ensure the following environment variables are exported before copying the below Azure CLI commands. + +{{}} + | Name | Description | + |------------------ | ----------------- | + | APP_LOCATION | Location of the resource group + | APP_RESOURCE_GROUP | Name of the resource group the virtual machine is in | + | APP_VNET_NAME | Name of the virtual network the virtual machine is in | + | APP_SUBNET_NAME | Name of the subnet the virtual machine is in | + | APP_VM_NAME | Name of the workload virtual machine | + | APP_NIC_NAME | Name of the network interface of the virtual machine | + | APP_IP_CONFIG_NAME | Name of the IP configuration associated with the NIC | +{{}} + +### Create a load balancer + +```bash +$ az network lb create \ + --resource-group $APP_RESOURCE_GROUP \ + --name load-balancer \ + --sku Standard \ + --vnet-name $APP_VNET_NAME \ + --subnet $APP_SUBNET_NAME \ + --frontend-ip-name frontend \ + --backend-pool-name backend-pool +``` + +### Create health probes and load balancing rules + +Depending on your NGINX configuration, you will need to add a load balancing rule and health probe for each port your upstream servers are listening on. For example, given the following NGINX configuration snippet, + +```nginx +upstream { + server 10.0.1.4:8000; +} +``` + +Create a health probe monitoring on port `8000`: + +```bash +$ az network lb probe create \ + --resource-group $APP_RESOURCE_GROUP \ + --lb-name load-balancer \ + --name 8000-probe \ + --protocol tcp \ + --port 8000 +``` + +Create a load balancing rule listening on port `8000`: + +```bash +$ az network lb rule create \ + --resource-group $APP_RESOURCE_GROUP \ + --lb-name load-balancer \ + --name 8000-rule \ + --protocol tcp \ + --frontend-port 8000 \ + --backend-port 8000 \ + --frontend-ip-name frontend \ + --backend-pool-name backend-pool \ + --probe-name 8000-probe \ + --idle-timeout 15 \ + --enable-tcp-reset true +``` + +### Configure the workload VM behind the load balancer + +```bash +$ az network nic ip-config address-pool add \ + --address-pool backend-pool \ + --ip-config-name $APP_IP_CONFIG_NAME \ + --nic-name $APP_NIC_NAME \ + --resource-group $APP_RESOURCE_GROUP \ + --lb-name load-balancer +``` + +### Disable network policy + +The `privateLinkServiceNetworkPolicies` setting must be disabled to add a private link service in a virtual network. + +```bash +$ az network vnet subnet update \ + --name $APP_SUBNET_NAME \ + --vnet-name $APP_VNET_NAME \ + --resource-group $APP_RESOURCE_GROUP \ + --disable-private-link-service-network-policies yes +``` + +### Create a private link service + +```bash +$ az network private-link-service create \ + --resource-group $APP_RESOURCE_GROUP \ + --name private-link-service \ + --vnet-name $APP_VNET_NAME \ + --subnet $APP_SUBNET_NAME \ + --lb-name load-balancer \ + --lb-frontend-ip-configs frontend \ + --location $APP_LOCATION +``` + +
+ +## Create a private endpoint + +A private endpoint is a network interface that connects to a service powered by Azure Private Link. To connect your NGINXaaS to your upstreams using a private endpoint, + +1. Add a new, non-delegated subnet in your NGINXaaS deployment's virtual network. +1. Create a private endpoint. +1. Update your NGINX configuration to reference the private endpoint. + +The following example demonstrates this process using an existing NGINXaaS deployment and a Private Link service. + +
+Create a private endpoint - Azure CLI + +### Prerequisites + +- Resource Group +- Virtual Network +- NGINXaaS deployment +- Private Link service + +Please ensure the following environment variables are exported before copying the below Azure CLI commands. + +{{}} + | Name | Description | + |------------------ | ----------------- | + | DEP_RESOURCE_GROUP | Name of the resource group the NGINXaaS deployment is in | + | DEP_VNET_NAME | Name of the virtual network the NGINXaaS deployment is in | + | PRIVATE_ENDPOINT_SUBNET_ADDRESS_SPACE | Desired address space of the private endpoint's subnet | + | PRIVATE_LINK_SERVICE_ID | Resource ID of the Private Link service | +{{}} + +### Create a new subnet + +You must create a new subnet for the private endpoint because the existing NGINXaaS deployment's subnet is already delegated. + +```bash +$ az network vnet subnet create \ + --resource-group $DEP_RESOURCE_GROUP \ + --vnet-name $DEP_VNET_NAME \ + --name subnet-priv-endpoint \ + --address-prefix $PRIVATE_ENDPOINT_SUBNET_ADDRESS_SPACE +``` + +### Create a private endpoint + +```bash +$ az network private-endpoint create \ + --connection-name connection-1 \ + --name private-endpoint \ + --private-connection-resource-id $PRIVATE_LINK_SERVICE_ID \ + --resource-group $DEP_RESOURCE_GROUP \ + --subnet subnet-priv-endpoint \ + --manual-request false \ + --vnet-name $DEP_VNET_NAME +``` + +### Update your NGINXaaS configuration with the private endpoint's IP address + +First, get the IP address of the private endpoint: + +```bash +$ export nic_id=$(az network private-endpoint show \ + --resource-group $DEP_RESOURCE_GROUP \ + --name private-endpoint \ + --query "networkInterfaces[0].id" \ + --output tsv) + +$ az network nic show \ + --ids $nic_id \ + --query "ipConfigurations[0].privateIPAddress" \ + --output tsv +``` + +Then, reference it in your NGINX configuration's upstream servers. For example: + +```nginx +upstream { + server :8000; +} +``` + +
+ + +## Additional Resources + +The following guides provide step-by-step instructions to create a Private Link service and a private endpoint with your preferred client tool: + + +* [Azure portal](https://learn.microsoft.com/en-us/azure/private-link/create-private-link-service-portal?tabs=dynamic-ip) +* [Azure CLI](https://learn.microsoft.com/en-us/azure/private-link/create-private-link-service-cli) +* [ARM template](https://learn.microsoft.com/en-us/azure/private-link/create-private-link-service-template) + diff --git a/content/nginxaas-azure/quickstart/security-controls/securing-upstream-traffic.md b/content/nginxaas-azure/quickstart/security-controls/securing-upstream-traffic.md new file mode 100644 index 000000000..51da538ec --- /dev/null +++ b/content/nginxaas-azure/quickstart/security-controls/securing-upstream-traffic.md @@ -0,0 +1,122 @@ +--- +title: "Securing upstream traffic" +weight: 300 +categories: ["tasks"] +toc: true +docs: "DOCS-1475" +--- + +Learn how to encrypt HTTP traffic between F5 NGINX as a Service for Azure (NGINXaaS) and an upstream group or a proxied server. To secure TCP traffic to upstream servers, follow the [NGINX Plus guide](https://docs.nginx.com/nginx/admin-guide/security-controls/securing-tcp-traffic-upstream/). As with securing HTTP traffic, you will need to [add the SSL/TLS client certificate]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md">}}) to the NGINXaaS deployment. + +### Prerequisites + +- [Add a SSL/TLS Certificate]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md">}}) to the NGINXaaS deployment. +- Enable [njs module]({{< relref "/nginxaas-azure/quickstart/njs-support.md">}}) if configuration uses njs directives. + +### Configuring NGINX + +[Add the client certificate and the key]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md">}}) that will be used to authenticate NGINX to the NGINXaaS deployment. Make a note of the filepaths you assign to the `Certificate path` and `Key path`. + +Next, change the URL to an upstream group to support SSL connections. In the NGINX configuration file, specify the “https” protocol for the proxied server or an upstream group in the `proxy_pass` directive: + +```nginx +location /upstream { + proxy_pass https://backend.example.com; +} +``` + +Add the client certificate and key to the NGINX config to authenticate NGINX on each upstream server with `proxy_ssl_certificate` and `proxy_ssl_certificate_key` directives using the filepaths noted above. NGINXaaS for Azure expects the directive's file arguments to match the filepaths assigned to a certificate and key that have been added to the NGINXaaS Deployment. + +```nginx +location /upstream { + proxy_pass https://backend.example.com; + proxy_ssl_certificate /etc/nginx/client.pem; + proxy_ssl_certificate_key /etc/nginx/client.key; +} +``` + +If you use a self-signed certificate for an upstream or your own CA, you may include this file by adding it to the [NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md">}}) and including the `proxy_ssl_trusted_certificate` directive. The file must be in the PEM format. Optionally, include the [`proxy_ssl_verify`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify) and [`proxy_ssl_verify_depth`](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_ssl_verify_depth) directives to have NGINX check the validity of the security certificates: + +```nginx +location /upstream { + # ... + proxy_ssl_trusted_certificate /etc/nginx/trusted_ca_cert.crt; + proxy_ssl_verify on; + proxy_ssl_verify_depth 2; + # ... +} +``` + +If your configuration is using the [njs module]({{< relref "/nginxaas-azure/quickstart/njs-support.md">}}), you can include the `js_fetch_trusted_certificate` directive to [verify](http://nginx.org/en/docs/njs/reference.html#fetch_verify) HTTPS certificates with the [Fetch API](http://nginx.org/en/docs/njs/reference.html#ngx_fetch). + +Toggle `yes` to include the CA file as proctectd file when using Azure Portal as show below: + +![Screenshot of the Azure portal showing the toggle for protected files](/nginxaas-azure/add-ca-as-protected-file.png) + +### Configuring upstreams + +Each upstream server should be configured to accept HTTPS connections. For each upstream server, specify a path to the server certificate and the private key [added to the NGINXaaS Deployment]({{< relref "/nginxaas-azure/getting-started/ssl-tls-certificates/ssl-tls-certificates-portal.md">}}) with `ssl_certificate` and `ssl_certificate_key` directives: + +```nginx +server { + listen 443 ssl; + server_name backend1.example.com; + + ssl_certificate /etc/ssl/certs/server.crt; + ssl_certificate_key /etc/ssl/certs/server.key; + #... + location /upstream { + proxy_pass http://url_to_app.com; + # ... + } +} +``` + +Specify the path to a trusted client CA certificate added to the [NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md">}}) with the `ssl_client_certificate` or `ssl_trusted_certificate` directives. The file should be in PEM format. + +```nginx +server { + #... + ssl_client_certificate /etc/ssl/certs/ca.crt; + ssl_verify_client optional; + #... +} +``` + +Complete example to secure your traffic between NGINX and upstream servers is available [here](https://docs.nginx.com/nginx/admin-guide/security-controls/securing-http-traffic-upstream/#complete-example). + +### Additional configuration + +If your keys specified in `proxy_ssl_certificate_key` use passphrase, then include the passphrases as file to the NGINX configuration and reference the file in `proxy_ssl_password_file`. It is recomended to use a protected file as an argument for this directive. + +```nginx +location /upstream { + proxy_pass https://backend.example.com; + proxy_ssl_certificate /etc/nginx/client.pem; + proxy_ssl_certificate_key /etc/nginx/client.key; + proxy_ssl_password_file pswd.txt; +} +``` + +You can also configure NGINX with a list of revoked certificates using `proxy_ssl_crl` directive. Include this file in PEM format in your NGINX configuration. + +```nginx +location /upstream { + # ... + proxy_ssl_crl /etc/nginx/revoked.crt; + # ... +} +``` + +`ssl_session_ticket_key` directive specifies a file with the secret key used to encrypt and decrypt TLS session tickets. To use these directives in your config file, include a file to your [NGINX configuration]({{< relref "/nginxaas-azure/getting-started/nginx-configuration/nginx-configuration-portal.md" >}}) with 80 or 48 bytes of random data generated using `openssl` command, in your config bundle. For example, + +```nginx +http { + server { + ssl_certificate /etc/nginx/client.pem; + ssl_certificate_key /etc/nginx/client.key; + ssl_client_certificate /etc/nginx/ca.pem; + ssl_session_ticket_key keys; + } +} +``` diff --git a/content/nginxaas-azure/quickstart/upgrade-channels.md b/content/nginxaas-azure/quickstart/upgrade-channels.md new file mode 100644 index 000000000..cf31fb0de --- /dev/null +++ b/content/nginxaas-azure/quickstart/upgrade-channels.md @@ -0,0 +1,42 @@ +--- +title: "Upgrade channels" +weight: 150 +categories: ["tasks"] +toc: true +docs: "DOCS-1480" +--- + +## Overview + +Maintaining the latest version NGINX Plus, operating system (OS), and other software dependencies is a key feature offered by F5 NGINX as a Service for Azure (NGINXaaS). The **Upgrade Channel** is an upgrade path to which you can subscribe your NGINXaaS deployment to control the timing of software upgrades. The following channels are available: + +{{}} +| Channel | Description | +|-------------|---------------------------| +| preview | Selecting this channel automatically upgrades your deployment to the latest supported version of NGINX Plus and its dependencies soon after they become available. We recommend using this setting to try out new capabilities in deployments running in your development, testing, and staging environments. | +| stable | A deployment running on this channel will receive updates on NGINX Plus and its dependencies at a slower rate than the **Preview** channel. We recommend using this setting for production deployments where you might want stable features instead of the latest ones. This is the **default channel** if you do not specify one for your deployment. | +{{}} + +{{}} All channels will receive continuous updates related to OS patches, and security fixes. +{{}} + +## Availability of new features + +### NGINX Plus and related modules + +{{}} +| Channel | Availablity of NGINX Plus and related modules | +|-------------|-----------------------------------------------| +| preview | No sooner than 14 days of a new NGINX Plus [release](https://docs.nginx.com/nginx/releases/). | +| stable | No sooner than 45 days of a new NGINX Plus [release](https://docs.nginx.com/nginx/releases/). | +{{}} + +A new version of NGINX Plus and its related modules is first introduced to the **preview** channel, where it is goes through our acceptance testing. Once we have baked the software in the **preview** channel for a reasonable time, it is eventually graduated to the **stable** channel. The actual promotion timelines can vary, and you can view our [Changelog]({{< relref "/nginxaas-azure/changelog.md" >}}) for latest updates. + +## Changing the upgrade channel + +To change the upgrade channel on your deployment using the Azure Portal: + +1. Select **NGINX Upgrades** in the left menu. +1. Choose the desired **Upgrade Channel** from the dropdown menu. +1. Click **Submit**. diff --git a/content/nginxaas-azure/troubleshooting/_index.md b/content/nginxaas-azure/troubleshooting/_index.md new file mode 100644 index 000000000..f10607b28 --- /dev/null +++ b/content/nginxaas-azure/troubleshooting/_index.md @@ -0,0 +1,8 @@ +--- +title: Troubleshooting +weight: 700 +url: /nginxaas/azure/troubleshooting/ +menu: + docs: + parent: NGINXaaS for Azure +--- \ No newline at end of file diff --git a/content/nginxaas-azure/troubleshooting/migrate-from-standard.md b/content/nginxaas-azure/troubleshooting/migrate-from-standard.md new file mode 100644 index 000000000..970dd4b70 --- /dev/null +++ b/content/nginxaas-azure/troubleshooting/migrate-from-standard.md @@ -0,0 +1,51 @@ +--- +title: "Migrating from Standard to Standard V2" +weight: 200 +categories: ["tasks"] +toc: true +--- + +## Overview + +F5 NGINX as a Service for Azure (NGINXaaS) now supports in-place migration from Standard plan to the Standard V2 plan, we encourage you to upgrade your deployment to the Standard V2 plan as soon as possible. **The Standard plan is scheduled for retirement on May 1, 2025**. If you fail to migrate by May 1, 2025, your NGINXaaS deployment will stop receiving automatic updates that address critical security issues. + +The Standard V2 plan maintains the same price as the Standard plan for existing capabilities. Enabling new capabilities such as NGINX App Protect WAF or additional listen ports that were added as part of Standard V2 will incur additional charges. + +{{< note >}} We currently only support in-place migration from Standard plan to the Standard V2 plan. Please avoid updating your Basic plan deployments to Standard V2 plan using this guide. {{< /note >}} + +## Migration Steps + +### Using the Portal + +1. Go to the **Overview** page of the NGINXaaS deployment in the Azure portal. +2. Under **Essentials**, find the **Pricing Tier** and select **Click to Upgrade**. +3. Select the Standard V2 plan and select Submit. + +### Using Terraform + +1. Update the Terraform AzureRM provider to 4.6.0 or above. + +``` +terraform { + required_version = "~> 1.3" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = "~> 4.6.0" + } + } +} +``` + +2. Modify the SKU to `standardv2_Monthly` in the azurerm_nginx_deployment resource. +3. Run `terraform plan`. Look at the output of terraform plan to ensure that your NGINXaaS deployment is not being replaced. +4. Run `terraform apply` to upgrade the deployment. + +### Using Azure-cli + +Run the below command to update your NGINXaaS deployment. + +```bash + az nginx deployment update --name myDeployment --resource-group \ + myResourceGroup --sku name="standardv2_Monthly_gmz7xq9ge3py" +``` diff --git a/content/nginxaas-azure/troubleshooting/troubleshooting.md b/content/nginxaas-azure/troubleshooting/troubleshooting.md new file mode 100644 index 000000000..b91270425 --- /dev/null +++ b/content/nginxaas-azure/troubleshooting/troubleshooting.md @@ -0,0 +1,53 @@ +--- +title: "Get help" +weight: 100 +categories: ["tasks"] +toc: true +docs: "DOCS-882" +--- + +## Contact NGINX support + +To contact support about F5 NGINX as a Service for Azure (NGINXaaS): + +1. Go to your NGINXaaS deployment. + +2. Select **New Support request** in the left menu. + +3. Select **Raise a Support ticket**. + + ![Screenshot of the Azure portal showing the Raise support ticket button](/nginxaas-azure/raise-ticket.png) + +4. You will be redirected to **MyF5** to create a new case. Log in to MyF5 with your F5 account. + +{{< note >}}If you can't complete a deployment successfully, the "New support request" option won't be available on the left-hand navigation menu. To raise a support ticket, go to the [MyF5 portal](https://my.f5.com). {{< /note >}} + +5. Go to the **Case Management** section and select **Create new case**. + + ![Screenshot of the MyF5 portal showing the Create new case button](/nginxaas-azure/new-case.png) + +6. Select **NGINXaaS** in the Product dropdown. + + {{< img src="nginxaas-azure/create-case.png" alt="MyF5 Case form" >}} + +7. Complete the request with the relevant information about your issue, bug report, or feedback. If you are contacting us to report an issue, please include the following information, available in the **Properties** section of your deployment, for the support team to begin their investigation: + +- Location +- Date and time of the issue +- Resource ID + +![Screenshot of the Azure portal showing the Properties section](/nginxaas-azure/properties.png) + +8. Complete the **Additional information** and **Contact details** sections of your case and select **Submit**. + +## Update support contact information + +To provide or update the preferred support contact email: + +1. Go to your NGINX as a Service (NGINXaaS) for Azure deployment. + +2. Select **New Support request** in the left menu. + +3. Select the `Edit` Button next to the **Support Contact Email** field. + +4. Provide a new email address in the field and select **Submit**. diff --git a/layouts/index.html b/layouts/index.html index 1057533b2..37486508e 100644 --- a/layouts/index.html +++ b/layouts/index.html @@ -60,7 +60,7 @@

NGINX Gateway Fabric

@@ -69,7 +69,7 @@

NGINX Open Source

diff --git a/layouts/shortcodes/golden-star.html b/layouts/shortcodes/golden-star.html new file mode 100644 index 000000000..4f7eecce9 --- /dev/null +++ b/layouts/shortcodes/golden-star.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/layouts/shortcodes/icon-warning.html b/layouts/shortcodes/icon-warning.html new file mode 100644 index 000000000..e37033d75 --- /dev/null +++ b/layouts/shortcodes/icon-warning.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/nginxaas-azure/add-ca-as-protected-file.png b/static/nginxaas-azure/add-ca-as-protected-file.png new file mode 100644 index 0000000000000000000000000000000000000000..442f63bdd5a47fe920adfe177205e04cc4ce1ce6 GIT binary patch literal 50006 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
hTpDj(uM5qQKSvhpe3VH3 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

){?EbhG%Ct!(JXBqm61Sck8M3Uz#kBZj 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�AfQJ}|gUUtjl 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 FzW@Y#QV9S6 literal 0 HcmV?d00001 diff --git a/static/nginxaas-azure/diagnostic-settings.png b/static/nginxaas-azure/diagnostic-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..ece806c47267d1869022bfc9cf52d426e4040040 GIT binary patch literal 59283 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�+87Z%d-KJ^P2 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

4pE$;NP|Lm!~>C5r291 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 z z=7x`k=MKHuzMnDw(cXiIw^F>U^Ft&fXpX#@{C-LsFE35-@EKCAI<4xk_94bc8QZ$q zqOsLYev`-6G&gNKbPmd|&-Gm~!t3vGi~74Me@mz?8v7msECG%mD9%aa+nlIAIX0H7 zTQh+vd;a4kZ~EYn5E%7;%TyJdZmjAQ=HnYArK!+u%vhIy|9*cyGz<8GMDhvjk@VZ+ zo`)TjyyfH-<9(zc%*d~`D0Hr#N3So}L1qeM<%G&gw5Wjoy{SmGOzbuS&H{vEU4DLi ze6j3RTz7>tW87;$i?j5b$|LNTUB1?B!i9^NOP5_RZONtz?rJ}<6kskj<1KRM-vT@@ zJjC974|DNWAYZF zoeFb%s>C8b8w^RIL)R~Cpg!TBozA#!a>U+@z!KuDfeAx)))1=`Tv~=3%hszxTC693 zX4wr^fBO9ux3>lM>H~2XE^m8cz zMf{2L#XH$elH>Ia=0u}k%EfheY_g;T18w;)stZFO=5weP}q*KrE_&ke> zx}#4j#(8{wsc(ONC=>kYu3(?lzU1h2&d_%r*Q-V!JorVy3EFe_Ko_5vqb%46&CS){ z-gm~ldzWK9QELMrsBH6RhZcjy;$CSedW-P>KF0reY)G2eM!5~YhB|XnT7d@>N^6UHC8;?t!d#1jc-(+0~bhLfun=T?PK!ewI+y};Yb(en?*eR$i;of85o@2|V(fa4N zw)M@MMg|9WlKPeQ_%GK76qhm`rlNK}`I+Wk`B~q#(gyRjpswmeT#sspWn-{NVWiLK z_jiLxys-@D;K}iwRdNRUi@Cu^o~8+m+6v9DNdE9ogeBv}vB50;j#2}=E8?yqns_wf>3R0^BYX5c%x)9uZB8P_wzBI!PXt5FRuRePBxFEk5> z&xAzW6;DvHu@3_m5&JjFRJGhkQ$62bW7hcI&Isi%d{UMtLyfgHCl(hUC3~Hs-0Aix zSD&k?_M3|jM)Rivv#`^GEP?!or>PG0(J%t%*y7U$u&^fmQz_d-U?to391G(YIavvnO4l#yT8+GK)#<;K3M1Gubw zB00x87fR(JkyHK{bexGOIp=T9o2C~@yeV7NrJ&pL?8K}$4g|T}5bQ4uR2dLA zBqShe4HedP&(9~@E=bO|WZ5aeV(^isBV#k6w+jT4yNheP;X*_|c1LJf}rskiZ3RV#IT&pj2B zwb0=Wmf7LGv=bA*Kbv%|H-q$rzmD%oJ5j~;!PB$NAUk#PZPAMEi1PXv53Txx%Cg=m z)J|6$P;*f4rQJn+kmf;0bBo2T-nZB~8Wd=uR~xFSREfOjjT2F@zp!qAPiF z{mBYgS{V7UFf;e`_F9j%t~b=vkrjfWQ&EwVHu~!C;qJL?BqnC@Wv%Abo5xGzZw_mz zb8&LEt(F`V6RS9wwC{h1XnM$s_oANOFvtTYzbG-dV_*XQjQtoa-V%=pxS*+I*#3Ju zCmOeCwzl0sb4ewNVQadT=zl*bR^lrOnfm*?+voHnnMfP>-`_t8`->v|{iDV=|NnoJ zuFL;_9sXS^|L?BDdWfd3jFuM0c!*muQ26J+<(F^8RnM06_V`9~l?wP2K}yIVK7g`6 zI5=3|UmoUREx^Yo^7Z#W9B&5#MZ853VsD?LtP}I!8h8GNDpv_HgO(L^5Ux|LFo#sl zPtO}${JzVs07^)40IkR_hTR}5-7R_Xzwc3Yv=C@(Zfs1roAoX|Fr}`(p}`tB+9SKF zbz}cpF<8ofo9ZQv=j!s{%^lP&cID+x#@#PG4n5@r=JNN@)7XbotzI}g|I9OgDa3p3 zTnL}T(`V0665ajva`)t~0uh^@tG%vIrcRELS{Dri1D07CNy+Mo&K|+q`LVW{iM$mc zPaws)b#VOmktg)LBwMjBNs3&66AF0BHilaI`da$!1r8er!#l5EA$>)iUijaBaf5Z( zISi>}eNRcI2X2;On&^Wyn^q_}>4qHe=j^;{1L3Hj6B^LZaCI?%#=H!>Pf?xpnCWTyZv}P>7dTH`!mtTkx%zTuVK(H{93?C)EYacq zbFSq3_k5cfUPeI`HMM-~qS5164IQs(&;M`#kvl{s%9H1dDPGul(@-HewntnKV7DBE zOj9+*b`GtplM9;Y5WWpf9phbuO8TnlL~_AZK0pGimYvHVMA-MLjA4i{ z#fpH~ZM?APS>K1r0``VSQz5kh(Pr(T6~54F}s5#6JLIt$@>QBR)Sdf|NZp6mfExPbgdYuk`uv%bm>unM zuwQlpezW=FOd1n)$8 zRsF-1FCx9_7P>Z$+xY!=>_Y{&1QNrDLXET0l4}F+Ha?KhTo-s|v~h?`?o}M7UmjPP zCcVl*@fkXYI$1ypjJ;I-)A5iP(+|*RTdZxIZ6x(-V7b5Y@L*)ZzQV{kC}PRWw=g?P z#avrh>nVgkfN6URBGfPbw@1we`3@?9AiS2;X$QWW$FU1k$Bv2bgNeJbu_ouEKYNH9 z;>$5cXPKDdq$bt0c7Q(4d-klS@%IPO4AD+fJUslfy+}YKN~_8uWd&RlsN1W*T|M&w zWhP+O_Ys&*DkR;_0-O!ljnC;f-~S%KwD-;JOr_1uRwa@JMjh6*OdT0Ur*@l}kC>FP z4w{8T$veZMyIZ!7T+-~HcIEGs15`l^3TkTWty8@aQoNNtS^SlnJ#b^DM#Ss0fQKNNy!N~=)8c~#xn909$@|jFes#Ek z5l%Qo3NzCeUKziGC+}be2D$Uo{T0+3>ml^N^2|$0YabL9Kd(|&`L~+cqu={}zm>e4 z+;;b;?}vBH`kj_=uwZPe|H4()lFG`#k!&})Ggv0pczJmv+5GC&MTlX^t!MERw)3Wb z9{yyg^b(?!M8$kqRO^yv1vG!hSESQW=O0FK)*lezK_jeu=MH_KqO!8>e5KyB;$L^Q zJ;a#d_>FR442}jZ&gI}K>os#K1`W@cif$lm^(A(3)eSe1MTA! zm43O4hQ49fcKFax3q6EgidvqXR|%a6h3>U~7eZvRn}xEVO;Zyrv)gj4J#t=N-x{(D z{C@1@Ey-K!4@1*L8h*T0S(rd#leSzXm;ypi=2LN}8L0aBsx^D^#Sab%#84F`U=X@BYhHF1>4q*!j_BI1kXj(=gRPKLExXEX_ zwYt`GkFAoVGA2@D_N!h(I%f|Ru&VIt&KuSnJ{knqA;Y9aJ~%8a46N9I3UWvE56GGZ z8EGF$GgJ5502X?H)d`Jq-?-X7q`O^npUt+K)3>nTCg7Pk0XxO_M~@uAc?v&zsD4Hy zphEc3AIIC^^7Vk)7NU0ezlE{h6ynqmgi6X^>D};XNmy%|@7fXiNn88kTZ5!-)-=|GuZ8xE zg|W=~R-a;Fu>-5Gi}T(;=E$L*E3Jz%n>LFucz21mwbkO`LklVa|4YxdLdsd5EjM`W zzh^Bn-SLw2NiipGd9cgnb##806dzG@i;iZvE+!@+k?6jPSpkGTSy}wJ2Jn8z+y4v$ z{UaeYBrlc}Up{s3l&Y$5QNS73a#T*`m3M&M)nh}{C@8AQ&FllFFw_|?t2{mA)Y3$g->_V_@ucS{95Ghu~eiGZ&TkfWW+KvW%O9;E8Tc(TKE zSIN%K2YzvU*XRu z##V6Qk(y_07e|cGwdxC2BPq+HDnmR8vWk}_mx=`2cK@>9M&Jo+`4TohIGyV z|4ut>Y~4NK!*gfb(U4sz9Kmfb`F#c}kjtM{Z5FH}LNQ;fKUO;Gh^l)*!N!j+Ug9F& z9O*D|OdNTV_9yqav`F|Z+e2&H2_Tv?rY-sw`~jC|_|$G~c2r9rQHcq>`O$V;r2I=w zUE$2T#`o`k$j%mcR`g&z8_17>^EY0ky%dSXda(lMu2VZusSMx3(mCxoBmQQj4JS+2HAWok+U%7b<6My2B}tI0;)N- zJn%7BP^kIwy#m$U|kU-(THx**JK}7dnWzpd%9`yLP&Kal9ZYEu8 z1KTd;6YkOF6;Im93bDkTy!D3BLbVRlZPZOa}_mW?q=wI$Eoz3yG=~Jt2q9&JSy6-2H z?{`VHDv;(4)qb<`uKRupccfdJ4n}g&NHSqNk4=R0*TND0O+>YNW^FAGKYf7b9ucd` zLqw+8+!0Ah_U*XTcWf_xSfHyT9vVx(6llJ+{mq&44+RAWW&K(e<{H~lwhrw!kF)fv zb`G6371Sc@o|a1gaV(3W<;aOf{ZBsN#zdy~On(p~&LU5J;I$D^SX^v|2XJ=cb{^?8 z0Q97@^+A9#70|NuWW6)EGH{!RP?kgl)Guc9(W+mFK(|DaY)Rxu! zqMS{kp+=;_=Y8x<&Gg7Cp)&T;33`z9wARs)<)kO~d7XNxTeUhr5hmyzAeCB_%zW7> zNZdeyK((`pfZ6%#pA#*OsZSado+Y4Jh(ep_>)Tga8h|c#pRwg^>2Fk!gky$BO}XF4 zZv#whY+*urCkY`6`-B9Dx8&iqk6hSo1n^pa|EkvPGm+^IYOkPnP`6*t0)8D+6KWJa zl19#FvZa4;uq)5by0*J0QPHimuYR|vT(rP+S`|IjA?f4rmI!t5Zz;MVZD^u$UG}~# z&64l#172kxB*#xLOF|IknH+f>k0eZeCUt6tVV>1@;NumQmH3m5KQs+U6e`{mCr=(D zgt8x{R!)?DYu*w z5U~C2w1i#M@BzOT&)P?3Kl8e4^G>&sFF~ScF?{>+ZIfeO-j#|m_pvj)ywQbbodW<021hH|qOUGA3bc za+qLWUt9RPb@vfv-`HpexesRS?WJma;;CPRp>%6^_HCph&hqgY1a*4Re0U$tYw^{7 zZ3RUZ&W@JH|{< z%E=15Hne12F&^6V-)FDp3K0;f{rzlQx^1t^ls{{oCPIa5PM$cC9~pvx7zFtB4GeHw zT)Bk8dGGJvZEZUzN?Nz6m)pc$0cIj2BlFDNsX)>PejJan_a|H{Lvaa|XfMDjSec?%E7HDYv3mhdZ3QOnu&%rm4rnV;IgeR{!vXE9 zuHi;vIxqm$c6yy-1rjEL#_#$?KLzuUSF9Esj95Hnf{u3 z<5#L_)QcBC{64n)(^ZD4Y4xhri}>Jn5QF%SC2paa3@}sshPI#yQ*wA4Tr8mkLJZ5X zS(;E_NtAAHM%Y|SYihbubQh}L9=ElU z1-7Q%veurJ5~A@N44018mFS_N2eckr32}y$yr8zp5PQZL)F}rp@fou!P2bxsRRbP_ zklnIx&7gYTK@Dx~s|DPeJtDFLFkY|$`vfBB_WUO$@R?m(;{e7_Mm#I}l$O%5*m3R3 zsZ-uFE0fe0Y*uStjsS_#wr5pU?L2yk@96Rmf4ONgR4=FJo353-{NGIrKDLX1g0Io* zWz8Vsjs~H%g>1y)otIY~>=yp1xhI<+?;ZNOu&}T*XLWjJLy7;ItgLz4^Z}GNC!{bg zVw4Ol?42TsEsme<1Y+ow(Nc=;0nf~uC7x!{k?}h_x}K zD02fM&;lf>+9T$&uCDA?QFzVZ%NNdIki^25-+OX)Eyo%|+Y}hS@*3Hi-ki$Iu?A~G z_p#uqvwyPTi%US$A~1CAHZnD^9Xl*)?rn3e88lgcvY%L;ZID7%Zh^&U%UUqzkns0p zF)$ET&1-E9M0kkNuhpFRc;=w(R^MLjMI(3tr1vjh05M8F?C8iao_Zu?y?gh*^d=Q5 z0*+|FHRa)Yo#rO70CA!CHQQ@Hdb_)eiyhe3O$RE60k^@a0HlM~4#C*?IEK>B%Z__x61b>c|=T$m6*;eVPU+&1< zLEPm{L&Gr`Ua>E$b8&MgSaZzT%Z&N`w)DlxsTd<|Fo#f-1D;BmEjj%hKUJoWI#p+cIBEY;k}2i8*Tk}|M>^PAv8dcw!zo= zU@OhA(+zgAqnG65<^m!dmWE?KfVe&08RHSIruyV|Lw!9o%;W@%e9|mfX#2pHa;NFo z5VAW+oOw&%HjHQvY7QkXtFiOb7VW8e@Kt7JJ(KxxeKmEsfy}W;BSAUOb~W?!;QDff zbt;ET0KlvWPtRJwU0~^R_uME*m^u0FXR#JmBgpa=`c_QHZvO=$BVVVIZSbQd(@=#`Fyc~S}>C;e#31W|o4Ro)|V1GEsp^SBsWw&4~ zQlLtFdQhiDoHt!vgnR&^EQLfh*$qL(9jEzq^h71}MBQAS0=Gzk5q(XZ=_)T(h?=tW z6|44FT;yOn;L)HZj)ff?t;V)jb6SM`!>LN8t|xrD)nn-GA<#}%%=+?+rfEekapf*F z)+^=x6_AWycc+DKHG|79%?p_2@;~Y>td0DNIC8S?j-YeccJ{B$8{MvTL-ypRLV&Ac z>+9emz}_UznqynqStjSODn1t>@Emsj!=YWEquk#9Z!gET|Ci@y8T{6bJ<_DWKF@Z+ z9`;;6+zKFT&2bOix_c}+F77bzZ;ZH=lceln!lf}t=y553rLRLP*zIdn8@AMp1ZU=($}=N zgpS_~TJ*g5c-JZ&P-!&3zMvC&)D1n+-?K$?n&1kwG=Af@n&2n{{{vl=YUl zY~L;sv?}kL9&d=dWi0LI>f|)^k;cvU2(^_J_dbW56B)4-`nzwPz9ij&niCM2R^U@91|6ZL=aW2~l z_-mz+N-}W?@er9(jsjL$d3k#XqpLzJ-TVN|?)pP;t?>{t^PNb>#*u)_-9=emgAyr^$gSbI& ziUOW;OK)34j8pF#l&8B0L<9MH?R9vjW++X6Bhzw52X>FGi6||AH~|n?txC0x+CB6u z>LrBr&M%|Oegj)pKZ7}aV|Dc|qUUtTrR!!4?bC#(FN?jtQjL3B(x6gCJ1;${8t}Zi zpHcjfNOeg^jsdmDa6`V$+=w4smnK6t9z3}7qu;FT%-!vbTfP5$WR_oDSpe<;2k5Bl zD-?O!lidWVY_@QPk5onm@Z<^jjVEp0l5abw-*+P!@b@j5o6gFCRLX)=7lcvaMvvA; z_QL2(y}+L5VRzxd)=u14;w@ks38t$mDl0GP4kD1kzN489p=i>wviqxK!Sz&AtJdbK zs{EF4Nec?wrHOw+E^Kr6KS)qfZy2;~hsliGM|r7;`6_szKp$i``{$T|MQoql-s#if z)R(Zo)?*;>&1Ji`%p>gO zmuhkL&f`OC!Yj_YG$$+8utl1G(mFr)I>irozM z4S0bgg_T(^IO(WIiQVe?^Q_!sojI8>mI4?rpz6JLYfG_Ot?59YkgQLjY%t^s@VB^P$;-Id8uM`FE2N*^*!(^JHZ%$9#pC zSUqkw)qWh6?e7^TLgVxL#*2qpKcPDUmPtoo00kS#V_~6~yucYxRZWdOa~y0>wcKqv zmNN|71=S%|)X~Yz%Bm}R<}8X86UJ}XY%=JMVh8F$^{mHj;MvrOY>3yW2M2p^BDUowq2LP0Uje~gVQ$g?I^+U?9OIXO!tMZ-if&!TK&atC$sSM|R|j#rd+ ze}mSFm;Czc%|vIm<^Ch;xAx!tw3Uee_;HP6osES>1?BAT;^!bbmzwOlY_t=(eCRRd zJ>%q)?`Hk{DR?sH(5lU*dIq@GgWa=>SWVXy&Qm@mDn0v=fKB}lifPe|(|PQtL(AkZ z!=<#T+z+?2BV+O`4^Q6XVVTmIK?$Zmug`PXEZN}k-q?_=XxY4(Ok;$vVR?S^`c_vY zy9{-W`Vx+)QDJI=ch-1^H7IHmKeG}saQvt+d5uaGGX@g7+JNk7m|zaJ^}ZJ2!2I+`G8QA689j z0$-Ysc&mDLrlD1H#^4$|dQ5}^JSHL;&CAQH^@Aupef&a0S!H)bUbOAX&zqW>0>((k zsdZKBaxpCLRHDPT@lgF+4N{oU(fy?`qxD>x_x9XF_i+43o?u)cys0smK_OKg%Fot# zFft)Qe9J=;F}PM9*eiS#{pD#MfM5A!W?&98B;jm}rQtz!LIZcm$>0%pBekiT6P@rT z!XU)qhm60kucv=sb<)O2^2*}Wz0VLk%>4L5=VFj z2Vav(NJs<~g4A~Id6=mAQXvB6^i?mLXU1Lmei0GLA7CD8AjbGbTbnq}pikf;otN<@JbmJ}1S zgGg4-i??R0%|2}2cg^m>=E6up%c^RD%IEttD~-nw`CPC%Vmo4Z(5Fa?YqqiN$ryLD zJLmShItpL~_jHFD5{EiPI|5HBT<2vvdCCOhW9-{e`yszU_~hxhNwKjk=tBa}o1P>L ze=e##UM(=51xwy|ea(7VPf4k5M2-c|5{jaGDQ)NkU{#1pRVhcuQm$#^`pm7-H>Vn} zo=+zU43BadG+XmMbDBVw@#Lh)Escj^sf#NsNDWlSme`yy`CjFVpI;N$c>Gqgu|s00 zdbUw!9y|>5ydozQ_$nQ(c-06y%)_J92=y8)Z#*B~inNuJmruI;ITU_U@Yt1=^`VDi zwr|*n5qD$)%}4;d+g+tdqws(Wd3OAQIaKznZ(Q7UxPo?2vr~m;e(xw5gr_`Db zN{#2_j+z>$&Kr~D@VwdCxt^{PWV5G2dV&$@<-`)O$1(H+v~=N@8c1{IU(C}DJKHnE zs>foi&&B^)?~uYg;mL@h+p&S-IKf=1QJDwp&oUx>`<2eEGz)ZiHYzD9T8wCK3{;Jh z&kWi1$!zkU0LN(*fyx#c8z_NBn zdchM?T;IKt>Ps86R06uyKp{#vgTSc&b&TI^v8;g+J#RRliM`Q>okw{?%d|0hUwZYe zY2U&AfeB+hJw!dHU_uOUni243z&QE!WCf$%VIk}gF%ezBGr75Wa7!h_@boTD0USnh z($Fa1g-jVa*$#*9i`Zh5)prY7{OJZcyT7k5f5mvdI?Vp^{>q2vm01)L5hEimCABd# z*7oh&502q7X)jgo%54O%+O5~O_KN7qM`4D8^rJ1r>lcSj? z!WjY|LkVKj8{K7RF?nL{Ns|>j&?M~og2tSGoXh9dHQ?Het0gwwIWR_TwvbtXlk+`EiDZ?6$4E@CO@wI zJ-vwQ4hRU~Yj3e``_eDNloDA=#ew62JCwGXCyih_Y~<1L@WYuw-;bH+hKe8u=13Uw zVp3x{TLHlCmV|^~KtM)nD%JSL&*S?J$^nU_K3bvunUZprKQz0Yz-t|}bDRo_wD0W8 z%q}PhG1N=~EQNPFLGsDX%v7YIQT-|qpog1{4@cPy*79ruzuU}8|Lp4%HlUM3%d9xm zR6rX?zt60k`j|v1OA>9T=n6H*aLr44m!CgF-^@~OzVbEt=Pu8yG=okxgK+uM*42du zY;<%~?8{GsQ-HlI3jgY$RZ_L5-eEt0(rN>@AnKlM0Kbc?>oO*AI2vrkB>&5}#@o#K zAv`QXtKVOA*`G@Jp8iC=%x1}H+w-u*o)X!cyQ4((K9(B?x2lcVGVk2yCzCy9Xr^Xr z$)PfrC|mhn<_gBaUvp?kF!nppS7wnj#ld0nV|I9beO-d7ysOIrG2TXJ(`}|svI?y} zN3j_aVrS4IDx?0@=F-kIOIIa)Qf|+P$wEN^Rr~wHvK-F`9C9{D*C!gYe+yUbN+W zPR1D8kVp+K;Cv}Bj3(p#j`DK2J}$tV0Ewz?H_ zsflk{Fg28ZESVLQlpFoUa4lr}jZ&tKHM8Zo>siFv_A7Rs=Nok5&RmZ5(_kbqVT{^Q z1zQ<*$tx>U5ZGq_Oix=`SR`13o)XKV!0uyt99%bQHnpDq{-#Qv#3mT;DkLkHX>-BC zA5Oq<=mwymsd<8+q!BQL_*8D{0Rr~7J>K)$Mvrgp| zkxP70NEVKd=Sy)vV&@t4A|uD2^Li5b$csJt2mZPZEEit|5A>>Y$&YW*@1y$$`@Pc6 z`1$(6pix3X9J!Q3JtIAReRoaxZ)B5Zj~IP%_}sd8E-TLF0Bj2G`#mOZd*9RlSRVYK z!usqT3tm|({jSC`lf9RX=>C?uf0=B-d)ePY82^`=6MMKUwbD4gN2-Y`e+vb1u_#J{ z(&qZ#KSJxUN%@_Rk!AgG{I>?;VzH#F6jP?reLVs01$!v@NmQt9Y1ulH+A3j>vzh0( zONmlKtb$Cj&{Ok{^M<1AVtkgh+y8z}6OW03uI0$^Na{I)(my-zZj8wK&6^iCQ{8@i z>zBB5(lGBn(0+tH=IFh zLpp%SjV}Wff;PjtkJ=o#?jI7zH~5!ntoc-P*h~23>6D%=b?}oGNee6WsTm}}ZH4Pk zu)!tDy~G{D@&MM|98Vg9lRoRFLW;$g#Om{3D+G3kYk0=`7ZGm*%jd=WC36!}sOTJ} zq#rvTag8U7jqD2x{+Kb2*~XWYFO_VS07McB+MAkaCya?t_eawq^x(e!WaOH3@4zFWdGx}%Bm?-}5euPW4?6}iaraBXAe^{{Hb`9>&z8N zX%P}*C@A{kn2#2h;*ojQIe)c6SeKq>5D=J9z004G8rP z##RN5aeZ<9ucD_#8r%GSXmEj5c$o4UB6d-W0eQk)(|E!dc(MgQ66&ZT)YV{*g?A?e z|6~{CBoZ;LCicK)_3j;QjR&nss)EF$nE?qUJ-utTTL>zuKA%cTh7?Q>Z@Rb;8k5~` zQJ&rDzyO5)Gy_+lID}kr`MUouwiAsSReP*PB>&mcNVP6XcGg#0o2Kbdgk4?z#-@!3 ze#6KYo3@l5k@B|X89}OVy7tt`$eXr+_|Nc~gZmTj$D*FQZNE4$th*`m3Sf;*bMx|A z{mO+7mF@V$su4NZ>sUyF)YZjnJUctKoxlh-SWuUDt$uFwDTYLw9G^w?qJ$&U7;R=t ze)o<+GBov3**-!s#a2#VpSdj5*Y~Ow8G&&zqlZGW(mAvD0k@y;M$pOJ$btXHaMMY! z#vt7#&sm-;j4H(8Fc->$QPJH}0({jA~vMY$0t^MmfkW>-2wY{Vv z6c~*63=KmAeM!8(wyr0P!TcN?H6cZl z(u|C(Ea{t#j3itkx_xcG_Qp82O+ z8H!WJ5p4&F(6F$bJKYeZlB8b1PGx15^%EBPgk$n#V050;e>aAnylNj(<6fU5JL9VG zhniS5ppA4`CwJXMxEd`9%4Uh)s|KiHq>@26y10}{7O1}GU?JYX*M2$GQ)e!o&qPhc{+M_$ryiJSf>smn_X`VUC#Wy55dZvh7x92!U;`U@ z}oeQR2Q|jYIV)|B~(!uA=eLs zk4?Y(#jc|aOCA4vXsWI*?})8cRNj9-mEr86;{zhZmd&jLAu8tw{&944G{8D1KAAP? z3k>{2Y~A|ugUA}aFaL!L;TBE^13rfFMdJg7I5OoekCf{T|!>u|6?Xmvj#!?@C;=jpr-yLLWW|WHH0A4b%~i#V!Kg zogNPc?1F9w5#B-{_OwFoKL?TO(&O(xZM3ajxVvcA8>k+h4z0-UfUi z!j;ch1&DSJ3k%Ds&&>b(O&3c%_tUCH)9ZzA4@Y(gw^%DD`NMzK%LIH?k#vmB$Cgi5 z9ad3qD)Whow$cq=!&En-5g4B;-BVcNwUYpEOWOkD)*_Nt)2 z3lGZ|-tHPz(fydB)1W7)2+b?jx&UilP`WjtjY2?~&#T<)pR#eWXFC45*^UBZ0gKNf zFt8&dBU|zO{sCJuUJblQyVSJe(tnTlQY8Jw=@+Rh4f5gp-ljjfowh=oe&0%uAS@z5 z;*WNIcv_Hoc%+|DoRy8uP6GZC&|EJ}#Gi`NlJ%yh-lk;UO~4U_pbb33zagBpwKZLV z{}Fg+Jmsp@d%mrsNo%Y3NGv&Z&)FUV)#1Zv4b#-PE2Q{YZf#5bAemzS@|f3nzJmc; zb9eJ@-`PV!h~Z2eiQie;-hNe0#TLzf^sEW5U5-U9<^P^P&^=-D-}DjHRjhxRXO3^w z@buo4>@SA$*|Hlt6jMf6!=Ztpy6taY*;dQn{Bwtso{ny#$o(R=_UYSUZVsB;9d98D zz`%{}Ns7}LR9)-JN=`o36q9`S_<#YNB|yvYh99BooqV9awuZovpD#?HdOtNbt#Ya9 zn=5)@6>u+medNENL*LCItRP8$$MJ3YDTn8>dVXG@AhzDL6KL;%4rW z50Da#*9^%NqC$Z0-eQ!#WTNhVAX?5ag7BrKiSLOu|9!7P2UFEdBO?f&9Byy%^#H07$Adrnfe|?rbE|pX&lh_R78y35 z@l0x+IKeKGiGl8v&qtvSjQP0sCTz51tLqk56{X7UJzQAalb06oRWVVFk?=NVwKvKD z_C5{T@okTS-`f}V!&{9rGGuRE^MB8@vJ-`h`|BrN_Z1JEUd#&L_Ez6|2VsuySwiKT zv3RVDu0+v?jvWdPRii0dT#(r4PrGP;&_!#)@B?vjH80%})cSy7R= z7>5c>-s-zfI~++5rhxilt!uc>8dDOwFX{e!KeY_BgOY6b?K-7)hV_$G{-fjD=C<)h zUF)yyaCewF@3;4q;VEzLH`_)d1x?ZG9~|gbB1`o`VOHcxN4$((X@I|i6~mmjV*~;l zcCrxmJwLeHT90qQ&r*@t3P!i9#Pj@raf+s~wvHmlWywd`soDGWb`bQRj8@TEe|$zX zhA->~(nNb(lJFr}Oylg?l4Ab<8MCZ4ap*BD`9}NX$Bltks1J z?E}S83f!?5F|5Y1ct%PPo0a;YZ0+kSI!j{mO#l`#rlzLW)?@KQe3$6J6<|>fR%jIS zcMvRopCnGGcCq56q7oLM&jBpMG(&OD;+d%X_opF-#V`Ukyr9y2YWylUcN%Ok)~&HM zh$e<5B$yz=Lu!R~Cp7NAKE8PJBp(uEK0_2kKeVeTAWfjulo-+!h}Qy+i~#oZ?*I!0XI+N>Pah8G|p zJ*huDYtY<`pdSQ_jJ|A0P!K!?^=fx?b#}VBxJ>pHaHM>SM8h~Vw5g?qCeaX0I_!_f zhN|YThe2)X?y> zWN~GJ7W{CkF>jgVVmgzQC~* zdNBO=_AP+`&5U`quVBeKtZ8~08ot576Ni&dXSTmE6VI=bIB#jwQq z`+I71)DlbT5`@qY7oKvw0yQ0`>i^8oqXE9tA1)S?NcnAlerUAy^k79m*Au0{K8#kO zEz`y1xqt65@x#QQ6bzyi8-I|2CDOSqeuC( zEmh_B?W7J&s)@LKRc&_}m(v0(D=W^@j}sCOrsj7xH95ez8E}Y= zjSXxt%|JHzV*JSt!qEpzhYk%biP_rQgJ!8d!pj?#34AWd$9JyG)fU%Z|0Alk56Q<& z5s8IeM&I6|RntwDFU!x*SNi*u_dOolz<>$-%^dqCL6JcCjk~2DltkQxAYv8N_W)fR z6Yi;^{QQ;4%#@(oYT|EuEVH=$*>4{uB`Lwe!a}sO20kiqe$}zJ7H0g6?c29+lM=Ao zrH9_L=NX{$2d>2@1AMrJHew{?+aJ=O5}k!!o_6Pq`k6 zfrj__Hq2mpyR>u}p8BY92>;c4g$K7ZH^V5pyu2J!gE%PCJUl#D&Q?@(I=sR`79=JK z1^v>@aH97J=M5SRi6Z~tfp2@_w}oOHHA`5rggH6;><+>@7PoXfzq#=pZU&Bh!i3iz zzs|zO)Wjs=)-5FzR@k<}{hG22<9Rrm%*@Q&{6WJo?x_(jro{BD{l~{yd3o_?gEuxd zC@3f}ONWb%zX&H4Ze#XXFnN96Ds}EOA zr@FEX!66#nYpSia!kRjmwWDjakBrPx^wG%32y{}=)tVGJ;Ks`)bq)-8wWp~G&|@s@ zsDOX~JWLU2&sTV2iz}3HcTII*T|6`}kns2%n+|tpP0cm}ZgYEIU?7A76vMEB!DUuw z;Kib@rw}_J@WJO-9xFlw1YW>N3BQPvk`f1pZf()v{Q2pbnWO*O%vz_Wrl;XYf*veM zHCY<^E{B3v%;x-XXYAQ(K2JT%9i#X&b)y#+yNvx8`>So>Ty%2p6&3gNu z@njX|=d+6Zz%V4lB#(yxN@XY+N~b^t5TrgHijzUWi zXO#r5fdBf_nQz}DF82tyvSN-fwUfz*9t*Oc=_X>Y$Vin>h3|$}yZ<>X=*IYV%Qx&Z zg7IuNe6Do&$Z6bRWaHsM#IL~qj_9UUL_G z2W&<_r#lCbT7Bx6fPmxI`Y?R8avHhxQYxD2I zf@{pfxHycJ)Ip23dssd^6dJTSXE(Q->nkE!ll_G}h}Ez+cXP|J7Q)q`O5B`i=cvg< z@y$5}yL+#k<+hrCUJ2P6%F4<(m@0BH#S$nO93?9-2$`0qEDSOME6zaJp-D>al$McU zbMazUdU~CuFhrEtBBtM%h+Xe(RX#V7Ix$xa3|1reOW78e73V#Q?E>N|jv3THcu}~J z?j@KVM%N_fm!50?X(7aOS1pKvFaKJb`0}N|ra1;V76l!sYdkD;k&*C`dJLz=58+qf zgF{TG!z~8o36?Ha-ODKGcSP1h6@$@Z`Ups%FQNv=PfW}yQz=cf2e6{i%uMIRn6tDE zr>U9Qp^$Z= zu1RDlkzXxRFg8RSc`|~jx7OY6~uM5FYk$h z0jltv#!JLB95Qd?H&+siGy3`yBb9OlvvT(^1s{B3lsSYp98V67dr|JBfl613hTq&U zbQe-iKY3Ar9=1UzU^i)CK%9xh2gAb+IDoZ`c=696^_rOArS**AZo}V!$=(>)BiDU# zo+!*h@7~@Xa+OtR2+QSUv_swf^v|9}50MX>K#`B323}mXx_P|ouZsP}i{u32!Q9BD z+E5O@eH&Fbs+riJBsBLBpCCYJg{OSOOv0XBPoqCM*WEiyxMAIFy)c%AzcnXE+a9)S zXj{(eY;ZPQQZXGXk`axA#P}Bdr?t60X*V(WJRRYP%dnPJ<0WFx#qf>?bPd z%X|BQm#{@horQ=qsCP|#{kokvVu$LNI?*2eJ^~fA4R93Pw=WV|9FEKQX?Y-oEe_=0 zaisr#2{{Zxg5;*hDO%!-1`S6}$^*~|e?3zrr5eb?rJM#-OVjCTX-_3GoCQ1Rg$IS@@gQF8Ra)%X(7b0T}-9x5t486nscsEXCtH*S>SL0~$x z?<4~O5%TKL>*#yDILTPU>qTY<&zp3 znZSe!3JPejKvk9N#NhV*gA2m{)~3&i6VSy5pfk%!BP>b%sBWw|mM2Y!T(>C;8)2_r zMTd47UxPSa@*wBs%g=D5zj_rijzv@^ zfgd6&Vl2zdB>s{QA9N@~tnKZ2+zXDf!IpzSB`0A!Omi1IJ8-OOsx>@tgrQr2&p*Tk z=>LZfN14%QW@NPa2uL~hSzf&gCC4gI`_hs-4NWZ2=E~X{W`-#AUR=U>Mc%+9uTeN& zmS#G}hwU&f`ST;d`{>lvp@Rn#;^J&9Es2!@#=cNeVX=*Nj8F7y<$Re^YI`Mfb6<#- zz^frPRlj40sK5ZMt8Ma(3j*rC zAVOyW58$PuvcduPhPrm*MJ_o}91V@(f=Ge5o$!UmT;BT;t1dCvZQhi)~Oe=)%mBZkM(D`yzmTSLy zbo0->a>0_#$?eD>*?7m_TbXJGY1{+Fa+U0r$o|uH+b`)ndYpj8x+8$oB%NwPO>pVA zy>KBqDQTlcsJe~$Abwqu-Jo7j%m4t$l3GR(MAxY~If+S0g0$g{ z_4UN_XlmL^?-_Ga83Xq>aNRHAEMg+advyWuD+XhYbx?jFV1Ov-kb!Cw&XK(2Oms}+ zxToW{iis<94Cas~Ix|0E#_88xdNeYcGL!qkhtWfpmw$6_)e=Lyd~mwKkUc_j z&FnpVK>fycI3ut`YIrSl28K^hP1)Gmf||oPBgbh>p#)&@RR9TvX5ifF;txR7moHx` zIO#d4u7>;-`Gg;vBedo zJnDN8p4-O;c=`Cyw}_UpydlprNv$isL?i&BOa*cC14LqY%R>ZjoM4GEXiR&A*Q~i^ zzaS26z++t$GqU@_j!ee?1mysg)AVpf>6(c@b4*;owvWYqd^S!@K(Hywj$ue%w z96s;zA_`>a*HoWE`lqXab$40~I~9$__d=txUyfoPeAR?r6T%r9dpim3=KH~=fn&mc zVvG~pWBbO3v3ZnwpS+Xd{G!>6_Hcb&3zNSE4N;E+tUbG={Sb4lwQlW2tvGd5AlZNKxL&|uOHa2NFAHCesi@l%}pw0{!5rAdWH%Ie*=)F71Jx? z_Nd};OHIwDUI9e}fno<0d#D zlyF5pBZM7)fc_v>inZPN7biSH8=(@z;y1iJ7HVp?KZ~p!94hSevQr;WUc7%VDl7~w zDZ}{>lKA82Wp|c*Y3~>`JL`7L#_g2H@8&*i8N=JhRszx!xes>@G+rb~X9zz->gNCa zVZp?23j9HOE&RxRYqV}UqT9B8#|{i!sqNFyH#U9<*pi;kQK`wddVu=;-=HUoR|6Wk z#1Hg==JA;uRjN4xBMuxUa}5o9NVCD~WHw%i5$VRuS60+VU6mPPO0#z(Rqo~=M}Q^p zW|%@o+{#0lh|Z*WrPnc^HFw;DG`B6%UAtnTy_HYyn_+Vb=d@Q6_>UzG=M<_XOkhu8 zOe)JT6GaDTK)`gZmiw$7uWIZH{r*l%6?_B81Z~^C$^PidbtaD;5QB-jd&<^77uW(m+^e zr7%L-3oBz4LG4U*o_3QsT77yj@dbPysv&!vJMf=iVV+btM%g*Fucz_dT}jo})a=78 z!tZVN$;1CQh0+ukxTpy0EKfQtf+>pGRs=%Y;W7moMf99NXfVNnnBS&%|0`Qm zNYh%in{}3(N$MxjnoFHdO+ME z3N)jsSG#R)6)~4eBxKO5yI1;{2m?}dXbx} zqO6SeJa#ODVbJX36VE3Sg5sN@<|47QfTTbu3s<5_s3j9~QM|+zA5O?qs`O?MFlPPo zDkLT)7}q666z@o@+-^Z~d3iX!_)$RB3zPyUFYxg^*Uj*}P+KR8+9EmMROdPn5utb6tmw+O;Ag8N{PgjOQG&5!Ol?(SZM#{#AiH3Klx=KA7El&eaC zq>$x7{Yf>Ev4;Jp9rQ;AmLFz-l4-x0YV=)PSorxht4yKu!}hnX%=w}HhA$BU{D_JY zjn`BU0j<8~FU~Sz#wxQJP@pd0M! zS4EQ-rwsl|XhG_&Lz$kO%(5D@d%y0*rG3nI9p!-HNdqr9Itr8%761aE4eoqhTTLtd zl-LAZI>V~Vu6&tMm~oFQGq<=?`si7l6qKVW@Sg(!!{Y1)VW`x$~vNHveXunD233y>t!=oF7Fb zCFw6EJE8G~?VQm5Fh^`gzr(}+g?omiS9KkdRskK@RTlXM9>2^J*~syrJ#9ElD|}Qg z3c4OIj^)Wtje{X8B+sV>$YfDoo13#Fwwk}P2^&3C0Df-#7!k{S@#9dsIqXK=efv&1 zdYE`P0Tl0yO-*A*VgjtsURJR?V=MZ|O3oPWnZRo)(k@oW88+7d5a?Rf19bK~$CL$M zV(ROsb(Bo>KGuAaUa35k!pBKzNLVdvy^V{T`|Rn{{!Nk2i5)Mh$N$M6l`Tj*uIln$ zdR17Mo~fAyXGoUG$Lic1Z2M_wK(O^WdYY19Jm-5N$dKvM&%W3hd%thb9@4-MGMwQb zoS@+nAKxc>+W>V6G$$QZa6QPhe$o9u1|^D!^+ zz?#><=FBvdpc291p%VlIi~kyXOB&w2i^sUaWJkk?4`9)Bghkn6{r*g}t30PdPiXB- z+N)PFFN8Xf7uxNf3Yn;U3U~shdH*Kj73!aCB=B(UNf7@xiQDLqkKf z{?GPwjeteQ=)@BkOA0s^-t2JFVBC~AjA4}XX#nC~>p0hSvvKQ5v?6FP;}fbmERt@tb^q}^aPVNvwI?LLR0nSj$z(gJ`k(#} z-{(W88AW^^BboU7XxAZVbB@>cC- zWokx-_{9!RV&QA^77^A$z8cPQb&#e zzUU;$-amBOkei6Dn53>e9!*Opv>_U!$x2U1R`ff{xBwjmM&co1!pK*E-V|VFn|Mjv z+r#C^ErJ$RW)2<)C_@&9; zz9od=Zr^ocP$V&H$z~LngUKXvFNd7gJ}FE$#;TB!Fy@Ff@btw4mU0 zUqSlayL$s`u49#9TT_m|KLIh;$f(z8ummA6I!Bg+g9Du`AgXq~?EO&PrEADWFPkAY znRgsxWgSI(_AdV)JeWta9+$xNJZS0e=#ahn=LMW7)C~MKelrYLM5a9l9fN1n4OXJH zRZv_Uucy1AA^6h|MX#mjsD9G8U{?Tx3Pr_gIQ9Y?mA`%srUCV`#2PcfAB`d6BAjuN z8#DlG6H*t@(p?JR0^f}T2V~`dneGDzUONp+x{k486vE-aH4t++BS18}J*8>+Wn~Aj zfE)wL3X^yu8Cr%8)WM*oLCU{|aRxB+ozPHlLt+vV9-f}0{s`6-4NRD&ZvZGZ$`cn6 zkwI`o-|;_vPh=@@dBG=O2SiCeNbs*;FSKiAH`qxO|5Z(YSnq#Q$l3!6-OS7kO*(v` z^}2nE&vSBOsq`HC9^JpM7H=>=H%AnVs$ABtDg&hj^OKvZsyhQ~oLybnE3+n3lY>Bl zLDGii5P~3FCjeDYN@{8Rdh!1{Vs zDCogHadUBnsV9RE6JfkVY`M>l91{`}0_@Gt*N2em<3~L-R>3U-5~aCC7L#Ct;h>n^ z9khaRwXk8c$)^;US?X*08K!^rN$Ogdr**pFKyALd7T*5`ia&t#wyv%z#5S}TRaNWJ zEJP<`2SM3L8DG#9hywShu#kfffE^hfiIzHn46ZK3dI$mvd@(i^el0KHGG}MubGB73 zs)KZsaqlXB$g^C9LI7nPhCpFsATBBzbN_zpr%zC=b^~PrYLbX;p|y?R2E8*{9KaH^ zYFJ56B+Zvz(NsFWc>dfN)GaU-I@KDd@Sr6f`&i50-5y7~ye*OSA^Qq9{1dZL+M;a_ z;Lg!1fb$5(24sNu+~_S!ClCW#orcVAt{q^sL^TDXf`(2JZvMAWBFb*#*f zHD|LC^bHJLkTh}DLgNpiN#zVcNx>j1Ee-7|ezp@*KJBBRpfQ;$n2}1=jb0b%LcK#Q zcY(E};503KVf*Cv*0K4W5A>*2;|*M{UBi^9v&vomTDg@}Tu``Kj8k@fY*grEQlbWw6FaNmi%R`jt2?-rxs4k>&{GAM?I#ao^ z#FoiYdj`!w&^##Wv9y%6u2Aa?keDyzBJGc2i8mFw_kfrkI6(a9(_+knmW73ARgk*K zwYrb_(cKa}HiY^BANAV0x@ND_x-xIS8=8Tdoc~Hr!%h6s#>P=u--8A!6GIK69`HAO z1+wztGr7!dS`$2G&=MOREg~U-X+-FQliJEDl<`tPXU50JqkuOzH%Hj4Y&j24DC9HY zM>;Xpe1_Ad{_yE-eJGM%a^+nRTAko&G2=)ai5w(IVp9RIMDCL(mN++rC)m)68-S}N zds|nMAHFa+$tMxpKRjf&K?Ft70CKtem2FFc^(^9RTbsUx1(uD$>^En`IHJZ9>NMh> z#h6?U8p2?_pFSla z;QYX1jPCr*{dZrS!GD7lM9qrm^D~LTs2u+Z7T!o9#sX*YgKs)qs9xCb_^;>v6yFy{ zHrK8#qY;m(s|Y=29nA$5Y@bsZfr2j>;RIl_T;r`|7wnBtYvEQi1K>1RCDQ$eQL>#<|!9mu0(^=a=zO>*_x=iBUc%##f!Cgy`vntbpxE#^FoHuVBFT97jcK}hD1J9v}; zmIptaH#U(jQuBsAV#h=7LC&?bY>4mcnz8J`?_10C-(HW;UEc7u0IMC%(SiGKI$)L< zWXx0EaGewD7Pb&2kv@r`Q!r6uw%?Ze4Cskb%x+Ia14=rF!t@yu{6N$OV zQ!wKtcr)BGtDCBBWka_mM|}D4zDurtrX=7V+Z^r3f(B6OJ=rITzfql0&Qsuk@y9RD zO$P-rI3_5pT|)bB<{2xi43HLz=-VzE?#;xV$0{s`X_F#xw1z)?qO$s^EkgG z`)v}30n!)9!MDQPw;BnbK|DM5EgwXH6a2x3yNQxgWe9xG876dz*zdoz(~&s2k3S`2 zBVb)zS8#6xoYt^dXl|&-8TN3mMKBq4ejti^JS%}HJKYdRqt~zq}$?)GwPBqBqScSC? zG}!T~V{>CI@{kOWwfc+gEW_9Zm>4~vBwX>!y(Fomon0Ll?{A>PQ}o`K zdOtK0X=rD_b7_DsT9i8$>iiH~g8A#MuDT$cu42^u$0E3g#Ps!Y_*=kz7Ks}!JxBo1 zvBbX&BA_2apIL641! zv6)DR9O`>gr2Kp@T{1yd@5wud9_r;ZV6DFvz&Uj25c)cJWNxmmfRKR!0iZiFiYZJ@;pAlh@u7%{ z35n!kaE`zksPF9T?L%(g?nyeQq;vra1f==qPoH3b8CWwhP@IFge5fUql#~Fkz>TA) z&3PX=e(060HmqGsOQp0f6!s$-xRZvb;dufbB|`55OoA#9^e7(D zqdKXpOF}?#EF~pHbfJF@T7UE`J`GY9TO>dbTXTiRFVqJ2@6!?IbYP%;eBumFJGy5C z2;037$7t?NZDkzt{9};2YP4)ZI=0AhV$>yfGQ;C^_?00tWUTE3C&640Ody;?zc;tE zD0)r7kF~r!^mY?#>nLoBRRWc`)X}Rx8kRi5)m_ zjwSLzLINpaykd!jZ5R8)nCM4J9Wa}~@C1K1=1||j>3;mnml~T*KjUy5862&^z&g}x z3BI~vsvc8)F0Bbrc5PMD>27x2J1B7p8VJCFjbA`97&Io1zQ~_&b@csm9Lv(?v@0lLf$w6cn(+Hs>ptmxUUZSL~ zlF}D+O5OV)SCm724sc&y_YqTF;g#;R7*5q6{M&QnurRPY!0+y=N5RQW{dq3U{aH1J+g6AQc3m$>%C0RCJ-etw4Tsib-9q5 zzC+*1zBQr2YQyhMYDh>3te&uu1)7e5(yJ%^YJpEdlPcL`!C!_&IjEJuT0L~Oab1X- zMXWAX)@?-blOW^9O~4Ru>E4i}02T4Ai@kA61zmM|Cg#4IS)G~Hf4!|ZX<h>2a!1`}IDRSTJOV*Ay;vVngVl(w1tgSCyc7;smz{`1VY=vj$RTbKQ@N$AzXRyo)?6jN)Jv}AUyEnlt7mcShM zNpO4V+0RP8Mfz=s{Pldd2Uif~Fr1#(_Cd%1;tQe|^fE9WgDVSC5>jon#CMSHd5!jQ z;ARJh7EmZ|7{C}HxiDfl2Hf7hwfyi<1Vw`>n(^S-z>^!k$8r_8LK3mv*|QKDIHUR} z%90(rejFMf12Xye@K_Ez&ZbKr0Dhcj{5?s!er4H@v{}ES0`h}0JudeH{}zf#!Ak1W1{hQRd;6BNybESDuhnPJHwTT|>>OA3tDMisVhBn`y0=Fma1U_l_16 zED%*-`|jR7d%(~@-#^IZPpOB?+Twa_D9` zxjjS!3PWs!QINl=&G4p(T`5_QgV+>pX${V_7%&`<2)#Wm9whIWrDvyM(+GL3-C&6m ztkU*(96raxc!RP#b{9e0_R-3zk>8KQy`&7%pC4T(qolv3Tq_tgLS&^2L15HY1zD(?eiKkrbdrk4Y67sU9DvW(TfwnEw88%~T`P!|o^soStFZP#7dJ$Y%uq`1rGzPiKpu z6q7!54@IIrCI@6g>Zs-3V+^FZz1;;A@Qz)S5Jf{;{36{Or6h49;UVcLagyG6T~Gng z@3VBLK@k4sOFMLNVz-odah1WYM7Oo|towZk7u&%PMEV1#e{{8}0Nk9>JQ_SZwc z3?ztxJlDA3E7HpB=W2$E`#{}+fhx!&_@7_J$Yx0kS7K{VcQ;qcPPBBatvjpz{3s|Q zWS_O728SWkQ*CILfng>wT~tycnG}-t9G48Dp=)UN;8(uP$& zXqQ26`9k74%1KLT!^ekA`P3=p5gl}c?*u&ojH8>5#SOnM^2R%?yU>sbQIDxb*2As39euYN)a3Q_`L<{&LB|W95Y7383D$SWu zuv<{27OG=KGVxIXY1jLj5jFa(*gLv!cdMeRK^FiflaE6T{uQYg!Bthh!-GJGSNdO( z5D*O^geI|wK^JnPRMyu`~;;p&y zq2z_yorKVP_nuknnLt3IA92Om*%^EY2ArBZaTn0KT4xQjKNQwMa?_ zzVLFa>WOGz&#m!rsNa`FHCgJ3;!aD^vu0)rC)j=W#;pFaRUBuxbcN`+T@5d)T02Lx zQnN&^eSGXRSjxl2^Y^dCK{-#I%0x5#bpWwgSNmNDxH9YXSjge36d5;q!V2=@#W8g) zNf$64aHatqgKYMgcb`5JQzELj%D;cM`RC>euI|y zMG>yd%1RK5j-n-Tk{cv6hBOpzZg^g)X(J$fPMu22%(QoKFg|r^KQlyp%;^~~Y%W}x znVQl`S;B?L$js#Nt@=WHfbMB(9whkF>b$7YB6{5U> zAQZsbYmd`EKBfc#tL-%jA@uHDOs1ol8c*gWAS&D2Zx!AEZtjaD_~XC*L_WL34RSm8@6^v^Zgo zq_wFMkRMb%z%y2Vs0sW0uUeZSq0JV&CK52+oA@-|Bch@(~4*q@(LeKvZYu5>fr(v;_>r`JsLc*3s0TR>Z zpTVnWgn;kl++fo3f^r)@n);GTtW*1cinUdU!H-x*k&tX7JZRxcjo`ff|E<&p6HB0? zqvKj4MKjkGOdjA3-bsLA7v%v_8$h|G#5uIX!FXyJ^P>bTEJQFO*&0IgA$pgxkHRDq zdq8DU$eshDsKaX%K12eJt$)JY{780qo+& z@^cYlD-RmvO4#r~rg8ncbkY?^$2UZQ_+zU~+Wjry{ocL1o%S4nMl;4D4(fU!E{ML0 zA+1k+0EYD*%dsN}{Sb=QBn#oM#mEe+#i8&tTps3w2g~86G&SYubx;hqV8I8BKnZ6z z0v5K%5%0o@6T1o5y}Z!uj4I((!a*u5A-b0=S@>;mEyYw;ZUD34lagq>#k3T0It~bT z1#@(l5_jx5_*;cXHNj6{macH(kz;cJugcQ+HcJifu>0Wxs~*;&MVEk{_I)_YGpVs? z;~$`KNn-k2#?T)b=TZNg%d>F#WR~$N!X^Jbl2_sV?FjrDjQ6m}YnpfnONgMW^u9SZ zv$l?7X1MzE@?yQAN1}w=cPL^&LoUO;wdK?7$~=wD^Np`+ilLHk!!fRrZ~fzATbpp| zl33=+b_4xWr-*1`OzpPe$s|$Rq1Ocg3}^oSIgIef@@=d$D|UFmqL(gzmggQ5BV$|ehvW_Bq>vWD&sElc(>1or?ZKa4^*Odt=(l;% z#>RcU&miVH2k*rCDg`=HC~6I#*ZMj3Cqzfjw@Mj8Xm|Y7%upq?=I3Z)Jry^WIwKX2 za?P?t8d=-go-tl&zxn|F`n7OHU=+5TPdnTsM8X%90pzmr%2DQq_c3ArR=dvN!>h}m zNwca`u)!j9X)G##M+-wHFd9AyoB-KqOfc*|`Rf;obco-F8bkh1>h}<{HKqdx$VthS zp-LM2{{0UyQCu7?E*L}_931K8m(^w%kz^$Enzt)R6^Ai@2G`8FavDi*WJCdL;k$D% zr*aOm9Se(UOeu_vjDY{aiJ{33#J~=eG8j*X(gNuQlmteI3!sh%ue1lU$z!&X=|&- zeeOQh#mpO65uEOqhZVpw*#85UN@70xD1?F)rC$pe|EVfDcJ0hF9)|x1Vu~~e1KVl2#q%vaFzbeS= z=mR~(REUvgx^pm;bFI>6ifLX&BUZWZky*25p3R7m)%L)eCxItO>rBFIp9(Bi#W7f% zrLlN#?X73;t+4q^hEC=8xZr(T#+1%jenx_`_{oyWL)DSl;(;eg0}CcXW;1=o_7Xg& zhRVK0D*klPI3gs(Q+O4IG0$?e4DT?DeTT9eRl2Wlh1vOfoyYtq3=OUST>CuTSGEWQ zfDFXx_7l%vEuZ29GrINkzFRxOiVra}%k}lm@ohqaxO2;{+WWxjqR`eIE6j~oU>*vE zT+?FIoAq@R_*|J8FHFjmpZAT9T5f4SC@L<3KfSGuZ9w2*=%%3TUHNN~Ab(>&(Kkd+ zy3Y??QXP}aPEKkwRy~r;+anuIS2mPo3)2JPfQwC;WquYb_N6YDF0BlfT!B?wX;FUD zU-{{A7<_SlcX!S&6)x4+KaF&NPU<`4%jqdctmxQDfK9`=v-s!gNS@hL3=H&_+o=CK4ealP&M`X(@O0I4cKf4Y8l7kgZM1A zN?{lioXA|+Gp&07W4Fuf<7TZASjZ2E1F&%R@_=Q#AwRo1DFTsZq7lefps-Ih(xc)FW;v(X+MF? zYy6nBJgW$7aWDMf5qG|*2Pv~(r`}xZKG6|k0}L2JF9@$nIghm^ya514dAO!cwR6aF ze}^aiwzt^9+jDHs@9(*$oZlbI+P)7WAJfv8vVA{3E$6ApwSc9n;4}NmtSe9gK>O>< z6x%%2)qJI9eRZkzuM2!hlf|Tl4O*9cB{!Il zlW9dmNO3MiMpSg6y4+vx;w7piUlj*mZ2&^oTi<^C;E^`62Q0YWlLpR1)qzn;Vn<*}$>}lP7K8{;d#R)8KGTyA>3DldG%9RVrhrmV*@yM? zeEytrv=EI)j7=Be2=y2K01aDjeij~(@Yy}*EChnExb^<2Sr=T4Pu<-f5CSM$a|i#? zRQC?MokXkVQf7vKMRtlP9D;uaH2tGTIPiLX=D(^r89oHIj``byPYT$(^sUOWkDLHm z8L~+VE;pvdnmvRGW&p>)j=B~U%jkb1{lE!3sJgn^GFFcwYEFRg7C9H%z&k<*rJZdV z(i~XaB3Dm+#&_z&#OXCeEQ}1*n3Jl)((F-!17?)c&btMRFX2k%wwzm-5%W(Qbt`;! z|J7TYs_m0oUhAK3$2of~F72KBvrz6g>kImB#OE)R-vZ*Vqt)YYZ70eu!i;4V^}`_@!Q8vY~0JbH(}$9>fgo_&jsHAPuewD3d3MlYi6b711)ndyOfmC z`SVb1e<6~|V@G=a?_(vi-|X$|V)j@yUVy5aLhquX5V8yu6rg#K1iN}}IYXh&`7E2m zT?Vxw7~j}fnghgDA;r*lfW<@?x2NRvlmDGB@sn$+wz)^e_WznM*@^S8xT) zwkRv>abEbGVep-(hJn}?)Q-SwY*YXF?VGKQO%YNOx92@w4BLc;I%D}cRAn4Jv5vdR zKW!((#m7S=m44BzW-vJhuqf0fE6clcrp3f?(F#s8L)gq9-5;~T& zK6{=l7n#> z%rfLDC#k}vhJ2izU0GP3yTBGrgf^jWT;$+dJy-v|vKGi1xY>cEdrzG``)7Ii<#Z#l zv?U&U97B} zf3Fkri}Ia4>66bwqvRVG`RP%iy&8kNtBWUn!sDLW+Q;$^st=dG)a_ajp-bAPj5VRK z=BbVD@n8~ul4q+N5gz`k5I)_nCYe^vu9T%&ZA7S2T%?%gQGR|7B{*JC5!`A}_vv1J zbg_^)g$4!$h5KXK-_?I+?N!;TLvBPyLlBO=Tx-L>}L#yZeA`v^0nmX3y&|^ zXMZ}-?FuiU8~XaZf|oLiT`xYgiISCn+xF&-P3hmh7wNYJnEc&LR`989ZEmeBlbWwu zKKA2SBkmp)s*mF1xy`=ps4L!&ZZALyr^_)gIOtog*G-U~Ld;%IF}JiFMVA57AV^lW zcRt4WtVY0u6vfrwzkhd;l9pFgV5S)^8TiqCB+3O<diIGHDi%SGYE>eZ;3by^e8pC+@$*&$|Dpapkkqg4PML>pudc{ z5(wt7-Gp-AzNCmmN61PK-o<1*+dL=3 zR-cOz#ll+ZvuC#($DogD5xX5xZ&zqK<$P~`)mz3iMm>^+nTiUMxB`sg%lwErP8K~V zv{}(^a(%l_R~1VMV`L+2n9icF2Gt*>93SoO8F_)2h6WAQ_3L3mHFAB~W5HA>bad*~ z!c=9&DB!$>&EkcxUhUqqr{1Xj^(VoUPt`7Cw~HQt=Bucvz@Yi@aWlG}+lOUiw%6)0 zow2dzY;rnYn$1g=Iz&43B|b*K{(w!IWRt33YUtl<3N+NAPog53yY4fK$9dYFr4X9U zQCsT%`SwB^W-!sMg;uUU#g7}WPV4cpjwzLz)U>Zw(F5e^>i2$j{+&H_9H`U2bn-9u z$Hzm=;@z;@^TrLwDNGYq#}996d9AH3GEgalpT?U<*Jg@=(OAkZ*OmRH@T5F{mW+6p2Dy5SheJQ@!SDlOSUYd!UFbyqojds^B>(o zjp}@8$LrA=*}cCbesRuiMSdHBxv{0CrMtVhpkTh^srIW~Z`TLW>9-^rE4;gdnRsk? z!_Of}M`LXGgibwJ?!nh>knx+Un`pgJq`LDH>W!ROT$ZgfU!(v-EW<-&Ok1{D&PQ*Di`3 zgMqAxDp+ezPs!NkJ2=1h?)_O@#OFzrakKOAkoYKwo)^CNMF)q_lYgFI7|E?+JnZh) zFsBJi1l)|799yO+)J*d&R0-5o9c^U2j zhaa?nHI)z*#h@R3SwTRl1r9Jz)VzS%e@s&ru8~0;xP;)Il@&c)Ni-}0@r6YThbiS; ztYAs0_O1ZU*9;6(qhn&L^KF25hHJl17a6EoFj3?GcCxYV^xINQ4Gp9^Xj9AjfNaYz zD$L}puA!YSM;T|wiMCV`9!adpHRHe9crR&xWWi*}39s1&HU5m%HBV+~XTs*E&yFVw`93H;Hny)tp=)RCib^vBucZm|jveGumMB9-JO-Bdjb48J z@)BK&K+@pRc@w8UGTzAqf6A}urDORXB#$_gXV0toe9zcBbRGR2Jc`CU2MR%ILe1CJ z+dJ6bpL@RI?CZI0RgUar>`Jm)%fF)@TR(!U4M1bt*Gp)df!BmN2>N+| zBtVur3dNQ++YjD_P39w%r|;_PQG9I@r?K+Pq9yxuK-0W=e-CdwMxjS9mdKFHBVQd1(FOgdi`Sl72cThL-L^pc>^o{rgXC`9_i559I&fE=II8^vIUzLABnpMrAed2`?O6ptd#j^0icvV#6sSDt-Up6;j`wDI$&OuF&t&5t84 z(v5#lH1oKmXQ*)aEu><9#&Ys8hyzeko0dAtxUF^laWZB2kn%b6nvhH{Yx|G68`}x8 zAO-?a-W+E|r#3-z+lC*-p-mCSt(70~%BiE_v>m%+ahhSNHjRh{`8kx@dYNOZ6C(2d zhT7UW9N!Nh+@jpY!oHtS{zBaF+3KdLsVT}1{0!yl`R-I2rH%a-a!X8yo5q4Hoc5sF zVc#DO?GED611zVH(0$f(+9GjJ{9=sp#>YCJz9#E`4LsSkqShno?`&V>!Ygx%zXdYRmsO0lAtE}v72#M4&M1zh50*_PoWdI{cDxxyH>~g>T z`jvwknu-jv@BWWxqUUBX--ko`b((hH_#8F$%O#G@2Ec)a2UR}fiDwGV;4aSj+y!TY zGXr%qWGWD$H~G?4S%_Wg;=Q`RwhbHPdtoMwxri3{$xs#2)l9Npb7Q*!}A}zirbrfRGn^EyFxJ=S{c(_U?U2Grf`2VcFVMf&W~G9~i%P-RyaKoP4{gp% zt{xuu3vZI-C4>f@_{bWBW6}zVFyC%kAblI89y~MRcpzJ2(%GOk7y$tc0*XC@I$P86 zc&dI-=apJ#YUzbnVIQ=~_JzJRRqGk2(V(|&fW!igpu~iPrc=Sp8Uwyxln$foH}0VI z_y%OBG?UaJnGrCT;hc?vSdt?M#qa;s+M9+`*@o|0=+--*^kc3|4GC6sVg>JMKN&4s=4=$D( zAJ$CZ$FN=S@>&G?O1IQV`je?jLh^jNcgrt0Uj4Oym`PL&U%oUA{zd_oH>Os!A0l@E~fo)>qpf}XECr~>!`%(O5&aW-E@Qj(3*`|H;} zhwf{?_zWKL%I3q*#jpJw(iOL3 zB)gVPHvAl$JIv^m^~AR7LoKcBb?S~iRDpQ>-^<#-v7wJ$s(wp*lwEQr6SiG^C~vc4 zsT7tTp|d&Yq-SU4sgZUE1|t=$(nW<7+PA(w*F3En8)=tH8{xo~1jt|DbHYS@?vX#rVwxhw$B}*`BuIRS~utWuqO2b+fP5SWRfLE^$HE=OCKCY(QgVY&9ehfxl z_5E062tYXsF6mhTK~z;!yJBgHCa_<0YR2MaaYM`?!DaNjd2~l`|G>cQeSBfO(#JG3 zCen`5Ke%iQd<966eP$zU_msZ4Ks}4BRfPl>vz(YDgT5@lxRBn`J(yUTDmpv8(d;8p z=<#>q^@Amd;|JM)Z^`W39Gx5D(B-i_IHg6_UxY;${4yUI|Af(phx=(}kiMR0WPJVn znMdJhbOmgE@xk}HnP?`Rg2`*Ch3J}(RW;v{t> zIb)|G14On2v$L=~hi!p=jRHcj5UQw9U&j~3;nV%qEXUD7*!1{zX{S50R#{J;lmPu}Y^VWN zZ6}xS4N!YlzO~5L7m?srV^nfVN^6l`2J+rw=yO0<4c-`x>r`O_Z+uBrTQw36m|)Bw zTJ+ev>SpOfS<9xZZ{MJSt&hqVGA__Q5v)WmN1C5++b-N0Tbw;7IFyWi{9}DWyUXaV zJ0TIvCu&-+dN2O@%HEs|KMlxg#}+1z$V%y~_722O$<2kajVmm1Oxs)+8|hQ483ZDV zieyTp$B6i#8Tz5md%<9^9dM)!@DZrf(G>tO^4X~r^!nig11PY2YYxF8!}L~|Az-zm zF2K435!xTeyX8(lBf{SkbxwP`2l9PXwWX59VA&uue0cm~`>AcQ!Ooy4V=I zU$#AdLHy7mSepWSz7H)8tiFIRdCS1xVK?O`Joc+5YU%SK14O0+ARS2U?6y7&@V3bN7{o)Xy^aQ_mq>My$RD2*DtB z%Y$RQM;@Z`#oY1da*k7kDQtqa0KRDV)Xbgr1ha25o0+M;z7&Yk;eOcOOnzlO6Fgt; zrlq7D#^Qj2ivW%xlY;aRf@+MR!&q!R*~wmqLUc>u(+r}%ED$q59O#(={Xm};3CV=) zosp~P@FG6z2oNrb8&C+uN!Awib`&#mrmL+TFIQ9>#kgoli z7zBGdcT*RrJfA+T%d`0&5pxgjVp}Xt>I@z`Y)p+*)6)Y-s#V5iNg#UxFF()_cZB5T z>iTU1w0-flp0MPhY=&_TokDr%x1x<(TsArqM-3 zw@YI86cx)-=%=VC+?^BOLDN*wFEL*;I)7D={7EH!V8lkCuY`nX!e|jPxDzLE0!?8#kf~g64iokfxQ&Px4&<{Svcb0m{W?|YHiW`4 z%zOhO5p9Y}<$V(l(c8iX9&4?w@Gb^+1sduQtS`{i!g&St3{*hq%D}Y~m7NNodSGa% z9_ZDF9THPg22nIK`Vul+3k#l-Kb)O&NwE1tp}AASn)Bt=-u`~Xl#`V~BKx0e3vkt( zrt_9@G=Qf>*qV5G?H3ZVXZDtkSwa^JM>t$-j4Z71LG{uM0dt$g6Gn4l;daV-Fq#s*u`;UzM`>^vkLVepgUavqkXDSZN38P2 z=_qwE`M71c%b~@L2=b-8JaPWEWqYf2Ub#hNu9jlA!<>RJ&ccaM6Y~p(kUAouplJng z9uH#Izii`GVDj_z_|{qIc%+;4Rrg4rnH#1lBN9XO50V&v+5&MN)zaZz zayiQ9Jqq3n-(9-=DnVU>P8=}4IZ9hkX8fK zX6dp2T*4uJY>iR)HRkk4$u5C`d-sxlHzy1@tSL0^j-&G`DY5Q66cD_lMJ?DpA$s}o zKF;=;W*rNjVuzL&RiQd4_#*e4aAheWmrAVBu~*Mrjx@8jPF39@E-4u&eeJJl)0?_F zpP&P<#b5OGUAy6@R{s-bD%R6(Stsbg_sNeY4*Qj@URj#|Au>5xL6zipyK(()S$$6O z@feBS$=^3|$Xf`1UXS2@|M%kSKcsj#!)CA+#qp%(+mQMU0YPtYF5cE$DyDSw)Mg3~nEmNJ0SR1lO#(A=Lc`Ox% zH>vtdBffrtaDsukn#8EG+5`wvM?!b!WaV|fHFLVI)Y+boIHPWQ3B7JW%dHC&UW@{B${%V5>3|GF52 z20L2xumAwB(6ae3cxSe4xhYSdnq$S2C|HZ2^rAbvCPcsr6QzT(&ov*3CRGrb>jgVI z4p!FBfWh#s!H@L6z%9TUfJ6ZDJAfAp&9b?7jwRtb1JppIz$bw`a89|kF>c{V{OO-g zuW#O571xLv<<|ncL{M*|j)zGNp#>`|6Y1}XL8BJ6(^yAg4wAjlydbE2m^sOBPxSOR?cs134K*QxKO|s zw4$X>Hk1d6k1WUQ*ke}i>jv8r)6UOYS}Ac$%d4vG%ofip*tA^k(qB^0`TclbL8)!t z$pogiy^ik(rUC;3_tk!QmHXe)IljzDkppeu*dqVmao+@%V>dT%roNv(&l#-FDLTXW7?z!N?f$kkp7Ibee z;$;e!pFZ+w1h=AKSy zGdz~Q_-F3Pr_22pFS2Y2U1k#BQ4jj>w63P^-WK$w4KIy`Dr4PB-7q%Nn?b(Bb3u(8 zh0Db1YcI7^Kx0!@o_lr{!kw~qzQ$UGIh;uhiaUHcOCBzS9w^qC9DA(D`7O^T3Tpy= z`XkT1e{+0lOJL|#iq{5mVlVj_Jx8yFjgV57Z*@XrY5Wm~@s8jxIhVAIT?jpKoVz1= z=uW22)3dAkeqAW``OLmjkrZhJ%`cZ|+*YcoqNN*+?-d?f}$eJaebUqPz4MT)JSFu=ub&^I|=2 z<<98muG7N?Rs-CN51|RSutQ zUbcrX+b>Dm4IC16@85q1zYY1=^7o=G{N5EUUbi+dRwz%cz~@s1n6LLa=yBZX?)z0e zui~fZm*mMaX2~{3R;ZVsJz(F$dqZ&?bS5we{V&{*xsMYUg8`6JVACQ$96+e+sFvOR$E?eE(61yQr;HgIUMUOWJ(A8jwPXg?md)7{0I+$ zpv!da|Ne<(af5Ss_5b|O$N%5{{WH!TGpz8CUxC^dv`SPWT5l*!YDuSHTMQEc2v!yT zd>o|$&SSWSCH?qBaS$p{LTU~?}a5M3dN%3gNAuOO8)2vm3VEa4)7rn0@1htz+-7Sh%^8Ltc*{ePI~S# zF*St_O+WgYtgp&K5>isw$z*hAbd8M{;O^5J{OCBOZVN!aQI7dVf+h)6o~%%UHXn3H z<2m3IqwA+cLT`v|>(*D!>yghvK|+~GA&6vdlPcXhv9YmO)>IPuPQd7m+iFvEUx3qy zat&x0>?@{#bYeLLa^Cr3Yq1l6CLkU#RUrCZFM{e3XpkDo28~nUawa`Q|9-p*m;IV2ZIR)DhJ>m|cT@D6%$81%%KU$1&*su(tUM7YyF? z0L|oe>(;^920AuicIdPLn|+>`s8SGo>z3N(%K}uWmaVvy?!$8j9B*bSj&ED#4IM8W zpP9Y&Uc2_xa{XQBkSzUF6zG5$1C1TP3rDe=@2E59>5b$S6}Yo=Uit2>T+4f)YFk?m z6Ej=dW=`D!4G+|h!*X(7$XfSHgoK7xE$5y?@WVh17E2`bxc=A4ui?xKUZ~L@A;#<& z-1h52u!x&&3b4Q{LEk<&=mtBTrc(tTFL4sPgPMGAoCOz*_7U~sCMXeM*r@u3*^hei z^9$)aB_&JvG1Oog;7^dT-950xuuuuS8a^tyV_|QRK z%_F~+gF|Hha5T(HHp#$BJkc-4N!kl74frX{YAGlv{DT0!7bdDg$!^|%TJ&(m(Skt} z8dCT1C7AW-t4$xDW<({M3EB8vA80EG`7;VKoa8p`ZK#`YC)SI=*X{!xG(j>ZOe|qg zOi#wajLGGY#|AFL6NZpaBRl>Ik(sAZwcH5}jV+8a5dTi-fF5~8`CID?$NrZYC1uG0 zDuCr#8nckzzD5x(yGH~^WM(Fr@;Og7Huppt4*I}AqUl{#$k?QWM)~cW7;Haqsv^HV zL-mip!I}XMin5;U9YBp2($9QXQzM819q%vNNh;IC4SBK#ieS(^_KS#QynG4koNTD^ z|D{(L9V35jNH?&R@#9*2M>JQFL}Rj+?4HKv<{Y%wQ6Rw32rL;K3O0?kU@v38LnVn9 zT(@C6xbJsi+GhE}xTinoIaBy_QTHN1B43tm7 z0atbo|B;(;KyEZ`?TF|CfIxK{cw?u`&*SXDj)EI4-LN#lx5vfEzhotIC;G@aK#5ZQ=;xyITLRe;d{ffvEc+lRl#;fNa zzzRh6Q*34qLD#%k_pzy|%%@w3Lx~I(B#4(79A+F2i5~cOsIL%v;1DnaV}d`!tvYI_ zDr#yh5dev;-G~CQdmVV@7(lfm^EXviR|_0CK&IrLuiCWBj*!2#wCp#?=0Rm6A#vtLO!`)8 zLjo2OeBS)XaQzxaQ(^Tpw>Te?AYDuZD8HrpZ<)?=hxGMTZHZ-fye>5 zLDLuh1if01;^NE@$4S1kqeWx(G-474a&X8u!IUS40VH^_8D49E&!yo~C9XCrQ&M5! z9M+}Hcj=P=n>p=5c0n}_!G33FCs2UbPz@#TsGR$RgQFMlA(&f_afhC&29Db?->Zq1 zu-QQskdVl$C{g&WbtrEgZrZFKnY6lleW9@}oWc;w5$meD67xR6-sjAjetRjd?{q90 z!0S*V!vEHd@m>u`oH#SliG#SXkyvEsOCih#5>;4uII14w#2#$h38~6d$#I#{N?!tugS`woPYb{T zXqEr7W8Zhx3KpB_-#pj7f~?8gyTnyZ6W1Jb6*kX2{d5@@6lFYC0BjfTMdUQW{Ort` z^puoRt7f31E-rRgu0X=iDPqd#TL7giBnN$hOy+0LLMpwM@17gN1R*4V%$n$~fByV? zdKyUlHp}RT4}T5}z`xoRRVXbCEjIA_VS}l;(O*nlT!n=2^W%FKMC=X@I1k+62jy{U zv7pEr{C6}q(YT6>i*xq^S^|ZJrmkukH0&p^gz3D!bTZ$Brw5D(Z@(|SB+BmG zJp#K9a?KSK*Q5A;PW!t+e@ob^v+Fql9c4m!iVwFNFDnPSC`Le`0(Ja0OK&)){IK_@KpR>X@0u9ZSOA zyQ>iD$|(OBo>1sgn3%}n992*-YdeO@6G0l@_sI94sYlAzH`X1f#dAaPV;(0M{%uuN zRfrA(0za|4N%1hjLU9hsAOV?FL@NJFSud~mydiKYcFu@Q zFiizRUeR?99}V0HZsRMyoOiHZQ6+~TY99Pe;MMSX-BqJTE=Q^XgW~cGW5Q|`niEj+ zp^=41uj#{wK%u7uCKi5Dx!aDGXl&H8`}gD|m4sCoyhqN^JPJft3QgFwc>9(uJwV$r z%?aKj5fRR)L2&u#gv|)JnmA=k*FEk4i@X5dWrp-c^EOFqc*>(i_B{%F%h{HKc zOe|;YExJQSP|hc#*McC2D+}9D>}OOam3#n`jD>k2F{z*TTQ3-RsRi)y8a)jBB9fDf zIhbPxw4uN_JuB-f@r^g`ya+E0thVqCH!+M3>nQTWB2?h6vZhEx(87S`9$a5@%fVv+ zsIYf%+8d9lU~OUpeEU|gaUKc2ANlS#F&&GyWGccp78)!=kU3*5BJ+oJ8_dnZ7Plb) zYeWd)<`T+LI1?eWf|{EB{P}|OnK&SAY-|v>(IL+rlEM*)eSsIodPq2xg4(Kp>81KP z%C2tYw>y^o_Z0xwfr9n|IxZFrLC_0Xe}9ensBl}tY$^|gK!hH!nhY=j1?vyVvBlWg zd9?WLV}m=eHNbYl!A(>wz|eJ4bn)KwhuQ`2;1sWn0&2nN5Lzwxy8ZnZ>2!ty>I2t^ zP-CuWiuFy%jxJxhf)xU!6V^S%xn%PCzFGpE_0fU3Ms`fe7(ZWNoZJIVt@CR$WI{tM#wYNds_fjBGz5GznNpd2KmlrVILZ$Z$;@u?|T z0dMuAwqnK<`Z9tZRu>8&lGfG^gRc)}BqBMs6gPyRBicprzuLYRzL*&Nl!%iD2AOBi zUf1#2E&jHZf2Kvxj6wr7rV!jldSAiQRKg}2#!qnG&48K2aKSau#qb{ZeL9jpL=oq{brUfb7;L`t$?TV zax(!_=n%_%H7;-hmF?l1FA>@?-xO0OvG34HHpYCNipaV+1y~u)1B>C6u>{@_SVw^p zCl~t4Nv%z{9YOm?8!W(OC6C89F52pqN-$(Rd-g0g2<^QlZh5pAkC-OZ7m^YZAh=Z) z?hgNW8BILk1^5Cm;#$ux4;l!lectdp!XtY?)KUR4a?{tE#UU_Fu~=Y^kHYc+)+0Af zrA(84*#>u4>hgV9RIN!4L3N1I5hXpY(ezlCNO2hu$={S0Y`2Q4?-~hMqj|}-`+{E) z^$v9AMo^_MMZ_Q?*4`Hcag`ly2Y{|^o*?94oH7jGIkU%+#g{FvT$=6KyzmY~A0x9s zbbV4DjIlsQu=&Ihir9z4cIodQE1Vg2r#fH`9_vZi+cHy88H%dSqT`3cU?aOIt^Q($ z;j4h-VN5VKGS0os?6zg9-R|uOl&GjWafJ{ply0s)Bq@pUJ7G85(Q+;X#DSk8FUMp^ zvo;AroDUksY9)fA&}J>|z(q1g!3EEV0uK%F!-t1nmHp59WZAwQgX3;+NMht75059! zvPxlV^oOl+_Y@1RQ>b?;%;~iP_`9;3eh4AR5hXBH6`pp-HpoCyhrHMCYpB>uuKKl` z_jJIzVgW6T1uUA8;ba%A06Y;Dn;`;-^C|dSs1&a^$3jCt87r`7a8R)16~GFYl1T|sb$>y>Ra@SKwCnaM?`Dys?A(bYOaf2KY{SL zzXVR_wgAe@4&GFM5%-~w4*(Av8&(hCOUzCRt}usTtrf_;pXU;_1yJd!Kc7L;c;)O_ zP%-Q}>Ml-|^dr2<=E44Z@}3GJRM#(ALkodpNx z17{Uc;szGA?g6QUp1CF29@=CC%o@d9xf(U_U_g18L<^&i$dPonH>|_!W$O#kMW`5r zFurP{q%~WH`wncYW5;7+3JMCak>HqwAjo*>W}m{P1K4YmM;;r7ywSsc3yVn5SUb3?2k=*IOUof1o?hg6-Gf#%$l*Sss=?+X z;zDdXS0VsKI&kpb1e6{9&+`SgM$b za3r;!=luPX$BzdgB7qzp>la$pv){CskTnCCDpMY$VLmLVI>zR!y|$axnrD?81=Kw! zk~36DScuWKEOv1)Kfc8-%1gjYuq%S0696YTwffLLVh{($g?KJ6dHJ)IuU3L1U&!`@ zWp#BzGBP^{N-TR=oDOfav5|e9&DlKz8J$!Gr2*g&>^~=&TqDFFXu8 zs+{jG3;Zy7&+!!I8IH18xD^R$mBVeV6V&K|#8>9bB=hMWB)xa45tkMCHh( z`jwfAuJnfW>wBi=K&o$gR%x>z`3{blg#t8*CzG`(|Df_->QWDY1gtktxdYp=1-oN*VoF<|pwd;C zuV=rE!a&Lwr(Yt11>H9Bm)yotE&z|%G}AY2U0n*`gMI&QqN5`QaUwiraRLy*Fv*Hc z1*w!UKuOn9W{K;{E-W$38aojN^idr=vE9Cicvw~FR3SG5mM7)(lYFxj<|kxLQ~I7fOs244N{9OaP8np* zz&5zwYl@yB$W9PE<>U~aTcDDJY0qd*KIzfD$e(O2MGULdnQBmzEs(~tiaD(rzLMsw6c+Y{e?}%koG>kpmVAkC!*Xw3Kd3W~11WU9Df4)v)aFF9#;6V?PGaao6(lbsT zsc2-$cMo0~1bGX28~|73CCGRoepOj%eGW3@igmgeo>zREE4;c&wevKlK31MfM$;%n z4C`;74KJ9DT<4O}UJcodxV$njUF)%U4f;wrRgN6N;_d|q?(k*n%}k>Ea(TBeC(^tm zOnpb1JTkJVdMgGjKm9_7KDZI0;D`Jl4`l10H#q+Od6I5x=-PylFZ*RT(@6e)!fgj? zM3}aMSY(EO zo{7G;sttpUDS36UT25BhN%gufkVGI;0i$yl^sEr8!`j1Q&oz|5;yXrAFmnA-#|Pp~ zKSoG6WDbUKCHj$V=E=SHA3j9Ov=!jtx_@J+kC{haWWRQ+;+0K0XLKd=o|MZL7PMcC zm=uCXK(32}1Nf_DZkoQFI5!c?`81=S!`=j7S-AAeG7iGVGbcwZs@`@aMPTQqTNPuX zVHy@Qf1&#u!g4}^W>?WwxmvkT)@&zvZXR|KpC8nQ82 z^BN8$wLm&%Q@^5Ya7lrQB{It`>4{AkD@Y5ozohQD_wG@O8wNie@xEU5H{gBOj)@x~ zy)5C~=`7Gr6!$?@tDvxqE~JHq=MWt6Ys5AtER5UT&)s=k{kdLpXz1p^3OE=R^lL}? zf32>#trk1xJA1e}9?f|^t=JAoOVLmRVW?R>*M{gw`B!ORy7Q8?ySsE~)ywpB z(53j5$gnPCmd`gz%FSi%N@AG{4~G$y3(nfrN)X89JbP9NhBc&pqHR4M0^O=n>Ucgf zSGd>}{MG};1VSY<70t&7QXM9%X+-x<(ddW2Fsj|$?k#aUqm{}2k8$K*4UXQ1sous4 zM+?5yAon}GD+K*u1BM)BfF<s4CV%fwIwuX9eoOAcb>DKwXFZwvsf0DkeMSgPy2FJxK021ldy=t>%;qU3Y6ufs)#L?Od7nDP%0faTeq5IZ}-Pq7!6lE3L z*Vvy;V_rn9x-BtO zCP?ey@qV-ynW;b|@5|`~Qd5ocg)s<9svAT`Ac@H2U?X?Q+12g9qdEWyh6VqR9@q+(H6)&&u*v1)d{F;OSYOXX zrtCb}v_|2Xwg6T(8mE{8tFEb8xgN!t^d>*5L7w#^RGt{EhFpP}iW3#~xT}=NNEz7zlXCSv)5c%zGmTlWWjD7rXMij3DMTv~|mm+D+x^;n#LqaPn|64AYsDYUt zpqE32g`@zfx0R(O{VxqGU?kdo{`_miP{eK&?x>nETN3pm27BSW#JHXD7XDi=FAyIA zLvkR}Lr}njm8lP34LMKQegM-yA*@CF7illLZ9nRWL1?gExL0#uYR)teWiDYy4S)oV zNx&(-oah1CXM9C34GBa3VKz`=334?01gHlc3XRd~hA<=(T`4W@41e@r0s|rQuSJgt zI51|xbHmXGLS8ZnTwSD)9swDT;Ozm_10#en@kv60u+V}|47&G`E$={{iV!gi;po}P z0o)UWj&cpOcxx1WHIre{ga<(3o*TXd|6OuZtgM>@wz7oXO<7QxfvUh`TNg+)?4k7Z zz<>yvzYpClj3NV%$H4XV<7M$1ik$MiLVwADgbPoO=(uY!)&}M&$)Z5OI6hn?)C1^7 z%kCM2p8@Mp`W`9!cQ_N#4nyq<4Gr2eU=`sRxT;RlCdEGjWYNP#=7B{j3w|#YP|$HA zDFwwq_G(~tLD!kxepvYctXsc*n?*4W+yO9brQQf6dv-?d(f@kQI8#f|xd#CbHyLRU z4lk+HH&D`}9Hg~llWRT}7sMUK$SN4d*Vckf0$hZcpH=2Ko_E63v=ezVRyNc-CdS5a zWSaH#K7M?|T>XRP=s_tUHPe%m_{tCqtSf}UH)cKRK$&Iu>dI+X*MjnZ%Vij{Dk6Ju z7&YpJ4H33iuC!suCsr5GaareKefsd5Xo%LlP>%wf5;n{g_~&?El%C#z+NiVB6mw0u zxmR_qxKBsB2`iC6wIhWg=_W64#r#Dn;2iks6IvXjoKqkfV^nY|EH{ufue@;4Ji!>IYEQFAdV^6yx9c6F~}vj_=0hXAj`jrOQk5?7QoL8hYX%xVqug z!35OyvPs+!c;3OXKkO4Y{VSMOaxhk{ z;_KH)Sx02s61E-Nw{264-GCGVJ$sftL;hG-Si2{H3xN|)l%A1rKqkDh>M_Y~mlWV3 z!eJR5M~B~ISg%;k0;2UtUxrY@(!=aLq89=dtmi4jq-a^UQ{C2*lg|Oz!ypn|ZJdSU ziZT*WyLax~7b`0yES&!GCAUjJ;{eWD6;)NiMDZDbZWu7tgn@FN5h!`F-c4M6x#k)l zZR+mtm%v;5a(d6w*M%>UAip7iiiCt7;8i?dm{@=cMmX<_reTNMYI z1d2ycSuE-{b;V;361*-5kfsMx4OP*Zfo(wrq36wR9WE=QR_qa3D24CTGmwOwHJJR& z0p8o%Vz0uC2{*dkr%)rg8ITkLJQg*IzH)vNGiCYYSQQT~-4XyLZn)6pKumr=5;CLW`63AArE;LERh#nC<_OL^sPd<^ zP70)An}J;PrGdg*+}*BDL`JMXy(xgBm__{bzApE9G*QL-~$lB&4& z`|wm!H`KB3+TX6f&q}0k?|hh*$YvICBE>ppz3GdAPUS?_2QeXu3frDvW^#H5X6=0c zeFcW4KwyB#CKpojsS~(J_#{jF7e`BUnPizz#vK$BQzkun`0$7CaX3nhnC)laVE-58 z7-mIk|2KtJNq@3Na9jW|a(8A9t{{$Hn5f%4SDX6eDQ~uVyzr#r(fC`bIVaW}Woq5Q zqI%lsXrpSyx##A3nAh^--h5=lzmKjM^-8k6CZqPH7uipM#Qbx4xr!E<>+R;%aLwyK zxEJ5=hgtfYbNnYh9DBzmu+t-ZWkjHy;4Ym!Tetc*X(xEK+6ry(q<;_j!)t;@SjQPx z#67WmnCo-8>{qYk^1cD(|A?v#44lVToa3ixFC1|9p0n)zFG|9ca~Bif4JYV5WN$f^);WwxTVL1Ae& zq2M`*kPP*75ADr5ap6KAhGR2Rm2Yio`SK;=8y^4~nSJ{Pu4z`j)N46($o=(eXn8an zG?$iE5T^!k-q<90@6>0{B;4z^hx?HzXc#~7UQDzZn&`=@KT%)e?G4TtDV|@eDK=3~ ziR3o#in886f52X9;_6ir#c_Qgnm>87Cq4HTfqIDPh}bcbcHgn<`6A7VoNf97mR;(I zF=I&&PA_NpGE=*R&EzlEebdSWXL#HX<80G$uQpJGL>cUb!bU87%3mcK?y68OYBbX2o!|HVg$FX?awWW)ga_k~=VdYT~@A zUrZtZk;Qo*gWStkUz$FMj$T-78$*i1OvPs&9o>UtLwrZt^8(BQl3c9WLL+Bnom|?Q zKEE`7J}V2qses}98Qi?e*W%SUf0AoxQ1q+vhTHCmgc|IFl;y8gG%be zL#gm%NlcQ}pu>d9)HHp*@3T`>)HG&cab{vmFVjmttw#>fa+Q_&K7VeqYV9VT_YyZ0 zGu<3{sOl$9*bFvZn0)JT8^(87deakwd$T*fG>o?QJv|*#Ggv6YxO)?mpQvS1;->G_ z$a|55Zt}wBCLY&Gs!rK``--1}S-_)h{B7{pz|8QVj&Nkrxy9E#{N72;Mx9pjac^zE z&yXnKJb=%9RLB7i!moynCM?hMG=KVZFh5h>XVRi7gu{J$2suq#w+1+aTwhX4Rax+t5X$5QMeT^EZ z6Qu3WR-^wSY+7)@p;sNH02)gp?RgYhhny_+_J;7OG)V9krTHaiPS}oGNe7R1q@eIg zNKcQo-zgk9-(4{kq{oi4St2hF8BR9*3~aT5h)-6mXLC*-J&2=OS(*vZ>dQ5)A5S;PR-8v?_L$AX)_(ke-@HAkb^yN!;<%hiv zzF~B<%biv3Ny{^QyvznRSwm~%b_DYBIWb6KrwJx{;h*+gS5gT zAN#9|OofRPq}_U-CBA)YYj`9!GY~f;=W4%P```nZ_xA@*uV>p|>^LA1`QdxsHLJQ$ z=RIbIOC?`?O`X$BY|aqJtjwOujWeU2TMfJq((n4$bmgQ$#5ml3;lnWn)<2~sOYZ%t zb|sV}PfOhY>=m*Wrv6;;3k=*Q{4PGB==PBoluBJoCaVz=*z%zncAbSC>tPDr{P&Gj zD4QmdHMwcto%xan4>C(WPfaZk2F{w^Re;(`%B8`Y_Aw+zff&u(5d<#qs`;6!@?FfW zOB;7eZrZiomkj5^)`0as4cZ7IX~BM7i%;|1C*_F;bZKN3eqDENMKC-= zM^UMwCAM|z1)BCH7Z*9NMLiL-ZkLJ4>B@Q@wF>9y>0QFuZ^C=d`|tcPyNjrMH6KMI z_L8%+vId8Ky{u`ftE~ltc3W%zQA0zu%6&-e(0yFD?uhA@FXwQW_GaXk42=di z-R$Gj&=VZond=<0nxg&Vn`T`{hv%p63I%XO|ISVT)~6~bO>6Tyx|})V;O9IEEr;p+ z;*1WTR=-0bo>b`leyyA7A&Z{`XHdao`gb+`J&A%{f7sCqWvfmvpKMAE@Ia40qbKAa zJbwHlA>k&ud%_iC+({HTe40&jylW1Ft&7!Ee{~L;53<|k9H8W6PW+l-!kzr3cfz&6 zXE0)a6p|WG&({IE*;|>nNo=ODI`&qNepfIsG~6Ra-tWO?9Y8AYy%?tPrw7|5^x&-QC7Bc;#gjh&tJx> z=qjy+0RBvfW_Wl~7j5gILmTTnQQqgf45|w)3<*NU+eJ;y(rk;GQ}8465Mf|2+YYT1 zq7Y3R(g8UBC3o(^760Lwe8>8d*p-Hqvu>7FYqsBA|6n7#klD@JUxJ5RY==U2+%{~j z*~S>=+Z=-_k1%xg>6^qXd%gC2n<;?C>>cXvQ+#X+@AS5o<=M6W?XJ+E^AenE>9oGm zr#uM!z!!Ea?C}^pRR$zs5k2q;UfsRd=uiE`o@rJ2G?-;-H-yu0Ucalj9pN>fW?$z| zMmFZpu~S@FT^1ByJj& zy0$+0kjAW_#=d=%69p4Jst#X~(XF^~1M!PjqrWx`i+#QWwEPH+@}dG>3Xqwb|L2Nb z6!KoPSOPL?x}^d_kUhg@hS^ZmJ%AywPe_y-iVWxe6*XLdF`lnD^ft}hPfF+VGVuCC zmtGjAIL0P+XHGRcXIESnZ<_(RWw+Sl4}GZgF`gqWyM4;_siVWifnES5x~~2p*h-hqT7SEnK_JvTJ`osN!pS&d)=oWHQYh1{`}ec4AVnS$S2Vv8pNzRwl8l4CJw{iWwPeDP4*Q{I-WpYMe zUl*oE4Z=rA$k%IKDG?JxV@mPwZ*68qM-$o8t0{*{e>!SA_47bwD0%G{5+| z(D7nqM8qDcOrKI;zwCAe&7+6iCS7RckX5L?SXo%O&{ZC|wuxGeroY-me8<-eW-7jn z+{#rv5~wO!49u6}sn$n6ctqVM<0at_e)qd5cTY>~caJ@?1zopXC<(P$=hZZF1ShzLKC+>*N%O{0!SYMUZ^}k`v8T1(?i7#_|mg0Yfdx0 zO1ehI5T(hr6PIQWop2J|ZE%5`%*85~cTe1=%?YuD_VMqvUpyhTz%9x*V06*M04_MB8%Cay zl7)pt1z~XB3dD#D8Hp&QE&L;PJqTmP$R!2}PmwE&5*a%&=76_s$YCtol`B`l6y;}k zH`hQ>=7+vFVt@#o{?@g6mzI(!!jT@cALB8?1GL}9ZVqOKAAum`6K5!RUTAk{y&>|C zcW?c{$ti5TivEPfXY92DLcY&d3 z-;0(H5yFD|_sebHy<7gRpXP_PYj5E-!O9eE18RQy%$ZxX4TcEfEIaQ+E^AC{8t-q@MdvrcyEN?_0iOh`jXqUYx>s&O9r1|+a< zQ)P`YatOuDG;QP_&=^kj`+b-)Ww`D`9L{LEffniSR81&Cu3IzR;UKO2G~zTATat0~ z;=T1zdw0AXdvGfEI4P}vC^_;)tm%uT@i^H~=1&w}KlRZ)dkO>^2rkC(pxDG(v67`7 z6kQyU9>e6v^)ct}oewh9U1^e$h;k@cb#bW6WY&CYlxf@yrs$${%; zuVmq=o2OSU_I$==Q6}NK0g}_0C#!rpd-0+Kz}Q#6BteNIQ~7!tvUFL^E1m&eNdx{4uiX_9F{hff++)c+aNog0mNnrE}DWF9pj z63b0Hexe@y=Ndo2Ml4lsO@rbKspHh-%`H}&cL$kHk2r)!;@6BB1`h$qJSn~D6A%EP z2r^GV0h7b5z)_%2SA>l@;7R)^g4=#MZTi+Jr;V$ovJ{5?JUlwHbNtzBib(zoshrUh zR}5?oOm3znbpCkcF4y+ktkIyq$6L30&$0IwqHoReP1|zBci7ZF9vkoB@ct$b*B1|$ zG2p^Xt9^m3!{cwa+>U!O4_cP$VV>fbYky%Z_HEJEbmLbTn{m(B*7CxiKVQX|sqE|- z-90@Psj|qh?%flkUPdGJAVSxnL-anosYy@}O;4ZpBQxz5E&uqDO!Mc5V}5DXT231Fl4tW7787SglgxV!z*U9v1Eur7^r2_?h*;fI7jmJ zte72|Z^WbBnRkQ^J=SWWcpDt$HBGNOE%8$du6-N0OIf0}d4*H2%+nq@n+-um-PB?1D3Zc3oMyb0uy0+Yj^Et?@_(Z50wysgNJSnzX0%^Sc`7b9i_i1^X}Z7G)G@ObgxFsj1fOU(ztX1eP+^w*B{XK6p;m4?Bzn(WKf<3}p%L+;%EFyYQAud}cw4xD$KQ&Rt%)Xo5IVJ=<8(yxiE~(z?+zx1 zYU#;%c+d!{e*=dLedSwY;rz_Zca@bF8#}%J3C&KXEW36g;n}!rJJmLEN6(nDow>P# zsId3PA8#*7;v}dzn2b_Y_p_G8iIkMW_KKHNvfnM&>@n^FiAZ3Jy zaGL?7|2L@OeQa`vXJ=o(_+`=51Z7 zXDbmSVJmv>3fL^O(aTdqXHUF{FhTTuLS9bKY;J1G_E}!aZijma?xSb)h~>_I;IpS; zz{C746q>f>F;Qx@ji&2BA-(&N7GCK`7uaQtp(n`kNlB_nr=ZTq14ifaOSg!VXPGOY z&N<>4k4x-M%_V=b=foc}$%CLUP-501&;Y4{&qgZRZyMW&tY#IveYFXQTG*lWhWJQJ&7A)} o8u4dORw?~cQT>1a_u}S>c4_k1U3QpXFfbfd)l^BRp7s5|02$W<`Tzg` literal 0 HcmV?d00001 diff --git a/static/nginxaas-azure/azure-metrics-nginxaas.certificates.png b/static/nginxaas-azure/azure-metrics-nginxaas.certificates.png new file mode 100644 index 0000000000000000000000000000000000000000..f909392abd478659c60505b9ecb25abea70cbcfe GIT binary patch literal 36582 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 vvcq literal 0 HcmV?d00001 diff --git a/static/nginxaas-azure/create-case.png b/static/nginxaas-azure/create-case.png new file mode 100644 index 0000000000000000000000000000000000000000..9edafb5b693179ff1aa5ee2cee18b7d2418ff74e GIT binary patch literal 28119 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 summary { + list-style: none; + padding-left: 20px; + margin: 20px 2px; + text-decoration: underline; + color: #515357; +} +#calculator details > summary::before { + content: "\FF0B"; + border: 2px solid gray; + display: inline-flex; + justify-content: center; + align-items: center; + position: absolute; + top: 2px; + left: 0; + height: 11px; + width: 11px; + font-size: 10px; + font-weight: 600; + border-radius: 50%; + text-decoration: none; +} +#calculator details[open] > summary::before { + content: "\FF0D"; +} + +#calculator .details-content { + padding: 10px; + display: flex; + + width: 100%; +} + +#calculator .details-section { + padding: 10px; + background-color: rgba(217, 217, 217, 0.1); + margin-right: 10px; + flex: 1; +} +#calculator .details-section:first-child { + flex: 2; +} + +#calculator .bandwidth-input-container::after { + content: "Mbps"; + color: #6C778C; + font-size: 12px; + margin-left: -60px; +} +#calculator .avg-conn-duration-container::after { + content: "seconds"; + color: #6C778C; + font-size: 12px; + margin-left: -70px; +} + +#calculator #ncuEstimateValue { + /* display: flex; */ + /* align-items: center; */ + /* justify-content: center; */ + font-weight: 700; +} + +#calculator input:invalid + #ncuValidation::after { + content: "Must be a multiple of 10, with a minimum of 10"; + color: #aa0000; + padding-left: 5px; + font-size: 12px; +} + +#calculator .totals { + display: flex; + justify-content: left; +} +#calculator .totals > span { + margin-right: 20px; +} + + +#calculator table { + margin: 0 auto; + border-collapse: collapse; +} + +#calculator th { + padding-bottom: 16px; +} + +#calculator tr.selected { + background-color: #e9f3ea; +} + + +#calculator .math { + font-weight: 300; + font-size: 12px; + background-color: #f7f7f7; + + margin: 8px 0 4px 0; + padding: 8px; +} + +#calculator pre { + font-family: inherit; +} + +#calculator var { + font-family: inherit; + font-weight: bolder; +} + +#calculator .titleCol { + font-weight: 400; + vertical-align: bottom; +} + +#calculator dt { + margin: 24px 0 8px 0; +} +#calculator dd { + margin-bottom: 8px; +} + +#calculator h3 { + display: flex; + justify-content: space-between; +} + +#calculator h3 label { + font-size: 14px; + width: 40%; + text-align: right; +} +#calculator h3 label input { + width: 20px; + vertical-align: middle; +} + +/* added for iteration 3 */ + +#calculator .form-section { + border: 1px solid #B7B7B7; + border-radius: 4px; + margin-bottom: 20px; +} +#calculator .form-section h4 { + font-weight: 600; +} +#calculator .form-section-content { + padding: 20px 18px; +} +#calculator .form-section-content:last-child { + padding-bottom: 18px; + border-top: 1px solid #B7B7B7; +} + +@media print { + body { + visibility: hidden; + height: 0; + } + + footer { + display: none; + } + + #calculator { + visibility: visible; + position: absolute; + top: 20px; + + margin: 0 auto; + + width: 100%; + } + + #calculator h3#calculator-section-heading { + justify-content: left; + } + + #calculator h3#calculator-section-heading button { + visibility: hidden; + } + + #calculator-section-heading::before { + content: "NGINX as a Service for Azure\00a0" + } +} diff --git a/static/nginxaas-azure/deployment-complete.png b/static/nginxaas-azure/deployment-complete.png new file mode 100644 index 0000000000000000000000000000000000000000..09feb295f4280149a1bf9e94e3d2495d924427bf GIT binary patch literal 74095 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%0D=`&l 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 z