Skip to content

Commit f8d473b

Browse files
azure-sdkbenbp
andauthored
Sync eng/common directory with azure-sdk-tools for PR 8371 (Azure#22981)
* 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 <[email protected]>
1 parent dd2ec87 commit f8d473b

File tree

3 files changed

+70
-13
lines changed

3 files changed

+70
-13
lines changed

eng/common/TestResources/New-TestResources.ps1

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ param (
8080
[ValidateNotNull()]
8181
[hashtable] $EnvironmentVariables = @{},
8282

83+
# List of CIDR ranges to add to specific resource firewalls, e.g. @(10.100.0.0/16, 10.200.0.0/16)
84+
[Parameter()]
85+
[ValidateCount(0,399)]
86+
[Validatescript({
87+
foreach ($range in $PSItem) {
88+
if ($range -like '*/31' -or $range -like '*/32') {
89+
throw "Firewall IP Ranges cannot contain a /31 or /32 CIDR"
90+
}
91+
}
92+
return $true
93+
})]
94+
[array] $AllowIpRanges = @(),
95+
8396
[Parameter()]
8497
[switch] $CI = ($null -ne $env:SYSTEM_TEAMPROJECTID),
8598

@@ -106,15 +119,6 @@ param (
106119

107120
. $PSScriptRoot/SubConfig-Helpers.ps1
108121

109-
$azsdkPipelineVnet = "/subscriptions/a18897a6-7e44-457d-9260-f2854c0aca42/resourceGroups/azsdk-pools/providers/Microsoft.Network/virtualNetworks/azsdk-pipeline-vnet-wus"
110-
$azsdkPipelineSubnets = @(
111-
($azsdkPipelineVnet + "/subnets/pipeline-subnet-ubuntu-1804-general"),
112-
($azsdkPipelineVnet + "/subnets/pipeline-subnet-ubuntu-2004-general"),
113-
($azsdkPipelineVnet + "/subnets/pipeline-subnet-ubuntu-2204-general"),
114-
($azsdkPipelineVnet + "/subnets/pipeline-subnet-win-2019-general"),
115-
($azsdkPipelineVnet + "/subnets/pipeline-subnet-win-2022-general")
116-
)
117-
118122
if (!$ServicePrincipalAuth) {
119123
# Clear secrets if not using Service Principal auth. This prevents secrets
120124
# from being passed to pre- and post-scripts.
@@ -262,7 +266,7 @@ function MergeHashes([hashtable] $source, [psvariable] $dest)
262266
function BuildBicepFile([System.IO.FileSystemInfo] $file)
263267
{
264268
if (!(Get-Command bicep -ErrorAction Ignore)) {
265-
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"
269+
Write-Error "A bicep file was found at '$($file.FullName)' but the Azure Bicep CLI is not installed. See aka.ms/bicep-install"
266270
throw
267271
}
268272

@@ -758,8 +762,9 @@ try {
758762
if ($TestApplicationSecret -and $ServicePrincipalAuth) {
759763
$templateParameters.Add('testApplicationSecret', $TestApplicationSecret)
760764
}
761-
if ($CI -and $Environment -eq 'AzureCloud') {
762-
$templateParameters.Add('azsdkPipelineSubnetList', $azsdkPipelineSubnets)
765+
# Only add subnets when running in an azure pipeline context
766+
if ($CI -and $Environment -eq 'AzureCloud' -and $env:PoolSubnet) {
767+
$templateParameters.Add('azsdkPipelineSubnetList', @($env:PoolSubnet))
763768
}
764769

765770
$defaultCloudParameters = LoadCloudConfig $Environment
@@ -838,6 +843,32 @@ try {
838843
-templateFile $templateFile `
839844
-environmentVariables $EnvironmentVariables
840845

846+
$storageAccounts = Retry { Get-AzResource -ResourceGroupName $ResourceGroupName -ResourceType "Microsoft.Storage/storageAccounts" }
847+
# Add client IP to storage account when running as local user. Pipeline's have their own vnet with access
848+
if ($storageAccounts) {
849+
foreach ($account in $storageAccounts) {
850+
$rules = Get-AzStorageAccountNetworkRuleSet -ResourceGroupName $ResourceGroupName -AccountName $account.Name
851+
if ($rules -and $rules.DefaultAction -eq "Allow") {
852+
Write-Host "Restricting network rules in storage account '$($account.Name)' to deny access by default"
853+
Retry { Update-AzStorageAccountNetworkRuleSet -ResourceGroupName $ResourceGroupName -Name $account.Name -DefaultAction Deny }
854+
if ($CI -and $env:PoolSubnet) {
855+
Write-Host "Enabling access to '$($account.Name)' from pipeline subnet $($env:PoolSubnet)"
856+
Retry { Add-AzStorageAccountNetworkRule -ResourceGroupName $ResourceGroupName -Name $account.Name -VirtualNetworkResourceId $env:PoolSubnet }
857+
} elseif ($AllowIpRanges) {
858+
Write-Host "Enabling access to '$($account.Name)' to $($AllowIpRanges.Length) IP ranges"
859+
$ipRanges = $AllowIpRanges | ForEach-Object {
860+
@{ Action = 'allow'; IPAddressOrRange = $_ }
861+
}
862+
Retry { Update-AzStorageAccountNetworkRuleSet -ResourceGroupName $ResourceGroupName -Name $account.Name -IPRule $ipRanges | Out-Null }
863+
} elseif (!$CI) {
864+
Write-Host "Enabling access to '$($account.Name)' from client IP"
865+
$clientIp ??= Retry { Invoke-RestMethod -Uri 'https://icanhazip.com/' } # cloudflare owned ip site
866+
Retry { Add-AzStorageAccountNetworkRule -ResourceGroupName $ResourceGroupName -Name $account.Name -IPAddressOrRange $clientIp | Out-Null }
867+
}
868+
}
869+
}
870+
}
871+
841872
$postDeploymentScript = $templateFile.originalFilePath | Split-Path | Join-Path -ChildPath "$ResourceType-resources-post.ps1"
842873
if (Test-Path $postDeploymentScript) {
843874
Log "Invoking post-deployment script '$postDeploymentScript'"
@@ -852,7 +883,6 @@ try {
852883
Write-Host "Deleting ARM deployment as it may contain secrets. Deployed resources will not be affected."
853884
$null = $deployment | Remove-AzResourceGroupDeployment
854885
}
855-
856886
} finally {
857887
$exitActions.Invoke()
858888
}
@@ -1023,6 +1053,10 @@ Optional key-value pairs of parameters to pass to the ARM template(s).
10231053
.PARAMETER EnvironmentVariables
10241054
Optional key-value pairs of parameters to set as environment variables to the shell.
10251055
1056+
.PARAMETER AllowIpRanges
1057+
Optional array of CIDR ranges to add to the network firewall for resource types like storage.
1058+
When running locally, if this parameter is not set then the client's IP will be queried and added to the firewall instead.
1059+
10261060
.PARAMETER CI
10271061
Indicates the script is run as part of a Continuous Integration / Continuous
10281062
Deployment (CI/CD) build (only Azure Pipelines is currently supported).

eng/common/TestResources/build-test-resource-config.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,25 @@ parameters:
1414
default: null
1515

1616
steps:
17+
- task: AzurePowerShell@5
18+
displayName: Set Pipeline Subnet Info
19+
env: ${{ parameters.EnvVars }}
20+
inputs:
21+
azureSubscription: azure-sdk-tests
22+
azurePowerShellVersion: LatestVersion
23+
pwsh: true
24+
ScriptType: InlineScript
25+
Inline: |
26+
Set-AzContext 'Azure SDK Engineering System'
27+
if ($env:Pool -eq 'Azure Pipelines') {
28+
Write-Host "Skipping pool subnet lookup when running on an Azure Pipelines hosted pool"
29+
Write-Host "##vso[task.setvariable variable=PoolSubnet;]"
30+
exit 0
31+
}
32+
$poolSubnet = (Get-AzResource -ResourceGroupName azsdk-pools -Name $env:Pool -ExpandProperties).Properties.networkProfile.subnetId
33+
Write-Host "Setting pipeline subnet env variable PoolSubnet to '$poolSubnet'"
34+
Write-Host "##vso[task.setvariable variable=PoolSubnet;]$poolSubnet"
35+
1736
- pwsh: |
1837
. ./eng/common/TestResources/SubConfig-Helpers.ps1
1938

eng/common/TestResources/deploy-test-resources.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ steps:
4646
displayName: Deploy test resources
4747
env:
4848
TEMP: $(Agent.TempDirectory)
49+
PoolSubnet: $(PoolSubnet)
4950
${{ insert }}: ${{ parameters.EnvVars }}
5051
inputs:
5152
azureSubscription: ${{ parameters.ServiceConnection }}
@@ -68,6 +69,7 @@ steps:
6869
-DeleteAfterHours '${{ parameters.DeleteAfterHours }}' `
6970
@subscriptionConfiguration `
7071
-AdditionalParameters ${{ parameters.ArmTemplateParameters }} `
72+
-AllowIpRanges ('$(azsdk-corp-net-ip-ranges)' -split ',') `
7173
-CI `
7274
-Force `
7375
-Verbose | Out-Null
@@ -89,11 +91,13 @@ steps:
8991
-DeleteAfterHours '${{ parameters.DeleteAfterHours }}' `
9092
@subscriptionConfiguration `
9193
-AdditionalParameters ${{ parameters.ArmTemplateParameters }} `
94+
-AllowIpRanges ('$(azsdk-corp-net-ip-ranges)' -split ',') `
9295
-CI `
9396
-ServicePrincipalAuth `
9497
-Force `
9598
-Verbose | Out-Null
9699
displayName: Deploy test resources
97100
env:
98101
TEMP: $(Agent.TempDirectory)
102+
PoolSubnet: $(PoolSubnet)
99103
${{ insert }}: ${{ parameters.EnvVars }}

0 commit comments

Comments
 (0)