-
Notifications
You must be signed in to change notification settings - Fork 355
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add private-endpoint e2e (#2687)
## Description Added e2e test with private-endpoint to reflect https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deployment-script-vnet-private-endpoint. ## Pipeline Reference <!-- Insert your Pipeline Status Badge below --> | Pipeline | | -------- | | [![avm.res.resources.deployment-script](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.resources.deployment-script.yml/badge.svg?branch=userrs%2Fsegraef%2Fds-pe)](https://github.com/Azure/bicep-registry-modules/actions/workflows/avm.res.resources.deployment-script.yml) | ## Type of Change <!-- Use the checkboxes [x] on the options that are relevant. --> - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [x] Azure Verified Module updates: - [ ] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [ ] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [x] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [x] Update to documentation ## Checklist - [x] I'm sure there are no other open Pull Requests for the same update/change - [x] I have run `Set-AVMModule` locally to generate the supporting module files. - [x] My corresponding pipelines / checks run clean and green without any errors or warnings <!-- Please keep up to date with the contribution guide at https://aka.ms/avm/contribute/bicep --> --------- Co-authored-by: Alexander Sehr <ASehr@hotmail.de>
- Loading branch information
1 parent
2a48a03
commit 1533f62
Showing
3 changed files
with
334 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
154 changes: 154 additions & 0 deletions
154
avm/res/resources/deployment-script/tests/e2e/private-endpoint/dependencies.bicep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
@description('Optional. The location to deploy resources to.') | ||
param location string = resourceGroup().location | ||
|
||
@description('Required. The name of the managed identity to create.') | ||
param managedIdentityName string | ||
|
||
@description('Required. The name of the Virtual Network to create.') | ||
param virtualNetworkName string | ||
|
||
@description('Required. The name of the Storage Account to create.') | ||
param storageAccountName string | ||
|
||
@description('Required. The name of the private endpoint to create.') | ||
param privateEndpointName string | ||
|
||
var addressPrefix = '10.0.0.0/16' | ||
|
||
// Role required for deployment script to be able to use a storage account via private networking | ||
resource storageFileDataPrivilegedContributor 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { | ||
name: '69566ab7-960f-475b-8e7c-b3118f30c6bd' | ||
scope: tenant() | ||
} | ||
|
||
resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { | ||
name: managedIdentityName | ||
location: location | ||
} | ||
|
||
resource storageFileSharePermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { | ||
name: guid('storageFileDataPrivilegedContributorRole', managedIdentity.id, storageAccount.id) | ||
scope: storageAccount | ||
properties: { | ||
principalId: managedIdentity.properties.principalId | ||
roleDefinitionId: storageFileDataPrivilegedContributor.id | ||
principalType: 'ServicePrincipal' | ||
} | ||
} | ||
|
||
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-04-01' = { | ||
name: storageAccountName | ||
location: location | ||
sku: { | ||
name: 'Standard_LRS' | ||
} | ||
kind: 'StorageV2' | ||
properties: { | ||
publicNetworkAccess: 'Disabled' | ||
allowSharedKeyAccess: true // Cannot be set to false when using a private network for the deployment script | ||
networkAcls: { | ||
defaultAction: 'Deny' | ||
bypass: 'AzureServices' | ||
} | ||
} | ||
} | ||
|
||
resource privateEndpoint 'Microsoft.Network/privateEndpoints@2023-11-01' = { | ||
name: privateEndpointName | ||
location: location | ||
properties: { | ||
subnet: { | ||
id: virtualNetwork.properties.subnets[1].id | ||
} | ||
privateLinkServiceConnections: [ | ||
{ | ||
name: '${privateEndpointName}-storageConnection' | ||
properties: { | ||
privateLinkServiceId: storageAccount.id | ||
groupIds: [ | ||
'file' | ||
] | ||
} | ||
} | ||
] | ||
} | ||
} | ||
|
||
resource privateDnsZone 'Microsoft.Network/privateDnsZones@2020-06-01' = { | ||
name: 'privatelink.file.${environment().suffixes.storage}' | ||
location: 'global' | ||
|
||
resource virtualNetworkLink 'virtualNetworkLinks' = { | ||
name: uniqueString(virtualNetwork.name) | ||
location: 'global' | ||
properties: { | ||
registrationEnabled: false | ||
virtualNetwork: { | ||
id: virtualNetwork.id | ||
} | ||
} | ||
} | ||
|
||
resource resRecord 'A' = { | ||
name: storageAccount.name | ||
properties: { | ||
ttl: 10 | ||
aRecords: [ | ||
{ | ||
ipv4Address: first(first(privateEndpoint.properties.customDnsConfigs)!.ipAddresses) | ||
} | ||
] | ||
} | ||
} | ||
} | ||
|
||
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { | ||
name: virtualNetworkName | ||
location: location | ||
properties: { | ||
addressSpace: { | ||
addressPrefixes: [ | ||
addressPrefix | ||
] | ||
} | ||
subnets: [ | ||
{ | ||
name: 'defaultSubnet' | ||
properties: { | ||
addressPrefix: cidrSubnet(addressPrefix, 24, 0) | ||
serviceEndpoints: [ | ||
{ | ||
service: 'Microsoft.Storage' | ||
} | ||
] | ||
delegations: [ | ||
{ | ||
name: 'Microsoft.ContainerInstance.containerGroups' | ||
properties: { | ||
serviceName: 'Microsoft.ContainerInstance/containerGroups' | ||
} | ||
} | ||
] | ||
} | ||
} | ||
{ | ||
name: 'peSubnet' | ||
properties: { | ||
addressPrefix: cidrSubnet(addressPrefix, 24, 1) | ||
} | ||
} | ||
] | ||
} | ||
} | ||
|
||
@description('The principal ID of the created Managed Identity.') | ||
output managedIdentityPrincipalId string = managedIdentity.properties.principalId | ||
|
||
@description('The resource ID of the created Managed Identity.') | ||
output managedIdentityResourceId string = managedIdentity.id | ||
|
||
@description('The resource ID of the created storage account.') | ||
output storageAccountResourceId string = storageAccount.id | ||
|
||
@description('The resource ID of the created Virtual Network Subnet.') | ||
output subnetResourceId string = virtualNetwork.properties.subnets[0].id |
73 changes: 73 additions & 0 deletions
73
avm/res/resources/deployment-script/tests/e2e/private-endpoint/main.test.bicep
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
targetScope = 'subscription' | ||
|
||
metadata name = 'Using Private Endpoint' | ||
metadata description = 'This instance deploys the module with access to a private endpoint.' | ||
|
||
// ========== // | ||
// Parameters // | ||
// ========== // | ||
|
||
@description('Optional. The name of the resource group to deploy for testing purposes.') | ||
@maxLength(90) | ||
param resourceGroupName string = 'avm-${namePrefix}-resources.deploymentscripts-${serviceShort}-rg' | ||
|
||
@description('Optional. The location to deploy resources to.') | ||
param resourceLocation 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 = 'rdspe' | ||
|
||
@description('Optional. A token to inject into the name of each resource.') | ||
param namePrefix string = '#_namePrefix_#' | ||
|
||
// ============ // | ||
// Dependencies // | ||
// ============ // | ||
|
||
// General resources | ||
// ================= | ||
resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { | ||
name: resourceGroupName | ||
location: resourceLocation | ||
} | ||
|
||
module nestedDependencies 'dependencies.bicep' = { | ||
scope: resourceGroup | ||
name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' | ||
params: { | ||
managedIdentityName: 'dep-${namePrefix}-msi-${serviceShort}' | ||
storageAccountName: 'dep${namePrefix}sa${serviceShort}' | ||
virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' | ||
privateEndpointName: 'dep-${namePrefix}-pe-${serviceShort}' | ||
location: resourceLocation | ||
} | ||
} | ||
|
||
// ============== // | ||
// Test Execution // | ||
// ============== // | ||
|
||
module testDeployment '../../../main.bicep' = { | ||
scope: resourceGroup | ||
name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}' | ||
params: { | ||
name: '${namePrefix}${serviceShort}001' | ||
location: resourceLocation | ||
azCliVersion: '2.9.1' | ||
kind: 'AzureCLI' | ||
retentionInterval: 'P1D' | ||
cleanupPreference: 'Always' | ||
subnetResourceIds: [ | ||
nestedDependencies.outputs.subnetResourceId | ||
] | ||
managedIdentities: { | ||
userAssignedResourcesIds: [ | ||
nestedDependencies.outputs.managedIdentityResourceId | ||
] | ||
} | ||
timeout: 'PT1H' | ||
runOnce: true | ||
scriptContent: 'echo \'AVM Deployment Script test!\'' | ||
storageAccountResourceId: nestedDependencies.outputs.storageAccountResourceId | ||
} | ||
} |