diff --git a/.azuredevops/modulePipelines/ms.network.networkinterfaces.yml b/.azuredevops/modulePipelines/ms.network.networkinterfaces.yml new file mode 100644 index 0000000000..b4c77b7569 --- /dev/null +++ b/.azuredevops/modulePipelines/ms.network.networkinterfaces.yml @@ -0,0 +1,55 @@ +name: 'Network - NetworkInterfaces' + +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.networkinterfaces.yml' + - '/.azuredevops/pipelineTemplates/module.*.yml' + - '/arm/Microsoft.Network/networkInterfaces/*' + - '/arm/.global/global.module.tests.ps1' + exclude: + - '/**/*.md' + +variables: + - template: '../../global.variables.yml' + - group: 'PLATFORM_VARIABLES' + - name: modulePath + value: '/arm/Microsoft.Network/networkInterfaces' + +stages: + - stage: Validation + displayName: Static validation + jobs: + - template: /.azuredevops/pipelineTemplates/jobs.validateModulePester.yml + + - stage: Deployment + displayName: Deployment validation + jobs: + - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml + parameters: + removeDeployment: '${{ parameters.removeDeployment }}' + deploymentBlocks: + - path: $(modulePath)/.parameters/min.parameters.json + - path: $(modulePath)/.parameters/parameters.json + + - stage: Publishing + displayName: Publishing + condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/main'), eq(variables['Build.SourceBranch'], 'refs/heads/master'), eq('${{ parameters.prerelease }}', 'true'))) + jobs: + - template: /.azuredevops/pipelineTemplates/jobs.publishModule.yml diff --git a/.github/workflows/ms.network.networkinterfaces.yml b/.github/workflows/ms.network.networkinterfaces.yml new file mode 100644 index 0000000000..feda3575e3 --- /dev/null +++ b/.github/workflows/ms.network.networkinterfaces.yml @@ -0,0 +1,142 @@ +name: 'Network: NetworkInterfaces' + +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.networkinterfaces.yml' + - 'arm/Microsoft.Network/networkInterfaces/**' + - 'arm/.global/global.module.tests.ps1' + - '!*/**/readme.md' + - 'utilities/pipelines/**' + - '!utilities/pipelines/dependencies/**' + +env: + variablesPath: 'global.variables.yml' + modulePath: 'arm/Microsoft.Network/networkInterfaces' + workflowPath: '.github/workflows/ms.network.networkinterfaces.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 }}' + DEPLOYMENT_SP_ID: '${{ secrets.DEPLOYMENT_SP_ID }}' + +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-parameter-file-paths + uses: ./.github/actions/templates/getParameterFiles + with: + modulePath: '${{ env.modulePath }}' + outputs: + removeDeployment: ${{ steps.get-workflow-param.outputs.removeDeployment }} + parameterFilePaths: ${{ steps.get-parameter-file-paths.outputs.parameterFilePaths }} + + ######################### + # 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: 'Run tests' + uses: ./.github/actions/templates/validateModulePester + with: + modulePath: '${{ env.modulePath }}' + + ############################# + # 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: + parameterFilePaths: ${{ fromJSON(needs.job_initialize_pipeline.outputs.parameterFilePaths) }} + 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 parameter file [${{ matrix.parameterFilePaths }}]' + uses: ./.github/actions/templates/validateModuleDeployment + with: + templateFilePath: '${{ env.modulePath }}/deploy.bicep' + parameterFilePath: '${{ env.modulePath }}/${{ matrix.parameterFilePaths }}' + 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/arm/.global/global.module.tests.ps1 b/arm/.global/global.module.tests.ps1 index 52fd8a4fb3..133a967ae4 100644 --- a/arm/.global/global.module.tests.ps1 +++ b/arm/.global/global.module.tests.ps1 @@ -49,8 +49,8 @@ Describe 'File/folder tests' -Tag Modules { $workflowsFolderName = Join-Path $RepoRoot '.github' 'workflows' $workflowFileName = '{0}.yml' -f $moduleFolderName.Replace('\', '/').Replace('/', '.').Replace('Microsoft', 'ms').ToLower() - - Test-Path (Join-Path $workflowsFolderName $workflowFileName) | Should -Be $true + $workflowPath = Join-Path $workflowsFolderName $workflowFileName + Test-Path $workflowPath | Should -Be $true -Because "path [$workflowPath] should exist." } } @@ -64,8 +64,8 @@ Describe 'File/folder tests' -Tag Modules { $pipelinesFolderName = Join-Path $RepoRoot '.azuredevops' 'modulePipelines' $pipelineFileName = '{0}.yml' -f $moduleFolderName.Replace('\', '/').Replace('/', '.').Replace('Microsoft', 'ms').ToLower() - - Test-Path (Join-Path $pipelinesFolderName $pipelineFileName) | Should -Be $true + $pipelinePath = Join-Path $pipelinesFolderName $pipelineFileName + Test-Path $pipelinePath | Should -Be $true -Because "path [$pipelinePath] should exist." } } diff --git a/arm/Microsoft.Network/networkInterfaces/.bicep/nested_rbac.bicep b/arm/Microsoft.Network/networkInterfaces/.bicep/nested_rbac.bicep new file mode 100644 index 0000000000..e66a728227 --- /dev/null +++ b/arm/Microsoft.Network/networkInterfaces/.bicep/nested_rbac.bicep @@ -0,0 +1,63 @@ +@sys.description('Required. The IDs of the principals to assign the role to.') +param principalIds array + +@sys.description('Required. The name of the role to assign. If it cannot be found you can specify the role definition ID instead.') +param roleDefinitionIdOrName string + +@sys.description('Required. The resource ID of the resource to apply the role assignment to.') +param resourceId string + +@sys.description('Optional. The principal type of the assigned principal ID.') +@allowed([ + 'ServicePrincipal' + 'Group' + 'User' + 'ForeignGroup' + 'Device' + '' +]) +param principalType string = '' + +@sys.description('Optional. The description of the role assignment.') +param description string = '' + +var builtInRoleNames = { + 'Owner': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '8e3af657-a8ff-443c-a75c-2fe8c4bcb635') + 'Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c') + 'Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'acdd72a7-3385-48ef-bd42-f606fba81ae7') + 'Avere Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4f8fab4f-1852-4a58-a46a-8eaf358af14a') + 'Avere Operator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c025889f-8102-4ebf-b32c-fc0c6f0c6bd9') + 'DevTest Labs User': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '76283e04-6283-4c54-8f91-bcf1374a3c64') + 'Domain Services Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'eeaeda52-9324-47f6-8069-5d5bade478b2') + 'Domain Services Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '361898ef-9ed1-48c2-849c-a832951106bb') + 'Log Analytics Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '92aaf0da-9dab-42b6-94a3-d43ce8d16293') + 'Log Analytics Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '73c42c96-874c-492b-b04d-ab87d138a893') + 'Managed Application Contributor Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '641177b8-a67a-45b9-a033-47bc880bb21e') + 'Managed Application Operator Role': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'c7393b34-138c-406f-901b-d8cf2b17e6ae') + 'Managed Applications Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b9331d33-8a36-4f8c-b097-4f54124fdb44') + 'Monitoring Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '749f88d5-cbae-40b8-bcfc-e573ddc772fa') + 'Monitoring Metrics Publisher': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '3913510d-42f4-4e42-8a64-420c390055eb') + 'Monitoring Reader': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '43d0d8ad-25c7-4714-9337-8ba259a9fe05') + 'Network Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4d97b98b-1d4f-4787-a291-c67834d212e7') + 'Resource Policy Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '36243c78-bf99-498c-9df9-86d9f8d28608') + 'User Access Administrator': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '18d7d88d-d35e-4fb5-a5c3-7773c20a72d9') + 'Virtual Machine Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '1c0163c0-47e6-4577-8991-ea5c82e286e4') + 'Virtual Machine Contributor': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '9980e02c-c2be-4d73-94e8-173b1dc7cf3c') + 'Virtual Machine User Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'fb879df8-f326-4884-b1cf-06f3ad86be52') + 'Windows Admin Center Administrator Login': subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'a6333a3e-0164-44c3-b281-7a577aff287f') +} + +resource networkInterface 'Microsoft.Network/networkInterfaces@2021-08-01' existing = { + name: last(split(resourceId, '/')) +} + +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-10-01-preview' = [for principalId in principalIds: { + name: guid(networkInterface.id, principalId, roleDefinitionIdOrName) + properties: { + description: description + roleDefinitionId: contains(builtInRoleNames, roleDefinitionIdOrName) ? builtInRoleNames[roleDefinitionIdOrName] : roleDefinitionIdOrName + principalId: principalId + principalType: any(!empty(principalType) ? principalType : null) + } + scope: networkInterface +}] diff --git a/arm/Microsoft.Network/networkInterfaces/.parameters/min.parameters.json b/arm/Microsoft.Network/networkInterfaces/.parameters/min.parameters.json new file mode 100644 index 0000000000..9fe27817ce --- /dev/null +++ b/arm/Microsoft.Network/networkInterfaces/.parameters/min.parameters.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "value": "<>-az-nic-min-001" + }, + "ipConfigurations": { + "value": [ + { + "name": "ipconfig01", + "subnetId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-001" + } + ] + } + } +} diff --git a/arm/Microsoft.Network/networkInterfaces/.parameters/parameters.json b/arm/Microsoft.Network/networkInterfaces/.parameters/parameters.json new file mode 100644 index 0000000000..7eb7ebc50f --- /dev/null +++ b/arm/Microsoft.Network/networkInterfaces/.parameters/parameters.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "value": "<>-az-nic-x-001" + }, + "roleAssignments": { + "value": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "<>" + ] + } + ] + }, + "ipConfigurations": { + "value": [ + { + "name": "ipconfig01", + "subnetId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-001", + "loadBalancerBackendAddressPools": [ + { + "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/loadBalancers/adp-<>-az-lb-internal-001/backendAddressPools/servers" + } + ], + "applicationSecurityGroups": [ + { + "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/applicationSecurityGroups/adp-<>-az-asg-x-001" + } + ] + } + ] + }, + "diagnosticLogsRetentionInDays": { + "value": 7 + }, + "diagnosticStorageAccountId": { + "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001" + }, + "diagnosticWorkspaceId": { + "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-az-law-x-001" + }, + "diagnosticEventHubAuthorizationRuleId": { + "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-<>-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey" + }, + "diagnosticEventHubName": { + "value": "adp-<>-az-evh-x-001" + } + } +} diff --git a/arm/Microsoft.Network/networkInterfaces/deploy.bicep b/arm/Microsoft.Network/networkInterfaces/deploy.bicep new file mode 100644 index 0000000000..611c37b801 --- /dev/null +++ b/arm/Microsoft.Network/networkInterfaces/deploy.bicep @@ -0,0 +1,168 @@ +@description('Required. The name of the network interface.') +param name string + +@description('Optional. Location for all resources.') +param location string = resourceGroup().location + +@description('Optional. Tags of the resource.') +param tags object = {} + +@description('Optional. Enable telemetry via the Customer Usage Attribution ID (GUID).') +param enableDefaultTelemetry bool = true + +@description('Optional. Indicates whether IP forwarding is enabled on this network interface.') +param enableIPForwarding bool = false + +@description('Optional. If the network interface is accelerated networking enabled.') +param enableAcceleratedNetworking bool = false + +@description('Optional. List of DNS servers IP addresses. Use \'AzureProvidedDNS\' to switch to azure provided DNS resolution. \'AzureProvidedDNS\' value cannot be combined with other IPs, it must be the only value in dnsServers collection.') +param dnsServers array = [] + +@description('Optional. The network security group (NSG) to attach to the network interface.') +param networkSecurityGroupResourceId string = '' + +@description('Required. A list of IPConfigurations of the network interface.') +param ipConfigurations array + +@allowed([ + 'CanNotDelete' + 'NotSpecified' + 'ReadOnly' +]) +@description('Optional. Specify the type of lock.') +param lock string = 'NotSpecified' + +@description('Optional. Array of role assignment objects that contain the \'roleDefinitionIdOrName\' and \'principalId\' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: \'/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11\'.') +param roleAssignments array = [] + +@description('Optional. Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely.') +@minValue(0) +@maxValue(365) +param diagnosticLogsRetentionInDays int = 365 + +@description('Optional. Resource ID of the diagnostic storage account.') +param diagnosticStorageAccountId string = '' + +@description('Optional. Resource identifier of log analytics.') +param diagnosticWorkspaceId string = '' + +@description('Optional. Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to.') +param diagnosticEventHubAuthorizationRuleId string = '' + +@description('Optional. Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category.') +param diagnosticEventHubName string = '' + +@description('Optional. The name of metrics that will be streamed.') +@allowed([ + 'AllMetrics' +]) +param diagnosticMetricsToEnable array = [ + 'AllMetrics' +] + +@description('Optional. The name of the diagnostic setting, if deployed.') +param diagnosticSettingsName string = '${name}-diagnosticSettings' + +var diagnosticsMetrics = [for metric in diagnosticMetricsToEnable: { + category: metric + timeGrain: null + enabled: true + retentionPolicy: { + enabled: true + days: diagnosticLogsRetentionInDays + } +}] + +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 networkInterface 'Microsoft.Network/networkInterfaces@2021-05-01' = { + name: name + location: location + tags: tags + properties: { + enableIPForwarding: enableIPForwarding + enableAcceleratedNetworking: enableAcceleratedNetworking + dnsSettings: !empty(dnsServers) ? { + dnsServers: dnsServers + } : null + networkSecurityGroup: !empty(networkSecurityGroupResourceId) ? { + id: networkSecurityGroupResourceId + } : null + ipConfigurations: [for (ipConfiguration, index) in ipConfigurations: { + name: !empty(ipConfiguration.name) ? ipConfiguration.name : null + properties: { + primary: index == 0 ? true : false + privateIPAllocationMethod: contains(ipConfiguration, 'privateIPAllocationMethod') ? (!empty(ipConfiguration.privateIPAllocationMethod) ? ipConfiguration.privateIPAllocationMethod : null) : null + privateIPAddress: contains(ipConfiguration, 'vmIPAddress') ? (!empty(ipConfiguration.vmIPAddress) ? ipConfiguration.vmIPAddress : null) : null + publicIPAddress: contains(ipConfiguration, 'publicIPAddressResourceId') ? { + id: ipConfiguration.publicIPAddressResourceId + } : null + subnet: { + id: ipConfiguration.subnetId + } + loadBalancerBackendAddressPools: contains(ipConfiguration, 'loadBalancerBackendAddressPools') ? ipConfiguration.loadBalancerBackendAddressPools : null + applicationSecurityGroups: contains(ipConfiguration, 'applicationSecurityGroups') ? ipConfiguration.applicationSecurityGroups : null + applicationGatewayBackendAddressPools: contains(ipConfiguration, 'applicationGatewayBackendAddressPools') ? ipConfiguration.applicationGatewayBackendAddressPools : null + gatewayLoadBalancer: contains(ipConfiguration, 'gatewayLoadBalancer') ? ipConfiguration.gatewayLoadBalancer : null + loadBalancerInboundNatRules: contains(ipConfiguration, 'loadBalancerInboundNatRules') ? ipConfiguration.loadBalancerInboundNatRules : null + privateIPAddressVersion: contains(ipConfiguration, 'privateIPAddressVersion') ? ipConfiguration.privateIPAddressVersion : null + virtualNetworkTaps: contains(ipConfiguration, 'virtualNetworkTaps') ? ipConfiguration.virtualNetworkTaps : null + } + }] + } +} + +resource networkInterface_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if (!empty(diagnosticStorageAccountId) || !empty(diagnosticWorkspaceId) || !empty(diagnosticEventHubAuthorizationRuleId) || !empty(diagnosticEventHubName)) { + name: diagnosticSettingsName + properties: { + storageAccountId: !empty(diagnosticStorageAccountId) ? diagnosticStorageAccountId : null + workspaceId: !empty(diagnosticWorkspaceId) ? diagnosticWorkspaceId : null + eventHubAuthorizationRuleId: !empty(diagnosticEventHubAuthorizationRuleId) ? diagnosticEventHubAuthorizationRuleId : null + eventHubName: !empty(diagnosticEventHubName) ? diagnosticEventHubName : null + metrics: diagnosticsMetrics + } + scope: networkInterface +} + +resource networkInterface_lock 'Microsoft.Authorization/locks@2017-04-01' = if (lock != 'NotSpecified') { + name: '${networkInterface.name}-${lock}-lock' + properties: { + level: lock + notes: lock == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot modify the resource or child resources.' + } + scope: networkInterface +} + +module networkInterface_rbac '.bicep/nested_rbac.bicep' = [for (roleAssignment, index) in roleAssignments: { + name: '${uniqueString(deployment().name, location)}-NIC-Rbac-${index}' + params: { + description: contains(roleAssignment, 'description') ? roleAssignment.description : '' + principalIds: roleAssignment.principalIds + principalType: contains(roleAssignment, 'principalType') ? roleAssignment.principalType : '' + roleDefinitionIdOrName: roleAssignment.roleDefinitionIdOrName + resourceId: networkInterface.id + } +}] + +@description('The name of the deployed resource.') +output name string = networkInterface.name + +@description('The resource ID of the deployed resource.') +output resourceId string = networkInterface.id + +@description('The resource group of the deployed resource.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = networkInterface.location diff --git a/arm/Microsoft.Network/networkInterfaces/readme.md b/arm/Microsoft.Network/networkInterfaces/readme.md new file mode 100644 index 0000000000..d8294ae6e8 --- /dev/null +++ b/arm/Microsoft.Network/networkInterfaces/readme.md @@ -0,0 +1,120 @@ +# Network Interface `[Microsoft.Network/networkInterfaces]` + +This module deploys Network Interfaces. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2017-04-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2017-04-01/locks) | +| `Microsoft.Authorization/roleAssignments` | [2020-10-01-preview](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-10-01-preview/roleAssignments) | +| `Microsoft.Insights/diagnosticSettings` | [2021-05-01-preview](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Insights/2021-05-01-preview/diagnosticSettings) | +| `Microsoft.Network/networkInterfaces` | [2021-05-01](https://docs.microsoft.com/en-us/azure/templates/Microsoft.Network/2021-05-01/networkInterfaces) | + +## Parameters + +**Required parameters** +| Parameter Name | Type | Description | +| :-- | :-- | :-- | +| `ipConfigurations` | array | A list of IPConfigurations of the network interface. | +| `name` | string | The name of the network interface. | + +**Optional parameters** +| Parameter Name | Type | Default Value | Allowed Values | Description | +| :-- | :-- | :-- | :-- | :-- | +| `diagnosticEventHubAuthorizationRuleId` | string | `''` | | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | +| `diagnosticEventHubName` | string | `''` | | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | +| `diagnosticLogsRetentionInDays` | int | `365` | | Specifies the number of days that logs will be kept for; a value of 0 will retain data indefinitely. | +| `diagnosticMetricsToEnable` | array | `[AllMetrics]` | `[AllMetrics]` | The name of metrics that will be streamed. | +| `diagnosticSettingsName` | string | `[format('{0}-diagnosticSettings', parameters('name'))]` | | The name of the diagnostic setting, if deployed. | +| `diagnosticStorageAccountId` | string | `''` | | Resource ID of the diagnostic storage account. | +| `diagnosticWorkspaceId` | string | `''` | | Resource identifier of log analytics. | +| `dnsServers` | array | `[]` | | List of DNS servers IP addresses. Use 'AzureProvidedDNS' to switch to azure provided DNS resolution. 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in dnsServers collection. | +| `enableAcceleratedNetworking` | bool | `False` | | If the network interface is accelerated networking enabled. | +| `enableDefaultTelemetry` | bool | `True` | | Enable telemetry via the Customer Usage Attribution ID (GUID). | +| `enableIPForwarding` | bool | `False` | | Indicates whether IP forwarding is enabled on this network interface. | +| `location` | string | `[resourceGroup().location]` | | Location for all resources. | +| `lock` | string | `'NotSpecified'` | `[CanNotDelete, NotSpecified, ReadOnly]` | Specify the type of lock. | +| `networkSecurityGroupResourceId` | string | `''` | | The network security group (NSG) to attach to the network interface. | +| `roleAssignments` | array | `[]` | | Array of role assignment objects that contain the 'roleDefinitionIdOrName' and 'principalId' to define RBAC role assignments on this resource. In the roleDefinitionIdOrName attribute, you can provide either the display name of the role definition, or its fully qualified ID in the following format: '/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11'. | +| `tags` | object | `{object}` | | Tags of the resource. | + + +### Parameter Usage: `ipConfigurations` + +The IP configurations to apply to the network interface. + +```json +{ + "name": "ipconfig01", + "subnetId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-001", + "loadBalancerBackendAddressPools": [ + { + "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/loadBalancers/adp-<>-az-lb-internal-001/backendAddressPools/servers" + } + ], + "applicationSecurityGroups": [ + { + "id": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/applicationSecurityGroups/adp-<>-az-asg-x-001" + } + ] +} +``` + +### Parameter Usage: `roleAssignments` + +Create a role assignment for the given resource. If you want to assign a service principal / managed identity that is created in the same deployment, make sure to also specify the `'principalType'` parameter and set it to `'ServicePrincipal'`. This will ensure the role assignment waits for the principal's propagation in Azure. + +```json +"roleAssignments": { + "value": [ + { + "roleDefinitionIdOrName": "Reader", + "description": "Reader Role Assignment", + "principalIds": [ + "12345678-1234-1234-1234-123456789012", // object 1 + "78945612-1234-1234-1234-123456789012" // object 2 + ] + }, + { + "roleDefinitionIdOrName": "/providers/Microsoft.Authorization/roleDefinitions/c2f4ef07-c644-48eb-af81-4b1b4947fb11", + "principalIds": [ + "12345678-1234-1234-1234-123456789012" // object 1 + ], + "principalType": "ServicePrincipal" + } + ] +} +``` + +### Parameter Usage: `tags` + +Tag names and tag values can be provided as needed. A tag can be left without a value. + +```json +"tags": { + "value": { + "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 deployed resource. | +| `resourceGroupName` | string | The resource group of the deployed resource. | +| `resourceId` | string | The resource ID of the deployed resource. | diff --git a/arm/Microsoft.Network/networkInterfaces/version.json b/arm/Microsoft.Network/networkInterfaces/version.json new file mode 100644 index 0000000000..badc0a2285 --- /dev/null +++ b/arm/Microsoft.Network/networkInterfaces/version.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", + "version": "0.5" +} diff --git a/arm/Microsoft.Sql/servers/databases/deploy.bicep b/arm/Microsoft.Sql/servers/databases/deploy.bicep index 2c1dbf863e..7b0d913b03 100644 --- a/arm/Microsoft.Sql/servers/databases/deploy.bicep +++ b/arm/Microsoft.Sql/servers/databases/deploy.bicep @@ -223,7 +223,7 @@ output name string = database.name @description('The resource ID of the deployed database.') output resourceId string = database.id -@description('The resourceGroup of the deployed database.') +@description('The resource group of the deployed database.') output resourceGroupName string = resourceGroup().name @description('The location the resource was deployed into.') diff --git a/arm/Microsoft.Sql/servers/databases/readme.md b/arm/Microsoft.Sql/servers/databases/readme.md index b8dc1027b1..598755dc6b 100644 --- a/arm/Microsoft.Sql/servers/databases/readme.md +++ b/arm/Microsoft.Sql/servers/databases/readme.md @@ -83,5 +83,5 @@ Tag names and tag values can be provided as needed. A tag can be left without a | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the deployed database. | -| `resourceGroupName` | string | The resourceGroup of the deployed database. | +| `resourceGroupName` | string | The resource group of the deployed database. | | `resourceId` | string | The resource ID of the deployed database. | diff --git a/arm/Microsoft.Sql/servers/deploy.bicep b/arm/Microsoft.Sql/servers/deploy.bicep index c754c94264..5626592660 100644 --- a/arm/Microsoft.Sql/servers/deploy.bicep +++ b/arm/Microsoft.Sql/servers/deploy.bicep @@ -209,7 +209,7 @@ output name string = server.name @description('The resource ID of the deployed SQL server.') output resourceId string = server.id -@description('The resourceGroup of the deployed SQL server.') +@description('The resource group of the deployed SQL server.') output resourceGroupName string = resourceGroup().name @description('The principal ID of the system assigned identity.') diff --git a/arm/Microsoft.Sql/servers/firewallRules/deploy.bicep b/arm/Microsoft.Sql/servers/firewallRules/deploy.bicep index ec242a2453..2ca51b8545 100644 --- a/arm/Microsoft.Sql/servers/firewallRules/deploy.bicep +++ b/arm/Microsoft.Sql/servers/firewallRules/deploy.bicep @@ -44,5 +44,5 @@ output name string = firewallRule.name @description('The resource ID of the deployed firewall rule.') output resourceId string = firewallRule.id -@description('The resourceGroup of the deployed firewall rule.') +@description('The resource group of the deployed firewall rule.') output resourceGroupName string = resourceGroup().name diff --git a/arm/Microsoft.Sql/servers/firewallRules/readme.md b/arm/Microsoft.Sql/servers/firewallRules/readme.md index 6d059ebe87..cfaef0038a 100644 --- a/arm/Microsoft.Sql/servers/firewallRules/readme.md +++ b/arm/Microsoft.Sql/servers/firewallRules/readme.md @@ -39,5 +39,5 @@ This module deploys an SQL Server Firewall rule. | Output Name | Type | Description | | :-- | :-- | :-- | | `name` | string | The name of the deployed firewall rule. | -| `resourceGroupName` | string | The resourceGroup of the deployed firewall rule. | +| `resourceGroupName` | string | The resource group of the deployed firewall rule. | | `resourceId` | string | The resource ID of the deployed firewall rule. | diff --git a/arm/Microsoft.Sql/servers/readme.md b/arm/Microsoft.Sql/servers/readme.md index fe4fe57da4..adae5067d3 100644 --- a/arm/Microsoft.Sql/servers/readme.md +++ b/arm/Microsoft.Sql/servers/readme.md @@ -169,6 +169,6 @@ To use Private Endpoint the following dependencies must be deployed: | :-- | :-- | :-- | | `location` | string | The location the resource was deployed into. | | `name` | string | The name of the deployed SQL server. | -| `resourceGroupName` | string | The resourceGroup of the deployed SQL server. | +| `resourceGroupName` | string | The resource group of the deployed SQL server. | | `resourceId` | string | The resource ID of the deployed SQL server. | | `systemAssignedPrincipalId` | string | The principal ID of the system assigned identity. | diff --git a/arm/Microsoft.Sql/servers/securityAlertPolicies/deploy.bicep b/arm/Microsoft.Sql/servers/securityAlertPolicies/deploy.bicep index 61e277134c..e745b2ce4d 100644 --- a/arm/Microsoft.Sql/servers/securityAlertPolicies/deploy.bicep +++ b/arm/Microsoft.Sql/servers/securityAlertPolicies/deploy.bicep @@ -69,5 +69,5 @@ output name string = securityAlertPolicy.name @description('The resource ID of the deployed security alert policy.') output resourceId string = securityAlertPolicy.id -@description('The resourceGroup of the deployed security alert policy.') +@description('The resource group of the deployed security alert policy.') output resourceGroupName string = resourceGroup().name diff --git a/arm/Microsoft.Sql/servers/securityAlertPolicies/readme.md b/arm/Microsoft.Sql/servers/securityAlertPolicies/readme.md index ba5330a064..5e7b710bc8 100644 --- a/arm/Microsoft.Sql/servers/securityAlertPolicies/readme.md +++ b/arm/Microsoft.Sql/servers/securityAlertPolicies/readme.md @@ -44,5 +44,5 @@ This module deploys an SQL Server Security Alert Policy. | Output Name | Type | Description | | :-- | :-- | :-- | | `name` | string | The name of the deployed security alert policy. | -| `resourceGroupName` | string | The resourceGroup of the deployed security alert policy. | +| `resourceGroupName` | string | The resource group of the deployed security alert policy. | | `resourceId` | string | The resource ID of the deployed security alert policy. |