I am giving my first steps with bicep, but I feel completely stuck :-/
I want to get the public ips from a App Service, and after that, I want to limit with them the access to an storage account. I face two problems:
Here is my code:
////// FIRST PART: TO GET THE APP SERVICE IP
resource sitewww 'Microsoft.Web/sites@2022-03-01' existing = {
name: 'mywebapp'
}
//Here I get the list of IPs
var ipSalidaString = string(sitewww.properties.outboundIpAddresses)
//I split the IPs list to an Array String, so I can use it
var allowedIpAddresses = split(ipSalidaString,',')
/// THIS FOR LOOP DOES NOT WORK AND I DO NOT KNOW WHY
var additionalIpSecurityRestrictions = [for ip in allowedIpAddresses: {
action: 'Allow'
value: ip
}]
////// Second Part: Update the IpRules of the Storage Account
resource almacenamiento 'Microsoft.Storage/storageAccounts@2022-09-01'{
name: 'teststorage'
location:localizacion
properties:{
publicNetworkAccess: 'Enabled'
networkAcls:{
defaultAction:'Deny'
ipRules: [{ /// MUST BE UPDATED
action: 'Allow'
value: '20.26.196.151'
}
]
}
}
}
I tried severals ways to iterate the for loop, but always says "this expression is being used in the for-expression, which requires a value that can be calculated at the start of the deployment. you are referencing a variable which cannot be calculated"
I expect to create a object with the IpRules for my storage account
As suggested by @silent, you should definitely use VNET integration to restrict traffic to the storage account rather than adding the outbound Ips of the webApp.
The issue you're seeing can be fixed by creating the storage account in its own module:
// storage-account.bicep
param location string = resourceGroup().location
param storageAccountName string
param ips array
resource storageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: storageAccountName
location: location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
properties: {
publicNetworkAccess: 'Enabled'
networkAcls: {
defaultAction: 'Deny'
ipRules: [for ip in ips: {
action: 'Allow'
value: ip
}]
}
}
}
You can then call this module from the parent bicep:
// main.bicep
param location string = resourceGroup().location
param webAppName string = 'mywebapp'
param storageAccountName string = 'teststorage'
// Get a reference to the existing webapp
resource webApp 'Microsoft.Web/sites@2022-03-01' existing = {
name: webAppName
}
// Create the storage with the IP rules
module storageAccount 'storage-account.bicep' = {
name: 'storage-account'
params: {
location: location
storageAccountName: storageAccountName
ips: split(webApp.properties.outboundIpAddresses, ',')
}
}