diff --git a/.azuredevops/modulePipelines/ms.network.applicationgatewaywebapplicationfirewallpolicies.yml b/.azuredevops/modulePipelines/ms.network.applicationgatewaywebapplicationfirewallpolicies.yml new file mode 100644 index 0000000000..3bce6f820b --- /dev/null +++ b/.azuredevops/modulePipelines/ms.network.applicationgatewaywebapplicationfirewallpolicies.yml @@ -0,0 +1,40 @@ +name: 'Network: ApplicationGatewayWebApplicationFirewallPolicies' + +parameters: + - name: removeDeployment + displayName: Remove deployed module + type: boolean + default: true + - name: prerelease + displayName: Publish prerelease module + type: boolean + default: false + +pr: none + +trigger: + batch: true + branches: + include: + - main + paths: + include: + - '/.azuredevops/modulePipelines/ms.network.applicationGatewayWebApplicationFirewallPolicies' + - '/.azuredevops/pipelineTemplates/*.yml' + - '/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/*' + - '/utilities/pipelines/*' + exclude: + - '/utilities/pipelines/dependencies/*' + - '/**/*.md' + +variables: + - template: '../../settings.yml' + - group: 'PLATFORM_VARIABLES' + - name: modulePath + value: '/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies' + +stages: + - template: /.azuredevops/pipelineTemplates/stages.module.yml + parameters: + removeDeployment: '${{ parameters.removeDeployment }}' + prerelease: '${{ parameters.prerelease }}' diff --git a/.github/workflows/ms.network.applicationgatewaywebapplicationfirewallpolicies.yml b/.github/workflows/ms.network.applicationgatewaywebapplicationfirewallpolicies.yml new file mode 100644 index 0000000000..025f704afe --- /dev/null +++ b/.github/workflows/ms.network.applicationgatewaywebapplicationfirewallpolicies.yml @@ -0,0 +1,145 @@ +name: 'Network: ApplicationGatewayWebApplicationFirewallPolicies' + +on: + workflow_dispatch: + inputs: + removeDeployment: + type: boolean + description: 'Remove deployed module' + required: false + default: true + prerelease: + type: boolean + description: 'Publish prerelease module' + required: false + default: false + push: + branches: + - main + paths: + - '.github/actions/templates/**' + - '.github/workflows/ms.network.applicationgatewaywebapplicationfirewallpolicies.yml' + - 'modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/**' + - 'utilities/pipelines/**' + - '!utilities/pipelines/dependencies/**' + - '!*/**/readme.md' + +env: + variablesPath: 'settings.yml' + modulePath: 'modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies' + workflowPath: '.github/workflows/ms.network.applicationgatewaywebapplicationfirewallpolicies.yml' + AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} + ARM_SUBSCRIPTION_ID: '${{ secrets.ARM_SUBSCRIPTION_ID }}' + ARM_MGMTGROUP_ID: '${{ secrets.ARM_MGMTGROUP_ID }}' + ARM_TENANT_ID: '${{ secrets.ARM_TENANT_ID }}' + TOKEN_NAMEPREFIX: '${{ secrets.TOKEN_NAMEPREFIX }}' + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-20.04 + name: 'Initialize pipeline' + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'Set input parameters to output variables' + id: get-workflow-param + uses: ./.github/actions/templates/getWorkflowInput + with: + workflowPath: '${{ env.workflowPath}}' + - name: 'Get parameter file paths' + id: get-module-test-file-paths + uses: ./.github/actions/templates/getModuleTestFiles + with: + modulePath: '${{ env.modulePath }}' + outputs: + removeDeployment: ${{ steps.get-workflow-param.outputs.removeDeployment }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + + ######################### + # Static validation # + ######################### + job_module_pester_validation: + runs-on: ubuntu-20.04 + name: 'Static validation' + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set environment variables + uses: ./.github/actions/templates/setEnvironmentVariables + with: + variablesPath: ${{ env.variablesPath }} + - name: 'Run tests' + uses: ./.github/actions/templates/validateModulePester + with: + modulePath: '${{ env.modulePath }}' + moduleTestFilePath: '${{ env.moduleTestFilePath }}' + + ############################# + # Deployment validation # + ############################# + job_module_deploy_validation: + runs-on: ubuntu-20.04 + name: 'Deployment validation' + needs: + - job_initialize_pipeline + - job_module_pester_validation + strategy: + fail-fast: false + matrix: + moduleTestFilePaths: ${{ fromJSON(needs.job_initialize_pipeline.outputs.moduleTestFilePaths) }} + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set environment variables + uses: ./.github/actions/templates/setEnvironmentVariables + with: + variablesPath: ${{ env.variablesPath }} + - name: 'Using test file [${{ matrix.moduleTestFilePaths }}]' + uses: ./.github/actions/templates/validateModuleDeployment + with: + templateFilePath: '${{ env.modulePath }}/${{ matrix.moduleTestFilePaths }}' + location: '${{ env.location }}' + resourceGroupName: '${{ env.resourceGroupName }}' + subscriptionId: '${{ secrets.ARM_SUBSCRIPTION_ID }}' + managementGroupId: '${{ secrets.ARM_MGMTGROUP_ID }}' + removeDeployment: '${{ needs.job_initialize_pipeline.outputs.removeDeployment }}' + + ################## + # Publishing # + ################## + job_publish_module: + name: 'Publishing' + if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master' || github.event.inputs.prerelease == 'true' + runs-on: ubuntu-20.04 + needs: + - job_module_deploy_validation + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Set environment variables + uses: ./.github/actions/templates/setEnvironmentVariables + with: + variablesPath: ${{ env.variablesPath }} + - name: 'Publishing' + uses: ./.github/actions/templates/publishModule + with: + templateFilePath: '${{ env.modulePath }}/deploy.bicep' + templateSpecsRGName: '${{ env.templateSpecsRGName }}' + templateSpecsRGLocation: '${{ env.templateSpecsRGLocation }}' + templateSpecsDescription: '${{ env.templateSpecsDescription }}' + templateSpecsDoPublish: '${{ env.templateSpecsDoPublish }}' + bicepRegistryName: '${{ env.bicepRegistryName }}' + bicepRegistryRGName: '${{ env.bicepRegistryRGName }}' + bicepRegistryRgLocation: '${{ env.bicepRegistryRgLocation }}' + bicepRegistryDoPublish: '${{ env.bicepRegistryDoPublish }}' diff --git a/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/.test/common/deploy.test.bicep b/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/.test/common/deploy.test.bicep new file mode 100644 index 0000000000..9a2c20a646 --- /dev/null +++ b/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/.test/common/deploy.test.bicep @@ -0,0 +1,56 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'ms.network.applicationGatewayWebApplicationFirewallPolicies-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nagwafpcom' + +// =========== // +// Deployments // +// =========== // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../deploy.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name)}-test-${serviceShort}' + params: { + name: '<>${serviceShort}001' + policySettings: { + fileUploadLimitInMb: 10 + state: 'Enabled' + mode: 'Prevention' + } + managedRules: { + managedRuleSets: [ + { + ruleSetType: 'OWASP' + ruleSetVersion: '3.2' + ruleGroupOverrides: [] + } + { + ruleSetType: 'Microsoft_BotManagerRuleSet' + ruleSetVersion: '0.1' + ruleGroupOverrides: [] + } + ] + } + } +} diff --git a/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/deploy.bicep b/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/deploy.bicep new file mode 100644 index 0000000000..8a34607d08 --- /dev/null +++ b/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/deploy.bicep @@ -0,0 +1,55 @@ +@description('Required. Name of the Application Gateway WAF policy.') +param name string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. Resource tags.') +param tags object = {} + +@description('Optional. Enable telemetry via the Customer Usage Attribution ID (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. Describes the managedRules structure.') +param managedRules object = {} + +@description('Optional. The custom rules inside the policy.') +param customRules array = [] + +@description('Optional. The PolicySettings for policy.') +param policySettings object = {} + +resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (enableDefaultTelemetry) { + name: 'pid-47ed15a6-730a-4827-bcb4-0fd963ffbd82-${uniqueString(deployment().name, location)}' + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + } + } +} + +resource applicationGatewayWAFPolicy 'Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies@2022-01-01' = { + name: name + location: location + tags: tags + properties: { + managedRules: managedRules + customRules: customRules + policySettings: policySettings + } +} + +@description('The name of the application gateway WAF policy.') +output name string = applicationGatewayWAFPolicy.name + +@description('The resource ID of the application gateway WAF policy.') +output resourceId string = applicationGatewayWAFPolicy.id + +@description('The resource group the application gateway WAF policy was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = applicationGatewayWAFPolicy.location diff --git a/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/readme.md b/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/readme.md new file mode 100644 index 0000000000..d6d04cab8e --- /dev/null +++ b/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/readme.md @@ -0,0 +1,185 @@ +# `[Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies]` + +This module deploys a WAF policy. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Deployment examples](#Deployment-examples) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies` | [2022-01-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-01-01/ApplicationGatewayWebApplicationFirewallPolicies) | + +## Parameters + +**Required parameters** + +| Parameter Name | Type | Description | +| :-- | :-- | :-- | +| `name` | string | Name of the Application Gateway WAF policy. | + +**Optional parameters** + +| Parameter Name | Type | Default Value | Description | +| :-- | :-- | :-- | :-- | +| `customRules` | array | `[]` | The custom rules inside the policy. | +| `enableDefaultTelemetry` | bool | `True` | Enable telemetry via the Customer Usage Attribution ID (GUID). | +| `location` | string | `[resourceGroup().location]` | Location for all resources. | +| `managedRules` | object | `{object}` | Describes the managedRules structure. | +| `policySettings` | object | `{object}` | The PolicySettings for policy. | +| `tags` | object | `{object}` | Resource tags. | + + +### Parameter Usage: `` + +// TODO: Fill in Parameter usage + +### Parameter Usage: `tags` + +Tag names and tag values can be provided as needed. A tag can be left without a value. + +
+ +Parameter JSON format + +```json +"tags": { + "value": { + "Environment": "Non-Prod", + "Contact": "test.user@testcompany.com", + "PurchaseOrder": "1234", + "CostCenter": "7890", + "ServiceName": "DeploymentValidation", + "Role": "DeploymentValidation" + } +} +``` + +
+ +
+ +Bicep format + +```bicep +tags: { + Environment: 'Non-Prod' + Contact: 'test.user@testcompany.com' + PurchaseOrder: '1234' + CostCenter: '7890' + ServiceName: 'DeploymentValidation' + Role: 'DeploymentValidation' +} +``` + +
+

+ +## Outputs + +| Output Name | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the application gateway WAF policy. | +| `resourceGroupName` | string | The resource group the application gateway WAF policy was deployed into. | +| `resourceId` | string | The resource ID of the application gateway WAF policy. | + +## Cross-referenced modules + +_None_ + +## Deployment examples + +The following module usage examples are retrieved from the content of the files hosted in the module's `.test` folder. + >**Note**: The name of each example is based on the name of the file from which it is taken. + + >**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +

Example 1: Common

+ +
+ +via Bicep module + +```bicep +module applicationGatewayWebApplicationFirewallPolicies './Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/deploy.bicep' = { + name: '${uniqueString(deployment().name)}-test-wafpolicy' + params: { + // Required parameters + name: '<>wafpolicy001' + // Non-required parameters + managedRules: { + managedRuleSets: [ + { + ruleGroupOverrides: [] + ruleSetType: 'OWASP' + ruleSetVersion: '3.2' + } + { + ruleGroupOverrides: [] + ruleSetType: 'Microsoft_BotManagerRuleSet' + ruleSetVersion: '0.1' + } + ] + } + policySettings: { + fileUploadLimitInMb: 10 + mode: 'Prevention' + state: 'Enabled' + } + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "<>wafpolicy001" + }, + // Non-required parameters + "managedRules": { + "value": { + "managedRuleSets": [ + { + "ruleGroupOverrides": [], + "ruleSetType": "OWASP", + "ruleSetVersion": "3.2" + }, + { + "ruleGroupOverrides": [], + "ruleSetType": "Microsoft_BotManagerRuleSet", + "ruleSetVersion": "0.1" + } + ] + } + }, + "policySettings": { + "value": { + "fileUploadLimitInMb": 10, + "mode": "Prevention", + "state": "Enabled" + } + } + } +} +``` + +
+

diff --git a/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/version.json b/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/version.json new file mode 100644 index 0000000000..badc0a2285 --- /dev/null +++ b/modules/Microsoft.Network/applicationGatewayWebApplicationFirewallPolicies/version.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", + "version": "0.5" +}