Repository navigation
Expand file tree
/
Copy pathmain.bicep
More file actions
244 lines (199 loc) · 10.9 KB
/
Copy pathmain.bicep
File metadata and controls
244 lines (199 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
//==============================================================================
// Parameters
//==============================================================================
targetScope = 'resourceGroup'
@description('Optional. Name of the hub. Used to ensure unique resource names. Default: "finops-hub".')
param hubName string
@description('Optional. Azure location where all resources should be created. See https://aka.ms/azureregions. Default: Same as deployment.')
param location string = resourceGroup().location
// @description('Optional. Azure location to use for a temporary Event Grid namespace to register the Microsoft.EventGrid resource provider if the primary location is not supported. The namespace will be deleted and is not used for hub operation. Default: "" (same as location).')
// param eventGridLocation string = ''
@allowed([
'Premium_LRS'
'Premium_ZRS'
])
@description('Optional. Storage SKU to use. LRS = Lowest cost, ZRS = High availability. Note Standard SKUs are not available for Data Lake gen2 storage. Allowed: Premium_LRS, Premium_ZRS. Default: Premium_LRS.')
param storageSku string = 'Premium_LRS'
@description('Optional. Enable infrastructure encryption on the storage account. Default = false.')
param enableInfrastructureEncryption bool = false
@description('Optional. Enable purge protection for the Key Vault. Default: false.')
param enablePurgeProtection bool = false
@description('Optional. Storage account to push data to for ingestion into a remote hub.')
param remoteHubStorageUri string = ''
@description('Optional. Storage account key to use when pushing data to a remote hub.')
@secure()
param remoteHubStorageKey string = ''
@description('Optional. Enable managed exports where your FinOps hub instance will create and run Cost Management exports on your behalf. Not supported for Microsoft Customer Agreement (MCA) billing profiles. Requires the ability to grant the Role Based Access Control Administrator role to FinOps hubs, which is required to create Cost Management exports. Default: true.')
param enableManagedExports bool = true
@description('Optional. Enable recommendations ingested from Azure Resource Graph based on configurable queries. The Data Factory managed identity requires Reader role on management groups or subscriptions to execute Resource Graph queries. Default: false.')
param enableRecommendations bool = false
@description('Optional. Enable Azure Hybrid Benefit recommendations that flag VMs and SQL VMs without Azure Hybrid Benefit enabled. May generate noise if your organization does not have on-premises licenses. Requires enableRecommendations. Default: false.')
param enableAHBRecommendations bool = false
@description('Optional. Enable non-Spot AKS cluster recommendations that flag AKS clusters with autoscaling but not using Spot VMs. May generate noise since Spot VMs are only appropriate for interruptible workloads. Requires enableRecommendations. Default: false.')
param enableSpotRecommendations bool = false
@description('Optional. Name of the Azure Data Explorer cluster to use for advanced analytics. If empty, Azure Data Explorer will not be deployed. Required to use with Power BI if you have more than $2-5M/mo in costs being monitored. Default: "" (do not use).')
param dataExplorerName string = ''
// https://learn.microsoft.com/azure/templates/microsoft.kusto/clusters?pivots=deployment-language-bicep#azuresku
@description('Optional. Name of the Azure Data Explorer SKU. Default: "Dev(No SLA)_Standard_D11_v2".')
@allowed([
'Dev(No SLA)_Standard_E2a_v4' // 2 CPU, 16GB RAM, 24GB cache, ~$115/mo
'Dev(No SLA)_Standard_D11_v2' // 2 CPU, 14GB RAM, 78GB cache, ~$135/mo
'Standard_D11_v2' // 2 CPU, 14GB RAM, 78GB cache, ~$295/mo
'Standard_D12_v2'
'Standard_D13_v2'
'Standard_D14_v2'
'Standard_D16d_v5'
'Standard_D32d_v4'
'Standard_D32d_v5'
'Standard_DS13_v2+1TB_PS'
'Standard_DS13_v2+2TB_PS'
'Standard_DS14_v2+3TB_PS'
'Standard_DS14_v2+4TB_PS'
'Standard_E2a_v4' // 2 CPU, 14GB RAM, 78GB cache, ~$275/mo
'Standard_E2ads_v5'
'Standard_E2d_v4'
'Standard_E2d_v5'
'Standard_E4a_v4'
'Standard_E4ads_v5'
'Standard_E4d_v4'
'Standard_E4d_v5'
'Standard_E8a_v4'
'Standard_E8ads_v5'
'Standard_E8as_v4+1TB_PS'
'Standard_E8as_v4+2TB_PS'
'Standard_E8as_v5+1TB_PS'
'Standard_E8as_v5+2TB_PS'
'Standard_E8d_v4'
'Standard_E8d_v5'
'Standard_E8s_v4+1TB_PS'
'Standard_E8s_v4+2TB_PS'
'Standard_E8s_v5+1TB_PS'
'Standard_E8s_v5+2TB_PS'
'Standard_E16a_v4'
'Standard_E16ads_v5'
'Standard_E16as_v4+3TB_PS'
'Standard_E16as_v4+4TB_PS'
'Standard_E16as_v5+3TB_PS'
'Standard_E16as_v5+4TB_PS'
'Standard_E16d_v4'
'Standard_E16d_v5'
'Standard_E16s_v4+3TB_PS'
'Standard_E16s_v4+4TB_PS'
'Standard_E16s_v5+3TB_PS'
'Standard_E16s_v5+4TB_PS'
'Standard_E64i_v3'
'Standard_E80ids_v4'
'Standard_EC8ads_v5'
'Standard_EC8as_v5+1TB_PS'
'Standard_EC8as_v5+2TB_PS'
'Standard_EC16ads_v5'
'Standard_EC16as_v5+3TB_PS'
'Standard_EC16as_v5+4TB_PS'
'Standard_L4s'
'Standard_L8as_v3'
'Standard_L8s'
'Standard_L8s_v2'
'Standard_L8s_v3'
'Standard_L16as_v3'
'Standard_L16s'
'Standard_L16s_v2'
'Standard_L16s_v3'
'Standard_L32as_v3'
'Standard_L32s_v3'
])
param dataExplorerSku string = 'Dev(No SLA)_Standard_D11_v2'
@description('Optional. Number of nodes to use in the cluster. Allowed values: 1 for the Basic SKU tier and 2-1000 for Standard. Default: 1 for dev/test SKUs, 2 for standard SKUs.')
@minValue(1)
@maxValue(1000)
param dataExplorerCapacity int = 1
// cSpell:ignore eventhouse
@description('Optional. Microsoft Fabric eventhouse query URI. Default: "" (do not use).')
param fabricQueryUri string = ''
@description('Optional. Number of capacity units for the Microsoft Fabric capacity. This is the number in your Fabric SKU (e.g., Trial = 1, F2 = 2, F64 = 64). This is used to manage parallelization in data pipelines. If you change capacity, please redeploy the template. Allowed values: 1 for the Fabric trial and 2-2048 based on the assigned Fabric capacity (e.g., F2-F2048). Default: 2.')
@minValue(1)
@maxValue(2048)
param fabricCapacityUnits int = 2
@description('Optional. Tags to apply to all resources. We will also add the cm-resource-parent tag for improved cost roll-ups in Cost Management.')
param tags object = {}
@description('Optional. Tags to apply to resources based on their resource type. Resource type specific tags will be merged with tags for all resources.')
param tagsByResource object = {}
@description('Optional. List of scope IDs to monitor and ingest cost for.')
param scopesToMonitor array = []
@description('Optional. Number of days of data to retain in the msexports container. Default: 0.')
param exportRetentionInDays int = 0
@description('Optional. Number of months of data to retain in the ingestion container. Default: 13.')
param ingestionRetentionInMonths int = 13
@description('Optional. Number of days of data to retain in the Data Explorer *_raw tables. Default: 0.')
param dataExplorerRawRetentionInDays int = 0
@description('Optional. Number of months of data to retain in the Data Explorer *_final_v* tables. Default: 13.')
param dataExplorerFinalRetentionInMonths int = 13
@description('Optional. Enable public access to FinOps hubs resources. Default: true.')
param enablePublicAccess bool = true
@description('Optional. Deploy a NAT Gateway for controlled outbound access when private routing is enabled. When true, the script and Data Explorer subnets route outbound traffic through the NAT Gateway. Ignored when enablePublicAccess is true. Default: false.')
param enableNatGateway bool = false
@description('Optional. Address space for the workload. Minimum /26 subnet size is required for the workload. Default: "10.20.30.0/26".')
param virtualNetworkAddressPrefix string = '10.20.30.0/26'
//==============================================================================
// Resources
//==============================================================================
module hub 'modules/hub.bicep' = {
name: 'hub'
params: {
hubName: hubName
location: location
// eventGridLocation: eventGridLocation
storageSku: storageSku
enableInfrastructureEncryption: enableInfrastructureEncryption
enablePurgeProtection: enablePurgeProtection
enableManagedExports: enableManagedExports
enableRecommendations: enableRecommendations
enableAHBRecommendations: enableAHBRecommendations
enableSpotRecommendations: enableSpotRecommendations
dataExplorerName: dataExplorerName
dataExplorerSku: dataExplorerSku
dataExplorerCapacity: dataExplorerCapacity
fabricQueryUri: fabricQueryUri
fabricCapacityUnits: fabricCapacityUnits
tags: tags
tagsByResource: tagsByResource
scopesToMonitor: scopesToMonitor
exportRetentionInDays: exportRetentionInDays
ingestionRetentionInMonths: ingestionRetentionInMonths
dataExplorerRawRetentionInDays: dataExplorerRawRetentionInDays
dataExplorerFinalRetentionInMonths: dataExplorerFinalRetentionInMonths
remoteHubStorageUri: remoteHubStorageUri
remoteHubStorageKey: remoteHubStorageKey
enablePublicAccess: enablePublicAccess
enableNatGateway: enableNatGateway
virtualNetworkAddressPrefix: virtualNetworkAddressPrefix
}
}
//==============================================================================
// Outputs
//==============================================================================
@description('Name of the resource group.')
output name string = hubName
@description('Azure resource location resources were deployed to.')
output location string = location
@description('Name of the Data Factory instance.')
output dataFactoryName string = hub.outputs.dataFactoryName
@description('Resource ID of the deployed storage account.')
output storageAccountId string = hub.outputs.storageAccountId
@description('Name of the storage account created for the hub instance. This must be used when connecting FinOps toolkit Power BI reports to your data.')
output storageAccountName string = hub.outputs.storageAccountName
@description('URL to use when connecting custom Power BI reports to your data.')
output storageUrlForPowerBI string = hub.outputs.storageUrlForPowerBI
@description('Resource ID of the Data Explorer cluster.')
output clusterId string = hub.outputs.clusterId
@description('URI of the Data Explorer cluster.')
output clusterUri string = hub.outputs.clusterUri
@description('Name of the Data Explorer database used for ingesting data.')
output ingestionDbName string = hub.outputs.ingestionDbName
@description('Name of the Data Explorer database used for querying data.')
output hubDbName string = hub.outputs.hubDbName
@description('Object ID of the Data Factory managed identity. This will be needed when configuring managed exports.')
output managedIdentityId string = hub.outputs.managedIdentityId
@description('Azure AD tenant ID. This will be needed when configuring managed exports.')
output managedIdentityTenantId string = hub.outputs.managedIdentityTenantId