diff --git a/.github/scripts/coverage/.coverageignore b/.github/scripts/coverage/.coverageignore
index fdc4ff8fd89..1a2ca3703ab 100644
--- a/.github/scripts/coverage/.coverageignore
+++ b/.github/scripts/coverage/.coverageignore
@@ -3,4 +3,5 @@ pkg/engine/mock/*.go
*/**/*_test.go
**/*_mock.go
pkg/parser/jsonfilter/parser/jsonfilter*
+pkg/parser/bicep/antlr/parser/bicep*
internal/sentry
diff --git a/.golangci.yml b/.golangci.yml
index a062ac63ada..913f6ab6f21 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -137,3 +137,4 @@ run:
- docs
- vendor
- pkg/parser/jsonfilter/parser
+ - pkg/parser/bicep/antlr
diff --git a/Makefile b/Makefile
index a506022fd7f..c5f169685cb 100644
--- a/Makefile
+++ b/Makefile
@@ -131,7 +131,7 @@ dkr-compose: ## build docker image and runs docker-compose up
.PHONY: dkr-build-antlr
dkr-build-antlr: ## build ANTLRv4 docker image and generate parser based on given grammar
@docker build -t antlr4-generator:dev -f ./docker/Dockerfile.antlr .
- @docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v $(pwd)/pkg/parser/jsonfilter/:/work -it antlr4-generator:dev
+ @docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v $(pwd)/pkg/parser:/work -it antlr4-generator:dev
.PHONY: release
release: ## goreleaser --rm-dist
diff --git a/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/negative1.bicep b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/negative1.bicep
new file mode 100644
index 00000000000..15acd7fcfa1
--- /dev/null
+++ b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/negative1.bicep
@@ -0,0 +1,9 @@
+resource sample_server_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/server/default'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/negative2.bicep b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/negative2.bicep
new file mode 100644
index 00000000000..15acd7fcfa1
--- /dev/null
+++ b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/negative2.bicep
@@ -0,0 +1,9 @@
+resource sample_server_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/server/default'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive1.bicep b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive1.bicep
new file mode 100644
index 00000000000..bdec0c0fc0d
--- /dev/null
+++ b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive1.bicep
@@ -0,0 +1,9 @@
+resource sample_server_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/server/default'
+ properties: {
+ emailAccountAdmins: false
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive2.bicep b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive2.bicep
new file mode 100644
index 00000000000..c2debc2e0cf
--- /dev/null
+++ b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive2.bicep
@@ -0,0 +1,8 @@
+resource sample_server_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/server/default'
+ properties: {
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive3.bicep b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive3.bicep
new file mode 100644
index 00000000000..bdec0c0fc0d
--- /dev/null
+++ b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive3.bicep
@@ -0,0 +1,9 @@
+resource sample_server_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/server/default'
+ properties: {
+ emailAccountAdmins: false
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive4.bicep b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive4.bicep
new file mode 100644
index 00000000000..c2debc2e0cf
--- /dev/null
+++ b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive4.bicep
@@ -0,0 +1,8 @@
+resource sample_server_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/server/default'
+ properties: {
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive_expected_result.json b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive_expected_result.json
index 9d18c13ae33..8c4c5e42123 100644
--- a/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/account_admins_not_notified_by_email/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "INFO",
"line": 15,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "Account Admins Not Notified By Email",
+ "severity": "INFO",
+ "line": 4,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "Account Admins Not Notified By Email",
+ "severity": "INFO",
+ "line": 3,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "Account Admins Not Notified By Email",
+ "severity": "INFO",
+ "line": 4,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "Account Admins Not Notified By Email",
+ "severity": "INFO",
+ "line": 3,
+ "filename": "positive4.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/negative1.bicep b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/negative1.bicep
new file mode 100644
index 00000000000..28feebcaee9
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/negative1.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/negative2.bicep b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/negative2.bicep
new file mode 100644
index 00000000000..28feebcaee9
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/negative2.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive1.bicep b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive1.bicep
new file mode 100644
index 00000000000..f7c4d735b8f
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive1.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive2.bicep b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive2.bicep
new file mode 100644
index 00000000000..2320fff408c
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive2.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: ''
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive3.bicep b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive3.bicep
new file mode 100644
index 00000000000..f7c4d735b8f
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive3.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive4.bicep b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive4.bicep
new file mode 100644
index 00000000000..2320fff408c
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive4.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: ''
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive_expected_result.json b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive_expected_result.json
index 680dc3ae97c..31a9ddc78c3 100644
--- a/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/aks_cluster_network_policy_not_configured/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 39,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "AKS Cluster Network Policy Not Configured",
+ "severity": "MEDIUM",
+ "line": 2,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "AKS Cluster Network Policy Not Configured",
+ "severity": "MEDIUM",
+ "line": 31,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "AKS Cluster Network Policy Not Configured",
+ "severity": "MEDIUM",
+ "line": 2,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "AKS Cluster Network Policy Not Configured",
+ "severity": "MEDIUM",
+ "line": 31,
+ "filename": "positive4.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..328011b6b12
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/negative1.bicep
@@ -0,0 +1,32 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ enableRBAC: true
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..328011b6b12
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/negative2.bicep
@@ -0,0 +1,32 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ enableRBAC: true
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..f7c4d735b8f
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive1.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..9b535a52948
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive2.bicep
@@ -0,0 +1,32 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ enableRBAC: false
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..f7c4d735b8f
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive3.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..9b535a52948
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive4.bicep
@@ -0,0 +1,32 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ enableRBAC: false
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive_expected_result.json
index 4044e4f5294..70cdf5c8a8f 100644
--- a/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/aks_cluster_rbac_disabled/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "HIGH",
"line": 38,
"fileName": "positive4.json"
+ },
+ {
+ "queryName": "AKS Cluster RBAC Disabled",
+ "severity": "HIGH",
+ "line": 4,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "AKS Cluster RBAC Disabled",
+ "severity": "HIGH",
+ "line": 26,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "AKS Cluster RBAC Disabled",
+ "severity": "HIGH",
+ "line": 4,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "AKS Cluster RBAC Disabled",
+ "severity": "HIGH",
+ "line": 26,
+ "fileName": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative1.bicep b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative1.bicep
new file mode 100644
index 00000000000..128a124cf0a
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative1.bicep
@@ -0,0 +1,39 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ addonProfiles: {
+ kubeDashboard: {
+ enabled: false
+ }
+ }
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative2.bicep b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative2.bicep
new file mode 100644
index 00000000000..128a124cf0a
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative2.bicep
@@ -0,0 +1,39 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ addonProfiles: {
+ kubeDashboard: {
+ enabled: false
+ }
+ }
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative3.bicep b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative3.bicep
new file mode 100644
index 00000000000..28feebcaee9
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative3.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative4.bicep b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative4.bicep
new file mode 100644
index 00000000000..28feebcaee9
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/negative4.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive1.bicep b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive1.bicep
new file mode 100644
index 00000000000..a16bdd9730f
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive1.bicep
@@ -0,0 +1,39 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ addonProfiles: {
+ kubeDashboard: {
+ enabled: true
+ }
+ }
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive2.bicep b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive2.bicep
new file mode 100644
index 00000000000..a16bdd9730f
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive2.bicep
@@ -0,0 +1,39 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ addonProfiles: {
+ kubeDashboard: {
+ enabled: true
+ }
+ }
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive_expected_result.json
index da466fb42f9..2a226e8456a 100644
--- a/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/aks_dashboard_enabled/test/positive_expected_result.json
@@ -10,5 +10,17 @@
"severity": "LOW",
"line": 16,
"filename": "positive2.json"
+ },
+ {
+ "queryName": "AKS Dashboard Is Enabled",
+ "severity": "LOW",
+ "line": 8,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "AKS Dashboard Is Enabled",
+ "severity": "LOW",
+ "line": 8,
+ "filename": "positive2.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..ef868ef0acd
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/negative1.bicep
@@ -0,0 +1,39 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ addonProfiles: {
+ omsagent: {
+ enabled: true
+ }
+ }
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..ef868ef0acd
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/negative2.bicep
@@ -0,0 +1,39 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ addonProfiles: {
+ omsagent: {
+ enabled: true
+ }
+ }
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..c7ae876259c
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive1.bicep
@@ -0,0 +1,39 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ addonProfiles: {
+ omsagent: {
+ enabled: false
+ }
+ }
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..28feebcaee9
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive2.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..c7ae876259c
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive3.bicep
@@ -0,0 +1,39 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ addonProfiles: {
+ omsagent: {
+ enabled: false
+ }
+ }
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..28feebcaee9
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive4.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ networkProfile: {
+ networkPolicy: 'azure'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive_expected_result.json
index ab9b11c83cd..1f589057ff2 100644
--- a/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/aks_logging_azure_monitoring_disabled/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 8,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "AKS Logging To Azure Monitoring Is Disabled",
+ "severity": "MEDIUM",
+ "line": 8,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "AKS Logging To Azure Monitoring Is Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "AKS Logging To Azure Monitoring Is Disabled",
+ "severity": "MEDIUM",
+ "line": 8,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "AKS Logging To Azure Monitoring Is Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "filename": "positive4.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..4c413a954e2
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative1.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ apiServerAccessProfile: {
+ authorizedIPRanges: ['192.168.0.1', '192.168.0.18']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..0ae5b2a2224
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative2.bicep
@@ -0,0 +1,32 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2019-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ apiServerAuthorizedIPRanges: ['192.168.0.1', '192.168.0.18']
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative3.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative3.bicep
new file mode 100644
index 00000000000..4c413a954e2
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative3.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ apiServerAccessProfile: {
+ authorizedIPRanges: ['192.168.0.1', '192.168.0.18']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative4.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative4.bicep
new file mode 100644
index 00000000000..0ae5b2a2224
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/negative4.bicep
@@ -0,0 +1,32 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2019-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ apiServerAuthorizedIPRanges: ['192.168.0.1', '192.168.0.18']
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..98ce916790d
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive1.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2017-08-31' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive10.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive10.bicep
new file mode 100644
index 00000000000..a4f7dcaa482
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive10.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ apiServerAccessProfile: {
+ authorizedIPRanges: []
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..2c4d107bc6b
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive2.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2019-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..55d3a47753d
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive3.bicep
@@ -0,0 +1,32 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2019-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ apiServerAuthorizedIPRanges: []
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..f7c4d735b8f
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive4.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive5.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive5.bicep
new file mode 100644
index 00000000000..a4f7dcaa482
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive5.bicep
@@ -0,0 +1,34 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ apiServerAccessProfile: {
+ authorizedIPRanges: []
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive6.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive6.bicep
new file mode 100644
index 00000000000..98ce916790d
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive6.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2017-08-31' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive7.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive7.bicep
new file mode 100644
index 00000000000..2c4d107bc6b
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive7.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2019-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive8.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive8.bicep
new file mode 100644
index 00000000000..55d3a47753d
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive8.bicep
@@ -0,0 +1,32 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2019-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ apiServerAuthorizedIPRanges: []
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive9.bicep b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive9.bicep
new file mode 100644
index 00000000000..f7c4d735b8f
--- /dev/null
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive9.bicep
@@ -0,0 +1,31 @@
+resource aksCluster1 'Microsoft.ContainerService/managedClusters@2020-02-01' = {
+ name: 'aksCluster1'
+ location: resourceGroup().location
+ properties: {
+ kubernetesVersion: '1.15.7'
+ dnsPrefix: 'dnsprefix'
+ agentPoolProfiles: [
+ {
+ name: 'agentpool'
+ count: 2
+ vmSize: 'Standard_A1'
+ osType: 'Linux'
+ storageProfile: 'ManagedDisks'
+ }
+ ]
+ linuxProfile: {
+ adminUsername: 'adminUserName'
+ ssh: {
+ publicKeys: [
+ {
+ keyData: 'keyData'
+ }
+ ]
+ }
+ }
+ servicePrincipalProfile: {
+ clientId: 'servicePrincipalAppId'
+ secret: 'servicePrincipalAppPassword'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive_expected_result.json
index 07da9b40775..5c44f1fdc75 100644
--- a/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/aks_with_authorized_ip_ranges_disabled/test/positive_expected_result.json
@@ -58,5 +58,65 @@
"severity": "LOW",
"line": 39,
"filename": "positive10.json"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 1,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 2,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 30,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 2,
+ "filename": "positive4.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 31,
+ "filename": "positive5.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 1,
+ "filename": "positive6.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 2,
+ "filename": "positive7.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 30,
+ "filename": "positive8.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 2,
+ "filename": "positive9.bicep"
+ },
+ {
+ "queryName": "AKS With Authorized IP Ranges Disabled",
+ "severity": "LOW",
+ "line": 31,
+ "filename": "positive10.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative1.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative1.bicep
new file mode 100644
index 00000000000..09fe9eba4eb
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative1.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ enabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative2.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative2.bicep
new file mode 100644
index 00000000000..09fe9eba4eb
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative2.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ enabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative3.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative3.bicep
new file mode 100644
index 00000000000..09fe9eba4eb
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative3.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ enabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative4.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative4.bicep
new file mode 100644
index 00000000000..09fe9eba4eb
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/negative4.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ enabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive1.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive1.bicep
new file mode 100644
index 00000000000..3c7a2884f6d
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive1.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ enabled: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive2.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive2.bicep
new file mode 100644
index 00000000000..9df4a4ca82f
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive2.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ alwaysOn: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive3.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive3.bicep
new file mode 100644
index 00000000000..3c7a2884f6d
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive3.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ enabled: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive4.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive4.bicep
new file mode 100644
index 00000000000..9fcdbd767f9
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive4.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ alwaysOn: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive5.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive5.bicep
new file mode 100644
index 00000000000..3c7a2884f6d
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive5.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ enabled: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive6.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive6.bicep
new file mode 100644
index 00000000000..9df4a4ca82f
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive6.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ alwaysOn: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive7.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive7.bicep
new file mode 100644
index 00000000000..3c7a2884f6d
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive7.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ enabled: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive8.bicep b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive8.bicep
new file mode 100644
index 00000000000..9fcdbd767f9
--- /dev/null
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive8.bicep
@@ -0,0 +1,35 @@
+resource appServicePlan1 'Microsoft.Web/serverfarms@2018-02-01' = {
+ name: 'appServicePlan1'
+ location: resourceGroup().location
+ sku: {
+ name: 'F1'
+ capacity: 1
+ }
+ tags: {
+ displayName: 'appServicePlan1'
+ }
+ properties: {
+ name: 'appServicePlan1'
+ }
+}
+
+resource webApp1 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: appServicePlan1.id
+ }
+}
+
+resource webApp1_authsettings 'Microsoft.Web/sites/config@2020-12-01' = {
+ parent: webApp1
+ name: 'authsettings'
+ properties: {
+ alwaysOn: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive_expected_result.json b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive_expected_result.json
index 62411c91ec7..d3571dede33 100644
--- a/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/app_service_authentication_not_set/test/positive_expected_result.json
@@ -46,5 +46,53 @@
"severity": "MEDIUM",
"line": 42,
"fileName": "positive8.json"
+ },
+ {
+ "queryName": "App Service Authentication Is Not Set",
+ "severity": "MEDIUM",
+ "line": 33,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "App Service Authentication Is Not Set",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "App Service Authentication Is Not Set",
+ "severity": "MEDIUM",
+ "line": 33,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "App Service Authentication Is Not Set",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "App Service Authentication Is Not Set",
+ "severity": "MEDIUM",
+ "line": 33,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "App Service Authentication Is Not Set",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive6.bicep"
+ },
+ {
+ "queryName": "App Service Authentication Is Not Set",
+ "severity": "MEDIUM",
+ "line": 33,
+ "fileName": "positive7.bicep"
+ },
+ {
+ "queryName": "App Service Authentication Is Not Set",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive8.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative1.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative1.bicep
new file mode 100644
index 00000000000..765e610bad4
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative1.bicep
@@ -0,0 +1,68 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+@description('Specifies the location for all resources.')
+param location string = resourceGroup().location
+
+@description('Specifies a username for the Virtual Machine.')
+param adminUsername string
+
+@description(
+ 'Specifies the SSH rsa public key file as a string. Use "ssh-keygen -t rsa -b 2048" to generate your SSH key pairs.'
+)
+param adminPublicKey string
+
+@description('description')
+param vmSize string = 'Standard_D2s_v3'
+
+var vmName = '${projectName}-vm'
+var networkInterfaceName = '${projectName}-nic'
+
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: vmName
+ adminUsername: adminUsername
+ linuxConfiguration: {
+ disablePasswordAuthentication: true
+ ssh: {
+ publicKeys: [
+ {
+ path: '/home/${adminUsername}/.ssh/authorized_keys'
+ keyData: adminPublicKey
+ }
+ ]
+ }
+ }
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'Canonical'
+ offer: 'UbuntuServer'
+ sku: '18.04-LTS'
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'fromImage'
+ }
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId(
+ 'Microsoft.Network/networkInterfaces',
+ networkInterfaceName
+ )
+ }
+ ]
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
+ ]
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative2.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative2.bicep
new file mode 100644
index 00000000000..2243e011c26
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative2.bicep
@@ -0,0 +1,97 @@
+@description('Username for the Virtual Machine.')
+param adminUsername string
+
+@description('Password for the Virtual Machine.')
+@minLength(12)
+@secure()
+param adminPassword string
+
+@description(
+ 'The Windows version for the VM. This will pick a fully patched image of this given Windows version.'
+)
+@allowed(
+ [
+ '2008-R2-SP1'
+ '2012-Datacenter'
+ '2012-R2-Datacenter'
+ '2016-Nano-Server'
+ '2016-Datacenter-with-Containers'
+ '2016-Datacenter'
+ '2019-Datacenter'
+ '2019-Datacenter-Core'
+ '2019-Datacenter-Core-smalldisk'
+ '2019-Datacenter-Core-with-Containers'
+ '2019-Datacenter-Core-with-Containers-smalldisk'
+ '2019-Datacenter-smalldisk'
+ '2019-Datacenter-with-Containers'
+ '2019-Datacenter-with-Containers-smalldisk'
+ ]
+)
+param OSVersion string = '2019-Datacenter'
+
+@description('Size of the virtual machine.')
+param vmSize string = 'Standard_D2_v3'
+
+@description('Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Name of the virtual machine.')
+param vmName string = 'simple-vm'
+
+var storageAccountName = 'bootdiags${uniqueString(resourceGroup().id)}'
+var nicName = 'myVMNic'
+
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: vmName
+ adminUsername: adminUsername
+ adminPassword: adminPassword
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'MicrosoftWindowsServer'
+ offer: 'WindowsServer'
+ sku: OSVersion
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'FromImage'
+ managedDisk: {
+ storageAccountType: 'StandardSSD_LRS'
+ }
+ }
+ dataDisks: [
+ {
+ diskSizeGB: 1023
+ lun: 0
+ createOption: 'Empty'
+ }
+ ]
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId('Microsoft.Network/networkInterfaces', nicName)
+ }
+ ]
+ }
+ diagnosticsProfile: {
+ bootDiagnostics: {
+ enabled: true
+ storageUri: reference(
+ resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
+ ).primaryEndpoints.blob
+ }
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', nicName)
+ resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
+ ]
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative3.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative3.bicep
new file mode 100644
index 00000000000..765e610bad4
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative3.bicep
@@ -0,0 +1,68 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+@description('Specifies the location for all resources.')
+param location string = resourceGroup().location
+
+@description('Specifies a username for the Virtual Machine.')
+param adminUsername string
+
+@description(
+ 'Specifies the SSH rsa public key file as a string. Use "ssh-keygen -t rsa -b 2048" to generate your SSH key pairs.'
+)
+param adminPublicKey string
+
+@description('description')
+param vmSize string = 'Standard_D2s_v3'
+
+var vmName = '${projectName}-vm'
+var networkInterfaceName = '${projectName}-nic'
+
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: vmName
+ adminUsername: adminUsername
+ linuxConfiguration: {
+ disablePasswordAuthentication: true
+ ssh: {
+ publicKeys: [
+ {
+ path: '/home/${adminUsername}/.ssh/authorized_keys'
+ keyData: adminPublicKey
+ }
+ ]
+ }
+ }
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'Canonical'
+ offer: 'UbuntuServer'
+ sku: '18.04-LTS'
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'fromImage'
+ }
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId(
+ 'Microsoft.Network/networkInterfaces',
+ networkInterfaceName
+ )
+ }
+ ]
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
+ ]
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative4.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative4.bicep
new file mode 100644
index 00000000000..2243e011c26
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative4.bicep
@@ -0,0 +1,97 @@
+@description('Username for the Virtual Machine.')
+param adminUsername string
+
+@description('Password for the Virtual Machine.')
+@minLength(12)
+@secure()
+param adminPassword string
+
+@description(
+ 'The Windows version for the VM. This will pick a fully patched image of this given Windows version.'
+)
+@allowed(
+ [
+ '2008-R2-SP1'
+ '2012-Datacenter'
+ '2012-R2-Datacenter'
+ '2016-Nano-Server'
+ '2016-Datacenter-with-Containers'
+ '2016-Datacenter'
+ '2019-Datacenter'
+ '2019-Datacenter-Core'
+ '2019-Datacenter-Core-smalldisk'
+ '2019-Datacenter-Core-with-Containers'
+ '2019-Datacenter-Core-with-Containers-smalldisk'
+ '2019-Datacenter-smalldisk'
+ '2019-Datacenter-with-Containers'
+ '2019-Datacenter-with-Containers-smalldisk'
+ ]
+)
+param OSVersion string = '2019-Datacenter'
+
+@description('Size of the virtual machine.')
+param vmSize string = 'Standard_D2_v3'
+
+@description('Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Name of the virtual machine.')
+param vmName string = 'simple-vm'
+
+var storageAccountName = 'bootdiags${uniqueString(resourceGroup().id)}'
+var nicName = 'myVMNic'
+
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: vmName
+ adminUsername: adminUsername
+ adminPassword: adminPassword
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'MicrosoftWindowsServer'
+ offer: 'WindowsServer'
+ sku: OSVersion
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'FromImage'
+ managedDisk: {
+ storageAccountType: 'StandardSSD_LRS'
+ }
+ }
+ dataDisks: [
+ {
+ diskSizeGB: 1023
+ lun: 0
+ createOption: 'Empty'
+ }
+ ]
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId('Microsoft.Network/networkInterfaces', nicName)
+ }
+ ]
+ }
+ diagnosticsProfile: {
+ bootDiagnostics: {
+ enabled: true
+ storageUri: reference(
+ resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
+ ).primaryEndpoints.blob
+ }
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', nicName)
+ resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
+ ]
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative5.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative5.bicep
new file mode 100644
index 00000000000..87adabc94ef
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/negative5.bicep
@@ -0,0 +1,289 @@
+@description('The name of the VM')
+param virtualMachineName string = 'myVM'
+
+@description('The virtual machine size.')
+param virtualMachineSize string = 'Standard_D8s_v3'
+
+@description('Specify the name of an existing VNet in the same resource group')
+param existingVirtualNetworkName string
+
+@description('Specify the resrouce group of the existing VNet')
+param existingVnetResourceGroup string = resourceGroup().name
+
+@description('Specify the name of the Subnet Name')
+param existingSubnetName string
+
+@description('Windows Server and SQL Offer')
+@allowed(
+ [
+ 'sql2019-ws2019'
+ 'sql2017-ws2019'
+ 'SQL2017-WS2016'
+ 'SQL2016SP1-WS2016'
+ 'SQL2016SP2-WS2016'
+ 'SQL2014SP3-WS2012R2'
+ 'SQL2014SP2-WS2012R2'
+ ]
+)
+param imageOffer string = 'sql2019-ws2019'
+
+@description('SQL Server Sku')
+@allowed(['Standard', 'Enterprise', 'SQLDEV', 'Web', 'Express'])
+param sqlSku string = 'Standard'
+
+@description('Zone to deploy to')
+@allowed([1, 2, 3])
+param zone int = 1
+
+@description('The admin user name of the VM')
+param adminUsername string
+
+@description('The admin password of the VM')
+@secure()
+param adminPassword string
+
+@description('SQL Server Workload Type')
+@allowed(['General', 'OLTP', 'DW'])
+param storageWorkloadType string = 'General'
+
+@description('Amount of data disks (1TB each) for SQL Data files')
+@minValue(1)
+@maxValue(8)
+param sqlDataDisksCount int = 1
+
+@description(
+ 'Path for SQL Data files. Please choose drive letter from F to Z, and other drives from A to E are reserved for system'
+)
+param dataPath string = 'F:\\SQLData'
+
+@description('SQL Log UltraSSD Disk size in GiB.')
+param sqlLogUltraSSDDiskSizeInGB int = 512
+
+@description(
+ 'SQL Log UltraSSD Disk IOPS value representing the maximum IOPS that the disk can achieve.'
+)
+param sqlLogUltraSSDdiskIOPSReadWrite int = 20000
+
+@description(
+ 'SQL Log UltraSSD Disk MBps value representing the maximum throughput that the disk can achieve.'
+)
+param sqlLogUltraSSDdiskMbpsReadWrite int = 500
+
+@description(
+ 'Path for SQL Log files. Please choose drive letter from F to Z and different than the one used for SQL data. Drive letter from A to E are reserved for system'
+)
+param logPath string = 'G:\\SQLLog'
+
+@description('Location for all resources.')
+@allowed(['East US 2', 'SouthEast Asia', 'North Europe'])
+param location string
+
+var networkInterfaceName = '${virtualMachineName}-nic'
+var networkSecurityGroupName = '${virtualMachineName}-nsg'
+var networkSecurityGroupRules = [
+ {
+ name: 'RDP'
+ properties: {
+ priority: 300
+ protocol: 'TCP'
+ access: 'Allow'
+ direction: 'Inbound'
+ sourceAddressPrefix: '*'
+ sourcePortRange: '*'
+ destinationAddressPrefix: '*'
+ destinationPortRange: '3389'
+ }
+ }
+]
+var publicIpAddressName = '${virtualMachineName}-publicip-${uniqueString(virtualMachineName)}'
+var publicIpAddressType = 'Dynamic'
+var publicIpAddressSku = 'Basic'
+var diskConfigurationType = 'NEW'
+var nsgId = networkSecurityGroup.id
+var subnetRef = resourceId(
+ existingVnetResourceGroup,
+ 'Microsoft.Network/virtualNetWorks/subnets',
+ existingVirtualNetworkName,
+ existingSubnetName
+)
+var dataDisksLuns = array(range(0, sqlDataDisksCount))
+var logDisksLuns = array(range(sqlDataDisksCount, 1))
+var dataDisks = {
+ createOption: 'empty'
+ caching: 'ReadOnly'
+ writeAcceleratorEnabled: false
+ storageAccountType: 'Premium_LRS'
+ diskSizeGB: 1023
+}
+var tempDbPath = 'D:\\SQLTempdb'
+
+resource virtualMachineName_dataDisk_UltraSSD 'Microsoft.Compute/disks@2019-11-01' = [
+ for i in range(0, 1): {
+ name: '${virtualMachineName}-dataDisk-UltraSSD-${i}'
+ location: location
+ sku: {
+ name: 'UltraSSD_LRS'
+ }
+ zones: [zone]
+ properties: {
+ creationData: {
+ createOption: 'Empty'
+ }
+ encryptionSettingsCollection: {
+ enabled: false
+ encryptionSettings: [
+ {
+ diskEncryptionKey: {
+ sourceVault: {
+ id: '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault'
+ }
+ secretUrl: 'https://myvmvault.vault-int.azure-int.net/secrets/{secret}'
+ }
+ keyEncryptionKey: {
+ sourceVault: {
+ id: '/subscriptions/{subscriptionId}/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myVMVault'
+ }
+ keyUrl: 'https://myvmvault.vault-int.azure-int.net/keys/{key}'
+ }
+ }
+ ]
+ }
+ diskSizeGB: sqlLogUltraSSDDiskSizeInGB
+ diskIOPSReadWrite: sqlLogUltraSSDdiskIOPSReadWrite
+ diskMBpsReadWrite: sqlLogUltraSSDdiskMbpsReadWrite
+ }
+ }
+]
+
+resource publicIpAddress 'Microsoft.Network/publicIpAddresses@2020-05-01' = {
+ name: publicIpAddressName
+ location: location
+ sku: {
+ name: publicIpAddressSku
+ }
+ zones: [zone]
+ properties: {
+ publicIPAllocationMethod: publicIpAddressType
+ }
+}
+
+resource networkSecurityGroup 'Microsoft.Network/networkSecurityGroups@2020-05-01' = {
+ name: networkSecurityGroupName
+ location: location
+ properties: {
+ securityRules: networkSecurityGroupRules
+ }
+}
+
+resource networkInterface 'Microsoft.Network/networkInterfaces@2020-05-01' = {
+ name: networkInterfaceName
+ location: location
+ properties: {
+ ipConfigurations: [
+ {
+ name: 'ipconfig1'
+ properties: {
+ subnet: {
+ id: subnetRef
+ }
+ privateIPAllocationMethod: 'Dynamic'
+ publicIPAddress: {
+ id: publicIpAddress.id
+ }
+ }
+ }
+ ]
+ enableAcceleratedNetworking: true
+ networkSecurityGroup: {
+ id: nsgId
+ }
+ }
+}
+
+resource virtualMachine 'Microsoft.Compute/virtualMachines@2019-12-01' = {
+ name: virtualMachineName
+ location: location
+ zones: [zone]
+ properties: {
+ hardwareProfile: {
+ vmSize: virtualMachineSize
+ }
+ additionalCapabilities: {
+ ultraSSDEnabled: 'true'
+ }
+ storageProfile: {
+ osDisk: {
+ createOption: 'fromImage'
+ managedDisk: {
+ storageAccountType: 'Premium_LRS'
+ }
+ }
+ imageReference: {
+ publisher: 'MicrosoftSQLServer'
+ offer: imageOffer
+ sku: sqlSku
+ version: 'latest'
+ }
+ dataDisks: [
+ for j in range(0, (sqlDataDisksCount + 1)): {
+ lun: j
+ createOption: 'attach'
+ caching: ((j >= sqlDataDisksCount) ? 'None' : dataDisks.caching)
+ managedDisk: {
+ id: ((j >= sqlDataDisksCount)
+ ? resourceId(
+ 'Microsoft.Compute/disks/',
+ '${virtualMachineName}-dataDisk-UltraSSD-0'
+ )
+ : resourceId(
+ 'Microsoft.Compute/disks/',
+ '${virtualMachineName}-dataDisk-${j}'
+ ))
+ }
+ }
+ ]
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: networkInterface.id
+ }
+ ]
+ }
+ osProfile: {
+ computerName: virtualMachineName
+ adminUsername: adminUsername
+ adminPassword: adminPassword
+ windowsConfiguration: {
+ enableAutomaticUpdates: true
+ provisionVMAgent: true
+ }
+ }
+ }
+ dependsOn: [virtualMachineName_dataDisk_UltraSSD, 'PremiumSSDLoop']
+}
+
+resource Microsoft_SqlVirtualMachine_SqlVirtualMachines_virtualMachine 'Microsoft.SqlVirtualMachine/SqlVirtualMachines@2017-03-01-preview' = {
+ name: virtualMachineName
+ location: location
+ properties: {
+ virtualMachineResourceId: virtualMachine.id
+ sqlManagement: 'Full'
+ sqlServerLicenseType: 'PAYG'
+ storageConfigurationSettings: {
+ diskConfigurationType: diskConfigurationType
+ storageWorkloadType: storageWorkloadType
+ sqlDataSettings: {
+ luns: dataDisksLuns
+ defaultFilePath: dataPath
+ }
+ sqlLogSettings: {
+ luns: logDisksLuns
+ defaultFilePath: logPath
+ }
+ sqlTempDbSettings: {
+ defaultFilePath: tempDbPath
+ }
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive1.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive1.bicep
new file mode 100644
index 00000000000..6eab151ce1a
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive1.bicep
@@ -0,0 +1,55 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+@description('Specifies the location for all resources.')
+param location string = resourceGroup().location
+
+@description('Specifies a username for the Virtual Machine.')
+param adminUsername string
+
+@description('description')
+param vmSize string = 'Standard_D2s_v3'
+
+var vmName = '${projectName}-vm'
+var networkInterfaceName = '${projectName}-nic'
+
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: vmName
+ adminUsername: adminUsername
+ linuxConfiguration: {
+ disablePasswordAuthentication: false
+ }
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'Canonical'
+ offer: 'UbuntuServer'
+ sku: '18.04-LTS'
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'fromImage'
+ }
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId(
+ 'Microsoft.Network/networkInterfaces',
+ networkInterfaceName
+ )
+ }
+ ]
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
+ ]
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive2.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive2.bicep
new file mode 100644
index 00000000000..269c260743c
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive2.bicep
@@ -0,0 +1,52 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+@description('Specifies the location for all resources.')
+param location string = resourceGroup().location
+
+@description('Specifies a username for the Virtual Machine.')
+param adminUsername string
+
+@description('description')
+param vmSize string = 'Standard_D2s_v3'
+
+var vmName = '${projectName}-vm'
+var networkInterfaceName = '${projectName}-nic'
+
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: vmName
+ adminUsername: adminUsername
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'Canonical'
+ offer: 'UbuntuServer'
+ sku: '18.04-LTS'
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'fromImage'
+ }
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId(
+ 'Microsoft.Network/networkInterfaces',
+ networkInterfaceName
+ )
+ }
+ ]
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
+ ]
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive3.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive3.bicep
new file mode 100644
index 00000000000..6eab151ce1a
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive3.bicep
@@ -0,0 +1,55 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+@description('Specifies the location for all resources.')
+param location string = resourceGroup().location
+
+@description('Specifies a username for the Virtual Machine.')
+param adminUsername string
+
+@description('description')
+param vmSize string = 'Standard_D2s_v3'
+
+var vmName = '${projectName}-vm'
+var networkInterfaceName = '${projectName}-nic'
+
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: vmName
+ adminUsername: adminUsername
+ linuxConfiguration: {
+ disablePasswordAuthentication: false
+ }
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'Canonical'
+ offer: 'UbuntuServer'
+ sku: '18.04-LTS'
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'fromImage'
+ }
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId(
+ 'Microsoft.Network/networkInterfaces',
+ networkInterfaceName
+ )
+ }
+ ]
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
+ ]
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive4.bicep b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive4.bicep
new file mode 100644
index 00000000000..269c260743c
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive4.bicep
@@ -0,0 +1,52 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+@description('Specifies the location for all resources.')
+param location string = resourceGroup().location
+
+@description('Specifies a username for the Virtual Machine.')
+param adminUsername string
+
+@description('description')
+param vmSize string = 'Standard_D2s_v3'
+
+var vmName = '${projectName}-vm'
+var networkInterfaceName = '${projectName}-nic'
+
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: vmName
+ adminUsername: adminUsername
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'Canonical'
+ offer: 'UbuntuServer'
+ sku: '18.04-LTS'
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'fromImage'
+ }
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId(
+ 'Microsoft.Network/networkInterfaces',
+ networkInterfaceName
+ )
+ }
+ ]
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', networkInterfaceName)
+ ]
+}
diff --git a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive_expected_result.json b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive_expected_result.json
index 90610f903ce..9b56de65a46 100644
--- a/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/azure_instance_using_basic_authentication/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 42,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "Azure Instance Using Basic Authentication",
+ "severity": "MEDIUM",
+ "line": 27,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "Azure Instance Using Basic Authentication",
+ "severity": "MEDIUM",
+ "line": 17,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "Azure Instance Using Basic Authentication",
+ "severity": "MEDIUM",
+ "line": 27,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "Azure Instance Using Basic Authentication",
+ "severity": "MEDIUM",
+ "line": 17,
+ "filename": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/negative1.bicep b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/negative1.bicep
new file mode 100644
index 00000000000..7a51402cbac
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/negative1.bicep
@@ -0,0 +1,31 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+var vmName = '${projectName}-vm'
+
+resource vmName_disk1 'Microsoft.Compute/disks@2020-09-30' = {
+ name: '${vmName}-disk1'
+ location: resourceGroup().location
+ sku: {
+ name: 'Standard_LRS'
+ }
+ properties: {
+ creationData: {
+ createOption: 'Empty'
+ }
+ diskSizeGB: 512
+ encryptionSettingsCollection: {
+ enabled: true
+ encryptionSettings: [
+ {
+ diskEncryptionKey: {
+ secretUrl: 'https://secret.com/secrets/secret'
+ sourceVault: {
+ id: '/someid/somekey'
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/negative2.bicep b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/negative2.bicep
new file mode 100644
index 00000000000..7a51402cbac
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/negative2.bicep
@@ -0,0 +1,31 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+var vmName = '${projectName}-vm'
+
+resource vmName_disk1 'Microsoft.Compute/disks@2020-09-30' = {
+ name: '${vmName}-disk1'
+ location: resourceGroup().location
+ sku: {
+ name: 'Standard_LRS'
+ }
+ properties: {
+ creationData: {
+ createOption: 'Empty'
+ }
+ diskSizeGB: 512
+ encryptionSettingsCollection: {
+ enabled: true
+ encryptionSettings: [
+ {
+ diskEncryptionKey: {
+ secretUrl: 'https://secret.com/secrets/secret'
+ sourceVault: {
+ id: '/someid/somekey'
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive1.bicep b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive1.bicep
new file mode 100644
index 00000000000..d9af58059ee
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive1.bicep
@@ -0,0 +1,31 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+var vmName = '${projectName}-vm'
+
+resource vmName_disk1 'Microsoft.Compute/disks@2020-09-30' = {
+ name: '${vmName}-disk1'
+ location: resourceGroup().location
+ sku: {
+ name: 'Standard_LRS'
+ }
+ properties: {
+ creationData: {
+ createOption: 'Empty'
+ }
+ diskSizeGB: 512
+ encryptionSettingsCollection: {
+ enabled: false
+ encryptionSettings: [
+ {
+ diskEncryptionKey: {
+ secretUrl: 'https://secret.com/secrets/secret'
+ sourceVault: {
+ id: '/someid/somekey'
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive2.bicep b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive2.bicep
new file mode 100644
index 00000000000..b9cd95bea36
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive2.bicep
@@ -0,0 +1,18 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+var vmName = '${projectName}-vm'
+
+resource vmName_disk1 'Microsoft.Compute/disks@2020-09-30' = {
+ name: '${vmName}-disk1'
+ location: resourceGroup().location
+ sku: {
+ name: 'Standard_LRS'
+ }
+ properties: {
+ creationData: {
+ createOption: 'Empty'
+ }
+ diskSizeGB: 512
+ }
+}
diff --git a/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive3.bicep b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive3.bicep
new file mode 100644
index 00000000000..d9af58059ee
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive3.bicep
@@ -0,0 +1,31 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+var vmName = '${projectName}-vm'
+
+resource vmName_disk1 'Microsoft.Compute/disks@2020-09-30' = {
+ name: '${vmName}-disk1'
+ location: resourceGroup().location
+ sku: {
+ name: 'Standard_LRS'
+ }
+ properties: {
+ creationData: {
+ createOption: 'Empty'
+ }
+ diskSizeGB: 512
+ encryptionSettingsCollection: {
+ enabled: false
+ encryptionSettings: [
+ {
+ diskEncryptionKey: {
+ secretUrl: 'https://secret.com/secrets/secret'
+ sourceVault: {
+ id: '/someid/somekey'
+ }
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive4.bicep b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive4.bicep
new file mode 100644
index 00000000000..b9cd95bea36
--- /dev/null
+++ b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive4.bicep
@@ -0,0 +1,18 @@
+@description('Specifies a name for generating resource names.')
+param projectName string
+
+var vmName = '${projectName}-vm'
+
+resource vmName_disk1 'Microsoft.Compute/disks@2020-09-30' = {
+ name: '${vmName}-disk1'
+ location: resourceGroup().location
+ sku: {
+ name: 'Standard_LRS'
+ }
+ properties: {
+ creationData: {
+ createOption: 'Empty'
+ }
+ diskSizeGB: 512
+ }
+}
diff --git a/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive_expected_result.json b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive_expected_result.json
index 428e8043646..f69a151c8c5 100644
--- a/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/azure_managed_disk_without_encryption/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "HIGH",
"line": 21,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "Azure Managed Disk Without Encryption",
+ "severity": "HIGH",
+ "line": 18,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "Azure Managed Disk Without Encryption",
+ "severity": "HIGH",
+ "line": 7,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "Azure Managed Disk Without Encryption",
+ "severity": "HIGH",
+ "line": 18,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "Azure Managed Disk Without Encryption",
+ "severity": "HIGH",
+ "line": 7,
+ "filename": "positive4.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/negative1.bicep b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/negative1.bicep
new file mode 100644
index 00000000000..ae76d77701c
--- /dev/null
+++ b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/negative1.bicep
@@ -0,0 +1,18 @@
+param supportLogStorageAccountType string
+param storageApiVersion string = '2021-06-01'
+
+var computeLocation = 'comloc'
+
+resource negative1 'Microsoft.Storage/storageAccounts@storageApiVersion' = {
+ kind: 'Storage'
+ location: computeLocation
+ name: 'negative1'
+ properties: {
+ publicNetworkAccess: 'Disabled'
+ }
+ sku: {
+ name: supportLogStorageAccountType
+ }
+ tags: {}
+ dependsOn: []
+}
diff --git a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/negative2.bicep b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/negative2.bicep
new file mode 100644
index 00000000000..380bbdf43e1
--- /dev/null
+++ b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/negative2.bicep
@@ -0,0 +1,19 @@
+param supportLogStorageAccountType string
+
+var computeLocation = 'comloc'
+
+resource negative2 'Microsoft.Storage/storageAccounts@2021-06-01' = {
+ kind: 'Storage'
+ location: computeLocation
+ name: 'negative2'
+ properties: {
+ networkAcls: {
+ defaultAction: 'Deny'
+ }
+ }
+ sku: {
+ name: supportLogStorageAccountType
+ }
+ tags: {}
+ dependsOn: []
+}
diff --git a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive1.bicep b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive1.bicep
new file mode 100644
index 00000000000..8672c796698
--- /dev/null
+++ b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive1.bicep
@@ -0,0 +1,20 @@
+param supportLogStorageAccountType string
+param storageApiVersion string = '2021-06-01'
+
+var computeLocation = 'comloc'
+
+resource positive1 'Microsoft.Storage/storageAccounts@storageApiVersion' = {
+ kind: 'Storage'
+ location: computeLocation
+ name: 'positive1'
+ properties: {
+ networkAcls: {
+ defaultAction: 'Allow'
+ }
+ }
+ sku: {
+ name: supportLogStorageAccountType
+ }
+ tags: {}
+ dependsOn: []
+}
diff --git a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive2.bicep b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive2.bicep
new file mode 100644
index 00000000000..7c18a5d9b82
--- /dev/null
+++ b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive2.bicep
@@ -0,0 +1,16 @@
+param supportLogStorageAccountType string
+param storageApiVersion string = '2021-06-01'
+
+var computeLocation = 'comloc'
+
+resource positive2 'Microsoft.Storage/storageAccounts@storageApiVersion' = {
+ kind: 'Storage'
+ location: computeLocation
+ name: 'positive2'
+ properties: {}
+ sku: {
+ name: supportLogStorageAccountType
+ }
+ tags: {}
+ dependsOn: []
+}
diff --git a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive3.bicep b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive3.bicep
new file mode 100644
index 00000000000..0b2da297940
--- /dev/null
+++ b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive3.bicep
@@ -0,0 +1,18 @@
+param supportLogStorageAccountType string
+param storageApiVersion string = '2021-06-01'
+
+var computeLocation = 'comloc'
+
+resource positive3 'Microsoft.Storage/storageAccounts@storageApiVersion' = {
+ kind: 'Storage'
+ location: computeLocation
+ name: 'positive3'
+ properties: {
+ publicNetworkAccess: 'Enabled'
+ }
+ sku: {
+ name: supportLogStorageAccountType
+ }
+ tags: {}
+ dependsOn: []
+}
diff --git a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive_expected_result.json b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive_expected_result.json
index bd1b964727d..51ce6bdf54a 100644
--- a/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/default_azure_storage_account_network_access_is_too_permissive/test/positive_expected_result.json
@@ -16,5 +16,23 @@
"severity": "HIGH",
"line": 12,
"fileName": "positive3.json"
+ },
+ {
+ "queryName": "Default Azure Storage Account Network Access Is Too Permissive",
+ "severity": "HIGH",
+ "line": 12,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Default Azure Storage Account Network Access Is Too Permissive",
+ "severity": "HIGH",
+ "line": 10,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Default Azure Storage Account Network Access Is Too Permissive",
+ "severity": "HIGH",
+ "line": 11,
+ "fileName": "positive3.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/negative1.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/negative1.bicep
new file mode 100644
index 00000000000..26f3a5742be
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/negative1.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/negative2.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/negative2.bicep
new file mode 100644
index 00000000000..26f3a5742be
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/negative2.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive1.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive1.bicep
new file mode 100644
index 00000000000..fce90975370
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive1.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'Off'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive10.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive10.bicep
new file mode 100644
index 00000000000..edfc2f0fe0c
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive10.bicep
@@ -0,0 +1,11 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive11.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive11.bicep
new file mode 100644
index 00000000000..d761b527a04
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive11.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'Off'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive12.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive12.bicep
new file mode 100644
index 00000000000..316159f73c0
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive12.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive2.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive2.bicep
new file mode 100644
index 00000000000..047c95bb6d7
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive2.bicep
@@ -0,0 +1,11 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive3.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive3.bicep
new file mode 100644
index 00000000000..0de0191abec
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive3.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive4.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive4.bicep
new file mode 100644
index 00000000000..edfc2f0fe0c
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive4.bicep
@@ -0,0 +1,11 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive5.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive5.bicep
new file mode 100644
index 00000000000..d761b527a04
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive5.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'Off'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive6.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive6.bicep
new file mode 100644
index 00000000000..316159f73c0
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive6.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive7.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive7.bicep
new file mode 100644
index 00000000000..fce90975370
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive7.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'Off'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive8.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive8.bicep
new file mode 100644
index 00000000000..047c95bb6d7
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive8.bicep
@@ -0,0 +1,11 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive9.bicep b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive9.bicep
new file mode 100644
index 00000000000..0de0191abec
--- /dev/null
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive9.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive_expected_result.json b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive_expected_result.json
index 41a16fb6131..205542f4c46 100644
--- a/assets/queries/azureResourceManager/email_notifications_set_off/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/email_notifications_set_off/test/positive_expected_result.json
@@ -70,5 +70,77 @@
"severity": "INFO",
"line": 22,
"filename": "positive12.json"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 7,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 3,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 6,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 3,
+ "filename": "positive4.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 11,
+ "filename": "positive5.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 10,
+ "filename": "positive6.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 7,
+ "filename": "positive7.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 3,
+ "filename": "positive8.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 6,
+ "filename": "positive9.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 3,
+ "filename": "positive10.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 11,
+ "filename": "positive11.bicep"
+ },
+ {
+ "queryName": "Email Notifications Disabled",
+ "severity": "INFO",
+ "line": 10,
+ "filename": "positive12.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative1.bicep b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative1.bicep
new file mode 100644
index 00000000000..0dee47cf157
--- /dev/null
+++ b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative1.bicep
@@ -0,0 +1,15 @@
+@secure()
+param secureParameter string = newGuid()
+param adminLogin string
+param sqlServerName string
+
+resource sqlServer 'Microsoft.Sql/servers@2015-05-01-preview' = {
+ name: sqlServerName
+ location: resourceGroup().location
+ tags: {}
+ properties: {
+ administratorLogin: adminLogin
+ administratorLoginPassword: secureParameter
+ version: '12.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative2.bicep b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative2.bicep
new file mode 100644
index 00000000000..c76d59fecb6
--- /dev/null
+++ b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative2.bicep
@@ -0,0 +1,15 @@
+@secure()
+param adminPassword string
+param adminLogin string
+param sqlServerName string
+
+resource sqlServer 'Microsoft.Sql/servers@2015-05-01-preview' = {
+ name: sqlServerName
+ location: resourceGroup().location
+ tags: {}
+ properties: {
+ administratorLogin: adminLogin
+ administratorLoginPassword: adminPassword
+ version: '12.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative3.bicep b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative3.bicep
new file mode 100644
index 00000000000..0dee47cf157
--- /dev/null
+++ b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative3.bicep
@@ -0,0 +1,15 @@
+@secure()
+param secureParameter string = newGuid()
+param adminLogin string
+param sqlServerName string
+
+resource sqlServer 'Microsoft.Sql/servers@2015-05-01-preview' = {
+ name: sqlServerName
+ location: resourceGroup().location
+ tags: {}
+ properties: {
+ administratorLogin: adminLogin
+ administratorLoginPassword: secureParameter
+ version: '12.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative4.bicep b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative4.bicep
new file mode 100644
index 00000000000..c76d59fecb6
--- /dev/null
+++ b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/negative4.bicep
@@ -0,0 +1,15 @@
+@secure()
+param adminPassword string
+param adminLogin string
+param sqlServerName string
+
+resource sqlServer 'Microsoft.Sql/servers@2015-05-01-preview' = {
+ name: sqlServerName
+ location: resourceGroup().location
+ tags: {}
+ properties: {
+ administratorLogin: adminLogin
+ administratorLoginPassword: adminPassword
+ version: '12.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive1.bicep b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive1.bicep
new file mode 100644
index 00000000000..dbbd4ac48cf
--- /dev/null
+++ b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive1.bicep
@@ -0,0 +1,15 @@
+@secure()
+param adminPassword string = 'HardcodedPassword'
+param adminLogin string
+param sqlServerName string
+
+resource sqlServer 'Microsoft.Sql/servers@2015-05-01-preview' = {
+ name: sqlServerName
+ location: resourceGroup().location
+ tags: {}
+ properties: {
+ administratorLogin: adminLogin
+ administratorLoginPassword: adminPassword
+ version: '12.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive2.bicep b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive2.bicep
new file mode 100644
index 00000000000..dbbd4ac48cf
--- /dev/null
+++ b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive2.bicep
@@ -0,0 +1,15 @@
+@secure()
+param adminPassword string = 'HardcodedPassword'
+param adminLogin string
+param sqlServerName string
+
+resource sqlServer 'Microsoft.Sql/servers@2015-05-01-preview' = {
+ name: sqlServerName
+ location: resourceGroup().location
+ tags: {}
+ properties: {
+ administratorLogin: adminLogin
+ administratorLoginPassword: adminPassword
+ version: '12.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive_expected_result.json b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive_expected_result.json
index 8ee8524f96f..66a1cf66b62 100644
--- a/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/hardcoded_securestring_parameter_default_value/test/positive_expected_result.json
@@ -10,5 +10,17 @@
"severity": "HIGH",
"line": 9,
"fileName": "positive2.json"
+ },
+ {
+ "queryName": "Hardcoded SecureString Parameter Default Value",
+ "severity": "HIGH",
+ "line": 2,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Hardcoded SecureString Parameter Default Value",
+ "severity": "HIGH",
+ "line": 2,
+ "fileName": "positive2.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/negative1.bicep b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/negative1.bicep
new file mode 100644
index 00000000000..605f77b7f5b
--- /dev/null
+++ b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/negative1.bicep
@@ -0,0 +1,29 @@
+resource keyVaultInstance 'Microsoft.KeyVault/vaults@2019-09-01' = {
+ name: 'keyVaultInstance'
+ location: 'location'
+ tags: {}
+ properties: {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ sku: {
+ family: 'A'
+ name: 'standard'
+ }
+ accessPolicies: [
+ {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ objectId: '99998888-8666-4144-9199-2d7cd0111111'
+ permissions: {
+ keys: ['encrypt']
+ }
+ }
+ ]
+ vaultUri: 'string'
+ enabledForDeployment: true
+ enabledForDiskEncryption: true
+ enabledForTemplateDeployment: true
+ enableSoftDelete: true
+ softDeleteRetentionInDays: 80
+ enableRbacAuthorization: true
+ enablePurgeProtection: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/negative2.bicep b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/negative2.bicep
new file mode 100644
index 00000000000..605f77b7f5b
--- /dev/null
+++ b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/negative2.bicep
@@ -0,0 +1,29 @@
+resource keyVaultInstance 'Microsoft.KeyVault/vaults@2019-09-01' = {
+ name: 'keyVaultInstance'
+ location: 'location'
+ tags: {}
+ properties: {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ sku: {
+ family: 'A'
+ name: 'standard'
+ }
+ accessPolicies: [
+ {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ objectId: '99998888-8666-4144-9199-2d7cd0111111'
+ permissions: {
+ keys: ['encrypt']
+ }
+ }
+ ]
+ vaultUri: 'string'
+ enabledForDeployment: true
+ enabledForDiskEncryption: true
+ enabledForTemplateDeployment: true
+ enableSoftDelete: true
+ softDeleteRetentionInDays: 80
+ enableRbacAuthorization: true
+ enablePurgeProtection: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive1.bicep b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive1.bicep
new file mode 100644
index 00000000000..6810bc4560a
--- /dev/null
+++ b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive1.bicep
@@ -0,0 +1,28 @@
+resource keyVaultInstance 'Microsoft.KeyVault/vaults@2019-09-01' = {
+ name: 'keyVaultInstance'
+ location: 'location'
+ tags: {}
+ properties: {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ sku: {
+ family: 'A'
+ name: 'standard'
+ }
+ accessPolicies: [
+ {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ objectId: '99998888-8666-4144-9199-2d7cd0111111'
+ permissions: {
+ keys: ['encrypt']
+ }
+ }
+ ]
+ vaultUri: 'string'
+ enabledForDeployment: true
+ enabledForDiskEncryption: true
+ enabledForTemplateDeployment: true
+ enableSoftDelete: true
+ softDeleteRetentionInDays: 80
+ enableRbacAuthorization: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive2.bicep b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive2.bicep
new file mode 100644
index 00000000000..87d7c4a0542
--- /dev/null
+++ b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive2.bicep
@@ -0,0 +1,29 @@
+resource keyVaultInstance 'Microsoft.KeyVault/vaults@2019-09-01' = {
+ name: 'keyVaultInstance'
+ location: 'location'
+ tags: {}
+ properties: {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ sku: {
+ family: 'A'
+ name: 'standard'
+ }
+ accessPolicies: [
+ {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ objectId: '99998888-8666-4144-9199-2d7cd0111111'
+ permissions: {
+ keys: ['encrypt']
+ }
+ }
+ ]
+ vaultUri: 'string'
+ enabledForDeployment: true
+ enabledForDiskEncryption: true
+ enabledForTemplateDeployment: true
+ enableSoftDelete: true
+ softDeleteRetentionInDays: 80
+ enableRbacAuthorization: true
+ enablePurgeProtection: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive3.bicep b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive3.bicep
new file mode 100644
index 00000000000..6810bc4560a
--- /dev/null
+++ b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive3.bicep
@@ -0,0 +1,28 @@
+resource keyVaultInstance 'Microsoft.KeyVault/vaults@2019-09-01' = {
+ name: 'keyVaultInstance'
+ location: 'location'
+ tags: {}
+ properties: {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ sku: {
+ family: 'A'
+ name: 'standard'
+ }
+ accessPolicies: [
+ {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ objectId: '99998888-8666-4144-9199-2d7cd0111111'
+ permissions: {
+ keys: ['encrypt']
+ }
+ }
+ ]
+ vaultUri: 'string'
+ enabledForDeployment: true
+ enabledForDiskEncryption: true
+ enabledForTemplateDeployment: true
+ enableSoftDelete: true
+ softDeleteRetentionInDays: 80
+ enableRbacAuthorization: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive4.bicep b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive4.bicep
new file mode 100644
index 00000000000..87d7c4a0542
--- /dev/null
+++ b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive4.bicep
@@ -0,0 +1,29 @@
+resource keyVaultInstance 'Microsoft.KeyVault/vaults@2019-09-01' = {
+ name: 'keyVaultInstance'
+ location: 'location'
+ tags: {}
+ properties: {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ sku: {
+ family: 'A'
+ name: 'standard'
+ }
+ accessPolicies: [
+ {
+ tenantId: '72f98888-8666-4144-9199-2d7cd0111111'
+ objectId: '99998888-8666-4144-9199-2d7cd0111111'
+ permissions: {
+ keys: ['encrypt']
+ }
+ }
+ ]
+ vaultUri: 'string'
+ enabledForDeployment: true
+ enabledForDiskEncryption: true
+ enabledForTemplateDeployment: true
+ enableSoftDelete: true
+ softDeleteRetentionInDays: 80
+ enableRbacAuthorization: true
+ enablePurgeProtection: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive5.bicep b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive5.bicep
new file mode 100644
index 00000000000..b6f1c125f60
--- /dev/null
+++ b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive5.bicep
@@ -0,0 +1,165 @@
+param vaults_pgs_bot_prod_name int = 5
+
+resource vaults_pgs_bot_prod_name_resource 'Microsoft.KeyVault/vaults@2016-10-01' = {
+ name: vaults_pgs_bot_prod_name
+ location: 'westeurope'
+ tags: {
+ ProjectCodeBU: 'UKMUMD'
+ ApplicationName: 'PGS HR Chatbot'
+ ProjectCodePGDS: 'PRJ0024896'
+ CostCentreBU: 'UKMUMD'
+ DataClassification: 'General'
+ BusinessUnit: 'PGS'
+ Owner: 'Pru UK Andover Innovation Team'
+ Contact: 'andover2@prudential.co.uk'
+ CostCentrePGDS: 'ITBUEXP'
+ Criticality: 'Low'
+ }
+ properties: {
+ sku: {
+ family: 'A'
+ name: 'standard'
+ }
+ tenantId: 'aa42167d-6f8d-45ce-b655-d245ef97da66'
+ accessPolicies: [
+ {
+ tenantId: 'aa42167d-6f8d-45ce-b655-d245ef97da66'
+ objectId: 'f3e7baf5-8d66-4fb2-b7aa-7b7484309df6'
+ permissions: {
+ keys: [
+ 'Get'
+ 'Create'
+ 'Delete'
+ 'List'
+ 'Update'
+ 'Import'
+ 'Backup'
+ 'Restore'
+ 'Recover'
+ ]
+ secrets: [
+ 'Get'
+ 'List'
+ 'Set'
+ 'Delete'
+ 'Backup'
+ 'Restore'
+ 'Recover'
+ ]
+ certificates: [
+ 'Get'
+ 'Delete'
+ 'List'
+ 'Create'
+ 'Import'
+ 'Update'
+ 'DeleteIssuers'
+ 'GetIssuers'
+ 'ListIssuers'
+ 'ManageContacts'
+ 'ManageIssuers'
+ 'SetIssuers'
+ ]
+ storage: [
+ 'delete'
+ 'deletesas'
+ 'get'
+ 'getsas'
+ 'list'
+ 'listsas'
+ 'regeneratekey'
+ 'set'
+ 'setsas'
+ 'update'
+ ]
+ }
+ }
+ {
+ tenantId: 'aa42167d-6f8d-45ce-b655-d245ef97da66'
+ objectId: '1033a977-ffdc-4359-869a-b673d075f128'
+ permissions: {
+ keys: []
+ secrets: [
+ 'Get'
+ ]
+ certificates: []
+ storage: []
+ }
+ }
+ {
+ tenantId: 'aa42167d-6f8d-45ce-b655-d245ef97da66'
+ objectId: '13be5d2d-6e1f-4667-add4-02d2d1142ac5'
+ permissions: {
+ keys: []
+ secrets: [
+ 'Get'
+ 'List'
+ 'Set'
+ 'Delete'
+ 'Backup'
+ 'Restore'
+ 'Recover'
+ 'Purge'
+ ]
+ certificates: []
+ storage: []
+ }
+ }
+ {
+ tenantId: 'aa42167d-6f8d-45ce-b655-d245ef97da66'
+ objectId: 'e56a2de8-a788-415f-b10f-14bfd3000e1d'
+ permissions: {
+ keys: [
+ 'Get'
+ 'List'
+ 'Update'
+ 'Create'
+ 'Import'
+ 'Delete'
+ 'Recover'
+ 'Backup'
+ 'Restore'
+ 'Decrypt'
+ 'Encrypt'
+ 'UnwrapKey'
+ 'WrapKey'
+ 'Verify'
+ 'Sign'
+ 'Purge'
+ ]
+ secrets: [
+ 'Get'
+ 'List'
+ 'Set'
+ 'Delete'
+ 'Recover'
+ 'Backup'
+ 'Restore'
+ 'Purge'
+ ]
+ certificates: [
+ 'Get'
+ 'List'
+ 'Update'
+ 'Create'
+ 'Import'
+ 'Delete'
+ 'Recover'
+ 'Backup'
+ 'Restore'
+ 'ManageContacts'
+ 'ManageIssuers'
+ 'GetIssuers'
+ 'ListIssuers'
+ 'SetIssuers'
+ 'DeleteIssuers'
+ 'Purge'
+ ]
+ }
+ }
+ ]
+ enabledForDeployment: false
+ enabledForDiskEncryption: false
+ enabledForTemplateDeployment: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive_expected_result.json b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive_expected_result.json
index 70c55b484d3..aedb11e80d1 100644
--- a/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/key_vault_not_recoverable/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "HIGH",
"line": 23,
"fileName": "positive5.json"
+ },
+ {
+ "queryName": "Key Vault Not Recoverable",
+ "severity": "HIGH",
+ "line": 5,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Key Vault Not Recoverable",
+ "severity": "HIGH",
+ "line": 27,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Key Vault Not Recoverable",
+ "severity": "HIGH",
+ "line": 5,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Key Vault Not Recoverable",
+ "severity": "HIGH",
+ "line": 27,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Key Vault Not Recoverable",
+ "severity": "HIGH",
+ "line": 18,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Key Vault Not Recoverable",
+ "severity": "HIGH",
+ "line": 18,
+ "fileName": "positive5.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/log_profile_incorrect_category/test/negative1.bicep b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/negative1.bicep
new file mode 100644
index 00000000000..cfbbe1b2039
--- /dev/null
+++ b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/negative1.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'eastus'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['eastus']
+ categories: ['Write']
+ retentionPolicy: {
+ enabled: true
+ days: 450
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/log_profile_incorrect_category/test/negative2.bicep b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/negative2.bicep
new file mode 100644
index 00000000000..cfbbe1b2039
--- /dev/null
+++ b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/negative2.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'eastus'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['eastus']
+ categories: ['Write']
+ retentionPolicy: {
+ enabled: true
+ days: 450
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive1.bicep b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive1.bicep
new file mode 100644
index 00000000000..e53aac892fb
--- /dev/null
+++ b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive1.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'eastus'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['eastus']
+ categories: ['Writ']
+ retentionPolicy: {
+ enabled: true
+ days: 450
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive2.bicep b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive2.bicep
new file mode 100644
index 00000000000..e53aac892fb
--- /dev/null
+++ b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive2.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'eastus'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['eastus']
+ categories: ['Writ']
+ retentionPolicy: {
+ enabled: true
+ days: 450
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive_expected_result.json b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive_expected_result.json
index d6d8fd0dca2..5493d0ff29d 100644
--- a/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/log_profile_incorrect_category/test/positive_expected_result.json
@@ -10,5 +10,17 @@
"severity": "LOW",
"line": 24,
"fileName": "positive2.json"
+ },
+ {
+ "queryName": "Log Profile Incorrect Category",
+ "severity": "LOW",
+ "line": 9,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Log Profile Incorrect Category",
+ "severity": "LOW",
+ "line": 9,
+ "fileName": "positive2.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..fa00f3f509a
--- /dev/null
+++ b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/negative1.bicep
@@ -0,0 +1,14 @@
+resource server 'Microsoft.DBforMySQL/servers@2017-12-01' = {
+ name: 'server'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ properties: {
+ version: '5.6'
+ sslEnforcement: 'Enabled'
+ createMode: 'GeoRestore'
+ sourceServerId: 'id'
+ }
+ location: 'location'
+ tags: {}
+}
diff --git a/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..fa00f3f509a
--- /dev/null
+++ b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/negative2.bicep
@@ -0,0 +1,14 @@
+resource server 'Microsoft.DBforMySQL/servers@2017-12-01' = {
+ name: 'server'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ properties: {
+ version: '5.6'
+ sslEnforcement: 'Enabled'
+ createMode: 'GeoRestore'
+ sourceServerId: 'id'
+ }
+ location: 'location'
+ tags: {}
+}
diff --git a/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..0e217e6268b
--- /dev/null
+++ b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive1.bicep
@@ -0,0 +1,13 @@
+resource server 'Microsoft.DBforMySQL/servers@2017-12-01' = {
+ name: 'server'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ properties: {
+ version: '5.6'
+ createMode: 'GeoRestore'
+ sourceServerId: 'id'
+ }
+ location: 'location'
+ tags: {}
+}
diff --git a/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..74ba85a1f9d
--- /dev/null
+++ b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive2.bicep
@@ -0,0 +1,14 @@
+resource server 'Microsoft.DBforMySQL/servers@2017-12-01' = {
+ name: 'server'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ properties: {
+ version: '5.6'
+ sslEnforcement: 'Disabled'
+ createMode: 'GeoRestore'
+ sourceServerId: 'id'
+ }
+ location: 'location'
+ tags: {}
+}
diff --git a/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..0e217e6268b
--- /dev/null
+++ b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive3.bicep
@@ -0,0 +1,13 @@
+resource server 'Microsoft.DBforMySQL/servers@2017-12-01' = {
+ name: 'server'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ properties: {
+ version: '5.6'
+ createMode: 'GeoRestore'
+ sourceServerId: 'id'
+ }
+ location: 'location'
+ tags: {}
+}
diff --git a/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..74ba85a1f9d
--- /dev/null
+++ b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive4.bicep
@@ -0,0 +1,14 @@
+resource server 'Microsoft.DBforMySQL/servers@2017-12-01' = {
+ name: 'server'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ properties: {
+ version: '5.6'
+ sslEnforcement: 'Disabled'
+ createMode: 'GeoRestore'
+ sourceServerId: 'id'
+ }
+ location: 'location'
+ tags: {}
+}
diff --git a/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive_expected_result.json
index e9aa5d90167..a2a485c0bac 100644
--- a/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/mysql_server_ssl_enforcement_disabled/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 20,
"fileName": "positive4.json"
+ },
+ {
+ "queryName": "MySQL Server SSL Enforcement Disabled",
+ "severity": "MEDIUM",
+ "line": 6,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "MySQL Server SSL Enforcement Disabled",
+ "severity": "MEDIUM",
+ "line": 8,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "MySQL Server SSL Enforcement Disabled",
+ "severity": "MEDIUM",
+ "line": 6,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "MySQL Server SSL Enforcement Disabled",
+ "severity": "MEDIUM",
+ "line": 8,
+ "fileName": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative1.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative1.bicep
new file mode 100644
index 00000000000..5188c2febbc
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative1.bicep
@@ -0,0 +1,24 @@
+resource security_group 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'security group'
+ location: 'location1'
+ tags: {}
+ properties: {
+ securityRules: [
+ {
+ id: 'id'
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '3389'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Deny'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule'
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative2.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative2.bicep
new file mode 100644
index 00000000000..5ac777d2a3e
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative2.bicep
@@ -0,0 +1,14 @@
+resource sample_securitygroup 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ name: 'sample/securitygroup'
+ properties: {
+ description: 'access'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['4030-5100']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative3.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative3.bicep
new file mode 100644
index 00000000000..01771aa98d6
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative3.bicep
@@ -0,0 +1,22 @@
+resource securitygroup 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'securitygroup'
+ location: 'location1'
+ tags: {}
+ properties: {}
+}
+
+resource securitygroup_sr 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ parent: securitygroup
+ properties: {
+ description: 'access'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['6634']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+ name: 'sr'
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative4.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative4.bicep
new file mode 100644
index 00000000000..5188c2febbc
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative4.bicep
@@ -0,0 +1,24 @@
+resource security_group 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'security group'
+ location: 'location1'
+ tags: {}
+ properties: {
+ securityRules: [
+ {
+ id: 'id'
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '3389'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Deny'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule'
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative5.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative5.bicep
new file mode 100644
index 00000000000..5ac777d2a3e
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative5.bicep
@@ -0,0 +1,14 @@
+resource sample_securitygroup 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ name: 'sample/securitygroup'
+ properties: {
+ description: 'access'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['4030-5100']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative6.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative6.bicep
new file mode 100644
index 00000000000..01771aa98d6
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/negative6.bicep
@@ -0,0 +1,22 @@
+resource securitygroup 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'securitygroup'
+ location: 'location1'
+ tags: {}
+ properties: {}
+}
+
+resource securitygroup_sr 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ parent: securitygroup
+ properties: {
+ description: 'access'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['6634']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+ name: 'sr'
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive1.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive1.bicep
new file mode 100644
index 00000000000..7123b102346
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive1.bicep
@@ -0,0 +1,39 @@
+resource security_group 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'security group'
+ location: 'location1'
+ tags: {}
+ properties: {
+ securityRules: [
+ {
+ id: 'id'
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '3389'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule'
+ }
+ {
+ id: 'id2'
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '22'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Deny'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule2'
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive2.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive2.bicep
new file mode 100644
index 00000000000..1ced10f0188
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive2.bicep
@@ -0,0 +1,14 @@
+resource sample_securitygroup 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ name: 'sample/securitygroup'
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['3333-3389']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive3.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive3.bicep
new file mode 100644
index 00000000000..75dc7c65ccc
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive3.bicep
@@ -0,0 +1,22 @@
+resource securitygroup 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'securitygroup'
+ location: 'location1'
+ tags: {}
+ properties: {}
+}
+
+resource securitygroup_sr 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ parent: securitygroup
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['3333-3389']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+ name: 'sr'
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive4.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive4.bicep
new file mode 100644
index 00000000000..99da3c759c4
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive4.bicep
@@ -0,0 +1,24 @@
+resource security_group 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'security group'
+ location: 'location1'
+ tags: {}
+ properties: {
+ securityRules: [
+ {
+ id: 'id'
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '3389'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule'
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive5.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive5.bicep
new file mode 100644
index 00000000000..1ced10f0188
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive5.bicep
@@ -0,0 +1,14 @@
+resource sample_securitygroup 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ name: 'sample/securitygroup'
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['3333-3389']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive6.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive6.bicep
new file mode 100644
index 00000000000..75dc7c65ccc
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive6.bicep
@@ -0,0 +1,22 @@
+resource securitygroup 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'securitygroup'
+ location: 'location1'
+ tags: {}
+ properties: {}
+}
+
+resource securitygroup_sr 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ parent: securitygroup
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['3333-3389']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+ name: 'sr'
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive_expected_result.json b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive_expected_result.json
index d8f69b76e0d..81f2c0350d3 100644
--- a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_rdp/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "HIGH",
"line": 22,
"fileName": "positive6.json"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To RDP",
+ "severity": "HIGH",
+ "line": 9,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To RDP",
+ "severity": "HIGH",
+ "line": 3,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To RDP",
+ "severity": "HIGH",
+ "line": 10,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To RDP",
+ "severity": "HIGH",
+ "line": 9,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To RDP",
+ "severity": "HIGH",
+ "line": 3,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To RDP",
+ "severity": "HIGH",
+ "line": 10,
+ "fileName": "positive6.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative1.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative1.bicep
new file mode 100644
index 00000000000..ee5ac3bcee3
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative1.bicep
@@ -0,0 +1,24 @@
+resource security_group 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'security group'
+ location: 'location1'
+ tags: {}
+ properties: {
+ securityRules: [
+ {
+ id: 'id'
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '22'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Deny'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule'
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative2.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative2.bicep
new file mode 100644
index 00000000000..5ac777d2a3e
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative2.bicep
@@ -0,0 +1,14 @@
+resource sample_securitygroup 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ name: 'sample/securitygroup'
+ properties: {
+ description: 'access'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['4030-5100']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative3.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative3.bicep
new file mode 100644
index 00000000000..01771aa98d6
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative3.bicep
@@ -0,0 +1,22 @@
+resource securitygroup 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'securitygroup'
+ location: 'location1'
+ tags: {}
+ properties: {}
+}
+
+resource securitygroup_sr 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ parent: securitygroup
+ properties: {
+ description: 'access'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['6634']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+ name: 'sr'
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative4.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative4.bicep
new file mode 100644
index 00000000000..ee5ac3bcee3
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative4.bicep
@@ -0,0 +1,24 @@
+resource security_group 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'security group'
+ location: 'location1'
+ tags: {}
+ properties: {
+ securityRules: [
+ {
+ id: 'id'
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '22'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Deny'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule'
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative5.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative5.bicep
new file mode 100644
index 00000000000..5ac777d2a3e
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative5.bicep
@@ -0,0 +1,14 @@
+resource sample_securitygroup 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ name: 'sample/securitygroup'
+ properties: {
+ description: 'access'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['4030-5100']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative6.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative6.bicep
new file mode 100644
index 00000000000..01771aa98d6
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/negative6.bicep
@@ -0,0 +1,22 @@
+resource securitygroup 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'securitygroup'
+ location: 'location1'
+ tags: {}
+ properties: {}
+}
+
+resource securitygroup_sr 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ parent: securitygroup
+ properties: {
+ description: 'access'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['6634']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+ name: 'sr'
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive1.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive1.bicep
new file mode 100644
index 00000000000..1fc290ccf3d
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive1.bicep
@@ -0,0 +1,39 @@
+resource security_group 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'security group'
+ location: 'location1'
+ tags: {}
+ properties: {
+ securityRules: [
+ {
+ id: 'id'
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '22'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule'
+ }
+ {
+ id: 'id2'
+ properties: {
+ description: 'access to RDP'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '3389'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Deny'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule2'
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive2.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive2.bicep
new file mode 100644
index 00000000000..5ef4d1c1452
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive2.bicep
@@ -0,0 +1,14 @@
+resource sample_securitygroup 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ name: 'sample/securitygroup'
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['22-23']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive3.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive3.bicep
new file mode 100644
index 00000000000..f6aaaa8f206
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive3.bicep
@@ -0,0 +1,22 @@
+resource securitygroup 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'securitygroup'
+ location: 'location1'
+ tags: {}
+ properties: {}
+}
+
+resource securitygroup_sr 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ parent: securitygroup
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['22-23']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+ name: 'sr'
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive4.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive4.bicep
new file mode 100644
index 00000000000..d56b261851f
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive4.bicep
@@ -0,0 +1,24 @@
+resource security_group 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'security group'
+ location: 'location1'
+ tags: {}
+ properties: {
+ securityRules: [
+ {
+ id: 'id'
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRange: '22'
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 301
+ direction: 'Inbound'
+ }
+ name: 'security rule'
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive5.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive5.bicep
new file mode 100644
index 00000000000..5ef4d1c1452
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive5.bicep
@@ -0,0 +1,14 @@
+resource sample_securitygroup 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ name: 'sample/securitygroup'
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['22-23']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive6.bicep b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive6.bicep
new file mode 100644
index 00000000000..f6aaaa8f206
--- /dev/null
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive6.bicep
@@ -0,0 +1,22 @@
+resource securitygroup 'Microsoft.Network/networkSecurityGroups@2020-11-01' = {
+ name: 'securitygroup'
+ location: 'location1'
+ tags: {}
+ properties: {}
+}
+
+resource securitygroup_sr 'Microsoft.Network/networkSecurityGroups/securityRules@2020-11-01' = {
+ parent: securitygroup
+ properties: {
+ description: 'access to SSH'
+ protocol: 'Tcp'
+ sourcePortRange: '*'
+ destinationPortRanges: ['22-23']
+ sourceAddressPrefix: '*'
+ destinationAddressPrefix: '*'
+ access: 'Allow'
+ priority: 100
+ direction: 'Inbound'
+ }
+ name: 'sr'
+}
diff --git a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive_expected_result.json b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive_expected_result.json
index 89f5d2d09c0..f4b05c4f8ac 100644
--- a/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/network_security_group_with_unrestricted_access_to_ssh/test/positive_expected_result.json
@@ -40,5 +40,41 @@
"severity": "MEDIUM",
"line": 22,
"fileName": "positive7.json"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To SSH",
+ "severity": "MEDIUM",
+ "line": 9,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To SSH",
+ "severity": "MEDIUM",
+ "line": 3,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To SSH",
+ "severity": "MEDIUM",
+ "line": 10,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To SSH",
+ "severity": "MEDIUM",
+ "line": 9,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To SSH",
+ "severity": "MEDIUM",
+ "line": 3,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Network Security Group With Unrestricted Access To SSH",
+ "severity": "MEDIUM",
+ "line": 10,
+ "fileName": "positive6.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/negative1.bicep b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/negative1.bicep
new file mode 100644
index 00000000000..967f0ca6bb6
--- /dev/null
+++ b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/negative1.bicep
@@ -0,0 +1,18 @@
+@description('Name sof resource group')
+param resourceGroupName string
+
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/negative2.bicep b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/negative2.bicep
new file mode 100644
index 00000000000..967f0ca6bb6
--- /dev/null
+++ b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/negative2.bicep
@@ -0,0 +1,18 @@
+@description('Name sof resource group')
+param resourceGroupName string
+
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive1.bicep b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive1.bicep
new file mode 100644
index 00000000000..be678e8f4bc
--- /dev/null
+++ b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive1.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive2.bicep b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive2.bicep
new file mode 100644
index 00000000000..be678e8f4bc
--- /dev/null
+++ b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive2.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive_expected_result.json b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive_expected_result.json
index 47e85da9240..05b67ec86dd 100644
--- a/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/phone_number_not_set_security_contacts/test/positive_expected_result.json
@@ -10,5 +10,17 @@
"severity": "LOW",
"line": 15,
"fileName": "positive2.json"
+ },
+ {
+ "queryName": "Phone Number Not Set For Security Contacts",
+ "severity": "LOW",
+ "line": 3,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Phone Number Not Set For Security Contacts",
+ "severity": "LOW",
+ "line": 3,
+ "fileName": "positive2.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..cba1be8698b
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative1.bicep
@@ -0,0 +1,38 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
+
+resource servers1_connection_throttling 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: servers1
+ name: 'connection_throttling'
+ properties: {
+ value: 'On'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..cba1be8698b
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative2.bicep
@@ -0,0 +1,38 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
+
+resource servers1_connection_throttling 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: servers1
+ name: 'connection_throttling'
+ properties: {
+ value: 'On'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative3.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative3.bicep
new file mode 100644
index 00000000000..cba1be8698b
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative3.bicep
@@ -0,0 +1,38 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
+
+resource servers1_connection_throttling 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: servers1
+ name: 'connection_throttling'
+ properties: {
+ value: 'On'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative4.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative4.bicep
new file mode 100644
index 00000000000..cba1be8698b
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/negative4.bicep
@@ -0,0 +1,38 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
+
+resource servers1_connection_throttling 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: servers1
+ name: 'connection_throttling'
+ properties: {
+ value: 'On'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..bcb6d9b23f9
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive1.bicep
@@ -0,0 +1,38 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
+
+resource servers1_connection_throttling 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: servers1
+ name: 'connection_throttling'
+ properties: {
+ value: 'Off'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..7a3c82cc54b
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive2.bicep
@@ -0,0 +1,30 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..8629a9b9536
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive3.bicep
@@ -0,0 +1,38 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
+
+resource servers1_sample_config 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: servers1
+ name: 'sample_config'
+ properties: {
+ value: 'Off'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..bcb6d9b23f9
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive4.bicep
@@ -0,0 +1,38 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
+
+resource servers1_connection_throttling 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: servers1
+ name: 'connection_throttling'
+ properties: {
+ value: 'Off'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive5.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive5.bicep
new file mode 100644
index 00000000000..7a3c82cc54b
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive5.bicep
@@ -0,0 +1,30 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive6.bicep b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive6.bicep
new file mode 100644
index 00000000000..8629a9b9536
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive6.bicep
@@ -0,0 +1,38 @@
+resource servers1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ name: 'servers1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ sku: {
+ name: 'B_Gen4_1'
+ tier: 'Basic'
+ capacity: 500
+ size: '500MB'
+ family: 'family'
+ }
+ properties: {
+ version: '11'
+ sslEnforcement: 'Enabled'
+ minimalTlsVersion: 'TLS1_2'
+ infrastructureEncryption: 'Enabled'
+ publicNetworkAccess: 'Disabled'
+ storageProfile: {
+ backupRetentionDays: 90
+ geoRedundantBackup: 'Enabled'
+ storageMB: 50
+ storageAutogrow: 'Enabled'
+ }
+ createMode: 'Replica'
+ sourceServerId: 'sample_id'
+ }
+ location: 'string'
+ tags: {}
+}
+
+resource servers1_sample_config 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: servers1
+ name: 'sample_config'
+ properties: {
+ value: 'Off'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive_expected_result.json
index 695cc730245..b27316cd0d4 100644
--- a/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/postgres_sql_database_server_connection_throttling_disabled/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "MEDIUM",
"line": 11,
"fileName": "positive6.json"
+ },
+ {
+ "queryName": "PostgresSQL Database Server Connection Throttling Disabled",
+ "severity": "MEDIUM",
+ "line": 36,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "PostgresSQL Database Server Connection Throttling Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "PostgresSQL Database Server Connection Throttling Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "PostgresSQL Database Server Connection Throttling Disabled",
+ "severity": "MEDIUM",
+ "line": 36,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "PostgresSQL Database Server Connection Throttling Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "PostgresSQL Database Server Connection Throttling Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive6.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..25d91d13f3a
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/negative1.bicep
@@ -0,0 +1,45 @@
+param databaseSkuName string
+param databaseSkuTier string
+param databaseDTU string
+param databaseSkuSizeMB string
+
+resource MyDBServerNeg1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServerNeg1'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: databaseSkuName
+ tier: databaseSkuTier
+ capacity: databaseDTU
+ size: databaseSkuSizeMB
+ family: 'SkuFamily'
+ }
+}
+
+resource MyDBServerNeg1_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServerNeg1
+ name: 'log_checkpoints'
+ properties: {
+ value: 'on'
+ }
+ location: resourceGroup().location
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/MyDBServer'
+ ]
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..25d91d13f3a
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/negative2.bicep
@@ -0,0 +1,45 @@
+param databaseSkuName string
+param databaseSkuTier string
+param databaseDTU string
+param databaseSkuSizeMB string
+
+resource MyDBServerNeg1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServerNeg1'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: databaseSkuName
+ tier: databaseSkuTier
+ capacity: databaseDTU
+ size: databaseSkuSizeMB
+ family: 'SkuFamily'
+ }
+}
+
+resource MyDBServerNeg1_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServerNeg1
+ name: 'log_checkpoints'
+ properties: {
+ value: 'on'
+ }
+ location: resourceGroup().location
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/MyDBServer'
+ ]
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..c69776cb159
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive1.bicep
@@ -0,0 +1,89 @@
+param dataDirectory string
+param maxSizeMB string
+param minSizeMB string
+param pageSizeMB string
+param workMemMB string
+param maintenanceMemMB string
+param checkpointSegments string
+param checkpointCompletionTarget string
+
+resource MyDBServer1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer1'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer1_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServer1
+ name: 'log_checkpoints'
+ properties: {
+ configurationSets: [
+ {
+ configurationSetType: 'Microsoft.DBforPostgreSQL/servers/configurations/dbconfig'
+ configurationSet: {
+ name: 'dbconfig'
+ configurationParameters: [
+ {
+ name: 'data_directory'
+ value: dataDirectory
+ }
+ {
+ name: 'max_size'
+ value: maxSizeMB
+ }
+ {
+ name: 'min_size'
+ value: minSizeMB
+ }
+ {
+ name: 'page_size'
+ value: pageSizeMB
+ }
+ {
+ name: 'work_mem'
+ value: workMemMB
+ }
+ {
+ name: 'maintenance_work_mem'
+ value: maintenanceMemMB
+ }
+ {
+ name: 'checkpoint_segments'
+ value: checkpointSegments
+ }
+ {
+ name: 'checkpoint_completion_target'
+ value: checkpointCompletionTarget
+ }
+ ]
+ }
+ }
+ ]
+ }
+ location: resourceGroup().location
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/MyDBServer'
+ ]
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..d503968ed30
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive2.bicep
@@ -0,0 +1,37 @@
+resource MyDBServer2 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer2'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer2_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServer2
+ name: 'log_checkpoints'
+ properties: {
+ value: 'off'
+ }
+ location: resourceGroup().location
+ dependsOn: ['Microsoft.DBforPostgreSQL/servers/MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..59dfce33c72
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive3.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_checkpoints'
+ properties: {
+ value: 'off'
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..300426acf61
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive4.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_checkpoints'
+ properties: {
+ source: 'source'
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive5.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive5.bicep
new file mode 100644
index 00000000000..c69776cb159
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive5.bicep
@@ -0,0 +1,89 @@
+param dataDirectory string
+param maxSizeMB string
+param minSizeMB string
+param pageSizeMB string
+param workMemMB string
+param maintenanceMemMB string
+param checkpointSegments string
+param checkpointCompletionTarget string
+
+resource MyDBServer1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer1'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer1_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServer1
+ name: 'log_checkpoints'
+ properties: {
+ configurationSets: [
+ {
+ configurationSetType: 'Microsoft.DBforPostgreSQL/servers/configurations/dbconfig'
+ configurationSet: {
+ name: 'dbconfig'
+ configurationParameters: [
+ {
+ name: 'data_directory'
+ value: dataDirectory
+ }
+ {
+ name: 'max_size'
+ value: maxSizeMB
+ }
+ {
+ name: 'min_size'
+ value: minSizeMB
+ }
+ {
+ name: 'page_size'
+ value: pageSizeMB
+ }
+ {
+ name: 'work_mem'
+ value: workMemMB
+ }
+ {
+ name: 'maintenance_work_mem'
+ value: maintenanceMemMB
+ }
+ {
+ name: 'checkpoint_segments'
+ value: checkpointSegments
+ }
+ {
+ name: 'checkpoint_completion_target'
+ value: checkpointCompletionTarget
+ }
+ ]
+ }
+ }
+ ]
+ }
+ location: resourceGroup().location
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/MyDBServer'
+ ]
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive6.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive6.bicep
new file mode 100644
index 00000000000..d503968ed30
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive6.bicep
@@ -0,0 +1,37 @@
+resource MyDBServer2 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer2'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer2_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServer2
+ name: 'log_checkpoints'
+ properties: {
+ value: 'off'
+ }
+ location: resourceGroup().location
+ dependsOn: ['Microsoft.DBforPostgreSQL/servers/MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive7.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive7.bicep
new file mode 100644
index 00000000000..59dfce33c72
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive7.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_checkpoints'
+ properties: {
+ value: 'off'
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive8.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive8.bicep
new file mode 100644
index 00000000000..300426acf61
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive8.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_checkpoints 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_checkpoints'
+ properties: {
+ source: 'source'
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive_expected_result.json
index 12b6a9328df..1cc3d9d0314 100644
--- a/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_checkpoint_disabled/test/positive_expected_result.json
@@ -46,5 +46,53 @@
"severity": "MEDIUM",
"line": 45,
"fileName": "positive8.json"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Checkpoints Disabled",
+ "severity": "MEDIUM",
+ "line": 40,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Checkpoints Disabled",
+ "severity": "MEDIUM",
+ "line": 33,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Checkpoints Disabled",
+ "severity": "MEDIUM",
+ "line": 32,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Checkpoints Disabled",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Checkpoints Disabled",
+ "severity": "MEDIUM",
+ "line": 40,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Checkpoints Disabled",
+ "severity": "MEDIUM",
+ "line": 33,
+ "fileName": "positive6.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Checkpoints Disabled",
+ "severity": "MEDIUM",
+ "line": 32,
+ "fileName": "positive7.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Checkpoints Disabled",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive8.bicep"
}
-]
+]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..6ae9c4584c7
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative1.bicep
@@ -0,0 +1,31 @@
+resource MyDBServerNeg1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServerNeg1'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+}
+
+resource MyDBServerNeg1_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServerNeg1
+ name: 'log_connections'
+ properties: {
+ value: 'on'
+ }
+ location: resourceGroup().location
+ dependsOn: ['Microsoft.DBforPostgreSQL/servers/MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..eef84783af1
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative2.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_connections'
+ properties: {
+ value: 'on'
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative3.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative3.bicep
new file mode 100644
index 00000000000..6ae9c4584c7
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative3.bicep
@@ -0,0 +1,31 @@
+resource MyDBServerNeg1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServerNeg1'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+}
+
+resource MyDBServerNeg1_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServerNeg1
+ name: 'log_connections'
+ properties: {
+ value: 'on'
+ }
+ location: resourceGroup().location
+ dependsOn: ['Microsoft.DBforPostgreSQL/servers/MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative4.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative4.bicep
new file mode 100644
index 00000000000..eef84783af1
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/negative4.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_connections'
+ properties: {
+ value: 'on'
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..6cf5d66c773
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive1.bicep
@@ -0,0 +1,43 @@
+resource MyDBServer1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer1'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer1_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServer1
+ name: 'log_connections'
+ properties: {
+ configurationSets: [
+ {
+ configurationSetType: 'Microsoft.DBforPostgreSQL/servers/configurations/dbconfig'
+ configurationSet: {
+ name: 'dbconfig'
+ }
+ }
+ ]
+ }
+ location: resourceGroup().location
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..570a007e459
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive2.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer2 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer2'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer2_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServer2
+ name: 'log_connections'
+ properties: {
+ value: 'off'
+ }
+ location: resourceGroup().location
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..7bb9001e643
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive3.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_connections'
+ properties: {
+ value: 'off'
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..11454ba3cc9
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive4.bicep
@@ -0,0 +1,43 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_connections'
+ properties: {
+ configurationSets: [
+ {
+ configurationSetType: 'Microsoft.DBforPostgreSQL/servers/configurations/dbconfig'
+ configurationSet: {
+ name: 'dbconfig'
+ }
+ }
+ ]
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive5.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive5.bicep
new file mode 100644
index 00000000000..6cf5d66c773
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive5.bicep
@@ -0,0 +1,43 @@
+resource MyDBServer1 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer1'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer1_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServer1
+ name: 'log_connections'
+ properties: {
+ configurationSets: [
+ {
+ configurationSetType: 'Microsoft.DBforPostgreSQL/servers/configurations/dbconfig'
+ configurationSet: {
+ name: 'dbconfig'
+ }
+ }
+ ]
+ }
+ location: resourceGroup().location
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive6.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive6.bicep
new file mode 100644
index 00000000000..570a007e459
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive6.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer2 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer2'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer2_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ parent: MyDBServer2
+ name: 'log_connections'
+ properties: {
+ value: 'off'
+ }
+ location: resourceGroup().location
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive7.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive7.bicep
new file mode 100644
index 00000000000..7bb9001e643
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive7.bicep
@@ -0,0 +1,36 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_connections'
+ properties: {
+ value: 'off'
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive8.bicep b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive8.bicep
new file mode 100644
index 00000000000..11454ba3cc9
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive8.bicep
@@ -0,0 +1,43 @@
+resource MyDBServer3 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer3'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: 'S0'
+ tier: 'Basic'
+ capacity: 1
+ family: 'GeneralPurpose'
+ }
+}
+
+resource MyDBServer_log_connections 'Microsoft.DBforPostgreSQL/servers/configurations@2017-12-01' = {
+ name: 'MyDBServer/log_connections'
+ properties: {
+ configurationSets: [
+ {
+ configurationSetType: 'Microsoft.DBforPostgreSQL/servers/configurations/dbconfig'
+ configurationSet: {
+ name: 'dbconfig'
+ }
+ }
+ ]
+ }
+ location: resourceGroup().location
+ dependsOn: ['MyDBServer']
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive_expected_result.json
index 23c9049a5a2..20ea5616ff9 100644
--- a/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/postgres_sql_server_log_connections_disabled/test/positive_expected_result.json
@@ -46,5 +46,53 @@
"severity": "MEDIUM",
"line": 45,
"fileName": "positive8.json"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Connections Disabled",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Connections Disabled",
+ "severity": "MEDIUM",
+ "line": 33,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Connections Disabled",
+ "severity": "MEDIUM",
+ "line": 32,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Connections Disabled",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Connections Disabled",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Connections Disabled",
+ "severity": "MEDIUM",
+ "line": 33,
+ "fileName": "positive6.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Connections Disabled",
+ "severity": "MEDIUM",
+ "line": 32,
+ "fileName": "positive7.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server Log Connections Disabled",
+ "severity": "MEDIUM",
+ "line": 31,
+ "fileName": "positive8.bicep"
}
-]
+]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..a50d7c38c63
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/negative1.bicep
@@ -0,0 +1,62 @@
+param databaseSkuName int = 5
+param databaseSkuTier int = 5
+param databaseDTU int = 5
+param databaseSkuSizeMB int = 5
+
+var serverName = 'server'
+
+resource MyDBServer 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer'
+ properties: {
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ sslEnforcement: 'Enabled'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ defaultSecondaryLocation: resourceGroup().location
+ maxSizeInGB: '10'
+ isEncrypted: 'false'
+ isNetworkAccessible: 'true'
+ identity: ''
+ }
+ sku: {
+ name: databaseSkuName
+ tier: databaseSkuTier
+ capacity: databaseDTU
+ size: databaseSkuSizeMB
+ family: 'SkuFamily'
+ }
+}
+
+resource MyDBServer_serverName_firewall 'Microsoft.DBforPostgreSQL/servers/firewallrules@2017-12-01' = {
+ parent: MyDBServer
+ location: resourceGroup().location
+ name: '${serverName}firewall'
+ properties: {
+ startIpAddress: '0.0.0.0'
+ endIpAddress: '255.255.255.255'
+ }
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/${serverName}'
+ ]
+}
+
+resource MyDBServer_myDB1 'Microsoft.DBforPostgreSQL/servers/databases@2017-12-01' = {
+ parent: MyDBServer
+ name: 'myDB1'
+ properties: {
+ charset: 'utf8'
+ collation: 'English_United States.1252'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..a50d7c38c63
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/negative2.bicep
@@ -0,0 +1,62 @@
+param databaseSkuName int = 5
+param databaseSkuTier int = 5
+param databaseDTU int = 5
+param databaseSkuSizeMB int = 5
+
+var serverName = 'server'
+
+resource MyDBServer 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer'
+ properties: {
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ sslEnforcement: 'Enabled'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ defaultSecondaryLocation: resourceGroup().location
+ maxSizeInGB: '10'
+ isEncrypted: 'false'
+ isNetworkAccessible: 'true'
+ identity: ''
+ }
+ sku: {
+ name: databaseSkuName
+ tier: databaseSkuTier
+ capacity: databaseDTU
+ size: databaseSkuSizeMB
+ family: 'SkuFamily'
+ }
+}
+
+resource MyDBServer_serverName_firewall 'Microsoft.DBforPostgreSQL/servers/firewallrules@2017-12-01' = {
+ parent: MyDBServer
+ location: resourceGroup().location
+ name: '${serverName}firewall'
+ properties: {
+ startIpAddress: '0.0.0.0'
+ endIpAddress: '255.255.255.255'
+ }
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/${serverName}'
+ ]
+}
+
+resource MyDBServer_myDB1 'Microsoft.DBforPostgreSQL/servers/databases@2017-12-01' = {
+ parent: MyDBServer
+ name: 'myDB1'
+ properties: {
+ charset: 'utf8'
+ collation: 'English_United States.1252'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..57441b3c99f
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive1.bicep
@@ -0,0 +1,57 @@
+param databaseSkuName int = 5
+param databaseSkuTier int = 5
+param databaseDTU int = 5
+param databaseSkuSizeMB int = 5
+
+var serverName = 'server'
+
+resource MyDBServer 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: databaseSkuName
+ tier: databaseSkuTier
+ capacity: databaseDTU
+ size: databaseSkuSizeMB
+ family: 'SkuFamily'
+ }
+}
+
+resource MyDBServer_serverName_firewall 'Microsoft.DBforPostgreSQL/servers/firewallrules@2017-12-01' = {
+ parent: MyDBServer
+ location: resourceGroup().location
+ name: '${serverName}firewall'
+ properties: {
+ startIpAddress: '0.0.0.0'
+ endIpAddress: '255.255.255.255'
+ }
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/${serverName}'
+ ]
+}
+
+resource MyDBServer_myDB1 'Microsoft.DBforPostgreSQL/servers/databases@2017-12-01' = {
+ parent: MyDBServer
+ name: 'myDB1'
+ properties: {
+ charset: 'utf8'
+ collation: 'English_United States.1252'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..02c447fe38d
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive2.bicep
@@ -0,0 +1,61 @@
+param databaseSkuName int = 5
+param databaseSkuTier int = 5
+param databaseDTU int = 5
+param databaseSkuSizeMB int = 5
+
+var serverName = 'server'
+
+resource MyDBServer 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer'
+ properties: {
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ defaultSecondaryLocation: resourceGroup().location
+ maxSizeInGB: '10'
+ isEncrypted: 'false'
+ isNetworkAccessible: 'true'
+ identity: ''
+ }
+ sku: {
+ name: databaseSkuName
+ tier: databaseSkuTier
+ capacity: databaseDTU
+ size: databaseSkuSizeMB
+ family: 'SkuFamily'
+ }
+}
+
+resource MyDBServer_serverName_firewall 'Microsoft.DBforPostgreSQL/servers/firewallrules@2017-12-01' = {
+ parent: MyDBServer
+ location: resourceGroup().location
+ name: '${serverName}firewall'
+ properties: {
+ startIpAddress: '0.0.0.0'
+ endIpAddress: '255.255.255.255'
+ }
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/${serverName}'
+ ]
+}
+
+resource MyDBServer_myDB1 'Microsoft.DBforPostgreSQL/servers/databases@2017-12-01' = {
+ parent: MyDBServer
+ name: 'myDB1'
+ properties: {
+ charset: 'utf8'
+ collation: 'English_United States.1252'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..57441b3c99f
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive3.bicep
@@ -0,0 +1,57 @@
+param databaseSkuName int = 5
+param databaseSkuTier int = 5
+param databaseDTU int = 5
+param databaseSkuSizeMB int = 5
+
+var serverName = 'server'
+
+resource MyDBServer 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer'
+ properties: {
+ sslEnforcement: 'Disabled'
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ }
+ sku: {
+ name: databaseSkuName
+ tier: databaseSkuTier
+ capacity: databaseDTU
+ size: databaseSkuSizeMB
+ family: 'SkuFamily'
+ }
+}
+
+resource MyDBServer_serverName_firewall 'Microsoft.DBforPostgreSQL/servers/firewallrules@2017-12-01' = {
+ parent: MyDBServer
+ location: resourceGroup().location
+ name: '${serverName}firewall'
+ properties: {
+ startIpAddress: '0.0.0.0'
+ endIpAddress: '255.255.255.255'
+ }
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/${serverName}'
+ ]
+}
+
+resource MyDBServer_myDB1 'Microsoft.DBforPostgreSQL/servers/databases@2017-12-01' = {
+ parent: MyDBServer
+ name: 'myDB1'
+ properties: {
+ charset: 'utf8'
+ collation: 'English_United States.1252'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..02c447fe38d
--- /dev/null
+++ b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive4.bicep
@@ -0,0 +1,61 @@
+param databaseSkuName int = 5
+param databaseSkuTier int = 5
+param databaseDTU int = 5
+param databaseSkuSizeMB int = 5
+
+var serverName = 'server'
+
+resource MyDBServer 'Microsoft.DBforPostgreSQL/servers@2017-12-01' = {
+ kind: ''
+ location: resourceGroup().location
+ name: 'MyDBServer'
+ properties: {
+ version: '11'
+ administratorLogin: 'root'
+ administratorLoginPassword: '12345'
+ storageMB: '2048'
+ createMode: 'Default'
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ creationDate: '2019-04-01T00:00:00Z'
+ lastModifiedDate: '2019-04-01T00:00:00Z'
+ maxSizeUnits: 'SizeUnit.megabytes'
+ isReadOnly: 'false'
+ isAutoUpgradeEnabled: 'true'
+ isStateful: 'false'
+ isExternal: 'false'
+ defaultSecondaryLocation: resourceGroup().location
+ maxSizeInGB: '10'
+ isEncrypted: 'false'
+ isNetworkAccessible: 'true'
+ identity: ''
+ }
+ sku: {
+ name: databaseSkuName
+ tier: databaseSkuTier
+ capacity: databaseDTU
+ size: databaseSkuSizeMB
+ family: 'SkuFamily'
+ }
+}
+
+resource MyDBServer_serverName_firewall 'Microsoft.DBforPostgreSQL/servers/firewallrules@2017-12-01' = {
+ parent: MyDBServer
+ location: resourceGroup().location
+ name: '${serverName}firewall'
+ properties: {
+ startIpAddress: '0.0.0.0'
+ endIpAddress: '255.255.255.255'
+ }
+ dependsOn: [
+ 'Microsoft.DBforPostgreSQL/servers/${serverName}'
+ ]
+}
+
+resource MyDBServer_myDB1 'Microsoft.DBforPostgreSQL/servers/databases@2017-12-01' = {
+ parent: MyDBServer
+ name: 'myDB1'
+ properties: {
+ charset: 'utf8'
+ collation: 'English_United States.1252'
+ }
+}
diff --git a/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive_expected_result.json
index ca8b3e0d43a..55b0b39ad44 100644
--- a/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/postgres_sql_server_ssl_disabled/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 15,
"fileName": "positive4.json"
+ },
+ {
+ "queryName": "PostgreSQL Database Server SSL Disabled",
+ "severity": "MEDIUM",
+ "line": 13,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server SSL Disabled",
+ "severity": "MEDIUM",
+ "line": 12,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server SSL Disabled",
+ "severity": "MEDIUM",
+ "line": 13,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "PostgreSQL Database Server SSL Disabled",
+ "severity": "MEDIUM",
+ "line": 12,
+ "fileName": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/negative1.bicep b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/negative1.bicep
new file mode 100644
index 00000000000..16b85bbe326
--- /dev/null
+++ b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/negative1.bicep
@@ -0,0 +1,13 @@
+resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: 'roleDef'
+ properties: {
+ roleName: 'my-custom-role'
+ description: 'This is a custom role'
+ permissions: [
+ {
+ actions: ['Microsoft.Authorization/roleDefinitions/read']
+ }
+ ]
+ assignableScopes: [subscription().id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/negative2.bicep b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/negative2.bicep
new file mode 100644
index 00000000000..16b85bbe326
--- /dev/null
+++ b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/negative2.bicep
@@ -0,0 +1,13 @@
+resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: 'roleDef'
+ properties: {
+ roleName: 'my-custom-role'
+ description: 'This is a custom role'
+ permissions: [
+ {
+ actions: ['Microsoft.Authorization/roleDefinitions/read']
+ }
+ ]
+ assignableScopes: [subscription().id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive1.bicep b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive1.bicep
new file mode 100644
index 00000000000..45c4124d4b7
--- /dev/null
+++ b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive1.bicep
@@ -0,0 +1,13 @@
+resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: 'roleDef'
+ properties: {
+ roleName: 'my-custom-role'
+ description: 'This is a custom role'
+ permissions: [
+ {
+ actions: ['*']
+ }
+ ]
+ assignableScopes: [subscription().id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive2.bicep b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive2.bicep
new file mode 100644
index 00000000000..368fedc0aed
--- /dev/null
+++ b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive2.bicep
@@ -0,0 +1,13 @@
+resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: 'roleDef'
+ properties: {
+ roleName: 'my-custom-role'
+ description: 'This is a custom role'
+ permissions: [
+ {
+ actions: ['Microsoft.Authorization/roleDefinitions/write']
+ }
+ ]
+ assignableScopes: [subscription().id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive3.bicep b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive3.bicep
new file mode 100644
index 00000000000..45c4124d4b7
--- /dev/null
+++ b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive3.bicep
@@ -0,0 +1,13 @@
+resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: 'roleDef'
+ properties: {
+ roleName: 'my-custom-role'
+ description: 'This is a custom role'
+ permissions: [
+ {
+ actions: ['*']
+ }
+ ]
+ assignableScopes: [subscription().id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive4.bicep b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive4.bicep
new file mode 100644
index 00000000000..368fedc0aed
--- /dev/null
+++ b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive4.bicep
@@ -0,0 +1,13 @@
+resource roleDef 'Microsoft.Authorization/roleDefinitions@2018-01-01-preview' = {
+ name: 'roleDef'
+ properties: {
+ roleName: 'my-custom-role'
+ description: 'This is a custom role'
+ permissions: [
+ {
+ actions: ['Microsoft.Authorization/roleDefinitions/write']
+ }
+ ]
+ assignableScopes: [subscription().id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive_expected_result.json b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive_expected_result.json
index 848b2a462bd..494dc192beb 100644
--- a/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/role_definitions_allow_custom_subscription_role_creation/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "HIGH",
"line": 20,
"fileName": "positive4.json"
+ },
+ {
+ "queryName": "Role Definitions Allow Custom Subscription Role Creation",
+ "severity": "HIGH",
+ "line": 8,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Role Definitions Allow Custom Subscription Role Creation",
+ "severity": "HIGH",
+ "line": 8,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Role Definitions Allow Custom Subscription Role Creation",
+ "severity": "HIGH",
+ "line": 8,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Role Definitions Allow Custom Subscription Role Creation",
+ "severity": "HIGH",
+ "line": 8,
+ "fileName": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/secret_without_expiration_date/test/negative1.bicep b/assets/queries/azureResourceManager/secret_without_expiration_date/test/negative1.bicep
new file mode 100644
index 00000000000..7ed87f0e955
--- /dev/null
+++ b/assets/queries/azureResourceManager/secret_without_expiration_date/test/negative1.bicep
@@ -0,0 +1,40 @@
+resource keyVault1 'Microsoft.KeyVault/vaults@2016-10-01' = {
+ name: 'keyVault1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'keyVault1'
+ }
+ properties: {
+ enabledForDeployment: true
+ enabledForTemplateDeployment: true
+ enabledForDiskEncryption: true
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ accessPolicies: [
+ {
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ objectId: 'objectId'
+ permissions: {
+ keys: ['Get']
+ secrets: ['List', 'Get', 'Set']
+ }
+ }
+ ]
+ sku: {
+ name: 'standard'
+ family: 'A'
+ }
+ }
+}
+
+resource keyVault1_keyVaultSecret1 'Microsoft.KeyVault/vaults/secrets@2016-10-01' = {
+ parent: keyVault1
+ name: 'keyVaultSecret1'
+ properties: {
+ value: 'secretValue'
+ attributes: {
+ enabled: true
+ nbf: 1585206000
+ exp: 1679814000
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/secret_without_expiration_date/test/negative2.bicep b/assets/queries/azureResourceManager/secret_without_expiration_date/test/negative2.bicep
new file mode 100644
index 00000000000..7ed87f0e955
--- /dev/null
+++ b/assets/queries/azureResourceManager/secret_without_expiration_date/test/negative2.bicep
@@ -0,0 +1,40 @@
+resource keyVault1 'Microsoft.KeyVault/vaults@2016-10-01' = {
+ name: 'keyVault1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'keyVault1'
+ }
+ properties: {
+ enabledForDeployment: true
+ enabledForTemplateDeployment: true
+ enabledForDiskEncryption: true
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ accessPolicies: [
+ {
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ objectId: 'objectId'
+ permissions: {
+ keys: ['Get']
+ secrets: ['List', 'Get', 'Set']
+ }
+ }
+ ]
+ sku: {
+ name: 'standard'
+ family: 'A'
+ }
+ }
+}
+
+resource keyVault1_keyVaultSecret1 'Microsoft.KeyVault/vaults/secrets@2016-10-01' = {
+ parent: keyVault1
+ name: 'keyVaultSecret1'
+ properties: {
+ value: 'secretValue'
+ attributes: {
+ enabled: true
+ nbf: 1585206000
+ exp: 1679814000
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive1.bicep b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive1.bicep
new file mode 100644
index 00000000000..991b532bdda
--- /dev/null
+++ b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive1.bicep
@@ -0,0 +1,37 @@
+resource keyVault1 'Microsoft.KeyVault/vaults@2016-10-01' = {
+ name: 'keyVault1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'keyVault1'
+ }
+ properties: {
+ enabledForDeployment: true
+ enabledForTemplateDeployment: true
+ enabledForDiskEncryption: true
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ accessPolicies: [
+ {
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ objectId: 'objectId'
+ permissions: {
+ keys: ['Get']
+ secrets: ['List', 'Get', 'Set']
+ }
+ }
+ ]
+ sku: {
+ name: 'standard'
+ family: 'A'
+ }
+ }
+}
+
+resource keyVault1_secretid1 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = {
+ parent: keyVault1
+ name: 'secretid1'
+ tags: {}
+ properties: {
+ value: 'string'
+ contentType: 'string'
+ }
+}
diff --git a/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive2.bicep b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive2.bicep
new file mode 100644
index 00000000000..a6b4f52eef3
--- /dev/null
+++ b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive2.bicep
@@ -0,0 +1,40 @@
+resource keyVault1 'Microsoft.KeyVault/vaults@2016-10-01' = {
+ name: 'keyVault1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'keyVault1'
+ }
+ properties: {
+ enabledForDeployment: true
+ enabledForTemplateDeployment: true
+ enabledForDiskEncryption: true
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ accessPolicies: [
+ {
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ objectId: 'objectId'
+ permissions: {
+ keys: ['Get']
+ secrets: ['List', 'Get', 'Set']
+ }
+ }
+ ]
+ sku: {
+ name: 'standard'
+ family: 'A'
+ }
+ }
+}
+
+resource keyVault1_keyVaultSecret1 'Microsoft.KeyVault/vaults/secrets@2016-10-01' = {
+ parent: keyVault1
+ name: 'keyVaultSecret1'
+ properties: {
+ value: 'string'
+ contentType: 'string'
+ attributes: {
+ enabled: true
+ nbf: 1585206000
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive3.bicep b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive3.bicep
new file mode 100644
index 00000000000..991b532bdda
--- /dev/null
+++ b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive3.bicep
@@ -0,0 +1,37 @@
+resource keyVault1 'Microsoft.KeyVault/vaults@2016-10-01' = {
+ name: 'keyVault1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'keyVault1'
+ }
+ properties: {
+ enabledForDeployment: true
+ enabledForTemplateDeployment: true
+ enabledForDiskEncryption: true
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ accessPolicies: [
+ {
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ objectId: 'objectId'
+ permissions: {
+ keys: ['Get']
+ secrets: ['List', 'Get', 'Set']
+ }
+ }
+ ]
+ sku: {
+ name: 'standard'
+ family: 'A'
+ }
+ }
+}
+
+resource keyVault1_secretid1 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = {
+ parent: keyVault1
+ name: 'secretid1'
+ tags: {}
+ properties: {
+ value: 'string'
+ contentType: 'string'
+ }
+}
diff --git a/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive4.bicep b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive4.bicep
new file mode 100644
index 00000000000..a6b4f52eef3
--- /dev/null
+++ b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive4.bicep
@@ -0,0 +1,40 @@
+resource keyVault1 'Microsoft.KeyVault/vaults@2016-10-01' = {
+ name: 'keyVault1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'keyVault1'
+ }
+ properties: {
+ enabledForDeployment: true
+ enabledForTemplateDeployment: true
+ enabledForDiskEncryption: true
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ accessPolicies: [
+ {
+ tenantId: 'xx0xxx10-00x0-00x0-0x01-x0x0x01xx100'
+ objectId: 'objectId'
+ permissions: {
+ keys: ['Get']
+ secrets: ['List', 'Get', 'Set']
+ }
+ }
+ ]
+ sku: {
+ name: 'standard'
+ family: 'A'
+ }
+ }
+}
+
+resource keyVault1_keyVaultSecret1 'Microsoft.KeyVault/vaults/secrets@2016-10-01' = {
+ parent: keyVault1
+ name: 'keyVaultSecret1'
+ properties: {
+ value: 'string'
+ contentType: 'string'
+ attributes: {
+ enabled: true
+ nbf: 1585206000
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive_expected_result.json b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive_expected_result.json
index cc8fef2be57..07b856517d0 100644
--- a/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/secret_without_expiration_date/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 56,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "Secret Without Expiration Date",
+ "severity": "MEDIUM",
+ "line": 33,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "Secret Without Expiration Date",
+ "severity": "MEDIUM",
+ "line": 35,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "Secret Without Expiration Date",
+ "severity": "MEDIUM",
+ "line": 33,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "Secret Without Expiration Date",
+ "severity": "MEDIUM",
+ "line": 35,
+ "filename": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/negative1.bicep b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/negative1.bicep
new file mode 100644
index 00000000000..8b81169e2e4
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/negative1.bicep
@@ -0,0 +1,38 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2014-04-01' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_securityPolicy1 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'securityPolicy1'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+ dependsOn: [sqlServer1]
+}
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/negative2.bicep b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/negative2.bicep
new file mode 100644
index 00000000000..8b81169e2e4
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/negative2.bicep
@@ -0,0 +1,38 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2014-04-01' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_securityPolicy1 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'securityPolicy1'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+ dependsOn: [sqlServer1]
+}
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive1.bicep b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive1.bicep
new file mode 100644
index 00000000000..639eb07e2b2
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive1.bicep
@@ -0,0 +1,37 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2014-04-01' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_securityPolicy1 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'securityPolicy1'
+ properties: {
+ emailAccountAdmins: true
+ retentionDays: 4
+ state: 'Enabled'
+ }
+ dependsOn: [sqlServer1]
+}
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive2.bicep b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive2.bicep
new file mode 100644
index 00000000000..0b2f05d3408
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive2.bicep
@@ -0,0 +1,38 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2014-04-01' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_securityPolicy1 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'securityPolicy1'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: []
+ retentionDays: 4
+ state: 'Enabled'
+ }
+ dependsOn: [sqlServer1]
+}
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive3.bicep b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive3.bicep
new file mode 100644
index 00000000000..226d8dc314e
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive3.bicep
@@ -0,0 +1,38 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2014-04-01' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_securityPolicy1 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'securityPolicy1'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['', '']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+ dependsOn: [sqlServer1]
+}
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive4.bicep b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive4.bicep
new file mode 100644
index 00000000000..639eb07e2b2
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive4.bicep
@@ -0,0 +1,37 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2014-04-01' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_securityPolicy1 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'securityPolicy1'
+ properties: {
+ emailAccountAdmins: true
+ retentionDays: 4
+ state: 'Enabled'
+ }
+ dependsOn: [sqlServer1]
+}
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive5.bicep b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive5.bicep
new file mode 100644
index 00000000000..0b2f05d3408
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive5.bicep
@@ -0,0 +1,38 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2014-04-01' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_securityPolicy1 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'securityPolicy1'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: []
+ retentionDays: 4
+ state: 'Enabled'
+ }
+ dependsOn: [sqlServer1]
+}
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive6.bicep b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive6.bicep
new file mode 100644
index 00000000000..226d8dc314e
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive6.bicep
@@ -0,0 +1,38 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2014-04-01' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_securityPolicy1 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'securityPolicy1'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['', '']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+ dependsOn: [sqlServer1]
+}
diff --git a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive_expected_result.json b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive_expected_result.json
index 7d363cac535..203f8fff574 100644
--- a/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/sql_alert_policy_without_emails/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "INFO",
"line": 50,
"filename": "positive6.json"
+ },
+ {
+ "queryName": "SQL Alert Policy Without Emails",
+ "severity": "INFO",
+ "line": 31,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "SQL Alert Policy Without Emails",
+ "severity": "INFO",
+ "line": 33,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "SQL Alert Policy Without Emails",
+ "severity": "INFO",
+ "line": 33,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "SQL Alert Policy Without Emails",
+ "severity": "INFO",
+ "line": 31,
+ "filename": "positive4.bicep"
+ },
+ {
+ "queryName": "SQL Alert Policy Without Emails",
+ "severity": "INFO",
+ "line": 33,
+ "filename": "positive5.bicep"
+ },
+ {
+ "queryName": "SQL Alert Policy Without Emails",
+ "severity": "INFO",
+ "line": 33,
+ "filename": "positive6.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative1.bicep b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative1.bicep
new file mode 100644
index 00000000000..9e8401770ae
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative1.bicep
@@ -0,0 +1,7 @@
+resource sample_firewall 'Microsoft.Sql/servers/firewallRules@2021-02-01-preview' = {
+ name: 'sample/firewall'
+ properties: {
+ endIpAddress: '0.0.0.0'
+ startIpAddress: '0.0.0.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative2.bicep b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative2.bicep
new file mode 100644
index 00000000000..3914a3a94f3
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative2.bicep
@@ -0,0 +1,7 @@
+resource sample_firewall 'Microsoft.Sql/servers/firewallRules@2021-02-01-preview' = {
+ name: 'sample/firewall'
+ properties: {
+ endIpAddress: '192.168.1.2'
+ startIpAddress: '192.168.1.254'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative3.bicep b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative3.bicep
new file mode 100644
index 00000000000..9e8401770ae
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative3.bicep
@@ -0,0 +1,7 @@
+resource sample_firewall 'Microsoft.Sql/servers/firewallRules@2021-02-01-preview' = {
+ name: 'sample/firewall'
+ properties: {
+ endIpAddress: '0.0.0.0'
+ startIpAddress: '0.0.0.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative4.bicep b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative4.bicep
new file mode 100644
index 00000000000..3914a3a94f3
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/negative4.bicep
@@ -0,0 +1,7 @@
+resource sample_firewall 'Microsoft.Sql/servers/firewallRules@2021-02-01-preview' = {
+ name: 'sample/firewall'
+ properties: {
+ endIpAddress: '192.168.1.2'
+ startIpAddress: '192.168.1.254'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive1.bicep b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive1.bicep
new file mode 100644
index 00000000000..d8432478f39
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive1.bicep
@@ -0,0 +1,21 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_AllowAllWindowsAzureIps 'Microsoft.Sql/servers/firewallRules@2021-02-01-preview' = {
+ parent: sqlServer1
+ location: resourceGroup().location
+ name: 'AllowAllWindowsAzureIps'
+ properties: {
+ endIpAddress: '255.255.255.255'
+ startIpAddress: '0.0.0.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive2.bicep b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive2.bicep
new file mode 100644
index 00000000000..2f8fe41d8c3
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive2.bicep
@@ -0,0 +1,7 @@
+resource sample_firewall 'Microsoft.Sql/servers/firewallRules@2021-02-01-preview' = {
+ name: 'sample/firewall'
+ properties: {
+ endIpAddress: '255.255.255.255'
+ startIpAddress: '0.0.0.0/0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive3.bicep b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive3.bicep
new file mode 100644
index 00000000000..d8432478f39
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive3.bicep
@@ -0,0 +1,21 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_AllowAllWindowsAzureIps 'Microsoft.Sql/servers/firewallRules@2021-02-01-preview' = {
+ parent: sqlServer1
+ location: resourceGroup().location
+ name: 'AllowAllWindowsAzureIps'
+ properties: {
+ endIpAddress: '255.255.255.255'
+ startIpAddress: '0.0.0.0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive4.bicep b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive4.bicep
new file mode 100644
index 00000000000..2f8fe41d8c3
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive4.bicep
@@ -0,0 +1,7 @@
+resource sample_firewall 'Microsoft.Sql/servers/firewallRules@2021-02-01-preview' = {
+ name: 'sample/firewall'
+ properties: {
+ endIpAddress: '255.255.255.255'
+ startIpAddress: '0.0.0.0/0'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive_expected_result.json b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive_expected_result.json
index b6fe1a7f551..0b8fdaabb48 100644
--- a/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/sql_database_server_firewall_allows_all_ips/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "CRITICAL",
"line": 16,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "SQL Database Server Firewall Allows All IPS",
+ "severity": "CRITICAL",
+ "line": 18,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "SQL Database Server Firewall Allows All IPS",
+ "severity": "CRITICAL",
+ "line": 4,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "SQL Database Server Firewall Allows All IPS",
+ "severity": "CRITICAL",
+ "line": 18,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "SQL Database Server Firewall Allows All IPS",
+ "severity": "CRITICAL",
+ "line": 4,
+ "filename": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..9aa532a81ef
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative1.bicep
@@ -0,0 +1,10 @@
+resource sample_databases_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/databases/default'
+ properties: {
+ disabledAlerts: []
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..0aad626f49d
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative2.bicep
@@ -0,0 +1,9 @@
+resource sample_databases_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/databases/default'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative3.bicep b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative3.bicep
new file mode 100644
index 00000000000..c7db07ef044
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative3.bicep
@@ -0,0 +1,9 @@
+resource sample_databases_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/databases/default'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Disabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative4.bicep b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative4.bicep
new file mode 100644
index 00000000000..9aa532a81ef
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative4.bicep
@@ -0,0 +1,10 @@
+resource sample_databases_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/databases/default'
+ properties: {
+ disabledAlerts: []
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative5.bicep b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative5.bicep
new file mode 100644
index 00000000000..0aad626f49d
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative5.bicep
@@ -0,0 +1,9 @@
+resource sample_databases_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/databases/default'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative6.bicep b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative6.bicep
new file mode 100644
index 00000000000..c7db07ef044
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/negative6.bicep
@@ -0,0 +1,9 @@
+resource sample_databases_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/databases/default'
+ properties: {
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Disabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..0e0d36691ad
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive1.bicep
@@ -0,0 +1,10 @@
+resource sample_databases_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/databases/default'
+ properties: {
+ disabledAlerts: ['Sql_Injection']
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..0e0d36691ad
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive2.bicep
@@ -0,0 +1,10 @@
+resource sample_databases_default 'Microsoft.Sql/servers/databases/securityAlertPolicies@2021-02-01-preview' = {
+ name: 'sample/databases/default'
+ properties: {
+ disabledAlerts: ['Sql_Injection']
+ emailAccountAdmins: true
+ emailAddresses: ['sample@email.com']
+ retentionDays: 4
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive_expected_result.json
index 49d4e56fd3d..6c4cf599b71 100644
--- a/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/sql_server_database_with_alerts_disabled/test/positive_expected_result.json
@@ -10,5 +10,17 @@
"severity": "MEDIUM",
"line": 16,
"filename": "positive2.json"
+ },
+ {
+ "queryName": "SQL Server Database With Alerts Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "SQL Server Database With Alerts Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "filename": "positive2.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/negative1.bicep b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/negative1.bicep
new file mode 100644
index 00000000000..1505a122c36
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/negative1.bicep
@@ -0,0 +1,40 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 100
+ state: 'Enabled'
+ dependsOn: [sqlServer1_sqlDatabase1.id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/negative2.bicep b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/negative2.bicep
new file mode 100644
index 00000000000..1505a122c36
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/negative2.bicep
@@ -0,0 +1,40 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 100
+ state: 'Enabled'
+ dependsOn: [sqlServer1_sqlDatabase1.id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive1.bicep b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive1.bicep
new file mode 100644
index 00000000000..4ce07f7f4d7
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive1.bicep
@@ -0,0 +1,40 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 50
+ state: 'Enabled'
+ dependsOn: [sqlServer1_sqlDatabase1.id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive2.bicep b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive2.bicep
new file mode 100644
index 00000000000..49fb1b44521
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive2.bicep
@@ -0,0 +1,39 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ state: 'Enabled'
+ dependsOn: [sqlServer1_sqlDatabase1.id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive3.bicep b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive3.bicep
new file mode 100644
index 00000000000..4ce07f7f4d7
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive3.bicep
@@ -0,0 +1,40 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 50
+ state: 'Enabled'
+ dependsOn: [sqlServer1_sqlDatabase1.id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive4.bicep b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive4.bicep
new file mode 100644
index 00000000000..49fb1b44521
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive4.bicep
@@ -0,0 +1,39 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ state: 'Enabled'
+ dependsOn: [sqlServer1_sqlDatabase1.id]
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive_expected_result.json b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive_expected_result.json
index 7b48bb96d7a..7a9d92c7b2f 100644
--- a/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/sql_server_database_with_low_retention_days/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "LOW",
"line": 45,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "SQL Server Database With Unrecommended Retention Days",
+ "severity": "LOW",
+ "line": 36,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "SQL Server Database With Unrecommended Retention Days",
+ "severity": "LOW",
+ "line": 31,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "SQL Server Database With Unrecommended Retention Days",
+ "severity": "LOW",
+ "line": 36,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "SQL Server Database With Unrecommended Retention Days",
+ "severity": "LOW",
+ "line": 31,
+ "filename": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative1.bicep b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative1.bicep
new file mode 100644
index 00000000000..29ce4a74896
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative1.bicep
@@ -0,0 +1,39 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_ssqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'ssqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: 107374182
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_ssqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_ssqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 100
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative2.bicep b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative2.bicep
new file mode 100644
index 00000000000..7b56756b386
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative2.bicep
@@ -0,0 +1,39 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: 1073741824
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 100
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative3.bicep b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative3.bicep
new file mode 100644
index 00000000000..29ce4a74896
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative3.bicep
@@ -0,0 +1,39 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_ssqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'ssqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: 107374182
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_ssqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_ssqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 100
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative4.bicep b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative4.bicep
new file mode 100644
index 00000000000..7b56756b386
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/negative4.bicep
@@ -0,0 +1,39 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: 1073741824
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 100
+ state: 'Enabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive1.bicep b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive1.bicep
new file mode 100644
index 00000000000..8eac6379d2c
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive1.bicep
@@ -0,0 +1,26 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive2.bicep b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive2.bicep
new file mode 100644
index 00000000000..4894e9921fe
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive2.bicep
@@ -0,0 +1,39 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: 1073741824
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 100
+ state: 'Disabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive3.bicep b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive3.bicep
new file mode 100644
index 00000000000..8eac6379d2c
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive3.bicep
@@ -0,0 +1,26 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: '1073741824'
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive4.bicep b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive4.bicep
new file mode 100644
index 00000000000..4894e9921fe
--- /dev/null
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive4.bicep
@@ -0,0 +1,39 @@
+resource sqlServer1 'Microsoft.Sql/servers@2021-02-01-preview' = {
+ name: 'sqlServer1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlServer1'
+ }
+ properties: {
+ administratorLogin: 'adminUsername'
+ administratorLoginPassword: 'adminPassword'
+ }
+}
+
+resource sqlServer1_sqlDatabase1 'Microsoft.Sql/servers/databases@2021-02-01-preview' = {
+ parent: sqlServer1
+ name: 'sqlDatabase1'
+ location: resourceGroup().location
+ tags: {
+ displayName: 'sqlDatabase1'
+ }
+ properties: {
+ collation: 'SQL_Latin1_General_CP1_CI_AS'
+ edition: 'Basic'
+ maxSizeBytes: 1073741824
+ requestedServiceObjectiveName: 'Basic'
+ }
+}
+
+resource sqlServer1_sqlDatabase1_default 'Microsoft.Sql/servers/databases/auditingSettings@2021-02-01-preview' = {
+ parent: sqlServer1_sqlDatabase1
+ name: 'default'
+ properties: {
+ auditActionsAndGroups: ['DATABASE_LOGOUT_GROUP']
+ isAzureMonitorTargetEnabled: true
+ isStorageSecondaryKeyInUse: true
+ queueDelayMs: 1000
+ retentionDays: 100
+ state: 'Disabled'
+ }
+}
diff --git a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive_expected_result.json b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive_expected_result.json
index ddf5fc11edf..031eb5f9e4d 100644
--- a/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/sql_server_database_without_auditing/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 24,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "SQL Server Database Without Auditing",
+ "severity": "MEDIUM",
+ "line": 15,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "SQL Server Database Without Auditing",
+ "severity": "MEDIUM",
+ "line": 15,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "SQL Server Database Without Auditing",
+ "severity": "MEDIUM",
+ "line": 15,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "SQL Server Database Without Auditing",
+ "severity": "MEDIUM",
+ "line": 15,
+ "filename": "positive4.bicep"
}
-]
+]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/standard_price_not_selected/test/negative1.bicep b/assets/queries/azureResourceManager/standard_price_not_selected/test/negative1.bicep
new file mode 100644
index 00000000000..9c25285d67b
--- /dev/null
+++ b/assets/queries/azureResourceManager/standard_price_not_selected/test/negative1.bicep
@@ -0,0 +1,20 @@
+resource webApp1 'Microsoft.Web/sites@2018-11-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')
+ }
+ dependsOn: [resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]
+}
+
+resource Princing 'Microsoft.Security/pricings@2017-08-01-preview' = {
+ name: 'Princing'
+ properties: {
+ pricingTier: 'Standard'
+ }
+}
diff --git a/assets/queries/azureResourceManager/standard_price_not_selected/test/negative2.bicep b/assets/queries/azureResourceManager/standard_price_not_selected/test/negative2.bicep
new file mode 100644
index 00000000000..9c25285d67b
--- /dev/null
+++ b/assets/queries/azureResourceManager/standard_price_not_selected/test/negative2.bicep
@@ -0,0 +1,20 @@
+resource webApp1 'Microsoft.Web/sites@2018-11-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')
+ }
+ dependsOn: [resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]
+}
+
+resource Princing 'Microsoft.Security/pricings@2017-08-01-preview' = {
+ name: 'Princing'
+ properties: {
+ pricingTier: 'Standard'
+ }
+}
diff --git a/assets/queries/azureResourceManager/standard_price_not_selected/test/negative3.bicep b/assets/queries/azureResourceManager/standard_price_not_selected/test/negative3.bicep
new file mode 100644
index 00000000000..93217fda79e
--- /dev/null
+++ b/assets/queries/azureResourceManager/standard_price_not_selected/test/negative3.bicep
@@ -0,0 +1,197 @@
+@description(
+ 'Name of the central Log Analytics workspace that stores security event and data collected by Azure Security Center'
+)
+@allowed(['az-security-workspace'])
+param workspaceName string = 'az-security-workspace'
+
+@description(
+ 'Name of the resource group where the central log analytics workspace belongs to'
+)
+@allowed(['azsec-security-rg'])
+param workspaceRgName string = 'azsec-security-rg'
+
+@description('Specify whether Auto Provisoning is turned on or off')
+@allowed(['On', 'Off'])
+param autoProvisionSetting string = 'On'
+
+@description(
+ 'Email of the administrator who should be notified about Azure Security Center alert'
+)
+param ascOwnerEmail string
+
+@description(
+ 'Phone number of the administrator should be notified about Azure Security Center alert'
+)
+param ascOwnerContact string
+
+@description(
+ 'Specify whether you want to notify high severity alert to ASC administrator'
+)
+@allowed(['On', 'Off'])
+param highSeverityAlertNotification string = 'On'
+
+@description(
+ 'Specifiy whether you want to notify high severity alert to subscription owner'
+)
+@allowed(['On', 'Off'])
+param subscriptionOwnerNotification string = 'On'
+
+@description(
+ 'Specifiy whether you want to enable Standard tier for Virtual Machine resource type'
+)
+@allowed(['Standard', 'Free'])
+param virtualMachineTier string = 'Standard'
+
+@description(
+ 'Specify whether you want to enable Standard tier for Azure App Service resource type'
+)
+@allowed(['Standard', 'Free'])
+param appServiceTier string = 'Standard'
+
+@description(
+ 'Specify whether you want to enable Standard tier for PaaS SQL Service resource type'
+)
+@allowed(['Standard', 'Free'])
+param paasSQLServiceTier string = 'Standard'
+
+@description(
+ 'Specify whether you want to enable Standard tier for SQL Server on VM resource type'
+)
+@allowed(['Standard', 'Free'])
+param sqlServerOnVmTier string = 'Standard'
+
+@description(
+ 'Specify whether you want to enable Standard tier for Storage Account resource type'
+)
+@allowed(['Standard', 'Free'])
+param storageAccountTier string = 'Standard'
+
+@description(
+ 'Specify whether you want to enable Standard tier for Kubernetes service resource type'
+)
+@allowed(['Standard', 'Free'])
+param kubernetesServiceTier string = 'Standard'
+
+@description(
+ 'Specify whether you want to enable Standard tier for Container Registry resource type'
+)
+@allowed(['Standard', 'Free'])
+param containerRegistryTier string = 'Standard'
+
+@description(
+ 'Specify whether you want to enable Standard tier for Key Vault resource type'
+)
+@allowed(['Standard', 'Free'])
+param keyvaultTier string = 'Standard'
+
+@description(
+ 'Select integration name to enable. Only MCAS or MDATP is supported.'
+)
+@allowed(['MCAS', 'MDATP'])
+param integrationName string
+
+@description('Specify whether you want to enable or not.')
+@allowed([true, false])
+param integrationEnabled bool
+
+resource default 'Microsoft.Security/workspaceSettings@2017-08-01-preview' = {
+ name: 'default'
+ properties: {
+ scope: subscription().id
+ workspaceId: '${subscription().id}/resourceGroups/${workspaceRgName}/providers/Microsoft.OperationalInsights/workspaces/${workspaceName}'
+ }
+}
+
+resource Microsoft_Security_autoProvisioningSettings_default 'Microsoft.Security/autoProvisioningSettings@2017-08-01-preview' = {
+ name: 'default'
+ properties: {
+ autoProvision: autoProvisionSetting
+ }
+}
+
+resource default1 'Microsoft.Security/securityContacts@2017-08-01-preview' = {
+ name: 'default1'
+ properties: {
+ emails: ascOwnerEmail
+ phone: ascOwnerContact
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: highSeverityAlertNotification
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: subscriptionOwnerNotification
+ }
+ }
+}
+
+resource VirtualMachines 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'VirtualMachines'
+ properties: {
+ pricingTier: virtualMachineTier
+ }
+}
+
+resource AppServices 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'AppServices'
+ properties: {
+ pricingTier: appServiceTier
+ }
+ dependsOn: [VirtualMachines]
+}
+
+resource SqlServers 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'SqlServers'
+ properties: {
+ pricingTier: paasSQLServiceTier
+ }
+ dependsOn: [AppServices]
+}
+
+resource SqlServerVirtualMachines 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'SqlServerVirtualMachines'
+ properties: {
+ pricingTier: sqlServerOnVmTier
+ }
+ dependsOn: [SqlServers]
+}
+
+resource StorageAccounts 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'StorageAccounts'
+ properties: {
+ pricingTier: storageAccountTier
+ }
+ dependsOn: [SqlServerVirtualMachines]
+}
+
+resource KubernetesService 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'KubernetesService'
+ properties: {
+ pricingTier: kubernetesServiceTier
+ }
+ dependsOn: [StorageAccounts]
+}
+
+resource ContainerRegistry 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'ContainerRegistry'
+ properties: {
+ pricingTier: containerRegistryTier
+ }
+ dependsOn: [KubernetesService]
+}
+
+resource KeyVaults 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'KeyVaults'
+ properties: {
+ pricingTier: keyvaultTier
+ }
+ dependsOn: [ContainerRegistry]
+}
+
+resource integration 'Microsoft.Security/settings@2019-01-01' = {
+ name: integrationName
+ kind: 'DataExportSettings'
+ properties: {
+ enabled: integrationEnabled
+ }
+}
diff --git a/assets/queries/azureResourceManager/standard_price_not_selected/test/positive1.bicep b/assets/queries/azureResourceManager/standard_price_not_selected/test/positive1.bicep
new file mode 100644
index 00000000000..85ca3401022
--- /dev/null
+++ b/assets/queries/azureResourceManager/standard_price_not_selected/test/positive1.bicep
@@ -0,0 +1,20 @@
+resource webApp1 'Microsoft.Web/sites@2018-11-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')
+ }
+ dependsOn: [resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]
+}
+
+resource Princing 'Microsoft.Security/pricings@2017-08-01-preview' = {
+ name: 'Princing'
+ properties: {
+ pricingTier: 'Free'
+ }
+}
diff --git a/assets/queries/azureResourceManager/standard_price_not_selected/test/positive2.bicep b/assets/queries/azureResourceManager/standard_price_not_selected/test/positive2.bicep
new file mode 100644
index 00000000000..85ca3401022
--- /dev/null
+++ b/assets/queries/azureResourceManager/standard_price_not_selected/test/positive2.bicep
@@ -0,0 +1,20 @@
+resource webApp1 'Microsoft.Web/sites@2018-11-01' = {
+ name: 'webApp1'
+ location: resourceGroup().location
+ tags: {
+ 'hidden-related:${resourceGroup().id}/providers/Microsoft.Web/serverfarms/appServicePlan1': 'Resource'
+ displayName: 'webApp1'
+ }
+ properties: {
+ name: 'webApp1'
+ serverFarmId: resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')
+ }
+ dependsOn: [resourceId('Microsoft.Web/serverfarms', 'appServicePlan1')]
+}
+
+resource Princing 'Microsoft.Security/pricings@2017-08-01-preview' = {
+ name: 'Princing'
+ properties: {
+ pricingTier: 'Free'
+ }
+}
diff --git a/assets/queries/azureResourceManager/standard_price_not_selected/test/positive3.bicep b/assets/queries/azureResourceManager/standard_price_not_selected/test/positive3.bicep
new file mode 100644
index 00000000000..07a43aa798a
--- /dev/null
+++ b/assets/queries/azureResourceManager/standard_price_not_selected/test/positive3.bicep
@@ -0,0 +1,12 @@
+@description(
+ 'Specifiy whether you want to enable Standard tier for Virtual Machine resource type'
+)
+@allowed(['Standard', 'Free'])
+param virtualMachineTier string = 'Free'
+
+resource VirtualMachines 'Microsoft.Security/pricings@2018-06-01' = {
+ name: 'VirtualMachines'
+ properties: {
+ pricingTier: virtualMachineTier
+ }
+}
diff --git a/assets/queries/azureResourceManager/standard_price_not_selected/test/positive_expected_result.json b/assets/queries/azureResourceManager/standard_price_not_selected/test/positive_expected_result.json
index 1bdd4945792..d934e5404b5 100644
--- a/assets/queries/azureResourceManager/standard_price_not_selected/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/standard_price_not_selected/test/positive_expected_result.json
@@ -16,5 +16,23 @@
"severity": "LOW",
"line": 23,
"filename": "positive3.json"
+ },
+ {
+ "queryName": "Standard Price Is Not Selected",
+ "severity": "LOW",
+ "line": 18,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "Standard Price Is Not Selected",
+ "severity": "LOW",
+ "line": 18,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "Standard Price Is Not Selected",
+ "severity": "LOW",
+ "line": 10,
+ "filename": "positive3.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/negative1.bicep b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/negative1.bicep
new file mode 100644
index 00000000000..fb6c6db603c
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/negative1.bicep
@@ -0,0 +1,17 @@
+resource storageaccount1Negative1 'Microsoft.Storage/storageAccounts@2021-02-01' = {
+ name: 'storageaccount1Negative1'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {
+ networkAcls: {
+ defaultAction: 'Deny'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/negative2.bicep b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/negative2.bicep
new file mode 100644
index 00000000000..fb6c6db603c
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/negative2.bicep
@@ -0,0 +1,17 @@
+resource storageaccount1Negative1 'Microsoft.Storage/storageAccounts@2021-02-01' = {
+ name: 'storageaccount1Negative1'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {
+ networkAcls: {
+ defaultAction: 'Deny'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive1.bicep b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive1.bicep
new file mode 100644
index 00000000000..24ddf1f0e63
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive1.bicep
@@ -0,0 +1,24 @@
+@description('Storage Account type')
+@allowed(['Standard_LRS', 'Standard_GRS', 'Standard_ZRS', 'Premium_LRS'])
+param storageAccountType string = 'Standard_LRS'
+
+@description('Location for all resources.')
+param location string = resourceGroup().location
+
+var storageAccountName = 'store${uniqueString(resourceGroup().id)}'
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: storageAccountName
+ location: location
+ sku: {
+ name: storageAccountType
+ }
+ kind: 'StorageV2'
+ properties: {
+ networkAcls: {
+ defaultAction: 'Allow'
+ }
+ }
+}
+
+output storageAccountName string = storageAccountName
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive2.bicep b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive2.bicep
new file mode 100644
index 00000000000..f92a0b1ed70
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive2.bicep
@@ -0,0 +1,13 @@
+resource storageaccount1Positive2 'Microsoft.Storage/storageAccounts@2017-10-01' = {
+ name: 'storageaccount1Positive2'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive3.bicep b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive3.bicep
new file mode 100644
index 00000000000..e096df7e842
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive3.bicep
@@ -0,0 +1,13 @@
+resource storageaccount1Positive3 'Microsoft.Storage/storageAccounts@2016-12-01' = {
+ name: 'storageaccount1Positive3'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'Storage'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive4.bicep b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive4.bicep
new file mode 100644
index 00000000000..24ddf1f0e63
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive4.bicep
@@ -0,0 +1,24 @@
+@description('Storage Account type')
+@allowed(['Standard_LRS', 'Standard_GRS', 'Standard_ZRS', 'Premium_LRS'])
+param storageAccountType string = 'Standard_LRS'
+
+@description('Location for all resources.')
+param location string = resourceGroup().location
+
+var storageAccountName = 'store${uniqueString(resourceGroup().id)}'
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: storageAccountName
+ location: location
+ sku: {
+ name: storageAccountType
+ }
+ kind: 'StorageV2'
+ properties: {
+ networkAcls: {
+ defaultAction: 'Allow'
+ }
+ }
+}
+
+output storageAccountName string = storageAccountName
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive5.bicep b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive5.bicep
new file mode 100644
index 00000000000..f92a0b1ed70
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive5.bicep
@@ -0,0 +1,13 @@
+resource storageaccount1Positive2 'Microsoft.Storage/storageAccounts@2017-10-01' = {
+ name: 'storageaccount1Positive2'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive6.bicep b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive6.bicep
new file mode 100644
index 00000000000..e096df7e842
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive6.bicep
@@ -0,0 +1,13 @@
+resource storageaccount1Positive3 'Microsoft.Storage/storageAccounts@2016-12-01' = {
+ name: 'storageaccount1Positive3'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'Storage'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive_expected_result.json b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive_expected_result.json
index 4287a0eb99d..efe274a3d47 100644
--- a/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/storage_account_allows_network_default_access/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "LOW",
"line": 10,
"fileName": "positive6.json"
+ },
+ {
+ "queryName": "Storage Account Allows Default Network Access",
+ "severity": "LOW",
+ "line": 19,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Default Network Access",
+ "severity": "LOW",
+ "line": 12,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Default Network Access",
+ "severity": "LOW",
+ "line": 1,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Default Network Access",
+ "severity": "LOW",
+ "line": 19,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Default Network Access",
+ "severity": "LOW",
+ "line": 12,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Default Network Access",
+ "severity": "LOW",
+ "line": 1,
+ "fileName": "positive6.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative1.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative1.bicep
new file mode 100644
index 00000000000..55c4c961ae6
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative1.bicep
@@ -0,0 +1,15 @@
+resource storageaccount1Negative1 'Microsoft.Storage/storageAccounts@2021-02-01' = {
+ name: 'storageaccount1Negative1'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {
+ supportsHttpsTrafficOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative2.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative2.bicep
new file mode 100644
index 00000000000..26b3b54190d
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative2.bicep
@@ -0,0 +1,13 @@
+resource storageaccount1Positive3 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storageaccount1Positive3'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative3.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative3.bicep
new file mode 100644
index 00000000000..55c4c961ae6
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative3.bicep
@@ -0,0 +1,15 @@
+resource storageaccount1Negative1 'Microsoft.Storage/storageAccounts@2021-02-01' = {
+ name: 'storageaccount1Negative1'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {
+ supportsHttpsTrafficOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative4.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative4.bicep
new file mode 100644
index 00000000000..26b3b54190d
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/negative4.bicep
@@ -0,0 +1,13 @@
+resource storageaccount1Positive3 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storageaccount1Positive3'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive1.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive1.bicep
new file mode 100644
index 00000000000..db070e8b163
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive1.bicep
@@ -0,0 +1,15 @@
+resource storageaccount1 'Microsoft.Storage/storageAccounts@2021-02-01' = {
+ name: 'storageaccount1'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {
+ supportsHttpsTrafficOnly: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive2.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive2.bicep
new file mode 100644
index 00000000000..03652431ed9
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive2.bicep
@@ -0,0 +1,12 @@
+resource storageaccount1Positive2 'Microsoft.Storage/storageAccounts@2017-10-01' = {
+ name: 'storageaccount1Positive2'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive3.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive3.bicep
new file mode 100644
index 00000000000..523176375c9
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive3.bicep
@@ -0,0 +1,13 @@
+resource storageaccount1Positive3 'Microsoft.Storage/storageAccounts@2018-02-01' = {
+ name: 'storageaccount1Positive3'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive4.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive4.bicep
new file mode 100644
index 00000000000..db070e8b163
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive4.bicep
@@ -0,0 +1,15 @@
+resource storageaccount1 'Microsoft.Storage/storageAccounts@2021-02-01' = {
+ name: 'storageaccount1'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {
+ supportsHttpsTrafficOnly: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive5.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive5.bicep
new file mode 100644
index 00000000000..03652431ed9
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive5.bicep
@@ -0,0 +1,12 @@
+resource storageaccount1Positive2 'Microsoft.Storage/storageAccounts@2017-10-01' = {
+ name: 'storageaccount1Positive2'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive6.bicep b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive6.bicep
new file mode 100644
index 00000000000..523176375c9
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive6.bicep
@@ -0,0 +1,13 @@
+resource storageaccount1Positive3 'Microsoft.Storage/storageAccounts@2018-02-01' = {
+ name: 'storageaccount1Positive3'
+ tags: {
+ displayName: 'storageaccount1'
+ }
+ location: resourceGroup().location
+ kind: 'StorageV2'
+ sku: {
+ name: 'Premium_LRS'
+ tier: 'Premium'
+ }
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive_expected_result.json b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive_expected_result.json
index b610df4a795..a7fe7354ff6 100644
--- a/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/storage_account_allows_unsecure_transfer/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "MEDIUM",
"line": 20,
"fileName": "positive6.json"
+ },
+ {
+ "queryName": "Storage Account Allows Unsecure Transfer",
+ "severity": "MEDIUM",
+ "line": 13,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Unsecure Transfer",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Unsecure Transfer",
+ "severity": "MEDIUM",
+ "line": 12,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Unsecure Transfer",
+ "severity": "MEDIUM",
+ "line": 13,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Unsecure Transfer",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Storage Account Allows Unsecure Transfer",
+ "severity": "MEDIUM",
+ "line": 12,
+ "fileName": "positive6.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative1.bicep b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative1.bicep
new file mode 100644
index 00000000000..a2a80c135c5
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative1.bicep
@@ -0,0 +1,8 @@
+resource blob_container_example 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-02-01' = {
+ name: 'blob/container/example'
+ properties: {
+ denyEncryptionScopeOverride: true
+ publicAccess: 'None'
+ metadata: {}
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative2.bicep b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative2.bicep
new file mode 100644
index 00000000000..4a0b6c5e1ab
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative2.bicep
@@ -0,0 +1,90 @@
+@description('Name of the virtual network to use for cloud shell containers.')
+param existingVNETName string
+
+@description('Name of the subnet to use for storage account.')
+param existingStorageSubnetName string
+
+@description('Name of the subnet to use for cloud shell containers.')
+param existingContainerSubnetName string
+
+@description('Name of the storage account in subnet.')
+param storageAccountName string
+
+@description('Location for all resources.')
+param location string = resourceGroup().location
+
+var containerSubnetRef = resourceId(
+ 'Microsoft.Network/virtualNetworks/subnets',
+ existingVNETName,
+ existingContainerSubnetName
+)
+var storageSubnetRef = resourceId(
+ 'Microsoft.Network/virtualNetworks/subnets',
+ existingVNETName,
+ existingStorageSubnetName
+)
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: storageAccountName
+ location: location
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ networkAcls: {
+ bypass: 'None'
+ virtualNetworkRules: [
+ {
+ id: containerSubnetRef
+ action: 'Allow'
+ }
+ {
+ id: storageSubnetRef
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Deny'
+ }
+ supportsHttpsTrafficOnly: true
+ encryption: {
+ services: {
+ file: {
+ keyType: 'Account'
+ enabled: true
+ }
+ blob: {
+ keyType: 'Account'
+ enabled: true
+ }
+ }
+ keySource: 'Microsoft.Storage'
+ }
+ accessTier: 'Cool'
+ }
+}
+
+resource storageAccountName_default 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01' = {
+ parent: storageAccount
+ name: 'default'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ properties: {
+ deleteRetentionPolicy: {
+ enabled: false
+ }
+ }
+}
+
+resource storageAccountName_default_container 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = {
+ parent: storageAccountName_default
+ name: 'container'
+ properties: {
+ denyEncryptionScopeOverride: true
+ publicAccess: 'None'
+ metadata: {}
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative3.bicep b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative3.bicep
new file mode 100644
index 00000000000..31cecd636e7
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/negative3.bicep
@@ -0,0 +1,33 @@
+@description('Specifies the name of the Azure Storage account.')
+param storageAccountName string
+
+@description('Specifies the name of the blob container.')
+param containerName string = 'logs'
+
+@description(
+ 'Specifies the location in which the Azure Storage resources should be deployed.'
+)
+param location string = resourceGroup().location
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: storageAccountName
+ location: location
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ }
+}
+
+resource storageAccountName_default_container 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = {
+ name: '${storageAccountName}/default/${containerName}'
+ properties: {
+ denyEncryptionScopeOverride: true
+ publicAccess: 'None'
+ metadata: {}
+ }
+ dependsOn: [storageAccount]
+}
diff --git a/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive1.bicep b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive1.bicep
new file mode 100644
index 00000000000..74647217fe5
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive1.bicep
@@ -0,0 +1,8 @@
+resource blob_container_example 'Microsoft.Storage/storageAccounts/blobServices/containers@2021-02-01' = {
+ name: 'blob/container/example'
+ properties: {
+ denyEncryptionScopeOverride: true
+ publicAccess: 'Container'
+ metadata: {}
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive2.bicep b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive2.bicep
new file mode 100644
index 00000000000..ed32c989d85
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive2.bicep
@@ -0,0 +1,90 @@
+@description('Name of the virtual network to use for cloud shell containers.')
+param existingVNETName string
+
+@description('Name of the subnet to use for storage account.')
+param existingStorageSubnetName string
+
+@description('Name of the subnet to use for cloud shell containers.')
+param existingContainerSubnetName string
+
+@description('Name of the storage account in subnet.')
+param storageAccountName string
+
+@description('Location for all resources.')
+param location string = resourceGroup().location
+
+var containerSubnetRef = resourceId(
+ 'Microsoft.Network/virtualNetworks/subnets',
+ existingVNETName,
+ existingContainerSubnetName
+)
+var storageSubnetRef = resourceId(
+ 'Microsoft.Network/virtualNetworks/subnets',
+ existingVNETName,
+ existingStorageSubnetName
+)
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: storageAccountName
+ location: location
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ networkAcls: {
+ bypass: 'None'
+ virtualNetworkRules: [
+ {
+ id: containerSubnetRef
+ action: 'Allow'
+ }
+ {
+ id: storageSubnetRef
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Deny'
+ }
+ supportsHttpsTrafficOnly: true
+ encryption: {
+ services: {
+ file: {
+ keyType: 'Account'
+ enabled: true
+ }
+ blob: {
+ keyType: 'Account'
+ enabled: true
+ }
+ }
+ keySource: 'Microsoft.Storage'
+ }
+ accessTier: 'Cool'
+ }
+}
+
+resource storageAccountName_default 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01' = {
+ parent: storageAccount
+ name: 'default'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ properties: {
+ deleteRetentionPolicy: {
+ enabled: false
+ }
+ }
+}
+
+resource storageAccountName_default_container 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = {
+ parent: storageAccountName_default
+ name: 'container'
+ properties: {
+ denyEncryptionScopeOverride: true
+ publicAccess: 'Blob'
+ metadata: {}
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive3.bicep b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive3.bicep
new file mode 100644
index 00000000000..eb6327f22b7
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive3.bicep
@@ -0,0 +1,33 @@
+@description('Specifies the name of the Azure Storage account.')
+param storageAccountName string
+
+@description('Specifies the name of the blob container.')
+param containerName string = 'logs'
+
+@description(
+ 'Specifies the location in which the Azure Storage resources should be deployed.'
+)
+param location string = resourceGroup().location
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: storageAccountName
+ location: location
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ }
+}
+
+resource storageAccountName_default_container 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = {
+ name: '${storageAccountName}/default/${containerName}'
+ properties: {
+ denyEncryptionScopeOverride: true
+ publicAccess: 'Blob'
+ metadata: {}
+ }
+ dependsOn: [storageAccount]
+}
diff --git a/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive_expected_result.json b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive_expected_result.json
index 5b6961233e3..8958f4d9404 100644
--- a/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/storage_blob_service_container_with_public_access/test/positive_expected_result.json
@@ -40,5 +40,23 @@
"severity": "HIGH",
"line": 96,
"fileName": "positive7.json"
+ },
+ {
+ "queryName": "Storage Blob Service Container With Public Access",
+ "severity": "HIGH",
+ "line": 5,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Storage Blob Service Container With Public Access",
+ "severity": "HIGH",
+ "line": 87,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Storage Blob Service Container With Public Access",
+ "severity": "HIGH",
+ "line": 29,
+ "fileName": "positive3.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..67d7f58e39c
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/negative1.bicep
@@ -0,0 +1,19 @@
+resource default_Microsoft_Insights 'Microsoft.Storage/storageAccounts/queueServices/providers/diagnosticsettings@2017-05-01-preview' = {
+ name: 'Microsoft.Storage/storageAccounts/queueServices/providers'
+ properties: {
+ logs: [
+ {
+ category: 'StorageRead'
+ enabled: true
+ }
+ {
+ category: 'StorageWrite'
+ enabled: true
+ }
+ {
+ category: 'StorageDelete'
+ enabled: true
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..881432f2508
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive1.bicep
@@ -0,0 +1,19 @@
+resource default_Microsoft_Insights 'Microsoft.Storage/storageAccounts/queueServices/providers/diagnosticsettings@2017-05-01-preview' = {
+ name: 'Microsoft.Storage/storageAccounts/queueServices/providers'
+ properties: {
+ logs: [
+ {
+ category: 'StorageRead'
+ enabled: false
+ }
+ {
+ category: 'StorageWrite'
+ enabled: false
+ }
+ {
+ category: 'StorageDelete'
+ enabled: false
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..9abd315009a
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive2.bicep
@@ -0,0 +1,6 @@
+resource default_Microsoft_Insights 'Microsoft.Storage/storageAccounts/queueServices/providers/diagnosticsettings@2017-05-01-preview' = {
+ name: 'Microsoft.Storage/storageAccounts/queueServices/providers'
+ properties:{
+ logs:[]
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..7ee37f5a4ef
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive3.bicep
@@ -0,0 +1,19 @@
+resource default_Microsoft_Insights 'Microsoft.Storage/storageAccounts/queueServices/providers/diagnosticsettings@2017-05-01-preview' = {
+ name: 'Microsoft.Storage/storageAccounts/queueServices/providers'
+ properties: {
+ logs: [
+ {
+ category: 'StorageRead'
+ enabled: false
+ }
+ {
+ category: 'StorageWrite'
+ enabled: true
+ }
+ {
+ category: 'StorageDelete'
+ enabled: false
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..e17fc0b221a
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive4.bicep
@@ -0,0 +1,11 @@
+resource default_Microsoft_Insights 'Microsoft.Storage/storageAccounts/queueServices/providers/diagnosticsettings@2017-05-01-preview' = {
+ name: 'Microsoft.Storage/storageAccounts/queueServices/providers'
+ properties: {
+ logs: [
+ {
+ category: 'StorageWrite'
+ enabled: true
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive5.bicep b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive5.bicep
new file mode 100644
index 00000000000..2eee3637d3e
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive5.bicep
@@ -0,0 +1,11 @@
+resource default_Microsoft_Insights 'Microsoft.Storage/storageAccounts/queueServices/providers/diagnosticsettings@2017-05-01-preview' = {
+ name: 'Microsoft.Storage/storageAccounts/queueServices/providers'
+ properties: {
+ logs: [
+ {
+ category: 'StorageWrite'
+ enabled: false
+ }
+ ]
+ }
+}
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive6.bicep b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive6.bicep
new file mode 100644
index 00000000000..a0df173d8fc
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive6.bicep
@@ -0,0 +1,3 @@
+resource default_Microsoft_Insights 'Microsoft.Storage/storageAccounts/queueServices/providers/diagnosticsettings@2017-05-01-preview' = {
+ name: 'Microsoft.Storage/storageAccounts/queueServices/providers'
+}
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive7.bicep b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive7.bicep
new file mode 100644
index 00000000000..6c28c1c2649
--- /dev/null
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive7.bicep
@@ -0,0 +1,4 @@
+resource default_Microsoft_Insights 'Microsoft.Storage/storageAccounts/queueServices/providers/diagnosticsettings@2017-05-01-preview' = {
+ name: 'Microsoft.Storage/storageAccounts/queueServices/providers'
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive_expected_result.json
index db3efe2941c..a38a9ae1865 100644
--- a/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/storage_logging_for_read_write_delete_requests_disabled/test/positive_expected_result.json
@@ -106,5 +106,119 @@
"severity": "MEDIUM",
"line": 69,
"fileName": "positive6.json"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 7,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 15,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 11,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 7,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 15,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 7,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 4,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive6.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive6.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 2,
+ "fileName": "positive6.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 3,
+ "fileName": "positive7.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 3,
+ "fileName": "positive7.bicep"
+ },
+ {
+ "queryName": "Storage Logging For Read Write And Delete Requests Disabled",
+ "severity": "MEDIUM",
+ "line": 3,
+ "fileName": "positive7.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative1.bicep b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative1.bicep
new file mode 100644
index 00000000000..d0eac8e9c62
--- /dev/null
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative1.bicep
@@ -0,0 +1,25 @@
+resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storage'
+ location: 'location1'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ networkAcls: {
+ virtualNetworkRules: [
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Allow'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative2.bicep b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative2.bicep
new file mode 100644
index 00000000000..1263f5ffa71
--- /dev/null
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative2.bicep
@@ -0,0 +1,26 @@
+resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storage'
+ location: 'location1'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ networkAcls: {
+ bypass: 'AzureServices'
+ virtualNetworkRules: [
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Deny'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative3.bicep b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative3.bicep
new file mode 100644
index 00000000000..d0eac8e9c62
--- /dev/null
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative3.bicep
@@ -0,0 +1,25 @@
+resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storage'
+ location: 'location1'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ networkAcls: {
+ virtualNetworkRules: [
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Allow'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative4.bicep b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative4.bicep
new file mode 100644
index 00000000000..1263f5ffa71
--- /dev/null
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/negative4.bicep
@@ -0,0 +1,26 @@
+resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storage'
+ location: 'location1'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ networkAcls: {
+ bypass: 'AzureServices'
+ virtualNetworkRules: [
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Deny'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive1.bicep b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive1.bicep
new file mode 100644
index 00000000000..1199327af79
--- /dev/null
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive1.bicep
@@ -0,0 +1,26 @@
+resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storage'
+ location: 'location1'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ networkAcls: {
+ bypass: 'None'
+ virtualNetworkRules: [
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Deny'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive2.bicep b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive2.bicep
new file mode 100644
index 00000000000..60ae2d6c063
--- /dev/null
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive2.bicep
@@ -0,0 +1,16 @@
+resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storage'
+ location: 'location1'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ networkAcls: {
+ bypass: 'None'
+ defaultAction: 'Deny'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive3.bicep b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive3.bicep
new file mode 100644
index 00000000000..1199327af79
--- /dev/null
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive3.bicep
@@ -0,0 +1,26 @@
+resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storage'
+ location: 'location1'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ networkAcls: {
+ bypass: 'None'
+ virtualNetworkRules: [
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ {
+ id: 'id'
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Deny'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive4.bicep b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive4.bicep
new file mode 100644
index 00000000000..60ae2d6c063
--- /dev/null
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive4.bicep
@@ -0,0 +1,16 @@
+resource storage 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: 'storage'
+ location: 'location1'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ accessTier: 'Hot'
+ networkAcls: {
+ bypass: 'None'
+ defaultAction: 'Deny'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive_expected_result.json
index aa83a1091b1..3663ce2444c 100644
--- a/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/trusted_microsoft_services_not_enabled/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 23,
"fileName": "positive4.json"
+ },
+ {
+ "queryName": "Trusted Microsoft Services Not Enabled",
+ "severity": "MEDIUM",
+ "line": 11,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Trusted Microsoft Services Not Enabled",
+ "severity": "MEDIUM",
+ "line": 11,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Trusted Microsoft Services Not Enabled",
+ "severity": "MEDIUM",
+ "line": 11,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Trusted Microsoft Services Not Enabled",
+ "severity": "MEDIUM",
+ "line": 11,
+ "fileName": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/negative1.bicep b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/negative1.bicep
new file mode 100644
index 00000000000..5b54e902114
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/negative1.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'location'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['location1']
+ categories: ['Write']
+ retentionPolicy: {
+ enabled: true
+ days: 400
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/negative2.bicep b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/negative2.bicep
new file mode 100644
index 00000000000..5b54e902114
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/negative2.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'location'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['location1']
+ categories: ['Write']
+ retentionPolicy: {
+ enabled: true
+ days: 400
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive1.bicep b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive1.bicep
new file mode 100644
index 00000000000..d59ff8b7796
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive1.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'location'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['location1']
+ categories: ['Write']
+ retentionPolicy: {
+ enabled: true
+ days: 300
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive2.bicep b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive2.bicep
new file mode 100644
index 00000000000..ea22101c9c7
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive2.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'location'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['location1']
+ categories: ['Write']
+ retentionPolicy: {
+ enabled: false
+ days: 300
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive3.bicep b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive3.bicep
new file mode 100644
index 00000000000..d59ff8b7796
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive3.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'location'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['location1']
+ categories: ['Write']
+ retentionPolicy: {
+ enabled: true
+ days: 300
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive4.bicep b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive4.bicep
new file mode 100644
index 00000000000..ea22101c9c7
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive4.bicep
@@ -0,0 +1,15 @@
+resource string 'microsoft.insights/logprofiles@2016-03-01' = {
+ name: 'string'
+ location: 'location'
+ tags: {}
+ properties: {
+ storageAccountId: 'storageAccountId'
+ serviceBusRuleId: 'serviceBusRuleId'
+ locations: ['location1']
+ categories: ['Write']
+ retentionPolicy: {
+ enabled: false
+ days: 300
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive_expected_result.json b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive_expected_result.json
index b2162149cd8..3ce6f3b5fcd 100644
--- a/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/unrecommended_log_profile_retention_policy/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "LOW",
"line": 28,
"fileName": "positive4.json"
+ },
+ {
+ "queryName": "Unrecommended Log Profile Retention Policy",
+ "severity": "LOW",
+ "line": 12,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Unrecommended Log Profile Retention Policy",
+ "severity": "LOW",
+ "line": 12,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Unrecommended Log Profile Retention Policy",
+ "severity": "LOW",
+ "line": 11,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Unrecommended Log Profile Retention Policy",
+ "severity": "LOW",
+ "line": 12,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Unrecommended Log Profile Retention Policy",
+ "severity": "LOW",
+ "line": 11,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Unrecommended Log Profile Retention Policy",
+ "severity": "LOW",
+ "line": 12,
+ "fileName": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative1.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative1.bicep
new file mode 100644
index 00000000000..92e80a9d0ed
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative1.bicep
@@ -0,0 +1,17 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/flowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ retentionPolicy: {
+ days: 92
+ enabled: true
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative2.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative2.bicep
new file mode 100644
index 00000000000..07adf43e456
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative2.bicep
@@ -0,0 +1,17 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/FlowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ retentionPolicy: {
+ days: 95
+ enabled: true
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative3.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative3.bicep
new file mode 100644
index 00000000000..92e80a9d0ed
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative3.bicep
@@ -0,0 +1,17 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/flowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ retentionPolicy: {
+ days: 92
+ enabled: true
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative4.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative4.bicep
new file mode 100644
index 00000000000..07adf43e456
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/negative4.bicep
@@ -0,0 +1,17 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/FlowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ retentionPolicy: {
+ days: 95
+ enabled: true
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive1.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive1.bicep
new file mode 100644
index 00000000000..71504ddc706
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive1.bicep
@@ -0,0 +1,17 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/flowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ retentionPolicy: {
+ days: 2
+ enabled: false
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive2.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive2.bicep
new file mode 100644
index 00000000000..7eb2e0048bd
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive2.bicep
@@ -0,0 +1,16 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/FlowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ retentionPolicy: {
+ days: 2
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive3.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive3.bicep
new file mode 100644
index 00000000000..760c06b0ea9
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive3.bicep
@@ -0,0 +1,13 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/FlowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive4.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive4.bicep
new file mode 100644
index 00000000000..461f5de28d2
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive4.bicep
@@ -0,0 +1,16 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/FlowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ retentionPolicy: {
+ days: 95
+ enabled: true
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive5.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive5.bicep
new file mode 100644
index 00000000000..71504ddc706
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive5.bicep
@@ -0,0 +1,17 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/flowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ retentionPolicy: {
+ days: 2
+ enabled: false
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive6.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive6.bicep
new file mode 100644
index 00000000000..7eb2e0048bd
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive6.bicep
@@ -0,0 +1,16 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/FlowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ retentionPolicy: {
+ days: 2
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive7.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive7.bicep
new file mode 100644
index 00000000000..760c06b0ea9
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive7.bicep
@@ -0,0 +1,13 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/FlowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ enabled: true
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive8.bicep b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive8.bicep
new file mode 100644
index 00000000000..461f5de28d2
--- /dev/null
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive8.bicep
@@ -0,0 +1,16 @@
+resource flowlogs_sample 'Microsoft.Network/networkWatchers/FlowLogs@2020-11-01' = {
+ name: 'flowlogs/sample'
+ location: 'location'
+ tags: {}
+ properties: {
+ targetResourceId: 'targetResourceId'
+ storageId: 'storageId'
+ retentionPolicy: {
+ days: 95
+ enabled: true
+ }
+ format: {
+ type: 'JSON'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive_expected_result.json b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive_expected_result.json
index 5b9f8ed8b13..559db459cb4 100644
--- a/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/unrecommended_network_watcher_flow_log_retention_policy/test/positive_expected_result.json
@@ -70,5 +70,77 @@
"severity": "LOW",
"line": 17,
"fileName": "positive8.json"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 10,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 11,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 10,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 9,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 10,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 11,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 9,
+ "fileName": "positive6.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 10,
+ "fileName": "positive6.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive7.bicep"
+ },
+ {
+ "queryName": "Unrecommended Network Watcher Flow Log Retention Policy",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive8.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/negative1.bicep b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/negative1.bicep
new file mode 100644
index 00000000000..d89cbaa2d53
--- /dev/null
+++ b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/negative1.bicep
@@ -0,0 +1,9 @@
+resource App 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'App'
+ location: resourceGroup().location
+ properties: {
+ siteConfig: {
+ minTlsVersion: '1.2'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/negative2.bicep b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/negative2.bicep
new file mode 100644
index 00000000000..d89cbaa2d53
--- /dev/null
+++ b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/negative2.bicep
@@ -0,0 +1,9 @@
+resource App 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'App'
+ location: resourceGroup().location
+ properties: {
+ siteConfig: {
+ minTlsVersion: '1.2'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive1.bicep b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive1.bicep
new file mode 100644
index 00000000000..93f9cb55fe5
--- /dev/null
+++ b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive1.bicep
@@ -0,0 +1,9 @@
+resource App 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'App'
+ location: resourceGroup().location
+ properties: {
+ siteConfig: {
+ minTlsVersion: '1.0'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive2.bicep b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive2.bicep
new file mode 100644
index 00000000000..3b9462b1ddd
--- /dev/null
+++ b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive2.bicep
@@ -0,0 +1,5 @@
+resource App 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'App'
+ location: resourceGroup().location
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive3.bicep b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive3.bicep
new file mode 100644
index 00000000000..93f9cb55fe5
--- /dev/null
+++ b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive3.bicep
@@ -0,0 +1,9 @@
+resource App 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'App'
+ location: resourceGroup().location
+ properties: {
+ siteConfig: {
+ minTlsVersion: '1.0'
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive4.bicep b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive4.bicep
new file mode 100644
index 00000000000..3b9462b1ddd
--- /dev/null
+++ b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive4.bicep
@@ -0,0 +1,5 @@
+resource App 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'App'
+ location: resourceGroup().location
+ properties: {}
+}
diff --git a/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive_expected_result.json b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive_expected_result.json
index d0e889f2cb6..6ec44374599 100644
--- a/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/web_app_not_using_tls_last_version/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 10,
"filename": "positive4.json"
+ },
+ {
+ "queryName": "Web App Not Using TLS Last Version",
+ "severity": "MEDIUM",
+ "line": 6,
+ "filename": "positive1.bicep"
+ },
+ {
+ "queryName": "Web App Not Using TLS Last Version",
+ "severity": "MEDIUM",
+ "line": 2,
+ "filename": "positive2.bicep"
+ },
+ {
+ "queryName": "Web App Not Using TLS Last Version",
+ "severity": "MEDIUM",
+ "line": 6,
+ "filename": "positive3.bicep"
+ },
+ {
+ "queryName": "Web App Not Using TLS Last Version",
+ "severity": "MEDIUM",
+ "line": 2,
+ "filename": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..17d6bf657c2
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative1.bicep
@@ -0,0 +1,12 @@
+resource webSiteNegative1 'Microsoft.Web/sites@2019-08-01' = {
+ name: 'webSiteNegative1'
+ location: 'location1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..2a7a84b391b
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative2.bicep
@@ -0,0 +1,17 @@
+var identityName = 'value'
+
+resource webSiteNegative2 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSiteNegative2'
+ location: 'location1'
+ tags: {}
+ identity: {
+ type: 'UserAssigned'
+ userAssignedIdentities: {
+ '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',identityName)}': {}
+ }
+ }
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative3.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative3.bicep
new file mode 100644
index 00000000000..17d6bf657c2
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative3.bicep
@@ -0,0 +1,12 @@
+resource webSiteNegative1 'Microsoft.Web/sites@2019-08-01' = {
+ name: 'webSiteNegative1'
+ location: 'location1'
+ identity: {
+ type: 'SystemAssigned'
+ }
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative4.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative4.bicep
new file mode 100644
index 00000000000..2a7a84b391b
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/negative4.bicep
@@ -0,0 +1,17 @@
+var identityName = 'value'
+
+resource webSiteNegative2 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSiteNegative2'
+ location: 'location1'
+ tags: {}
+ identity: {
+ type: 'UserAssigned'
+ userAssignedIdentities: {
+ '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',identityName)}': {}
+ }
+ }
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..885ee15b357
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive1.bicep
@@ -0,0 +1,9 @@
+resource webSitePositive2 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSitePositive2'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..0349686eb23
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive2.bicep
@@ -0,0 +1,12 @@
+resource webSitePositive3 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSitePositive3'
+ location: 'location1'
+ tags: {}
+ identity: {
+ type: 'None'
+ }
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..67607270b21
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive3.bicep
@@ -0,0 +1,10 @@
+resource webSitePositive3 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSitePositive3'
+ location: 'location1'
+ tags: {}
+ identity: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..885ee15b357
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive4.bicep
@@ -0,0 +1,9 @@
+resource webSitePositive2 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSitePositive2'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive5.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive5.bicep
new file mode 100644
index 00000000000..0349686eb23
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive5.bicep
@@ -0,0 +1,12 @@
+resource webSitePositive3 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSitePositive3'
+ location: 'location1'
+ tags: {}
+ identity: {
+ type: 'None'
+ }
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive6.bicep b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive6.bicep
new file mode 100644
index 00000000000..67607270b21
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive6.bicep
@@ -0,0 +1,10 @@
+resource webSitePositive3 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSitePositive3'
+ location: 'location1'
+ tags: {}
+ identity: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive_expected_result.json
index a970f83c2e4..294c2c55972 100644
--- a/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/website_azure_active_directory_disabled/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "LOW",
"line": 17,
"fileName": "positive6.json"
+ },
+ {
+ "queryName": "Website Azure Active Directory Disabled",
+ "severity": "LOW",
+ "line": 2,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Website Azure Active Directory Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Website Azure Active Directory Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Website Azure Active Directory Disabled",
+ "severity": "LOW",
+ "line": 2,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Website Azure Active Directory Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Website Azure Active Directory Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive6.bicep"
}
]
diff --git a/assets/queries/azureResourceManager/website_not_forcing_https/test/negative1.bicep b/assets/queries/azureResourceManager/website_not_forcing_https/test/negative1.bicep
new file mode 100644
index 00000000000..29fc2158115
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_not_forcing_https/test/negative1.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_not_forcing_https/test/negative2.bicep b/assets/queries/azureResourceManager/website_not_forcing_https/test/negative2.bicep
new file mode 100644
index 00000000000..29fc2158115
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_not_forcing_https/test/negative2.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_not_forcing_https/test/positive1.bicep b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive1.bicep
new file mode 100644
index 00000000000..6f0ef54f3aa
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive1.bicep
@@ -0,0 +1,8 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_not_forcing_https/test/positive2.bicep b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive2.bicep
new file mode 100644
index 00000000000..758b59cc289
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive2.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_not_forcing_https/test/positive3.bicep b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive3.bicep
new file mode 100644
index 00000000000..6f0ef54f3aa
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive3.bicep
@@ -0,0 +1,8 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_not_forcing_https/test/positive4.bicep b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive4.bicep
new file mode 100644
index 00000000000..758b59cc289
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive4.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_not_forcing_https/test/positive_expected_result.json b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive_expected_result.json
index 85d5eb855d9..139dfcbc9e3 100644
--- a/assets/queries/azureResourceManager/website_not_forcing_https/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/website_not_forcing_https/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 19,
"fileName": "positive4.json"
+ },
+ {
+ "queryName": "Website Not Forcing HTTPS",
+ "severity": "MEDIUM",
+ "line": 5,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Website Not Forcing HTTPS",
+ "severity": "MEDIUM",
+ "line": 7,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Website Not Forcing HTTPS",
+ "severity": "MEDIUM",
+ "line": 5,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Website Not Forcing HTTPS",
+ "severity": "MEDIUM",
+ "line": 7,
+ "fileName": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..c003246f604
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/negative1.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ clientCertEnabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..c003246f604
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/negative2.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ clientCertEnabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..6f0ef54f3aa
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive1.bicep
@@ -0,0 +1,8 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..5ce6fbc0e6a
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive2.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ clientCertEnabled: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..6f0ef54f3aa
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive3.bicep
@@ -0,0 +1,8 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..5ce6fbc0e6a
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive4.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ clientCertEnabled: false
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive_expected_result.json
index e6c734aee1f..68777490f18 100644
--- a/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/website_with_client_certificate_auth_disabled/test/positive_expected_result.json
@@ -22,5 +22,29 @@
"severity": "MEDIUM",
"line": 19,
"fileName": "positive4.json"
+ },
+ {
+ "queryName": "Website with Client Certificate Auth Disabled",
+ "severity": "MEDIUM",
+ "line": 5,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Website with Client Certificate Auth Disabled",
+ "severity": "MEDIUM",
+ "line": 7,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Website with Client Certificate Auth Disabled",
+ "severity": "MEDIUM",
+ "line": 5,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Website with Client Certificate Auth Disabled",
+ "severity": "MEDIUM",
+ "line": 7,
+ "fileName": "positive4.bicep"
}
]
\ No newline at end of file
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/negative1.bicep b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/negative1.bicep
new file mode 100644
index 00000000000..b0b8c8e726b
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/negative1.bicep
@@ -0,0 +1,12 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ siteConfig: {
+ http20Enabled: true
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/negative2.bicep b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/negative2.bicep
new file mode 100644
index 00000000000..b0b8c8e726b
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/negative2.bicep
@@ -0,0 +1,12 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ siteConfig: {
+ http20Enabled: true
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive1.bicep b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive1.bicep
new file mode 100644
index 00000000000..29fc2158115
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive1.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive2.bicep b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive2.bicep
new file mode 100644
index 00000000000..03656e73be2
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive2.bicep
@@ -0,0 +1,12 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ siteConfig: {
+ http20Enabled: false
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive3.bicep b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive3.bicep
new file mode 100644
index 00000000000..b4cfb1a0ac3
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive3.bicep
@@ -0,0 +1,10 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ siteConfig: {}
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive4.bicep b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive4.bicep
new file mode 100644
index 00000000000..29fc2158115
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive4.bicep
@@ -0,0 +1,9 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive5.bicep b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive5.bicep
new file mode 100644
index 00000000000..03656e73be2
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive5.bicep
@@ -0,0 +1,12 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ siteConfig: {
+ http20Enabled: false
+ }
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive6.bicep b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive6.bicep
new file mode 100644
index 00000000000..b4cfb1a0ac3
--- /dev/null
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive6.bicep
@@ -0,0 +1,10 @@
+resource webSite 'Microsoft.Web/sites@2020-12-01' = {
+ name: 'webSite'
+ location: 'location1'
+ tags: {}
+ properties: {
+ enabled: true
+ httpsOnly: true
+ siteConfig: {}
+ }
+}
diff --git a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive_expected_result.json b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive_expected_result.json
index 7e237461eb5..1385deea8c6 100644
--- a/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive_expected_result.json
+++ b/assets/queries/azureResourceManager/website_with_http20enabled_disabled/test/positive_expected_result.json
@@ -34,5 +34,41 @@
"severity": "LOW",
"line": 17,
"fileName": "positive6.json"
+ },
+ {
+ "queryName": "Website with 'Http20Enabled' Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive1.bicep"
+ },
+ {
+ "queryName": "Website with 'Http20Enabled' Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive2.bicep"
+ },
+ {
+ "queryName": "Website with 'Http20Enabled' Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive3.bicep"
+ },
+ {
+ "queryName": "Website with 'Http20Enabled' Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive4.bicep"
+ },
+ {
+ "queryName": "Website with 'Http20Enabled' Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive5.bicep"
+ },
+ {
+ "queryName": "Website with 'Http20Enabled' Disabled",
+ "severity": "LOW",
+ "line": 5,
+ "fileName": "positive6.bicep"
}
]
diff --git a/docker/Dockerfile.antlr b/docker/Dockerfile.antlr
index b6a3773a185..59dfd91819a 100644
--- a/docker/Dockerfile.antlr
+++ b/docker/Dockerfile.antlr
@@ -32,4 +32,4 @@ RUN adduser \
COPY --from=builder /opt/antlr4/antlr4/antlr4-tool.jar /usr/local/lib/
WORKDIR /work
ENTRYPOINT ["java", "-Xmx500M", "-cp", "/usr/local/lib/antlr4-tool.jar", "org.antlr.v4.Tool"]
-CMD [ "-Dlanguage=Go", "-visitor", "-no-listener", "-o", "parser", "JSONFilter.g4" ]
+CMD [ "-Dlanguage=Go", "-visitor", "-no-listener", "-o", "parser", "jsonfilter/JSONFilter.g4", "-Dlanguage=Go", "-visitor", "-no-listener", "-o", "parser", "bicep/antlr/bicep.g4"]
diff --git a/docs/commands.md b/docs/commands.md
index f0394f9a83d..3c992ed8d36 100644
--- a/docs/commands.md
+++ b/docs/commands.md
@@ -73,8 +73,8 @@ Use "kics [command] --help" for more information about a command.
| -r, --secrets-regexes-path string | path to secrets regex rules configuration file|
| --terraform-vars-path | string path where terraform variables are present|
| --timeout int | number of seconds the query has to execute before being canceled (default 60)|
-| -t, --type strings | case insensitive list of platform types to scan
(Ansible, AzureResourceManager, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC,GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerLessFW, Terraform)
cannot be provided with type exclusion flags|
-| --exclude-type strings | case insensitive list of platform types not to scan
(Ansible, AzureResourceManager, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerLessFW, Terraform)
cannot be provided with type inclusion flags|
+| -t, --type strings | case insensitive list of platform types to scan
(Ansible, AzureResourceManager, Bicep, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC,GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerLessFW, Terraform)
cannot be provided with type exclusion flags|
+| --exclude-type strings | case insensitive list of platform types not to scan
(Ansible, AzureResourceManager, Bicep, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerLessFW, Terraform)
cannot be provided with type inclusion flags|
Usage:
diff --git a/docs/dockerhub.md b/docs/dockerhub.md
index 6601d65462b..b8fe69d373f 100644
--- a/docs/dockerhub.md
+++ b/docs/dockerhub.md
@@ -136,10 +136,10 @@ Flags:
-r, --secrets-regexes-path string path to secrets regex rules configuration file
--timeout int number of seconds the query has to execute before being canceled (default 60)
-t, --type strings case insensitive list of platform types to scan
- (Ansible, AzureResourceManager, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerLessFW, Terraform)
+ (Ansible, AzureResourceManager, Bicep, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerLessFW, Terraform)
cannot be provided with type exclusion flags
--exclude-type strings case insensitive list of platform types not to scan
- (Ansible, AzureResourceManager, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerLessFW, Terraform)
+ (Ansible, AzureResourceManager, Bicep, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerLessFW, Terraform)
cannot be provided with type inclusion flags
```
diff --git a/docs/future_improvements.md b/docs/future_improvements.md
new file mode 100644
index 00000000000..cfe91162b9a
--- /dev/null
+++ b/docs/future_improvements.md
@@ -0,0 +1,48 @@
+## Introduction
+
+We're dedicated to improving detection capabilities, addressing limitations, and incorporating user feedback to deliver a more robust scanning solution. As technology evolves and user needs evolve, we are committed to continually improving KICS to provide greater value, efficiency, and security for our users.
+
+Here, you'll find information on upcoming enhancements, planned features, and areas of focus for future releases.
+
+---
+
+## Bicep
+
+### Linting and File Validation
+
+Currently, KICS doesn't perform validation checks on Bicep files before scanning them.
+This means that even if a file isn't syntactically or structurally correct, it will still be scanned, potentially leading to inaccurate results without any error notifications. We're actively prioritizing this fix and anticipate implementing it in the forthcoming weeks.
+
+### Commands on Bicep Files as Comments
+
+The current version does not support **ignoring sections using special commands in comments** when scanning Bicep files. Unlike other file types, where comments starting with `kics-scan` can control the scan behavior, this feature is not yet available for Bicep.
+
+We are working on adding this capability in future updates. Until then, please note that Bicep files will be scanned in their entirety, and commands in comments will be ignored.
+
+More information about commands on comments in files is available on [Running KICS documentation page](https://docs.kics.io/latest/running-kics/#using_commands_on_scanned_files_as_comments)
+
+### Logic and Cycle Operators
+
+Currently, KICS does not analyze logic and cycle operators. This means that expressions within constructs such as for and if statements are ignored during the scanning process. As a result, any security issues or vulnerabilities present within these constructs will not be detected by KICS.
+
+### Module Support
+
+KICS does not currently support the analysis of modules within Bicep files. Due to our current scanning methodology, which involves processing each file independently, we are unable to scan other files referenced within modules. Therefore, any security issues or vulnerabilities contained within modules will not be identified by KICS.
+
+### Passwords and Secrets Query
+
+Due to the nature of regex-based pattern matching, the passwords and secrets query may generate false positives when applied to Bicep files. Bicep files have a different syntax and structure compared to other file formats which can affect the accuracy of the query.
+
+To avoid potential false positives and improve the accuracy of scans when working with Bicep files, we recommend users consider disabling the passwords and secrets query. This can be done by using the "--disable-secrets" flag.
+
+**Note**: When using the "--disable-secrets" flag, be aware that this will disable the passwords and secrets query for all languages, not just Bicep files. As a result, you may miss some security checks in other files. Before using this flag, carefully consider the impact on your overall security coverage, especially if your project includes multiple languages or file types.
+
+We advise reviewing your project's specific security needs to determine if this flag is appropriate. More information about the passwords and secrets query is available in our [Password and Secrets documentation](https://github.com/Checkmarx/kics/blob/master/docs/secrets.md).
+
+
+---
+
+## Contribution
+
+If you'd like to contribute or provide insightful feedback regarding KICS' capabilities and limitations, please don't hesitate to contact [our team](https://github.com/Checkmarx/kics/issues/).
+We appreciate your patience and understanding as we strive to deliver a more robust scanning solution.
\ No newline at end of file
diff --git a/docs/platforms.md b/docs/platforms.md
index f361fc325ac..beddfb6ea1d 100644
--- a/docs/platforms.md
+++ b/docs/platforms.md
@@ -9,14 +9,26 @@ KICS supports scanning Ansible files with `.yaml` extension.
KICS can decrypt Ansible Vault files on the fly. For that, you need to define the environment variable `ANSIBLE_VAULT_PASSWORD_FILE`.
## Ansible Config
+
KICS supports scanning Ansible Configuration files with `.cfg` or `.conf` extension.
## Ansible Inventory
+
KICS supports scanning Ansible Inventory files with `.ini`, `.json` or `.yaml` extension.
## Azure Resource Manager
-KICS supports scanning Azure Resource Manager (ARM) templates with `.json` extension. To build ARM JSON templates from Bicep code check the [official ARM documentation](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-cli#build) and [here](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/compare-template-syntax) to understand the differences between ARM JSON templates and Bicep.
+KICS supports scanning Azure Resource Manager (ARM) templates with `.json` extension.
+
+## Bicep
+
+KICS supports scanning Bicep files with `.bicep` extension.
+
+For instructions on converting between ARM JSON templates and Bicep code, refer to the [official ARM documentation](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/bicep-cli#build). To understand the distinctions between the two, explore the [official syntax comparison](https://docs.microsoft.com/en-us/azure/azure-resource-manager/bicep/compare-template-syntax).
+
+Note that KICS recognizes this technology as Azure Resource Manager (for queries purpose).
+
+Explore our ongoing enhancements and planned features on our [Future Improvements](future_improvements.md) page.
## CDK
diff --git a/e2e/fixtures/E2E_CLI_013 b/e2e/fixtures/E2E_CLI_013
index 827a6f6ae73..8be27088c85 100644
--- a/e2e/fixtures/E2E_CLI_013
+++ b/e2e/fixtures/E2E_CLI_013
@@ -1,5 +1,6 @@
Ansible
AzureResourceManager
+Bicep
Buildah
CICD
CloudFormation
diff --git a/e2e/fixtures/E2E_CLI_091_PAYLOAD.json b/e2e/fixtures/E2E_CLI_091_PAYLOAD.json
new file mode 100644
index 00000000000..2cc4ea05b0d
--- /dev/null
+++ b/e2e/fixtures/E2E_CLI_091_PAYLOAD.json
@@ -0,0 +1,372 @@
+{
+ "document": [
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "On"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "On"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "On"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "On"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "Off"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "On"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "On"
+ },
+ "emails": "sample@email.com",
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "On"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "Off"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "On"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ]
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "On"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "On"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "On"
+ },
+ "emails": "sample@email.com",
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "On"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "Off"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "On"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ]
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High",
+ "state": "Off"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "On"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "On"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ },
+ {
+ "file": "file",
+ "id": "0",
+ "parameters": {},
+ "resources": [
+ {
+ "apiVersion": "2020-01-01-preview",
+ "identifier": "security_contact",
+ "name": "security contact",
+ "properties": {
+ "alertNotifications": {
+ "minimalSeverity": "High"
+ },
+ "emails": "sample@email.com",
+ "notificationsByRole": {
+ "roles": [
+ "Owner"
+ ],
+ "state": "On"
+ },
+ "phone": "9999999"
+ },
+ "type": "Microsoft.Security/securityContacts"
+ }
+ ],
+ "variables": {}
+ }
+ ]
+}
diff --git a/e2e/fixtures/E2E_CLI_091_RESULT.json b/e2e/fixtures/E2E_CLI_091_RESULT.json
new file mode 100644
index 00000000000..81255188947
--- /dev/null
+++ b/e2e/fixtures/E2E_CLI_091_RESULT.json
@@ -0,0 +1,200 @@
+{
+ "kics_version": "development",
+ "files_scanned": 14,
+ "lines_scanned": 204,
+ "files_parsed": 14,
+ "lines_parsed": 204,
+ "lines_ignored": 0,
+ "files_failed_to_scan": 0,
+ "queries_total": 43,
+ "queries_failed_to_execute": 0,
+ "queries_failed_to_compute_similarity_id": 0,
+ "scan_id": "console",
+ "severity_counters": {
+ "CRITICAL": 0,
+ "HIGH": 0,
+ "INFO": 12,
+ "LOW": 0,
+ "MEDIUM": 0,
+ "TRACE": 0
+ },
+ "total_counter": 12,
+ "total_bom_resources": 0,
+ "start": "2024-05-13T14:56:28.4200497+01:00",
+ "end": "2024-05-13T14:56:32.4884749+01:00",
+ "paths": [
+ "/path/test/fixtures/bicep_test/test"
+ ],
+ "queries": [
+ {
+ "query_name": "Email Notifications Disabled",
+ "query_id": "79c2c2c0-eb00-47c0-ac16-f8b0e2c81c92",
+ "query_url": "https://docs.microsoft.com/en-us/azure/templates/microsoft.security/securitycontacts",
+ "severity": "INFO",
+ "platform": "AzureResourceManager",
+ "cloud_provider": "AZURE",
+ "category": "Networking and Firewall",
+ "experimental": false,
+ "description": "Email notifications about new security alerts, should be set to 'On', and be sent to persons with specific RBAC roles on the subscription",
+ "description_id": "7f5b9ef4",
+ "files": [
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive12.bicep",
+ "similarity_id": "c1c095342af7dbf263e52e6ed344fd07ef39dca36e654aeffecb3c40530728aa",
+ "line": 10,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "MissingAttribute",
+ "search_key": "resources.name={{security contact}}.properties.notificationsByRole",
+ "search_line": 10,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' should have 'notificationsByRole.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' doesn't have 'notificationsByRole.state' property defined"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive2.bicep",
+ "similarity_id": "cde286e1f04fd3a1ce64f647e9483728511e154bab26b6ed418ac9373fbb42e6",
+ "line": 3,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "MissingAttribute",
+ "search_key": "resources.name={{security contact}}.properties",
+ "search_line": 3,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' should have 'alertNotifications.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' doesn't have 'alertNotifications' property defined"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive7.bicep",
+ "similarity_id": "1137382a29991fd5de51071734a6b3ba2deb0b5090fd06c0573e35bb79d78b15",
+ "line": 7,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "IncorrectValue",
+ "search_key": "resources.name={{security contact}}.properties.alertNotifications.state",
+ "search_line": 7,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' property value should have 'alertNotifications.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' should have 'alertNotifications.state' property set to 'Off'"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive10.bicep",
+ "similarity_id": "904900ad2ed3ec646f8f9390b6a223b4541044101f250b4d4e4740eea76a9461",
+ "line": 3,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "MissingAttribute",
+ "search_key": "resources.name={{security contact}}.properties",
+ "search_line": 3,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' should have 'notificationsByRole.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' doesn't have 'notificationsByRole' property defined"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive8.bicep",
+ "similarity_id": "34afd47f5ee4c855d2733888cc0b2a9df989a61d33340fb873a666ab4cc87eb1",
+ "line": 3,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "MissingAttribute",
+ "search_key": "resources.name={{security contact}}.properties",
+ "search_line": 3,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' should have 'alertNotifications.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' doesn't have 'alertNotifications' property defined"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive5.bicep",
+ "similarity_id": "3e045654ceb3b05fe41f5e9e64a797725302d50ce01079e8f04255a7c0cdf9a6",
+ "line": 11,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "IncorrectValue",
+ "search_key": "resources.name={{security contact}}.properties.notificationsByRole.state",
+ "search_line": 11,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' property value should have 'notificationsByRole.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' should have 'notificationsByRole.state' property set to 'Off'"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive1.bicep",
+ "similarity_id": "e29ed60beffa13540f660e8290dd546afe1c3ff9f735b0851f8862010b0cd03c",
+ "line": 7,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "IncorrectValue",
+ "search_key": "resources.name={{security contact}}.properties.alertNotifications.state",
+ "search_line": 7,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' property value should have 'alertNotifications.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' should have 'alertNotifications.state' property set to 'Off'"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive4.bicep",
+ "similarity_id": "18470b0d2877779414ff2b495c997afe4cd925fb5c055eeeadb8e617772a5c52",
+ "line": 3,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "MissingAttribute",
+ "search_key": "resources.name={{security contact}}.properties",
+ "search_line": 3,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' should have 'notificationsByRole.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' doesn't have 'notificationsByRole' property defined"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive3.bicep",
+ "similarity_id": "f0bc728e7dd11b3bd9bb68ba9ed364a1918e1988de56cef9aada9bd658c668f0",
+ "line": 6,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "MissingAttribute",
+ "search_key": "resources.name={{security contact}}.properties.alertNotifications",
+ "search_line": 6,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' should have 'alertNotifications.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' doesn't have 'alertNotifications.state' property defined"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive11.bicep",
+ "similarity_id": "e7f46abecbf3efb96157925b4e3c7b693e8670673f12b8241e6c2f8d0d1ff11a",
+ "line": 11,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "IncorrectValue",
+ "search_key": "resources.name={{security contact}}.properties.notificationsByRole.state",
+ "search_line": 11,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' property value should have 'notificationsByRole.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' should have 'notificationsByRole.state' property set to 'Off'"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive6.bicep",
+ "similarity_id": "c607324d4aaa4b87c9652f3e2c345d60d17e009d138e6873f457b08f5da58b20",
+ "line": 10,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "MissingAttribute",
+ "search_key": "resources.name={{security contact}}.properties.notificationsByRole",
+ "search_line": 10,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' should have 'notificationsByRole.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' doesn't have 'notificationsByRole.state' property defined"
+ },
+ {
+ "file_name": "/path/test/fixtures/bicep_test/test/positive9.bicep",
+ "similarity_id": "abe2b32de833f56224ef281c8833ed5398a80c29fb4f0cbdf00462b2f4cb80eb",
+ "line": 6,
+ "resource_type": "Microsoft.Security/securityContacts",
+ "resource_name": "security contact",
+ "issue_type": "MissingAttribute",
+ "search_key": "resources.name={{security contact}}.properties.alertNotifications",
+ "search_line": 6,
+ "search_value": "",
+ "expected_value": "resource with type 'Microsoft.Security/securityContacts' should have 'alertNotifications.state' property set to 'On'",
+ "actual_value": "resource with type 'Microsoft.Security/securityContacts' doesn't have 'alertNotifications.state' property defined"
+ }
+ ]
+ }
+ ]
+}
diff --git a/e2e/fixtures/assets/scan_help b/e2e/fixtures/assets/scan_help
index aaf3d2eb818..0817202a5e0 100644
--- a/e2e/fixtures/assets/scan_help
+++ b/e2e/fixtures/assets/scan_help
@@ -27,7 +27,7 @@ Flags:
can be provided multiple times or as a comma separated string
example: 'info,low'
--exclude-type strings case insensitive list of platform types not to scan
- (Ansible, AzureResourceManager, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerlessFW, Terraform)
+ (Ansible, AzureResourceManager, Bicep, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerlessFW, Terraform)
cannot be provided with type inclusion flags
--experimental-queries include experimental queries (queries not yet thoroughly reviewed)
--fail-on strings which kind of results should return an exit code different from 0
@@ -62,7 +62,7 @@ Flags:
--terraform-vars-path string path where terraform variables are present
--timeout int number of seconds the query has to execute before being canceled (default 60)
-t, --type strings case insensitive list of platform types to scan
- (Ansible, AzureResourceManager, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerlessFW, Terraform)
+ (Ansible, AzureResourceManager, Bicep, Buildah, CICD, CloudFormation, Crossplane, DockerCompose, Dockerfile, GRPC, GoogleDeploymentManager, Knative, Kubernetes, OpenAPI, Pulumi, ServerlessFW, Terraform)
cannot be provided with type exclusion flags
Global Flags:
diff --git a/e2e/testcases/e2e-cli-091_bicep_scan_output_payload.go b/e2e/testcases/e2e-cli-091_bicep_scan_output_payload.go
new file mode 100644
index 00000000000..ff1e341ee77
--- /dev/null
+++ b/e2e/testcases/e2e-cli-091_bicep_scan_output_payload.go
@@ -0,0 +1,31 @@
+package testcases
+
+// E2E-CLI-091 - Kics scan command with -o and -d flags on bicep files
+// should perform the scan successfully, evaluating the result and payload files
+func init() { //nolint
+ testSample := TestCase{
+ Name: "should perform a scan on bicep files and create a result and payload file [E2E-CLI-091]",
+ Args: args{
+ Args: []cmdArgs{
+ []string{"scan", "-o", "/path/e2e/output",
+ "--output-name", "E2E_CLI_091_RESULT",
+ "-p", "\"/path/test/fixtures/bicep_test/test\"",
+ "-d", "/path/e2e/output/E2E_CLI_091_PAYLOAD.json",
+ "--disable-secrets",
+ },
+ },
+ ExpectedResult: []ResultsValidation{
+ {
+ ResultsFile: "E2E_CLI_091_RESULT",
+ ResultsFormats: []string{"json"},
+ },
+ },
+ ExpectedPayload: []string{
+ "E2E_CLI_091_PAYLOAD.json",
+ },
+ },
+ WantStatus: []int{20},
+ }
+
+ Tests = append(Tests, testSample)
+}
diff --git a/go.mod b/go.mod
index 21c67c32ae2..77b9d405c16 100644
--- a/go.mod
+++ b/go.mod
@@ -68,7 +68,7 @@ require (
cloud.google.com/go/iam v1.1.5 // indirect
cloud.google.com/go/storage v1.36.0 // indirect
github.com/Microsoft/hcsshim v0.12.1-0.20240402173835-42671b424b99 // indirect
- github.com/aws/aws-sdk-go v1.44.122 // indirect
+ github.com/aws/aws-sdk-go v1.44.295 // indirect
github.com/aws/smithy-go v1.20.2 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/typeurl/v2 v2.1.1 // indirect
diff --git a/go.sum b/go.sum
index 35bf1e1067a..790ea866bbc 100644
--- a/go.sum
+++ b/go.sum
@@ -238,8 +238,9 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/aws/aws-sdk-go v1.44.122 h1:p6mw01WBaNpbdP2xrisz5tIkcNwzj/HysobNoaAHjgo=
github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
+github.com/aws/aws-sdk-go v1.44.295 h1:SGjU1+MqttXfRiWHD6WU0DRhaanJgAFY+xIhEaugV8Y=
+github.com/aws/aws-sdk-go v1.44.295/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v1.26.1 h1:5554eUqIYVWpU0YmeeYZ0wU64H2VLBs8TlhRB2L+EkA=
github.com/aws/aws-sdk-go-v2 v1.26.1/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM=
github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q=
diff --git a/internal/constants/constants.go b/internal/constants/constants.go
index 979eb620ca2..27a59d3fb80 100644
--- a/internal/constants/constants.go
+++ b/internal/constants/constants.go
@@ -51,6 +51,7 @@ var (
"OpenAPI": "openAPI",
"Terraform": "terraform",
"AzureResourceManager": "azureResourceManager",
+ "Bicep": "bicep",
"GoogleDeploymentManager": "googleDeploymentManager",
"GRPC": "grpc",
"Buildah": "buildah",
diff --git a/mkdocs.yml b/mkdocs.yml
index 0d5ebea0b33..f2da55dd4da 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -38,6 +38,7 @@ nav:
- Architecture: architecture.md
- Auto Remediation : kics_auto_remediation.md
- Certifications: certifications.md
+ - Future Improvements: future_improvements.md
- Changes in v1.3.0: changes.md
- Changes in v1.6.0: changes1_6.md
- Changes in v1.7.0: changes1_7.md
diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go
index d09ce59cf5b..b8c25326ab4 100644
--- a/pkg/analyzer/analyzer.go
+++ b/pkg/analyzer/analyzer.go
@@ -88,6 +88,7 @@ var (
".cfg": true,
".conf": true,
".ini": true,
+ ".bicep": true,
}
supportedRegexes = map[string][]string{
"azureresourcemanager": append(armRegexTypes, arm),
@@ -117,6 +118,7 @@ const (
json = ".json"
sh = ".sh"
arm = "azureresourcemanager"
+ bicep = "bicep"
kubernetes = "kubernetes"
terraform = "terraform"
gdm = "googledeploymentmanager"
@@ -366,7 +368,7 @@ func Analyze(a *Analyzer) (model.AnalyzedPaths, error) {
// worker determines the type of the file by ext (dockerfile and terraform)/content and
// writes the answer to the results channel
// if no types were found, the worker will write the path of the file in the unwanted channel
-func (a *analyzerInfo) worker(results, unwanted chan<- string, locCount chan<- int, wg *sync.WaitGroup) {
+func (a *analyzerInfo) worker(results, unwanted chan<- string, locCount chan<- int, wg *sync.WaitGroup) { //nolint: gocyclo
defer wg.Done()
ext, errExt := utils.GetExtension(a.filePath)
@@ -394,6 +396,12 @@ func (a *analyzerInfo) worker(results, unwanted chan<- string, locCount chan<- i
results <- terraform
locCount <- linesCount
}
+ // Bicep
+ case ".bicep":
+ if a.isAvailableType(bicep) {
+ results <- bicep
+ locCount <- linesCount
+ }
// GRPC
case ".proto":
if a.isAvailableType(grpc) {
diff --git a/pkg/analyzer/analyzer_test.go b/pkg/analyzer/analyzer_test.go
index 98cdf146a9c..9885ef7fb05 100644
--- a/pkg/analyzer/analyzer_test.go
+++ b/pkg/analyzer/analyzer_test.go
@@ -423,6 +423,19 @@ func TestAnalyzer_Analyze(t *testing.T) {
excludeGitIgnore: false,
MaxFileSize: -1,
},
+ {
+ name: "analyze_test_bicep",
+ paths: []string{filepath.FromSlash("../../test/fixtures/bicep_test")},
+ wantTypes: []string{"bicep"},
+ wantExclude: []string{},
+ typesFromFlag: []string{""},
+ excludeTypesFromFlag: []string{""},
+ wantLOC: 697,
+ wantErr: false,
+ gitIgnoreFileName: "",
+ excludeGitIgnore: false,
+ MaxFileSize: -1,
+ },
}
for _, tt := range tests {
diff --git a/pkg/detector/default_detect.go b/pkg/detector/default_detect.go
index d7a605978ca..27d10de1215 100644
--- a/pkg/detector/default_detect.go
+++ b/pkg/detector/default_detect.go
@@ -46,6 +46,13 @@ func (d defaultDetectLine) DetectLine(file *model.FileMetadata, searchKey string
for _, key := range splitSanitized {
substr1, substr2 := GenerateSubstrings(key, extractedString)
+ // BICEP-specific tweaks in order to make bicep files compatible with ARM queries
+ if file.Kind == "BICEP" {
+ substr1 = strings.ReplaceAll(substr1, "resources", "resource")
+ substr1 = strings.ReplaceAll(substr1, "parameters", "param")
+ substr1 = strings.ReplaceAll(substr1, "variables", "variable")
+ }
+
detector, lines = detector.DetectCurrentLine(substr1, substr2, 0, lines)
if detector.IsBreak {
diff --git a/pkg/engine/source/filesystem_test.go b/pkg/engine/source/filesystem_test.go
index cd2538292dc..3f99fe8b4de 100644
--- a/pkg/engine/source/filesystem_test.go
+++ b/pkg/engine/source/filesystem_test.go
@@ -733,6 +733,7 @@ func TestListSupportedPlatforms(t *testing.T) {
expected := []string{
"Ansible",
"AzureResourceManager",
+ "Bicep",
"Buildah",
"CICD",
"CloudFormation",
diff --git a/pkg/model/model.go b/pkg/model/model.go
index 97dfcdbe793..8284908de43 100644
--- a/pkg/model/model.go
+++ b/pkg/model/model.go
@@ -11,6 +11,7 @@ import (
// Constants to describe what kind of file refers
const (
KindTerraform FileKind = "TF"
+ KindBICEP FileKind = "BICEP"
KindJSON FileKind = "JSON"
KindYAML FileKind = "YAML"
KindYML FileKind = "YML"
diff --git a/pkg/parser/bicep/antlr/bicep.g4 b/pkg/parser/bicep/antlr/bicep.g4
new file mode 100644
index 00000000000..441325e0ec0
--- /dev/null
+++ b/pkg/parser/bicep/antlr/bicep.g4
@@ -0,0 +1,303 @@
+grammar bicep;
+
+// program -> statement* EOF
+program: statement* EOF;
+
+statement:
+ targetScopeDecl
+ | importDecl
+ | metadataDecl
+ | parameterDecl
+ | typeDecl
+ | variableDecl
+ | resourceDecl
+ | moduleDecl
+ | outputDecl
+ | NL;
+
+// targetScopeDecl -> "targetScope" "=" expression NL
+targetScopeDecl: TARGET_SCOPE ASSIGN expression NL;
+
+// importDecl -> decorator* "import" interpString(specification) importWithClause? importAsClause? NL
+importDecl:
+ decorator* IMPORT specification = interpString (
+ WITH object
+ | AS alias = identifier
+ )* NL;
+
+// metadataDecl -> "metadata" IDENTIFIER(name) "=" expression NL
+metadataDecl: METADATA name = identifier ASSIGN expression NL;
+
+// parameterDecl -> decorator* "parameter" IDENTIFIER(name) typeExpression parameterDefaultValue? NL
+// | decorator* "parameter" IDENTIFIER(name) "resource" interpString(type) parameterDefaultValue? NL
+// |
+parameterDecl:
+ decorator* PARAM name = identifier (
+ typeExpression parameterDefaultValue?
+ | RESOURCE type = interpString parameterDefaultValue?
+ ) NL;
+
+// parameterDefaultValue -> "=" expression
+parameterDefaultValue: ASSIGN expression;
+
+// typeDecl -> decorator* "type" IDENTIFIER(name) "=" typeExpression NL
+typeDecl:
+ decorator* TYPE name = identifier ASSIGN typeExpression NL;
+
+// variableDecl -> decorator* "variable" IDENTIFIER(name) "=" expression NL
+variableDecl:
+ decorator* VAR name = identifier ASSIGN expression NL;
+
+// resourceDecl -> decorator* "resource" IDENTIFIER(name) interpString(type) "existing"? "=" (ifCondition | object | forExpression) NL
+resourceDecl:
+ decorator* RESOURCE name = identifier type = interpString EXISTING? ASSIGN (
+ ifCondition
+ | object
+ | forExpression
+ ) NL;
+
+// moduleDecl -> decorator* "module" IDENTIFIER(name) interpString(type) "=" (ifCondition | object | forExpression) NL
+moduleDecl:
+ decorator* MODULE name = identifier type = interpString ASSIGN (
+ ifCondition
+ | object
+ | forExpression
+ ) NL;
+
+// outputDecl -> decorator* "output" IDENTIFIER(name) IDENTIFIER(type) "=" expression NL decorator*
+// "output" IDENTIFIER(name) "resource" interpString(type) "=" expression NL
+outputDecl:
+ decorator* OUTPUT name = identifier (
+ type1 = identifier
+ | RESOURCE type2 = interpString
+ ) ASSIGN expression NL;
+
+// ifCondition -> "if" parenthesizedExpression object
+ifCondition: IF parenthesizedExpression object;
+
+// forExpression -> "[" "for" (IDENTIFIER(item) | forVariableBlock) "in" expression ":" forBody "]"
+forExpression:
+ OBRACK NL* FOR (item = identifier | forVariableBlock) IN expression COL forBody NL* CBRACK;
+
+// forVariableBlock -> "(" IDENTIFIER(item) "," IDENTIFIER(index) ")"
+forVariableBlock:
+ OPAR item = identifier COMMA index = identifier CPAR;
+
+// forBody -> expression(body) | ifCondition
+forBody: body = expression | ifCondition;
+
+// interpString -> stringLeftPiece ( expression stringMiddlePiece )* expression stringRightPiece | stringComplete
+interpString:
+ STRING_LEFT_PIECE (expression STRING_MIDDLE_PIECE)* expression STRING_RIGHT_PIECE
+ | STRING_COMPLETE;
+
+// expression -> expression "[" expression "]" | expression "." IDENTIFIER(property) | expression
+// ":" IDENTIFIER(name)
+expression:
+ expression OBRACK expression CBRACK
+ | expression QMARK expression COL expression
+ | expression DOT property = identifier
+ | expression DOT functionCall
+ | expression COL name = identifier
+ | expression logicCharacter expression
+ | primaryExpression;
+
+// lambdaExpression -> ( "(" argumentList? ")" | IDENTIFIER ) "=>" expression
+lambdaExpression:
+ (OPAR argumentList? CPAR | identifier) ARROW expression;
+
+logicCharacter: (GT | GTE | LT | LTE | EQ | NEQ);
+
+// primaryExpression -> literalValue | interpString | multilineString | array | object |
+// parenthesizedExpression
+primaryExpression:
+ literalValue
+ | functionCall
+ | interpString
+ | MULTILINE_STRING
+ | array
+ | object
+ | forExpression
+ | parenthesizedExpression
+ | lambdaExpression;
+
+// parenthesizedExpression -> "(" expression ")"
+parenthesizedExpression: OPAR NL? expression NL? CPAR;
+
+// typeExpression -> singularTypeExpression ("|" singularTypeExpression)*
+typeExpression: type = identifier;
+
+// literalValue -> NUMBER | "true" | "false" | "null"
+literalValue: NUMBER | TRUE | FALSE | NULL | identifier;
+
+// object -> "{" ( NL+ ( objectProperty NL+ )* )? "}"
+object: OBRACE (NL+ ( objectProperty NL+)*)? CBRACE;
+
+// objectProperty -> ( IDENTIFIER(name) | interpString ) ":" expression
+objectProperty: (name = identifier | interpString) COL expression;
+
+// array -> "[" NL* arrayItem* "]"
+array: OBRACK NL* arrayItem* CBRACK;
+
+// arrayItem -> expression (NL+|COMMA)?
+arrayItem: expression (NL+ | COMMA)?;
+
+// decorator -> "@" decoratorExpression NL
+decorator: AT decoratorExpression NL;
+
+// decoratorExpression -> functionCall | memberExpression "." functionCall
+decoratorExpression: functionCall | expression DOT functionCall;
+
+// functionCall -> IDENTIFIER "(" argumentList? ")"
+functionCall: identifier OPAR (NL? argumentList)? NL? CPAR;
+
+// argumentList -> expression ("," expression)*
+argumentList: expression (COMMA NL? expression)*;
+
+identifier:
+ IDENTIFIER
+ | IMPORT
+ | WITH
+ | AS
+ | METADATA
+ | PARAM
+ | RESOURCE
+ | MODULE
+ | OUTPUT
+ | EXISTING
+ | TYPE
+ | VAR
+ | IF
+ | FOR
+ | IN
+ | TRUE
+ | FALSE
+ | NULL
+ | TARGET_SCOPE
+ | STRING
+ | INT
+ | BOOL
+ | ARRAY
+ | OBJECT;
+
+// multilineString -> "'''" + MULTILINESTRINGCHAR+ + "'''"
+MULTILINE_STRING: '\'\'\'' .*? '\'\'\'';
+
+AT: '@';
+
+COMMA: ',';
+
+OBRACK: '[';
+
+CBRACK: ']';
+
+OPAR: '(';
+
+CPAR: ')';
+
+DOT: '.';
+
+PIPE: '|';
+
+COL: ':' | '::';
+
+ASSIGN: '=';
+
+OBRACE: '{';
+
+CBRACE: '}';
+
+PARAM: 'param';
+
+VAR: 'var';
+
+TRUE: 'true';
+
+FALSE: 'false';
+
+NULL: 'null';
+
+ARRAY: 'array';
+
+OBJECT: 'object';
+
+RESOURCE: 'resource';
+
+OUTPUT: 'output';
+
+TARGET_SCOPE: 'targetScope';
+
+IMPORT: 'import';
+
+WITH: 'with';
+
+AS: 'as';
+
+METADATA: 'metadata';
+
+EXISTING: 'existing';
+
+TYPE: 'type';
+
+MODULE: 'module';
+
+// stringLeftPiece -> "'" STRINGCHAR* "${"
+STRING_LEFT_PIECE: '\'' STRINGCHAR* '${';
+
+// stringMiddlePiece -> "}" STRINGCHAR* "${"
+STRING_MIDDLE_PIECE: '}' STRINGCHAR* '${';
+
+// stringRightPiece -> "}" STRINGCHAR* "'"
+STRING_RIGHT_PIECE: '}' STRINGCHAR* '\'';
+
+// stringComplete -> "'" STRINGCHAR* "'"
+STRING_COMPLETE: '\'' STRINGCHAR* '\'';
+
+STRING: 'string';
+
+INT: 'int';
+
+BOOL: 'bool';
+
+IF: 'if';
+
+FOR: 'for';
+
+IN: 'in';
+
+QMARK: '?';
+
+GT: '>';
+
+GTE: '>=';
+
+LT: '<';
+
+LTE: '<=';
+
+EQ: '==';
+
+NEQ: '!=';
+
+ARROW: '=>';
+
+IDENTIFIER: [a-zA-Z_] [a-zA-Z_0-9]*;
+
+NUMBER: [0-9]+ ('.' [0-9]+)?;
+
+// NL -> ("\n" | "\r")+
+NL: [\r\n]+;
+
+SINGLE_LINE_COMMENT: '//' ~[\r\n]* -> skip;
+
+MULTI_LINE_COMMENT: '/*' .*? '*/' -> skip;
+
+SPACES: [ \t]+ -> skip;
+
+UNKNOWN: .;
+
+fragment STRINGCHAR: ~[\\'\n\r\t$] | ESCAPE;
+
+fragment ESCAPE: '\\' ([\\'nrt$] | 'u{' HEX+ '}');
+
+fragment HEX: [0-9a-fA-F];
\ No newline at end of file
diff --git a/pkg/parser/bicep/antlr/parser/bicep.interp b/pkg/parser/bicep/antlr/parser/bicep.interp
new file mode 100644
index 00000000000..b4bc97baaf6
--- /dev/null
+++ b/pkg/parser/bicep/antlr/parser/bicep.interp
@@ -0,0 +1,154 @@
+token literal names:
+null
+null
+'@'
+','
+'['
+']'
+'('
+')'
+'.'
+'|'
+null
+'='
+'{'
+'}'
+'param'
+'var'
+'true'
+'false'
+'null'
+'array'
+'object'
+'resource'
+'output'
+'targetScope'
+'import'
+'with'
+'as'
+'metadata'
+'existing'
+'type'
+'module'
+null
+null
+null
+null
+'string'
+'int'
+'bool'
+'if'
+'for'
+'in'
+'?'
+'>'
+'>='
+'<'
+'<='
+'=='
+'!='
+'=>'
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+MULTILINE_STRING
+AT
+COMMA
+OBRACK
+CBRACK
+OPAR
+CPAR
+DOT
+PIPE
+COL
+ASSIGN
+OBRACE
+CBRACE
+PARAM
+VAR
+TRUE
+FALSE
+NULL
+ARRAY
+OBJECT
+RESOURCE
+OUTPUT
+TARGET_SCOPE
+IMPORT
+WITH
+AS
+METADATA
+EXISTING
+TYPE
+MODULE
+STRING_LEFT_PIECE
+STRING_MIDDLE_PIECE
+STRING_RIGHT_PIECE
+STRING_COMPLETE
+STRING
+INT
+BOOL
+IF
+FOR
+IN
+QMARK
+GT
+GTE
+LT
+LTE
+EQ
+NEQ
+ARROW
+IDENTIFIER
+NUMBER
+NL
+SINGLE_LINE_COMMENT
+MULTI_LINE_COMMENT
+SPACES
+UNKNOWN
+
+rule names:
+program
+statement
+targetScopeDecl
+importDecl
+metadataDecl
+parameterDecl
+parameterDefaultValue
+typeDecl
+variableDecl
+resourceDecl
+moduleDecl
+outputDecl
+ifCondition
+forExpression
+forVariableBlock
+forBody
+interpString
+expression
+lambdaExpression
+logicCharacter
+primaryExpression
+parenthesizedExpression
+typeExpression
+literalValue
+object
+objectProperty
+array
+arrayItem
+decorator
+decoratorExpression
+functionCall
+argumentList
+identifier
+
+
+atn:
+[4, 1, 55, 436, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 1, 0, 5, 0, 68, 8, 0, 10, 0, 12, 0, 71, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 85, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 5, 3, 93, 8, 3, 10, 3, 12, 3, 96, 9, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 5, 3, 104, 8, 3, 10, 3, 12, 3, 107, 9, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 5, 5, 118, 8, 5, 10, 5, 12, 5, 121, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 127, 8, 5, 1, 5, 1, 5, 1, 5, 3, 5, 132, 8, 5, 3, 5, 134, 8, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 7, 5, 7, 142, 8, 7, 10, 7, 12, 7, 145, 9, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 5, 8, 154, 8, 8, 10, 8, 12, 8, 157, 9, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 5, 9, 166, 8, 9, 10, 9, 12, 9, 169, 9, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 175, 8, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 181, 8, 9, 1, 9, 1, 9, 1, 10, 5, 10, 186, 8, 10, 10, 10, 12, 10, 189, 9, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 198, 8, 10, 1, 10, 1, 10, 1, 11, 5, 11, 203, 8, 11, 10, 11, 12, 11, 206, 9, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 213, 8, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 5, 13, 225, 8, 13, 10, 13, 12, 13, 228, 9, 13, 1, 13, 1, 13, 1, 13, 3, 13, 233, 8, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 5, 13, 240, 8, 13, 10, 13, 12, 13, 243, 9, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 3, 15, 255, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 5, 16, 261, 8, 16, 10, 16, 12, 16, 264, 9, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 270, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 5, 17, 299, 8, 17, 10, 17, 12, 17, 302, 9, 17, 1, 18, 1, 18, 3, 18, 306, 8, 18, 1, 18, 1, 18, 3, 18, 310, 8, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 326, 8, 20, 1, 21, 1, 21, 3, 21, 330, 8, 21, 1, 21, 1, 21, 3, 21, 334, 8, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 345, 8, 23, 1, 24, 1, 24, 4, 24, 349, 8, 24, 11, 24, 12, 24, 350, 1, 24, 1, 24, 4, 24, 355, 8, 24, 11, 24, 12, 24, 356, 5, 24, 359, 8, 24, 10, 24, 12, 24, 362, 9, 24, 3, 24, 364, 8, 24, 1, 24, 1, 24, 1, 25, 1, 25, 3, 25, 370, 8, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 5, 26, 377, 8, 26, 10, 26, 12, 26, 380, 9, 26, 1, 26, 5, 26, 383, 8, 26, 10, 26, 12, 26, 386, 9, 26, 1, 26, 1, 26, 1, 27, 1, 27, 4, 27, 392, 8, 27, 11, 27, 12, 27, 393, 1, 27, 3, 27, 397, 8, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 3, 29, 408, 8, 29, 1, 30, 1, 30, 1, 30, 3, 30, 413, 8, 30, 1, 30, 3, 30, 416, 8, 30, 1, 30, 3, 30, 419, 8, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 3, 31, 426, 8, 31, 1, 31, 5, 31, 429, 8, 31, 10, 31, 12, 31, 432, 9, 31, 1, 32, 1, 32, 1, 32, 0, 1, 34, 33, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 0, 2, 1, 0, 42, 47, 3, 0, 14, 30, 35, 40, 49, 49, 474, 0, 69, 1, 0, 0, 0, 2, 84, 1, 0, 0, 0, 4, 86, 1, 0, 0, 0, 6, 94, 1, 0, 0, 0, 8, 110, 1, 0, 0, 0, 10, 119, 1, 0, 0, 0, 12, 137, 1, 0, 0, 0, 14, 143, 1, 0, 0, 0, 16, 155, 1, 0, 0, 0, 18, 167, 1, 0, 0, 0, 20, 187, 1, 0, 0, 0, 22, 204, 1, 0, 0, 0, 24, 218, 1, 0, 0, 0, 26, 222, 1, 0, 0, 0, 28, 246, 1, 0, 0, 0, 30, 254, 1, 0, 0, 0, 32, 269, 1, 0, 0, 0, 34, 271, 1, 0, 0, 0, 36, 309, 1, 0, 0, 0, 38, 314, 1, 0, 0, 0, 40, 325, 1, 0, 0, 0, 42, 327, 1, 0, 0, 0, 44, 337, 1, 0, 0, 0, 46, 344, 1, 0, 0, 0, 48, 346, 1, 0, 0, 0, 50, 369, 1, 0, 0, 0, 52, 374, 1, 0, 0, 0, 54, 389, 1, 0, 0, 0, 56, 398, 1, 0, 0, 0, 58, 407, 1, 0, 0, 0, 60, 409, 1, 0, 0, 0, 62, 422, 1, 0, 0, 0, 64, 433, 1, 0, 0, 0, 66, 68, 3, 2, 1, 0, 67, 66, 1, 0, 0, 0, 68, 71, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 72, 1, 0, 0, 0, 71, 69, 1, 0, 0, 0, 72, 73, 5, 0, 0, 1, 73, 1, 1, 0, 0, 0, 74, 85, 3, 4, 2, 0, 75, 85, 3, 6, 3, 0, 76, 85, 3, 8, 4, 0, 77, 85, 3, 10, 5, 0, 78, 85, 3, 14, 7, 0, 79, 85, 3, 16, 8, 0, 80, 85, 3, 18, 9, 0, 81, 85, 3, 20, 10, 0, 82, 85, 3, 22, 11, 0, 83, 85, 5, 51, 0, 0, 84, 74, 1, 0, 0, 0, 84, 75, 1, 0, 0, 0, 84, 76, 1, 0, 0, 0, 84, 77, 1, 0, 0, 0, 84, 78, 1, 0, 0, 0, 84, 79, 1, 0, 0, 0, 84, 80, 1, 0, 0, 0, 84, 81, 1, 0, 0, 0, 84, 82, 1, 0, 0, 0, 84, 83, 1, 0, 0, 0, 85, 3, 1, 0, 0, 0, 86, 87, 5, 23, 0, 0, 87, 88, 5, 11, 0, 0, 88, 89, 3, 34, 17, 0, 89, 90, 5, 51, 0, 0, 90, 5, 1, 0, 0, 0, 91, 93, 3, 56, 28, 0, 92, 91, 1, 0, 0, 0, 93, 96, 1, 0, 0, 0, 94, 92, 1, 0, 0, 0, 94, 95, 1, 0, 0, 0, 95, 97, 1, 0, 0, 0, 96, 94, 1, 0, 0, 0, 97, 98, 5, 24, 0, 0, 98, 105, 3, 32, 16, 0, 99, 100, 5, 25, 0, 0, 100, 104, 3, 48, 24, 0, 101, 102, 5, 26, 0, 0, 102, 104, 3, 64, 32, 0, 103, 99, 1, 0, 0, 0, 103, 101, 1, 0, 0, 0, 104, 107, 1, 0, 0, 0, 105, 103, 1, 0, 0, 0, 105, 106, 1, 0, 0, 0, 106, 108, 1, 0, 0, 0, 107, 105, 1, 0, 0, 0, 108, 109, 5, 51, 0, 0, 109, 7, 1, 0, 0, 0, 110, 111, 5, 27, 0, 0, 111, 112, 3, 64, 32, 0, 112, 113, 5, 11, 0, 0, 113, 114, 3, 34, 17, 0, 114, 115, 5, 51, 0, 0, 115, 9, 1, 0, 0, 0, 116, 118, 3, 56, 28, 0, 117, 116, 1, 0, 0, 0, 118, 121, 1, 0, 0, 0, 119, 117, 1, 0, 0, 0, 119, 120, 1, 0, 0, 0, 120, 122, 1, 0, 0, 0, 121, 119, 1, 0, 0, 0, 122, 123, 5, 14, 0, 0, 123, 133, 3, 64, 32, 0, 124, 126, 3, 44, 22, 0, 125, 127, 3, 12, 6, 0, 126, 125, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 134, 1, 0, 0, 0, 128, 129, 5, 21, 0, 0, 129, 131, 3, 32, 16, 0, 130, 132, 3, 12, 6, 0, 131, 130, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 134, 1, 0, 0, 0, 133, 124, 1, 0, 0, 0, 133, 128, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 135, 136, 5, 51, 0, 0, 136, 11, 1, 0, 0, 0, 137, 138, 5, 11, 0, 0, 138, 139, 3, 34, 17, 0, 139, 13, 1, 0, 0, 0, 140, 142, 3, 56, 28, 0, 141, 140, 1, 0, 0, 0, 142, 145, 1, 0, 0, 0, 143, 141, 1, 0, 0, 0, 143, 144, 1, 0, 0, 0, 144, 146, 1, 0, 0, 0, 145, 143, 1, 0, 0, 0, 146, 147, 5, 29, 0, 0, 147, 148, 3, 64, 32, 0, 148, 149, 5, 11, 0, 0, 149, 150, 3, 44, 22, 0, 150, 151, 5, 51, 0, 0, 151, 15, 1, 0, 0, 0, 152, 154, 3, 56, 28, 0, 153, 152, 1, 0, 0, 0, 154, 157, 1, 0, 0, 0, 155, 153, 1, 0, 0, 0, 155, 156, 1, 0, 0, 0, 156, 158, 1, 0, 0, 0, 157, 155, 1, 0, 0, 0, 158, 159, 5, 15, 0, 0, 159, 160, 3, 64, 32, 0, 160, 161, 5, 11, 0, 0, 161, 162, 3, 34, 17, 0, 162, 163, 5, 51, 0, 0, 163, 17, 1, 0, 0, 0, 164, 166, 3, 56, 28, 0, 165, 164, 1, 0, 0, 0, 166, 169, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 167, 168, 1, 0, 0, 0, 168, 170, 1, 0, 0, 0, 169, 167, 1, 0, 0, 0, 170, 171, 5, 21, 0, 0, 171, 172, 3, 64, 32, 0, 172, 174, 3, 32, 16, 0, 173, 175, 5, 28, 0, 0, 174, 173, 1, 0, 0, 0, 174, 175, 1, 0, 0, 0, 175, 176, 1, 0, 0, 0, 176, 180, 5, 11, 0, 0, 177, 181, 3, 24, 12, 0, 178, 181, 3, 48, 24, 0, 179, 181, 3, 26, 13, 0, 180, 177, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 180, 179, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 183, 5, 51, 0, 0, 183, 19, 1, 0, 0, 0, 184, 186, 3, 56, 28, 0, 185, 184, 1, 0, 0, 0, 186, 189, 1, 0, 0, 0, 187, 185, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 190, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 190, 191, 5, 30, 0, 0, 191, 192, 3, 64, 32, 0, 192, 193, 3, 32, 16, 0, 193, 197, 5, 11, 0, 0, 194, 198, 3, 24, 12, 0, 195, 198, 3, 48, 24, 0, 196, 198, 3, 26, 13, 0, 197, 194, 1, 0, 0, 0, 197, 195, 1, 0, 0, 0, 197, 196, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, 200, 5, 51, 0, 0, 200, 21, 1, 0, 0, 0, 201, 203, 3, 56, 28, 0, 202, 201, 1, 0, 0, 0, 203, 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 204, 205, 1, 0, 0, 0, 205, 207, 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 207, 208, 5, 22, 0, 0, 208, 212, 3, 64, 32, 0, 209, 213, 3, 64, 32, 0, 210, 211, 5, 21, 0, 0, 211, 213, 3, 32, 16, 0, 212, 209, 1, 0, 0, 0, 212, 210, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 215, 5, 11, 0, 0, 215, 216, 3, 34, 17, 0, 216, 217, 5, 51, 0, 0, 217, 23, 1, 0, 0, 0, 218, 219, 5, 38, 0, 0, 219, 220, 3, 42, 21, 0, 220, 221, 3, 48, 24, 0, 221, 25, 1, 0, 0, 0, 222, 226, 5, 4, 0, 0, 223, 225, 5, 51, 0, 0, 224, 223, 1, 0, 0, 0, 225, 228, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0, 226, 227, 1, 0, 0, 0, 227, 229, 1, 0, 0, 0, 228, 226, 1, 0, 0, 0, 229, 232, 5, 39, 0, 0, 230, 233, 3, 64, 32, 0, 231, 233, 3, 28, 14, 0, 232, 230, 1, 0, 0, 0, 232, 231, 1, 0, 0, 0, 233, 234, 1, 0, 0, 0, 234, 235, 5, 40, 0, 0, 235, 236, 3, 34, 17, 0, 236, 237, 5, 10, 0, 0, 237, 241, 3, 30, 15, 0, 238, 240, 5, 51, 0, 0, 239, 238, 1, 0, 0, 0, 240, 243, 1, 0, 0, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 244, 1, 0, 0, 0, 243, 241, 1, 0, 0, 0, 244, 245, 5, 5, 0, 0, 245, 27, 1, 0, 0, 0, 246, 247, 5, 6, 0, 0, 247, 248, 3, 64, 32, 0, 248, 249, 5, 3, 0, 0, 249, 250, 3, 64, 32, 0, 250, 251, 5, 7, 0, 0, 251, 29, 1, 0, 0, 0, 252, 255, 3, 34, 17, 0, 253, 255, 3, 24, 12, 0, 254, 252, 1, 0, 0, 0, 254, 253, 1, 0, 0, 0, 255, 31, 1, 0, 0, 0, 256, 262, 5, 31, 0, 0, 257, 258, 3, 34, 17, 0, 258, 259, 5, 32, 0, 0, 259, 261, 1, 0, 0, 0, 260, 257, 1, 0, 0, 0, 261, 264, 1, 0, 0, 0, 262, 260, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 265, 1, 0, 0, 0, 264, 262, 1, 0, 0, 0, 265, 266, 3, 34, 17, 0, 266, 267, 5, 33, 0, 0, 267, 270, 1, 0, 0, 0, 268, 270, 5, 34, 0, 0, 269, 256, 1, 0, 0, 0, 269, 268, 1, 0, 0, 0, 270, 33, 1, 0, 0, 0, 271, 272, 6, 17, -1, 0, 272, 273, 3, 40, 20, 0, 273, 300, 1, 0, 0, 0, 274, 275, 10, 6, 0, 0, 275, 276, 5, 41, 0, 0, 276, 277, 3, 34, 17, 0, 277, 278, 5, 10, 0, 0, 278, 279, 3, 34, 17, 7, 279, 299, 1, 0, 0, 0, 280, 281, 10, 2, 0, 0, 281, 282, 3, 38, 19, 0, 282, 283, 3, 34, 17, 3, 283, 299, 1, 0, 0, 0, 284, 285, 10, 7, 0, 0, 285, 286, 5, 4, 0, 0, 286, 287, 3, 34, 17, 0, 287, 288, 5, 5, 0, 0, 288, 299, 1, 0, 0, 0, 289, 290, 10, 5, 0, 0, 290, 291, 5, 8, 0, 0, 291, 299, 3, 64, 32, 0, 292, 293, 10, 4, 0, 0, 293, 294, 5, 8, 0, 0, 294, 299, 3, 60, 30, 0, 295, 296, 10, 3, 0, 0, 296, 297, 5, 10, 0, 0, 297, 299, 3, 64, 32, 0, 298, 274, 1, 0, 0, 0, 298, 280, 1, 0, 0, 0, 298, 284, 1, 0, 0, 0, 298, 289, 1, 0, 0, 0, 298, 292, 1, 0, 0, 0, 298, 295, 1, 0, 0, 0, 299, 302, 1, 0, 0, 0, 300, 298, 1, 0, 0, 0, 300, 301, 1, 0, 0, 0, 301, 35, 1, 0, 0, 0, 302, 300, 1, 0, 0, 0, 303, 305, 5, 6, 0, 0, 304, 306, 3, 62, 31, 0, 305, 304, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 307, 1, 0, 0, 0, 307, 310, 5, 7, 0, 0, 308, 310, 3, 64, 32, 0, 309, 303, 1, 0, 0, 0, 309, 308, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 312, 5, 48, 0, 0, 312, 313, 3, 34, 17, 0, 313, 37, 1, 0, 0, 0, 314, 315, 7, 0, 0, 0, 315, 39, 1, 0, 0, 0, 316, 326, 3, 46, 23, 0, 317, 326, 3, 60, 30, 0, 318, 326, 3, 32, 16, 0, 319, 326, 5, 1, 0, 0, 320, 326, 3, 52, 26, 0, 321, 326, 3, 48, 24, 0, 322, 326, 3, 26, 13, 0, 323, 326, 3, 42, 21, 0, 324, 326, 3, 36, 18, 0, 325, 316, 1, 0, 0, 0, 325, 317, 1, 0, 0, 0, 325, 318, 1, 0, 0, 0, 325, 319, 1, 0, 0, 0, 325, 320, 1, 0, 0, 0, 325, 321, 1, 0, 0, 0, 325, 322, 1, 0, 0, 0, 325, 323, 1, 0, 0, 0, 325, 324, 1, 0, 0, 0, 326, 41, 1, 0, 0, 0, 327, 329, 5, 6, 0, 0, 328, 330, 5, 51, 0, 0, 329, 328, 1, 0, 0, 0, 329, 330, 1, 0, 0, 0, 330, 331, 1, 0, 0, 0, 331, 333, 3, 34, 17, 0, 332, 334, 5, 51, 0, 0, 333, 332, 1, 0, 0, 0, 333, 334, 1, 0, 0, 0, 334, 335, 1, 0, 0, 0, 335, 336, 5, 7, 0, 0, 336, 43, 1, 0, 0, 0, 337, 338, 3, 64, 32, 0, 338, 45, 1, 0, 0, 0, 339, 345, 5, 50, 0, 0, 340, 345, 5, 16, 0, 0, 341, 345, 5, 17, 0, 0, 342, 345, 5, 18, 0, 0, 343, 345, 3, 64, 32, 0, 344, 339, 1, 0, 0, 0, 344, 340, 1, 0, 0, 0, 344, 341, 1, 0, 0, 0, 344, 342, 1, 0, 0, 0, 344, 343, 1, 0, 0, 0, 345, 47, 1, 0, 0, 0, 346, 363, 5, 12, 0, 0, 347, 349, 5, 51, 0, 0, 348, 347, 1, 0, 0, 0, 349, 350, 1, 0, 0, 0, 350, 348, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 351, 360, 1, 0, 0, 0, 352, 354, 3, 50, 25, 0, 353, 355, 5, 51, 0, 0, 354, 353, 1, 0, 0, 0, 355, 356, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 357, 359, 1, 0, 0, 0, 358, 352, 1, 0, 0, 0, 359, 362, 1, 0, 0, 0, 360, 358, 1, 0, 0, 0, 360, 361, 1, 0, 0, 0, 361, 364, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0, 363, 348, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365, 366, 5, 13, 0, 0, 366, 49, 1, 0, 0, 0, 367, 370, 3, 64, 32, 0, 368, 370, 3, 32, 16, 0, 369, 367, 1, 0, 0, 0, 369, 368, 1, 0, 0, 0, 370, 371, 1, 0, 0, 0, 371, 372, 5, 10, 0, 0, 372, 373, 3, 34, 17, 0, 373, 51, 1, 0, 0, 0, 374, 378, 5, 4, 0, 0, 375, 377, 5, 51, 0, 0, 376, 375, 1, 0, 0, 0, 377, 380, 1, 0, 0, 0, 378, 376, 1, 0, 0, 0, 378, 379, 1, 0, 0, 0, 379, 384, 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 381, 383, 3, 54, 27, 0, 382, 381, 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 387, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 388, 5, 5, 0, 0, 388, 53, 1, 0, 0, 0, 389, 396, 3, 34, 17, 0, 390, 392, 5, 51, 0, 0, 391, 390, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 391, 1, 0, 0, 0, 393, 394, 1, 0, 0, 0, 394, 397, 1, 0, 0, 0, 395, 397, 5, 3, 0, 0, 396, 391, 1, 0, 0, 0, 396, 395, 1, 0, 0, 0, 396, 397, 1, 0, 0, 0, 397, 55, 1, 0, 0, 0, 398, 399, 5, 2, 0, 0, 399, 400, 3, 58, 29, 0, 400, 401, 5, 51, 0, 0, 401, 57, 1, 0, 0, 0, 402, 408, 3, 60, 30, 0, 403, 404, 3, 34, 17, 0, 404, 405, 5, 8, 0, 0, 405, 406, 3, 60, 30, 0, 406, 408, 1, 0, 0, 0, 407, 402, 1, 0, 0, 0, 407, 403, 1, 0, 0, 0, 408, 59, 1, 0, 0, 0, 409, 410, 3, 64, 32, 0, 410, 415, 5, 6, 0, 0, 411, 413, 5, 51, 0, 0, 412, 411, 1, 0, 0, 0, 412, 413, 1, 0, 0, 0, 413, 414, 1, 0, 0, 0, 414, 416, 3, 62, 31, 0, 415, 412, 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 418, 1, 0, 0, 0, 417, 419, 5, 51, 0, 0, 418, 417, 1, 0, 0, 0, 418, 419, 1, 0, 0, 0, 419, 420, 1, 0, 0, 0, 420, 421, 5, 7, 0, 0, 421, 61, 1, 0, 0, 0, 422, 430, 3, 34, 17, 0, 423, 425, 5, 3, 0, 0, 424, 426, 5, 51, 0, 0, 425, 424, 1, 0, 0, 0, 425, 426, 1, 0, 0, 0, 426, 427, 1, 0, 0, 0, 427, 429, 3, 34, 17, 0, 428, 423, 1, 0, 0, 0, 429, 432, 1, 0, 0, 0, 430, 428, 1, 0, 0, 0, 430, 431, 1, 0, 0, 0, 431, 63, 1, 0, 0, 0, 432, 430, 1, 0, 0, 0, 433, 434, 7, 1, 0, 0, 434, 65, 1, 0, 0, 0, 47, 69, 84, 94, 103, 105, 119, 126, 131, 133, 143, 155, 167, 174, 180, 187, 197, 204, 212, 226, 232, 241, 254, 262, 269, 298, 300, 305, 309, 325, 329, 333, 344, 350, 356, 360, 363, 369, 378, 384, 393, 396, 407, 412, 415, 418, 425, 430]
\ No newline at end of file
diff --git a/pkg/parser/bicep/antlr/parser/bicep.tokens b/pkg/parser/bicep/antlr/parser/bicep.tokens
new file mode 100644
index 00000000000..30828ecdad0
--- /dev/null
+++ b/pkg/parser/bicep/antlr/parser/bicep.tokens
@@ -0,0 +1,97 @@
+MULTILINE_STRING=1
+AT=2
+COMMA=3
+OBRACK=4
+CBRACK=5
+OPAR=6
+CPAR=7
+DOT=8
+PIPE=9
+COL=10
+ASSIGN=11
+OBRACE=12
+CBRACE=13
+PARAM=14
+VAR=15
+TRUE=16
+FALSE=17
+NULL=18
+ARRAY=19
+OBJECT=20
+RESOURCE=21
+OUTPUT=22
+TARGET_SCOPE=23
+IMPORT=24
+WITH=25
+AS=26
+METADATA=27
+EXISTING=28
+TYPE=29
+MODULE=30
+STRING_LEFT_PIECE=31
+STRING_MIDDLE_PIECE=32
+STRING_RIGHT_PIECE=33
+STRING_COMPLETE=34
+STRING=35
+INT=36
+BOOL=37
+IF=38
+FOR=39
+IN=40
+QMARK=41
+GT=42
+GTE=43
+LT=44
+LTE=45
+EQ=46
+NEQ=47
+ARROW=48
+IDENTIFIER=49
+NUMBER=50
+NL=51
+SINGLE_LINE_COMMENT=52
+MULTI_LINE_COMMENT=53
+SPACES=54
+UNKNOWN=55
+'@'=2
+','=3
+'['=4
+']'=5
+'('=6
+')'=7
+'.'=8
+'|'=9
+'='=11
+'{'=12
+'}'=13
+'param'=14
+'var'=15
+'true'=16
+'false'=17
+'null'=18
+'array'=19
+'object'=20
+'resource'=21
+'output'=22
+'targetScope'=23
+'import'=24
+'with'=25
+'as'=26
+'metadata'=27
+'existing'=28
+'type'=29
+'module'=30
+'string'=35
+'int'=36
+'bool'=37
+'if'=38
+'for'=39
+'in'=40
+'?'=41
+'>'=42
+'>='=43
+'<'=44
+'<='=45
+'=='=46
+'!='=47
+'=>'=48
diff --git a/pkg/parser/bicep/antlr/parser/bicepLexer.interp b/pkg/parser/bicep/antlr/parser/bicepLexer.interp
new file mode 100644
index 00000000000..910e27c4102
--- /dev/null
+++ b/pkg/parser/bicep/antlr/parser/bicepLexer.interp
@@ -0,0 +1,185 @@
+token literal names:
+null
+null
+'@'
+','
+'['
+']'
+'('
+')'
+'.'
+'|'
+null
+'='
+'{'
+'}'
+'param'
+'var'
+'true'
+'false'
+'null'
+'array'
+'object'
+'resource'
+'output'
+'targetScope'
+'import'
+'with'
+'as'
+'metadata'
+'existing'
+'type'
+'module'
+null
+null
+null
+null
+'string'
+'int'
+'bool'
+'if'
+'for'
+'in'
+'?'
+'>'
+'>='
+'<'
+'<='
+'=='
+'!='
+'=>'
+null
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+MULTILINE_STRING
+AT
+COMMA
+OBRACK
+CBRACK
+OPAR
+CPAR
+DOT
+PIPE
+COL
+ASSIGN
+OBRACE
+CBRACE
+PARAM
+VAR
+TRUE
+FALSE
+NULL
+ARRAY
+OBJECT
+RESOURCE
+OUTPUT
+TARGET_SCOPE
+IMPORT
+WITH
+AS
+METADATA
+EXISTING
+TYPE
+MODULE
+STRING_LEFT_PIECE
+STRING_MIDDLE_PIECE
+STRING_RIGHT_PIECE
+STRING_COMPLETE
+STRING
+INT
+BOOL
+IF
+FOR
+IN
+QMARK
+GT
+GTE
+LT
+LTE
+EQ
+NEQ
+ARROW
+IDENTIFIER
+NUMBER
+NL
+SINGLE_LINE_COMMENT
+MULTI_LINE_COMMENT
+SPACES
+UNKNOWN
+
+rule names:
+MULTILINE_STRING
+AT
+COMMA
+OBRACK
+CBRACK
+OPAR
+CPAR
+DOT
+PIPE
+COL
+ASSIGN
+OBRACE
+CBRACE
+PARAM
+VAR
+TRUE
+FALSE
+NULL
+ARRAY
+OBJECT
+RESOURCE
+OUTPUT
+TARGET_SCOPE
+IMPORT
+WITH
+AS
+METADATA
+EXISTING
+TYPE
+MODULE
+STRING_LEFT_PIECE
+STRING_MIDDLE_PIECE
+STRING_RIGHT_PIECE
+STRING_COMPLETE
+STRING
+INT
+BOOL
+IF
+FOR
+IN
+QMARK
+GT
+GTE
+LT
+LTE
+EQ
+NEQ
+ARROW
+IDENTIFIER
+NUMBER
+NL
+SINGLE_LINE_COMMENT
+MULTI_LINE_COMMENT
+SPACES
+UNKNOWN
+STRINGCHAR
+ESCAPE
+HEX
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[4, 0, 55, 434, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 123, 8, 0, 10, 0, 12, 0, 126, 9, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 3, 9, 151, 8, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 5, 30, 273, 8, 30, 10, 30, 12, 30, 276, 9, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 5, 31, 283, 8, 31, 10, 31, 12, 31, 286, 9, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 5, 32, 293, 8, 32, 10, 32, 12, 32, 296, 9, 32, 1, 32, 1, 32, 1, 33, 1, 33, 5, 33, 302, 8, 33, 10, 33, 12, 33, 305, 9, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 5, 48, 358, 8, 48, 10, 48, 12, 48, 361, 9, 48, 1, 49, 4, 49, 364, 8, 49, 11, 49, 12, 49, 365, 1, 49, 1, 49, 4, 49, 370, 8, 49, 11, 49, 12, 49, 371, 3, 49, 374, 8, 49, 1, 50, 4, 50, 377, 8, 50, 11, 50, 12, 50, 378, 1, 51, 1, 51, 1, 51, 1, 51, 5, 51, 385, 8, 51, 10, 51, 12, 51, 388, 9, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 5, 52, 396, 8, 52, 10, 52, 12, 52, 399, 9, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 4, 53, 407, 8, 53, 11, 53, 12, 53, 408, 1, 53, 1, 53, 1, 54, 1, 54, 1, 55, 1, 55, 3, 55, 417, 8, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 4, 56, 425, 8, 56, 11, 56, 12, 56, 426, 1, 56, 1, 56, 3, 56, 431, 8, 56, 1, 57, 1, 57, 2, 124, 397, 0, 58, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 0, 113, 0, 115, 0, 1, 0, 8, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 1, 0, 48, 57, 2, 0, 10, 10, 13, 13, 2, 0, 9, 9, 32, 32, 5, 0, 9, 10, 13, 13, 36, 36, 39, 39, 92, 92, 6, 0, 36, 36, 39, 39, 92, 92, 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 447, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 1, 117, 1, 0, 0, 0, 3, 131, 1, 0, 0, 0, 5, 133, 1, 0, 0, 0, 7, 135, 1, 0, 0, 0, 9, 137, 1, 0, 0, 0, 11, 139, 1, 0, 0, 0, 13, 141, 1, 0, 0, 0, 15, 143, 1, 0, 0, 0, 17, 145, 1, 0, 0, 0, 19, 150, 1, 0, 0, 0, 21, 152, 1, 0, 0, 0, 23, 154, 1, 0, 0, 0, 25, 156, 1, 0, 0, 0, 27, 158, 1, 0, 0, 0, 29, 164, 1, 0, 0, 0, 31, 168, 1, 0, 0, 0, 33, 173, 1, 0, 0, 0, 35, 179, 1, 0, 0, 0, 37, 184, 1, 0, 0, 0, 39, 190, 1, 0, 0, 0, 41, 197, 1, 0, 0, 0, 43, 206, 1, 0, 0, 0, 45, 213, 1, 0, 0, 0, 47, 225, 1, 0, 0, 0, 49, 232, 1, 0, 0, 0, 51, 237, 1, 0, 0, 0, 53, 240, 1, 0, 0, 0, 55, 249, 1, 0, 0, 0, 57, 258, 1, 0, 0, 0, 59, 263, 1, 0, 0, 0, 61, 270, 1, 0, 0, 0, 63, 280, 1, 0, 0, 0, 65, 290, 1, 0, 0, 0, 67, 299, 1, 0, 0, 0, 69, 308, 1, 0, 0, 0, 71, 315, 1, 0, 0, 0, 73, 319, 1, 0, 0, 0, 75, 324, 1, 0, 0, 0, 77, 327, 1, 0, 0, 0, 79, 331, 1, 0, 0, 0, 81, 334, 1, 0, 0, 0, 83, 336, 1, 0, 0, 0, 85, 338, 1, 0, 0, 0, 87, 341, 1, 0, 0, 0, 89, 343, 1, 0, 0, 0, 91, 346, 1, 0, 0, 0, 93, 349, 1, 0, 0, 0, 95, 352, 1, 0, 0, 0, 97, 355, 1, 0, 0, 0, 99, 363, 1, 0, 0, 0, 101, 376, 1, 0, 0, 0, 103, 380, 1, 0, 0, 0, 105, 391, 1, 0, 0, 0, 107, 406, 1, 0, 0, 0, 109, 412, 1, 0, 0, 0, 111, 416, 1, 0, 0, 0, 113, 418, 1, 0, 0, 0, 115, 432, 1, 0, 0, 0, 117, 118, 5, 39, 0, 0, 118, 119, 5, 39, 0, 0, 119, 120, 5, 39, 0, 0, 120, 124, 1, 0, 0, 0, 121, 123, 9, 0, 0, 0, 122, 121, 1, 0, 0, 0, 123, 126, 1, 0, 0, 0, 124, 125, 1, 0, 0, 0, 124, 122, 1, 0, 0, 0, 125, 127, 1, 0, 0, 0, 126, 124, 1, 0, 0, 0, 127, 128, 5, 39, 0, 0, 128, 129, 5, 39, 0, 0, 129, 130, 5, 39, 0, 0, 130, 2, 1, 0, 0, 0, 131, 132, 5, 64, 0, 0, 132, 4, 1, 0, 0, 0, 133, 134, 5, 44, 0, 0, 134, 6, 1, 0, 0, 0, 135, 136, 5, 91, 0, 0, 136, 8, 1, 0, 0, 0, 137, 138, 5, 93, 0, 0, 138, 10, 1, 0, 0, 0, 139, 140, 5, 40, 0, 0, 140, 12, 1, 0, 0, 0, 141, 142, 5, 41, 0, 0, 142, 14, 1, 0, 0, 0, 143, 144, 5, 46, 0, 0, 144, 16, 1, 0, 0, 0, 145, 146, 5, 124, 0, 0, 146, 18, 1, 0, 0, 0, 147, 151, 5, 58, 0, 0, 148, 149, 5, 58, 0, 0, 149, 151, 5, 58, 0, 0, 150, 147, 1, 0, 0, 0, 150, 148, 1, 0, 0, 0, 151, 20, 1, 0, 0, 0, 152, 153, 5, 61, 0, 0, 153, 22, 1, 0, 0, 0, 154, 155, 5, 123, 0, 0, 155, 24, 1, 0, 0, 0, 156, 157, 5, 125, 0, 0, 157, 26, 1, 0, 0, 0, 158, 159, 5, 112, 0, 0, 159, 160, 5, 97, 0, 0, 160, 161, 5, 114, 0, 0, 161, 162, 5, 97, 0, 0, 162, 163, 5, 109, 0, 0, 163, 28, 1, 0, 0, 0, 164, 165, 5, 118, 0, 0, 165, 166, 5, 97, 0, 0, 166, 167, 5, 114, 0, 0, 167, 30, 1, 0, 0, 0, 168, 169, 5, 116, 0, 0, 169, 170, 5, 114, 0, 0, 170, 171, 5, 117, 0, 0, 171, 172, 5, 101, 0, 0, 172, 32, 1, 0, 0, 0, 173, 174, 5, 102, 0, 0, 174, 175, 5, 97, 0, 0, 175, 176, 5, 108, 0, 0, 176, 177, 5, 115, 0, 0, 177, 178, 5, 101, 0, 0, 178, 34, 1, 0, 0, 0, 179, 180, 5, 110, 0, 0, 180, 181, 5, 117, 0, 0, 181, 182, 5, 108, 0, 0, 182, 183, 5, 108, 0, 0, 183, 36, 1, 0, 0, 0, 184, 185, 5, 97, 0, 0, 185, 186, 5, 114, 0, 0, 186, 187, 5, 114, 0, 0, 187, 188, 5, 97, 0, 0, 188, 189, 5, 121, 0, 0, 189, 38, 1, 0, 0, 0, 190, 191, 5, 111, 0, 0, 191, 192, 5, 98, 0, 0, 192, 193, 5, 106, 0, 0, 193, 194, 5, 101, 0, 0, 194, 195, 5, 99, 0, 0, 195, 196, 5, 116, 0, 0, 196, 40, 1, 0, 0, 0, 197, 198, 5, 114, 0, 0, 198, 199, 5, 101, 0, 0, 199, 200, 5, 115, 0, 0, 200, 201, 5, 111, 0, 0, 201, 202, 5, 117, 0, 0, 202, 203, 5, 114, 0, 0, 203, 204, 5, 99, 0, 0, 204, 205, 5, 101, 0, 0, 205, 42, 1, 0, 0, 0, 206, 207, 5, 111, 0, 0, 207, 208, 5, 117, 0, 0, 208, 209, 5, 116, 0, 0, 209, 210, 5, 112, 0, 0, 210, 211, 5, 117, 0, 0, 211, 212, 5, 116, 0, 0, 212, 44, 1, 0, 0, 0, 213, 214, 5, 116, 0, 0, 214, 215, 5, 97, 0, 0, 215, 216, 5, 114, 0, 0, 216, 217, 5, 103, 0, 0, 217, 218, 5, 101, 0, 0, 218, 219, 5, 116, 0, 0, 219, 220, 5, 83, 0, 0, 220, 221, 5, 99, 0, 0, 221, 222, 5, 111, 0, 0, 222, 223, 5, 112, 0, 0, 223, 224, 5, 101, 0, 0, 224, 46, 1, 0, 0, 0, 225, 226, 5, 105, 0, 0, 226, 227, 5, 109, 0, 0, 227, 228, 5, 112, 0, 0, 228, 229, 5, 111, 0, 0, 229, 230, 5, 114, 0, 0, 230, 231, 5, 116, 0, 0, 231, 48, 1, 0, 0, 0, 232, 233, 5, 119, 0, 0, 233, 234, 5, 105, 0, 0, 234, 235, 5, 116, 0, 0, 235, 236, 5, 104, 0, 0, 236, 50, 1, 0, 0, 0, 237, 238, 5, 97, 0, 0, 238, 239, 5, 115, 0, 0, 239, 52, 1, 0, 0, 0, 240, 241, 5, 109, 0, 0, 241, 242, 5, 101, 0, 0, 242, 243, 5, 116, 0, 0, 243, 244, 5, 97, 0, 0, 244, 245, 5, 100, 0, 0, 245, 246, 5, 97, 0, 0, 246, 247, 5, 116, 0, 0, 247, 248, 5, 97, 0, 0, 248, 54, 1, 0, 0, 0, 249, 250, 5, 101, 0, 0, 250, 251, 5, 120, 0, 0, 251, 252, 5, 105, 0, 0, 252, 253, 5, 115, 0, 0, 253, 254, 5, 116, 0, 0, 254, 255, 5, 105, 0, 0, 255, 256, 5, 110, 0, 0, 256, 257, 5, 103, 0, 0, 257, 56, 1, 0, 0, 0, 258, 259, 5, 116, 0, 0, 259, 260, 5, 121, 0, 0, 260, 261, 5, 112, 0, 0, 261, 262, 5, 101, 0, 0, 262, 58, 1, 0, 0, 0, 263, 264, 5, 109, 0, 0, 264, 265, 5, 111, 0, 0, 265, 266, 5, 100, 0, 0, 266, 267, 5, 117, 0, 0, 267, 268, 5, 108, 0, 0, 268, 269, 5, 101, 0, 0, 269, 60, 1, 0, 0, 0, 270, 274, 5, 39, 0, 0, 271, 273, 3, 111, 55, 0, 272, 271, 1, 0, 0, 0, 273, 276, 1, 0, 0, 0, 274, 272, 1, 0, 0, 0, 274, 275, 1, 0, 0, 0, 275, 277, 1, 0, 0, 0, 276, 274, 1, 0, 0, 0, 277, 278, 5, 36, 0, 0, 278, 279, 5, 123, 0, 0, 279, 62, 1, 0, 0, 0, 280, 284, 5, 125, 0, 0, 281, 283, 3, 111, 55, 0, 282, 281, 1, 0, 0, 0, 283, 286, 1, 0, 0, 0, 284, 282, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287, 1, 0, 0, 0, 286, 284, 1, 0, 0, 0, 287, 288, 5, 36, 0, 0, 288, 289, 5, 123, 0, 0, 289, 64, 1, 0, 0, 0, 290, 294, 5, 125, 0, 0, 291, 293, 3, 111, 55, 0, 292, 291, 1, 0, 0, 0, 293, 296, 1, 0, 0, 0, 294, 292, 1, 0, 0, 0, 294, 295, 1, 0, 0, 0, 295, 297, 1, 0, 0, 0, 296, 294, 1, 0, 0, 0, 297, 298, 5, 39, 0, 0, 298, 66, 1, 0, 0, 0, 299, 303, 5, 39, 0, 0, 300, 302, 3, 111, 55, 0, 301, 300, 1, 0, 0, 0, 302, 305, 1, 0, 0, 0, 303, 301, 1, 0, 0, 0, 303, 304, 1, 0, 0, 0, 304, 306, 1, 0, 0, 0, 305, 303, 1, 0, 0, 0, 306, 307, 5, 39, 0, 0, 307, 68, 1, 0, 0, 0, 308, 309, 5, 115, 0, 0, 309, 310, 5, 116, 0, 0, 310, 311, 5, 114, 0, 0, 311, 312, 5, 105, 0, 0, 312, 313, 5, 110, 0, 0, 313, 314, 5, 103, 0, 0, 314, 70, 1, 0, 0, 0, 315, 316, 5, 105, 0, 0, 316, 317, 5, 110, 0, 0, 317, 318, 5, 116, 0, 0, 318, 72, 1, 0, 0, 0, 319, 320, 5, 98, 0, 0, 320, 321, 5, 111, 0, 0, 321, 322, 5, 111, 0, 0, 322, 323, 5, 108, 0, 0, 323, 74, 1, 0, 0, 0, 324, 325, 5, 105, 0, 0, 325, 326, 5, 102, 0, 0, 326, 76, 1, 0, 0, 0, 327, 328, 5, 102, 0, 0, 328, 329, 5, 111, 0, 0, 329, 330, 5, 114, 0, 0, 330, 78, 1, 0, 0, 0, 331, 332, 5, 105, 0, 0, 332, 333, 5, 110, 0, 0, 333, 80, 1, 0, 0, 0, 334, 335, 5, 63, 0, 0, 335, 82, 1, 0, 0, 0, 336, 337, 5, 62, 0, 0, 337, 84, 1, 0, 0, 0, 338, 339, 5, 62, 0, 0, 339, 340, 5, 61, 0, 0, 340, 86, 1, 0, 0, 0, 341, 342, 5, 60, 0, 0, 342, 88, 1, 0, 0, 0, 343, 344, 5, 60, 0, 0, 344, 345, 5, 61, 0, 0, 345, 90, 1, 0, 0, 0, 346, 347, 5, 61, 0, 0, 347, 348, 5, 61, 0, 0, 348, 92, 1, 0, 0, 0, 349, 350, 5, 33, 0, 0, 350, 351, 5, 61, 0, 0, 351, 94, 1, 0, 0, 0, 352, 353, 5, 61, 0, 0, 353, 354, 5, 62, 0, 0, 354, 96, 1, 0, 0, 0, 355, 359, 7, 0, 0, 0, 356, 358, 7, 1, 0, 0, 357, 356, 1, 0, 0, 0, 358, 361, 1, 0, 0, 0, 359, 357, 1, 0, 0, 0, 359, 360, 1, 0, 0, 0, 360, 98, 1, 0, 0, 0, 361, 359, 1, 0, 0, 0, 362, 364, 7, 2, 0, 0, 363, 362, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365, 363, 1, 0, 0, 0, 365, 366, 1, 0, 0, 0, 366, 373, 1, 0, 0, 0, 367, 369, 5, 46, 0, 0, 368, 370, 7, 2, 0, 0, 369, 368, 1, 0, 0, 0, 370, 371, 1, 0, 0, 0, 371, 369, 1, 0, 0, 0, 371, 372, 1, 0, 0, 0, 372, 374, 1, 0, 0, 0, 373, 367, 1, 0, 0, 0, 373, 374, 1, 0, 0, 0, 374, 100, 1, 0, 0, 0, 375, 377, 7, 3, 0, 0, 376, 375, 1, 0, 0, 0, 377, 378, 1, 0, 0, 0, 378, 376, 1, 0, 0, 0, 378, 379, 1, 0, 0, 0, 379, 102, 1, 0, 0, 0, 380, 381, 5, 47, 0, 0, 381, 382, 5, 47, 0, 0, 382, 386, 1, 0, 0, 0, 383, 385, 8, 3, 0, 0, 384, 383, 1, 0, 0, 0, 385, 388, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 386, 387, 1, 0, 0, 0, 387, 389, 1, 0, 0, 0, 388, 386, 1, 0, 0, 0, 389, 390, 6, 51, 0, 0, 390, 104, 1, 0, 0, 0, 391, 392, 5, 47, 0, 0, 392, 393, 5, 42, 0, 0, 393, 397, 1, 0, 0, 0, 394, 396, 9, 0, 0, 0, 395, 394, 1, 0, 0, 0, 396, 399, 1, 0, 0, 0, 397, 398, 1, 0, 0, 0, 397, 395, 1, 0, 0, 0, 398, 400, 1, 0, 0, 0, 399, 397, 1, 0, 0, 0, 400, 401, 5, 42, 0, 0, 401, 402, 5, 47, 0, 0, 402, 403, 1, 0, 0, 0, 403, 404, 6, 52, 0, 0, 404, 106, 1, 0, 0, 0, 405, 407, 7, 4, 0, 0, 406, 405, 1, 0, 0, 0, 407, 408, 1, 0, 0, 0, 408, 406, 1, 0, 0, 0, 408, 409, 1, 0, 0, 0, 409, 410, 1, 0, 0, 0, 410, 411, 6, 53, 0, 0, 411, 108, 1, 0, 0, 0, 412, 413, 9, 0, 0, 0, 413, 110, 1, 0, 0, 0, 414, 417, 8, 5, 0, 0, 415, 417, 3, 113, 56, 0, 416, 414, 1, 0, 0, 0, 416, 415, 1, 0, 0, 0, 417, 112, 1, 0, 0, 0, 418, 430, 5, 92, 0, 0, 419, 431, 7, 6, 0, 0, 420, 421, 5, 117, 0, 0, 421, 422, 5, 123, 0, 0, 422, 424, 1, 0, 0, 0, 423, 425, 3, 115, 57, 0, 424, 423, 1, 0, 0, 0, 425, 426, 1, 0, 0, 0, 426, 424, 1, 0, 0, 0, 426, 427, 1, 0, 0, 0, 427, 428, 1, 0, 0, 0, 428, 429, 5, 125, 0, 0, 429, 431, 1, 0, 0, 0, 430, 419, 1, 0, 0, 0, 430, 420, 1, 0, 0, 0, 431, 114, 1, 0, 0, 0, 432, 433, 7, 7, 0, 0, 433, 116, 1, 0, 0, 0, 18, 0, 124, 150, 274, 284, 294, 303, 359, 365, 371, 373, 378, 386, 397, 408, 416, 426, 430, 1, 6, 0, 0]
\ No newline at end of file
diff --git a/pkg/parser/bicep/antlr/parser/bicepLexer.tokens b/pkg/parser/bicep/antlr/parser/bicepLexer.tokens
new file mode 100644
index 00000000000..30828ecdad0
--- /dev/null
+++ b/pkg/parser/bicep/antlr/parser/bicepLexer.tokens
@@ -0,0 +1,97 @@
+MULTILINE_STRING=1
+AT=2
+COMMA=3
+OBRACK=4
+CBRACK=5
+OPAR=6
+CPAR=7
+DOT=8
+PIPE=9
+COL=10
+ASSIGN=11
+OBRACE=12
+CBRACE=13
+PARAM=14
+VAR=15
+TRUE=16
+FALSE=17
+NULL=18
+ARRAY=19
+OBJECT=20
+RESOURCE=21
+OUTPUT=22
+TARGET_SCOPE=23
+IMPORT=24
+WITH=25
+AS=26
+METADATA=27
+EXISTING=28
+TYPE=29
+MODULE=30
+STRING_LEFT_PIECE=31
+STRING_MIDDLE_PIECE=32
+STRING_RIGHT_PIECE=33
+STRING_COMPLETE=34
+STRING=35
+INT=36
+BOOL=37
+IF=38
+FOR=39
+IN=40
+QMARK=41
+GT=42
+GTE=43
+LT=44
+LTE=45
+EQ=46
+NEQ=47
+ARROW=48
+IDENTIFIER=49
+NUMBER=50
+NL=51
+SINGLE_LINE_COMMENT=52
+MULTI_LINE_COMMENT=53
+SPACES=54
+UNKNOWN=55
+'@'=2
+','=3
+'['=4
+']'=5
+'('=6
+')'=7
+'.'=8
+'|'=9
+'='=11
+'{'=12
+'}'=13
+'param'=14
+'var'=15
+'true'=16
+'false'=17
+'null'=18
+'array'=19
+'object'=20
+'resource'=21
+'output'=22
+'targetScope'=23
+'import'=24
+'with'=25
+'as'=26
+'metadata'=27
+'existing'=28
+'type'=29
+'module'=30
+'string'=35
+'int'=36
+'bool'=37
+'if'=38
+'for'=39
+'in'=40
+'?'=41
+'>'=42
+'>='=43
+'<'=44
+'<='=45
+'=='=46
+'!='=47
+'=>'=48
diff --git a/pkg/parser/bicep/antlr/parser/bicep_base_visitor.go b/pkg/parser/bicep/antlr/parser/bicep_base_visitor.go
new file mode 100644
index 00000000000..4af209ed435
--- /dev/null
+++ b/pkg/parser/bicep/antlr/parser/bicep_base_visitor.go
@@ -0,0 +1,141 @@
+// Code generated from bicep.g4 by ANTLR 4.13.1. DO NOT EDIT.
+
+package parser // bicep
+
+import "github.com/antlr4-go/antlr/v4"
+
+type BasebicepVisitor struct {
+ *antlr.BaseParseTreeVisitor
+}
+
+func (v *BasebicepVisitor) VisitProgram(ctx *ProgramContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitStatement(ctx *StatementContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitTargetScopeDecl(ctx *TargetScopeDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitImportDecl(ctx *ImportDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitMetadataDecl(ctx *MetadataDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitParameterDecl(ctx *ParameterDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitParameterDefaultValue(ctx *ParameterDefaultValueContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitTypeDecl(ctx *TypeDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitVariableDecl(ctx *VariableDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitResourceDecl(ctx *ResourceDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitModuleDecl(ctx *ModuleDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitOutputDecl(ctx *OutputDeclContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitIfCondition(ctx *IfConditionContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitForExpression(ctx *ForExpressionContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitForVariableBlock(ctx *ForVariableBlockContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitForBody(ctx *ForBodyContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitInterpString(ctx *InterpStringContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitExpression(ctx *ExpressionContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitLambdaExpression(ctx *LambdaExpressionContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitLogicCharacter(ctx *LogicCharacterContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitPrimaryExpression(ctx *PrimaryExpressionContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitParenthesizedExpression(ctx *ParenthesizedExpressionContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitTypeExpression(ctx *TypeExpressionContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitLiteralValue(ctx *LiteralValueContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitObject(ctx *ObjectContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitObjectProperty(ctx *ObjectPropertyContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitArray(ctx *ArrayContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitArrayItem(ctx *ArrayItemContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitDecorator(ctx *DecoratorContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitDecoratorExpression(ctx *DecoratorExpressionContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitFunctionCall(ctx *FunctionCallContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitArgumentList(ctx *ArgumentListContext) interface{} {
+ return v.VisitChildren(ctx)
+}
+
+func (v *BasebicepVisitor) VisitIdentifier(ctx *IdentifierContext) interface{} {
+ return v.VisitChildren(ctx)
+}
diff --git a/pkg/parser/bicep/antlr/parser/bicep_lexer.go b/pkg/parser/bicep/antlr/parser/bicep_lexer.go
new file mode 100644
index 00000000000..814a84be2e2
--- /dev/null
+++ b/pkg/parser/bicep/antlr/parser/bicep_lexer.go
@@ -0,0 +1,362 @@
+// Code generated from bicep.g4 by ANTLR 4.13.1. DO NOT EDIT.
+
+package parser
+
+import (
+ "fmt"
+ "github.com/antlr4-go/antlr/v4"
+ "sync"
+ "unicode"
+)
+
+// Suppress unused import error
+var _ = fmt.Printf
+var _ = sync.Once{}
+var _ = unicode.IsLetter
+
+type bicepLexer struct {
+ *antlr.BaseLexer
+ channelNames []string
+ modeNames []string
+ // TODO: EOF string
+}
+
+var BicepLexerLexerStaticData struct {
+ once sync.Once
+ serializedATN []int32
+ ChannelNames []string
+ ModeNames []string
+ LiteralNames []string
+ SymbolicNames []string
+ RuleNames []string
+ PredictionContextCache *antlr.PredictionContextCache
+ atn *antlr.ATN
+ decisionToDFA []*antlr.DFA
+}
+
+func biceplexerLexerInit() {
+ staticData := &BicepLexerLexerStaticData
+ staticData.ChannelNames = []string{
+ "DEFAULT_TOKEN_CHANNEL", "HIDDEN",
+ }
+ staticData.ModeNames = []string{
+ "DEFAULT_MODE",
+ }
+ staticData.LiteralNames = []string{
+ "", "", "'@'", "','", "'['", "']'", "'('", "')'", "'.'", "'|'", "",
+ "'='", "'{'", "'}'", "'param'", "'var'", "'true'", "'false'", "'null'",
+ "'array'", "'object'", "'resource'", "'output'", "'targetScope'", "'import'",
+ "'with'", "'as'", "'metadata'", "'existing'", "'type'", "'module'",
+ "", "", "", "", "'string'", "'int'", "'bool'", "'if'", "'for'", "'in'",
+ "'?'", "'>'", "'>='", "'<'", "'<='", "'=='", "'!='", "'=>'",
+ }
+ staticData.SymbolicNames = []string{
+ "", "MULTILINE_STRING", "AT", "COMMA", "OBRACK", "CBRACK", "OPAR", "CPAR",
+ "DOT", "PIPE", "COL", "ASSIGN", "OBRACE", "CBRACE", "PARAM", "VAR",
+ "TRUE", "FALSE", "NULL", "ARRAY", "OBJECT", "RESOURCE", "OUTPUT", "TARGET_SCOPE",
+ "IMPORT", "WITH", "AS", "METADATA", "EXISTING", "TYPE", "MODULE", "STRING_LEFT_PIECE",
+ "STRING_MIDDLE_PIECE", "STRING_RIGHT_PIECE", "STRING_COMPLETE", "STRING",
+ "INT", "BOOL", "IF", "FOR", "IN", "QMARK", "GT", "GTE", "LT", "LTE",
+ "EQ", "NEQ", "ARROW", "IDENTIFIER", "NUMBER", "NL", "SINGLE_LINE_COMMENT",
+ "MULTI_LINE_COMMENT", "SPACES", "UNKNOWN",
+ }
+ staticData.RuleNames = []string{
+ "MULTILINE_STRING", "AT", "COMMA", "OBRACK", "CBRACK", "OPAR", "CPAR",
+ "DOT", "PIPE", "COL", "ASSIGN", "OBRACE", "CBRACE", "PARAM", "VAR",
+ "TRUE", "FALSE", "NULL", "ARRAY", "OBJECT", "RESOURCE", "OUTPUT", "TARGET_SCOPE",
+ "IMPORT", "WITH", "AS", "METADATA", "EXISTING", "TYPE", "MODULE", "STRING_LEFT_PIECE",
+ "STRING_MIDDLE_PIECE", "STRING_RIGHT_PIECE", "STRING_COMPLETE", "STRING",
+ "INT", "BOOL", "IF", "FOR", "IN", "QMARK", "GT", "GTE", "LT", "LTE",
+ "EQ", "NEQ", "ARROW", "IDENTIFIER", "NUMBER", "NL", "SINGLE_LINE_COMMENT",
+ "MULTI_LINE_COMMENT", "SPACES", "UNKNOWN", "STRINGCHAR", "ESCAPE", "HEX",
+ }
+ staticData.PredictionContextCache = antlr.NewPredictionContextCache()
+ staticData.serializedATN = []int32{
+ 4, 0, 55, 434, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2,
+ 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2,
+ 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15,
+ 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7,
+ 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25,
+ 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2,
+ 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36,
+ 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7,
+ 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46,
+ 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2,
+ 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57,
+ 7, 57, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 123, 8, 0, 10, 0, 12, 0, 126,
+ 9, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4,
+ 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9,
+ 3, 9, 151, 8, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13,
+ 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1,
+ 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17,
+ 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1,
+ 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20,
+ 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1,
+ 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22,
+ 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1,
+ 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26,
+ 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1,
+ 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29,
+ 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 5, 30, 273, 8, 30, 10,
+ 30, 12, 30, 276, 9, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 5, 31, 283,
+ 8, 31, 10, 31, 12, 31, 286, 9, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 5,
+ 32, 293, 8, 32, 10, 32, 12, 32, 296, 9, 32, 1, 32, 1, 32, 1, 33, 1, 33,
+ 5, 33, 302, 8, 33, 10, 33, 12, 33, 305, 9, 33, 1, 33, 1, 33, 1, 34, 1,
+ 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36,
+ 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1,
+ 38, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42,
+ 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1,
+ 46, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 5, 48, 358, 8, 48, 10, 48, 12, 48,
+ 361, 9, 48, 1, 49, 4, 49, 364, 8, 49, 11, 49, 12, 49, 365, 1, 49, 1, 49,
+ 4, 49, 370, 8, 49, 11, 49, 12, 49, 371, 3, 49, 374, 8, 49, 1, 50, 4, 50,
+ 377, 8, 50, 11, 50, 12, 50, 378, 1, 51, 1, 51, 1, 51, 1, 51, 5, 51, 385,
+ 8, 51, 10, 51, 12, 51, 388, 9, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1,
+ 52, 5, 52, 396, 8, 52, 10, 52, 12, 52, 399, 9, 52, 1, 52, 1, 52, 1, 52,
+ 1, 52, 1, 52, 1, 53, 4, 53, 407, 8, 53, 11, 53, 12, 53, 408, 1, 53, 1,
+ 53, 1, 54, 1, 54, 1, 55, 1, 55, 3, 55, 417, 8, 55, 1, 56, 1, 56, 1, 56,
+ 1, 56, 1, 56, 1, 56, 4, 56, 425, 8, 56, 11, 56, 12, 56, 426, 1, 56, 1,
+ 56, 3, 56, 431, 8, 56, 1, 57, 1, 57, 2, 124, 397, 0, 58, 1, 1, 3, 2, 5,
+ 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25,
+ 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43,
+ 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61,
+ 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79,
+ 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97,
+ 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 0, 113, 0,
+ 115, 0, 1, 0, 8, 3, 0, 65, 90, 95, 95, 97, 122, 4, 0, 48, 57, 65, 90, 95,
+ 95, 97, 122, 1, 0, 48, 57, 2, 0, 10, 10, 13, 13, 2, 0, 9, 9, 32, 32, 5,
+ 0, 9, 10, 13, 13, 36, 36, 39, 39, 92, 92, 6, 0, 36, 36, 39, 39, 92, 92,
+ 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 447, 0, 1,
+ 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9,
+ 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0,
+ 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0,
+ 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0,
+ 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0,
+ 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1,
+ 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55,
+ 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0,
+ 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0,
+ 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0,
+ 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0,
+ 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1,
+ 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101,
+ 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0,
+ 0, 109, 1, 0, 0, 0, 1, 117, 1, 0, 0, 0, 3, 131, 1, 0, 0, 0, 5, 133, 1,
+ 0, 0, 0, 7, 135, 1, 0, 0, 0, 9, 137, 1, 0, 0, 0, 11, 139, 1, 0, 0, 0, 13,
+ 141, 1, 0, 0, 0, 15, 143, 1, 0, 0, 0, 17, 145, 1, 0, 0, 0, 19, 150, 1,
+ 0, 0, 0, 21, 152, 1, 0, 0, 0, 23, 154, 1, 0, 0, 0, 25, 156, 1, 0, 0, 0,
+ 27, 158, 1, 0, 0, 0, 29, 164, 1, 0, 0, 0, 31, 168, 1, 0, 0, 0, 33, 173,
+ 1, 0, 0, 0, 35, 179, 1, 0, 0, 0, 37, 184, 1, 0, 0, 0, 39, 190, 1, 0, 0,
+ 0, 41, 197, 1, 0, 0, 0, 43, 206, 1, 0, 0, 0, 45, 213, 1, 0, 0, 0, 47, 225,
+ 1, 0, 0, 0, 49, 232, 1, 0, 0, 0, 51, 237, 1, 0, 0, 0, 53, 240, 1, 0, 0,
+ 0, 55, 249, 1, 0, 0, 0, 57, 258, 1, 0, 0, 0, 59, 263, 1, 0, 0, 0, 61, 270,
+ 1, 0, 0, 0, 63, 280, 1, 0, 0, 0, 65, 290, 1, 0, 0, 0, 67, 299, 1, 0, 0,
+ 0, 69, 308, 1, 0, 0, 0, 71, 315, 1, 0, 0, 0, 73, 319, 1, 0, 0, 0, 75, 324,
+ 1, 0, 0, 0, 77, 327, 1, 0, 0, 0, 79, 331, 1, 0, 0, 0, 81, 334, 1, 0, 0,
+ 0, 83, 336, 1, 0, 0, 0, 85, 338, 1, 0, 0, 0, 87, 341, 1, 0, 0, 0, 89, 343,
+ 1, 0, 0, 0, 91, 346, 1, 0, 0, 0, 93, 349, 1, 0, 0, 0, 95, 352, 1, 0, 0,
+ 0, 97, 355, 1, 0, 0, 0, 99, 363, 1, 0, 0, 0, 101, 376, 1, 0, 0, 0, 103,
+ 380, 1, 0, 0, 0, 105, 391, 1, 0, 0, 0, 107, 406, 1, 0, 0, 0, 109, 412,
+ 1, 0, 0, 0, 111, 416, 1, 0, 0, 0, 113, 418, 1, 0, 0, 0, 115, 432, 1, 0,
+ 0, 0, 117, 118, 5, 39, 0, 0, 118, 119, 5, 39, 0, 0, 119, 120, 5, 39, 0,
+ 0, 120, 124, 1, 0, 0, 0, 121, 123, 9, 0, 0, 0, 122, 121, 1, 0, 0, 0, 123,
+ 126, 1, 0, 0, 0, 124, 125, 1, 0, 0, 0, 124, 122, 1, 0, 0, 0, 125, 127,
+ 1, 0, 0, 0, 126, 124, 1, 0, 0, 0, 127, 128, 5, 39, 0, 0, 128, 129, 5, 39,
+ 0, 0, 129, 130, 5, 39, 0, 0, 130, 2, 1, 0, 0, 0, 131, 132, 5, 64, 0, 0,
+ 132, 4, 1, 0, 0, 0, 133, 134, 5, 44, 0, 0, 134, 6, 1, 0, 0, 0, 135, 136,
+ 5, 91, 0, 0, 136, 8, 1, 0, 0, 0, 137, 138, 5, 93, 0, 0, 138, 10, 1, 0,
+ 0, 0, 139, 140, 5, 40, 0, 0, 140, 12, 1, 0, 0, 0, 141, 142, 5, 41, 0, 0,
+ 142, 14, 1, 0, 0, 0, 143, 144, 5, 46, 0, 0, 144, 16, 1, 0, 0, 0, 145, 146,
+ 5, 124, 0, 0, 146, 18, 1, 0, 0, 0, 147, 151, 5, 58, 0, 0, 148, 149, 5,
+ 58, 0, 0, 149, 151, 5, 58, 0, 0, 150, 147, 1, 0, 0, 0, 150, 148, 1, 0,
+ 0, 0, 151, 20, 1, 0, 0, 0, 152, 153, 5, 61, 0, 0, 153, 22, 1, 0, 0, 0,
+ 154, 155, 5, 123, 0, 0, 155, 24, 1, 0, 0, 0, 156, 157, 5, 125, 0, 0, 157,
+ 26, 1, 0, 0, 0, 158, 159, 5, 112, 0, 0, 159, 160, 5, 97, 0, 0, 160, 161,
+ 5, 114, 0, 0, 161, 162, 5, 97, 0, 0, 162, 163, 5, 109, 0, 0, 163, 28, 1,
+ 0, 0, 0, 164, 165, 5, 118, 0, 0, 165, 166, 5, 97, 0, 0, 166, 167, 5, 114,
+ 0, 0, 167, 30, 1, 0, 0, 0, 168, 169, 5, 116, 0, 0, 169, 170, 5, 114, 0,
+ 0, 170, 171, 5, 117, 0, 0, 171, 172, 5, 101, 0, 0, 172, 32, 1, 0, 0, 0,
+ 173, 174, 5, 102, 0, 0, 174, 175, 5, 97, 0, 0, 175, 176, 5, 108, 0, 0,
+ 176, 177, 5, 115, 0, 0, 177, 178, 5, 101, 0, 0, 178, 34, 1, 0, 0, 0, 179,
+ 180, 5, 110, 0, 0, 180, 181, 5, 117, 0, 0, 181, 182, 5, 108, 0, 0, 182,
+ 183, 5, 108, 0, 0, 183, 36, 1, 0, 0, 0, 184, 185, 5, 97, 0, 0, 185, 186,
+ 5, 114, 0, 0, 186, 187, 5, 114, 0, 0, 187, 188, 5, 97, 0, 0, 188, 189,
+ 5, 121, 0, 0, 189, 38, 1, 0, 0, 0, 190, 191, 5, 111, 0, 0, 191, 192, 5,
+ 98, 0, 0, 192, 193, 5, 106, 0, 0, 193, 194, 5, 101, 0, 0, 194, 195, 5,
+ 99, 0, 0, 195, 196, 5, 116, 0, 0, 196, 40, 1, 0, 0, 0, 197, 198, 5, 114,
+ 0, 0, 198, 199, 5, 101, 0, 0, 199, 200, 5, 115, 0, 0, 200, 201, 5, 111,
+ 0, 0, 201, 202, 5, 117, 0, 0, 202, 203, 5, 114, 0, 0, 203, 204, 5, 99,
+ 0, 0, 204, 205, 5, 101, 0, 0, 205, 42, 1, 0, 0, 0, 206, 207, 5, 111, 0,
+ 0, 207, 208, 5, 117, 0, 0, 208, 209, 5, 116, 0, 0, 209, 210, 5, 112, 0,
+ 0, 210, 211, 5, 117, 0, 0, 211, 212, 5, 116, 0, 0, 212, 44, 1, 0, 0, 0,
+ 213, 214, 5, 116, 0, 0, 214, 215, 5, 97, 0, 0, 215, 216, 5, 114, 0, 0,
+ 216, 217, 5, 103, 0, 0, 217, 218, 5, 101, 0, 0, 218, 219, 5, 116, 0, 0,
+ 219, 220, 5, 83, 0, 0, 220, 221, 5, 99, 0, 0, 221, 222, 5, 111, 0, 0, 222,
+ 223, 5, 112, 0, 0, 223, 224, 5, 101, 0, 0, 224, 46, 1, 0, 0, 0, 225, 226,
+ 5, 105, 0, 0, 226, 227, 5, 109, 0, 0, 227, 228, 5, 112, 0, 0, 228, 229,
+ 5, 111, 0, 0, 229, 230, 5, 114, 0, 0, 230, 231, 5, 116, 0, 0, 231, 48,
+ 1, 0, 0, 0, 232, 233, 5, 119, 0, 0, 233, 234, 5, 105, 0, 0, 234, 235, 5,
+ 116, 0, 0, 235, 236, 5, 104, 0, 0, 236, 50, 1, 0, 0, 0, 237, 238, 5, 97,
+ 0, 0, 238, 239, 5, 115, 0, 0, 239, 52, 1, 0, 0, 0, 240, 241, 5, 109, 0,
+ 0, 241, 242, 5, 101, 0, 0, 242, 243, 5, 116, 0, 0, 243, 244, 5, 97, 0,
+ 0, 244, 245, 5, 100, 0, 0, 245, 246, 5, 97, 0, 0, 246, 247, 5, 116, 0,
+ 0, 247, 248, 5, 97, 0, 0, 248, 54, 1, 0, 0, 0, 249, 250, 5, 101, 0, 0,
+ 250, 251, 5, 120, 0, 0, 251, 252, 5, 105, 0, 0, 252, 253, 5, 115, 0, 0,
+ 253, 254, 5, 116, 0, 0, 254, 255, 5, 105, 0, 0, 255, 256, 5, 110, 0, 0,
+ 256, 257, 5, 103, 0, 0, 257, 56, 1, 0, 0, 0, 258, 259, 5, 116, 0, 0, 259,
+ 260, 5, 121, 0, 0, 260, 261, 5, 112, 0, 0, 261, 262, 5, 101, 0, 0, 262,
+ 58, 1, 0, 0, 0, 263, 264, 5, 109, 0, 0, 264, 265, 5, 111, 0, 0, 265, 266,
+ 5, 100, 0, 0, 266, 267, 5, 117, 0, 0, 267, 268, 5, 108, 0, 0, 268, 269,
+ 5, 101, 0, 0, 269, 60, 1, 0, 0, 0, 270, 274, 5, 39, 0, 0, 271, 273, 3,
+ 111, 55, 0, 272, 271, 1, 0, 0, 0, 273, 276, 1, 0, 0, 0, 274, 272, 1, 0,
+ 0, 0, 274, 275, 1, 0, 0, 0, 275, 277, 1, 0, 0, 0, 276, 274, 1, 0, 0, 0,
+ 277, 278, 5, 36, 0, 0, 278, 279, 5, 123, 0, 0, 279, 62, 1, 0, 0, 0, 280,
+ 284, 5, 125, 0, 0, 281, 283, 3, 111, 55, 0, 282, 281, 1, 0, 0, 0, 283,
+ 286, 1, 0, 0, 0, 284, 282, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 287,
+ 1, 0, 0, 0, 286, 284, 1, 0, 0, 0, 287, 288, 5, 36, 0, 0, 288, 289, 5, 123,
+ 0, 0, 289, 64, 1, 0, 0, 0, 290, 294, 5, 125, 0, 0, 291, 293, 3, 111, 55,
+ 0, 292, 291, 1, 0, 0, 0, 293, 296, 1, 0, 0, 0, 294, 292, 1, 0, 0, 0, 294,
+ 295, 1, 0, 0, 0, 295, 297, 1, 0, 0, 0, 296, 294, 1, 0, 0, 0, 297, 298,
+ 5, 39, 0, 0, 298, 66, 1, 0, 0, 0, 299, 303, 5, 39, 0, 0, 300, 302, 3, 111,
+ 55, 0, 301, 300, 1, 0, 0, 0, 302, 305, 1, 0, 0, 0, 303, 301, 1, 0, 0, 0,
+ 303, 304, 1, 0, 0, 0, 304, 306, 1, 0, 0, 0, 305, 303, 1, 0, 0, 0, 306,
+ 307, 5, 39, 0, 0, 307, 68, 1, 0, 0, 0, 308, 309, 5, 115, 0, 0, 309, 310,
+ 5, 116, 0, 0, 310, 311, 5, 114, 0, 0, 311, 312, 5, 105, 0, 0, 312, 313,
+ 5, 110, 0, 0, 313, 314, 5, 103, 0, 0, 314, 70, 1, 0, 0, 0, 315, 316, 5,
+ 105, 0, 0, 316, 317, 5, 110, 0, 0, 317, 318, 5, 116, 0, 0, 318, 72, 1,
+ 0, 0, 0, 319, 320, 5, 98, 0, 0, 320, 321, 5, 111, 0, 0, 321, 322, 5, 111,
+ 0, 0, 322, 323, 5, 108, 0, 0, 323, 74, 1, 0, 0, 0, 324, 325, 5, 105, 0,
+ 0, 325, 326, 5, 102, 0, 0, 326, 76, 1, 0, 0, 0, 327, 328, 5, 102, 0, 0,
+ 328, 329, 5, 111, 0, 0, 329, 330, 5, 114, 0, 0, 330, 78, 1, 0, 0, 0, 331,
+ 332, 5, 105, 0, 0, 332, 333, 5, 110, 0, 0, 333, 80, 1, 0, 0, 0, 334, 335,
+ 5, 63, 0, 0, 335, 82, 1, 0, 0, 0, 336, 337, 5, 62, 0, 0, 337, 84, 1, 0,
+ 0, 0, 338, 339, 5, 62, 0, 0, 339, 340, 5, 61, 0, 0, 340, 86, 1, 0, 0, 0,
+ 341, 342, 5, 60, 0, 0, 342, 88, 1, 0, 0, 0, 343, 344, 5, 60, 0, 0, 344,
+ 345, 5, 61, 0, 0, 345, 90, 1, 0, 0, 0, 346, 347, 5, 61, 0, 0, 347, 348,
+ 5, 61, 0, 0, 348, 92, 1, 0, 0, 0, 349, 350, 5, 33, 0, 0, 350, 351, 5, 61,
+ 0, 0, 351, 94, 1, 0, 0, 0, 352, 353, 5, 61, 0, 0, 353, 354, 5, 62, 0, 0,
+ 354, 96, 1, 0, 0, 0, 355, 359, 7, 0, 0, 0, 356, 358, 7, 1, 0, 0, 357, 356,
+ 1, 0, 0, 0, 358, 361, 1, 0, 0, 0, 359, 357, 1, 0, 0, 0, 359, 360, 1, 0,
+ 0, 0, 360, 98, 1, 0, 0, 0, 361, 359, 1, 0, 0, 0, 362, 364, 7, 2, 0, 0,
+ 363, 362, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365, 363, 1, 0, 0, 0, 365,
+ 366, 1, 0, 0, 0, 366, 373, 1, 0, 0, 0, 367, 369, 5, 46, 0, 0, 368, 370,
+ 7, 2, 0, 0, 369, 368, 1, 0, 0, 0, 370, 371, 1, 0, 0, 0, 371, 369, 1, 0,
+ 0, 0, 371, 372, 1, 0, 0, 0, 372, 374, 1, 0, 0, 0, 373, 367, 1, 0, 0, 0,
+ 373, 374, 1, 0, 0, 0, 374, 100, 1, 0, 0, 0, 375, 377, 7, 3, 0, 0, 376,
+ 375, 1, 0, 0, 0, 377, 378, 1, 0, 0, 0, 378, 376, 1, 0, 0, 0, 378, 379,
+ 1, 0, 0, 0, 379, 102, 1, 0, 0, 0, 380, 381, 5, 47, 0, 0, 381, 382, 5, 47,
+ 0, 0, 382, 386, 1, 0, 0, 0, 383, 385, 8, 3, 0, 0, 384, 383, 1, 0, 0, 0,
+ 385, 388, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 386, 387, 1, 0, 0, 0, 387,
+ 389, 1, 0, 0, 0, 388, 386, 1, 0, 0, 0, 389, 390, 6, 51, 0, 0, 390, 104,
+ 1, 0, 0, 0, 391, 392, 5, 47, 0, 0, 392, 393, 5, 42, 0, 0, 393, 397, 1,
+ 0, 0, 0, 394, 396, 9, 0, 0, 0, 395, 394, 1, 0, 0, 0, 396, 399, 1, 0, 0,
+ 0, 397, 398, 1, 0, 0, 0, 397, 395, 1, 0, 0, 0, 398, 400, 1, 0, 0, 0, 399,
+ 397, 1, 0, 0, 0, 400, 401, 5, 42, 0, 0, 401, 402, 5, 47, 0, 0, 402, 403,
+ 1, 0, 0, 0, 403, 404, 6, 52, 0, 0, 404, 106, 1, 0, 0, 0, 405, 407, 7, 4,
+ 0, 0, 406, 405, 1, 0, 0, 0, 407, 408, 1, 0, 0, 0, 408, 406, 1, 0, 0, 0,
+ 408, 409, 1, 0, 0, 0, 409, 410, 1, 0, 0, 0, 410, 411, 6, 53, 0, 0, 411,
+ 108, 1, 0, 0, 0, 412, 413, 9, 0, 0, 0, 413, 110, 1, 0, 0, 0, 414, 417,
+ 8, 5, 0, 0, 415, 417, 3, 113, 56, 0, 416, 414, 1, 0, 0, 0, 416, 415, 1,
+ 0, 0, 0, 417, 112, 1, 0, 0, 0, 418, 430, 5, 92, 0, 0, 419, 431, 7, 6, 0,
+ 0, 420, 421, 5, 117, 0, 0, 421, 422, 5, 123, 0, 0, 422, 424, 1, 0, 0, 0,
+ 423, 425, 3, 115, 57, 0, 424, 423, 1, 0, 0, 0, 425, 426, 1, 0, 0, 0, 426,
+ 424, 1, 0, 0, 0, 426, 427, 1, 0, 0, 0, 427, 428, 1, 0, 0, 0, 428, 429,
+ 5, 125, 0, 0, 429, 431, 1, 0, 0, 0, 430, 419, 1, 0, 0, 0, 430, 420, 1,
+ 0, 0, 0, 431, 114, 1, 0, 0, 0, 432, 433, 7, 7, 0, 0, 433, 116, 1, 0, 0,
+ 0, 18, 0, 124, 150, 274, 284, 294, 303, 359, 365, 371, 373, 378, 386, 397,
+ 408, 416, 426, 430, 1, 6, 0, 0,
+ }
+ deserializer := antlr.NewATNDeserializer(nil)
+ staticData.atn = deserializer.Deserialize(staticData.serializedATN)
+ atn := staticData.atn
+ staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState))
+ decisionToDFA := staticData.decisionToDFA
+ for index, state := range atn.DecisionToState {
+ decisionToDFA[index] = antlr.NewDFA(state, index)
+ }
+}
+
+// bicepLexerInit initializes any static state used to implement bicepLexer. By default the
+// static state used to implement the lexer is lazily initialized during the first call to
+// NewbicepLexer(). You can call this function if you wish to initialize the static state ahead
+// of time.
+func BicepLexerInit() {
+ staticData := &BicepLexerLexerStaticData
+ staticData.once.Do(biceplexerLexerInit)
+}
+
+// NewbicepLexer produces a new lexer instance for the optional input antlr.CharStream.
+func NewbicepLexer(input antlr.CharStream) *bicepLexer {
+ BicepLexerInit()
+ l := new(bicepLexer)
+ l.BaseLexer = antlr.NewBaseLexer(input)
+ staticData := &BicepLexerLexerStaticData
+ l.Interpreter = antlr.NewLexerATNSimulator(l, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache)
+ l.channelNames = staticData.ChannelNames
+ l.modeNames = staticData.ModeNames
+ l.RuleNames = staticData.RuleNames
+ l.LiteralNames = staticData.LiteralNames
+ l.SymbolicNames = staticData.SymbolicNames
+ l.GrammarFileName = "bicep.g4"
+ // TODO: l.EOF = antlr.TokenEOF
+
+ return l
+}
+
+// bicepLexer tokens.
+const (
+ bicepLexerMULTILINE_STRING = 1
+ bicepLexerAT = 2
+ bicepLexerCOMMA = 3
+ bicepLexerOBRACK = 4
+ bicepLexerCBRACK = 5
+ bicepLexerOPAR = 6
+ bicepLexerCPAR = 7
+ bicepLexerDOT = 8
+ bicepLexerPIPE = 9
+ bicepLexerCOL = 10
+ bicepLexerASSIGN = 11
+ bicepLexerOBRACE = 12
+ bicepLexerCBRACE = 13
+ bicepLexerPARAM = 14
+ bicepLexerVAR = 15
+ bicepLexerTRUE = 16
+ bicepLexerFALSE = 17
+ bicepLexerNULL = 18
+ bicepLexerARRAY = 19
+ bicepLexerOBJECT = 20
+ bicepLexerRESOURCE = 21
+ bicepLexerOUTPUT = 22
+ bicepLexerTARGET_SCOPE = 23
+ bicepLexerIMPORT = 24
+ bicepLexerWITH = 25
+ bicepLexerAS = 26
+ bicepLexerMETADATA = 27
+ bicepLexerEXISTING = 28
+ bicepLexerTYPE = 29
+ bicepLexerMODULE = 30
+ bicepLexerSTRING_LEFT_PIECE = 31
+ bicepLexerSTRING_MIDDLE_PIECE = 32
+ bicepLexerSTRING_RIGHT_PIECE = 33
+ bicepLexerSTRING_COMPLETE = 34
+ bicepLexerSTRING = 35
+ bicepLexerINT = 36
+ bicepLexerBOOL = 37
+ bicepLexerIF = 38
+ bicepLexerFOR = 39
+ bicepLexerIN = 40
+ bicepLexerQMARK = 41
+ bicepLexerGT = 42
+ bicepLexerGTE = 43
+ bicepLexerLT = 44
+ bicepLexerLTE = 45
+ bicepLexerEQ = 46
+ bicepLexerNEQ = 47
+ bicepLexerARROW = 48
+ bicepLexerIDENTIFIER = 49
+ bicepLexerNUMBER = 50
+ bicepLexerNL = 51
+ bicepLexerSINGLE_LINE_COMMENT = 52
+ bicepLexerMULTI_LINE_COMMENT = 53
+ bicepLexerSPACES = 54
+ bicepLexerUNKNOWN = 55
+)
diff --git a/pkg/parser/bicep/antlr/parser/bicep_parser.go b/pkg/parser/bicep/antlr/parser/bicep_parser.go
new file mode 100644
index 00000000000..b2fcf1bc93b
--- /dev/null
+++ b/pkg/parser/bicep/antlr/parser/bicep_parser.go
@@ -0,0 +1,7863 @@
+// Code generated from bicep.g4 by ANTLR 4.13.1. DO NOT EDIT.
+
+package parser // bicep
+
+import (
+ "fmt"
+ "strconv"
+ "sync"
+
+ "github.com/antlr4-go/antlr/v4"
+)
+
+// Suppress unused import errors
+var _ = fmt.Printf
+var _ = strconv.Itoa
+var _ = sync.Once{}
+
+type bicepParser struct {
+ *antlr.BaseParser
+}
+
+var BicepParserStaticData struct {
+ once sync.Once
+ serializedATN []int32
+ LiteralNames []string
+ SymbolicNames []string
+ RuleNames []string
+ PredictionContextCache *antlr.PredictionContextCache
+ atn *antlr.ATN
+ decisionToDFA []*antlr.DFA
+}
+
+func bicepParserInit() {
+ staticData := &BicepParserStaticData
+ staticData.LiteralNames = []string{
+ "", "", "'@'", "','", "'['", "']'", "'('", "')'", "'.'", "'|'", "",
+ "'='", "'{'", "'}'", "'param'", "'var'", "'true'", "'false'", "'null'",
+ "'array'", "'object'", "'resource'", "'output'", "'targetScope'", "'import'",
+ "'with'", "'as'", "'metadata'", "'existing'", "'type'", "'module'",
+ "", "", "", "", "'string'", "'int'", "'bool'", "'if'", "'for'", "'in'",
+ "'?'", "'>'", "'>='", "'<'", "'<='", "'=='", "'!='", "'=>'",
+ }
+ staticData.SymbolicNames = []string{
+ "", "MULTILINE_STRING", "AT", "COMMA", "OBRACK", "CBRACK", "OPAR", "CPAR",
+ "DOT", "PIPE", "COL", "ASSIGN", "OBRACE", "CBRACE", "PARAM", "VAR",
+ "TRUE", "FALSE", "NULL", "ARRAY", "OBJECT", "RESOURCE", "OUTPUT", "TARGET_SCOPE",
+ "IMPORT", "WITH", "AS", "METADATA", "EXISTING", "TYPE", "MODULE", "STRING_LEFT_PIECE",
+ "STRING_MIDDLE_PIECE", "STRING_RIGHT_PIECE", "STRING_COMPLETE", "STRING",
+ "INT", "BOOL", "IF", "FOR", "IN", "QMARK", "GT", "GTE", "LT", "LTE",
+ "EQ", "NEQ", "ARROW", "IDENTIFIER", "NUMBER", "NL", "SINGLE_LINE_COMMENT",
+ "MULTI_LINE_COMMENT", "SPACES", "UNKNOWN",
+ }
+ staticData.RuleNames = []string{
+ "program", "statement", "targetScopeDecl", "importDecl", "metadataDecl",
+ "parameterDecl", "parameterDefaultValue", "typeDecl", "variableDecl",
+ "resourceDecl", "moduleDecl", "outputDecl", "ifCondition", "forExpression",
+ "forVariableBlock", "forBody", "interpString", "expression", "lambdaExpression",
+ "logicCharacter", "primaryExpression", "parenthesizedExpression", "typeExpression",
+ "literalValue", "object", "objectProperty", "array", "arrayItem", "decorator",
+ "decoratorExpression", "functionCall", "argumentList", "identifier",
+ }
+ staticData.PredictionContextCache = antlr.NewPredictionContextCache()
+ staticData.serializedATN = []int32{
+ 4, 1, 55, 436, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7,
+ 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7,
+ 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15,
+ 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2,
+ 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26,
+ 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7,
+ 31, 2, 32, 7, 32, 1, 0, 5, 0, 68, 8, 0, 10, 0, 12, 0, 71, 9, 0, 1, 0, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 85,
+ 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 5, 3, 93, 8, 3, 10, 3, 12, 3,
+ 96, 9, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 5, 3, 104, 8, 3, 10, 3, 12,
+ 3, 107, 9, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 5,
+ 5, 118, 8, 5, 10, 5, 12, 5, 121, 9, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 127,
+ 8, 5, 1, 5, 1, 5, 1, 5, 3, 5, 132, 8, 5, 3, 5, 134, 8, 5, 1, 5, 1, 5, 1,
+ 6, 1, 6, 1, 6, 1, 7, 5, 7, 142, 8, 7, 10, 7, 12, 7, 145, 9, 7, 1, 7, 1,
+ 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 5, 8, 154, 8, 8, 10, 8, 12, 8, 157, 9,
+ 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 5, 9, 166, 8, 9, 10, 9, 12,
+ 9, 169, 9, 9, 1, 9, 1, 9, 1, 9, 1, 9, 3, 9, 175, 8, 9, 1, 9, 1, 9, 1, 9,
+ 1, 9, 3, 9, 181, 8, 9, 1, 9, 1, 9, 1, 10, 5, 10, 186, 8, 10, 10, 10, 12,
+ 10, 189, 9, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10,
+ 198, 8, 10, 1, 10, 1, 10, 1, 11, 5, 11, 203, 8, 11, 10, 11, 12, 11, 206,
+ 9, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 213, 8, 11, 1, 11, 1,
+ 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 5, 13, 225,
+ 8, 13, 10, 13, 12, 13, 228, 9, 13, 1, 13, 1, 13, 1, 13, 3, 13, 233, 8,
+ 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 5, 13, 240, 8, 13, 10, 13, 12, 13,
+ 243, 9, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1,
+ 15, 1, 15, 3, 15, 255, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 5, 16, 261, 8,
+ 16, 10, 16, 12, 16, 264, 9, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 270,
+ 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1,
+ 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17,
+ 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 5, 17, 299, 8, 17, 10,
+ 17, 12, 17, 302, 9, 17, 1, 18, 1, 18, 3, 18, 306, 8, 18, 1, 18, 1, 18,
+ 3, 18, 310, 8, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1,
+ 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 326, 8, 20, 1, 21,
+ 1, 21, 3, 21, 330, 8, 21, 1, 21, 1, 21, 3, 21, 334, 8, 21, 1, 21, 1, 21,
+ 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 3, 23, 345, 8, 23, 1,
+ 24, 1, 24, 4, 24, 349, 8, 24, 11, 24, 12, 24, 350, 1, 24, 1, 24, 4, 24,
+ 355, 8, 24, 11, 24, 12, 24, 356, 5, 24, 359, 8, 24, 10, 24, 12, 24, 362,
+ 9, 24, 3, 24, 364, 8, 24, 1, 24, 1, 24, 1, 25, 1, 25, 3, 25, 370, 8, 25,
+ 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 5, 26, 377, 8, 26, 10, 26, 12, 26, 380,
+ 9, 26, 1, 26, 5, 26, 383, 8, 26, 10, 26, 12, 26, 386, 9, 26, 1, 26, 1,
+ 26, 1, 27, 1, 27, 4, 27, 392, 8, 27, 11, 27, 12, 27, 393, 1, 27, 3, 27,
+ 397, 8, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1,
+ 29, 3, 29, 408, 8, 29, 1, 30, 1, 30, 1, 30, 3, 30, 413, 8, 30, 1, 30, 3,
+ 30, 416, 8, 30, 1, 30, 3, 30, 419, 8, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1,
+ 31, 3, 31, 426, 8, 31, 1, 31, 5, 31, 429, 8, 31, 10, 31, 12, 31, 432, 9,
+ 31, 1, 32, 1, 32, 1, 32, 0, 1, 34, 33, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18,
+ 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
+ 56, 58, 60, 62, 64, 0, 2, 1, 0, 42, 47, 3, 0, 14, 30, 35, 40, 49, 49, 474,
+ 0, 69, 1, 0, 0, 0, 2, 84, 1, 0, 0, 0, 4, 86, 1, 0, 0, 0, 6, 94, 1, 0, 0,
+ 0, 8, 110, 1, 0, 0, 0, 10, 119, 1, 0, 0, 0, 12, 137, 1, 0, 0, 0, 14, 143,
+ 1, 0, 0, 0, 16, 155, 1, 0, 0, 0, 18, 167, 1, 0, 0, 0, 20, 187, 1, 0, 0,
+ 0, 22, 204, 1, 0, 0, 0, 24, 218, 1, 0, 0, 0, 26, 222, 1, 0, 0, 0, 28, 246,
+ 1, 0, 0, 0, 30, 254, 1, 0, 0, 0, 32, 269, 1, 0, 0, 0, 34, 271, 1, 0, 0,
+ 0, 36, 309, 1, 0, 0, 0, 38, 314, 1, 0, 0, 0, 40, 325, 1, 0, 0, 0, 42, 327,
+ 1, 0, 0, 0, 44, 337, 1, 0, 0, 0, 46, 344, 1, 0, 0, 0, 48, 346, 1, 0, 0,
+ 0, 50, 369, 1, 0, 0, 0, 52, 374, 1, 0, 0, 0, 54, 389, 1, 0, 0, 0, 56, 398,
+ 1, 0, 0, 0, 58, 407, 1, 0, 0, 0, 60, 409, 1, 0, 0, 0, 62, 422, 1, 0, 0,
+ 0, 64, 433, 1, 0, 0, 0, 66, 68, 3, 2, 1, 0, 67, 66, 1, 0, 0, 0, 68, 71,
+ 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 72, 1, 0, 0, 0,
+ 71, 69, 1, 0, 0, 0, 72, 73, 5, 0, 0, 1, 73, 1, 1, 0, 0, 0, 74, 85, 3, 4,
+ 2, 0, 75, 85, 3, 6, 3, 0, 76, 85, 3, 8, 4, 0, 77, 85, 3, 10, 5, 0, 78,
+ 85, 3, 14, 7, 0, 79, 85, 3, 16, 8, 0, 80, 85, 3, 18, 9, 0, 81, 85, 3, 20,
+ 10, 0, 82, 85, 3, 22, 11, 0, 83, 85, 5, 51, 0, 0, 84, 74, 1, 0, 0, 0, 84,
+ 75, 1, 0, 0, 0, 84, 76, 1, 0, 0, 0, 84, 77, 1, 0, 0, 0, 84, 78, 1, 0, 0,
+ 0, 84, 79, 1, 0, 0, 0, 84, 80, 1, 0, 0, 0, 84, 81, 1, 0, 0, 0, 84, 82,
+ 1, 0, 0, 0, 84, 83, 1, 0, 0, 0, 85, 3, 1, 0, 0, 0, 86, 87, 5, 23, 0, 0,
+ 87, 88, 5, 11, 0, 0, 88, 89, 3, 34, 17, 0, 89, 90, 5, 51, 0, 0, 90, 5,
+ 1, 0, 0, 0, 91, 93, 3, 56, 28, 0, 92, 91, 1, 0, 0, 0, 93, 96, 1, 0, 0,
+ 0, 94, 92, 1, 0, 0, 0, 94, 95, 1, 0, 0, 0, 95, 97, 1, 0, 0, 0, 96, 94,
+ 1, 0, 0, 0, 97, 98, 5, 24, 0, 0, 98, 105, 3, 32, 16, 0, 99, 100, 5, 25,
+ 0, 0, 100, 104, 3, 48, 24, 0, 101, 102, 5, 26, 0, 0, 102, 104, 3, 64, 32,
+ 0, 103, 99, 1, 0, 0, 0, 103, 101, 1, 0, 0, 0, 104, 107, 1, 0, 0, 0, 105,
+ 103, 1, 0, 0, 0, 105, 106, 1, 0, 0, 0, 106, 108, 1, 0, 0, 0, 107, 105,
+ 1, 0, 0, 0, 108, 109, 5, 51, 0, 0, 109, 7, 1, 0, 0, 0, 110, 111, 5, 27,
+ 0, 0, 111, 112, 3, 64, 32, 0, 112, 113, 5, 11, 0, 0, 113, 114, 3, 34, 17,
+ 0, 114, 115, 5, 51, 0, 0, 115, 9, 1, 0, 0, 0, 116, 118, 3, 56, 28, 0, 117,
+ 116, 1, 0, 0, 0, 118, 121, 1, 0, 0, 0, 119, 117, 1, 0, 0, 0, 119, 120,
+ 1, 0, 0, 0, 120, 122, 1, 0, 0, 0, 121, 119, 1, 0, 0, 0, 122, 123, 5, 14,
+ 0, 0, 123, 133, 3, 64, 32, 0, 124, 126, 3, 44, 22, 0, 125, 127, 3, 12,
+ 6, 0, 126, 125, 1, 0, 0, 0, 126, 127, 1, 0, 0, 0, 127, 134, 1, 0, 0, 0,
+ 128, 129, 5, 21, 0, 0, 129, 131, 3, 32, 16, 0, 130, 132, 3, 12, 6, 0, 131,
+ 130, 1, 0, 0, 0, 131, 132, 1, 0, 0, 0, 132, 134, 1, 0, 0, 0, 133, 124,
+ 1, 0, 0, 0, 133, 128, 1, 0, 0, 0, 134, 135, 1, 0, 0, 0, 135, 136, 5, 51,
+ 0, 0, 136, 11, 1, 0, 0, 0, 137, 138, 5, 11, 0, 0, 138, 139, 3, 34, 17,
+ 0, 139, 13, 1, 0, 0, 0, 140, 142, 3, 56, 28, 0, 141, 140, 1, 0, 0, 0, 142,
+ 145, 1, 0, 0, 0, 143, 141, 1, 0, 0, 0, 143, 144, 1, 0, 0, 0, 144, 146,
+ 1, 0, 0, 0, 145, 143, 1, 0, 0, 0, 146, 147, 5, 29, 0, 0, 147, 148, 3, 64,
+ 32, 0, 148, 149, 5, 11, 0, 0, 149, 150, 3, 44, 22, 0, 150, 151, 5, 51,
+ 0, 0, 151, 15, 1, 0, 0, 0, 152, 154, 3, 56, 28, 0, 153, 152, 1, 0, 0, 0,
+ 154, 157, 1, 0, 0, 0, 155, 153, 1, 0, 0, 0, 155, 156, 1, 0, 0, 0, 156,
+ 158, 1, 0, 0, 0, 157, 155, 1, 0, 0, 0, 158, 159, 5, 15, 0, 0, 159, 160,
+ 3, 64, 32, 0, 160, 161, 5, 11, 0, 0, 161, 162, 3, 34, 17, 0, 162, 163,
+ 5, 51, 0, 0, 163, 17, 1, 0, 0, 0, 164, 166, 3, 56, 28, 0, 165, 164, 1,
+ 0, 0, 0, 166, 169, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 167, 168, 1, 0, 0,
+ 0, 168, 170, 1, 0, 0, 0, 169, 167, 1, 0, 0, 0, 170, 171, 5, 21, 0, 0, 171,
+ 172, 3, 64, 32, 0, 172, 174, 3, 32, 16, 0, 173, 175, 5, 28, 0, 0, 174,
+ 173, 1, 0, 0, 0, 174, 175, 1, 0, 0, 0, 175, 176, 1, 0, 0, 0, 176, 180,
+ 5, 11, 0, 0, 177, 181, 3, 24, 12, 0, 178, 181, 3, 48, 24, 0, 179, 181,
+ 3, 26, 13, 0, 180, 177, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 180, 179, 1,
+ 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 183, 5, 51, 0, 0, 183, 19, 1, 0, 0,
+ 0, 184, 186, 3, 56, 28, 0, 185, 184, 1, 0, 0, 0, 186, 189, 1, 0, 0, 0,
+ 187, 185, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 190, 1, 0, 0, 0, 189,
+ 187, 1, 0, 0, 0, 190, 191, 5, 30, 0, 0, 191, 192, 3, 64, 32, 0, 192, 193,
+ 3, 32, 16, 0, 193, 197, 5, 11, 0, 0, 194, 198, 3, 24, 12, 0, 195, 198,
+ 3, 48, 24, 0, 196, 198, 3, 26, 13, 0, 197, 194, 1, 0, 0, 0, 197, 195, 1,
+ 0, 0, 0, 197, 196, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, 200, 5, 51, 0,
+ 0, 200, 21, 1, 0, 0, 0, 201, 203, 3, 56, 28, 0, 202, 201, 1, 0, 0, 0, 203,
+ 206, 1, 0, 0, 0, 204, 202, 1, 0, 0, 0, 204, 205, 1, 0, 0, 0, 205, 207,
+ 1, 0, 0, 0, 206, 204, 1, 0, 0, 0, 207, 208, 5, 22, 0, 0, 208, 212, 3, 64,
+ 32, 0, 209, 213, 3, 64, 32, 0, 210, 211, 5, 21, 0, 0, 211, 213, 3, 32,
+ 16, 0, 212, 209, 1, 0, 0, 0, 212, 210, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0,
+ 214, 215, 5, 11, 0, 0, 215, 216, 3, 34, 17, 0, 216, 217, 5, 51, 0, 0, 217,
+ 23, 1, 0, 0, 0, 218, 219, 5, 38, 0, 0, 219, 220, 3, 42, 21, 0, 220, 221,
+ 3, 48, 24, 0, 221, 25, 1, 0, 0, 0, 222, 226, 5, 4, 0, 0, 223, 225, 5, 51,
+ 0, 0, 224, 223, 1, 0, 0, 0, 225, 228, 1, 0, 0, 0, 226, 224, 1, 0, 0, 0,
+ 226, 227, 1, 0, 0, 0, 227, 229, 1, 0, 0, 0, 228, 226, 1, 0, 0, 0, 229,
+ 232, 5, 39, 0, 0, 230, 233, 3, 64, 32, 0, 231, 233, 3, 28, 14, 0, 232,
+ 230, 1, 0, 0, 0, 232, 231, 1, 0, 0, 0, 233, 234, 1, 0, 0, 0, 234, 235,
+ 5, 40, 0, 0, 235, 236, 3, 34, 17, 0, 236, 237, 5, 10, 0, 0, 237, 241, 3,
+ 30, 15, 0, 238, 240, 5, 51, 0, 0, 239, 238, 1, 0, 0, 0, 240, 243, 1, 0,
+ 0, 0, 241, 239, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 244, 1, 0, 0, 0,
+ 243, 241, 1, 0, 0, 0, 244, 245, 5, 5, 0, 0, 245, 27, 1, 0, 0, 0, 246, 247,
+ 5, 6, 0, 0, 247, 248, 3, 64, 32, 0, 248, 249, 5, 3, 0, 0, 249, 250, 3,
+ 64, 32, 0, 250, 251, 5, 7, 0, 0, 251, 29, 1, 0, 0, 0, 252, 255, 3, 34,
+ 17, 0, 253, 255, 3, 24, 12, 0, 254, 252, 1, 0, 0, 0, 254, 253, 1, 0, 0,
+ 0, 255, 31, 1, 0, 0, 0, 256, 262, 5, 31, 0, 0, 257, 258, 3, 34, 17, 0,
+ 258, 259, 5, 32, 0, 0, 259, 261, 1, 0, 0, 0, 260, 257, 1, 0, 0, 0, 261,
+ 264, 1, 0, 0, 0, 262, 260, 1, 0, 0, 0, 262, 263, 1, 0, 0, 0, 263, 265,
+ 1, 0, 0, 0, 264, 262, 1, 0, 0, 0, 265, 266, 3, 34, 17, 0, 266, 267, 5,
+ 33, 0, 0, 267, 270, 1, 0, 0, 0, 268, 270, 5, 34, 0, 0, 269, 256, 1, 0,
+ 0, 0, 269, 268, 1, 0, 0, 0, 270, 33, 1, 0, 0, 0, 271, 272, 6, 17, -1, 0,
+ 272, 273, 3, 40, 20, 0, 273, 300, 1, 0, 0, 0, 274, 275, 10, 6, 0, 0, 275,
+ 276, 5, 41, 0, 0, 276, 277, 3, 34, 17, 0, 277, 278, 5, 10, 0, 0, 278, 279,
+ 3, 34, 17, 7, 279, 299, 1, 0, 0, 0, 280, 281, 10, 2, 0, 0, 281, 282, 3,
+ 38, 19, 0, 282, 283, 3, 34, 17, 3, 283, 299, 1, 0, 0, 0, 284, 285, 10,
+ 7, 0, 0, 285, 286, 5, 4, 0, 0, 286, 287, 3, 34, 17, 0, 287, 288, 5, 5,
+ 0, 0, 288, 299, 1, 0, 0, 0, 289, 290, 10, 5, 0, 0, 290, 291, 5, 8, 0, 0,
+ 291, 299, 3, 64, 32, 0, 292, 293, 10, 4, 0, 0, 293, 294, 5, 8, 0, 0, 294,
+ 299, 3, 60, 30, 0, 295, 296, 10, 3, 0, 0, 296, 297, 5, 10, 0, 0, 297, 299,
+ 3, 64, 32, 0, 298, 274, 1, 0, 0, 0, 298, 280, 1, 0, 0, 0, 298, 284, 1,
+ 0, 0, 0, 298, 289, 1, 0, 0, 0, 298, 292, 1, 0, 0, 0, 298, 295, 1, 0, 0,
+ 0, 299, 302, 1, 0, 0, 0, 300, 298, 1, 0, 0, 0, 300, 301, 1, 0, 0, 0, 301,
+ 35, 1, 0, 0, 0, 302, 300, 1, 0, 0, 0, 303, 305, 5, 6, 0, 0, 304, 306, 3,
+ 62, 31, 0, 305, 304, 1, 0, 0, 0, 305, 306, 1, 0, 0, 0, 306, 307, 1, 0,
+ 0, 0, 307, 310, 5, 7, 0, 0, 308, 310, 3, 64, 32, 0, 309, 303, 1, 0, 0,
+ 0, 309, 308, 1, 0, 0, 0, 310, 311, 1, 0, 0, 0, 311, 312, 5, 48, 0, 0, 312,
+ 313, 3, 34, 17, 0, 313, 37, 1, 0, 0, 0, 314, 315, 7, 0, 0, 0, 315, 39,
+ 1, 0, 0, 0, 316, 326, 3, 46, 23, 0, 317, 326, 3, 60, 30, 0, 318, 326, 3,
+ 32, 16, 0, 319, 326, 5, 1, 0, 0, 320, 326, 3, 52, 26, 0, 321, 326, 3, 48,
+ 24, 0, 322, 326, 3, 26, 13, 0, 323, 326, 3, 42, 21, 0, 324, 326, 3, 36,
+ 18, 0, 325, 316, 1, 0, 0, 0, 325, 317, 1, 0, 0, 0, 325, 318, 1, 0, 0, 0,
+ 325, 319, 1, 0, 0, 0, 325, 320, 1, 0, 0, 0, 325, 321, 1, 0, 0, 0, 325,
+ 322, 1, 0, 0, 0, 325, 323, 1, 0, 0, 0, 325, 324, 1, 0, 0, 0, 326, 41, 1,
+ 0, 0, 0, 327, 329, 5, 6, 0, 0, 328, 330, 5, 51, 0, 0, 329, 328, 1, 0, 0,
+ 0, 329, 330, 1, 0, 0, 0, 330, 331, 1, 0, 0, 0, 331, 333, 3, 34, 17, 0,
+ 332, 334, 5, 51, 0, 0, 333, 332, 1, 0, 0, 0, 333, 334, 1, 0, 0, 0, 334,
+ 335, 1, 0, 0, 0, 335, 336, 5, 7, 0, 0, 336, 43, 1, 0, 0, 0, 337, 338, 3,
+ 64, 32, 0, 338, 45, 1, 0, 0, 0, 339, 345, 5, 50, 0, 0, 340, 345, 5, 16,
+ 0, 0, 341, 345, 5, 17, 0, 0, 342, 345, 5, 18, 0, 0, 343, 345, 3, 64, 32,
+ 0, 344, 339, 1, 0, 0, 0, 344, 340, 1, 0, 0, 0, 344, 341, 1, 0, 0, 0, 344,
+ 342, 1, 0, 0, 0, 344, 343, 1, 0, 0, 0, 345, 47, 1, 0, 0, 0, 346, 363, 5,
+ 12, 0, 0, 347, 349, 5, 51, 0, 0, 348, 347, 1, 0, 0, 0, 349, 350, 1, 0,
+ 0, 0, 350, 348, 1, 0, 0, 0, 350, 351, 1, 0, 0, 0, 351, 360, 1, 0, 0, 0,
+ 352, 354, 3, 50, 25, 0, 353, 355, 5, 51, 0, 0, 354, 353, 1, 0, 0, 0, 355,
+ 356, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 357, 359,
+ 1, 0, 0, 0, 358, 352, 1, 0, 0, 0, 359, 362, 1, 0, 0, 0, 360, 358, 1, 0,
+ 0, 0, 360, 361, 1, 0, 0, 0, 361, 364, 1, 0, 0, 0, 362, 360, 1, 0, 0, 0,
+ 363, 348, 1, 0, 0, 0, 363, 364, 1, 0, 0, 0, 364, 365, 1, 0, 0, 0, 365,
+ 366, 5, 13, 0, 0, 366, 49, 1, 0, 0, 0, 367, 370, 3, 64, 32, 0, 368, 370,
+ 3, 32, 16, 0, 369, 367, 1, 0, 0, 0, 369, 368, 1, 0, 0, 0, 370, 371, 1,
+ 0, 0, 0, 371, 372, 5, 10, 0, 0, 372, 373, 3, 34, 17, 0, 373, 51, 1, 0,
+ 0, 0, 374, 378, 5, 4, 0, 0, 375, 377, 5, 51, 0, 0, 376, 375, 1, 0, 0, 0,
+ 377, 380, 1, 0, 0, 0, 378, 376, 1, 0, 0, 0, 378, 379, 1, 0, 0, 0, 379,
+ 384, 1, 0, 0, 0, 380, 378, 1, 0, 0, 0, 381, 383, 3, 54, 27, 0, 382, 381,
+ 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 384, 385, 1, 0,
+ 0, 0, 385, 387, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 388, 5, 5, 0, 0,
+ 388, 53, 1, 0, 0, 0, 389, 396, 3, 34, 17, 0, 390, 392, 5, 51, 0, 0, 391,
+ 390, 1, 0, 0, 0, 392, 393, 1, 0, 0, 0, 393, 391, 1, 0, 0, 0, 393, 394,
+ 1, 0, 0, 0, 394, 397, 1, 0, 0, 0, 395, 397, 5, 3, 0, 0, 396, 391, 1, 0,
+ 0, 0, 396, 395, 1, 0, 0, 0, 396, 397, 1, 0, 0, 0, 397, 55, 1, 0, 0, 0,
+ 398, 399, 5, 2, 0, 0, 399, 400, 3, 58, 29, 0, 400, 401, 5, 51, 0, 0, 401,
+ 57, 1, 0, 0, 0, 402, 408, 3, 60, 30, 0, 403, 404, 3, 34, 17, 0, 404, 405,
+ 5, 8, 0, 0, 405, 406, 3, 60, 30, 0, 406, 408, 1, 0, 0, 0, 407, 402, 1,
+ 0, 0, 0, 407, 403, 1, 0, 0, 0, 408, 59, 1, 0, 0, 0, 409, 410, 3, 64, 32,
+ 0, 410, 415, 5, 6, 0, 0, 411, 413, 5, 51, 0, 0, 412, 411, 1, 0, 0, 0, 412,
+ 413, 1, 0, 0, 0, 413, 414, 1, 0, 0, 0, 414, 416, 3, 62, 31, 0, 415, 412,
+ 1, 0, 0, 0, 415, 416, 1, 0, 0, 0, 416, 418, 1, 0, 0, 0, 417, 419, 5, 51,
+ 0, 0, 418, 417, 1, 0, 0, 0, 418, 419, 1, 0, 0, 0, 419, 420, 1, 0, 0, 0,
+ 420, 421, 5, 7, 0, 0, 421, 61, 1, 0, 0, 0, 422, 430, 3, 34, 17, 0, 423,
+ 425, 5, 3, 0, 0, 424, 426, 5, 51, 0, 0, 425, 424, 1, 0, 0, 0, 425, 426,
+ 1, 0, 0, 0, 426, 427, 1, 0, 0, 0, 427, 429, 3, 34, 17, 0, 428, 423, 1,
+ 0, 0, 0, 429, 432, 1, 0, 0, 0, 430, 428, 1, 0, 0, 0, 430, 431, 1, 0, 0,
+ 0, 431, 63, 1, 0, 0, 0, 432, 430, 1, 0, 0, 0, 433, 434, 7, 1, 0, 0, 434,
+ 65, 1, 0, 0, 0, 47, 69, 84, 94, 103, 105, 119, 126, 131, 133, 143, 155,
+ 167, 174, 180, 187, 197, 204, 212, 226, 232, 241, 254, 262, 269, 298, 300,
+ 305, 309, 325, 329, 333, 344, 350, 356, 360, 363, 369, 378, 384, 393, 396,
+ 407, 412, 415, 418, 425, 430,
+ }
+ deserializer := antlr.NewATNDeserializer(nil)
+ staticData.atn = deserializer.Deserialize(staticData.serializedATN)
+ atn := staticData.atn
+ staticData.decisionToDFA = make([]*antlr.DFA, len(atn.DecisionToState))
+ decisionToDFA := staticData.decisionToDFA
+ for index, state := range atn.DecisionToState {
+ decisionToDFA[index] = antlr.NewDFA(state, index)
+ }
+}
+
+// bicepParserInit initializes any static state used to implement bicepParser. By default the
+// static state used to implement the parser is lazily initialized during the first call to
+// NewbicepParser(). You can call this function if you wish to initialize the static state ahead
+// of time.
+func BicepParserInit() {
+ staticData := &BicepParserStaticData
+ staticData.once.Do(bicepParserInit)
+}
+
+// NewbicepParser produces a new parser instance for the optional input antlr.TokenStream.
+func NewbicepParser(input antlr.TokenStream) *bicepParser {
+ BicepParserInit()
+ this := new(bicepParser)
+ this.BaseParser = antlr.NewBaseParser(input)
+ staticData := &BicepParserStaticData
+ this.Interpreter = antlr.NewParserATNSimulator(this, staticData.atn, staticData.decisionToDFA, staticData.PredictionContextCache)
+ this.RuleNames = staticData.RuleNames
+ this.LiteralNames = staticData.LiteralNames
+ this.SymbolicNames = staticData.SymbolicNames
+ this.GrammarFileName = "bicep.g4"
+
+ return this
+}
+
+// bicepParser tokens.
+const (
+ bicepParserEOF = antlr.TokenEOF
+ bicepParserMULTILINE_STRING = 1
+ bicepParserAT = 2
+ bicepParserCOMMA = 3
+ bicepParserOBRACK = 4
+ bicepParserCBRACK = 5
+ bicepParserOPAR = 6
+ bicepParserCPAR = 7
+ bicepParserDOT = 8
+ bicepParserPIPE = 9
+ bicepParserCOL = 10
+ bicepParserASSIGN = 11
+ bicepParserOBRACE = 12
+ bicepParserCBRACE = 13
+ bicepParserPARAM = 14
+ bicepParserVAR = 15
+ bicepParserTRUE = 16
+ bicepParserFALSE = 17
+ bicepParserNULL = 18
+ bicepParserARRAY = 19
+ bicepParserOBJECT = 20
+ bicepParserRESOURCE = 21
+ bicepParserOUTPUT = 22
+ bicepParserTARGET_SCOPE = 23
+ bicepParserIMPORT = 24
+ bicepParserWITH = 25
+ bicepParserAS = 26
+ bicepParserMETADATA = 27
+ bicepParserEXISTING = 28
+ bicepParserTYPE = 29
+ bicepParserMODULE = 30
+ bicepParserSTRING_LEFT_PIECE = 31
+ bicepParserSTRING_MIDDLE_PIECE = 32
+ bicepParserSTRING_RIGHT_PIECE = 33
+ bicepParserSTRING_COMPLETE = 34
+ bicepParserSTRING = 35
+ bicepParserINT = 36
+ bicepParserBOOL = 37
+ bicepParserIF = 38
+ bicepParserFOR = 39
+ bicepParserIN = 40
+ bicepParserQMARK = 41
+ bicepParserGT = 42
+ bicepParserGTE = 43
+ bicepParserLT = 44
+ bicepParserLTE = 45
+ bicepParserEQ = 46
+ bicepParserNEQ = 47
+ bicepParserARROW = 48
+ bicepParserIDENTIFIER = 49
+ bicepParserNUMBER = 50
+ bicepParserNL = 51
+ bicepParserSINGLE_LINE_COMMENT = 52
+ bicepParserMULTI_LINE_COMMENT = 53
+ bicepParserSPACES = 54
+ bicepParserUNKNOWN = 55
+)
+
+// bicepParser rules.
+const (
+ bicepParserRULE_program = 0
+ bicepParserRULE_statement = 1
+ bicepParserRULE_targetScopeDecl = 2
+ bicepParserRULE_importDecl = 3
+ bicepParserRULE_metadataDecl = 4
+ bicepParserRULE_parameterDecl = 5
+ bicepParserRULE_parameterDefaultValue = 6
+ bicepParserRULE_typeDecl = 7
+ bicepParserRULE_variableDecl = 8
+ bicepParserRULE_resourceDecl = 9
+ bicepParserRULE_moduleDecl = 10
+ bicepParserRULE_outputDecl = 11
+ bicepParserRULE_ifCondition = 12
+ bicepParserRULE_forExpression = 13
+ bicepParserRULE_forVariableBlock = 14
+ bicepParserRULE_forBody = 15
+ bicepParserRULE_interpString = 16
+ bicepParserRULE_expression = 17
+ bicepParserRULE_lambdaExpression = 18
+ bicepParserRULE_logicCharacter = 19
+ bicepParserRULE_primaryExpression = 20
+ bicepParserRULE_parenthesizedExpression = 21
+ bicepParserRULE_typeExpression = 22
+ bicepParserRULE_literalValue = 23
+ bicepParserRULE_object = 24
+ bicepParserRULE_objectProperty = 25
+ bicepParserRULE_array = 26
+ bicepParserRULE_arrayItem = 27
+ bicepParserRULE_decorator = 28
+ bicepParserRULE_decoratorExpression = 29
+ bicepParserRULE_functionCall = 30
+ bicepParserRULE_argumentList = 31
+ bicepParserRULE_identifier = 32
+)
+
+// IProgramContext is an interface to support dynamic dispatch.
+type IProgramContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ EOF() antlr.TerminalNode
+ AllStatement() []IStatementContext
+ Statement(i int) IStatementContext
+
+ // IsProgramContext differentiates from other interfaces.
+ IsProgramContext()
+}
+
+type ProgramContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyProgramContext() *ProgramContext {
+ var p = new(ProgramContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_program
+ return p
+}
+
+func InitEmptyProgramContext(p *ProgramContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_program
+}
+
+func (*ProgramContext) IsProgramContext() {}
+
+func NewProgramContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ProgramContext {
+ var p = new(ProgramContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_program
+
+ return p
+}
+
+func (s *ProgramContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ProgramContext) EOF() antlr.TerminalNode {
+ return s.GetToken(bicepParserEOF, 0)
+}
+
+func (s *ProgramContext) AllStatement() []IStatementContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IStatementContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IStatementContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IStatementContext); ok {
+ tst[i] = t.(IStatementContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ProgramContext) Statement(i int) IStatementContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IStatementContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IStatementContext)
+}
+
+func (s *ProgramContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ProgramContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ProgramContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitProgram(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) Program() (localctx IProgramContext) {
+ localctx = NewProgramContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 0, bicepParserRULE_program)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(69)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&2251801590022148) != 0 {
+ {
+ p.SetState(66)
+ p.Statement()
+ }
+
+ p.SetState(71)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(72)
+ p.Match(bicepParserEOF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IStatementContext is an interface to support dynamic dispatch.
+type IStatementContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ TargetScopeDecl() ITargetScopeDeclContext
+ ImportDecl() IImportDeclContext
+ MetadataDecl() IMetadataDeclContext
+ ParameterDecl() IParameterDeclContext
+ TypeDecl() ITypeDeclContext
+ VariableDecl() IVariableDeclContext
+ ResourceDecl() IResourceDeclContext
+ ModuleDecl() IModuleDeclContext
+ OutputDecl() IOutputDeclContext
+ NL() antlr.TerminalNode
+
+ // IsStatementContext differentiates from other interfaces.
+ IsStatementContext()
+}
+
+type StatementContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyStatementContext() *StatementContext {
+ var p = new(StatementContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_statement
+ return p
+}
+
+func InitEmptyStatementContext(p *StatementContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_statement
+}
+
+func (*StatementContext) IsStatementContext() {}
+
+func NewStatementContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *StatementContext {
+ var p = new(StatementContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_statement
+
+ return p
+}
+
+func (s *StatementContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *StatementContext) TargetScopeDecl() ITargetScopeDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ITargetScopeDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ITargetScopeDeclContext)
+}
+
+func (s *StatementContext) ImportDecl() IImportDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IImportDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IImportDeclContext)
+}
+
+func (s *StatementContext) MetadataDecl() IMetadataDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IMetadataDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IMetadataDeclContext)
+}
+
+func (s *StatementContext) ParameterDecl() IParameterDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParameterDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParameterDeclContext)
+}
+
+func (s *StatementContext) TypeDecl() ITypeDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ITypeDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ITypeDeclContext)
+}
+
+func (s *StatementContext) VariableDecl() IVariableDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IVariableDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IVariableDeclContext)
+}
+
+func (s *StatementContext) ResourceDecl() IResourceDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IResourceDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IResourceDeclContext)
+}
+
+func (s *StatementContext) ModuleDecl() IModuleDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IModuleDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IModuleDeclContext)
+}
+
+func (s *StatementContext) OutputDecl() IOutputDeclContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IOutputDeclContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IOutputDeclContext)
+}
+
+func (s *StatementContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *StatementContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *StatementContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *StatementContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitStatement(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) Statement() (localctx IStatementContext) {
+ localctx = NewStatementContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 2, bicepParserRULE_statement)
+ p.SetState(84)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 1, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(74)
+ p.TargetScopeDecl()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(75)
+ p.ImportDecl()
+ }
+
+ case 3:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(76)
+ p.MetadataDecl()
+ }
+
+ case 4:
+ p.EnterOuterAlt(localctx, 4)
+ {
+ p.SetState(77)
+ p.ParameterDecl()
+ }
+
+ case 5:
+ p.EnterOuterAlt(localctx, 5)
+ {
+ p.SetState(78)
+ p.TypeDecl()
+ }
+
+ case 6:
+ p.EnterOuterAlt(localctx, 6)
+ {
+ p.SetState(79)
+ p.VariableDecl()
+ }
+
+ case 7:
+ p.EnterOuterAlt(localctx, 7)
+ {
+ p.SetState(80)
+ p.ResourceDecl()
+ }
+
+ case 8:
+ p.EnterOuterAlt(localctx, 8)
+ {
+ p.SetState(81)
+ p.ModuleDecl()
+ }
+
+ case 9:
+ p.EnterOuterAlt(localctx, 9)
+ {
+ p.SetState(82)
+ p.OutputDecl()
+ }
+
+ case 10:
+ p.EnterOuterAlt(localctx, 10)
+ {
+ p.SetState(83)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ITargetScopeDeclContext is an interface to support dynamic dispatch.
+type ITargetScopeDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ TARGET_SCOPE() antlr.TerminalNode
+ ASSIGN() antlr.TerminalNode
+ Expression() IExpressionContext
+ NL() antlr.TerminalNode
+
+ // IsTargetScopeDeclContext differentiates from other interfaces.
+ IsTargetScopeDeclContext()
+}
+
+type TargetScopeDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyTargetScopeDeclContext() *TargetScopeDeclContext {
+ var p = new(TargetScopeDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_targetScopeDecl
+ return p
+}
+
+func InitEmptyTargetScopeDeclContext(p *TargetScopeDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_targetScopeDecl
+}
+
+func (*TargetScopeDeclContext) IsTargetScopeDeclContext() {}
+
+func NewTargetScopeDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TargetScopeDeclContext {
+ var p = new(TargetScopeDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_targetScopeDecl
+
+ return p
+}
+
+func (s *TargetScopeDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *TargetScopeDeclContext) TARGET_SCOPE() antlr.TerminalNode {
+ return s.GetToken(bicepParserTARGET_SCOPE, 0)
+}
+
+func (s *TargetScopeDeclContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(bicepParserASSIGN, 0)
+}
+
+func (s *TargetScopeDeclContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *TargetScopeDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *TargetScopeDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *TargetScopeDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *TargetScopeDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitTargetScopeDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) TargetScopeDecl() (localctx ITargetScopeDeclContext) {
+ localctx = NewTargetScopeDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 4, bicepParserRULE_targetScopeDecl)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(86)
+ p.Match(bicepParserTARGET_SCOPE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(87)
+ p.Match(bicepParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(88)
+ p.expression(0)
+ }
+ {
+ p.SetState(89)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IImportDeclContext is an interface to support dynamic dispatch.
+type IImportDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetSpecification returns the specification rule contexts.
+ GetSpecification() IInterpStringContext
+
+ // GetAlias returns the alias rule contexts.
+ GetAlias() IIdentifierContext
+
+ // SetSpecification sets the specification rule contexts.
+ SetSpecification(IInterpStringContext)
+
+ // SetAlias sets the alias rule contexts.
+ SetAlias(IIdentifierContext)
+
+ // Getter signatures
+ IMPORT() antlr.TerminalNode
+ NL() antlr.TerminalNode
+ InterpString() IInterpStringContext
+ AllDecorator() []IDecoratorContext
+ Decorator(i int) IDecoratorContext
+ AllWITH() []antlr.TerminalNode
+ WITH(i int) antlr.TerminalNode
+ AllObject() []IObjectContext
+ Object(i int) IObjectContext
+ AllAS() []antlr.TerminalNode
+ AS(i int) antlr.TerminalNode
+ AllIdentifier() []IIdentifierContext
+ Identifier(i int) IIdentifierContext
+
+ // IsImportDeclContext differentiates from other interfaces.
+ IsImportDeclContext()
+}
+
+type ImportDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ specification IInterpStringContext
+ alias IIdentifierContext
+}
+
+func NewEmptyImportDeclContext() *ImportDeclContext {
+ var p = new(ImportDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_importDecl
+ return p
+}
+
+func InitEmptyImportDeclContext(p *ImportDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_importDecl
+}
+
+func (*ImportDeclContext) IsImportDeclContext() {}
+
+func NewImportDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ImportDeclContext {
+ var p = new(ImportDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_importDecl
+
+ return p
+}
+
+func (s *ImportDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ImportDeclContext) GetSpecification() IInterpStringContext { return s.specification }
+
+func (s *ImportDeclContext) GetAlias() IIdentifierContext { return s.alias }
+
+func (s *ImportDeclContext) SetSpecification(v IInterpStringContext) { s.specification = v }
+
+func (s *ImportDeclContext) SetAlias(v IIdentifierContext) { s.alias = v }
+
+func (s *ImportDeclContext) IMPORT() antlr.TerminalNode {
+ return s.GetToken(bicepParserIMPORT, 0)
+}
+
+func (s *ImportDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *ImportDeclContext) InterpString() IInterpStringContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInterpStringContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInterpStringContext)
+}
+
+func (s *ImportDeclContext) AllDecorator() []IDecoratorContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IDecoratorContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IDecoratorContext); ok {
+ tst[i] = t.(IDecoratorContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ImportDeclContext) Decorator(i int) IDecoratorContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDecoratorContext)
+}
+
+func (s *ImportDeclContext) AllWITH() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserWITH)
+}
+
+func (s *ImportDeclContext) WITH(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserWITH, i)
+}
+
+func (s *ImportDeclContext) AllObject() []IObjectContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IObjectContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IObjectContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IObjectContext); ok {
+ tst[i] = t.(IObjectContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ImportDeclContext) Object(i int) IObjectContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IObjectContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IObjectContext)
+}
+
+func (s *ImportDeclContext) AllAS() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserAS)
+}
+
+func (s *ImportDeclContext) AS(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserAS, i)
+}
+
+func (s *ImportDeclContext) AllIdentifier() []IIdentifierContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IIdentifierContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IIdentifierContext); ok {
+ tst[i] = t.(IIdentifierContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ImportDeclContext) Identifier(i int) IIdentifierContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *ImportDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ImportDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ImportDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitImportDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ImportDecl() (localctx IImportDeclContext) {
+ localctx = NewImportDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 6, bicepParserRULE_importDecl)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(94)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserAT {
+ {
+ p.SetState(91)
+ p.Decorator()
+ }
+
+ p.SetState(96)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(97)
+ p.Match(bicepParserIMPORT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(98)
+
+ var _x = p.InterpString()
+
+ localctx.(*ImportDeclContext).specification = _x
+ }
+ p.SetState(105)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserWITH || _la == bicepParserAS {
+ p.SetState(103)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case bicepParserWITH:
+ {
+ p.SetState(99)
+ p.Match(bicepParserWITH)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(100)
+ p.Object()
+ }
+
+ case bicepParserAS:
+ {
+ p.SetState(101)
+ p.Match(bicepParserAS)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(102)
+
+ var _x = p.Identifier()
+
+ localctx.(*ImportDeclContext).alias = _x
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+ p.SetState(107)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(108)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IMetadataDeclContext is an interface to support dynamic dispatch.
+type IMetadataDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // Getter signatures
+ METADATA() antlr.TerminalNode
+ ASSIGN() antlr.TerminalNode
+ Expression() IExpressionContext
+ NL() antlr.TerminalNode
+ Identifier() IIdentifierContext
+
+ // IsMetadataDeclContext differentiates from other interfaces.
+ IsMetadataDeclContext()
+}
+
+type MetadataDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ name IIdentifierContext
+}
+
+func NewEmptyMetadataDeclContext() *MetadataDeclContext {
+ var p = new(MetadataDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_metadataDecl
+ return p
+}
+
+func InitEmptyMetadataDeclContext(p *MetadataDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_metadataDecl
+}
+
+func (*MetadataDeclContext) IsMetadataDeclContext() {}
+
+func NewMetadataDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *MetadataDeclContext {
+ var p = new(MetadataDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_metadataDecl
+
+ return p
+}
+
+func (s *MetadataDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *MetadataDeclContext) GetName() IIdentifierContext { return s.name }
+
+func (s *MetadataDeclContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *MetadataDeclContext) METADATA() antlr.TerminalNode {
+ return s.GetToken(bicepParserMETADATA, 0)
+}
+
+func (s *MetadataDeclContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(bicepParserASSIGN, 0)
+}
+
+func (s *MetadataDeclContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *MetadataDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *MetadataDeclContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *MetadataDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *MetadataDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *MetadataDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitMetadataDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) MetadataDecl() (localctx IMetadataDeclContext) {
+ localctx = NewMetadataDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 8, bicepParserRULE_metadataDecl)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(110)
+ p.Match(bicepParserMETADATA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(111)
+
+ var _x = p.Identifier()
+
+ localctx.(*MetadataDeclContext).name = _x
+ }
+ {
+ p.SetState(112)
+ p.Match(bicepParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(113)
+ p.expression(0)
+ }
+ {
+ p.SetState(114)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IParameterDeclContext is an interface to support dynamic dispatch.
+type IParameterDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // GetType_ returns the type_ rule contexts.
+ GetType_() IInterpStringContext
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // SetType_ sets the type_ rule contexts.
+ SetType_(IInterpStringContext)
+
+ // Getter signatures
+ PARAM() antlr.TerminalNode
+ NL() antlr.TerminalNode
+ Identifier() IIdentifierContext
+ TypeExpression() ITypeExpressionContext
+ RESOURCE() antlr.TerminalNode
+ AllDecorator() []IDecoratorContext
+ Decorator(i int) IDecoratorContext
+ InterpString() IInterpStringContext
+ ParameterDefaultValue() IParameterDefaultValueContext
+
+ // IsParameterDeclContext differentiates from other interfaces.
+ IsParameterDeclContext()
+}
+
+type ParameterDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ name IIdentifierContext
+ type_ IInterpStringContext
+}
+
+func NewEmptyParameterDeclContext() *ParameterDeclContext {
+ var p = new(ParameterDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_parameterDecl
+ return p
+}
+
+func InitEmptyParameterDeclContext(p *ParameterDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_parameterDecl
+}
+
+func (*ParameterDeclContext) IsParameterDeclContext() {}
+
+func NewParameterDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParameterDeclContext {
+ var p = new(ParameterDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_parameterDecl
+
+ return p
+}
+
+func (s *ParameterDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ParameterDeclContext) GetName() IIdentifierContext { return s.name }
+
+func (s *ParameterDeclContext) GetType_() IInterpStringContext { return s.type_ }
+
+func (s *ParameterDeclContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *ParameterDeclContext) SetType_(v IInterpStringContext) { s.type_ = v }
+
+func (s *ParameterDeclContext) PARAM() antlr.TerminalNode {
+ return s.GetToken(bicepParserPARAM, 0)
+}
+
+func (s *ParameterDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *ParameterDeclContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *ParameterDeclContext) TypeExpression() ITypeExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ITypeExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ITypeExpressionContext)
+}
+
+func (s *ParameterDeclContext) RESOURCE() antlr.TerminalNode {
+ return s.GetToken(bicepParserRESOURCE, 0)
+}
+
+func (s *ParameterDeclContext) AllDecorator() []IDecoratorContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IDecoratorContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IDecoratorContext); ok {
+ tst[i] = t.(IDecoratorContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ParameterDeclContext) Decorator(i int) IDecoratorContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDecoratorContext)
+}
+
+func (s *ParameterDeclContext) InterpString() IInterpStringContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInterpStringContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInterpStringContext)
+}
+
+func (s *ParameterDeclContext) ParameterDefaultValue() IParameterDefaultValueContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParameterDefaultValueContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParameterDefaultValueContext)
+}
+
+func (s *ParameterDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ParameterDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ParameterDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitParameterDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ParameterDecl() (localctx IParameterDeclContext) {
+ localctx = NewParameterDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 10, bicepParserRULE_parameterDecl)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(119)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserAT {
+ {
+ p.SetState(116)
+ p.Decorator()
+ }
+
+ p.SetState(121)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(122)
+ p.Match(bicepParserPARAM)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(123)
+
+ var _x = p.Identifier()
+
+ localctx.(*ParameterDeclContext).name = _x
+ }
+ p.SetState(133)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 8, p.GetParserRuleContext()) {
+ case 1:
+ {
+ p.SetState(124)
+ p.TypeExpression()
+ }
+ p.SetState(126)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserASSIGN {
+ {
+ p.SetState(125)
+ p.ParameterDefaultValue()
+ }
+
+ }
+
+ case 2:
+ {
+ p.SetState(128)
+ p.Match(bicepParserRESOURCE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(129)
+
+ var _x = p.InterpString()
+
+ localctx.(*ParameterDeclContext).type_ = _x
+ }
+ p.SetState(131)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserASSIGN {
+ {
+ p.SetState(130)
+ p.ParameterDefaultValue()
+ }
+
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+ {
+ p.SetState(135)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IParameterDefaultValueContext is an interface to support dynamic dispatch.
+type IParameterDefaultValueContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ASSIGN() antlr.TerminalNode
+ Expression() IExpressionContext
+
+ // IsParameterDefaultValueContext differentiates from other interfaces.
+ IsParameterDefaultValueContext()
+}
+
+type ParameterDefaultValueContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyParameterDefaultValueContext() *ParameterDefaultValueContext {
+ var p = new(ParameterDefaultValueContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_parameterDefaultValue
+ return p
+}
+
+func InitEmptyParameterDefaultValueContext(p *ParameterDefaultValueContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_parameterDefaultValue
+}
+
+func (*ParameterDefaultValueContext) IsParameterDefaultValueContext() {}
+
+func NewParameterDefaultValueContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParameterDefaultValueContext {
+ var p = new(ParameterDefaultValueContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_parameterDefaultValue
+
+ return p
+}
+
+func (s *ParameterDefaultValueContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ParameterDefaultValueContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(bicepParserASSIGN, 0)
+}
+
+func (s *ParameterDefaultValueContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ParameterDefaultValueContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ParameterDefaultValueContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ParameterDefaultValueContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitParameterDefaultValue(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ParameterDefaultValue() (localctx IParameterDefaultValueContext) {
+ localctx = NewParameterDefaultValueContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 12, bicepParserRULE_parameterDefaultValue)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(137)
+ p.Match(bicepParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(138)
+ p.expression(0)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ITypeDeclContext is an interface to support dynamic dispatch.
+type ITypeDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // Getter signatures
+ TYPE() antlr.TerminalNode
+ ASSIGN() antlr.TerminalNode
+ TypeExpression() ITypeExpressionContext
+ NL() antlr.TerminalNode
+ Identifier() IIdentifierContext
+ AllDecorator() []IDecoratorContext
+ Decorator(i int) IDecoratorContext
+
+ // IsTypeDeclContext differentiates from other interfaces.
+ IsTypeDeclContext()
+}
+
+type TypeDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ name IIdentifierContext
+}
+
+func NewEmptyTypeDeclContext() *TypeDeclContext {
+ var p = new(TypeDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_typeDecl
+ return p
+}
+
+func InitEmptyTypeDeclContext(p *TypeDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_typeDecl
+}
+
+func (*TypeDeclContext) IsTypeDeclContext() {}
+
+func NewTypeDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TypeDeclContext {
+ var p = new(TypeDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_typeDecl
+
+ return p
+}
+
+func (s *TypeDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *TypeDeclContext) GetName() IIdentifierContext { return s.name }
+
+func (s *TypeDeclContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *TypeDeclContext) TYPE() antlr.TerminalNode {
+ return s.GetToken(bicepParserTYPE, 0)
+}
+
+func (s *TypeDeclContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(bicepParserASSIGN, 0)
+}
+
+func (s *TypeDeclContext) TypeExpression() ITypeExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ITypeExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ITypeExpressionContext)
+}
+
+func (s *TypeDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *TypeDeclContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *TypeDeclContext) AllDecorator() []IDecoratorContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IDecoratorContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IDecoratorContext); ok {
+ tst[i] = t.(IDecoratorContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *TypeDeclContext) Decorator(i int) IDecoratorContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDecoratorContext)
+}
+
+func (s *TypeDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *TypeDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *TypeDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitTypeDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) TypeDecl() (localctx ITypeDeclContext) {
+ localctx = NewTypeDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 14, bicepParserRULE_typeDecl)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(143)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserAT {
+ {
+ p.SetState(140)
+ p.Decorator()
+ }
+
+ p.SetState(145)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(146)
+ p.Match(bicepParserTYPE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(147)
+
+ var _x = p.Identifier()
+
+ localctx.(*TypeDeclContext).name = _x
+ }
+ {
+ p.SetState(148)
+ p.Match(bicepParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(149)
+ p.TypeExpression()
+ }
+ {
+ p.SetState(150)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IVariableDeclContext is an interface to support dynamic dispatch.
+type IVariableDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // Getter signatures
+ VAR() antlr.TerminalNode
+ ASSIGN() antlr.TerminalNode
+ Expression() IExpressionContext
+ NL() antlr.TerminalNode
+ Identifier() IIdentifierContext
+ AllDecorator() []IDecoratorContext
+ Decorator(i int) IDecoratorContext
+
+ // IsVariableDeclContext differentiates from other interfaces.
+ IsVariableDeclContext()
+}
+
+type VariableDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ name IIdentifierContext
+}
+
+func NewEmptyVariableDeclContext() *VariableDeclContext {
+ var p = new(VariableDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_variableDecl
+ return p
+}
+
+func InitEmptyVariableDeclContext(p *VariableDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_variableDecl
+}
+
+func (*VariableDeclContext) IsVariableDeclContext() {}
+
+func NewVariableDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *VariableDeclContext {
+ var p = new(VariableDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_variableDecl
+
+ return p
+}
+
+func (s *VariableDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *VariableDeclContext) GetName() IIdentifierContext { return s.name }
+
+func (s *VariableDeclContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *VariableDeclContext) VAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserVAR, 0)
+}
+
+func (s *VariableDeclContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(bicepParserASSIGN, 0)
+}
+
+func (s *VariableDeclContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *VariableDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *VariableDeclContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *VariableDeclContext) AllDecorator() []IDecoratorContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IDecoratorContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IDecoratorContext); ok {
+ tst[i] = t.(IDecoratorContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *VariableDeclContext) Decorator(i int) IDecoratorContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDecoratorContext)
+}
+
+func (s *VariableDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *VariableDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *VariableDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitVariableDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) VariableDecl() (localctx IVariableDeclContext) {
+ localctx = NewVariableDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 16, bicepParserRULE_variableDecl)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(155)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserAT {
+ {
+ p.SetState(152)
+ p.Decorator()
+ }
+
+ p.SetState(157)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(158)
+ p.Match(bicepParserVAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(159)
+
+ var _x = p.Identifier()
+
+ localctx.(*VariableDeclContext).name = _x
+ }
+ {
+ p.SetState(160)
+ p.Match(bicepParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(161)
+ p.expression(0)
+ }
+ {
+ p.SetState(162)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IResourceDeclContext is an interface to support dynamic dispatch.
+type IResourceDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // GetType_ returns the type_ rule contexts.
+ GetType_() IInterpStringContext
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // SetType_ sets the type_ rule contexts.
+ SetType_(IInterpStringContext)
+
+ // Getter signatures
+ RESOURCE() antlr.TerminalNode
+ ASSIGN() antlr.TerminalNode
+ NL() antlr.TerminalNode
+ Identifier() IIdentifierContext
+ InterpString() IInterpStringContext
+ IfCondition() IIfConditionContext
+ Object() IObjectContext
+ ForExpression() IForExpressionContext
+ AllDecorator() []IDecoratorContext
+ Decorator(i int) IDecoratorContext
+ EXISTING() antlr.TerminalNode
+
+ // IsResourceDeclContext differentiates from other interfaces.
+ IsResourceDeclContext()
+}
+
+type ResourceDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ name IIdentifierContext
+ type_ IInterpStringContext
+}
+
+func NewEmptyResourceDeclContext() *ResourceDeclContext {
+ var p = new(ResourceDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_resourceDecl
+ return p
+}
+
+func InitEmptyResourceDeclContext(p *ResourceDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_resourceDecl
+}
+
+func (*ResourceDeclContext) IsResourceDeclContext() {}
+
+func NewResourceDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ResourceDeclContext {
+ var p = new(ResourceDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_resourceDecl
+
+ return p
+}
+
+func (s *ResourceDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ResourceDeclContext) GetName() IIdentifierContext { return s.name }
+
+func (s *ResourceDeclContext) GetType_() IInterpStringContext { return s.type_ }
+
+func (s *ResourceDeclContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *ResourceDeclContext) SetType_(v IInterpStringContext) { s.type_ = v }
+
+func (s *ResourceDeclContext) RESOURCE() antlr.TerminalNode {
+ return s.GetToken(bicepParserRESOURCE, 0)
+}
+
+func (s *ResourceDeclContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(bicepParserASSIGN, 0)
+}
+
+func (s *ResourceDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *ResourceDeclContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *ResourceDeclContext) InterpString() IInterpStringContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInterpStringContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInterpStringContext)
+}
+
+func (s *ResourceDeclContext) IfCondition() IIfConditionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIfConditionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIfConditionContext)
+}
+
+func (s *ResourceDeclContext) Object() IObjectContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IObjectContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IObjectContext)
+}
+
+func (s *ResourceDeclContext) ForExpression() IForExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IForExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IForExpressionContext)
+}
+
+func (s *ResourceDeclContext) AllDecorator() []IDecoratorContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IDecoratorContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IDecoratorContext); ok {
+ tst[i] = t.(IDecoratorContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ResourceDeclContext) Decorator(i int) IDecoratorContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDecoratorContext)
+}
+
+func (s *ResourceDeclContext) EXISTING() antlr.TerminalNode {
+ return s.GetToken(bicepParserEXISTING, 0)
+}
+
+func (s *ResourceDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ResourceDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ResourceDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitResourceDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ResourceDecl() (localctx IResourceDeclContext) {
+ localctx = NewResourceDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 18, bicepParserRULE_resourceDecl)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(167)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserAT {
+ {
+ p.SetState(164)
+ p.Decorator()
+ }
+
+ p.SetState(169)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(170)
+ p.Match(bicepParserRESOURCE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(171)
+
+ var _x = p.Identifier()
+
+ localctx.(*ResourceDeclContext).name = _x
+ }
+ {
+ p.SetState(172)
+
+ var _x = p.InterpString()
+
+ localctx.(*ResourceDeclContext).type_ = _x
+ }
+ p.SetState(174)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserEXISTING {
+ {
+ p.SetState(173)
+ p.Match(bicepParserEXISTING)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(176)
+ p.Match(bicepParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(180)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case bicepParserIF:
+ {
+ p.SetState(177)
+ p.IfCondition()
+ }
+
+ case bicepParserOBRACE:
+ {
+ p.SetState(178)
+ p.Object()
+ }
+
+ case bicepParserOBRACK:
+ {
+ p.SetState(179)
+ p.ForExpression()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+ {
+ p.SetState(182)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IModuleDeclContext is an interface to support dynamic dispatch.
+type IModuleDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // GetType_ returns the type_ rule contexts.
+ GetType_() IInterpStringContext
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // SetType_ sets the type_ rule contexts.
+ SetType_(IInterpStringContext)
+
+ // Getter signatures
+ MODULE() antlr.TerminalNode
+ ASSIGN() antlr.TerminalNode
+ NL() antlr.TerminalNode
+ Identifier() IIdentifierContext
+ InterpString() IInterpStringContext
+ IfCondition() IIfConditionContext
+ Object() IObjectContext
+ ForExpression() IForExpressionContext
+ AllDecorator() []IDecoratorContext
+ Decorator(i int) IDecoratorContext
+
+ // IsModuleDeclContext differentiates from other interfaces.
+ IsModuleDeclContext()
+}
+
+type ModuleDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ name IIdentifierContext
+ type_ IInterpStringContext
+}
+
+func NewEmptyModuleDeclContext() *ModuleDeclContext {
+ var p = new(ModuleDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_moduleDecl
+ return p
+}
+
+func InitEmptyModuleDeclContext(p *ModuleDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_moduleDecl
+}
+
+func (*ModuleDeclContext) IsModuleDeclContext() {}
+
+func NewModuleDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ModuleDeclContext {
+ var p = new(ModuleDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_moduleDecl
+
+ return p
+}
+
+func (s *ModuleDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ModuleDeclContext) GetName() IIdentifierContext { return s.name }
+
+func (s *ModuleDeclContext) GetType_() IInterpStringContext { return s.type_ }
+
+func (s *ModuleDeclContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *ModuleDeclContext) SetType_(v IInterpStringContext) { s.type_ = v }
+
+func (s *ModuleDeclContext) MODULE() antlr.TerminalNode {
+ return s.GetToken(bicepParserMODULE, 0)
+}
+
+func (s *ModuleDeclContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(bicepParserASSIGN, 0)
+}
+
+func (s *ModuleDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *ModuleDeclContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *ModuleDeclContext) InterpString() IInterpStringContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInterpStringContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInterpStringContext)
+}
+
+func (s *ModuleDeclContext) IfCondition() IIfConditionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIfConditionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIfConditionContext)
+}
+
+func (s *ModuleDeclContext) Object() IObjectContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IObjectContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IObjectContext)
+}
+
+func (s *ModuleDeclContext) ForExpression() IForExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IForExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IForExpressionContext)
+}
+
+func (s *ModuleDeclContext) AllDecorator() []IDecoratorContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IDecoratorContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IDecoratorContext); ok {
+ tst[i] = t.(IDecoratorContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ModuleDeclContext) Decorator(i int) IDecoratorContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDecoratorContext)
+}
+
+func (s *ModuleDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ModuleDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ModuleDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitModuleDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ModuleDecl() (localctx IModuleDeclContext) {
+ localctx = NewModuleDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 20, bicepParserRULE_moduleDecl)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(187)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserAT {
+ {
+ p.SetState(184)
+ p.Decorator()
+ }
+
+ p.SetState(189)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(190)
+ p.Match(bicepParserMODULE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(191)
+
+ var _x = p.Identifier()
+
+ localctx.(*ModuleDeclContext).name = _x
+ }
+ {
+ p.SetState(192)
+
+ var _x = p.InterpString()
+
+ localctx.(*ModuleDeclContext).type_ = _x
+ }
+ {
+ p.SetState(193)
+ p.Match(bicepParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(197)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case bicepParserIF:
+ {
+ p.SetState(194)
+ p.IfCondition()
+ }
+
+ case bicepParserOBRACE:
+ {
+ p.SetState(195)
+ p.Object()
+ }
+
+ case bicepParserOBRACK:
+ {
+ p.SetState(196)
+ p.ForExpression()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+ {
+ p.SetState(199)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IOutputDeclContext is an interface to support dynamic dispatch.
+type IOutputDeclContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // GetType1 returns the type1 rule contexts.
+ GetType1() IIdentifierContext
+
+ // GetType2 returns the type2 rule contexts.
+ GetType2() IInterpStringContext
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // SetType1 sets the type1 rule contexts.
+ SetType1(IIdentifierContext)
+
+ // SetType2 sets the type2 rule contexts.
+ SetType2(IInterpStringContext)
+
+ // Getter signatures
+ OUTPUT() antlr.TerminalNode
+ ASSIGN() antlr.TerminalNode
+ Expression() IExpressionContext
+ NL() antlr.TerminalNode
+ AllIdentifier() []IIdentifierContext
+ Identifier(i int) IIdentifierContext
+ RESOURCE() antlr.TerminalNode
+ AllDecorator() []IDecoratorContext
+ Decorator(i int) IDecoratorContext
+ InterpString() IInterpStringContext
+
+ // IsOutputDeclContext differentiates from other interfaces.
+ IsOutputDeclContext()
+}
+
+type OutputDeclContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ name IIdentifierContext
+ type1 IIdentifierContext
+ type2 IInterpStringContext
+}
+
+func NewEmptyOutputDeclContext() *OutputDeclContext {
+ var p = new(OutputDeclContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_outputDecl
+ return p
+}
+
+func InitEmptyOutputDeclContext(p *OutputDeclContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_outputDecl
+}
+
+func (*OutputDeclContext) IsOutputDeclContext() {}
+
+func NewOutputDeclContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *OutputDeclContext {
+ var p = new(OutputDeclContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_outputDecl
+
+ return p
+}
+
+func (s *OutputDeclContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *OutputDeclContext) GetName() IIdentifierContext { return s.name }
+
+func (s *OutputDeclContext) GetType1() IIdentifierContext { return s.type1 }
+
+func (s *OutputDeclContext) GetType2() IInterpStringContext { return s.type2 }
+
+func (s *OutputDeclContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *OutputDeclContext) SetType1(v IIdentifierContext) { s.type1 = v }
+
+func (s *OutputDeclContext) SetType2(v IInterpStringContext) { s.type2 = v }
+
+func (s *OutputDeclContext) OUTPUT() antlr.TerminalNode {
+ return s.GetToken(bicepParserOUTPUT, 0)
+}
+
+func (s *OutputDeclContext) ASSIGN() antlr.TerminalNode {
+ return s.GetToken(bicepParserASSIGN, 0)
+}
+
+func (s *OutputDeclContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *OutputDeclContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *OutputDeclContext) AllIdentifier() []IIdentifierContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IIdentifierContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IIdentifierContext); ok {
+ tst[i] = t.(IIdentifierContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *OutputDeclContext) Identifier(i int) IIdentifierContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *OutputDeclContext) RESOURCE() antlr.TerminalNode {
+ return s.GetToken(bicepParserRESOURCE, 0)
+}
+
+func (s *OutputDeclContext) AllDecorator() []IDecoratorContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IDecoratorContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IDecoratorContext); ok {
+ tst[i] = t.(IDecoratorContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *OutputDeclContext) Decorator(i int) IDecoratorContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDecoratorContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDecoratorContext)
+}
+
+func (s *OutputDeclContext) InterpString() IInterpStringContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInterpStringContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInterpStringContext)
+}
+
+func (s *OutputDeclContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *OutputDeclContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *OutputDeclContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitOutputDecl(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) OutputDecl() (localctx IOutputDeclContext) {
+ localctx = NewOutputDeclContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 22, bicepParserRULE_outputDecl)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(204)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserAT {
+ {
+ p.SetState(201)
+ p.Decorator()
+ }
+
+ p.SetState(206)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(207)
+ p.Match(bicepParserOUTPUT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(208)
+
+ var _x = p.Identifier()
+
+ localctx.(*OutputDeclContext).name = _x
+ }
+ p.SetState(212)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 17, p.GetParserRuleContext()) {
+ case 1:
+ {
+ p.SetState(209)
+
+ var _x = p.Identifier()
+
+ localctx.(*OutputDeclContext).type1 = _x
+ }
+
+ case 2:
+ {
+ p.SetState(210)
+ p.Match(bicepParserRESOURCE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(211)
+
+ var _x = p.InterpString()
+
+ localctx.(*OutputDeclContext).type2 = _x
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+ {
+ p.SetState(214)
+ p.Match(bicepParserASSIGN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(215)
+ p.expression(0)
+ }
+ {
+ p.SetState(216)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IIfConditionContext is an interface to support dynamic dispatch.
+type IIfConditionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ IF() antlr.TerminalNode
+ ParenthesizedExpression() IParenthesizedExpressionContext
+ Object() IObjectContext
+
+ // IsIfConditionContext differentiates from other interfaces.
+ IsIfConditionContext()
+}
+
+type IfConditionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyIfConditionContext() *IfConditionContext {
+ var p = new(IfConditionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_ifCondition
+ return p
+}
+
+func InitEmptyIfConditionContext(p *IfConditionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_ifCondition
+}
+
+func (*IfConditionContext) IsIfConditionContext() {}
+
+func NewIfConditionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *IfConditionContext {
+ var p = new(IfConditionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_ifCondition
+
+ return p
+}
+
+func (s *IfConditionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *IfConditionContext) IF() antlr.TerminalNode {
+ return s.GetToken(bicepParserIF, 0)
+}
+
+func (s *IfConditionContext) ParenthesizedExpression() IParenthesizedExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParenthesizedExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParenthesizedExpressionContext)
+}
+
+func (s *IfConditionContext) Object() IObjectContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IObjectContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IObjectContext)
+}
+
+func (s *IfConditionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *IfConditionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *IfConditionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitIfCondition(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) IfCondition() (localctx IIfConditionContext) {
+ localctx = NewIfConditionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 24, bicepParserRULE_ifCondition)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(218)
+ p.Match(bicepParserIF)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(219)
+ p.ParenthesizedExpression()
+ }
+ {
+ p.SetState(220)
+ p.Object()
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IForExpressionContext is an interface to support dynamic dispatch.
+type IForExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetItem returns the item rule contexts.
+ GetItem() IIdentifierContext
+
+ // SetItem sets the item rule contexts.
+ SetItem(IIdentifierContext)
+
+ // Getter signatures
+ OBRACK() antlr.TerminalNode
+ FOR() antlr.TerminalNode
+ IN() antlr.TerminalNode
+ Expression() IExpressionContext
+ COL() antlr.TerminalNode
+ ForBody() IForBodyContext
+ CBRACK() antlr.TerminalNode
+ ForVariableBlock() IForVariableBlockContext
+ AllNL() []antlr.TerminalNode
+ NL(i int) antlr.TerminalNode
+ Identifier() IIdentifierContext
+
+ // IsForExpressionContext differentiates from other interfaces.
+ IsForExpressionContext()
+}
+
+type ForExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ item IIdentifierContext
+}
+
+func NewEmptyForExpressionContext() *ForExpressionContext {
+ var p = new(ForExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_forExpression
+ return p
+}
+
+func InitEmptyForExpressionContext(p *ForExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_forExpression
+}
+
+func (*ForExpressionContext) IsForExpressionContext() {}
+
+func NewForExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForExpressionContext {
+ var p = new(ForExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_forExpression
+
+ return p
+}
+
+func (s *ForExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ForExpressionContext) GetItem() IIdentifierContext { return s.item }
+
+func (s *ForExpressionContext) SetItem(v IIdentifierContext) { s.item = v }
+
+func (s *ForExpressionContext) OBRACK() antlr.TerminalNode {
+ return s.GetToken(bicepParserOBRACK, 0)
+}
+
+func (s *ForExpressionContext) FOR() antlr.TerminalNode {
+ return s.GetToken(bicepParserFOR, 0)
+}
+
+func (s *ForExpressionContext) IN() antlr.TerminalNode {
+ return s.GetToken(bicepParserIN, 0)
+}
+
+func (s *ForExpressionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ForExpressionContext) COL() antlr.TerminalNode {
+ return s.GetToken(bicepParserCOL, 0)
+}
+
+func (s *ForExpressionContext) ForBody() IForBodyContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IForBodyContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IForBodyContext)
+}
+
+func (s *ForExpressionContext) CBRACK() antlr.TerminalNode {
+ return s.GetToken(bicepParserCBRACK, 0)
+}
+
+func (s *ForExpressionContext) ForVariableBlock() IForVariableBlockContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IForVariableBlockContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IForVariableBlockContext)
+}
+
+func (s *ForExpressionContext) AllNL() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserNL)
+}
+
+func (s *ForExpressionContext) NL(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, i)
+}
+
+func (s *ForExpressionContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *ForExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ForExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ForExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitForExpression(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ForExpression() (localctx IForExpressionContext) {
+ localctx = NewForExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 26, bicepParserRULE_forExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(222)
+ p.Match(bicepParserOBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(226)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserNL {
+ {
+ p.SetState(223)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ p.SetState(228)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(229)
+ p.Match(bicepParserFOR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(232)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case bicepParserPARAM, bicepParserVAR, bicepParserTRUE, bicepParserFALSE, bicepParserNULL, bicepParserARRAY, bicepParserOBJECT, bicepParserRESOURCE, bicepParserOUTPUT, bicepParserTARGET_SCOPE, bicepParserIMPORT, bicepParserWITH, bicepParserAS, bicepParserMETADATA, bicepParserEXISTING, bicepParserTYPE, bicepParserMODULE, bicepParserSTRING, bicepParserINT, bicepParserBOOL, bicepParserIF, bicepParserFOR, bicepParserIN, bicepParserIDENTIFIER:
+ {
+ p.SetState(230)
+
+ var _x = p.Identifier()
+
+ localctx.(*ForExpressionContext).item = _x
+ }
+
+ case bicepParserOPAR:
+ {
+ p.SetState(231)
+ p.ForVariableBlock()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+ {
+ p.SetState(234)
+ p.Match(bicepParserIN)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(235)
+ p.expression(0)
+ }
+ {
+ p.SetState(236)
+ p.Match(bicepParserCOL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(237)
+ p.ForBody()
+ }
+ p.SetState(241)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserNL {
+ {
+ p.SetState(238)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ p.SetState(243)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(244)
+ p.Match(bicepParserCBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IForVariableBlockContext is an interface to support dynamic dispatch.
+type IForVariableBlockContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetItem returns the item rule contexts.
+ GetItem() IIdentifierContext
+
+ // GetIndex returns the index rule contexts.
+ GetIndex() IIdentifierContext
+
+ // SetItem sets the item rule contexts.
+ SetItem(IIdentifierContext)
+
+ // SetIndex sets the index rule contexts.
+ SetIndex(IIdentifierContext)
+
+ // Getter signatures
+ OPAR() antlr.TerminalNode
+ COMMA() antlr.TerminalNode
+ CPAR() antlr.TerminalNode
+ AllIdentifier() []IIdentifierContext
+ Identifier(i int) IIdentifierContext
+
+ // IsForVariableBlockContext differentiates from other interfaces.
+ IsForVariableBlockContext()
+}
+
+type ForVariableBlockContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ item IIdentifierContext
+ index IIdentifierContext
+}
+
+func NewEmptyForVariableBlockContext() *ForVariableBlockContext {
+ var p = new(ForVariableBlockContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_forVariableBlock
+ return p
+}
+
+func InitEmptyForVariableBlockContext(p *ForVariableBlockContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_forVariableBlock
+}
+
+func (*ForVariableBlockContext) IsForVariableBlockContext() {}
+
+func NewForVariableBlockContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForVariableBlockContext {
+ var p = new(ForVariableBlockContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_forVariableBlock
+
+ return p
+}
+
+func (s *ForVariableBlockContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ForVariableBlockContext) GetItem() IIdentifierContext { return s.item }
+
+func (s *ForVariableBlockContext) GetIndex() IIdentifierContext { return s.index }
+
+func (s *ForVariableBlockContext) SetItem(v IIdentifierContext) { s.item = v }
+
+func (s *ForVariableBlockContext) SetIndex(v IIdentifierContext) { s.index = v }
+
+func (s *ForVariableBlockContext) OPAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserOPAR, 0)
+}
+
+func (s *ForVariableBlockContext) COMMA() antlr.TerminalNode {
+ return s.GetToken(bicepParserCOMMA, 0)
+}
+
+func (s *ForVariableBlockContext) CPAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserCPAR, 0)
+}
+
+func (s *ForVariableBlockContext) AllIdentifier() []IIdentifierContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IIdentifierContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IIdentifierContext); ok {
+ tst[i] = t.(IIdentifierContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ForVariableBlockContext) Identifier(i int) IIdentifierContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *ForVariableBlockContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ForVariableBlockContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ForVariableBlockContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitForVariableBlock(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ForVariableBlock() (localctx IForVariableBlockContext) {
+ localctx = NewForVariableBlockContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 28, bicepParserRULE_forVariableBlock)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(246)
+ p.Match(bicepParserOPAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(247)
+
+ var _x = p.Identifier()
+
+ localctx.(*ForVariableBlockContext).item = _x
+ }
+ {
+ p.SetState(248)
+ p.Match(bicepParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(249)
+
+ var _x = p.Identifier()
+
+ localctx.(*ForVariableBlockContext).index = _x
+ }
+ {
+ p.SetState(250)
+ p.Match(bicepParserCPAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IForBodyContext is an interface to support dynamic dispatch.
+type IForBodyContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetBody returns the body rule contexts.
+ GetBody() IExpressionContext
+
+ // SetBody sets the body rule contexts.
+ SetBody(IExpressionContext)
+
+ // Getter signatures
+ Expression() IExpressionContext
+ IfCondition() IIfConditionContext
+
+ // IsForBodyContext differentiates from other interfaces.
+ IsForBodyContext()
+}
+
+type ForBodyContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ body IExpressionContext
+}
+
+func NewEmptyForBodyContext() *ForBodyContext {
+ var p = new(ForBodyContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_forBody
+ return p
+}
+
+func InitEmptyForBodyContext(p *ForBodyContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_forBody
+}
+
+func (*ForBodyContext) IsForBodyContext() {}
+
+func NewForBodyContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ForBodyContext {
+ var p = new(ForBodyContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_forBody
+
+ return p
+}
+
+func (s *ForBodyContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ForBodyContext) GetBody() IExpressionContext { return s.body }
+
+func (s *ForBodyContext) SetBody(v IExpressionContext) { s.body = v }
+
+func (s *ForBodyContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ForBodyContext) IfCondition() IIfConditionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIfConditionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIfConditionContext)
+}
+
+func (s *ForBodyContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ForBodyContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ForBodyContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitForBody(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ForBody() (localctx IForBodyContext) {
+ localctx = NewForBodyContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 30, bicepParserRULE_forBody)
+ p.SetState(254)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 21, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(252)
+
+ var _x = p.expression(0)
+
+ localctx.(*ForBodyContext).body = _x
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(253)
+ p.IfCondition()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IInterpStringContext is an interface to support dynamic dispatch.
+type IInterpStringContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ STRING_LEFT_PIECE() antlr.TerminalNode
+ AllExpression() []IExpressionContext
+ Expression(i int) IExpressionContext
+ STRING_RIGHT_PIECE() antlr.TerminalNode
+ AllSTRING_MIDDLE_PIECE() []antlr.TerminalNode
+ STRING_MIDDLE_PIECE(i int) antlr.TerminalNode
+ STRING_COMPLETE() antlr.TerminalNode
+
+ // IsInterpStringContext differentiates from other interfaces.
+ IsInterpStringContext()
+}
+
+type InterpStringContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyInterpStringContext() *InterpStringContext {
+ var p = new(InterpStringContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_interpString
+ return p
+}
+
+func InitEmptyInterpStringContext(p *InterpStringContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_interpString
+}
+
+func (*InterpStringContext) IsInterpStringContext() {}
+
+func NewInterpStringContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *InterpStringContext {
+ var p = new(InterpStringContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_interpString
+
+ return p
+}
+
+func (s *InterpStringContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *InterpStringContext) STRING_LEFT_PIECE() antlr.TerminalNode {
+ return s.GetToken(bicepParserSTRING_LEFT_PIECE, 0)
+}
+
+func (s *InterpStringContext) AllExpression() []IExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IExpressionContext); ok {
+ tst[i] = t.(IExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *InterpStringContext) Expression(i int) IExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *InterpStringContext) STRING_RIGHT_PIECE() antlr.TerminalNode {
+ return s.GetToken(bicepParserSTRING_RIGHT_PIECE, 0)
+}
+
+func (s *InterpStringContext) AllSTRING_MIDDLE_PIECE() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserSTRING_MIDDLE_PIECE)
+}
+
+func (s *InterpStringContext) STRING_MIDDLE_PIECE(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserSTRING_MIDDLE_PIECE, i)
+}
+
+func (s *InterpStringContext) STRING_COMPLETE() antlr.TerminalNode {
+ return s.GetToken(bicepParserSTRING_COMPLETE, 0)
+}
+
+func (s *InterpStringContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *InterpStringContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *InterpStringContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitInterpString(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) InterpString() (localctx IInterpStringContext) {
+ localctx = NewInterpStringContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 32, bicepParserRULE_interpString)
+ var _alt int
+
+ p.SetState(269)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case bicepParserSTRING_LEFT_PIECE:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(256)
+ p.Match(bicepParserSTRING_LEFT_PIECE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(262)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 22, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ if _alt == 1 {
+ {
+ p.SetState(257)
+ p.expression(0)
+ }
+ {
+ p.SetState(258)
+ p.Match(bicepParserSTRING_MIDDLE_PIECE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ p.SetState(264)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 22, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(265)
+ p.expression(0)
+ }
+ {
+ p.SetState(266)
+ p.Match(bicepParserSTRING_RIGHT_PIECE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case bicepParserSTRING_COMPLETE:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(268)
+ p.Match(bicepParserSTRING_COMPLETE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IExpressionContext is an interface to support dynamic dispatch.
+type IExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetProperty returns the property rule contexts.
+ GetProperty() IIdentifierContext
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // SetProperty sets the property rule contexts.
+ SetProperty(IIdentifierContext)
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // Getter signatures
+ PrimaryExpression() IPrimaryExpressionContext
+ AllExpression() []IExpressionContext
+ Expression(i int) IExpressionContext
+ QMARK() antlr.TerminalNode
+ COL() antlr.TerminalNode
+ LogicCharacter() ILogicCharacterContext
+ OBRACK() antlr.TerminalNode
+ CBRACK() antlr.TerminalNode
+ DOT() antlr.TerminalNode
+ Identifier() IIdentifierContext
+ FunctionCall() IFunctionCallContext
+
+ // IsExpressionContext differentiates from other interfaces.
+ IsExpressionContext()
+}
+
+type ExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ property IIdentifierContext
+ name IIdentifierContext
+}
+
+func NewEmptyExpressionContext() *ExpressionContext {
+ var p = new(ExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_expression
+ return p
+}
+
+func InitEmptyExpressionContext(p *ExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_expression
+}
+
+func (*ExpressionContext) IsExpressionContext() {}
+
+func NewExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ExpressionContext {
+ var p = new(ExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_expression
+
+ return p
+}
+
+func (s *ExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ExpressionContext) GetProperty() IIdentifierContext { return s.property }
+
+func (s *ExpressionContext) GetName() IIdentifierContext { return s.name }
+
+func (s *ExpressionContext) SetProperty(v IIdentifierContext) { s.property = v }
+
+func (s *ExpressionContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *ExpressionContext) PrimaryExpression() IPrimaryExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IPrimaryExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IPrimaryExpressionContext)
+}
+
+func (s *ExpressionContext) AllExpression() []IExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IExpressionContext); ok {
+ tst[i] = t.(IExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ExpressionContext) Expression(i int) IExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ExpressionContext) QMARK() antlr.TerminalNode {
+ return s.GetToken(bicepParserQMARK, 0)
+}
+
+func (s *ExpressionContext) COL() antlr.TerminalNode {
+ return s.GetToken(bicepParserCOL, 0)
+}
+
+func (s *ExpressionContext) LogicCharacter() ILogicCharacterContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ILogicCharacterContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ILogicCharacterContext)
+}
+
+func (s *ExpressionContext) OBRACK() antlr.TerminalNode {
+ return s.GetToken(bicepParserOBRACK, 0)
+}
+
+func (s *ExpressionContext) CBRACK() antlr.TerminalNode {
+ return s.GetToken(bicepParserCBRACK, 0)
+}
+
+func (s *ExpressionContext) DOT() antlr.TerminalNode {
+ return s.GetToken(bicepParserDOT, 0)
+}
+
+func (s *ExpressionContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *ExpressionContext) FunctionCall() IFunctionCallContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IFunctionCallContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IFunctionCallContext)
+}
+
+func (s *ExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitExpression(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) Expression() (localctx IExpressionContext) {
+ return p.expression(0)
+}
+
+func (p *bicepParser) expression(_p int) (localctx IExpressionContext) {
+ var _parentctx antlr.ParserRuleContext = p.GetParserRuleContext()
+
+ _parentState := p.GetState()
+ localctx = NewExpressionContext(p, p.GetParserRuleContext(), _parentState)
+ var _prevctx IExpressionContext = localctx
+ var _ antlr.ParserRuleContext = _prevctx // TODO: To prevent unused variable warning.
+ _startState := 34
+ p.EnterRecursionRule(localctx, 34, bicepParserRULE_expression, _p)
+ var _alt int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(272)
+ p.PrimaryExpression()
+ }
+
+ p.GetParserRuleContext().SetStop(p.GetTokenStream().LT(-1))
+ p.SetState(300)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 25, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ for _alt != 2 && _alt != antlr.ATNInvalidAltNumber {
+ if _alt == 1 {
+ if p.GetParseListeners() != nil {
+ p.TriggerExitRuleEvent()
+ }
+ _prevctx = localctx
+ p.SetState(298)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 24, p.GetParserRuleContext()) {
+ case 1:
+ localctx = NewExpressionContext(p, _parentctx, _parentState)
+ p.PushNewRecursionContext(localctx, _startState, bicepParserRULE_expression)
+ p.SetState(274)
+
+ if !(p.Precpred(p.GetParserRuleContext(), 6)) {
+ p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 6)", ""))
+ goto errorExit
+ }
+ {
+ p.SetState(275)
+ p.Match(bicepParserQMARK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(276)
+ p.expression(0)
+ }
+ {
+ p.SetState(277)
+ p.Match(bicepParserCOL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(278)
+ p.expression(7)
+ }
+
+ case 2:
+ localctx = NewExpressionContext(p, _parentctx, _parentState)
+ p.PushNewRecursionContext(localctx, _startState, bicepParserRULE_expression)
+ p.SetState(280)
+
+ if !(p.Precpred(p.GetParserRuleContext(), 2)) {
+ p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 2)", ""))
+ goto errorExit
+ }
+ {
+ p.SetState(281)
+ p.LogicCharacter()
+ }
+ {
+ p.SetState(282)
+ p.expression(3)
+ }
+
+ case 3:
+ localctx = NewExpressionContext(p, _parentctx, _parentState)
+ p.PushNewRecursionContext(localctx, _startState, bicepParserRULE_expression)
+ p.SetState(284)
+
+ if !(p.Precpred(p.GetParserRuleContext(), 7)) {
+ p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 7)", ""))
+ goto errorExit
+ }
+ {
+ p.SetState(285)
+ p.Match(bicepParserOBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(286)
+ p.expression(0)
+ }
+ {
+ p.SetState(287)
+ p.Match(bicepParserCBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case 4:
+ localctx = NewExpressionContext(p, _parentctx, _parentState)
+ p.PushNewRecursionContext(localctx, _startState, bicepParserRULE_expression)
+ p.SetState(289)
+
+ if !(p.Precpred(p.GetParserRuleContext(), 5)) {
+ p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 5)", ""))
+ goto errorExit
+ }
+ {
+ p.SetState(290)
+ p.Match(bicepParserDOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(291)
+
+ var _x = p.Identifier()
+
+ localctx.(*ExpressionContext).property = _x
+ }
+
+ case 5:
+ localctx = NewExpressionContext(p, _parentctx, _parentState)
+ p.PushNewRecursionContext(localctx, _startState, bicepParserRULE_expression)
+ p.SetState(292)
+
+ if !(p.Precpred(p.GetParserRuleContext(), 4)) {
+ p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 4)", ""))
+ goto errorExit
+ }
+ {
+ p.SetState(293)
+ p.Match(bicepParserDOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(294)
+ p.FunctionCall()
+ }
+
+ case 6:
+ localctx = NewExpressionContext(p, _parentctx, _parentState)
+ p.PushNewRecursionContext(localctx, _startState, bicepParserRULE_expression)
+ p.SetState(295)
+
+ if !(p.Precpred(p.GetParserRuleContext(), 3)) {
+ p.SetError(antlr.NewFailedPredicateException(p, "p.Precpred(p.GetParserRuleContext(), 3)", ""))
+ goto errorExit
+ }
+ {
+ p.SetState(296)
+ p.Match(bicepParserCOL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(297)
+
+ var _x = p.Identifier()
+
+ localctx.(*ExpressionContext).name = _x
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+ }
+ p.SetState(302)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _alt = p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 25, p.GetParserRuleContext())
+ if p.HasError() {
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.UnrollRecursionContexts(_parentctx)
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ILambdaExpressionContext is an interface to support dynamic dispatch.
+type ILambdaExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ ARROW() antlr.TerminalNode
+ Expression() IExpressionContext
+ OPAR() antlr.TerminalNode
+ CPAR() antlr.TerminalNode
+ Identifier() IIdentifierContext
+ ArgumentList() IArgumentListContext
+
+ // IsLambdaExpressionContext differentiates from other interfaces.
+ IsLambdaExpressionContext()
+}
+
+type LambdaExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyLambdaExpressionContext() *LambdaExpressionContext {
+ var p = new(LambdaExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_lambdaExpression
+ return p
+}
+
+func InitEmptyLambdaExpressionContext(p *LambdaExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_lambdaExpression
+}
+
+func (*LambdaExpressionContext) IsLambdaExpressionContext() {}
+
+func NewLambdaExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LambdaExpressionContext {
+ var p = new(LambdaExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_lambdaExpression
+
+ return p
+}
+
+func (s *LambdaExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *LambdaExpressionContext) ARROW() antlr.TerminalNode {
+ return s.GetToken(bicepParserARROW, 0)
+}
+
+func (s *LambdaExpressionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *LambdaExpressionContext) OPAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserOPAR, 0)
+}
+
+func (s *LambdaExpressionContext) CPAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserCPAR, 0)
+}
+
+func (s *LambdaExpressionContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *LambdaExpressionContext) ArgumentList() IArgumentListContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IArgumentListContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IArgumentListContext)
+}
+
+func (s *LambdaExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *LambdaExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *LambdaExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitLambdaExpression(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) LambdaExpression() (localctx ILambdaExpressionContext) {
+ localctx = NewLambdaExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 36, bicepParserRULE_lambdaExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(309)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case bicepParserOPAR:
+ {
+ p.SetState(303)
+ p.Match(bicepParserOPAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(305)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1691035998605394) != 0 {
+ {
+ p.SetState(304)
+ p.ArgumentList()
+ }
+
+ }
+ {
+ p.SetState(307)
+ p.Match(bicepParserCPAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case bicepParserPARAM, bicepParserVAR, bicepParserTRUE, bicepParserFALSE, bicepParserNULL, bicepParserARRAY, bicepParserOBJECT, bicepParserRESOURCE, bicepParserOUTPUT, bicepParserTARGET_SCOPE, bicepParserIMPORT, bicepParserWITH, bicepParserAS, bicepParserMETADATA, bicepParserEXISTING, bicepParserTYPE, bicepParserMODULE, bicepParserSTRING, bicepParserINT, bicepParserBOOL, bicepParserIF, bicepParserFOR, bicepParserIN, bicepParserIDENTIFIER:
+ {
+ p.SetState(308)
+ p.Identifier()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+ {
+ p.SetState(311)
+ p.Match(bicepParserARROW)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(312)
+ p.expression(0)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ILogicCharacterContext is an interface to support dynamic dispatch.
+type ILogicCharacterContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ GT() antlr.TerminalNode
+ GTE() antlr.TerminalNode
+ LT() antlr.TerminalNode
+ LTE() antlr.TerminalNode
+ EQ() antlr.TerminalNode
+ NEQ() antlr.TerminalNode
+
+ // IsLogicCharacterContext differentiates from other interfaces.
+ IsLogicCharacterContext()
+}
+
+type LogicCharacterContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyLogicCharacterContext() *LogicCharacterContext {
+ var p = new(LogicCharacterContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_logicCharacter
+ return p
+}
+
+func InitEmptyLogicCharacterContext(p *LogicCharacterContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_logicCharacter
+}
+
+func (*LogicCharacterContext) IsLogicCharacterContext() {}
+
+func NewLogicCharacterContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LogicCharacterContext {
+ var p = new(LogicCharacterContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_logicCharacter
+
+ return p
+}
+
+func (s *LogicCharacterContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *LogicCharacterContext) GT() antlr.TerminalNode {
+ return s.GetToken(bicepParserGT, 0)
+}
+
+func (s *LogicCharacterContext) GTE() antlr.TerminalNode {
+ return s.GetToken(bicepParserGTE, 0)
+}
+
+func (s *LogicCharacterContext) LT() antlr.TerminalNode {
+ return s.GetToken(bicepParserLT, 0)
+}
+
+func (s *LogicCharacterContext) LTE() antlr.TerminalNode {
+ return s.GetToken(bicepParserLTE, 0)
+}
+
+func (s *LogicCharacterContext) EQ() antlr.TerminalNode {
+ return s.GetToken(bicepParserEQ, 0)
+}
+
+func (s *LogicCharacterContext) NEQ() antlr.TerminalNode {
+ return s.GetToken(bicepParserNEQ, 0)
+}
+
+func (s *LogicCharacterContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *LogicCharacterContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *LogicCharacterContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitLogicCharacter(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) LogicCharacter() (localctx ILogicCharacterContext) {
+ localctx = NewLogicCharacterContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 38, bicepParserRULE_logicCharacter)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(314)
+ _la = p.GetTokenStream().LA(1)
+
+ if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&277076930199552) != 0) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IPrimaryExpressionContext is an interface to support dynamic dispatch.
+type IPrimaryExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ LiteralValue() ILiteralValueContext
+ FunctionCall() IFunctionCallContext
+ InterpString() IInterpStringContext
+ MULTILINE_STRING() antlr.TerminalNode
+ Array() IArrayContext
+ Object() IObjectContext
+ ForExpression() IForExpressionContext
+ ParenthesizedExpression() IParenthesizedExpressionContext
+ LambdaExpression() ILambdaExpressionContext
+
+ // IsPrimaryExpressionContext differentiates from other interfaces.
+ IsPrimaryExpressionContext()
+}
+
+type PrimaryExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyPrimaryExpressionContext() *PrimaryExpressionContext {
+ var p = new(PrimaryExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_primaryExpression
+ return p
+}
+
+func InitEmptyPrimaryExpressionContext(p *PrimaryExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_primaryExpression
+}
+
+func (*PrimaryExpressionContext) IsPrimaryExpressionContext() {}
+
+func NewPrimaryExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *PrimaryExpressionContext {
+ var p = new(PrimaryExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_primaryExpression
+
+ return p
+}
+
+func (s *PrimaryExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *PrimaryExpressionContext) LiteralValue() ILiteralValueContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ILiteralValueContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ILiteralValueContext)
+}
+
+func (s *PrimaryExpressionContext) FunctionCall() IFunctionCallContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IFunctionCallContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IFunctionCallContext)
+}
+
+func (s *PrimaryExpressionContext) InterpString() IInterpStringContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInterpStringContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInterpStringContext)
+}
+
+func (s *PrimaryExpressionContext) MULTILINE_STRING() antlr.TerminalNode {
+ return s.GetToken(bicepParserMULTILINE_STRING, 0)
+}
+
+func (s *PrimaryExpressionContext) Array() IArrayContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IArrayContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IArrayContext)
+}
+
+func (s *PrimaryExpressionContext) Object() IObjectContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IObjectContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IObjectContext)
+}
+
+func (s *PrimaryExpressionContext) ForExpression() IForExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IForExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IForExpressionContext)
+}
+
+func (s *PrimaryExpressionContext) ParenthesizedExpression() IParenthesizedExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IParenthesizedExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IParenthesizedExpressionContext)
+}
+
+func (s *PrimaryExpressionContext) LambdaExpression() ILambdaExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(ILambdaExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(ILambdaExpressionContext)
+}
+
+func (s *PrimaryExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *PrimaryExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *PrimaryExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitPrimaryExpression(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) PrimaryExpression() (localctx IPrimaryExpressionContext) {
+ localctx = NewPrimaryExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 40, bicepParserRULE_primaryExpression)
+ p.SetState(325)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 28, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(316)
+ p.LiteralValue()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(317)
+ p.FunctionCall()
+ }
+
+ case 3:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(318)
+ p.InterpString()
+ }
+
+ case 4:
+ p.EnterOuterAlt(localctx, 4)
+ {
+ p.SetState(319)
+ p.Match(bicepParserMULTILINE_STRING)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case 5:
+ p.EnterOuterAlt(localctx, 5)
+ {
+ p.SetState(320)
+ p.Array()
+ }
+
+ case 6:
+ p.EnterOuterAlt(localctx, 6)
+ {
+ p.SetState(321)
+ p.Object()
+ }
+
+ case 7:
+ p.EnterOuterAlt(localctx, 7)
+ {
+ p.SetState(322)
+ p.ForExpression()
+ }
+
+ case 8:
+ p.EnterOuterAlt(localctx, 8)
+ {
+ p.SetState(323)
+ p.ParenthesizedExpression()
+ }
+
+ case 9:
+ p.EnterOuterAlt(localctx, 9)
+ {
+ p.SetState(324)
+ p.LambdaExpression()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IParenthesizedExpressionContext is an interface to support dynamic dispatch.
+type IParenthesizedExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ OPAR() antlr.TerminalNode
+ Expression() IExpressionContext
+ CPAR() antlr.TerminalNode
+ AllNL() []antlr.TerminalNode
+ NL(i int) antlr.TerminalNode
+
+ // IsParenthesizedExpressionContext differentiates from other interfaces.
+ IsParenthesizedExpressionContext()
+}
+
+type ParenthesizedExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyParenthesizedExpressionContext() *ParenthesizedExpressionContext {
+ var p = new(ParenthesizedExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_parenthesizedExpression
+ return p
+}
+
+func InitEmptyParenthesizedExpressionContext(p *ParenthesizedExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_parenthesizedExpression
+}
+
+func (*ParenthesizedExpressionContext) IsParenthesizedExpressionContext() {}
+
+func NewParenthesizedExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ParenthesizedExpressionContext {
+ var p = new(ParenthesizedExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_parenthesizedExpression
+
+ return p
+}
+
+func (s *ParenthesizedExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ParenthesizedExpressionContext) OPAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserOPAR, 0)
+}
+
+func (s *ParenthesizedExpressionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ParenthesizedExpressionContext) CPAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserCPAR, 0)
+}
+
+func (s *ParenthesizedExpressionContext) AllNL() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserNL)
+}
+
+func (s *ParenthesizedExpressionContext) NL(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, i)
+}
+
+func (s *ParenthesizedExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ParenthesizedExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ParenthesizedExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitParenthesizedExpression(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ParenthesizedExpression() (localctx IParenthesizedExpressionContext) {
+ localctx = NewParenthesizedExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 42, bicepParserRULE_parenthesizedExpression)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(327)
+ p.Match(bicepParserOPAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(329)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserNL {
+ {
+ p.SetState(328)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(331)
+ p.expression(0)
+ }
+ p.SetState(333)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserNL {
+ {
+ p.SetState(332)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(335)
+ p.Match(bicepParserCPAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ITypeExpressionContext is an interface to support dynamic dispatch.
+type ITypeExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetType_ returns the type_ rule contexts.
+ GetType_() IIdentifierContext
+
+ // SetType_ sets the type_ rule contexts.
+ SetType_(IIdentifierContext)
+
+ // Getter signatures
+ Identifier() IIdentifierContext
+
+ // IsTypeExpressionContext differentiates from other interfaces.
+ IsTypeExpressionContext()
+}
+
+type TypeExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ type_ IIdentifierContext
+}
+
+func NewEmptyTypeExpressionContext() *TypeExpressionContext {
+ var p = new(TypeExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_typeExpression
+ return p
+}
+
+func InitEmptyTypeExpressionContext(p *TypeExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_typeExpression
+}
+
+func (*TypeExpressionContext) IsTypeExpressionContext() {}
+
+func NewTypeExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *TypeExpressionContext {
+ var p = new(TypeExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_typeExpression
+
+ return p
+}
+
+func (s *TypeExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *TypeExpressionContext) GetType_() IIdentifierContext { return s.type_ }
+
+func (s *TypeExpressionContext) SetType_(v IIdentifierContext) { s.type_ = v }
+
+func (s *TypeExpressionContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *TypeExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *TypeExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *TypeExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitTypeExpression(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) TypeExpression() (localctx ITypeExpressionContext) {
+ localctx = NewTypeExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 44, bicepParserRULE_typeExpression)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(337)
+
+ var _x = p.Identifier()
+
+ localctx.(*TypeExpressionContext).type_ = _x
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// ILiteralValueContext is an interface to support dynamic dispatch.
+type ILiteralValueContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ NUMBER() antlr.TerminalNode
+ TRUE() antlr.TerminalNode
+ FALSE() antlr.TerminalNode
+ NULL() antlr.TerminalNode
+ Identifier() IIdentifierContext
+
+ // IsLiteralValueContext differentiates from other interfaces.
+ IsLiteralValueContext()
+}
+
+type LiteralValueContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyLiteralValueContext() *LiteralValueContext {
+ var p = new(LiteralValueContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_literalValue
+ return p
+}
+
+func InitEmptyLiteralValueContext(p *LiteralValueContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_literalValue
+}
+
+func (*LiteralValueContext) IsLiteralValueContext() {}
+
+func NewLiteralValueContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *LiteralValueContext {
+ var p = new(LiteralValueContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_literalValue
+
+ return p
+}
+
+func (s *LiteralValueContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *LiteralValueContext) NUMBER() antlr.TerminalNode {
+ return s.GetToken(bicepParserNUMBER, 0)
+}
+
+func (s *LiteralValueContext) TRUE() antlr.TerminalNode {
+ return s.GetToken(bicepParserTRUE, 0)
+}
+
+func (s *LiteralValueContext) FALSE() antlr.TerminalNode {
+ return s.GetToken(bicepParserFALSE, 0)
+}
+
+func (s *LiteralValueContext) NULL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNULL, 0)
+}
+
+func (s *LiteralValueContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *LiteralValueContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *LiteralValueContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *LiteralValueContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitLiteralValue(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) LiteralValue() (localctx ILiteralValueContext) {
+ localctx = NewLiteralValueContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 46, bicepParserRULE_literalValue)
+ p.SetState(344)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 31, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(339)
+ p.Match(bicepParserNUMBER)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(340)
+ p.Match(bicepParserTRUE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case 3:
+ p.EnterOuterAlt(localctx, 3)
+ {
+ p.SetState(341)
+ p.Match(bicepParserFALSE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case 4:
+ p.EnterOuterAlt(localctx, 4)
+ {
+ p.SetState(342)
+ p.Match(bicepParserNULL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case 5:
+ p.EnterOuterAlt(localctx, 5)
+ {
+ p.SetState(343)
+ p.Identifier()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IObjectContext is an interface to support dynamic dispatch.
+type IObjectContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ OBRACE() antlr.TerminalNode
+ CBRACE() antlr.TerminalNode
+ AllNL() []antlr.TerminalNode
+ NL(i int) antlr.TerminalNode
+ AllObjectProperty() []IObjectPropertyContext
+ ObjectProperty(i int) IObjectPropertyContext
+
+ // IsObjectContext differentiates from other interfaces.
+ IsObjectContext()
+}
+
+type ObjectContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyObjectContext() *ObjectContext {
+ var p = new(ObjectContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_object
+ return p
+}
+
+func InitEmptyObjectContext(p *ObjectContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_object
+}
+
+func (*ObjectContext) IsObjectContext() {}
+
+func NewObjectContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ObjectContext {
+ var p = new(ObjectContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_object
+
+ return p
+}
+
+func (s *ObjectContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ObjectContext) OBRACE() antlr.TerminalNode {
+ return s.GetToken(bicepParserOBRACE, 0)
+}
+
+func (s *ObjectContext) CBRACE() antlr.TerminalNode {
+ return s.GetToken(bicepParserCBRACE, 0)
+}
+
+func (s *ObjectContext) AllNL() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserNL)
+}
+
+func (s *ObjectContext) NL(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, i)
+}
+
+func (s *ObjectContext) AllObjectProperty() []IObjectPropertyContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IObjectPropertyContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IObjectPropertyContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IObjectPropertyContext); ok {
+ tst[i] = t.(IObjectPropertyContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ObjectContext) ObjectProperty(i int) IObjectPropertyContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IObjectPropertyContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IObjectPropertyContext)
+}
+
+func (s *ObjectContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ObjectContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ObjectContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitObject(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) Object() (localctx IObjectContext) {
+ localctx = NewObjectContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 48, bicepParserRULE_object)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(346)
+ p.Match(bicepParserOBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(363)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserNL {
+ p.SetState(348)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for ok := true; ok; ok = _la == bicepParserNL {
+ {
+ p.SetState(347)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ p.SetState(350)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ p.SetState(360)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&565136091758592) != 0 {
+ {
+ p.SetState(352)
+ p.ObjectProperty()
+ }
+ p.SetState(354)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for ok := true; ok; ok = _la == bicepParserNL {
+ {
+ p.SetState(353)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ p.SetState(356)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+ p.SetState(362)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+ }
+ {
+ p.SetState(365)
+ p.Match(bicepParserCBRACE)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IObjectPropertyContext is an interface to support dynamic dispatch.
+type IObjectPropertyContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // GetName returns the name rule contexts.
+ GetName() IIdentifierContext
+
+ // SetName sets the name rule contexts.
+ SetName(IIdentifierContext)
+
+ // Getter signatures
+ COL() antlr.TerminalNode
+ Expression() IExpressionContext
+ InterpString() IInterpStringContext
+ Identifier() IIdentifierContext
+
+ // IsObjectPropertyContext differentiates from other interfaces.
+ IsObjectPropertyContext()
+}
+
+type ObjectPropertyContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+ name IIdentifierContext
+}
+
+func NewEmptyObjectPropertyContext() *ObjectPropertyContext {
+ var p = new(ObjectPropertyContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_objectProperty
+ return p
+}
+
+func InitEmptyObjectPropertyContext(p *ObjectPropertyContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_objectProperty
+}
+
+func (*ObjectPropertyContext) IsObjectPropertyContext() {}
+
+func NewObjectPropertyContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ObjectPropertyContext {
+ var p = new(ObjectPropertyContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_objectProperty
+
+ return p
+}
+
+func (s *ObjectPropertyContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ObjectPropertyContext) GetName() IIdentifierContext { return s.name }
+
+func (s *ObjectPropertyContext) SetName(v IIdentifierContext) { s.name = v }
+
+func (s *ObjectPropertyContext) COL() antlr.TerminalNode {
+ return s.GetToken(bicepParserCOL, 0)
+}
+
+func (s *ObjectPropertyContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ObjectPropertyContext) InterpString() IInterpStringContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IInterpStringContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IInterpStringContext)
+}
+
+func (s *ObjectPropertyContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *ObjectPropertyContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ObjectPropertyContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ObjectPropertyContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitObjectProperty(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ObjectProperty() (localctx IObjectPropertyContext) {
+ localctx = NewObjectPropertyContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 50, bicepParserRULE_objectProperty)
+ p.EnterOuterAlt(localctx, 1)
+ p.SetState(369)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetTokenStream().LA(1) {
+ case bicepParserPARAM, bicepParserVAR, bicepParserTRUE, bicepParserFALSE, bicepParserNULL, bicepParserARRAY, bicepParserOBJECT, bicepParserRESOURCE, bicepParserOUTPUT, bicepParserTARGET_SCOPE, bicepParserIMPORT, bicepParserWITH, bicepParserAS, bicepParserMETADATA, bicepParserEXISTING, bicepParserTYPE, bicepParserMODULE, bicepParserSTRING, bicepParserINT, bicepParserBOOL, bicepParserIF, bicepParserFOR, bicepParserIN, bicepParserIDENTIFIER:
+ {
+ p.SetState(367)
+
+ var _x = p.Identifier()
+
+ localctx.(*ObjectPropertyContext).name = _x
+ }
+
+ case bicepParserSTRING_LEFT_PIECE, bicepParserSTRING_COMPLETE:
+ {
+ p.SetState(368)
+ p.InterpString()
+ }
+
+ default:
+ p.SetError(antlr.NewNoViableAltException(p, nil, nil, nil, nil, nil))
+ goto errorExit
+ }
+ {
+ p.SetState(371)
+ p.Match(bicepParserCOL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(372)
+ p.expression(0)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IArrayContext is an interface to support dynamic dispatch.
+type IArrayContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ OBRACK() antlr.TerminalNode
+ CBRACK() antlr.TerminalNode
+ AllNL() []antlr.TerminalNode
+ NL(i int) antlr.TerminalNode
+ AllArrayItem() []IArrayItemContext
+ ArrayItem(i int) IArrayItemContext
+
+ // IsArrayContext differentiates from other interfaces.
+ IsArrayContext()
+}
+
+type ArrayContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyArrayContext() *ArrayContext {
+ var p = new(ArrayContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_array
+ return p
+}
+
+func InitEmptyArrayContext(p *ArrayContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_array
+}
+
+func (*ArrayContext) IsArrayContext() {}
+
+func NewArrayContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ArrayContext {
+ var p = new(ArrayContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_array
+
+ return p
+}
+
+func (s *ArrayContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ArrayContext) OBRACK() antlr.TerminalNode {
+ return s.GetToken(bicepParserOBRACK, 0)
+}
+
+func (s *ArrayContext) CBRACK() antlr.TerminalNode {
+ return s.GetToken(bicepParserCBRACK, 0)
+}
+
+func (s *ArrayContext) AllNL() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserNL)
+}
+
+func (s *ArrayContext) NL(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, i)
+}
+
+func (s *ArrayContext) AllArrayItem() []IArrayItemContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IArrayItemContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IArrayItemContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IArrayItemContext); ok {
+ tst[i] = t.(IArrayItemContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ArrayContext) ArrayItem(i int) IArrayItemContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IArrayItemContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IArrayItemContext)
+}
+
+func (s *ArrayContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ArrayContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ArrayContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitArray(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) Array() (localctx IArrayContext) {
+ localctx = NewArrayContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 52, bicepParserRULE_array)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(374)
+ p.Match(bicepParserOBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(378)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserNL {
+ {
+ p.SetState(375)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ p.SetState(380)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ p.SetState(384)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for (int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&1691035998605394) != 0 {
+ {
+ p.SetState(381)
+ p.ArrayItem()
+ }
+
+ p.SetState(386)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+ {
+ p.SetState(387)
+ p.Match(bicepParserCBRACK)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IArrayItemContext is an interface to support dynamic dispatch.
+type IArrayItemContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Expression() IExpressionContext
+ COMMA() antlr.TerminalNode
+ AllNL() []antlr.TerminalNode
+ NL(i int) antlr.TerminalNode
+
+ // IsArrayItemContext differentiates from other interfaces.
+ IsArrayItemContext()
+}
+
+type ArrayItemContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyArrayItemContext() *ArrayItemContext {
+ var p = new(ArrayItemContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_arrayItem
+ return p
+}
+
+func InitEmptyArrayItemContext(p *ArrayItemContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_arrayItem
+}
+
+func (*ArrayItemContext) IsArrayItemContext() {}
+
+func NewArrayItemContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ArrayItemContext {
+ var p = new(ArrayItemContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_arrayItem
+
+ return p
+}
+
+func (s *ArrayItemContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ArrayItemContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ArrayItemContext) COMMA() antlr.TerminalNode {
+ return s.GetToken(bicepParserCOMMA, 0)
+}
+
+func (s *ArrayItemContext) AllNL() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserNL)
+}
+
+func (s *ArrayItemContext) NL(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, i)
+}
+
+func (s *ArrayItemContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ArrayItemContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ArrayItemContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitArrayItem(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ArrayItem() (localctx IArrayItemContext) {
+ localctx = NewArrayItemContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 54, bicepParserRULE_arrayItem)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(389)
+ p.expression(0)
+ }
+ p.SetState(396)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ switch p.GetTokenStream().LA(1) {
+ case bicepParserNL:
+ p.SetState(391)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for ok := true; ok; ok = _la == bicepParserNL {
+ {
+ p.SetState(390)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ p.SetState(393)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+ case bicepParserCOMMA:
+ {
+ p.SetState(395)
+ p.Match(bicepParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ case bicepParserMULTILINE_STRING, bicepParserOBRACK, bicepParserCBRACK, bicepParserOPAR, bicepParserOBRACE, bicepParserPARAM, bicepParserVAR, bicepParserTRUE, bicepParserFALSE, bicepParserNULL, bicepParserARRAY, bicepParserOBJECT, bicepParserRESOURCE, bicepParserOUTPUT, bicepParserTARGET_SCOPE, bicepParserIMPORT, bicepParserWITH, bicepParserAS, bicepParserMETADATA, bicepParserEXISTING, bicepParserTYPE, bicepParserMODULE, bicepParserSTRING_LEFT_PIECE, bicepParserSTRING_COMPLETE, bicepParserSTRING, bicepParserINT, bicepParserBOOL, bicepParserIF, bicepParserFOR, bicepParserIN, bicepParserIDENTIFIER, bicepParserNUMBER:
+
+ default:
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IDecoratorContext is an interface to support dynamic dispatch.
+type IDecoratorContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AT() antlr.TerminalNode
+ DecoratorExpression() IDecoratorExpressionContext
+ NL() antlr.TerminalNode
+
+ // IsDecoratorContext differentiates from other interfaces.
+ IsDecoratorContext()
+}
+
+type DecoratorContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyDecoratorContext() *DecoratorContext {
+ var p = new(DecoratorContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_decorator
+ return p
+}
+
+func InitEmptyDecoratorContext(p *DecoratorContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_decorator
+}
+
+func (*DecoratorContext) IsDecoratorContext() {}
+
+func NewDecoratorContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *DecoratorContext {
+ var p = new(DecoratorContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_decorator
+
+ return p
+}
+
+func (s *DecoratorContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *DecoratorContext) AT() antlr.TerminalNode {
+ return s.GetToken(bicepParserAT, 0)
+}
+
+func (s *DecoratorContext) DecoratorExpression() IDecoratorExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IDecoratorExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IDecoratorExpressionContext)
+}
+
+func (s *DecoratorContext) NL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, 0)
+}
+
+func (s *DecoratorContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *DecoratorContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *DecoratorContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitDecorator(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) Decorator() (localctx IDecoratorContext) {
+ localctx = NewDecoratorContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 56, bicepParserRULE_decorator)
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(398)
+ p.Match(bicepParserAT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(399)
+ p.DecoratorExpression()
+ }
+ {
+ p.SetState(400)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IDecoratorExpressionContext is an interface to support dynamic dispatch.
+type IDecoratorExpressionContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ FunctionCall() IFunctionCallContext
+ Expression() IExpressionContext
+ DOT() antlr.TerminalNode
+
+ // IsDecoratorExpressionContext differentiates from other interfaces.
+ IsDecoratorExpressionContext()
+}
+
+type DecoratorExpressionContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyDecoratorExpressionContext() *DecoratorExpressionContext {
+ var p = new(DecoratorExpressionContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_decoratorExpression
+ return p
+}
+
+func InitEmptyDecoratorExpressionContext(p *DecoratorExpressionContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_decoratorExpression
+}
+
+func (*DecoratorExpressionContext) IsDecoratorExpressionContext() {}
+
+func NewDecoratorExpressionContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *DecoratorExpressionContext {
+ var p = new(DecoratorExpressionContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_decoratorExpression
+
+ return p
+}
+
+func (s *DecoratorExpressionContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *DecoratorExpressionContext) FunctionCall() IFunctionCallContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IFunctionCallContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IFunctionCallContext)
+}
+
+func (s *DecoratorExpressionContext) Expression() IExpressionContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *DecoratorExpressionContext) DOT() antlr.TerminalNode {
+ return s.GetToken(bicepParserDOT, 0)
+}
+
+func (s *DecoratorExpressionContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *DecoratorExpressionContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *DecoratorExpressionContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitDecoratorExpression(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) DecoratorExpression() (localctx IDecoratorExpressionContext) {
+ localctx = NewDecoratorExpressionContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 58, bicepParserRULE_decoratorExpression)
+ p.SetState(407)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+
+ switch p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 41, p.GetParserRuleContext()) {
+ case 1:
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(402)
+ p.FunctionCall()
+ }
+
+ case 2:
+ p.EnterOuterAlt(localctx, 2)
+ {
+ p.SetState(403)
+ p.expression(0)
+ }
+ {
+ p.SetState(404)
+ p.Match(bicepParserDOT)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ {
+ p.SetState(405)
+ p.FunctionCall()
+ }
+
+ case antlr.ATNInvalidAltNumber:
+ goto errorExit
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IFunctionCallContext is an interface to support dynamic dispatch.
+type IFunctionCallContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ Identifier() IIdentifierContext
+ OPAR() antlr.TerminalNode
+ CPAR() antlr.TerminalNode
+ ArgumentList() IArgumentListContext
+ AllNL() []antlr.TerminalNode
+ NL(i int) antlr.TerminalNode
+
+ // IsFunctionCallContext differentiates from other interfaces.
+ IsFunctionCallContext()
+}
+
+type FunctionCallContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyFunctionCallContext() *FunctionCallContext {
+ var p = new(FunctionCallContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_functionCall
+ return p
+}
+
+func InitEmptyFunctionCallContext(p *FunctionCallContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_functionCall
+}
+
+func (*FunctionCallContext) IsFunctionCallContext() {}
+
+func NewFunctionCallContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *FunctionCallContext {
+ var p = new(FunctionCallContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_functionCall
+
+ return p
+}
+
+func (s *FunctionCallContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *FunctionCallContext) Identifier() IIdentifierContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IIdentifierContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IIdentifierContext)
+}
+
+func (s *FunctionCallContext) OPAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserOPAR, 0)
+}
+
+func (s *FunctionCallContext) CPAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserCPAR, 0)
+}
+
+func (s *FunctionCallContext) ArgumentList() IArgumentListContext {
+ var t antlr.RuleContext
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IArgumentListContext); ok {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IArgumentListContext)
+}
+
+func (s *FunctionCallContext) AllNL() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserNL)
+}
+
+func (s *FunctionCallContext) NL(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, i)
+}
+
+func (s *FunctionCallContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *FunctionCallContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *FunctionCallContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitFunctionCall(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) FunctionCall() (localctx IFunctionCallContext) {
+ localctx = NewFunctionCallContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 60, bicepParserRULE_functionCall)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(409)
+ p.Identifier()
+ }
+ {
+ p.SetState(410)
+ p.Match(bicepParserOPAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(415)
+ p.GetErrorHandler().Sync(p)
+
+ if p.GetInterpreter().AdaptivePredict(p.BaseParser, p.GetTokenStream(), 43, p.GetParserRuleContext()) == 1 {
+ p.SetState(412)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserNL {
+ {
+ p.SetState(411)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(414)
+ p.ArgumentList()
+ }
+
+ } else if p.HasError() { // JIM
+ goto errorExit
+ }
+ p.SetState(418)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserNL {
+ {
+ p.SetState(417)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(420)
+ p.Match(bicepParserCPAR)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IArgumentListContext is an interface to support dynamic dispatch.
+type IArgumentListContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ AllExpression() []IExpressionContext
+ Expression(i int) IExpressionContext
+ AllCOMMA() []antlr.TerminalNode
+ COMMA(i int) antlr.TerminalNode
+ AllNL() []antlr.TerminalNode
+ NL(i int) antlr.TerminalNode
+
+ // IsArgumentListContext differentiates from other interfaces.
+ IsArgumentListContext()
+}
+
+type ArgumentListContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyArgumentListContext() *ArgumentListContext {
+ var p = new(ArgumentListContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_argumentList
+ return p
+}
+
+func InitEmptyArgumentListContext(p *ArgumentListContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_argumentList
+}
+
+func (*ArgumentListContext) IsArgumentListContext() {}
+
+func NewArgumentListContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *ArgumentListContext {
+ var p = new(ArgumentListContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_argumentList
+
+ return p
+}
+
+func (s *ArgumentListContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *ArgumentListContext) AllExpression() []IExpressionContext {
+ children := s.GetChildren()
+ len := 0
+ for _, ctx := range children {
+ if _, ok := ctx.(IExpressionContext); ok {
+ len++
+ }
+ }
+
+ tst := make([]IExpressionContext, len)
+ i := 0
+ for _, ctx := range children {
+ if t, ok := ctx.(IExpressionContext); ok {
+ tst[i] = t.(IExpressionContext)
+ i++
+ }
+ }
+
+ return tst
+}
+
+func (s *ArgumentListContext) Expression(i int) IExpressionContext {
+ var t antlr.RuleContext
+ j := 0
+ for _, ctx := range s.GetChildren() {
+ if _, ok := ctx.(IExpressionContext); ok {
+ if j == i {
+ t = ctx.(antlr.RuleContext)
+ break
+ }
+ j++
+ }
+ }
+
+ if t == nil {
+ return nil
+ }
+
+ return t.(IExpressionContext)
+}
+
+func (s *ArgumentListContext) AllCOMMA() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserCOMMA)
+}
+
+func (s *ArgumentListContext) COMMA(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserCOMMA, i)
+}
+
+func (s *ArgumentListContext) AllNL() []antlr.TerminalNode {
+ return s.GetTokens(bicepParserNL)
+}
+
+func (s *ArgumentListContext) NL(i int) antlr.TerminalNode {
+ return s.GetToken(bicepParserNL, i)
+}
+
+func (s *ArgumentListContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *ArgumentListContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *ArgumentListContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitArgumentList(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) ArgumentList() (localctx IArgumentListContext) {
+ localctx = NewArgumentListContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 62, bicepParserRULE_argumentList)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(422)
+ p.expression(0)
+ }
+ p.SetState(430)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ for _la == bicepParserCOMMA {
+ {
+ p.SetState(423)
+ p.Match(bicepParserCOMMA)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+ p.SetState(425)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+
+ if _la == bicepParserNL {
+ {
+ p.SetState(424)
+ p.Match(bicepParserNL)
+ if p.HasError() {
+ // Recognition error - abort rule
+ goto errorExit
+ }
+ }
+
+ }
+ {
+ p.SetState(427)
+ p.expression(0)
+ }
+
+ p.SetState(432)
+ p.GetErrorHandler().Sync(p)
+ if p.HasError() {
+ goto errorExit
+ }
+ _la = p.GetTokenStream().LA(1)
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+// IIdentifierContext is an interface to support dynamic dispatch.
+type IIdentifierContext interface {
+ antlr.ParserRuleContext
+
+ // GetParser returns the parser.
+ GetParser() antlr.Parser
+
+ // Getter signatures
+ IDENTIFIER() antlr.TerminalNode
+ IMPORT() antlr.TerminalNode
+ WITH() antlr.TerminalNode
+ AS() antlr.TerminalNode
+ METADATA() antlr.TerminalNode
+ PARAM() antlr.TerminalNode
+ RESOURCE() antlr.TerminalNode
+ MODULE() antlr.TerminalNode
+ OUTPUT() antlr.TerminalNode
+ EXISTING() antlr.TerminalNode
+ TYPE() antlr.TerminalNode
+ VAR() antlr.TerminalNode
+ IF() antlr.TerminalNode
+ FOR() antlr.TerminalNode
+ IN() antlr.TerminalNode
+ TRUE() antlr.TerminalNode
+ FALSE() antlr.TerminalNode
+ NULL() antlr.TerminalNode
+ TARGET_SCOPE() antlr.TerminalNode
+ STRING() antlr.TerminalNode
+ INT() antlr.TerminalNode
+ BOOL() antlr.TerminalNode
+ ARRAY() antlr.TerminalNode
+ OBJECT() antlr.TerminalNode
+
+ // IsIdentifierContext differentiates from other interfaces.
+ IsIdentifierContext()
+}
+
+type IdentifierContext struct {
+ antlr.BaseParserRuleContext
+ parser antlr.Parser
+}
+
+func NewEmptyIdentifierContext() *IdentifierContext {
+ var p = new(IdentifierContext)
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_identifier
+ return p
+}
+
+func InitEmptyIdentifierContext(p *IdentifierContext) {
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, nil, -1)
+ p.RuleIndex = bicepParserRULE_identifier
+}
+
+func (*IdentifierContext) IsIdentifierContext() {}
+
+func NewIdentifierContext(parser antlr.Parser, parent antlr.ParserRuleContext, invokingState int) *IdentifierContext {
+ var p = new(IdentifierContext)
+
+ antlr.InitBaseParserRuleContext(&p.BaseParserRuleContext, parent, invokingState)
+
+ p.parser = parser
+ p.RuleIndex = bicepParserRULE_identifier
+
+ return p
+}
+
+func (s *IdentifierContext) GetParser() antlr.Parser { return s.parser }
+
+func (s *IdentifierContext) IDENTIFIER() antlr.TerminalNode {
+ return s.GetToken(bicepParserIDENTIFIER, 0)
+}
+
+func (s *IdentifierContext) IMPORT() antlr.TerminalNode {
+ return s.GetToken(bicepParserIMPORT, 0)
+}
+
+func (s *IdentifierContext) WITH() antlr.TerminalNode {
+ return s.GetToken(bicepParserWITH, 0)
+}
+
+func (s *IdentifierContext) AS() antlr.TerminalNode {
+ return s.GetToken(bicepParserAS, 0)
+}
+
+func (s *IdentifierContext) METADATA() antlr.TerminalNode {
+ return s.GetToken(bicepParserMETADATA, 0)
+}
+
+func (s *IdentifierContext) PARAM() antlr.TerminalNode {
+ return s.GetToken(bicepParserPARAM, 0)
+}
+
+func (s *IdentifierContext) RESOURCE() antlr.TerminalNode {
+ return s.GetToken(bicepParserRESOURCE, 0)
+}
+
+func (s *IdentifierContext) MODULE() antlr.TerminalNode {
+ return s.GetToken(bicepParserMODULE, 0)
+}
+
+func (s *IdentifierContext) OUTPUT() antlr.TerminalNode {
+ return s.GetToken(bicepParserOUTPUT, 0)
+}
+
+func (s *IdentifierContext) EXISTING() antlr.TerminalNode {
+ return s.GetToken(bicepParserEXISTING, 0)
+}
+
+func (s *IdentifierContext) TYPE() antlr.TerminalNode {
+ return s.GetToken(bicepParserTYPE, 0)
+}
+
+func (s *IdentifierContext) VAR() antlr.TerminalNode {
+ return s.GetToken(bicepParserVAR, 0)
+}
+
+func (s *IdentifierContext) IF() antlr.TerminalNode {
+ return s.GetToken(bicepParserIF, 0)
+}
+
+func (s *IdentifierContext) FOR() antlr.TerminalNode {
+ return s.GetToken(bicepParserFOR, 0)
+}
+
+func (s *IdentifierContext) IN() antlr.TerminalNode {
+ return s.GetToken(bicepParserIN, 0)
+}
+
+func (s *IdentifierContext) TRUE() antlr.TerminalNode {
+ return s.GetToken(bicepParserTRUE, 0)
+}
+
+func (s *IdentifierContext) FALSE() antlr.TerminalNode {
+ return s.GetToken(bicepParserFALSE, 0)
+}
+
+func (s *IdentifierContext) NULL() antlr.TerminalNode {
+ return s.GetToken(bicepParserNULL, 0)
+}
+
+func (s *IdentifierContext) TARGET_SCOPE() antlr.TerminalNode {
+ return s.GetToken(bicepParserTARGET_SCOPE, 0)
+}
+
+func (s *IdentifierContext) STRING() antlr.TerminalNode {
+ return s.GetToken(bicepParserSTRING, 0)
+}
+
+func (s *IdentifierContext) INT() antlr.TerminalNode {
+ return s.GetToken(bicepParserINT, 0)
+}
+
+func (s *IdentifierContext) BOOL() antlr.TerminalNode {
+ return s.GetToken(bicepParserBOOL, 0)
+}
+
+func (s *IdentifierContext) ARRAY() antlr.TerminalNode {
+ return s.GetToken(bicepParserARRAY, 0)
+}
+
+func (s *IdentifierContext) OBJECT() antlr.TerminalNode {
+ return s.GetToken(bicepParserOBJECT, 0)
+}
+
+func (s *IdentifierContext) GetRuleContext() antlr.RuleContext {
+ return s
+}
+
+func (s *IdentifierContext) ToStringTree(ruleNames []string, recog antlr.Recognizer) string {
+ return antlr.TreesStringTree(s, ruleNames, recog)
+}
+
+func (s *IdentifierContext) Accept(visitor antlr.ParseTreeVisitor) interface{} {
+ switch t := visitor.(type) {
+ case bicepVisitor:
+ return t.VisitIdentifier(s)
+
+ default:
+ return t.VisitChildren(s)
+ }
+}
+
+func (p *bicepParser) Identifier() (localctx IIdentifierContext) {
+ localctx = NewIdentifierContext(p, p.GetParserRuleContext(), p.GetState())
+ p.EnterRule(localctx, 64, bicepParserRULE_identifier)
+ var _la int
+
+ p.EnterOuterAlt(localctx, 1)
+ {
+ p.SetState(433)
+ _la = p.GetTokenStream().LA(1)
+
+ if !((int64(_la) & ^0x3f) == 0 && ((int64(1)<<_la)&565116764405760) != 0) {
+ p.GetErrorHandler().RecoverInline(p)
+ } else {
+ p.GetErrorHandler().ReportMatch(p)
+ p.Consume()
+ }
+ }
+
+errorExit:
+ if p.HasError() {
+ v := p.GetError()
+ localctx.SetException(v)
+ p.GetErrorHandler().ReportError(p, v)
+ p.GetErrorHandler().Recover(p, v)
+ p.SetError(nil)
+ }
+ p.ExitRule()
+ return localctx
+ goto errorExit // Trick to prevent compiler error if the label is not used
+}
+
+func (p *bicepParser) Sempred(localctx antlr.RuleContext, ruleIndex, predIndex int) bool {
+ switch ruleIndex {
+ case 17:
+ var t *ExpressionContext = nil
+ if localctx != nil {
+ t = localctx.(*ExpressionContext)
+ }
+ return p.Expression_Sempred(t, predIndex)
+
+ default:
+ panic("No predicate with index: " + fmt.Sprint(ruleIndex))
+ }
+}
+
+func (p *bicepParser) Expression_Sempred(localctx antlr.RuleContext, predIndex int) bool {
+ switch predIndex {
+ case 0:
+ return p.Precpred(p.GetParserRuleContext(), 6)
+
+ case 1:
+ return p.Precpred(p.GetParserRuleContext(), 2)
+
+ case 2:
+ return p.Precpred(p.GetParserRuleContext(), 7)
+
+ case 3:
+ return p.Precpred(p.GetParserRuleContext(), 5)
+
+ case 4:
+ return p.Precpred(p.GetParserRuleContext(), 4)
+
+ case 5:
+ return p.Precpred(p.GetParserRuleContext(), 3)
+
+ default:
+ panic("No predicate with index: " + fmt.Sprint(predIndex))
+ }
+}
diff --git a/pkg/parser/bicep/antlr/parser/bicep_visitor.go b/pkg/parser/bicep/antlr/parser/bicep_visitor.go
new file mode 100644
index 00000000000..73793c7a585
--- /dev/null
+++ b/pkg/parser/bicep/antlr/parser/bicep_visitor.go
@@ -0,0 +1,109 @@
+// Code generated from bicep.g4 by ANTLR 4.13.1. DO NOT EDIT.
+
+package parser // bicep
+
+import "github.com/antlr4-go/antlr/v4"
+
+// A complete Visitor for a parse tree produced by bicepParser.
+type bicepVisitor interface {
+ antlr.ParseTreeVisitor
+
+ // Visit a parse tree produced by bicepParser#program.
+ VisitProgram(ctx *ProgramContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#statement.
+ VisitStatement(ctx *StatementContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#targetScopeDecl.
+ VisitTargetScopeDecl(ctx *TargetScopeDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#importDecl.
+ VisitImportDecl(ctx *ImportDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#metadataDecl.
+ VisitMetadataDecl(ctx *MetadataDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#parameterDecl.
+ VisitParameterDecl(ctx *ParameterDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#parameterDefaultValue.
+ VisitParameterDefaultValue(ctx *ParameterDefaultValueContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#typeDecl.
+ VisitTypeDecl(ctx *TypeDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#variableDecl.
+ VisitVariableDecl(ctx *VariableDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#resourceDecl.
+ VisitResourceDecl(ctx *ResourceDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#moduleDecl.
+ VisitModuleDecl(ctx *ModuleDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#outputDecl.
+ VisitOutputDecl(ctx *OutputDeclContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#ifCondition.
+ VisitIfCondition(ctx *IfConditionContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#forExpression.
+ VisitForExpression(ctx *ForExpressionContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#forVariableBlock.
+ VisitForVariableBlock(ctx *ForVariableBlockContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#forBody.
+ VisitForBody(ctx *ForBodyContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#interpString.
+ VisitInterpString(ctx *InterpStringContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#expression.
+ VisitExpression(ctx *ExpressionContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#lambdaExpression.
+ VisitLambdaExpression(ctx *LambdaExpressionContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#logicCharacter.
+ VisitLogicCharacter(ctx *LogicCharacterContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#primaryExpression.
+ VisitPrimaryExpression(ctx *PrimaryExpressionContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#parenthesizedExpression.
+ VisitParenthesizedExpression(ctx *ParenthesizedExpressionContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#typeExpression.
+ VisitTypeExpression(ctx *TypeExpressionContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#literalValue.
+ VisitLiteralValue(ctx *LiteralValueContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#object.
+ VisitObject(ctx *ObjectContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#objectProperty.
+ VisitObjectProperty(ctx *ObjectPropertyContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#array.
+ VisitArray(ctx *ArrayContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#arrayItem.
+ VisitArrayItem(ctx *ArrayItemContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#decorator.
+ VisitDecorator(ctx *DecoratorContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#decoratorExpression.
+ VisitDecoratorExpression(ctx *DecoratorExpressionContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#functionCall.
+ VisitFunctionCall(ctx *FunctionCallContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#argumentList.
+ VisitArgumentList(ctx *ArgumentListContext) interface{}
+
+ // Visit a parse tree produced by bicepParser#identifier.
+ VisitIdentifier(ctx *IdentifierContext) interface{}
+}
diff --git a/pkg/parser/bicep/parser.go b/pkg/parser/bicep/parser.go
new file mode 100644
index 00000000000..858c480c725
--- /dev/null
+++ b/pkg/parser/bicep/parser.go
@@ -0,0 +1,876 @@
+package bicep
+
+import (
+ "encoding/json"
+ "strconv"
+ "strings"
+
+ "github.com/Checkmarx/kics/v2/pkg/model"
+ "github.com/Checkmarx/kics/v2/pkg/parser/bicep/antlr/parser"
+ "github.com/antlr4-go/antlr/v4"
+)
+
+type Parser struct {
+}
+
+const kicsPrefix = "_kics_"
+const kicsLine = kicsPrefix + "line"
+const kicsLines = kicsPrefix + "lines"
+const kicsArray = kicsPrefix + "arr"
+
+const CloseParenthesis = "')"
+
+type BicepVisitor struct {
+ parser.BasebicepVisitor
+ paramList map[string]interface{}
+ varList map[string]interface{}
+ resourceList []interface{}
+}
+
+type JSONBicep struct {
+ Parameters map[string]interface{} `json:"parameters"`
+ Variables map[string]interface{} `json:"variables"`
+ Resources []interface{} `json:"resources"`
+}
+
+type KicsObjectProperty struct {
+ objectProperty map[string]interface{}
+ line int
+}
+
+func NewBicepVisitor() *BicepVisitor {
+ paramList := map[string]interface{}{}
+ varList := map[string]interface{}{}
+ resourceList := []interface{}{}
+ return &BicepVisitor{paramList: paramList, varList: varList, resourceList: resourceList}
+}
+
+func convertVisitorToJSONBicep(visitor *BicepVisitor) *JSONBicep {
+ return &JSONBicep{
+ Parameters: visitor.paramList,
+ Variables: visitor.varList,
+ Resources: visitor.resourceList,
+ }
+}
+
+type Resource struct {
+ Name string
+ FullType string
+ Parent string
+ Children []*Resource
+ ResourceData interface{}
+}
+
+// Filters the Resource array in order to keep only the top-level resources while reformatting them
+func filterParentStructs(resources []*Resource) []interface{} {
+ filteredResources := []interface{}{}
+
+ for _, resource := range resources {
+ if resource.Parent == "" {
+ formattedNode := reformatTestTree(resource)
+ filteredResources = append(filteredResources, formattedNode)
+ }
+ }
+
+ return filteredResources
+}
+
+func setChildType(child map[string]interface{}, parentType string) {
+ childType, hasType := child["type"]
+ if !hasType {
+ return
+ }
+ childTypeString, ok := childType.(string)
+ if !ok {
+ return
+ }
+ if parentType != "" {
+ childTypeString = strings.Replace(childTypeString, parentType+"/", "", 1)
+ child["type"] = childTypeString
+ }
+}
+
+// Converts Resource struct array back to a JBicep structure
+func reformatTestTree(resource *Resource) map[string]interface{} {
+ reformattedResource := map[string]interface{}{}
+
+ children := []interface{}{}
+ for _, child := range resource.Children {
+ formattedChild := reformatTestTree(child)
+ setChildType(formattedChild, resource.FullType)
+ children = append(children, formattedChild)
+ }
+ if len(children) > 0 {
+ reformattedResource["resources"] = children
+ }
+
+ resData, ok := resource.ResourceData.(map[string]interface{})
+ if !ok {
+ return reformattedResource
+ }
+ for k, v := range resData {
+ reformattedResource[k] = v
+ }
+
+ return reformattedResource
+}
+
+// Adds resource to its parent's children array
+func addChildrenToParents(resources []*Resource) {
+ resourceMap := map[string]*Resource{}
+
+ // Loops twice through the resources array in order to first fill the resourceMap with the required data
+ for _, resource := range resources {
+ resourceMap[resource.Name] = resource
+ }
+
+ for _, resource := range resources {
+ if resource.Parent != "" {
+ parent, ok := resourceMap[resource.Parent]
+ if !ok {
+ continue
+ }
+ parent.Children = append(parent.Children, resource)
+ }
+ }
+}
+
+// Converts JBicep structure to a Resource struct array
+func convertOriginalResourcesToStruct(resources []interface{}) []*Resource {
+ newResources := []*Resource{}
+
+ for _, res := range resources {
+ actualRes, ok := res.(map[string]interface{})
+ if !ok {
+ return newResources
+ }
+ resName, hasName := actualRes["identifier"]
+ resType, hasType := actualRes["type"]
+
+ if !hasName || !hasType {
+ return newResources
+ }
+
+ resNameString, ok := resName.(string)
+ if !ok {
+ return newResources
+ }
+ resTypeString, ok := resType.(string)
+ if !ok {
+ return newResources
+ }
+
+ newRes := Resource{
+ Name: resNameString,
+ FullType: resTypeString,
+ ResourceData: res,
+ }
+
+ if resParent, hasParent := actualRes["parent"]; hasParent {
+ var ok bool
+ newRes.Parent, ok = resParent.(string)
+ if !ok {
+ return newResources
+ }
+ }
+
+ newResources = append(newResources, &newRes)
+ }
+
+ return newResources
+}
+
+func makeResourcesNestedStructure(jBicep *JSONBicep) []interface{} {
+ originalResources := jBicep.Resources
+
+ resources := convertOriginalResourcesToStruct(originalResources)
+ addChildrenToParents(resources)
+ filteredResources := filterParentStructs(resources)
+
+ return filteredResources
+}
+
+// Parse - parses bicep to BicepVisitor template (json file)
+func (p *Parser) Parse(file string, _ []byte) ([]model.Document, []int, error) {
+ bicepVisitor := NewBicepVisitor()
+ stream, err := antlr.NewFileStream(file)
+ if err != nil {
+ return nil, nil, err
+ }
+ lexer := parser.NewbicepLexer(stream)
+
+ tokenStream := antlr.NewCommonTokenStream(lexer, antlr.TokenDefaultChannel)
+ bicepParser := parser.NewbicepParser(tokenStream)
+
+ bicepParser.RemoveErrorListeners()
+ bicepParser.AddErrorListener(antlr.NewDiagnosticErrorListener(true))
+
+ program := bicepParser.Program()
+ if program != nil {
+ program.Accept(bicepVisitor)
+ }
+
+ var doc model.Document
+
+ jBicep := convertVisitorToJSONBicep(bicepVisitor)
+
+ nestedResources := makeResourcesNestedStructure(jBicep)
+ jBicep.Resources = nestedResources
+
+ bicepBytes, err := json.Marshal(jBicep)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ err = json.Unmarshal(bicepBytes, &doc)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return []model.Document{doc}, nil, nil
+}
+
+func (s *BicepVisitor) VisitProgram(ctx *parser.ProgramContext) interface{} {
+ for _, val := range ctx.AllStatement() {
+ val.Accept(s)
+ }
+
+ return nil
+}
+
+func (s *BicepVisitor) VisitStatement(ctx *parser.StatementContext) interface{} {
+ if ctx.ParameterDecl() != nil {
+ return ctx.ParameterDecl().Accept(s)
+ }
+ if ctx.VariableDecl() != nil {
+ return ctx.VariableDecl().Accept(s)
+ }
+ if ctx.ResourceDecl() != nil {
+ return ctx.ResourceDecl().Accept(s)
+ }
+
+ return nil
+}
+
+func parseDecorators(decorators []parser.IDecoratorContext, s *BicepVisitor) map[string]interface{} {
+ decoratorsMap := map[string]interface{}{}
+
+ for _, val := range decorators {
+ if val == nil {
+ continue
+ }
+
+ decorator, ok := val.Accept(s).(map[string][]interface{})
+ if !ok {
+ return map[string]interface{}{}
+ }
+ for name, values := range decorator {
+ if name == "description" {
+ if len(values) > 0 {
+ metadata := map[string]interface{}{}
+ metadata["description"] = values[0]
+ decoratorsMap["metadata"] = metadata
+ }
+ } else if name == "maxLength" || name == "minLength" || name == "minValue" || name == "maxValue" {
+ if len(values) > 0 {
+ decoratorsMap[name] = values[0]
+ }
+ } else {
+ decoratorsMap[name] = values
+ }
+ }
+ }
+
+ return decoratorsMap
+}
+
+func (s *BicepVisitor) VisitParameterDecl(ctx *parser.ParameterDeclContext) interface{} {
+ param := map[string]interface{}{}
+
+ identifier := checkAcceptAntlrString(ctx.Identifier(), s)
+
+ if ctx.ParameterDefaultValue() != nil {
+ paramVal := ctx.ParameterDefaultValue().Accept(s)
+ switch paramVal := paramVal.(type) {
+ case map[string][]interface{}:
+ stringifiedFunction := parseFunctionCall(paramVal)
+ param["defaultValue"] = "[" + stringifiedFunction + "]"
+ case interface{}:
+ if isDotFunction(paramVal) {
+ paramVal = "[" + paramVal.(string) + "]"
+ }
+ param["defaultValue"] = paramVal
+ default:
+ param["defaultValue"] = nil
+ }
+ }
+
+ if ctx.TypeExpression() != nil {
+ typeExpression := ctx.TypeExpression().Accept(s)
+ param["type"] = typeExpression
+ }
+
+ decoratorsMap := parseDecorators(ctx.AllDecorator(), s)
+ for name, values := range decoratorsMap {
+ if name == "secure" {
+ if param["type"] == "string" {
+ param["type"] = "secureString"
+ } else if param["type"] == "object" {
+ param["type"] = "secureObject"
+ }
+ } else {
+ if name == "allowed" {
+ param["allowedValues"] = values
+ } else {
+ param[name] = values
+ }
+ }
+ }
+
+ line := map[string]int{kicsLine: ctx.GetStop().GetLine()}
+ lines := map[string]map[string]int{
+ kicsPrefix + "defaultValue": line,
+ kicsPrefix + "type": line,
+ }
+
+ param[kicsLines] = lines
+
+ s.paramList[identifier] = param
+
+ return nil
+}
+
+func (s *BicepVisitor) VisitVariableDecl(ctx *parser.VariableDeclContext) interface{} {
+ var variable = map[string]interface{}{}
+
+ identifier := checkAcceptAntlrString(ctx.Identifier(), s)
+
+ decoratorsMap := parseDecorators(ctx.AllDecorator(), s)
+ for name, values := range decoratorsMap {
+ variable[name] = values
+ }
+
+ expression := checkAcceptExpression(ctx.Expression(), s)
+ variable["value"] = expression
+ s.varList[identifier] = variable
+
+ return nil
+}
+
+func (s *BicepVisitor) VisitResourceDecl(ctx *parser.ResourceDeclContext) interface{} {
+ resource := map[string]interface{}{}
+ resourceType := ""
+ apiVersion := ""
+
+ interpString := checkAcceptAntlrString(ctx.InterpString(), s)
+ identifier := checkAcceptAntlrString(ctx.Identifier(), s)
+
+ fullType := strings.Split(interpString, "@")
+ if len(fullType) > 0 {
+ resourceType = fullType[0]
+ }
+ if len(fullType) > 1 {
+ apiVersion = fullType[1]
+ }
+
+ resource["identifier"] = identifier
+ resource["type"] = resourceType
+ resource["apiVersion"] = apiVersion
+
+ decoratorsMap := parseDecorators(ctx.AllDecorator(), s)
+ for name, values := range decoratorsMap {
+ resource[name] = values
+ }
+
+ if ctx.Object() != nil {
+ object, ok := ctx.Object().Accept(s).(map[string]interface{})
+ if ok {
+ for key, val := range object {
+ resource[key] = val
+ }
+ }
+ }
+
+ lines := map[string]interface{}{}
+ if resKicsLines, hasLines := resource[kicsLines]; hasLines {
+ var ok bool
+ lines, ok = resKicsLines.(map[string]interface{})
+ if !ok {
+ lines = map[string]interface{}{}
+ }
+ }
+
+ line := map[string]int{kicsLine: ctx.GetStart().GetLine()}
+ lines[kicsPrefix+"apiVersion"] = line
+ lines[kicsPrefix+"type"] = line
+
+ s.resourceList = append(s.resourceList, resource)
+
+ return nil
+}
+
+func checkAcceptAntlrString(ctx antlr.ParserRuleContext, s *BicepVisitor) string {
+ if ctx != nil {
+ if result, ok := ctx.Accept(s).(string); ok {
+ return result
+ }
+ }
+
+ return ""
+}
+
+func checkAcceptExpression(ctx antlr.ParserRuleContext, s *BicepVisitor) interface{} {
+ if ctx != nil {
+ return ctx.Accept(s)
+ }
+
+ return ""
+}
+
+func (s *BicepVisitor) VisitParameterDefaultValue(ctx *parser.ParameterDefaultValueContext) interface{} {
+ param := checkAcceptExpression(ctx.Expression(), s)
+ return param
+}
+
+/*
+Converts functioncall data (map of identifying string to slice of arguments) into a string
+
+ Example: "FunctionName": ["arg1", 2, "arg3", map[Function2: [arg4, arg5]]] becomes
+ "FunctionName(arg1, 2, arg3, Function2(arg4, arg5))"
+*/
+func parseFunctionCall(functionData map[string][]interface{}) string {
+ stringifiedFunctionCall := ""
+
+ for functionName, argumentList := range functionData {
+ stringifiedFunctionCall += functionName + "("
+ for index, argument := range argumentList {
+ switch argument := argument.(type) {
+ case string:
+ stringifiedFunctionCall += argument
+ case int:
+ convertedArgument := strconv.Itoa(argument)
+ stringifiedFunctionCall += convertedArgument
+ case map[string][]interface{}:
+ stringifiedFunctionCall += parseFunctionCall(argument)
+ }
+
+ if index < len(argumentList)-1 {
+ stringifiedFunctionCall += ", "
+ }
+ }
+ stringifiedFunctionCall += ")"
+ }
+
+ return stringifiedFunctionCall
+}
+
+// function to check if an identifier is a parameter/variable and add the required keyword if so
+func convertToParamVar(str string, s *BicepVisitor) string {
+ for variable := range s.varList {
+ if variable == str {
+ return "variables('" + str + CloseParenthesis
+ }
+ }
+ for parameter := range s.paramList {
+ if parameter == str {
+ return "parameters('" + str + CloseParenthesis
+ }
+ }
+
+ return str
+}
+
+func (s *BicepVisitor) VisitExpression(ctx *parser.ExpressionContext) interface{} {
+ if ctx.GetChildCount() > 1 {
+ if ctx.DOT() != nil {
+ var expressionString string
+
+ var exp interface{} = ""
+ if ctx.Expression(0) != nil {
+ exp = ctx.Expression(0).Accept(s)
+ }
+
+ switch exp := exp.(type) {
+ case map[string][]interface{}:
+ expressionString = parseFunctionCall(exp)
+ case string:
+ expressionString = exp
+ default:
+ expressionString = ""
+ }
+
+ if ctx.Identifier() != nil {
+ identifier := checkAcceptAntlrString(ctx.Identifier(), s)
+ identifier = convertToParamVar(identifier, s)
+
+ return expressionString + "." + identifier
+ }
+
+ if ctx.FunctionCall() != nil {
+ fc := ctx.FunctionCall().Accept(s)
+ fcData, ok := fc.(map[string][]interface{})
+ if !ok {
+ return ""
+ }
+ functionCallString := parseFunctionCall(fcData)
+ return expressionString + "." + functionCallString
+ }
+ }
+ }
+
+ if ctx.PrimaryExpression() != nil {
+ return ctx.PrimaryExpression().Accept(s)
+ }
+
+ return nil
+}
+
+func (s *BicepVisitor) VisitPrimaryExpression(ctx *parser.PrimaryExpressionContext) interface{} {
+ if ctx.LiteralValue() != nil {
+ return ctx.LiteralValue().Accept(s)
+ }
+ if ctx.FunctionCall() != nil {
+ return ctx.FunctionCall().Accept(s)
+ }
+ if ctx.InterpString() != nil {
+ return ctx.InterpString().Accept(s)
+ }
+ if ctx.MULTILINE_STRING() != nil {
+ finalString := strings.ReplaceAll(ctx.MULTILINE_STRING().GetText(), "'''", "")
+ finalString = strings.ReplaceAll(finalString, "\r", "")
+ finalString = strings.ReplaceAll(finalString, "\n", "")
+ return finalString
+ }
+ if ctx.Array() != nil {
+ return ctx.Array().Accept(s)
+ }
+ if ctx.Object() != nil {
+ return ctx.Object().Accept(s)
+ }
+ if ctx.ParenthesizedExpression() != nil {
+ return ctx.ParenthesizedExpression().Accept(s)
+ }
+
+ return nil
+}
+
+func (s *BicepVisitor) VisitLiteralValue(ctx *parser.LiteralValueContext) interface{} {
+ if ctx.NUMBER() != nil {
+ number, _ := strconv.ParseFloat(ctx.NUMBER().GetText(), 32)
+ return number
+ }
+ if ctx.TRUE() != nil {
+ return true
+ }
+ if ctx.FALSE() != nil {
+ return false
+ }
+ if ctx.Identifier() != nil {
+ identifier, ok := ctx.Identifier().Accept(s).(string)
+ if ok {
+ identifier = convertToParamVar(identifier, s)
+ return identifier
+ }
+ }
+
+ return nil
+}
+
+func acceptExpressionAtIndex(idx int, ctx *parser.InterpStringContext, s *BicepVisitor) interface{} {
+ if ctx.Expression(idx) != nil {
+ return ctx.Expression(idx).Accept(s)
+ }
+
+ return ""
+}
+
+func buildComplexInterp(interpStringValues []interface{}) string {
+ str := ""
+ for _, v := range interpStringValues {
+ switch v := v.(type) {
+ case string:
+ str += v
+ case map[string][]interface{}:
+ for identifier, argumentList := range v {
+ resStr := "[" + identifier + "("
+ for idx, arg := range argumentList {
+ stringArg, ok := arg.(string)
+ if !ok {
+ return ""
+ }
+ resStr += stringArg
+ if idx < len(argumentList)-1 {
+ resStr += ", "
+ }
+ }
+
+ resStr += ")]"
+ str += resStr
+ }
+ }
+ }
+
+ return str
+}
+
+func parseComplexInterp(ctx *parser.InterpStringContext, s *BicepVisitor) string {
+ interpString := []interface{}{}
+
+ if ctx.STRING_LEFT_PIECE() == nil || ctx.STRING_RIGHT_PIECE() == nil {
+ return ""
+ }
+
+ leftPiece := ctx.STRING_LEFT_PIECE().GetText()
+ rightPiece := ctx.STRING_RIGHT_PIECE().GetText()
+ middlePieces := ctx.AllSTRING_MIDDLE_PIECE()
+
+ interpString = append(interpString, leftPiece)
+
+ if middlePieces != nil && (len(middlePieces) > 0) {
+ for idx, val := range middlePieces {
+ expression := acceptExpressionAtIndex(idx, ctx, s)
+ interpString = append(interpString, expression, val.GetText())
+ }
+ }
+
+ lastExpression := acceptExpressionAtIndex(len(middlePieces), ctx, s)
+ interpString = append(interpString,
+ lastExpression,
+ rightPiece)
+
+ resultString := buildComplexInterp(interpString)
+
+ return resultString
+}
+
+func (s *BicepVisitor) VisitInterpString(ctx *parser.InterpStringContext) interface{} {
+ if ctx.GetChildCount() > 1 {
+ complexInterpString := parseComplexInterp(ctx, s)
+ return complexInterpString
+ }
+
+ if ctx.STRING_COMPLETE() != nil {
+ unformattedString := ctx.STRING_COMPLETE().GetText()
+ finalString := strings.ReplaceAll(unformattedString, "'", "")
+ return finalString
+ }
+
+ return ""
+}
+
+func (s *BicepVisitor) VisitArray(ctx *parser.ArrayContext) interface{} {
+ array := []interface{}{}
+ for _, val := range ctx.AllArrayItem() {
+ expression := val.Accept(s)
+ if isParameter(expression) || isDotFunction(expression) {
+ expression = "[" + expression.(string) + "]"
+ }
+ array = append(array, expression)
+ }
+ return array
+}
+
+func (s *BicepVisitor) VisitArrayItem(ctx *parser.ArrayItemContext) interface{} {
+ return checkAcceptExpression(ctx.Expression(), s)
+}
+
+func isParameter(expression interface{}) bool {
+ exp, ok := expression.(string)
+ if !ok {
+ return false
+ }
+
+ return strings.Contains(exp, "parameters(") || strings.Contains(exp, "variables(")
+}
+
+func isDotFunction(expression interface{}) bool {
+ exp, ok := expression.(string)
+ if !ok {
+ return false
+ }
+
+ return strings.Contains(exp, ").")
+}
+
+func (s *BicepVisitor) VisitObject(ctx *parser.ObjectContext) interface{} {
+ object := map[string]interface{}{}
+ propertiesLines := map[string]interface{}{}
+
+ for _, val := range ctx.AllObjectProperty() {
+ objectProperty, ok := val.Accept(s).(KicsObjectProperty)
+ if !ok {
+ return object
+ }
+ for key, val := range objectProperty.objectProperty {
+ object[key] = val
+ line := map[string]interface{}{kicsLine: objectProperty.line}
+
+ arr, isArray := val.([]interface{})
+ if isArray {
+ for range arr {
+ arrLine := map[string]int{kicsLine: objectProperty.line}
+ kicsDefault := map[string]interface{}{kicsPrefix + "_default": arrLine}
+ kicsArr := []interface{}{kicsDefault}
+ line[kicsArray] = kicsArr
+ }
+ }
+ propertiesLines[kicsPrefix+key] = line
+ }
+ }
+
+ defaultLine := map[string]int{kicsLine: ctx.GetStart().GetLine()}
+ propertiesLines[kicsPrefix+"_default"] = defaultLine
+
+ object[kicsLines] = propertiesLines
+
+ return object
+}
+
+func (s *BicepVisitor) VisitObjectProperty(ctx *parser.ObjectPropertyContext) interface{} {
+ objectProperty := map[string]interface{}{}
+
+ if ctx.Expression() != nil {
+ objectValue := ctx.Expression().Accept(s)
+ if isParameter(objectValue) || isDotFunction(objectValue) {
+ objectValue = "[" + objectValue.(string) + "]"
+ }
+
+ if ctx.Identifier() != nil {
+ identifier, ok := ctx.Identifier().Accept(s).(string)
+ if ok {
+ objectProperty[identifier] = objectValue
+ }
+ }
+ if ctx.InterpString() != nil {
+ interpString, ok := ctx.InterpString().Accept(s).(string)
+ if ok {
+ objectProperty[interpString] = objectValue
+ }
+ }
+ }
+
+ return KicsObjectProperty{objectProperty: objectProperty, line: ctx.GetStart().GetLine()}
+}
+
+func (s *BicepVisitor) VisitIdentifier(ctx *parser.IdentifierContext) interface{} {
+ contexts := []antlr.TerminalNode{
+ ctx.IDENTIFIER(),
+ ctx.IMPORT(),
+ ctx.WITH(),
+ ctx.AS(),
+ ctx.METADATA(),
+ ctx.PARAM(),
+ ctx.RESOURCE(),
+ ctx.OUTPUT(),
+ ctx.EXISTING(),
+ ctx.VAR(),
+ ctx.IF(),
+ ctx.FOR(),
+ ctx.IN(),
+ ctx.TRUE(),
+ ctx.FALSE(),
+ ctx.NULL(),
+ ctx.TARGET_SCOPE(),
+ ctx.STRING(),
+ ctx.INT(),
+ ctx.BOOL(),
+ ctx.ARRAY(),
+ ctx.OBJECT(),
+ ctx.TYPE(),
+ ctx.MODULE(),
+ }
+
+ for _, context := range contexts {
+ if context != nil {
+ return context.GetText()
+ }
+ }
+
+ return ""
+}
+
+func (s *BicepVisitor) VisitParenthesizedExpression(ctx *parser.ParenthesizedExpressionContext) interface{} {
+ return checkAcceptExpression(ctx.Expression(), s)
+}
+
+func (s *BicepVisitor) VisitDecorator(ctx *parser.DecoratorContext) interface{} {
+ if ctx.DecoratorExpression() == nil {
+ return map[string][]interface{}{}
+ }
+ decorator := ctx.DecoratorExpression().Accept(s)
+ return decorator
+}
+
+func (s *BicepVisitor) VisitDecoratorExpression(ctx *parser.DecoratorExpressionContext) interface{} {
+ if ctx.FunctionCall() == nil {
+ return map[string][]interface{}{}
+ }
+ return ctx.FunctionCall().Accept(s)
+}
+
+func (s *BicepVisitor) VisitFunctionCall(ctx *parser.FunctionCallContext) interface{} {
+ var argumentList []interface{}
+ identifier := checkAcceptAntlrString(ctx.Identifier(), s)
+
+ if ctx.ArgumentList() != nil {
+ var ok bool
+ argumentList, ok = ctx.ArgumentList().Accept(s).([]interface{})
+ if !ok {
+ return map[string]interface{}{}
+ }
+ }
+ functionCall := map[string][]interface{}{
+ identifier: argumentList,
+ }
+
+ return functionCall
+}
+
+func (s *BicepVisitor) VisitArgumentList(ctx *parser.ArgumentListContext) interface{} {
+ var argumentList []interface{}
+
+ for _, val := range ctx.AllExpression() {
+ argument := val.Accept(s)
+ argumentList = append(argumentList, argument)
+ }
+ return argumentList
+}
+
+func (s *BicepVisitor) VisitTypeExpression(ctx *parser.TypeExpressionContext) interface{} {
+ return checkAcceptAntlrString(ctx.Identifier(), s)
+}
+
+// GetKind returns the kind of the parser
+func (p *Parser) GetKind() model.FileKind {
+ return model.KindBICEP
+}
+
+// SupportedExtensions returns Bicep extensions
+func (p *Parser) SupportedExtensions() []string {
+ return []string{".bicep"}
+}
+
+// SupportedTypes returns types supported by this parser, which are bicep files
+func (p *Parser) SupportedTypes() map[string]bool {
+ return map[string]bool{"bicep": true, "azureresourcemanager": true}
+}
+
+// GetCommentToken return the comment token of Bicep files - #
+func (p *Parser) GetCommentToken() string {
+ return "//"
+}
+
+// StringifyContent converts original content into string formatted version
+func (p *Parser) StringifyContent(content []byte) (string, error) {
+ return string(content), nil
+}
+
+// Resolve resolves bicep files variables
+func (p *Parser) Resolve(fileContent []byte, _ string, _ bool, _ int) ([]byte, error) {
+ return fileContent, nil
+}
+
+// GetResolvedFiles returns the list of files that are resolved
+func (p *Parser) GetResolvedFiles() map[string]model.ResolvedFile {
+ return make(map[string]model.ResolvedFile)
+}
diff --git a/pkg/parser/bicep/parser_test.go b/pkg/parser/bicep/parser_test.go
new file mode 100644
index 00000000000..30f47275af4
--- /dev/null
+++ b/pkg/parser/bicep/parser_test.go
@@ -0,0 +1,1737 @@
+package bicep
+
+import (
+ "encoding/json"
+ "path/filepath"
+ "reflect"
+ "testing"
+
+ "github.com/Checkmarx/kics/v2/pkg/model"
+ "github.com/stretchr/testify/require"
+)
+
+func TestParser_GetKind(t *testing.T) {
+ p := &Parser{}
+ require.Equal(t, model.KindBICEP, p.GetKind())
+}
+
+func TestParser_SupportedTypes(t *testing.T) {
+ p := &Parser{}
+ require.Equal(t, map[string]bool{"bicep": true, "azureresourcemanager": true}, p.SupportedTypes())
+}
+
+func TestParser_SupportedExtensions(t *testing.T) {
+ p := &Parser{}
+ require.Equal(t, []string{".bicep"}, p.SupportedExtensions())
+}
+
+func Test_Resolve(t *testing.T) {
+ parser := &Parser{}
+ param := `param vmName string = 'simple-vm'`
+ resolved, err := parser.Resolve([]byte(param), "test.bicep", true, 15)
+ require.NoError(t, err)
+ require.Equal(t, []byte(param), resolved)
+}
+
+func TestParser_GetResolvedFiles(t *testing.T) {
+ tests := []struct {
+ name string
+ want map[string]model.ResolvedFile
+ }{
+ {
+ name: "Should test getting empty resolved files",
+ want: map[string]model.ResolvedFile{},
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ p := &Parser{}
+ if got := p.GetResolvedFiles(); !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("GetResolvedFiles() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+// TestParser_StringifyContent tests the StringifyContent function
+func TestParser_StringifyContent(t *testing.T) {
+ type args struct {
+ content []byte
+ }
+ tests := []struct {
+ name string
+ p *Parser
+ args args
+ want string
+ wantErr bool
+ }{
+ {
+ name: "Bicep stringify content",
+ p: &Parser{},
+ args: args{
+ content: []byte(`param vmName string = 'simple-vm'`),
+ },
+ want: `param vmName string = 'simple-vm'`,
+ wantErr: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ p := &Parser{}
+ got, err := p.StringifyContent(tt.args.content)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("Parser.StringifyContent() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if got != tt.want {
+ t.Errorf("Parser.StringifyContent() = %v, want %v", got, tt.want)
+ }
+ })
+ }
+}
+
+// Test_GetCommentToken must get the token that represents a comment
+func Test_GetCommentToken(t *testing.T) {
+ parser := &Parser{}
+ require.Equal(t, "//", parser.GetCommentToken())
+}
+
+func TestParseBicepFile(t *testing.T) {
+ parser := &Parser{}
+ tests := []struct {
+ name string
+ filename string
+ want string
+ wantErr bool
+ }{
+ {
+ name: "Parse Bicep file with Unsuported Content",
+ filename: filepath.Join("..", "..", "..", "test", "fixtures", "bicep_test", "unsuported.bicep"),
+ want: `{
+ "parameters": {
+ "diagnosticLogCategoriesToEnable": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 44
+ },
+ "_kics_type": {
+ "_kics_line": 44
+ }
+ },
+ "allowedValues": [
+ [
+ "allLogs",
+ "ConnectedClientList"
+ ]
+ ],
+ "defaultValue": [
+ "allLogs"
+ ],
+ "metadata": {
+ "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource."
+ },
+ "type": "array"
+ },
+ "diagnosticMetricsToEnable": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 52
+ },
+ "_kics_type": {
+ "_kics_line": 52
+ }
+ },
+ "allowedValues": [
+ [
+ "AllMetrics"
+ ]
+ ],
+ "defaultValue": [
+ "AllMetrics"
+ ],
+ "metadata": {
+ "description": "Optional. The name of metrics that will be streamed."
+ },
+ "type": "array"
+ },
+ "diagnosticSettingsName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 32
+ },
+ "_kics_type": {
+ "_kics_line": 32
+ }
+ },
+ "defaultValue": "'${parameters('name')}-diagnosticSettings'",
+ "metadata": {
+ "description": "Optional. The name of the diagnostic setting, if deployed."
+ },
+ "type": "string"
+ },
+ "diagnosticWorkspaceId": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 35
+ },
+ "_kics_type": {
+ "_kics_line": 35
+ }
+ },
+ "defaultValue": "",
+ "metadata": {
+ "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
+ },
+ "type": "string"
+ },
+ "keyvaultName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 23
+ },
+ "_kics_type": {
+ "_kics_line": 23
+ }
+ },
+ "metadata": {
+ "description": "The name of an existing keyvault, that it will be used to store secrets (connection string)"
+ },
+ "type": "string"
+ },
+ "name": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 20
+ },
+ "_kics_type": {
+ "_kics_line": 20
+ }
+ },
+ "maxLength": 63,
+ "metadata": {
+ "description": "Required. The name of the Redis cache resource. Start and end with alphanumeric. Consecutive hyphens not allowed"
+ },
+ "minLength": 1,
+ "type": "string"
+ }
+ },
+ "resources": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 110
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 110
+ },
+ "_kics_name": {
+ "_kics_line": 111
+ },
+ "_kics_type": {
+ "_kics_line": 110
+ }
+ },
+ "apiVersion": "2022-11-01",
+ "identifier": "keyVault",
+ "name": "[parameters('keyvaultName')]",
+ "type": "Microsoft.KeyVault/vaults"
+ },
+ {
+ "apiVersion": "2021-05-01-preview",
+ "identifier": "redisCache_diagnosticSettings",
+ "type": "Microsoft.Insights/diagnosticSettings"
+ }
+ ],
+ "variables": {
+ "diagnosticsLogs": {
+ "value": null
+ },
+ "diagnosticsLogsSpecified": {
+ "value": null
+ },
+ "diagnosticsMetrics": {
+ "value": null
+ },
+ "dogs": {
+ "value": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 73
+ },
+ "_kics_age": {
+ "_kics_line": 75
+ },
+ "_kics_name": {
+ "_kics_line": 74
+ }
+ },
+ "age": 3,
+ "name": "Fido"
+ },
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 77
+ },
+ "_kics_age": {
+ "_kics_line": 79
+ },
+ "_kics_name": {
+ "_kics_line": 78
+ }
+ },
+ "age": 7,
+ "name": "Rex"
+ }
+ ]
+ }
+ }
+ }`,
+ },
+ {
+ name: "Parse Bicep file with parameters",
+ filename: filepath.Join("..", "..", "..", "test", "fixtures", "bicep_test", "parameters.bicep"),
+ want: `{
+ "parameters": {
+ "array": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 17
+ },
+ "_kics_type": {
+ "_kics_line": 17
+ }
+ },
+ "defaultValue": [
+ "string"
+ ],
+ "type": "string"
+ },
+ "isNumber": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 9
+ },
+ "_kics_type": {
+ "_kics_line": 9
+ }
+ },
+ "defaultValue": true,
+ "metadata": {
+ "description": "This is a test bool param declaration."
+ },
+ "type": "bool"
+ },
+ "middleString": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 12
+ },
+ "_kics_type": {
+ "_kics_line": 12
+ }
+ },
+ "defaultValue": "'teste-${parameters('numberNodes')}${parameters('isNumber')}-teste'",
+ "metadata": {
+ "description": "This is a test middle string param declaration."
+ },
+ "type": "string"
+ },
+ "null": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 19
+ },
+ "_kics_type": {
+ "_kics_line": 19
+ }
+ },
+ "defaultValue": null,
+ "type": "string"
+ },
+ "numberNodes": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 6
+ },
+ "_kics_type": {
+ "_kics_line": 6
+ }
+ },
+ "defaultValue": 2,
+ "metadata": {
+ "description": "This is a test int param declaration."
+ },
+ "type": "int"
+ },
+ "projectName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 3
+ },
+ "_kics_type": {
+ "_kics_line": 3
+ }
+ },
+ "defaultValue": "[newGuid()]",
+ "metadata": {
+ "description": "This is a test param with secure declaration."
+ },
+ "type": "secureString"
+ },
+ "secObj": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 15
+ },
+ "_kics_type": {
+ "_kics_line": 15
+ }
+ },
+ "defaultValue": false,
+ "type": "secureObject"
+ }
+ },
+ "resources": [],
+ "variables": {}
+ }`,
+ wantErr: false,
+ },
+ {
+ name: "Parse Bicep file with variables",
+ filename: filepath.Join("..", "..", "..", "test", "fixtures", "bicep_test", "variables.bicep"),
+ want: `{
+ "variables": {
+ "nicName": {
+ "metadata": {
+ "description": "This is a test var declaration."
+ },
+ "value": "myVMNic"
+ },
+ "storageAccountName": {
+ "metadata": {
+ "description": "This is a test var declaration."
+ },
+ "value": "'bootdiags${[uniqueString(resourceGroup().id)]}'"
+ }
+ },
+ "resources": [],
+ "parameters": {}
+ }`,
+ wantErr: false,
+ },
+ {
+ name: "Parse completed Bicep file",
+ filename: filepath.Join("..", "..", "..", "test", "fixtures", "bicep_test", "resources.bicep"),
+ want: `{
+ "parameters": {
+ "OSVersion": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 42
+ },
+ "_kics_type": {
+ "_kics_line": 42
+ }
+ },
+ "allowedValues": [
+ [
+ "2008-R2-SP1",
+ "2012-Datacenter",
+ "2012-R2-Datacenter",
+ "2016-Nano-Server",
+ "2016-Datacenter-with-Containers",
+ "2016-Datacenter",
+ "2019-Datacenter",
+ "2019-Datacenter-Core",
+ "2019-Datacenter-Core-smalldisk",
+ "2019-Datacenter-Core-with-Containers",
+ "2019-Datacenter-Core-with-Containers-smalldisk",
+ "2019-Datacenter-smalldisk",
+ "2019-Datacenter-with-Containers",
+ "2019-Datacenter-with-Containers-smalldisk"
+ ]
+ ],
+ "defaultValue": "2019-Datacenter",
+ "metadata": {
+ "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version."
+ },
+ "type": "string"
+ },
+ "adminPassword": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 9
+ },
+ "_kics_type": {
+ "_kics_line": 9
+ }
+ },
+ "metadata": {
+ "description": "Password for the Virtual Machine."
+ },
+ "minLength": 12,
+ "type": "secureString"
+ },
+ "adminUsername": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 4
+ },
+ "_kics_type": {
+ "_kics_line": 4
+ }
+ },
+ "metadata": {
+ "description": "Username for the Virtual Machine."
+ },
+ "type": "string"
+ },
+ "arrayP": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 136
+ },
+ "_kics_type": {
+ "_kics_line": 136
+ }
+ },
+ "defaultValue": [
+ "allLogs",
+ "ConnectedClientList"
+ ],
+ "type": "array"
+ },
+ "capacity": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 65
+ },
+ "_kics_type": {
+ "_kics_line": 65
+ }
+ },
+ "allowedValues": [
+ [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6
+ ]
+ ],
+ "defaultValue": 2,
+ "metadata": {
+ "description": "Optional. The size of the Redis cache to deploy. Valid values: for C (Basic/Standard) family (0, 1, 2, 3, 4, 5, 6), for P (Premium) family (1, 2, 3, 4)."
+ },
+ "type": "int"
+ },
+ "diagnosticLogCategoriesToEnable": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 18
+ },
+ "_kics_type": {
+ "_kics_line": 18
+ }
+ },
+ "allowedValues": [
+ [
+ "allLogs",
+ "ConnectedClientList"
+ ]
+ ],
+ "defaultValue": [
+ "allLogs"
+ ],
+ "metadata": {
+ "description": "Optional. The name of logs that will be streamed. \"allLogs\" includes all possible logs for the resource."
+ },
+ "type": "array"
+ },
+ "diagnosticMetricsToEnable": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 93
+ },
+ "_kics_type": {
+ "_kics_line": 93
+ }
+ },
+ "allowedValues": [
+ [
+ "AllMetrics"
+ ]
+ ],
+ "defaultValue": [
+ "AllMetrics"
+ ],
+ "metadata": {
+ "description": "Optional. The name of metrics that will be streamed."
+ },
+ "type": "array"
+ },
+ "diagnosticSettingsName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 82
+ },
+ "_kics_type": {
+ "_kics_line": 82
+ }
+ },
+ "defaultValue": "'${name}-diagnosticSettings'",
+ "metadata": {
+ "description": "Optional. The name of the diagnostic setting, if deployed."
+ },
+ "type": "string"
+ },
+ "diagnosticWorkspaceId": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 85
+ },
+ "_kics_type": {
+ "_kics_line": 85
+ }
+ },
+ "defaultValue": "",
+ "metadata": {
+ "description": "Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub."
+ },
+ "type": "string"
+ },
+ "enableNonSslPort": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 99
+ },
+ "_kics_type": {
+ "_kics_line": 99
+ }
+ },
+ "defaultValue": false,
+ "metadata": {
+ "description": "Optional. Specifies whether the non-ssl Redis server port (6379) is enabled."
+ },
+ "type": "bool"
+ },
+ "existingContainerSubnetName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 126
+ },
+ "_kics_type": {
+ "_kics_line": 126
+ }
+ },
+ "metadata": {
+ "description": "Name of the subnet to use for cloud shell containers."
+ },
+ "type": "string"
+ },
+ "existingStorageSubnetName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 123
+ },
+ "_kics_type": {
+ "_kics_line": 123
+ }
+ },
+ "metadata": {
+ "description": "Name of the subnet to use for storage account."
+ },
+ "type": "string"
+ },
+ "existingVNETName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 120
+ },
+ "_kics_type": {
+ "_kics_line": 120
+ }
+ },
+ "metadata": {
+ "description": "Name of the virtual network to use for cloud shell containers."
+ },
+ "type": "string"
+ },
+ "hasPrivateLink": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 96
+ },
+ "_kics_type": {
+ "_kics_line": 96
+ }
+ },
+ "defaultValue": false,
+ "metadata": {
+ "description": "Has the resource private endpoint?"
+ },
+ "type": "bool"
+ },
+ "keyvaultName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 68
+ },
+ "_kics_type": {
+ "_kics_line": 68
+ }
+ },
+ "metadata": {
+ "description": "The name of an existing keyvault, that it will be used to store secrets (connection string)"
+ },
+ "type": "string"
+ },
+ "location": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 112
+ },
+ "_kics_type": {
+ "_kics_line": 112
+ }
+ },
+ "defaultValue": "[resourceGroup().location]",
+ "metadata": {
+ "description": "Location for all resources."
+ },
+ "type": "string"
+ },
+ "name": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 131
+ },
+ "_kics_type": {
+ "_kics_line": 131
+ }
+ },
+ "maxLength": 63,
+ "metadata": {
+ "description": "Required. The name of the Redis cache resource. Start and end with alphanumeric. Consecutive hyphens not allowed"
+ },
+ "minLength": 1,
+ "type": "string"
+ },
+ "parenthesis": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 117
+ },
+ "_kics_type": {
+ "_kics_line": 117
+ }
+ },
+ "defaultValue": "simple-vm",
+ "type": "string"
+ },
+ "redisConfiguration": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 102
+ },
+ "_kics_type": {
+ "_kics_line": 102
+ }
+ },
+ "defaultValue": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 102
+ }
+ }
+ },
+ "metadata": {
+ "description": "Optional. All Redis Settings. Few possible keys: rdb-backup-enabled,rdb-storage-connection-string,rdb-backup-frequency,maxmemory-delta,maxmemory-policy,notify-keyspace-events,maxmemory-samples,slowlog-log-slower-than,slowlog-max-len,list-max-ziplist-entries,list-max-ziplist-value,hash-max-ziplist-entries,hash-max-ziplist-value,set-max-intset-entries,zset-max-ziplist-entries,zset-max-ziplist-value etc."
+ },
+ "type": "object"
+ },
+ "replicasPerMaster": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 106
+ },
+ "_kics_type": {
+ "_kics_line": 106
+ }
+ },
+ "defaultValue": 1,
+ "metadata": {
+ "description": "Optional. The number of replicas to be created per primary."
+ },
+ "minValue": 1,
+ "type": "int"
+ },
+ "replicasPerPrimary": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 49
+ },
+ "_kics_type": {
+ "_kics_line": 49
+ }
+ },
+ "defaultValue": 1,
+ "metadata": {
+ "description": "Optional. The number of replicas to be created per primary."
+ },
+ "minValue": 1,
+ "type": "int"
+ },
+ "shardCount": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 53
+ },
+ "_kics_type": {
+ "_kics_line": 53
+ }
+ },
+ "defaultValue": 1,
+ "metadata": {
+ "description": "Optional. The number of shards to be created on a Premium Cluster Cache."
+ },
+ "minValue": 1,
+ "type": "int"
+ },
+ "skuName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 76
+ },
+ "_kics_type": {
+ "_kics_line": 76
+ }
+ },
+ "allowedValues": [
+ [
+ "Basic",
+ "Premium",
+ "Standard"
+ ]
+ ],
+ "defaultValue": "Standard",
+ "metadata": {
+ "description": "Optional, default is Standard. The type of Redis cache to deploy."
+ },
+ "type": "string"
+ },
+ "subnetId": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 79
+ },
+ "_kics_type": {
+ "_kics_line": 79
+ }
+ },
+ "defaultValue": "",
+ "metadata": {
+ "description": "Optional. The full resource ID of a subnet in a virtual network to deploy the Redis cache in. Example format: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/Microsoft.{Network|ClassicNetwork}/VirtualNetworks/vnet1/subnets/subnet1."
+ },
+ "type": "string"
+ },
+ "tags": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 45
+ },
+ "_kics_type": {
+ "_kics_line": 45
+ }
+ },
+ "defaultValue": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 45
+ }
+ }
+ },
+ "metadata": {
+ "description": "Optional. Tags of the resource."
+ },
+ "type": "object"
+ },
+ "vmName": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 115
+ },
+ "_kics_type": {
+ "_kics_line": 115
+ }
+ },
+ "defaultValue": "simple-vm",
+ "metadata": {
+ "description": "Name of the virtual machine."
+ },
+ "type": "string"
+ },
+ "vmSize": {
+ "_kics_lines": {
+ "_kics_defaultValue": {
+ "_kics_line": 109
+ },
+ "_kics_type": {
+ "_kics_line": 109
+ }
+ },
+ "defaultValue": "Standard_D2_v3",
+ "metadata": {
+ "description": "Size of the virtual machine."
+ },
+ "type": "string"
+ }
+ },
+ "resources": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 173
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 172
+ },
+ "_kics_dependsOn": {
+ "_kics_arr": [
+ {
+ "_kics__default": {
+ "_kics_line": 222
+ }
+ }
+ ],
+ "_kics_line": 222
+ },
+ "_kics_location": {
+ "_kics_line": 175
+ },
+ "_kics_name": {
+ "_kics_line": 174
+ },
+ "_kics_properties": {
+ "_kics_line": 176
+ },
+ "_kics_type": {
+ "_kics_line": 172
+ }
+ },
+ "apiVersion": "2021-03-01",
+ "dependsOn": [
+ {
+ "resourceId": [
+ "Microsoft.Network/networkInterfaces",
+ "variables('nicName')"
+ ]
+ },
+ {
+ "resourceId": [
+ "Microsoft.Storage/storageAccounts",
+ "variables('storageAccountName')"
+ ]
+ }
+ ],
+ "identifier": "vm",
+ "location": "[parameters('location')]",
+ "metadata": {
+ "description": "This is a test description for resources"
+ },
+ "name": "[parameters('vmName')]",
+ "properties": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 176
+ },
+ "_kics_diagnosticsProfile": {
+ "_kics_line": 213
+ },
+ "_kics_hardwareProfile": {
+ "_kics_line": 177
+ },
+ "_kics_networkProfile": {
+ "_kics_line": 206
+ },
+ "_kics_osProfile": {
+ "_kics_line": 180
+ },
+ "_kics_storageProfile": {
+ "_kics_line": 185
+ }
+ },
+ "diagnosticsProfile": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 213
+ },
+ "_kics_bootDiagnostics": {
+ "_kics_line": 214
+ }
+ },
+ "bootDiagnostics": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 214
+ },
+ "_kics_enabled": {
+ "_kics_line": 215
+ },
+ "_kics_storageUri": {
+ "_kics_line": 216
+ }
+ },
+ "enabled": true,
+ "storageUri": "[reference(resourceId(Microsoft.Storage/storageAccounts, variables('storageAccountName'))).primaryEndpoints.blob]"
+ }
+ },
+ "hardwareProfile": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 177
+ },
+ "_kics_vmSize": {
+ "_kics_line": 178
+ }
+ },
+ "vmSize": "[parameters('vmSize')]"
+ },
+ "networkProfile": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 206
+ },
+ "_kics_networkInterfaces": {
+ "_kics_arr": [
+ {
+ "_kics__default": {
+ "_kics_line": 207
+ }
+ }
+ ],
+ "_kics_line": 207
+ }
+ },
+ "networkInterfaces": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 208
+ },
+ "_kics_id": {
+ "_kics_line": 209
+ }
+ },
+ "id": {
+ "resourceId": [
+ "Microsoft.Network/networkInterfaces",
+ "nick"
+ ]
+ }
+ }
+ ]
+ },
+ "osProfile": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 180
+ },
+ "_kics_adminPassword": {
+ "_kics_line": 183
+ },
+ "_kics_adminUsername": {
+ "_kics_line": 182
+ },
+ "_kics_computerName": {
+ "_kics_line": 181
+ }
+ },
+ "adminPassword": "[parameters('adminPassword')]",
+ "adminUsername": "[parameters('adminUsername')]",
+ "computerName": "computer"
+ },
+ "storageProfile": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 185
+ },
+ "_kics_dataDisks": {
+ "_kics_arr": [
+ {
+ "_kics__default": {
+ "_kics_line": 198
+ }
+ }
+ ],
+ "_kics_line": 198
+ },
+ "_kics_imageReference": {
+ "_kics_line": 186
+ },
+ "_kics_osDisk": {
+ "_kics_line": 192
+ }
+ },
+ "dataDisks": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 199
+ },
+ "_kics_createOption": {
+ "_kics_line": 202
+ },
+ "_kics_diskSizeGB": {
+ "_kics_line": 200
+ },
+ "_kics_lun": {
+ "_kics_line": 201
+ }
+ },
+ "createOption": "Empty",
+ "diskSizeGB": 1023,
+ "lun": 0
+ }
+ ],
+ "imageReference": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 186
+ },
+ "_kics_offer": {
+ "_kics_line": 188
+ },
+ "_kics_publisher": {
+ "_kics_line": 187
+ },
+ "_kics_sku": {
+ "_kics_line": 189
+ },
+ "_kics_version": {
+ "_kics_line": 190
+ }
+ },
+ "offer": "WindowsServer",
+ "publisher": "MicrosoftWindowsServer",
+ "sku": "[parameters('OSVersion')]",
+ "version": "latest"
+ },
+ "osDisk": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 192
+ },
+ "_kics_createOption": {
+ "_kics_line": 193
+ },
+ "_kics_managedDisk": {
+ "_kics_line": 194
+ }
+ },
+ "createOption": "FromImage",
+ "managedDisk": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 194
+ },
+ "_kics_storageAccountType": {
+ "_kics_line": 195
+ }
+ },
+ "storageAccountType": "StandardSSD_LRS"
+ }
+ }
+ }
+ },
+ "type": "Microsoft.Compute/virtualMachines"
+ },
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 228
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 228
+ },
+ "_kics_assignableScopes": {
+ "_kics_arr": [
+ {
+ "_kics__default": {
+ "_kics_line": 238
+ }
+ }
+ ],
+ "_kics_line": 238
+ },
+ "_kics_location": {
+ "_kics_line": 230
+ },
+ "_kics_name": {
+ "_kics_line": 229
+ },
+ "_kics_type": {
+ "_kics_line": 228
+ },
+ "_kics_userAssignedIdentities": {
+ "_kics_line": 235
+ }
+ },
+ "apiVersion": "2021-03-01",
+ "assignableScopes": [
+ "[subscription().id]"
+ ],
+ "identifier": "nic",
+ "location": null,
+ "name": null,
+ "type": "Microsoft.Network/networkInterfaces",
+ "userAssignedIdentities": {
+ "'${[resourceId(Microsoft.ManagedIdentity/userAssignedIdentities, variables('nicName'))]}'": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 236
+ }
+ }
+ },
+ "_kics_lines": {
+ "_kics_'${[resourceId(Microsoft.ManagedIdentity/userAssignedIdentities, variables('nicName'))]}'": {
+ "_kics_line": 236
+ },
+ "_kics__default": {
+ "_kics_line": 235
+ }
+ }
+ }
+ },
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 241
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 241
+ },
+ "_kics_kind": {
+ "_kics_line": 248
+ },
+ "_kics_location": {
+ "_kics_line": 243
+ },
+ "_kics_name": {
+ "_kics_line": 242
+ },
+ "_kics_properties": {
+ "_kics_line": 249
+ },
+ "_kics_sku": {
+ "_kics_line": 244
+ },
+ "_kics_type": {
+ "_kics_line": 241
+ }
+ },
+ "apiVersion": "2019-06-01",
+ "identifier": "storageAccount",
+ "kind": "StorageV2",
+ "location": "[parameters('location')]",
+ "name": "[variables('storageAccountName')]",
+ "properties": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 249
+ },
+ "_kics_accessTier": {
+ "_kics_line": 278
+ },
+ "_kics_encryption": {
+ "_kics_line": 265
+ },
+ "_kics_networkAcls": {
+ "_kics_line": 250
+ },
+ "_kics_supportsHttpsTrafficOnly": {
+ "_kics_line": 264
+ }
+ },
+ "accessTier": "Cool",
+ "encryption": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 265
+ },
+ "_kics_keySource": {
+ "_kics_line": 276
+ },
+ "_kics_services": {
+ "_kics_line": 266
+ }
+ },
+ "keySource": "Microsoft.Storage",
+ "services": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 266
+ },
+ "_kics_blob": {
+ "_kics_line": 271
+ },
+ "_kics_file": {
+ "_kics_line": 267
+ }
+ },
+ "blob": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 271
+ },
+ "_kics_enabled": {
+ "_kics_line": 273
+ },
+ "_kics_keyType": {
+ "_kics_line": 272
+ }
+ },
+ "enabled": true,
+ "keyType": "Account"
+ },
+ "file": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 267
+ },
+ "_kics_enabled": {
+ "_kics_line": 269
+ },
+ "_kics_keyType": {
+ "_kics_line": 268
+ }
+ },
+ "enabled": true,
+ "keyType": "Account"
+ }
+ }
+ },
+ "networkAcls": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 250
+ },
+ "_kics_bypass": {
+ "_kics_line": 251
+ },
+ "_kics_defaultAction": {
+ "_kics_line": 262
+ },
+ "_kics_virtualNetworkRules": {
+ "_kics_arr": [
+ {
+ "_kics__default": {
+ "_kics_line": 252
+ }
+ }
+ ],
+ "_kics_line": 252
+ }
+ },
+ "bypass": "None",
+ "defaultAction": "Deny",
+ "virtualNetworkRules": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 253
+ },
+ "_kics_action": {
+ "_kics_line": 255
+ },
+ "_kics_id": {
+ "_kics_line": 254
+ }
+ },
+ "action": "Allow",
+ "id": "[variables('containerSubnetRef')]"
+ },
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 257
+ },
+ "_kics_action": {
+ "_kics_line": 259
+ },
+ "_kics_id": {
+ "_kics_line": 258
+ }
+ },
+ "action": "Allow",
+ "id": "[variables('storageSubnetRef')]"
+ }
+ ]
+ },
+ "supportsHttpsTrafficOnly": true
+ },
+ "resources": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 282
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 282
+ },
+ "_kics_name": {
+ "_kics_line": 284
+ },
+ "_kics_parent": {
+ "_kics_line": 283
+ },
+ "_kics_properties": {
+ "_kics_line": 289
+ },
+ "_kics_sku": {
+ "_kics_line": 285
+ },
+ "_kics_type": {
+ "_kics_line": 282
+ }
+ },
+ "apiVersion": "2019-06-01",
+ "identifier": "storageAccountName_default",
+ "name": "default",
+ "parent": "storageAccount",
+ "properties": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 289
+ },
+ "_kics_deleteRetentionPolicy": {
+ "_kics_line": 290
+ }
+ },
+ "deleteRetentionPolicy": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 290
+ },
+ "_kics_enabled": {
+ "_kics_line": 291
+ }
+ },
+ "enabled": false
+ }
+ },
+ "resources": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 296
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 296
+ },
+ "_kics_name": {
+ "_kics_line": 298
+ },
+ "_kics_parent": {
+ "_kics_line": 297
+ },
+ "_kics_properties": {
+ "_kics_line": 299
+ },
+ "_kics_type": {
+ "_kics_line": 296
+ }
+ },
+ "apiVersion": "2019-06-01",
+ "identifier": "storageAccountName_default_container",
+ "name": "container",
+ "parent": "storageAccountName_default",
+ "properties": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 299
+ },
+ "_kics_denyEncryptionScopeOverride": {
+ "_kics_line": 300
+ },
+ "_kics_metadata": {
+ "_kics_line": 302
+ },
+ "_kics_publicAccess": {
+ "_kics_line": 301
+ }
+ },
+ "denyEncryptionScopeOverride": true,
+ "metadata": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 302
+ }
+ }
+ },
+ "publicAccess": "Blob"
+ },
+ "type": "containers"
+ }
+ ],
+ "sku": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 285
+ },
+ "_kics_name": {
+ "_kics_line": 286
+ },
+ "_kics_tier": {
+ "_kics_line": 287
+ }
+ },
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "type": "blobServices"
+ }
+ ],
+ "sku": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 244
+ },
+ "_kics_name": {
+ "_kics_line": 245
+ },
+ "_kics_tier": {
+ "_kics_line": 246
+ }
+ },
+ "name": "Standard_LRS",
+ "tier": "Standard"
+ },
+ "type": "Microsoft.Storage/storageAccounts"
+ },
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 306
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 306
+ },
+ "_kics_location": {
+ "_kics_line": 308
+ },
+ "_kics_name": {
+ "_kics_line": 307
+ },
+ "_kics_properties": {
+ "_kics_line": 311
+ },
+ "_kics_tags": {
+ "_kics_line": 309
+ },
+ "_kics_type": {
+ "_kics_line": 306
+ },
+ "_kics_zones": {
+ "_kics_line": 327
+ }
+ },
+ "apiVersion": "2021-06-01",
+ "identifier": "redisCache",
+ "location": "[parameters('location')]",
+ "name": "[parameters('name')]",
+ "properties": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 311
+ },
+ "_kics_enableNonSslPort": {
+ "_kics_line": 312
+ },
+ "_kics_minimumTlsVersion": {
+ "_kics_line": 313
+ },
+ "_kics_publicNetworkAccess": {
+ "_kics_line": 314
+ },
+ "_kics_redisConfiguration": {
+ "_kics_line": 315
+ },
+ "_kics_redisVersion": {
+ "_kics_line": 316
+ },
+ "_kics_replicasPerMaster": {
+ "_kics_line": 317
+ },
+ "_kics_replicasPerPrimary": {
+ "_kics_line": 318
+ },
+ "_kics_shardCount": {
+ "_kics_line": 319
+ },
+ "_kics_sku": {
+ "_kics_line": 320
+ },
+ "_kics_subnetId": {
+ "_kics_line": 325
+ }
+ },
+ "enableNonSslPort": "[parameters('enableNonSslPort')]",
+ "minimumTlsVersion": "1.2",
+ "publicNetworkAccess": null,
+ "redisConfiguration": null,
+ "redisVersion": "6",
+ "replicasPerMaster": null,
+ "replicasPerPrimary": null,
+ "shardCount": null,
+ "sku": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 320
+ },
+ "_kics_capacity": {
+ "_kics_line": 321
+ },
+ "_kics_family": {
+ "_kics_line": 322
+ },
+ "_kics_name": {
+ "_kics_line": 323
+ }
+ },
+ "capacity": "[parameters('capacity')]",
+ "family": null,
+ "name": "[parameters('skuName')]"
+ },
+ "subnetId": null
+ },
+ "tags": "[parameters('tags')]",
+ "type": "Microsoft.Cache/redis",
+ "zones": null
+ },
+ {
+ "apiVersion": "2021-05-01-preview",
+ "identifier": "redisCache_diagnosticSettings",
+ "type": "Microsoft.Insights/diagnosticSettings"
+ },
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 351
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 351
+ },
+ "_kics_name": {
+ "_kics_line": 352
+ },
+ "_kics_type": {
+ "_kics_line": 351
+ }
+ },
+ "apiVersion": "2022-11-01",
+ "identifier": "keyVault",
+ "name": "[parameters('keyvaultName')]",
+ "resources": [
+ {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 330
+ },
+ "_kics_apiVersion": {
+ "_kics_line": 330
+ },
+ "_kics_name": {
+ "_kics_line": 331
+ },
+ "_kics_parent": {
+ "_kics_line": 332
+ },
+ "_kics_properties": {
+ "_kics_line": 333
+ },
+ "_kics_type": {
+ "_kics_line": 330
+ }
+ },
+ "apiVersion": "2018-02-14",
+ "identifier": "redisConnectionStringSecret",
+ "name": "redisConStrSecret",
+ "parent": "keyVault",
+ "properties": {
+ "_kics_lines": {
+ "_kics__default": {
+ "_kics_line": 333
+ },
+ "_kics_value": {
+ "_kics_line": 334
+ }
+ },
+ "value": "['${redisCache.properties.hostName},password=${redisCache.listKeys().primaryKey},ssl=True,abortConnect=False']"
+ },
+ "type": "secrets"
+ }
+ ],
+ "type": "Microsoft.KeyVault/vaults"
+ }
+ ],
+ "variables": {
+ "containerSubnetRef": {
+ "value": {
+ "resourceId": [
+ "Microsoft.Network/virtualNetworks/subnets",
+ "parameters('existingVNETName')",
+ "parameters('existingContainerSubnetName')"
+ ]
+ }
+ },
+ "diagnosticsLogs": {
+ "value": null
+ },
+ "diagnosticsLogsSpecified": {
+ "value": null
+ },
+ "diagnosticsMetrics": {
+ "value": null
+ },
+ "nicName": {
+ "value": "myVMNic"
+ },
+ "storageAccountName": {
+ "value": "'bootdiags${[uniqueString(resourceGroup().id)]}'"
+ },
+ "storageSubnetRef": {
+ "value": {
+ "resourceId": [
+ "Microsoft.Network/virtualNetworks/subnets",
+ "parameters('existingVNETName')",
+ "parameters('existingStorageSubnetName')"
+ ]
+ }
+ }
+ }
+ }`,
+ wantErr: false,
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ document, _, err := parser.Parse(tt.filename, nil)
+ if (err != nil) != tt.wantErr {
+ t.Errorf("Parser.Parse() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ require.Len(t, document, 1)
+ //get first element of parsed file
+ parsedDoc := document[0]
+ fileString, err := json.Marshal(parsedDoc)
+ require.NoError(t, err)
+ require.JSONEq(t, tt.want, string(fileString))
+ })
+ }
+}
diff --git a/pkg/scan/scan.go b/pkg/scan/scan.go
index 5d8271d4d60..0c5c19ecbdf 100644
--- a/pkg/scan/scan.go
+++ b/pkg/scan/scan.go
@@ -15,6 +15,7 @@ import (
"github.com/Checkmarx/kics/v2/pkg/parser"
ansibleConfigParser "github.com/Checkmarx/kics/v2/pkg/parser/ansible/ini/config"
ansibleHostsParser "github.com/Checkmarx/kics/v2/pkg/parser/ansible/ini/hosts"
+ bicepParser "github.com/Checkmarx/kics/v2/pkg/parser/bicep"
buildahParser "github.com/Checkmarx/kics/v2/pkg/parser/buildah"
dockerParser "github.com/Checkmarx/kics/v2/pkg/parser/docker"
protoParser "github.com/Checkmarx/kics/v2/pkg/parser/grpc"
@@ -55,9 +56,12 @@ func (c *Client) initScan(ctx context.Context) (*executeScanParameters, error) {
return nil, nil
}
+ paramsPlatforms := c.ScanParams.Platform
+ useDifferentPlatformQueries(¶msPlatforms)
+
querySource := source.NewFilesystemSource(
c.ScanParams.QueriesPath,
- c.ScanParams.Platform,
+ paramsPlatforms,
c.ScanParams.CloudProvider,
c.ScanParams.LibrariesPath,
c.ScanParams.ExperimentalQueries)
@@ -167,6 +171,26 @@ func (c *Client) executeScan(ctx context.Context) (*Results, error) {
}, nil
}
+func useDifferentPlatformQueries(platforms *[]string) {
+ hasBicep := false
+ hasARM := false
+ for _, platform := range *platforms {
+ if platform == "bicep" {
+ hasBicep = true
+ }
+ if platform == "azureresourcemanager" {
+ hasARM = true
+ }
+ if hasARM && hasBicep {
+ break
+ }
+ }
+
+ if hasBicep && !hasARM {
+ *platforms = append(*platforms, "azureresourcemanager")
+ }
+}
+
func getExcludeResultsMap(excludeResults []string) map[string]bool {
excludeResultsMap := make(map[string]bool)
for _, er := range excludeResults {
@@ -227,6 +251,7 @@ func (c *Client) createService(
Add(&jsonParser.Parser{}).
Add(&yamlParser.Parser{}).
Add(terraformParser.NewDefaultWithVarsPath(c.ScanParams.TerraformVarsPath)).
+ Add(&bicepParser.Parser{}).
Add(&dockerParser.Parser{}).
Add(&protoParser.Parser{}).
Add(&buildahParser.Parser{}).
diff --git a/test/fixtures/bicep_test/parameters.bicep b/test/fixtures/bicep_test/parameters.bicep
new file mode 100644
index 00000000000..42924f5998e
--- /dev/null
+++ b/test/fixtures/bicep_test/parameters.bicep
@@ -0,0 +1,19 @@
+@description('This is a test param with secure declaration.')
+@secure()
+param projectName string = newGuid()
+
+@description('This is a test int param declaration.')
+param numberNodes int = 2
+
+@description('This is a test bool param declaration.')
+param isNumber bool = true
+
+@description('This is a test middle string param declaration.')
+param middleString string = 'teste-${numberNodes}${isNumber}-teste'
+
+@secure()
+param secObj object = false
+
+param array string = ['string']
+
+param null string = null
diff --git a/test/fixtures/bicep_test/resources.bicep b/test/fixtures/bicep_test/resources.bicep
new file mode 100644
index 00000000000..55d950f3775
--- /dev/null
+++ b/test/fixtures/bicep_test/resources.bicep
@@ -0,0 +1,353 @@
+@description(
+ 'Username for the Virtual Machine.'
+)
+param adminUsername string
+
+@description('Password for the Virtual Machine.')
+@minLength(12)
+@secure()
+param adminPassword string
+
+@description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource.')
+@allowed([
+ 'allLogs'
+ 'ConnectedClientList'
+])
+param diagnosticLogCategoriesToEnable array = [
+ 'allLogs'
+]
+
+@description(
+ '''The Windows version for the VM.
+ This will pick a fully patched image of this given Windows version.'''
+)
+@allowed(
+ [
+ '2008-R2-SP1'
+ '2012-Datacenter'
+ '2012-R2-Datacenter'
+ '2016-Nano-Server'
+ '2016-Datacenter-with-Containers'
+ '2016-Datacenter'
+ '2019-Datacenter'
+ '2019-Datacenter-Core'
+ '2019-Datacenter-Core-smalldisk'
+ '2019-Datacenter-Core-with-Containers'
+ '2019-Datacenter-Core-with-Containers-smalldisk'
+ '2019-Datacenter-smalldisk'
+ '2019-Datacenter-with-Containers'
+ '2019-Datacenter-with-Containers-smalldisk'
+ ]
+)
+param OSVersion string = '2019-Datacenter'
+
+@description('Optional. Tags of the resource.')
+param tags object = {}
+
+@minValue(1)
+@description('Optional. The number of replicas to be created per primary.')
+param replicasPerPrimary int = 1
+
+@minValue(1)
+@description('Optional. The number of shards to be created on a Premium Cluster Cache.')
+param shardCount int = 1
+
+@allowed([
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+])
+@description('Optional. The size of the Redis cache to deploy. Valid values: for C (Basic/Standard) family (0, 1, 2, 3, 4, 5, 6), for P (Premium) family (1, 2, 3, 4).')
+param capacity int = 2
+
+@description('The name of an existing keyvault, that it will be used to store secrets (connection string)' )
+param keyvaultName string
+
+@allowed([
+ 'Basic'
+ 'Premium'
+ 'Standard'
+])
+@description('Optional, default is Standard. The type of Redis cache to deploy.')
+param skuName string = 'Standard'
+
+@description('Optional. The full resource ID of a subnet in a virtual network to deploy the Redis cache in. Example format: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/Microsoft.{Network|ClassicNetwork}/VirtualNetworks/vnet1/subnets/subnet1.')
+param subnetId string = ''
+
+@description('Optional. The name of the diagnostic setting, if deployed.')
+param diagnosticSettingsName string = '${name}-diagnosticSettings'
+
+@description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.')
+param diagnosticWorkspaceId string = ''
+
+@description('Optional. The name of metrics that will be streamed.')
+@allowed([
+ 'AllMetrics'
+])
+param diagnosticMetricsToEnable array = [
+ 'AllMetrics'
+]
+
+@description('Has the resource private endpoint?')
+param hasPrivateLink bool = false
+
+@description('Optional. Specifies whether the non-ssl Redis server port (6379) is enabled.')
+param enableNonSslPort bool = false
+
+@description('Optional. All Redis Settings. Few possible keys: rdb-backup-enabled,rdb-storage-connection-string,rdb-backup-frequency,maxmemory-delta,maxmemory-policy,notify-keyspace-events,maxmemory-samples,slowlog-log-slower-than,slowlog-max-len,list-max-ziplist-entries,list-max-ziplist-value,hash-max-ziplist-entries,hash-max-ziplist-value,set-max-intset-entries,zset-max-ziplist-entries,zset-max-ziplist-value etc.')
+param redisConfiguration object = {}
+
+@minValue(1)
+@description('Optional. The number of replicas to be created per primary.')
+param replicasPerMaster int = 1
+
+@description('Size of the virtual machine.')
+param vmSize string = 'Standard_D2_v3'
+
+@description('Location for all resources.')
+param location string = resourceGroup().location
+
+@description('Name of the virtual machine.')
+param vmName string = 'simple-vm'
+
+param parenthesis string = ('simple-vm')
+
+@description('Name of the virtual network to use for cloud shell containers.')
+param existingVNETName string
+
+@description('Name of the subnet to use for storage account.')
+param existingStorageSubnetName string
+
+@description('Name of the subnet to use for cloud shell containers.')
+param existingContainerSubnetName string
+
+@description('Required. The name of the Redis cache resource. Start and end with alphanumeric. Consecutive hyphens not allowed')
+@maxLength(63)
+@minLength(1)
+param name string
+
+param arrayP array = [
+ 'allLogs'
+ 'ConnectedClientList'
+]
+
+var storageAccountName = 'bootdiags${uniqueString(resourceGroup().id)}'
+
+var nicName = 'myVMNic'
+
+var containerSubnetRef = resourceId(
+ 'Microsoft.Network/virtualNetworks/subnets',
+ existingVNETName,
+ existingContainerSubnetName
+)
+
+var storageSubnetRef = resourceId(
+ 'Microsoft.Network/virtualNetworks/subnets',
+ existingVNETName,
+ existingStorageSubnetName
+)
+
+var diagnosticsLogsSpecified = [for category in filter(diagnosticLogCategoriesToEnable, item => item != 'allLogs'): {
+ category: category
+ enabled: true
+}]
+
+var diagnosticsLogs = contains(diagnosticLogCategoriesToEnable, 'allLogs') ? [
+ {
+ categoryGroup: 'allLogs'
+ enabled: true
+ }
+] : diagnosticsLogsSpecified
+
+var diagnosticsMetrics = [for metric in diagnosticMetricsToEnable: {
+ category: metric
+ timeGrain: null
+ enabled: true
+}]
+
+@sys.description('This is a test description for resources')
+resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' = {
+ name: vmName
+ location: location
+ properties: {
+ hardwareProfile: {
+ vmSize: vmSize
+ }
+ osProfile: {
+ computerName: 'computer'
+ adminUsername: adminUsername
+ adminPassword: adminPassword
+ }
+ storageProfile: {
+ imageReference: {
+ publisher: 'MicrosoftWindowsServer'
+ offer: 'WindowsServer'
+ sku: OSVersion
+ version: 'latest'
+ }
+ osDisk: {
+ createOption: 'FromImage'
+ managedDisk: {
+ storageAccountType: 'StandardSSD_LRS'
+ }
+ }
+ dataDisks: [
+ {
+ diskSizeGB: 1023
+ lun: 0
+ createOption: 'Empty'
+ }
+ ]
+ }
+ networkProfile: {
+ networkInterfaces: [
+ {
+ id: resourceId('Microsoft.Network/networkInterfaces', 'nick')
+ }
+ ]
+ }
+ diagnosticsProfile: {
+ bootDiagnostics: {
+ enabled: true
+ storageUri: reference(
+ resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
+ ).primaryEndpoints.blob
+ }
+ }
+ }
+ dependsOn: [
+ resourceId('Microsoft.Network/networkInterfaces', nicName)
+ resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
+ ]
+}
+
+resource nic 'Microsoft.Network/networkInterfaces@2021-03-01' = {
+ name: arrayP[0]
+ location: [
+ for i in name: {
+ name: nicName
+ }
+ ]
+ userAssignedIdentities: {
+ '${resourceId('Microsoft.ManagedIdentity/userAssignedIdentities',nicName)}': {}
+ }
+ assignableScopes: [subscription().id]
+}
+
+resource storageAccount 'Microsoft.Storage/storageAccounts@2019-06-01' = {
+ name: storageAccountName
+ location: location
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ kind: 'StorageV2'
+ properties: {
+ networkAcls: {
+ bypass: 'None'
+ virtualNetworkRules: [
+ {
+ id: containerSubnetRef
+ action: 'Allow'
+ }
+ {
+ id: storageSubnetRef
+ action: 'Allow'
+ }
+ ]
+ defaultAction: 'Deny'
+ }
+ supportsHttpsTrafficOnly: true
+ encryption: {
+ services: {
+ file: {
+ keyType: 'Account'
+ enabled: true
+ }
+ blob: {
+ keyType: 'Account'
+ enabled: true
+ }
+ }
+ keySource: 'Microsoft.Storage'
+ }
+ accessTier: 'Cool'
+ }
+}
+
+resource storageAccountName_default 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01' = {
+ parent: storageAccount
+ name: 'default'
+ sku: {
+ name: 'Standard_LRS'
+ tier: 'Standard'
+ }
+ properties: {
+ deleteRetentionPolicy: {
+ enabled: false
+ }
+ }
+}
+
+resource storageAccountName_default_container 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = {
+ parent: storageAccountName_default
+ name: 'container'
+ properties: {
+ denyEncryptionScopeOverride: true
+ publicAccess: 'Blob'
+ metadata: {}
+ }
+}
+
+resource redisCache 'Microsoft.Cache/redis@2021-06-01' = {
+ name: name
+ location: location
+ tags: tags
+// identity: identity //20230301-getting a strange error that publcNetworkAccess and Identity cannot be set at the same time. The following updates can't be processed in one single request, please send seperate request to update them: 'properties.publicNetworkAccess,identity
+ properties: {
+ enableNonSslPort: enableNonSslPort
+ minimumTlsVersion: '1.2'
+ publicNetworkAccess: hasPrivateLink ? 'Disabled' : null
+ redisConfiguration: !empty(redisConfiguration) ? redisConfiguration : null
+ redisVersion: '6'
+ replicasPerMaster: skuName == 'Premium' ? replicasPerMaster : null
+ replicasPerPrimary: skuName == 'Premium' ? replicasPerPrimary : null
+ shardCount: skuName == 'Premium' ? shardCount : null // Not supported in free tier
+ sku: {
+ capacity: capacity
+ family: skuName == 'Premium' ? 'P' : 'C'
+ name: skuName
+ }
+ subnetId: !empty(subnetId) ? subnetId : null
+ }
+ zones: skuName == 'Premium' ? pickZones('Microsoft.Cache', 'redis', location, 1) : null
+}
+
+resource redisConnectionStringSecret 'Microsoft.KeyVault/vaults/secrets@2018-02-14' = {
+ name: 'redisConStrSecret'
+ parent: keyVault
+ properties: {
+ value: '${redisCache.properties.hostName},password=${redisCache.listKeys().primaryKey},ssl=True,abortConnect=False' //'${name}.redis.cache.windows.net,abortConnect=false,ssl=true,password=${listKeys(redis.id, redis.apiVersion).primaryKey}'
+ }
+}
+
+resource redisCache_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ( !empty(diagnosticWorkspaceId) ) {
+ name: diagnosticSettingsName
+ properties: {
+ storageAccountId: null
+ workspaceId: empty(diagnosticWorkspaceId) ? null : diagnosticWorkspaceId
+ eventHubAuthorizationRuleId: null
+ eventHubName: null
+ metrics: empty(diagnosticWorkspaceId) ? null : diagnosticsMetrics
+ logs: empty(diagnosticWorkspaceId) ? null : diagnosticsLogs
+ }
+ scope: redisCache
+}
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-11-01' existing = {
+ name: keyvaultName
+}
diff --git a/test/fixtures/bicep_test/test/negative1.bicep b/test/fixtures/bicep_test/test/negative1.bicep
new file mode 100644
index 00000000000..26f3a5742be
--- /dev/null
+++ b/test/fixtures/bicep_test/test/negative1.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/negative2.bicep b/test/fixtures/bicep_test/test/negative2.bicep
new file mode 100644
index 00000000000..26f3a5742be
--- /dev/null
+++ b/test/fixtures/bicep_test/test/negative2.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive1.bicep b/test/fixtures/bicep_test/test/positive1.bicep
new file mode 100644
index 00000000000..fce90975370
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive1.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'Off'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive10.bicep b/test/fixtures/bicep_test/test/positive10.bicep
new file mode 100644
index 00000000000..edfc2f0fe0c
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive10.bicep
@@ -0,0 +1,11 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive11.bicep b/test/fixtures/bicep_test/test/positive11.bicep
new file mode 100644
index 00000000000..d761b527a04
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive11.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'Off'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive12.bicep b/test/fixtures/bicep_test/test/positive12.bicep
new file mode 100644
index 00000000000..316159f73c0
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive12.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive2.bicep b/test/fixtures/bicep_test/test/positive2.bicep
new file mode 100644
index 00000000000..047c95bb6d7
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive2.bicep
@@ -0,0 +1,11 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive3.bicep b/test/fixtures/bicep_test/test/positive3.bicep
new file mode 100644
index 00000000000..0de0191abec
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive3.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive4.bicep b/test/fixtures/bicep_test/test/positive4.bicep
new file mode 100644
index 00000000000..edfc2f0fe0c
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive4.bicep
@@ -0,0 +1,11 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive5.bicep b/test/fixtures/bicep_test/test/positive5.bicep
new file mode 100644
index 00000000000..d761b527a04
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive5.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'Off'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive6.bicep b/test/fixtures/bicep_test/test/positive6.bicep
new file mode 100644
index 00000000000..316159f73c0
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive6.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'On'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive7.bicep b/test/fixtures/bicep_test/test/positive7.bicep
new file mode 100644
index 00000000000..fce90975370
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive7.bicep
@@ -0,0 +1,15 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ state: 'Off'
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive8.bicep b/test/fixtures/bicep_test/test/positive8.bicep
new file mode 100644
index 00000000000..047c95bb6d7
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive8.bicep
@@ -0,0 +1,11 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/test/positive9.bicep b/test/fixtures/bicep_test/test/positive9.bicep
new file mode 100644
index 00000000000..0de0191abec
--- /dev/null
+++ b/test/fixtures/bicep_test/test/positive9.bicep
@@ -0,0 +1,14 @@
+resource security_contact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
+ name: 'security contact'
+ properties: {
+ emails: 'sample@email.com'
+ phone: '9999999'
+ alertNotifications: {
+ minimalSeverity: 'High'
+ }
+ notificationsByRole: {
+ state: 'On'
+ roles: ['Owner']
+ }
+ }
+}
diff --git a/test/fixtures/bicep_test/unsuported.bicep b/test/fixtures/bicep_test/unsuported.bicep
new file mode 100644
index 00000000000..8af377c659d
--- /dev/null
+++ b/test/fixtures/bicep_test/unsuported.bicep
@@ -0,0 +1,130 @@
+targetScope = 'resourceGroup'
+
+type obj = {
+ level: 'bronze' | 'silver' | 'gold'
+}
+
+type oneOfSeveralObjects = {foo: 'bar'} | {fizz: 'buzz'} | {snap: 'crackle'}
+type mixedTypeArray = ('fizz' | 42 | {an: 'object'} | null)[]
+
+metadata singleExpressionMetaData = 'something'
+
+metadata objectMetaData = {
+ author: 'Someone'
+ description: 'Something'
+}
+
+@description('Required. The name of the Redis cache resource. Start and end with alphanumeric. Consecutive hyphens not allowed')
+@maxLength(63)
+@minLength(1)
+param name string
+
+@description('The name of an existing keyvault, that it will be used to store secrets (connection string)' )
+param keyvaultName string
+
+// @description('Optional. Enables system assigned managed identity on the resource.')
+// param systemAssignedIdentity bool = false
+
+// @description('Optional. The ID(s) to assign to the resource.')
+// param userAssignedIdentities object = {}
+
+@description('Optional. The name of the diagnostic setting, if deployed.')
+param diagnosticSettingsName string = '${name}-diagnosticSettings'
+
+@description('Optional. Resource ID of the diagnostic log analytics workspace. For security reasons, it is recommended to set diagnostic settings to send data to either storage account, log analytics workspace or event hub.')
+param diagnosticWorkspaceId string = ''
+
+@description('Optional. The name of logs that will be streamed. "allLogs" includes all possible logs for the resource.')
+@allowed([
+ 'allLogs'
+ 'ConnectedClientList'
+])
+param diagnosticLogCategoriesToEnable array = [
+ 'allLogs'
+]
+
+@description('Optional. The name of metrics that will be streamed.')
+@allowed([
+ 'AllMetrics'
+])
+param diagnosticMetricsToEnable array = [
+ 'AllMetrics'
+]
+
+var diagnosticsLogsSpecified = [for category in filter(diagnosticLogCategoriesToEnable, item => item != 'allLogs'): {
+ category: category
+ enabled: true
+}]
+
+var diagnosticsLogs = contains(diagnosticLogCategoriesToEnable, 'allLogs') ? [
+ {
+ categoryGroup: 'allLogs'
+ enabled: true
+ }
+] : diagnosticsLogsSpecified
+
+var diagnosticsMetrics = [for metric in diagnosticMetricsToEnable: {
+ category: metric
+ timeGrain: null
+ enabled: true
+}]
+
+var dogs = [
+ {
+ name: 'Fido'
+ age: 3
+ }
+ {
+ name: 'Rex'
+ age: 7
+ }
+]
+
+// var identityType = systemAssignedIdentity ? 'SystemAssigned' : !empty(userAssignedIdentities) ? 'UserAssigned' : 'None'
+
+// var identity = {
+// type: identityType
+// userAssignedIdentities: !empty(userAssignedIdentities) ? userAssignedIdentities : null
+// }
+
+module singleModuleWithIndexedDependencies 'passthrough.bicep' = {
+ name: 'hello'
+ params: {
+ myInput: concat(moduleCollectionWithCollectionDependencies[index].outputs.myOutput, storageAccounts[index * 3].properties.accessTier)
+ }
+ dependsOn: [
+ storageAccounts2[index - 10]
+ ]
+}
+
+module moduleCollectionWithIndexedDependencies 'passthrough.bicep' = [for moduleName in moduleSetup: {
+ name: moduleName
+ params: {
+ myInput: '${moduleCollectionWithCollectionDependencies[index].outputs.myOutput} - ${storageAccounts[index * 3].properties.accessTier} - ${moduleName}'
+ }
+ dependsOn: [
+ storageAccounts2[index - 9]
+ ]
+}]
+
+resource keyVault 'Microsoft.KeyVault/vaults@2022-11-01' existing = {
+ name: keyvaultName
+}
+
+resource redisCache_diagnosticSettings 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = if ( !empty(diagnosticWorkspaceId) ) {
+ name: diagnosticSettingsName
+ properties: {
+ storageAccountId: null
+ workspaceId: empty(diagnosticWorkspaceId) ? null : diagnosticWorkspaceId
+ eventHubAuthorizationRuleId: null
+ eventHubName: null
+ metrics: empty(diagnosticWorkspaceId) ? null : diagnosticsMetrics
+ logs: empty(diagnosticWorkspaceId) ? null : diagnosticsLogs
+ }
+ scope: resourceGroup()
+}
+
+@description('The resource name.')
+output name string = subscription().displayName
+
+output oldDogs array = filter(dogs, dog => dog.age >=5)
diff --git a/test/fixtures/bicep_test/variables.bicep b/test/fixtures/bicep_test/variables.bicep
new file mode 100644
index 00000000000..45014c1cb5e
--- /dev/null
+++ b/test/fixtures/bicep_test/variables.bicep
@@ -0,0 +1,5 @@
+@description('This is a test var declaration.')
+var storageAccountName = 'bootdiags${uniqueString(resourceGroup().id)}'
+
+@description('This is a test var declaration.')
+var nicName = 'myVMNic'
diff --git a/test/main_test.go b/test/main_test.go
index 9c50fae298a..9cdebacd972 100644
--- a/test/main_test.go
+++ b/test/main_test.go
@@ -17,7 +17,8 @@ import (
ansibleConfigParser "github.com/Checkmarx/kics/v2/pkg/parser/ansible/ini/config"
ansibleHostsParser "github.com/Checkmarx/kics/v2/pkg/parser/ansible/ini/hosts"
buildahParser "github.com/Checkmarx/kics/v2/pkg/parser/buildah"
- dockerParser "github.com/Checkmarx/kics/v2/pkg/parser/docker"
+ bicepParser "github.com/Checkmarx/kics/v2/pkg/parser/bicep"
+ dockerParser "github.com/Checkmarx/kics/v2/pkg/parser/docker"
protoParser "github.com/Checkmarx/kics/v2/pkg/parser/grpc"
jsonParser "github.com/Checkmarx/kics/v2/pkg/parser/json"
terraformParser "github.com/Checkmarx/kics/v2/pkg/parser/terraform"
@@ -64,7 +65,7 @@ var (
"../assets/queries/openAPI/general": {FileKind: []model.FileKind{model.KindYAML, model.KindJSON}, Platform: "openAPI"},
"../assets/queries/openAPI/3.0": {FileKind: []model.FileKind{model.KindYAML, model.KindJSON}, Platform: "openAPI"},
"../assets/queries/openAPI/2.0": {FileKind: []model.FileKind{model.KindYAML, model.KindJSON}, Platform: "openAPI"},
- "../assets/queries/azureResourceManager": {FileKind: []model.FileKind{model.KindJSON}, Platform: "azureResourceManager"},
+ "../assets/queries/azureResourceManager": {FileKind: []model.FileKind{model.KindJSON, model.KindBICEP}, Platform: "azureResourceManager"},
"../assets/queries/googleDeploymentManager/gcp": {FileKind: []model.FileKind{model.KindYAML}, Platform: "googleDeploymentManager"},
"../assets/queries/googleDeploymentManager/gcp_bom": {FileKind: []model.FileKind{model.KindYAML}, Platform: "googleDeploymentManager"},
"../assets/queries/grpc": {FileKind: []model.FileKind{model.KindPROTO}, Platform: "grpc"},
@@ -194,6 +195,7 @@ func getCombinedParser() []*parser.Parser {
bd, _ := parser.NewBuilder().
Add(&jsonParser.Parser{}).
Add(&yamlParser.Parser{}).
+ Add(&bicepParser.Parser{}).
Add(terraformParser.NewDefault()).
Add(&dockerParser.Parser{}).
Add(&protoParser.Parser{}).