Sync eng/common directory with azure-sdk-tools for PR 8371 (#5685)

* Restrict live test storage account access to client IP

* Add storage pools to test resources vnet allowlist

* Use pool subnet map to reduce number of subnets added to live test resources

* snap

* Add test resource parameter to add ip ranges to storage firewall

* Validate and update ip firewall rules

* Get pool subnet using separate workload identity

---------

Co-authored-by: Ben Broderick Phillips <bebroder@microsoft.com>
This commit is contained in:
Azure SDK Bot 2024-07-01 15:08:16 -04:00 committed by GitHub
parent 6f71dd3621
commit 88bb72c045
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 70 additions and 13 deletions

View File

@ -80,6 +80,19 @@ param (
[ValidateNotNull()]
[hashtable] $EnvironmentVariables = @{},
# List of CIDR ranges to add to specific resource firewalls, e.g. @(10.100.0.0/16, 10.200.0.0/16)
[Parameter()]
[ValidateCount(0,399)]
[Validatescript({
foreach ($range in $PSItem) {
if ($range -like '*/31' -or $range -like '*/32') {
throw "Firewall IP Ranges cannot contain a /31 or /32 CIDR"
}
}
return $true
})]
[array] $AllowIpRanges = @(),
[Parameter()]
[switch] $CI = ($null -ne $env:SYSTEM_TEAMPROJECTID),
@ -106,15 +119,6 @@ param (
. $PSScriptRoot/SubConfig-Helpers.ps1
$azsdkPipelineVnet = "/subscriptions/a18897a6-7e44-457d-9260-f2854c0aca42/resourceGroups/azsdk-pools/providers/Microsoft.Network/virtualNetworks/azsdk-pipeline-vnet-wus"
$azsdkPipelineSubnets = @(
($azsdkPipelineVnet + "/subnets/pipeline-subnet-ubuntu-1804-general"),
($azsdkPipelineVnet + "/subnets/pipeline-subnet-ubuntu-2004-general"),
($azsdkPipelineVnet + "/subnets/pipeline-subnet-ubuntu-2204-general"),
($azsdkPipelineVnet + "/subnets/pipeline-subnet-win-2019-general"),
($azsdkPipelineVnet + "/subnets/pipeline-subnet-win-2022-general")
)
if (!$ServicePrincipalAuth) {
# Clear secrets if not using Service Principal auth. This prevents secrets
# from being passed to pre- and post-scripts.
@ -262,7 +266,7 @@ function MergeHashes([hashtable] $source, [psvariable] $dest)
function BuildBicepFile([System.IO.FileSystemInfo] $file)
{
if (!(Get-Command bicep -ErrorAction Ignore)) {
Write-Error "A bicep file was found at '$($file.FullName)' but the Azure Bicep CLI is not installed. See https://aka.ms/install-bicep-pwsh"
Write-Error "A bicep file was found at '$($file.FullName)' but the Azure Bicep CLI is not installed. See aka.ms/bicep-install"
throw
}
@ -758,8 +762,9 @@ try {
if ($TestApplicationSecret -and $ServicePrincipalAuth) {
$templateParameters.Add('testApplicationSecret', $TestApplicationSecret)
}
if ($CI -and $Environment -eq 'AzureCloud') {
$templateParameters.Add('azsdkPipelineSubnetList', $azsdkPipelineSubnets)
# Only add subnets when running in an azure pipeline context
if ($CI -and $Environment -eq 'AzureCloud' -and $env:PoolSubnet) {
$templateParameters.Add('azsdkPipelineSubnetList', @($env:PoolSubnet))
}
$defaultCloudParameters = LoadCloudConfig $Environment
@ -838,6 +843,32 @@ try {
-templateFile $templateFile `
-environmentVariables $EnvironmentVariables
$storageAccounts = Retry { Get-AzResource -ResourceGroupName $ResourceGroupName -ResourceType "Microsoft.Storage/storageAccounts" }
# Add client IP to storage account when running as local user. Pipeline's have their own vnet with access
if ($storageAccounts) {
foreach ($account in $storageAccounts) {
$rules = Get-AzStorageAccountNetworkRuleSet -ResourceGroupName $ResourceGroupName -AccountName $account.Name
if ($rules -and $rules.DefaultAction -eq "Allow") {
Write-Host "Restricting network rules in storage account '$($account.Name)' to deny access by default"
Retry { Update-AzStorageAccountNetworkRuleSet -ResourceGroupName $ResourceGroupName -Name $account.Name -DefaultAction Deny }
if ($CI -and $env:PoolSubnet) {
Write-Host "Enabling access to '$($account.Name)' from pipeline subnet $($env:PoolSubnet)"
Retry { Add-AzStorageAccountNetworkRule -ResourceGroupName $ResourceGroupName -Name $account.Name -VirtualNetworkResourceId $env:PoolSubnet }
} elseif ($AllowIpRanges) {
Write-Host "Enabling access to '$($account.Name)' to $($AllowIpRanges.Length) IP ranges"
$ipRanges = $AllowIpRanges | ForEach-Object {
@{ Action = 'allow'; IPAddressOrRange = $_ }
}
Retry { Update-AzStorageAccountNetworkRuleSet -ResourceGroupName $ResourceGroupName -Name $account.Name -IPRule $ipRanges | Out-Null }
} elseif (!$CI) {
Write-Host "Enabling access to '$($account.Name)' from client IP"
$clientIp ??= Retry { Invoke-RestMethod -Uri 'https://icanhazip.com/' } # cloudflare owned ip site
Retry { Add-AzStorageAccountNetworkRule -ResourceGroupName $ResourceGroupName -Name $account.Name -IPAddressOrRange $clientIp | Out-Null }
}
}
}
}
$postDeploymentScript = $templateFile.originalFilePath | Split-Path | Join-Path -ChildPath "$ResourceType-resources-post.ps1"
if (Test-Path $postDeploymentScript) {
Log "Invoking post-deployment script '$postDeploymentScript'"
@ -852,7 +883,6 @@ try {
Write-Host "Deleting ARM deployment as it may contain secrets. Deployed resources will not be affected."
$null = $deployment | Remove-AzResourceGroupDeployment
}
} finally {
$exitActions.Invoke()
}
@ -1023,6 +1053,10 @@ Optional key-value pairs of parameters to pass to the ARM template(s).
.PARAMETER EnvironmentVariables
Optional key-value pairs of parameters to set as environment variables to the shell.
.PARAMETER AllowIpRanges
Optional array of CIDR ranges to add to the network firewall for resource types like storage.
When running locally, if this parameter is not set then the client's IP will be queried and added to the firewall instead.
.PARAMETER CI
Indicates the script is run as part of a Continuous Integration / Continuous
Deployment (CI/CD) build (only Azure Pipelines is currently supported).

View File

@ -14,6 +14,25 @@ parameters:
default: null
steps:
- task: AzurePowerShell@5
displayName: Set Pipeline Subnet Info
env: ${{ parameters.EnvVars }}
inputs:
azureSubscription: azure-sdk-tests
azurePowerShellVersion: LatestVersion
pwsh: true
ScriptType: InlineScript
Inline: |
Set-AzContext 'Azure SDK Engineering System'
if ($env:Pool -eq 'Azure Pipelines') {
Write-Host "Skipping pool subnet lookup when running on an Azure Pipelines hosted pool"
Write-Host "##vso[task.setvariable variable=PoolSubnet;]"
exit 0
}
$poolSubnet = (Get-AzResource -ResourceGroupName azsdk-pools -Name $env:Pool -ExpandProperties).Properties.networkProfile.subnetId
Write-Host "Setting pipeline subnet env variable PoolSubnet to '$poolSubnet'"
Write-Host "##vso[task.setvariable variable=PoolSubnet;]$poolSubnet"
- pwsh: |
. ./eng/common/TestResources/SubConfig-Helpers.ps1

View File

@ -46,6 +46,7 @@ steps:
displayName: Deploy test resources
env:
TEMP: $(Agent.TempDirectory)
PoolSubnet: $(PoolSubnet)
${{ insert }}: ${{ parameters.EnvVars }}
inputs:
azureSubscription: ${{ parameters.ServiceConnection }}
@ -68,6 +69,7 @@ steps:
-DeleteAfterHours '${{ parameters.DeleteAfterHours }}' `
@subscriptionConfiguration `
-AdditionalParameters ${{ parameters.ArmTemplateParameters }} `
-AllowIpRanges ('$(azsdk-corp-net-ip-ranges)' -split ',') `
-CI `
-Force `
-Verbose | Out-Null
@ -89,6 +91,7 @@ steps:
-DeleteAfterHours '${{ parameters.DeleteAfterHours }}' `
@subscriptionConfiguration `
-AdditionalParameters ${{ parameters.ArmTemplateParameters }} `
-AllowIpRanges ('$(azsdk-corp-net-ip-ranges)' -split ',') `
-CI `
-ServicePrincipalAuth `
-Force `
@ -96,4 +99,5 @@ steps:
displayName: Deploy test resources
env:
TEMP: $(Agent.TempDirectory)
PoolSubnet: $(PoolSubnet)
${{ insert }}: ${{ parameters.EnvVars }}