@@ -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-
118122if (! $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)
262266function 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
10241054Optional 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
10271061Indicates the script is run as part of a Continuous Integration / Continuous
10281062Deployment (CI/CD) build (only Azure Pipelines is currently supported).
0 commit comments