Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ternary operator on module scope #10419

Closed
brwilkinson opened this issue Apr 13, 2023 Discussed in #10417 · 8 comments
Closed

Ternary operator on module scope #10419

brwilkinson opened this issue Apr 13, 2023 Discussed in #10417 · 8 comments

Comments

@brwilkinson
Copy link
Collaborator

Discussed in #10417

Originally posted by TacticalNuclearSpud April 13, 2023
Is it possible to use the ternary operator on the scope tag of a bicep module? The template I have validates fine but fails on deployment.

I'd like to be able to specify if a new resource group is required, if it is, deploy it and subsequently deploy the module resources into it, but, if not, take the name of an existing resource group and deploy the resources to that.

I'm relatively new to bicep and really struggling to get my head round this one.

Current main.bicep

targetScope = 'subscription'

@description('The Azure region into which the resources should be deployed. Defaults to the location of the resource group')
param location string = 'uksouth'

@description('The customer name, default for testing')
param customerName string = 'ExampleCustomer'

param newResourceGroupRequired bool = false
// ignore below if above is set to true
var existingResourceGroupName = 'rg-demo-existing'

// Create new resource group if required
resource newResourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' = if (newResourceGroupRequired) {
  name: 'rg-demo-${customerName}-new'
  location: location
}

// Use existing resource group if required
resource existingResourceGroup 'Microsoft.Resources/resourceGroups@2022-09-01' existing = {
  name: existingResourceGroupName
}

module storage 'modules/storage.bicep' = {
  scope: newResourceGroupRequired ? newResourceGroup : existingResourceGroup
  name: 'storage'
  params: {
    location: location
    storageAccountName: 'satestmikeb56'
  }
}

The deployment fails with

New-AzDeployment: 17:08:19 - The deployment 'deployment' failed with error(s). Showing 2 out of 2 error(s).
Status Message: The Resource 'Microsoft.Storage/storageAccounts/satestmikeb56' under resource group '<null>' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix `(Code:ResourceNotFound)

If I leave the newResourceGroupRequired value set as false and set the scope on the module declaration to reference the newResourceGroup resource directly, as below, it deploys fine.

module storage 'modules/storage.bicep' = {
  scope: newResourceGroup
  name: 'storage'
  params: {
    location: location
    storageAccountName: 'satestmikeb56'
  }
}

Same if I change the bool to true and set the scope to existingResourceGroup, the storage module deploys without issue.

If used the ternary operator successfully on other parameters recently but I'm unable to do so in this case. Is there a another/better way to accomplish this?

Any help would be greatly appreciated!


It appears the nested deployment is not building correctly:

  • it is using the location
  • it is not adding the resourcegroup

what it is building to:

    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "storage",
      "location": "[deployment().location]",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },

what it should be building to:

    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2022-09-01",
      "name": "storage",
      "resourceGroup" : "[if(parameters('newResourceGroupRequired'), format('rg-demo-{0}-new', parameters('customerName')), variables('existingResourceGroupName'))]",
      // "location": "[deployment().location]",
      "properties": {
        "expressionEvaluationOptions": {
          "scope": "inner"
        },
@ghost ghost added the Needs: Triage 🔍 label Apr 13, 2023
@brwilkinson
Copy link
Collaborator Author

@TacticalNuclearSpud

You can drop back to this syntax as the workaround for this for now.

module storage 'modules/storage.bicep' = {
  scope: resourceGroup(newResourceGroupRequired ? newResourceGroup.name : existingResourceGroup.name) // <-- workaround
  name: 'storage'
  params: {
    location: location
    storageAccountName: 'satestmikeb56'
  }
}

@TacticalNuclearSpud
Copy link

@TacticalNuclearSpud

You can drop back to this syntax as the workaround for this for now.

module storage 'modules/storage.bicep' = {
  scope: resourceGroup(newResourceGroupRequired ? newResourceGroup.name : existingResourceGroup.name) // <-- workaround
  name: 'storage'
  params: {
    location: location
    storageAccountName: 'satestmikeb56'
  }
}

That worked perfectly, thanks very much!

@ttq-ak
Copy link

ttq-ak commented Apr 14, 2023

Just to add a comment and say I hit this earlier today too, but I got it on a variable that was a ternary of two resourcegroups so I think this might not be restricted to only scope functions. My bicep was like the below (Stripped down for a repro):

param UseRGOfKeyVault bool = false
param KeyVaultId string = '' //ResourceId of a keyvault

var TheResourceGroup = UseRGOfKeyVault ? resourceGroup(split(KeyVaultId,'/')[4]) : resourceGroup()

module 'SubModule' submodule.bicep {
    name: 'submodule'
    scope: TheResourceGroup 
}

When compiled into ARM the TheResourceGroup variable looked like the below:

"KeyVaultResourceGroup": "[if(parameters('UseRGOfKeyVault'), createObject(), resourceGroup())]",

Hopefully this is something that can either be fixed or flagged in bicep as something that doesn't work

@ttq-ak
Copy link

ttq-ak commented Apr 17, 2023

Have created another minimal repro to see if it was to do with my use of split inside resourceGroup, but it appears any value inside resourceGroup results in the ARM being compiled with a createObject()

Bicep:

param TheCondition bool = true

param AResourceId string

var TheSpecificResourceGroup = split(AResourceId, '/')[4]

var BothDefaultResourceGroup = TheCondition ? resourceGroup() : resourceGroup()

var FirstHardcodedResourceGroup = TheCondition ? resourceGroup('testing-rg') : resourceGroup()

var FirstSpecificResourceGroup = TheCondition ? resourceGroup(split(AResourceId, '/')[4]) : resourceGroup()

var SecondSpecificResourceGroup = TheCondition ? resourceGroup() : resourceGroup(split(AResourceId, '/')[4])

var BothSpecificResourceGroup = TheCondition ? resourceGroup(split(AResourceId, '/')[4]) : resourceGroup(split(AResourceId, '/')[4])

ARM:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.16.2.56959",
      "templateHash": "9124305957741027644"
    }
  },
  "parameters": {
    "TheCondition": {
      "type": "bool",
      "defaultValue": true
    },
    "AResourceId": {
      "type": "string"
    }
  },
  "variables": {
    "TheSpecificResourceGroup": "[split(parameters('AResourceId'), '/')[4]]",
    "BothDefaultResourceGroup": "[if(parameters('TheCondition'), resourceGroup(), resourceGroup())]",
    "FirstHardcodedResourceGroup": "[if(parameters('TheCondition'), createObject(), resourceGroup())]",
    "FirstSpecificResourceGroup": "[if(parameters('TheCondition'), createObject(), resourceGroup())]",
    "SecondSpecificResourceGroup": "[if(parameters('TheCondition'), resourceGroup(), createObject())]",
    "BothSpecificResourceGroup": "[if(parameters('TheCondition'), createObject(), createObject())]"
  },
  "resources": []
}

@brwilkinson
Copy link
Collaborator Author

@brwilkinson
Copy link
Collaborator Author

@anthony-c-martin can you please review above while looking at #10475

@anthony-c-martin
Copy link
Member

Related?

Good catch - yes these look like the same issue to me.

@stephaniezyen
Copy link
Contributor

Closing because of duplicate issue

@github-project-automation github-project-automation bot moved this from Todo to Done in Bicep Apr 28, 2023
@ghost ghost locked as resolved and limited conversation to collaborators May 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Archived in project
Development

No branches or pull requests

5 participants