Skip to content

Commit

Permalink
Support target scopes for modules (#771)
Browse files Browse the repository at this point in the history
* Add scope type

* Very basic emitter, no validation

* Attach function arguments to scope

* Add ability to set target scope

* Add example create-rg-lock-role-assignment

* Fix up some tests

* Pull in latest types, fix up tests

* Check for multiple instances of targetScope declaration

* Create INamedDeclarationSyntax

* Tidy up

* Add some tests

* Update docs for scopes

* Avoid outputting unrepresentible function types to JSON

* Tidy up, add some comments

* Combine AzResourceScope & ResoureScopeType enums

* Fix vscode e2e test
  • Loading branch information
anthony-c-martin authored Nov 3, 2020
1 parent 83b846d commit 895cac2
Show file tree
Hide file tree
Showing 126 changed files with 10,453 additions and 4,033 deletions.
2 changes: 1 addition & 1 deletion bicep-types-az
Submodule bicep-types-az updated 130 files
Original file line number Diff line number Diff line change
@@ -1,33 +1,5 @@
param location string {
default: resourceGroup().location
allowed: [
'australiacentral'
'australiaeast'
'australiasoutheast'
'brazilsouth'
'canadacentral'
'centralindia'
'centralus'
'eastasia'
'eastus'
'eastus2'
'francecentral'
'japaneast'
'koreacentral'
'northcentralus'
'northeurope'
'southafricanorth'
'southcentralus'
'southeastasia'
'switzerlandnorth'
'switzerlandwest'
'uksouth'
'ukwest'
'westcentralus'
'westeurope'
'westus'
'westus2'
]
}

param logAnalyticsWorkspaceName string = 'la-${uniqueString(resourceGroup().id)}'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,7 @@
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"allowedValues": [
"australiacentral",
"australiaeast",
"australiasoutheast",
"brazilsouth",
"canadacentral",
"centralindia",
"centralus",
"eastasia",
"eastus",
"eastus2",
"francecentral",
"japaneast",
"koreacentral",
"northcentralus",
"northeurope",
"southafricanorth",
"southcentralus",
"southeastasia",
"switzerlandnorth",
"switzerlandwest",
"uksouth",
"ukwest",
"westcentralus",
"westeurope",
"westus",
"westus2"
]
"defaultValue": "[resourceGroup().location]"
},
"logAnalyticsWorkspaceName": {
"type": "string",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
targetScope = 'resourceGroup'

param principalId string
param roleDefinitionId string
param roleAssignmentName string

resource lockResource 'Microsoft.Authorization/locks@2016-09-01' = {
name: 'DontDelete'
properties: {
level: 'CanNotDelete'
notes: 'Prevent deletion of the resourceGroup'
}
}

resource assignmentResource 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
name: guid(roleAssignmentName)
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId)
principalId: principalId
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string"
},
"roleDefinitionId": {
"type": "string"
},
"roleAssignmentName": {
"type": "string"
}
},
"functions": [],
"resources": [
{
"type": "Microsoft.Authorization/locks",
"apiVersion": "2016-09-01",
"name": "DontDelete",
"properties": {
"level": "CanNotDelete",
"notes": "Prevent deletion of the resourceGroup"
}
},
{
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2020-04-01-preview",
"name": "[guid(parameters('roleAssignmentName'))]",
"properties": {
"roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]",
"principalId": "[parameters('principalId')]"
}
}
]
}
23 changes: 23 additions & 0 deletions docs/examples/modules/create-rg-lock-role-assignment/main.bicep
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
targetScope = 'subscription'

param rgName string
param rgLocation string
param principalId string
param roleDefinitionId string = 'b24988ac-6180-42a0-ab88-20f7382dd24c' // default is contributor
param roleAssignmentName string = guid(principalId, roleDefinitionId, rgName)

resource newRg 'Microsoft.Resources/resourceGroups@2019-10-01' = {
name: rgName
location: rgLocation
properties: {}
}

module applyLock './applylock.bicep' = {
name: 'applyLock'
scope: resourceGroup(newRg.name)
params: {
principalId: principalId
roleDefinitionId: roleDefinitionId
roleAssignmentName: roleAssignmentName
}
}
95 changes: 95 additions & 0 deletions docs/examples/modules/create-rg-lock-role-assignment/main.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"rgName": {
"type": "string"
},
"rgLocation": {
"type": "string"
},
"principalId": {
"type": "string"
},
"roleDefinitionId": {
"type": "string",
"defaultValue": "b24988ac-6180-42a0-ab88-20f7382dd24c"
},
"roleAssignmentName": {
"type": "string",
"defaultValue": "[guid(parameters('principalId'), parameters('roleDefinitionId'), parameters('rgName'))]"
}
},
"functions": [],
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2019-10-01",
"name": "[parameters('rgName')]",
"location": "[parameters('rgLocation')]",
"properties": {}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2019-10-01",
"name": "applyLock",
"resourceGroup": "[parameters('rgName')]",
"properties": {
"expressionEvaluationOptions": {
"scope": "inner"
},
"mode": "Incremental",
"parameters": {
"principalId": {
"value": "[parameters('principalId')]"
},
"roleDefinitionId": {
"value": "[parameters('roleDefinitionId')]"
},
"roleAssignmentName": {
"value": "[parameters('roleAssignmentName')]"
}
},
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"principalId": {
"type": "string"
},
"roleDefinitionId": {
"type": "string"
},
"roleAssignmentName": {
"type": "string"
}
},
"functions": [],
"resources": [
{
"type": "Microsoft.Authorization/locks",
"apiVersion": "2016-09-01",
"name": "DontDelete",
"properties": {
"level": "CanNotDelete",
"notes": "Prevent deletion of the resourceGroup"
}
},
{
"type": "Microsoft.Authorization/roleAssignments",
"apiVersion": "2020-04-01-preview",
"name": "[guid(parameters('roleAssignmentName'))]",
"properties": {
"roleDefinitionId": "[subscriptionResourceId('Microsoft.Authorization/roleDefinitions', parameters('roleDefinitionId'))]",
"principalId": "[parameters('principalId')]"
}
}
]
}
},
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups', parameters('rgName'))]"
]
}
]
}
3 changes: 3 additions & 0 deletions docs/grammar.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@ The following is the active pseudo-grammar of the bicep language.
```
program -> statement* EOF
statement ->
targetScopeDecl |
parameterDecl |
variableDecl |
resourceDecl |
moduleDecl |
outputDecl |
NL
targetScopeDecl -> "targetScope" "=" expression
parameterDecl -> "parameter" IDENTIFIER(name) IDENTIFIER(type) (parameterDefaultValue | object(modifier))? NL
parameterDefaultValue -> "=" expression
Expand Down
19 changes: 18 additions & 1 deletion docs/spec/modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,21 @@ output ipFqdn string = publicIp.outputs.ipFqdn
```

### Notes
* All paths in Bicep must be specified using the forward slash (`/`) directory separator to ensure consistent compilation cross-platform. The Windows backslash (`\`) character is unsupported.
* All paths in Bicep must be specified using the forward slash (`/`) directory separator to ensure consistent compilation cross-platform. The Windows backslash (`\`) character is unsupported.

## Defining and configuring module scopes

It is possible to deploy across multiple scopes using the `scope` property when declaring a module. For example:

```bicep
module publicIp './publicIpAddress.bicep' = {
name: 'publicIp'
scope: resourceGroup('someOtherRg') // pass in a scope to a different resourceGroup
params: {
publicIpResourceName: publicIpName
dynamicAllocation: true
}
}
```

Please see [Resource Scopes](./resource-scopes.md) for more information and advanced usage.
Loading

0 comments on commit 895cac2

Please sign in to comment.