├── .gitignore
├── AnomaliesDetection
├── AnomaliesDetection.json
├── README.md
└── images
│ ├── KQL.jpg
│ ├── apikey.jpg
│ ├── compose.jpg
│ ├── emailandvariable.jpg
│ ├── identitypermission.jpg
│ ├── openai.jpg
│ ├── parallelism.jpg
│ ├── question.jpg
│ └── recurrence.jpg
├── Arc-SQL BPA
├── README.md
├── SQLBPA-V2.json
└── images
│ ├── ApiKey.jpg
│ ├── BingKey.jpg
│ ├── BingSearch.jpg
│ ├── BingSearch_Conf.jpg
│ ├── BingSearch_Creation.jpg
│ ├── HelpLinkParameter.jpg
│ ├── HighThroughput.jpg
│ ├── SubRegistration.jpg
│ ├── composeCSV.jpeg
│ ├── deploy.jpg
│ ├── enable.jpg
│ ├── final-questiontoAI.jpg
│ ├── http-connector.jpg
│ ├── identity.jpg
│ ├── query-value.jpg
│ ├── recurrence.jpg
│ ├── run-query-list-result1.jpg
│ ├── run-query-list-result2.jpg
│ ├── run-query-list-result3.jpg
│ ├── send-email1.jpg
│ ├── send-email2.jpg
│ ├── sendEmail-broken.jpg
│ ├── set-variable-redirect-url.jpeg
│ ├── severity.jpg
│ └── value-question.jpg
├── CODE_OF_CONDUCT.md
├── CostMonthlyCheck
├── CostMonthlyCheck.json
├── README.md
└── images
│ ├── ApiKey.jpg
│ ├── OpenAI.jpg
│ ├── Recurrence.jpg
│ ├── Sub-Id.jpeg
│ ├── example-notification.jpg
│ └── identity.jpg
├── FunctionAppSmartDocs
├── README.md
├── function_app.py
├── host.json
├── images
│ └── immagine.png
├── local.settings.json
└── requirements.txt
├── GIT.jpg
├── LICENSE
├── Learning
├── README.md
└── images
│ ├── AC.png
│ ├── Azure APIM.jpg
│ ├── Azure Logic APp.jpg
│ ├── AzureOpenAI.png
│ ├── Learn.png
│ ├── Microsoft Learn.jpg
│ └── model.jpg
├── OpenAI-CoreIntegrationLZ
├── AIServicesForInfraELZ.json
├── AnomaliesDetection.json
├── CostMonthlyCheck.json
├── CreateFunction.json
├── README.md
├── SQLBPAV2.json
├── UpdateManagement.json
├── images
│ ├── OpenAI-CoreIntegration_page-0001.jpg
│ ├── deploy.jpeg
│ ├── deployment_complete.jpeg
│ └── start_deployment.jpeg
├── templateBingSearch.json
└── templateOpenAI.json
├── Prereq.png
├── README.md
├── SECURITY.md
├── SUPPORT.md
└── UpdateManagement
├── README.md
├── UpdateManagement.json
└── images
├── ApiKey.jpg
├── Compose.jpeg
├── OpenAI.jpg
├── example-notification.jpg
├── identity.jpg
└── recurrence.jpg
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Ll]og/
33 | [Ll]ogs/
34 |
35 | # Visual Studio 2015/2017 cache/options directory
36 | .vs/
37 | # Uncomment if you have tasks that create the project's static files in wwwroot
38 | #wwwroot/
39 |
40 | # Visual Studio 2017 auto generated files
41 | Generated\ Files/
42 |
43 | # MSTest test Results
44 | [Tt]est[Rr]esult*/
45 | [Bb]uild[Ll]og.*
46 |
47 | # NUnit
48 | *.VisualState.xml
49 | TestResult.xml
50 | nunit-*.xml
51 |
52 | # Build Results of an ATL Project
53 | [Dd]ebugPS/
54 | [Rr]eleasePS/
55 | dlldata.c
56 |
57 | # Benchmark Results
58 | BenchmarkDotNet.Artifacts/
59 |
60 | # .NET Core
61 | project.lock.json
62 | project.fragment.lock.json
63 | artifacts/
64 |
65 | # ASP.NET Scaffolding
66 | ScaffoldingReadMe.txt
67 |
68 | # StyleCop
69 | StyleCopReport.xml
70 |
71 | # Files built by Visual Studio
72 | *_i.c
73 | *_p.c
74 | *_h.h
75 | *.ilk
76 | *.meta
77 | *.obj
78 | *.iobj
79 | *.pch
80 | *.pdb
81 | *.ipdb
82 | *.pgc
83 | *.pgd
84 | *.rsp
85 | *.sbr
86 | *.tlb
87 | *.tli
88 | *.tlh
89 | *.tmp
90 | *.tmp_proj
91 | *_wpftmp.csproj
92 | *.log
93 | *.tlog
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio 6 auto-generated project file (contains which files were open etc.)
298 | *.vbp
299 |
300 | # Visual Studio 6 workspace and project file (working project files containing files to include in project)
301 | *.dsw
302 | *.dsp
303 |
304 | # Visual Studio 6 technical files
305 | *.ncb
306 | *.aps
307 |
308 | # Visual Studio LightSwitch build output
309 | **/*.HTMLClient/GeneratedArtifacts
310 | **/*.DesktopClient/GeneratedArtifacts
311 | **/*.DesktopClient/ModelManifest.xml
312 | **/*.Server/GeneratedArtifacts
313 | **/*.Server/ModelManifest.xml
314 | _Pvt_Extensions
315 |
316 | # Paket dependency manager
317 | .paket/paket.exe
318 | paket-files/
319 |
320 | # FAKE - F# Make
321 | .fake/
322 |
323 | # CodeRush personal settings
324 | .cr/personal
325 |
326 | # Python Tools for Visual Studio (PTVS)
327 | __pycache__/
328 | *.pyc
329 |
330 | # Cake - Uncomment if you are using it
331 | # tools/**
332 | # !tools/packages.config
333 |
334 | # Tabs Studio
335 | *.tss
336 |
337 | # Telerik's JustMock configuration file
338 | *.jmconfig
339 |
340 | # BizTalk build output
341 | *.btp.cs
342 | *.btm.cs
343 | *.odx.cs
344 | *.xsd.cs
345 |
346 | # OpenCover UI analysis results
347 | OpenCover/
348 |
349 | # Azure Stream Analytics local run output
350 | ASALocalRun/
351 |
352 | # MSBuild Binary and Structured Log
353 | *.binlog
354 |
355 | # NVidia Nsight GPU debugger configuration file
356 | *.nvuser
357 |
358 | # MFractors (Xamarin productivity tool) working folder
359 | .mfractor/
360 |
361 | # Local History for Visual Studio
362 | .localhistory/
363 |
364 | # Visual Studio History (VSHistory) files
365 | .vshistory/
366 |
367 | # BeatPulse healthcheck temp database
368 | healthchecksdb
369 |
370 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
371 | MigrationBackup/
372 |
373 | # Ionide (cross platform F# VS Code tools) working folder
374 | .ionide/
375 |
376 | # Fody - auto-generated XML schema
377 | FodyWeavers.xsd
378 |
379 | # VS Code files for those working on multiple tools
380 | .vscode/*
381 | !.vscode/settings.json
382 | !.vscode/tasks.json
383 | !.vscode/launch.json
384 | !.vscode/extensions.json
385 | *.code-workspace
386 |
387 | # Local History for Visual Studio Code
388 | .history/
389 |
390 | # Windows Installer files from build outputs
391 | *.cab
392 | *.msi
393 | *.msix
394 | *.msm
395 | *.msp
396 |
397 | # JetBrains Rider
398 | *.sln.iml
399 |
--------------------------------------------------------------------------------
/AnomaliesDetection/AnomaliesDetection.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "workflows_OpenAIAnomalyDetectionAD_gen_name": {
6 | "defaultValue": "OpenAIAnomalyDetectionAD",
7 | "type": "String"
8 | },
9 | "connections_azuremonitorlogs_1_externalid": {
10 | "defaultValue": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/connections/office365')]",
11 | "type": "String"
12 | }
13 | },
14 | "variables": {},
15 | "resources": [
16 | {
17 | "type": "Microsoft.Logic/workflows",
18 | "apiVersion": "2017-07-01",
19 | "name": "[parameters('workflows_OpenAIAnomalyDetectionAD_gen_name')]",
20 | "location": "[resourceGroup().location]",
21 | "identity": {
22 | "type": "SystemAssigned"
23 | },
24 | "properties": {
25 | "state": "Disabled",
26 | "definition": {
27 | "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
28 | "contentVersion": "1.0.0.0",
29 | "parameters": {
30 | "$connections": {
31 | "defaultValue": {},
32 | "type": "Object"
33 | }
34 | },
35 | "triggers": {
36 | "Recurrence": {
37 | "recurrence": {
38 | "frequency": "Day",
39 | "interval": 1,
40 | "timeZone": "W. Europe Standard Time",
41 | "schedule": {
42 | "hours": [
43 | "9"
44 | ]
45 | }
46 | },
47 | "evaluatedRecurrence": {
48 | "frequency": "Day",
49 | "interval": 1,
50 | "timeZone": "W. Europe Standard Time",
51 | "schedule": {
52 | "hours": [
53 | "9"
54 | ]
55 | }
56 | },
57 | "type": "Recurrence"
58 | }
59 | },
60 | "actions": {
61 | "Api-Key": {
62 | "runAfter": {
63 | "Run_query_and_list_results_V2_(Preview)": [
64 | "Succeeded"
65 | ]
66 | },
67 | "type": "InitializeVariable",
68 | "inputs": {
69 | "variables": [
70 | {
71 | "name": "Api-Key",
72 | "type": "string",
73 | "value": "replace with your OpenAI api key"
74 | }
75 | ]
76 | }
77 | },
78 | "Compose": {
79 | "runAfter": {
80 | "Clean_Result_III": [
81 | "Succeeded"
82 | ]
83 | },
84 | "type": "Compose",
85 | "inputs": "\n\n
Sistema automatico di segnalazione anomalie in ambiente AD- SiverzaLab Environment
\n
\nSalve, a seguito di un analisi all'interno dell'infrastruttura monitorata, è stato evidenziata la seguente anomalia:
\n-------------------------------------------------------------------------------------
\n\n@{variables('ReportIII')}\n
\n\n
\n\n(*) Il sistema genera i dati sfruttando l'OpenAI pertando protrebbero verificarsi delle anomalie nel testo inerenti alla formattazione.
\n
\n\n"
86 | },
87 | "For_each_result": {
88 | "foreach": "@body('Run_query_and_list_results_V2_(Preview)')?['value']",
89 | "actions": {
90 | "Update_variable_Question": {
91 | "type": "SetVariable",
92 | "inputs": {
93 | "name": "Question",
94 | "value": "E' stata identificata la seguente anomalia da un sistema di monitoraggio. Dai qualche info in più su quando è stato identificato il messaggio, che EventID è con informazioni relative all'errore e la risorsa di riferimento, nient'altro:TimeGenerated=\n@{item()?['TimeGenerated']};@{item()?['ActualUsage']};@{item()?['ExpectedUsage']};@{item()?['AnomalyScore']};EvendID=@{item()?['EventID']};DC=@{item()?['Computer']}\nSegui questo esempio e usa \";\" come separatore:\nIl giorno 24 novembre 2024 alle ore 15 è stata segnalata un'anomalia sul sistema @{item()?['Computer']} con eventID @{item()?['EventID']}; L'event ID indica problemi di autenticazione utente;Alcuni step per il troublescooting:;Verifica Event Viewer; Verifica accessi anomali all'infrastruttura; Controlla le performance dell'applicazione;\n\n "
95 | }
96 | },
97 | "Ask_to_OpenAI": {
98 | "runAfter": {
99 | "Update_variable_Question": [
100 | "Succeeded"
101 | ]
102 | },
103 | "type": "Http",
104 | "inputs": {
105 | "uri": "https://changeendpointname.openai.azure.com/openai/deployments/changemodelname/chat/completions?api-version=2024-02-15-preview",
106 | "method": "POST",
107 | "headers": {
108 | "Content-Type": "application/json",
109 | "api-key": "@variables('Api-Key')"
110 | },
111 | "body": {
112 | "max_tokens": 600,
113 | "temperature": 0.3,
114 | "messages": [
115 | {
116 | "content": "Sei un assistente che elenca le anomalie avvenute sui Domain Controllers di Microsoft Active Directory.",
117 | "role": "user"
118 | },
119 | {
120 | "content": "@{variables('Question')}",
121 | "role": "user"
122 | }
123 | ]
124 | }
125 | }
126 | },
127 | "Parse_OpenAI_response": {
128 | "runAfter": {
129 | "Ask_to_OpenAI": [
130 | "Succeeded"
131 | ]
132 | },
133 | "type": "ParseJson",
134 | "inputs": {
135 | "content": "@body('Ask_to_OpenAI')",
136 | "schema": {
137 | "properties": {
138 | "body": {
139 | "properties": {
140 | "choices": {
141 | "items": {
142 | "properties": {
143 | "content_filter_results": {
144 | "properties": {
145 | "hate": {
146 | "properties": {
147 | "filtered": {
148 | "type": "boolean"
149 | },
150 | "severity": {
151 | "type": "string"
152 | }
153 | },
154 | "type": "object"
155 | },
156 | "self_harm": {
157 | "properties": {
158 | "filtered": {
159 | "type": "boolean"
160 | },
161 | "severity": {
162 | "type": "string"
163 | }
164 | },
165 | "type": "object"
166 | },
167 | "sexual": {
168 | "properties": {
169 | "filtered": {
170 | "type": "boolean"
171 | },
172 | "severity": {
173 | "type": "string"
174 | }
175 | },
176 | "type": "object"
177 | },
178 | "violence": {
179 | "properties": {
180 | "filtered": {
181 | "type": "boolean"
182 | },
183 | "severity": {
184 | "type": "string"
185 | }
186 | },
187 | "type": "object"
188 | }
189 | },
190 | "type": "object"
191 | },
192 | "finish_reason": {
193 | "type": "string"
194 | },
195 | "index": {
196 | "type": "integer"
197 | },
198 | "message": {
199 | "properties": {
200 | "content": {
201 | "type": "string"
202 | },
203 | "role": {
204 | "type": "string"
205 | }
206 | },
207 | "type": "object"
208 | }
209 | },
210 | "required": [
211 | "index",
212 | "finish_reason",
213 | "message",
214 | "content_filter_results"
215 | ],
216 | "type": "object"
217 | },
218 | "type": "array"
219 | },
220 | "created": {
221 | "type": "integer"
222 | },
223 | "id": {
224 | "type": "string"
225 | },
226 | "model": {
227 | "type": "string"
228 | },
229 | "object": {
230 | "type": "string"
231 | },
232 | "prompt_filter_results": {
233 | "items": {
234 | "properties": {
235 | "content_filter_results": {
236 | "properties": {
237 | "hate": {
238 | "properties": {
239 | "filtered": {
240 | "type": "boolean"
241 | },
242 | "severity": {
243 | "type": "string"
244 | }
245 | },
246 | "type": "object"
247 | },
248 | "self_harm": {
249 | "properties": {
250 | "filtered": {
251 | "type": "boolean"
252 | },
253 | "severity": {
254 | "type": "string"
255 | }
256 | },
257 | "type": "object"
258 | },
259 | "sexual": {
260 | "properties": {
261 | "filtered": {
262 | "type": "boolean"
263 | },
264 | "severity": {
265 | "type": "string"
266 | }
267 | },
268 | "type": "object"
269 | },
270 | "violence": {
271 | "properties": {
272 | "filtered": {
273 | "type": "boolean"
274 | },
275 | "severity": {
276 | "type": "string"
277 | }
278 | },
279 | "type": "object"
280 | }
281 | },
282 | "type": "object"
283 | },
284 | "prompt_index": {
285 | "type": "integer"
286 | }
287 | },
288 | "required": [
289 | "prompt_index",
290 | "content_filter_results"
291 | ],
292 | "type": "object"
293 | },
294 | "type": "array"
295 | },
296 | "usage": {
297 | "properties": {
298 | "completion_tokens": {
299 | "type": "integer"
300 | },
301 | "prompt_tokens": {
302 | "type": "integer"
303 | },
304 | "total_tokens": {
305 | "type": "integer"
306 | }
307 | },
308 | "type": "object"
309 | }
310 | },
311 | "type": "object"
312 | }
313 | },
314 | "type": "object"
315 | }
316 | }
317 | },
318 | "For_each": {
319 | "foreach": "@outputs('Parse_OpenAI_response')?['body']?['choices']",
320 | "actions": {
321 | "Append_to_array_variable": {
322 | "type": "AppendToArrayVariable",
323 | "inputs": {
324 | "name": "Anomalies",
325 | "value": "@items('For_each')?['message']?['content']"
326 | }
327 | }
328 | },
329 | "runAfter": {
330 | "Parse_OpenAI_response": [
331 | "Succeeded"
332 | ]
333 | },
334 | "type": "Foreach"
335 | }
336 | },
337 | "runAfter": {
338 | "Set_Variable_Anomaly_Detection": [
339 | "Succeeded"
340 | ]
341 | },
342 | "type": "Foreach",
343 | "runtimeConfiguration": {
344 | "concurrency": {
345 | "repetitions": 1
346 | }
347 | }
348 | },
349 | "Run_query_and_list_results_V2_(Preview)": {
350 | "runAfter": {},
351 | "type": "ApiConnection",
352 | "inputs": {
353 | "host": {
354 | "connection": {
355 | "name": "@parameters('$connections')['azuremonitorlogs-1']['connectionId']"
356 | }
357 | },
358 | "method": "post",
359 | "body": {
360 | "query": "let starttime = 7d; \nlet endtime = 0d;\nlet timeframe = 60m;\nEvent \n| where TimeGenerated between (startofday(ago(starttime)) .. startofday(ago(endtime))) \n| where Computer startswith \"DC\"\n| where RenderedDescription contains \"error\" \n| summarize count() by bin(TimeGenerated, 60s), Computer, EventID \n| make-series ActualUsage=avg(count_) default = 0 on TimeGenerated from startofday(ago(starttime)) \tto startofday(ago(endtime)) step timeframe by Computer, EventID \n| extend(Anomalies, AnomalyScore, ExpectedUsage) = series_decompose_anomalies(ActualUsage) \n| mv-expand\n ActualUsage to typeof(double),\n TimeGenerated to typeof(datetime),\n Anomalies to typeof(double),\n AnomalyScore to typeof(double),\n ExpectedUsage to typeof(long)\n| where abs(AnomalyScore) > 7 and abs(ActualUsage - ExpectedUsage) / ActualUsage > 0.5 \n| project TimeGenerated, ActualUsage, ExpectedUsage, abs(AnomalyScore), EventID, Computer\n| sort by abs(AnomalyScore) desc",
361 | "timerangetype": "3"
362 | },
363 | "path": "/queryDataV2",
364 | "queries": {
365 | "subscriptions": "replacewithsubid",
366 | "resourcegroups": "replacewithR",
367 | "resourcetype": "Log Analytics Workspace",
368 | "resourcename": "replacewithRN"
369 | }
370 | }
371 | },
372 | "Set_Variable_Question": {
373 | "runAfter": {
374 | "Api-Key": [
375 | "Succeeded"
376 | ]
377 | },
378 | "type": "InitializeVariable",
379 | "inputs": {
380 | "variables": [
381 | {
382 | "name": "Question",
383 | "type": "string"
384 | }
385 | ]
386 | }
387 | },
388 | "Set_Variable_Anomaly_Detection": {
389 | "runAfter": {
390 | "Set_Variable_Question": [
391 | "Succeeded"
392 | ]
393 | },
394 | "type": "InitializeVariable",
395 | "inputs": {
396 | "variables": [
397 | {
398 | "name": "Anomalies",
399 | "type": "array"
400 | }
401 | ]
402 | }
403 | },
404 | "Clean_Result_I": {
405 | "runAfter": {
406 | "For_each_result": [
407 | "Succeeded"
408 | ]
409 | },
410 | "type": "InitializeVariable",
411 | "inputs": {
412 | "variables": [
413 | {
414 | "name": "Report",
415 | "type": "string",
416 | "value": "@replace(string(variables('Anomalies')), '[\"','
')"
417 | }
418 | ]
419 | }
420 | },
421 | "Clean_Result_II": {
422 | "runAfter": {
423 | "Clean_Result_I": [
424 | "Succeeded"
425 | ]
426 | },
427 | "type": "InitializeVariable",
428 | "inputs": {
429 | "variables": [
430 | {
431 | "name": "ReportII",
432 | "type": "string",
433 | "value": "@replace(variables('Report'), '\",\"','
')"
434 | }
435 | ]
436 | }
437 | },
438 | "Clean_Result_III": {
439 | "runAfter": {
440 | "Clean_Result_II": [
441 | "Succeeded"
442 | ]
443 | },
444 | "type": "InitializeVariable",
445 | "inputs": {
446 | "variables": [
447 | {
448 | "name": "ReportIII",
449 | "type": "string",
450 | "value": "@replace(variables('ReportII'), '\"]','
')"
451 | }
452 | ]
453 | }
454 | }
455 | },
456 | "outputs": {}
457 | },
458 | "parameters": {
459 | "$connections": {
460 | "value": {
461 |
462 | }
463 | }
464 | }
465 | }
466 | }
467 | ]
468 | }
--------------------------------------------------------------------------------
/AnomaliesDetection/README.md:
--------------------------------------------------------------------------------
1 | Azure Anomalies Detection integration: Configuration
2 |
3 | | **Parameters** | **Information** | **Note** |
4 | | ------------- | ------------- | ------------- |
5 | | recurrence | The scheduled option for manage the Logic App execution | Configure the recurrence following your requirements |
6 | | api-key | The API code for manage your OpenAI service | Put your question in the "value" attribute |
7 | | changeendpointname | Insert the OpenAI endpoint name | You can found the value inside the OpenAI resource inside Azure Cognitive Service |
8 | | changemodelname | Insert the model name | You can found the value inside the OpenAI resource inside Azure Cognitive Service |
9 |
10 | Important
11 | This LogApp and the following changes are an example of integrating AnomalyDetection results with OpenAI, creating a report to send via Email with OpenAI comment.
12 |
13 |
14 | Required Identity
15 | Managed Identity
16 |
17 | After the deployment the Logic App is ready to be configured. As a first requirement, check if the Managed Identity is active and assign the required permission to work with the required resources (Log Analytics).
18 |
19 |
20 | 
21 |
22 | Ad this point, in the Logic App Designer, configure the Recurrence following your requirements.
23 |
24 |
25 | 
26 |
27 |
28 | "Run query and list result V2" is the core block here. We have to replace the block using the same one and modify the query. Below you can found the block and the query:
29 |
30 |
31 | 
32 |
33 | ```KQL
34 | let starttime = 7d;
35 | let endtime = 0d;
36 | let timeframe = 60m;
37 | Event
38 | | where TimeGenerated between (startofday(ago(starttime)) .. startofday(ago(endtime)))
39 | | where Computer startswith "DC"
40 | | where RenderedDescription contains "error"
41 | | summarize count() by bin(TimeGenerated, 60s), Computer, EventID
42 | | make-series ActualUsage=avg(count_) default = 0 on TimeGenerated from startofday(ago(starttime)) to startofday(ago(endtime)) step timeframe by Computer, EventID
43 | | extend(Anomalies, AnomalyScore, ExpectedUsage) = series_decompose_anomalies(ActualUsage)
44 | | mv-expand
45 | ActualUsage to typeof(double),
46 | TimeGenerated to typeof(datetime),
47 | Anomalies to typeof(double),
48 | AnomalyScore to typeof(double),
49 | ExpectedUsage to typeof(long)
50 | | where abs(AnomalyScore) > 7 and abs(ActualUsage - ExpectedUsage) / ActualUsage > 0.5
51 | | project TimeGenerated, ActualUsage, ExpectedUsage, abs(AnomalyScore), EventID, Computer
52 | | sort by abs(AnomalyScore) desc
53 | ```
54 |
55 |
56 | The Api-Key is needed for interact with the OpenAI model. You can place your key in the "Api-Key" variable.
57 |
58 |
59 | 
60 |
61 |
62 | Leave the Set Variable Question and Set Variable Anomaly Detection empty, the focus now is the For_each_result. Click on it, swith to "Setting", activate the "Limit" and set the "Degree of parallelism" to 1:
63 |
64 |
65 | 
66 |
67 |
68 | "Update variable Question" is another important point, because it handle the question that we pass to OpenAI. Modify the variable following your requirements.
69 |
70 |
71 | 
72 |
73 |
74 | At this point is importat to customize the "Ask to OpenAI" block. This block handle the communication with the LLM model. Customize the required parameters.
75 |
76 |
77 | 
78 |
79 |
80 | One of the last block to customize is the "Compose", because it manage the format of the communication that the e-mail block send to the attenders. Here you can found an example:
81 |
82 | ```Compose
83 |
84 |
85 | Sistema automatico di segnalazione anomalie in ambiente AD- SiverzaLab Environment
86 |
87 | Salve, a seguito di un analisi all'interno dell'infrastruttura monitorata, è stato evidenziata la seguente anomalia:
88 | -------------------------------------------------------------------------------------
89 |
90 | @{variables('ReportIII')}
91 |
92 |
93 |
94 |
95 | (*) Il sistema genera i dati sfruttando l'OpenAI pertando protrebbero verificarsi delle anomalie nel testo inerenti alla formattazione.
96 |
97 |
98 |
99 | ```
100 | > [!TIP]
101 | > The provided Logic App, as an artifact, will send an email without a condition. An improvement could be to manage the result using a condition, and if the condition is not satisfied, send an e-mail, in order to avoid unattended results. The configuration is up to your requirements.
102 |
103 | 
104 |
105 |
106 | The last point, we are talking about the "Send an email (V2) block. This block is used for send communication to the attenders. Customize the email, you can use the example below:
107 |
108 |
109 | 
--------------------------------------------------------------------------------
/AnomaliesDetection/images/KQL.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/KQL.jpg
--------------------------------------------------------------------------------
/AnomaliesDetection/images/apikey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/apikey.jpg
--------------------------------------------------------------------------------
/AnomaliesDetection/images/compose.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/compose.jpg
--------------------------------------------------------------------------------
/AnomaliesDetection/images/emailandvariable.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/emailandvariable.jpg
--------------------------------------------------------------------------------
/AnomaliesDetection/images/identitypermission.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/identitypermission.jpg
--------------------------------------------------------------------------------
/AnomaliesDetection/images/openai.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/openai.jpg
--------------------------------------------------------------------------------
/AnomaliesDetection/images/parallelism.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/parallelism.jpg
--------------------------------------------------------------------------------
/AnomaliesDetection/images/question.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/question.jpg
--------------------------------------------------------------------------------
/AnomaliesDetection/images/recurrence.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/AnomaliesDetection/images/recurrence.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/README.md:
--------------------------------------------------------------------------------
1 | Azure SQL BPA OpenAI integration: Configuration
2 |
3 | | **Parameters/Requirements** | **Information** | **Note** |
4 | | ------------- | ------------- | ------------- |
5 | | Azure OpenAI Model | This solution require specific Azure OpenAI Model | Version gpt-4-1106-preview |
6 | | replacewithsubid | Connection setting during deployment | Replace with your Subscription ID |
7 | | replacewithRG | Connection setting during deployment | Replace with the selected RG Name for the deployment |
8 | | replace with tenant id | HTTP Module: Tenant ID | Replace with your Tenant ID |
9 | | OpenAI API Key | String Resource to connect to OpenAI | Replace with your Azure OpenAI Key |
10 |
11 |
12 | Important
13 | This LogApp and the following changes are an example of integrating SQL BPA results with OpenAI, creating an HTML report and CSV file send via Email with OpenAI comment of Severity High and/or Medium results.
14 | You can customize them to your liking such as changing the query and/or question to ChatGPT as well as sending the results not only via email but also to Ondrive or Storage Account for example.
15 | Before using it you must have enabled and performed SQL Best Practices Assessment on your hybrid Machine.
16 |
17 |
18 | Reference:
19 | [Azure ARC SQL Assessment](https://learn.microsoft.com/en-us/sql/sql-server/azure-arc/assess?view=sql-server-ver16&tabs=portal)
20 |
21 | Deploy
22 |
23 | When you deploy, replace with your SubscriptionID and ResourceGroup Name:
24 |
25 | 
26 |
27 |
28 | Required Identity
29 | Managed Identity
30 |
31 | When the deployment is completed go in your Logic App and create a Managed Identity following the example below and give them __LogAnalytics Reader__ permission:
32 |
33 | 
34 |
35 | Logic App Workflow Setting
36 | High throughput
37 |
38 | Set High throughput to ON:
39 |
40 | 
41 |
42 | Deployment and Result
43 |
44 | After deployment completed, please follow the documentation:
45 |
46 |
47 | Change __Recurrence__ section after SQL BPA has been performed:
48 |
49 | 
50 |
51 | Change the broken module __Run query and list result__ with a new one
52 |
53 | Before:
54 | 
55 |
56 | After:
57 | 
58 |
59 | Compile all the information following your configuration.
60 | For the query field past the code below:
61 |
62 | ```query
63 | let selectedCategories = dynamic([]);
64 | let selectedTotSev = dynamic([]);
65 | SqlAssessment_CL
66 | | extend asmt = parse_csv(RawData)
67 | //| where asmt[11] =~ "MSSQLSERVER"
68 | | extend
69 | AsmtId=tostring(asmt[1]),
70 | CheckId=tostring(asmt[2]),
71 | DisplayString=asmt[3],
72 | Description=tostring(asmt[4]),
73 | HelpLink=asmt[5],
74 | TargetType=case(asmt[6] == 1, "Server", asmt[6] == 2, "Database", ""),
75 | TargetName=tostring(asmt[7]),
76 | Severity=case(asmt[8] == 30, "High", asmt[8] == 20, "Medium", asmt[8] == 10, "Low", asmt[8] == 0, "Information", asmt[8] == 1, "Warning", asmt[8] == 2, "Critical", "Passed"),
77 | Message=tostring(asmt[9]),
78 | TagsArr=split(tostring(asmt[10]), ","),
79 | Sev = toint(asmt[8])
80 | | where isnotempty(AsmtId)
81 | and (set_has_element(dynamic(['*']), CheckId) or "'*'" == "'*'")
82 | and (set_has_element(dynamic(['*']), TargetName) or "'*'" == "'*'")
83 | and set_has_element(dynamic([30, 20, 10, 0]), Sev)
84 | and (array_length(set_intersect(TagsArr, dynamic(['*']))) > 0 or "'*'" == "'*'")
85 | and (CheckId == '''' and Sev == 0 or "''" == "''")
86 | | extend Category = case(
87 | array_length(set_intersect(TagsArr, dynamic(["CPU", "IO", "Storage"]))) > 0,
88 | '0',
89 | array_length(set_intersect(TagsArr, dynamic(["TraceFlag", "Backup", "DBCC", "DBConfiguration", "SystemHealth", "Traces", "DBFileConfiguration", "Configuration", "Replication", "Agent", "Security", "DataIntegrity", "MaxDOP", "PageFile", "Memory", "Performance", "Statistics"]))) > 0,
90 | '1',
91 | array_length(set_intersect(TagsArr, dynamic(["UpdateIssues", "Index", "Naming", "Deprecated", "masterDB", "QueryOptimizer", "QueryStore", "Indexes"]))) > 0,
92 | '2',
93 | '3'
94 | )
95 | | where (Sev >= 0 and array_length(selectedTotSev) == 0 or Sev in (selectedTotSev))
96 | and (Category in (selectedCategories) or array_length(selectedCategories) == 0)
97 | | project
98 | TargetType,
99 | TargetName,
100 | Severity,
101 | Message,
102 | Tags=strcat_array(array_slice(TagsArr, 1, -1), ', '),
103 | CheckId,
104 | Description,
105 | HelpLink = tostring(HelpLink),
106 | SeverityCode = toint(Sev)
107 | | order by SeverityCode desc, TargetType desc, TargetName asc
108 | | project-away SeverityCode
109 | ```
110 |
111 | Configure the Api Key with the value inside your OpenAI Service:
112 |
113 | 
114 |
115 | Configure __ForeachSQLResult__ section with value of query result and each parameter in Question variable as you like:
116 |
117 | 
118 |
119 | And now configure the RedirectUrl variable following the example:
120 |
121 | 
122 |
123 | Configure the Question Variable following the example below:
124 |
125 | 
126 |
127 | NB. you can use the following variable below to valorize the items i greyed out:
128 |
129 | ```
130 | @{item()?['Message']}
131 |
132 | @{item()?['Description']}
133 |
134 | @{item()?['TargetType']}
135 | ```
136 |
137 | Configure the severity level as a condition filter as you prefer:
138 |
139 | 
140 |
141 | Now configure the HTTP Connector for OpenAI Connection following this configuration:
142 |
143 | 
144 |
145 | At this point, be sure that the ComposeCSV block is correctly configured. When the "Run query and list result" block is recreated some link can be resetted. Follow the ComposeCSV attribute configuration following the example below (if the new UI model is not useful for the customization, evaluate to switch in "code view" mode):
146 |
147 | 
148 |
149 | NB. you can use the following variable below to valorize the items i greyed out:
150 |
151 | ```
152 | @{items('For_eachSQLResult')?['TargetName']}
153 |
154 | @{items('For_eachSQLResult')?['Severity']}
155 |
156 | @{items('For_eachSQLResult')?['Message']}
157 |
158 | @{items('For_each_AI_Response')?['message']?['content']}
159 |
160 | @{items('For_eachSQLResult')?['HelpLink']}
161 |
162 | ```
163 |
164 | The last configuration is change the broken module __Send an email (V2)__ with a new one, add the attachment and customize the file name :
165 |
166 | Before
167 | 
168 |
169 | After
170 | 
171 |
172 | Here all the configuration related the 2 attachments:
173 |
174 | ```json
175 | {
176 | "Name": "Sql-BPA-Result@{formatDateTime(convertTimeZone(utcNow(),'UTC','Romance Standard Time'), 'yyyy-MM-ddTHH.mm')}.html",
177 | "ContentBytes": "@{base64(variables('HTML-custom'))}"
178 | },
179 | {
180 | "Name": "Sql-BPA-Result@{formatDateTime(convertTimeZone(utcNow(),'UTC','Romance Standard Time'), 'yyyy-MM-ddTHH.mm')}.csv",
181 | "ContentBytes": "@{base64(body('Create_CSV_table'))}"
182 | }
183 | ```
184 |
185 | Now save your LogicApp and __Enable__ it.
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/ApiKey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/ApiKey.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/BingKey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/BingKey.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/BingSearch.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/BingSearch.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/BingSearch_Conf.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/BingSearch_Conf.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/BingSearch_Creation.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/BingSearch_Creation.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/HelpLinkParameter.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/HelpLinkParameter.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/HighThroughput.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/HighThroughput.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/SubRegistration.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/SubRegistration.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/composeCSV.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/composeCSV.jpeg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/deploy.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/deploy.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/enable.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/enable.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/final-questiontoAI.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/final-questiontoAI.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/http-connector.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/http-connector.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/identity.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/identity.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/query-value.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/query-value.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/recurrence.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/recurrence.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/run-query-list-result1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/run-query-list-result1.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/run-query-list-result2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/run-query-list-result2.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/run-query-list-result3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/run-query-list-result3.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/send-email1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/send-email1.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/send-email2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/send-email2.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/sendEmail-broken.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/sendEmail-broken.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/set-variable-redirect-url.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/set-variable-redirect-url.jpeg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/severity.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/severity.jpg
--------------------------------------------------------------------------------
/Arc-SQL BPA/images/value-question.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Arc-SQL BPA/images/value-question.jpg
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/CostMonthlyCheck/README.md:
--------------------------------------------------------------------------------
1 | Azure Cost Monthly Check OpenAI integration: Configuration
2 |
3 | | **Parameters** | **Information** | **Note** |
4 | | ------------- | ------------- | ------------- |
5 | | replacewithsubid | Connection setting during deployment | Replace with your Subscription ID |
6 | | repreplacewithRG | Connection setting during deployment | Replace with the selected RG Name for the deployment |
7 | | api-key | The API code for manage your OpenAI service | The parameter is inside the second "Initialize Variable". Put your question in the "value" attribute |
8 | | changeendpointname | Insert the OpenAI endpoint name | You can found the value inside the OpenAI resource inside Azure Cognitive Service |
9 | | changemodelname | Insert the model name | You can found the value inside the OpenAI resource inside Azure Cognitive Service |
10 |
11 | Important
12 | This LogApp and the following changes are an example of Cost Monitor check with OpenAI send via Email .
13 |
14 |
15 | Required Identity
16 | Managed Identity
17 |
18 | Now configure the HTTP request to the Graph Explorer enabling the authentication via System Assigned Managed Identity. Please remind that the Managed Identity need to have the righ permission on the subscription for read the resources:
19 |
20 |
21 | 
22 |
23 |
24 | Deployment and Result
25 |
26 | After deployment completed, please follow the documentation:
27 |
28 |
29 | As first step please configure the required recurrence:
30 |
31 | 
32 |
33 | Configure the Api Key with the value inside your OpenAI Service:
34 |
35 | 
36 |
37 | Modify the required subscription id in each the HTTP connector in order to obtain the required information:
38 |
39 | 
40 |
41 | At this point we need to configure the Ask to OpenAI module replacing the required parameters:
42 |
43 | 
44 |
45 | Last step is to add a notification section.
46 | In the example below we have a "Send Email V2" connector for send the final report to the required people or to a Teams channel . If you want to follow the same approach configure the module following the same example adding them at the end of the Logic App. Make sure to use the correct variable in the body of the email in order to have them correctly formatted:
47 |
48 | 
--------------------------------------------------------------------------------
/CostMonthlyCheck/images/ApiKey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/CostMonthlyCheck/images/ApiKey.jpg
--------------------------------------------------------------------------------
/CostMonthlyCheck/images/OpenAI.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/CostMonthlyCheck/images/OpenAI.jpg
--------------------------------------------------------------------------------
/CostMonthlyCheck/images/Recurrence.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/CostMonthlyCheck/images/Recurrence.jpg
--------------------------------------------------------------------------------
/CostMonthlyCheck/images/Sub-Id.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/CostMonthlyCheck/images/Sub-Id.jpeg
--------------------------------------------------------------------------------
/CostMonthlyCheck/images/example-notification.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/CostMonthlyCheck/images/example-notification.jpg
--------------------------------------------------------------------------------
/CostMonthlyCheck/images/identity.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/CostMonthlyCheck/images/identity.jpg
--------------------------------------------------------------------------------
/FunctionAppSmartDocs/README.md:
--------------------------------------------------------------------------------
1 | SmartDocs Azure Function
2 |
3 | Overview
4 | The SmartDocs Azure Function is designed to generate technical documentation and detailed reporting based on Azure resource metadata using Azure OpenAI. The function leverages managed authentication to access Azure services and consolidates resource metadata into an easily readable, automatically generated document.
5 |
6 |
7 | > [!NOTE]
8 | > SmartDocs is an artifact designed to be tailored to specific client needs. Depending on requirements, aspects such as the document storage path and authentication/configuration details may need to be customized.
9 |
10 |
11 | Requirements
12 |
13 | - Azure OpenAI-CoreIntegration Landing Zone deployed
14 | - A Default Consumption Function App will be deployed with the [foundation ARM Template](../OpenAI-CoreIntegrationLZ/README.md)
15 | - OpenAI in place, always deployed with the [foundation ARM Template](../OpenAI-CoreIntegrationLZ/README.md)
16 | - A local environment ready for deploy the Function App to azure. [Follow the instruction here](https://learn.microsoft.com/en-us/azure/azure-functions/create-first-function-vs-code-python).
17 |
18 |
19 | > [!IMPORTANT]
20 | > In the [Consumption Plan](https://learn.microsoft.com/en-us/azure/azure-functions/consumption-plan), the function has a maximum runtime of 10 minutes. For larger workloads, use an App Service Plan with a higher SKU, such as Premium or Dedicated, to increase the allowable execution time.
21 |
22 |
23 | - Managed Identity configured with read access to the required resources (subscriptions, OpenAI for generating text and so on).
24 |
25 | - QUESTION_ENDPOINT Environment Variable: The Azure OpenAI endpoint for sending requests.
26 |
27 | Example files for Function deployment
28 |
29 | - [host.json](host.json)
30 | - [local.settings.json](./local.settings.json)
31 | - [requirements.txt](./requirements.txt)
32 | - [function_app.py](./function_app.py)
33 |
34 | PowerShell Script for Invocation
35 | Here is a PowerShell script to invoke the function using an HTTP POST request:
36 |
37 |
38 |
39 | ```
40 | powershell
41 | Copia codice
42 | # Function app URL
43 | $functionUrl = "https://smartdocsopenai.azurewebsites.net/api/smartdocs"
44 |
45 | # Parameters to send
46 | $body = @{
47 | tag_key = "Workload"
48 | tag_value = "Production"
49 | }
50 |
51 | # Invoke the Function App
52 | $response = Invoke-RestMethod -Uri $functionUrl -Method Post -Body ($body | ConvertTo-Json) -ContentType "application/json"
53 |
54 | # Output the response
55 | $response
56 | ```
57 |
58 |
59 | 
60 |
61 | > [!NOTE]
62 | > When planning to use this function for high workloads configure a Premium App Service Plan or higher to avoid time limitations.
63 | Monitor execution logs for potential issues related to timeouts or resource limits.
64 | Future Customizations
65 |
66 |
67 | Support and Contributions
68 | Contributions and enhancement requests are welcome! For any additional customization, feel free to open an issue or submit a pull request in this repository.
69 |
70 |
--------------------------------------------------------------------------------
/FunctionAppSmartDocs/function_app.py:
--------------------------------------------------------------------------------
1 | import os
2 | import logging
3 | import docx
4 | import csv
5 | import requests
6 | import collections.abc
7 | import azure.functions as func
8 | from azure.identity import ManagedIdentityCredential
9 | from azure.mgmt.resource import ResourceManagementClient
10 | from azure.mgmt.subscription import SubscriptionClient
11 |
12 | # Configurazione logging avanzato
13 | logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
14 |
15 | # Endpoint OpenAI
16 | QUESTION_ENDPOINT = os.getenv("QUESTION_ENDPOINT")
17 | logging.info(f"Question endpoint set to: {QUESTION_ENDPOINT}")
18 |
19 | # Autenticazione tramite identità gestita della Function App
20 | credential = ManagedIdentityCredential()
21 | subscription_client = SubscriptionClient(credential)
22 | tokenai = credential.get_token("https://cognitiveservices.azure.com/.default")
23 |
24 |
25 | # Funzione per appiattire un dizionario annidato in una struttura piana
26 | def flatten_dict(d, parent_key='', sep='_'):
27 | #logging.info(f"start function flatten_dict")
28 | items = []
29 | for k, v in d.items():
30 | new_key = f"{parent_key}{sep}{k}" if parent_key else k
31 |
32 | if isinstance(v, collections.abc.MutableMapping):
33 | items.extend(flatten_dict(v, new_key, sep=sep).items())
34 | elif isinstance(v, list):
35 | for i, item in enumerate(v):
36 | if isinstance(item, collections.abc.MutableMapping):
37 | items.extend(flatten_dict(item, f"{new_key}{sep}{i}", sep=sep).items())
38 | else:
39 | items.append((f"{new_key}{sep}{i}", item))
40 | else:
41 | items.append((new_key, v))
42 | return dict(items)
43 |
44 | # Funzione per ottenere tutte le risorse con un determinato tag in una sottoscrizione
45 | def get_resources_by_tag_in_subscription(subscription_id, tag_key, tag_value):
46 | logging.info(f"start get_resources_by_tag_in_subscription")
47 | resource_client = ResourceManagementClient(credential, subscription_id)
48 | tag_filter = f"tagName eq '{tag_key}' and tagValue eq '{tag_value}'"
49 | logging.info(f"Cercando risorse con il tag: {tag_key}={tag_value} nella sottoscrizione {subscription_id}")
50 |
51 | resources = resource_client.resources.list(filter=tag_filter)
52 | resources_list = []
53 |
54 | for resource in resources:
55 | resource_details = {
56 | 'name': resource.name,
57 | 'id': resource.id,
58 | 'location': resource.location,
59 | 'type': resource.type,
60 | 'tags': resource.tags
61 | }
62 | resources_list.append(resource_details)
63 | logging.info(f"Trovata risorsa: {resource.name} - {resource.type}")
64 |
65 | logging.info(str(resources_list))
66 | return resources_list
67 |
68 | # Funzione per ottenere i Resource Groups con un determinato tag in una sottoscrizione
69 | def get_resource_groups_by_tag_in_subscription(subscription_id, tag_key, tag_value):
70 | logging.info(f"start get_resource_groups_by_tag_in_subscription")
71 | resource_client = ResourceManagementClient(credential, subscription_id)
72 | logging.info(f"Cercando resource groups con il tag: {tag_key}={tag_value} nella sottoscrizione {subscription_id}")
73 | resource_groups = resource_client.resource_groups.list()
74 | matching_resource_groups = []
75 |
76 | for rg in resource_groups:
77 | if rg.tags and tag_key in rg.tags and rg.tags[tag_key] == tag_value:
78 | logging.info(f"Trovato resource group: {rg.name}")
79 | matching_resource_groups.append(rg)
80 | logging.info(str(matching_resource_groups))
81 | return matching_resource_groups
82 |
83 | # Funzione per ottenere tutte le risorse con un determinato tag da tutte le sottoscrizioni
84 | def get_all_resources(tag_key, tag_value):
85 | logging.info(f"start get_all_resources")
86 | all_resources = []
87 | added_resource_ids = set()
88 |
89 | # Elenca tutte le sottoscrizioni a cui hai accesso
90 | for subscription in subscription_client.subscriptions.list():
91 | subscription_id = subscription.subscription_id
92 | logging.info(f"Processando la sottoscrizione: {subscription_id}")
93 |
94 | # Cerca le risorse con il tag specificato in questa sottoscrizione
95 | resources = get_resources_by_tag_in_subscription(subscription_id, tag_key, tag_value)
96 | for resource in resources:
97 | logging.info(f"Analizzando risorsa {resource}")
98 | if resource['id'] not in added_resource_ids:
99 | all_resources.append(resource)
100 | added_resource_ids.add(resource['id'])
101 |
102 | # Cerca i resource group con il tag specificato in questa sottoscrizione
103 | resource_groups = get_resource_groups_by_tag_in_subscription(subscription_id, tag_key, tag_value)
104 | for rg in resource_groups:
105 | logging.info(f"Analizzando {rg}")
106 | # Cerca risorse all'interno di ciascun resource group
107 | rg_resources = get_resources_in_resource_group_in_subscription(subscription_id, rg.name)
108 | for resource in rg_resources:
109 | if resource['id'] not in added_resource_ids:
110 | all_resources.append(resource)
111 | added_resource_ids.add(resource['id'])
112 | logging.info(str(all_resources))
113 | return all_resources
114 |
115 | # Funzione per ottenere le risorse all'interno di un Resource Group in una sottoscrizione
116 | def get_resources_in_resource_group_in_subscription(subscription_id, resource_group_name):
117 | logging.info(f"start get_resources_in_resource_group_in_subscription")
118 | resource_client = ResourceManagementClient(credential, subscription_id)
119 | logging.info(f"Recuperando risorse dal resource group: {resource_group_name} nella sottoscrizione {subscription_id}")
120 | resources = resource_client.resources.list_by_resource_group(resource_group_name)
121 | resources_list = []
122 |
123 | for resource in resources:
124 | resource_details = {
125 | 'name': resource.name,
126 | 'id': resource.id,
127 | 'location': resource.location,
128 | 'type': resource.type,
129 | 'tags': resource.tags
130 | }
131 | resources_list.append(resource_details)
132 | logging.info(f"Trovata risorsa nel resource group {resource_group_name}: {resource.name} - {resource.type}")
133 | logging.info(str(resources_list))
134 | return resources_list
135 |
136 | # Funzione per ottenere l'API più recente per una risorsa specifica
137 | def get_latest_api_version(resource_client, resource_type):
138 | logging.info(f"start get_latest_api_version")
139 | provider_namespace, resource_type_name = resource_type.split('/', 1)
140 | provider = resource_client.providers.get(provider_namespace)
141 | resource_type_info = next(
142 | (t for t in provider.resource_types if t.resource_type == resource_type_name), None
143 | )
144 | if resource_type_info:
145 | return sorted(resource_type_info.api_versions, reverse=True)[0]
146 | return None
147 |
148 | # Funzione per ottenere i metadati completi di una risorsa specifica
149 | def get_resource_metadata(resource_client, resource):
150 | logging.info(f"start get_resource_metadata")
151 | resource_type = resource['type']
152 | api_version = get_latest_api_version(resource_client, resource_type)
153 | if api_version:
154 | logging.info(f"Usando l'API version: {api_version} per la risorsa {resource['name']}")
155 | resource_metadata = resource_client.resources.get_by_id(resource['id'], api_version=api_version)
156 | return resource_metadata
157 | else:
158 | logging.info(f"Impossibile trovare l'API per la risorsa {resource['name']} con tipo {resource['type']}")
159 | return None
160 |
161 | # Funzione per generare la overview del workload leggendo il file CSV
162 | def generate_workload_overview():
163 | logging.info(f"start generate_workload_overview")
164 | resources_info = []
165 |
166 | with open("/tmp/resources_with_expanded_metadata.csv", 'r', encoding='utf-8') as csv_file:
167 | reader = csv.DictReader(csv_file)
168 | for row in reader:
169 | resources_info.append(row)
170 |
171 | resources_str = "\n".join([
172 | f"Name: {row['Name']}, Type: {row['Type']}, Location: {row['Location']}, Resource Group: {row['Resource ID'].split('/')[4]}"
173 | for row in resources_info])
174 |
175 | payload = {
176 | "messages": [
177 | {"role": "system",
178 | "content": "You are an expert Azure Architect and Documentation Writer. Your job is to create a clear and detailed overview of an Azure workload."},
179 | {"role": "user",
180 | "content": f"Here is the list of resources in the workload:\n{resources_str}.\nGenerate a detailed and human-readable overview. Explain at the end how the workload is splitted, so if is multi-regional or not and so on."}
181 | ],
182 | "temperature": 0.7,
183 | "max_tokens": 16000
184 | }
185 |
186 | response = requests.post(
187 | QUESTION_ENDPOINT,
188 | headers={'content-type': 'application/json', 'Authorization': 'Bearer ' + tokenai.token},
189 | json=payload
190 | )
191 |
192 | response.raise_for_status()
193 | response_from_copilot = response.json()['choices'][0]['message']['content'].strip()
194 | logging.info(str(response_from_copilot))
195 | return response_from_copilot
196 |
197 | # Funzione per generare la documentazione con OpenAI
198 | def generate_infra_config(metadata_list):
199 | logging.info("Inizio della generazione della configurazione dell'infrastruttura.")
200 | document_content = ""
201 |
202 | for index, metadata in enumerate(metadata_list):
203 | logging.debug(f"Elaborazione del metadato {index + 1}/{len(metadata_list)}: {metadata}")
204 | metadata_str = str(metadata)
205 |
206 | payload = {
207 | "messages": [
208 | {"role": "system", "content": "You are an expert Azure Architect and Documentation Writer."},
209 | {"role": "user", "content": f"Here is the metadata for an Azure resource: \n{metadata_str}.\nPlease generate a detailed and human-readable documentation."}
210 | ],
211 | "temperature": 0.7,
212 | "max_tokens": 16000
213 | }
214 |
215 | try:
216 | # Invio richiesta a OpenAI
217 | logging.debug("Invio della richiesta a OpenAI con payload.")
218 | response = requests.post(
219 | QUESTION_ENDPOINT,
220 | headers={'Content-Type': 'application/json', 'Authorization': f'Bearer {tokenai.token}'},
221 | json=payload
222 | )
223 |
224 | # Gestione della risposta
225 | response.raise_for_status()
226 | response_data = response.json()
227 | response_from_copilot = response_data['choices'][0]['message']['content'].strip()
228 | logging.info(f"Risposta da OpenAI per il metadato {index + 1}: {response_from_copilot}")
229 |
230 | except requests.exceptions.RequestException as e:
231 | logging.error(f"Errore nella richiesta a OpenAI per il metadato {index + 1}: {e}")
232 | continue # Salta al prossimo elemento se c'è un errore
233 |
234 | # Revisione del contenuto tramite ArchitecturalReviewer e DocCreator
235 | response_from_DocCreator = response_from_copilot
236 | previousdoc = response_from_DocCreator
237 | for i in range(3):
238 | try:
239 | ArchitecturalReviewer_response = ArchitecturalReviewer(response_from_DocCreator)
240 | logging.debug(f"Risposta ArchitecturalReviewer (ciclo {i + 1}): {ArchitecturalReviewer_response}")
241 | response_from_DocCreator, previousdoc = DocCreator(ArchitecturalReviewer_response, previousdoc)
242 | logging.debug(f"Documento revisionato (ciclo {i + 1}): {response_from_DocCreator}")
243 | except Exception as e:
244 | logging.error(f"Errore durante la revisione della documentazione (ciclo {i + 1}): {e}")
245 | break # Interrompe la revisione in caso di errore
246 |
247 | # Aggiunge la documentazione revisionata al contenuto finale
248 | document_content += response_from_DocCreator + "\n\n"
249 |
250 | # Scrittura del contenuto finale in un file
251 | try:
252 | logging.info("Scrittura del documento finale nel file architecture.txt.")
253 | with open("/tmp/architecture.txt", "a", encoding="utf-8") as architecturefile:
254 | architecturefile.write(document_content)
255 | logging.info("Documento architecture.txt generato con successo.")
256 | except IOError as e:
257 | logging.error(f"Errore durante la scrittura del file architecture.txt: {e}")
258 |
259 | return document_content
260 |
261 | logging.info(f"start generate_infra_config")
262 | document_content = ""
263 |
264 | for metadata in metadata_list:
265 | metadata_str = str(metadata)
266 |
267 | payload = {
268 | "messages": [
269 | {"role": "system",
270 | "content": "You are an expert Azure Architect and Documentation Writer."},
271 | {"role": "user",
272 | "content": f"Here is the metadata for an Azure resource: \n{metadata_str}.\nPlease generate a detailed and human-readable documentation."}
273 | ],
274 | "temperature": 0.7,
275 | "max_tokens": 16000
276 | }
277 |
278 | response = requests.post(
279 | QUESTION_ENDPOINT,
280 | headers={'content-type': 'application/json', 'Authorization': 'Bearer ' + tokenai.token},
281 | json=payload
282 | )
283 |
284 | response.raise_for_status()
285 | response_from_copilot = response.json()['choices'][0]['message']['content'].strip()
286 | logging.info(str(response_from_copilot))
287 |
288 | # Passa il contenuto attraverso 3 cicli di revisione con ArchitecturalReviewer e DocCreator
289 | response_from_DocCreator = response_from_copilot
290 | previousdoc = response_from_DocCreator
291 | for i in range(3):
292 | ArchitecturalReviewer_response = ArchitecturalReviewer(response_from_DocCreator)
293 | response_from_DocCreator, previousdoc = DocCreator(ArchitecturalReviewer_response, previousdoc)
294 |
295 | # Aggiunge la documentazione revisionata al contenuto finale
296 | document_content += response_from_DocCreator + "\n\n"
297 |
298 | with open("architecture.txt", "a", encoding="utf-8") as architecturefile:
299 | architecturefile.write(document_content)
300 |
301 | return document_content
302 |
303 | # Funzione per convertire il file txt in docx e aggiungere l'overview
304 | def txt_to_docx():
305 | logging.info(f"start txt_to_docx")
306 | logging.info("Generazione dei file in corso...")
307 |
308 | doc = docx.Document()
309 |
310 | # Genera l'overview del workload
311 | overview = generate_workload_overview()
312 |
313 | # Aggiungi "Workload Overview" come Titolo 1
314 | doc.add_heading("Workload Overview", level=1)
315 | doc.add_paragraph(overview)
316 |
317 | # Aggiungi un'interruzione di pagina per iniziare i dettagli su una nuova pagina
318 | doc.add_page_break()
319 |
320 | # Aggiungi "Workload Details" come Titolo 1
321 | doc.add_heading("Workload Details", level=1)
322 |
323 | # Aggiungi il contenuto del file architecture.txt
324 | with open("architecture.txt", 'r', encoding='utf-8', errors='ignore') as openfile:
325 | line = openfile.read()
326 | doc.add_paragraph(line)
327 |
328 | # Salva il documento Word
329 | doc.save("Output.docx")
330 | logging.info("Il file Output.docx è stato creato con successo.")
331 |
332 | def cleanup_files():
333 | logging.info(f"start cleanup_files")
334 | logging.info("Cleaning up temporary files")
335 | if os.path.exists("architecture.txt"):
336 | os.remove("architecture.txt")
337 | logging.debug("architecture.txt deleted")
338 | if os.path.exists("resources_with_expanded_metadata.csv"):
339 | os.remove("resources_with_expanded_metadata.csv")
340 | logging.debug("resources_with_expanded_metadata.csv")
341 | if os.path.exists("Output.docx"):
342 | os.remove("Output.docx")
343 | logging.debug("Output.docx deleted")
344 | if os.path.exists("/tmp/architecture.txt"):
345 | os.remove("/tmp/architecture.txt")
346 | logging.debug("architecture.txt deleted")
347 | if os.path.exists("/tmp/resources_with_expanded_metadata.csv"):
348 | os.remove("/tmp/resources_with_expanded_metadata.csv")
349 | logging.debug("resources_with_expanded_metadata.csv")
350 | if os.path.exists("/tmp/Output.docx"):
351 | os.remove("/tmp/Output.docx")
352 | logging.debug("Output.docx deleted")
353 | logging.info("Temporary files cleanup completed")
354 |
355 |
356 | def save_resources_with_expanded_metadata_to_csv(resources, metadata_list):
357 | logging.info("Start save_resources_with_expanded_metadata_to_csv")
358 |
359 | all_keys = set()
360 |
361 | # Raccogli tutte le chiavi disponibili nei metadati, incluse quelle dei dizionari annidati
362 | try:
363 | for metadata in metadata_list:
364 | flat_metadata = flatten_dict(metadata.__dict__) # Appiattiamo il dizionario dei metadati
365 | logging.debug(f"Flat metadata for item: {flat_metadata}")
366 | all_keys.update(flat_metadata.keys())
367 | except AttributeError as e:
368 | logging.error(f"Errore durante l'appiattimento dei metadati: {e}")
369 | return
370 | except Exception as e:
371 | logging.error(f"Errore sconosciuto durante la raccolta delle chiavi: {e}")
372 | return
373 |
374 | # Trasforma il set delle chiavi in una lista ordinata per mantenere ordine nelle colonne
375 | all_keys = list(all_keys)
376 | logging.info(f"All unique metadata keys: {all_keys}")
377 |
378 | # Scrivi le risorse e i loro metadati in un file CSV
379 | try:
380 | with open("/tmp/resources_with_expanded_metadata.csv", mode="w", newline='', encoding="utf-8") as csv_file:
381 | # Creiamo l'header del CSV con tutte le chiavi uniche
382 | fieldnames = ['Name', 'Resource ID', 'Location', 'Type', 'Tags'] + all_keys
383 | logging.debug(f"Fieldnames for CSV: {fieldnames}")
384 | writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
385 |
386 | # Scriviamo l'intestazione
387 | writer.writeheader()
388 | logging.info("CSV header written successfully.")
389 |
390 | # Scrivi i dettagli di ogni risorsa e i suoi metadati
391 | for resource, metadata in zip(resources, metadata_list):
392 | logging.debug(f"Processing resource: {resource['name']}")
393 |
394 | # Crea la riga iniziale per la risorsa
395 | resource_row = {
396 | 'Name': resource['name'],
397 | 'Resource ID': resource['id'],
398 | 'Location': resource['location'],
399 | 'Type': resource['type'],
400 | 'Tags': resource['tags']
401 | }
402 |
403 | # Appiattiamo i metadati annidati prima di scriverli nel CSV
404 | try:
405 | flat_metadata = flatten_dict(metadata.__dict__)
406 | logging.debug(f"Flat metadata for resource {resource['name']}: {flat_metadata}")
407 | except AttributeError as e:
408 | logging.error(f"Errore durante l'appiattimento dei metadati per la risorsa {resource['name']}: {e}")
409 | continue
410 | except Exception as e:
411 | logging.error(f"Errore sconosciuto durante l'appiattimento dei metadati per {resource['name']}: {e}")
412 | continue
413 |
414 | # Aggiungi i metadati alle colonne, gestendo eventuali valori mancanti
415 | for key in all_keys:
416 | resource_row[key] = flat_metadata.get(key, 'N/A') # Usa 'N/A' per valori mancanti
417 |
418 | # Scrivi la riga nel CSV
419 | writer.writerow(resource_row)
420 | logging.debug(f"Row written for resource {resource['name']}")
421 |
422 | except IOError as e:
423 | logging.error(f"Errore durante la creazione del file CSV: {e}")
424 | except Exception as e:
425 | logging.error(f"Errore sconosciuto durante la scrittura nel file CSV: {e}")
426 |
427 | logging.info("Il file resources_with_expanded_metadata.csv è stato creato con successo.")
428 |
429 | logging.info(f"start save_resources_with_expanded_metadata_to_csv")
430 | all_keys = set()
431 |
432 | # Raccogli tutte le chiavi disponibili nei metadati, incluse quelle dei dizionari annidati
433 | for metadata in metadata_list:
434 | flat_metadata = flatten_dict(metadata.__dict__) # Appiattiamo il dizionario dei metadati
435 | all_keys.update(flat_metadata.keys())
436 |
437 | # Trasforma il set delle chiavi in una lista ordinata per mantenere ordine nelle colonne
438 | all_keys = list(all_keys)
439 | logging.info(f"all_keys: {all_keys}")
440 |
441 | # Scrivi le risorse e i loro metadati in un file CSV
442 | with open("/tmp/resources_with_expanded_metadata.csv", mode="w", newline='', encoding="utf-8") as csv_file:
443 | # Creiamo l'header del CSV con tutte le chiavi uniche
444 | fieldnames = ['Name', 'Resource ID', 'Location', 'Type', 'Tags'] + all_keys
445 | writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
446 |
447 | # Scriviamo l'intestazione
448 | writer.writeheader()
449 |
450 | # Scrivi i dettagli di ogni risorsa e i suoi metadati
451 | for resource, metadata in zip(resources, metadata_list):
452 | resource_row = {
453 | 'Name': resource['name'],
454 | 'Resource ID': resource['id'],
455 | 'Location': resource['location'],
456 | 'Type': resource['type'],
457 | 'Tags': resource['tags']
458 | }
459 |
460 | # Appiattiamo i metadati annidati prima di scriverli nel CSV
461 | flat_metadata = flatten_dict(metadata.__dict__)
462 |
463 | # Aggiungi i metadati alle colonne, gestendo eventuali valori mancanti
464 | for key in all_keys:
465 | resource_row[key] = flat_metadata.get(key, 'N/A') # Usa 'N/A' per valori mancanti
466 |
467 | # Scrivi la riga nel CSV
468 | writer.writerow(resource_row)
469 |
470 | logging.info("Il file resources_with_expanded_metadata.csv è stato creato con successo.")
471 |
472 | def ArchitecturalReviewer(response_from_DocCreator):
473 | logging.info(f"start ArchitecturalReviewer")
474 | payload = {
475 | "messages": [
476 | {"role": "system",
477 | "content": "You are the Azure architectural reviewer of the enterprise. Our team is creating documentation on our Azure architecture for the existing dedicated workload. The team will pass a specific piece of documentation to you each time. Make suggestions on how to make it more user-friendly the part without suggesting to add graph, diagrams, table of contents, feedback and so on. Suggest how to write the doc in a user-friendly readable way."},
478 | {"role": "user",
479 | "content": f"{response_from_DocCreator}"}
480 | ],
481 | "temperature": 0.7,
482 | "max_tokens": 16000
483 | }
484 |
485 | response = requests.post(
486 | QUESTION_ENDPOINT,
487 | headers={'content-type': 'application/json', 'Authorization': 'Bearer ' + tokenai.token},
488 | json=payload
489 | )
490 |
491 | response.raise_for_status()
492 | ArchitecturalReviewer_response = response.json()['choices'][0]['message']['content'].strip()
493 | logging.info(f"Architectural Reviewer Comments: {ArchitecturalReviewer_response}")
494 |
495 | return ArchitecturalReviewer_response
496 |
497 | def DocCreator(ArchitecturalReviewer_response,previousdoc):
498 | logging.info(f"start DocCreator")
499 | payload = {
500 | "messages": [
501 | {"role": "system",
502 | "content": "You have created a document about your Azure infrastructure related a workload. Your supervisor is reviewing the documentation. Generate a new documentation output based on his suggestions as an output."},
503 | {"role": "user",
504 | "content": f"source:{previousdoc}. Suggestion: {ArchitecturalReviewer_response}"}
505 | ],
506 | "temperature": 0.7,
507 | "max_tokens": 16000
508 | }
509 |
510 | response = requests.post(
511 | QUESTION_ENDPOINT,
512 | headers={'content-type': 'application/json', 'Authorization': 'Bearer ' + tokenai.token},
513 | json=payload
514 | )
515 |
516 | response.raise_for_status()
517 | response_from_DocCreator = response.json()['choices'][0]['message']['content'].strip()
518 | logging.info(f"Doc Creator Repsonse: {response_from_DocCreator}")
519 |
520 | return response_from_DocCreator, response_from_DocCreator
521 |
522 | app = func.FunctionApp(http_auth_level=func.AuthLevel.ANONYMOUS)
523 |
524 | @app.route(route="smartdocs")
525 | def smartdocs(req: func.HttpRequest) -> func.HttpResponse:
526 | logging.info("Received request for smartdocs function")
527 |
528 | tag_key = req.params.get("tag_key")
529 | tag_value = req.params.get("tag_value")
530 | if not tag_key or not tag_value:
531 | try:
532 | req_body = req.get_json()
533 | tag_key = tag_key or req_body.get("tag_key")
534 | tag_value = tag_value or req_body.get("tag_value")
535 | except ValueError:
536 | logging.error("Invalid request body")
537 | return func.HttpResponse("Missing 'tag_key' or 'tag_value' parameters.", status_code=400)
538 |
539 | if not tag_key or not tag_value:
540 | logging.error("Missing required parameters: 'tag_key' and 'tag_value'")
541 | return func.HttpResponse("Missing 'tag_key' or 'tag_value' parameters.", status_code=400)
542 |
543 | all_resources = get_all_resources(tag_key, tag_value)
544 | metadata_list = []
545 | processed_resource_ids = set()
546 |
547 | for subscription in subscription_client.subscriptions.list():
548 | subscription_id = subscription.subscription_id
549 | resource_client = ResourceManagementClient(credential, subscription_id)
550 | for resource in all_resources:
551 | if resource['id'] not in processed_resource_ids:
552 | metadata = get_resource_metadata(resource_client, resource)
553 | if metadata:
554 | metadata_list.append(metadata)
555 | processed_resource_ids.add(resource['id'])
556 |
557 | save_resources_with_expanded_metadata_to_csv(all_resources, metadata_list)
558 | document_content = generate_infra_config(metadata_list)
559 |
560 | with open("architecture.txt", "w", encoding="utf-8") as output_file:
561 | output_file.write(document_content)
562 | logging.info("Architecture text file saved")
563 |
564 | txt_to_docx()
565 | cleanup_files()
566 |
567 | logging.info("Function smartdocs completed successfully")
568 | return func.HttpResponse("Resource data processed successfully.", status_code=200)
569 |
--------------------------------------------------------------------------------
/FunctionAppSmartDocs/host.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0",
3 | "logging": {
4 | "applicationInsights": {
5 | "samplingSettings": {
6 | "isEnabled": true,
7 | "excludedTypes": "Request"
8 | }
9 | }
10 | },
11 | "extensionBundle": {
12 | "id": "Microsoft.Azure.Functions.ExtensionBundle",
13 | "version": "[4.*, 5.0.0)"
14 | }
15 | }
--------------------------------------------------------------------------------
/FunctionAppSmartDocs/images/immagine.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/FunctionAppSmartDocs/images/immagine.png
--------------------------------------------------------------------------------
/FunctionAppSmartDocs/local.settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "IsEncrypted": false,
3 | "Values": {
4 | "AzureWebJobsStorage": "",
5 | "FUNCTIONS_WORKER_RUNTIME": "python",
6 | "QUESTION_ENDPOINT": "change-with-openai-endpoint",
7 | "APPINSIGHTS_INSTRUMENTATIONKEY": "e4e0ad95-1088-4cdc-b5a2-0309d643c1a8",
8 | "APPLICATIONINSIGHTS_CONNECTION_STRING": "InstrumentationKey=e4e0ad95-1088-4cdc-b5a2-0309d643c1a8;IngestionEndpoint=https://westeurope-5.in.applicationinsights.azure.com/;LiveEndpoint=https://westeurope.livediagnostics.monitor.azure.com/;ApplicationId=5376b542-d34a-4776-b408-f51da0db884f",
9 | "FUNCTIONS_EXTENSION_VERSION": "~4"
10 | }
11 | }
--------------------------------------------------------------------------------
/FunctionAppSmartDocs/requirements.txt:
--------------------------------------------------------------------------------
1 | # DO NOT include azure-functions-worker in this file
2 | # The Python Worker is managed by Azure Functions platform
3 | # Manually managing azure-functions-worker may cause unexpected issues
4 |
5 | azure-functions
6 | azure-identity
7 | azure-mgmt-resource
8 | azure-mgmt-subscription
9 | requests
10 | python-docx
11 |
--------------------------------------------------------------------------------
/GIT.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/GIT.jpg
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
22 |
--------------------------------------------------------------------------------
/Learning/README.md:
--------------------------------------------------------------------------------
1 | # Learning Repository
2 |
3 |
4 |
5 | This folder contains information and learning resources for various Azure and OpenAI technologies. The goal is to provide a comprehensive understanding of these tools, their applications, and how to use them effectively.
6 |
7 | ---
8 |
9 | ##Contents
10 |
11 |
12 | ### 1. OpenAI on Azure
13 | - **Overview**: OpenAI on Azure enables developers to integrate advanced AI models like GPT and Codex into their applications. These models can help with text generation, summarization, code completion, and more.
14 | - **Use Cases**:
15 | - **Customer Support**: Implement AI-powered chatbots to handle common customer queries.
16 | - **Content Generation**: Automate the creation of articles, social media posts, and reports.
17 | - **Coding Assistance**: Enhance developer productivity by integrating AI-based coding tools.
18 | - **Key Features**:
19 | - Access to pre-trained OpenAI models such as GPT-4.
20 | - Fine-tuning capabilities for custom model training.
21 | - Built-in Azure security and compliance.
22 | - **Resources**:
23 | - [Azure OpenAI Documentation](https://learn.microsoft.com/en-us/azure/ai-services/openai/)
24 | - [Getting Started with Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/chatgpt-quickstart?tabs=command-line%2Cjavascript-keyless%2Ctypescript-keyless%2Cpython-new&pivots=programming-language-python)
25 | ---
26 |
27 |
28 |
29 | ### 2. Azure Logic Apps
30 | - **Overview**: Azure Logic Apps simplifies the creation of automated workflows by connecting various services and applications. It is a low-code/no-code solution suitable for developers and non-developers alike.
31 | - **Use Cases**:
32 | - **Automated Data Processing**: Integrate cloud services to process and store data.
33 | - **Alerting Systems**: Build workflows that trigger alerts based on specific conditions.
34 | - **Integration**: Connect on-premises systems with cloud-based applications.
35 | - **Key Features**:
36 | - Hundreds of pre-built connectors for services like Microsoft 365, SQL Server, and Salesforce.
37 | - Built-in monitoring and diagnostics tools.
38 | - Support for complex workflows with conditional logic.
39 | - **Resources**:
40 | - [Azure Logic Apps Overview](https://learn.microsoft.com/en-us/azure/logic-apps/)
41 | - [Tutorial for Azure Logic Apps](https://learn.microsoft.com/en-us/azure/logic-apps/tutorial-build-schedule-recurring-logic-app-workflow)
42 | ---
43 |
44 |
45 |
46 | ### 3. Azure API Management (APIM)
47 | - **Overview**: Azure API Management provides a comprehensive solution for managing, securing, and monitoring APIs. It is designed to help organizations expose their services securely while ensuring scalability and high performance.
48 | - **Use Cases**:
49 | - **API Gateways**: Centralize API traffic with built-in caching and load balancing.
50 | - **Security**: Protect APIs with authentication, authorization, and rate-limiting features.
51 | - **Developer Portals**: Provide documentation and tools for developers to interact with your APIs.
52 | - **Key Features**:
53 | - Full lifecycle API management: design, deploy, and retire APIs.
54 | - Built-in support for OpenAPI Specification.
55 | - Analytics and insights into API usage.
56 | - **Resources**:
57 | - [Introduction to Azure API Management](https://learn.microsoft.com/en-us/azure/api-management/)
58 | - [How to Create APIs with Azure APIM](https://learn.microsoft.com/en-us/azure/api-management/import-and-publish)
59 | ---
60 |
61 |
62 |
63 | ### 4. Artificial Intelligence (AI) and Machine Learning (ML) on Azure
64 | - **Overview**: Azure provides robust tools and frameworks for incorporating artificial intelligence (AI) and machine learning (ML) into business solutions. It supports a wide range of AI use cases, from large-scale language models to advanced deep learning frameworks.
65 | - **Use Cases**:
66 | - **Generative AI**: Develop applications that create new content such as text, images, or code.
67 | - **Predictive Analytics**: Use ML models to forecast trends and improve decision-making.
68 | - **Intelligent Automation**: Integrate AI into workflows to enhance efficiency and reduce manual effort.
69 | - **Key Features**:
70 | - Support for popular ML frameworks like TensorFlow and PyTorch.
71 | - Comprehensive AI services, including Azure Cognitive Services and Azure Machine Learning.
72 | - Seamless integration with other Azure tools for deployment and monitoring.
73 | - **Resources**:
74 | - [AI and Machine Learning Architecture Overview](https://learn.microsoft.com/en-us/azure/architecture/ai-ml/)
75 | ---
76 |
77 |
78 |
79 | ### 5. Get started with Azure OpenAI Service (MS Learning) and Design Architectures
80 | - **Overview**: This module provides engineers with the skills to begin building an Azure OpenAI Service solution.
81 | - **Learning objectives**: By the end of this module, you'll be able to:
82 | - Create an Azure OpenAI Service resource and understand types of Azure OpenAI base models.
83 | - Use the Azure AI Studio, console, or REST API to deploy a base model and test it in the Studio's playgrounds.
84 | - Generate completions to prompts and begin to manage model parameters.
85 | - **Resources**:
86 | - [Azure OpenAI Service Modules](https://learn.microsoft.com/en-us/training/modules/get-started-openai/)
87 | - [Module assessment](https://learn.microsoft.com/it-it/training/modules/get-started-openai/1-introduction/)
88 |
--------------------------------------------------------------------------------
/Learning/images/AC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Learning/images/AC.png
--------------------------------------------------------------------------------
/Learning/images/Azure APIM.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Learning/images/Azure APIM.jpg
--------------------------------------------------------------------------------
/Learning/images/Azure Logic APp.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Learning/images/Azure Logic APp.jpg
--------------------------------------------------------------------------------
/Learning/images/AzureOpenAI.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Learning/images/AzureOpenAI.png
--------------------------------------------------------------------------------
/Learning/images/Learn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Learning/images/Learn.png
--------------------------------------------------------------------------------
/Learning/images/Microsoft Learn.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Learning/images/Microsoft Learn.jpg
--------------------------------------------------------------------------------
/Learning/images/model.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Learning/images/model.jpg
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/AIServicesForInfraELZ.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "openAIResourceGroup": {
6 | "type": "string",
7 | "defaultValue": "OpenAIRG",
8 | "metadata": {
9 | "description": "Resource group for the OpenAI resource."
10 | }
11 | },
12 | "LogicAppsRG": {
13 | "type": "string",
14 | "defaultValue": "LogicAppsforAI",
15 | "metadata": {
16 | "description": "Resource group for the SQL BPA Logic App."
17 | }
18 | },
19 | "openAILocation": {
20 | "type": "string",
21 | "defaultValue": "westeurope",
22 | "metadata": {
23 | "description": "Location for the OpenAI resource."
24 | }
25 | },
26 | "logicAppsLocation": {
27 | "type": "string",
28 | "defaultValue": "westeurope",
29 | "metadata": {
30 | "description": "Location for the Logic Apps resource."
31 | }
32 | },
33 | "openAIName": {
34 | "type": "string",
35 | "defaultValue": "AzureOpenAIResource2024",
36 | "metadata": {
37 | "description": "Name for the OpenAI resource. Must be globally unique."
38 | }
39 | },
40 | "workflows_SQL_BPA_ReadLink_Generalized_name": {
41 | "defaultValue": "OpenAI-SQL-BPA",
42 | "type": "string",
43 | "metadata": {
44 | "description": "Logic App Name for SQL-BPA."
45 | }
46 | },
47 | "workflows_OpenAICostMngmtMonthlyCheck_name": {
48 | "defaultValue": "OpenAI-Cost-Monthly-Check",
49 | "type": "string",
50 | "metadata": {
51 | "description": "Logic App Name for Cost-Monthly-Check."
52 | }
53 | },
54 | "workflows_OpenAIsmartupdate_name": {
55 | "defaultValue": "OpenAI-Update-Management",
56 | "type": "string",
57 | "metadata": {
58 | "description": "Logic App Name for Update-Management."
59 | }
60 | },
61 | "workflows_AnomaliesDetection_name": {
62 | "defaultValue": "OpenAI-AnomaliesDetection",
63 | "type": "string",
64 | "metadata": {
65 | "description": "Logic App Name for Anomalies Detection."
66 | }
67 | },
68 | "FunctionRG": {
69 | "defaultValue": "FunctionRGAI",
70 | "type": "string",
71 | "metadata": {
72 | "description": "RG used for the function App"
73 | }
74 | },
75 | "FunctionRGLocation": {
76 | "defaultValue": "westeurope",
77 | "type": "string",
78 | "metadata": {
79 | "description": "RG used for the function App"
80 | }
81 | },
82 | "FunctionName": {
83 | "defaultValue": "OpenAISmartDocsFA",
84 | "type": "string",
85 | "metadata": {
86 | "description": "Function Name to Create."
87 | }
88 | },
89 | "FunctionLocation": {
90 | "defaultValue": "westeurope",
91 | "type": "string",
92 | "metadata": {
93 | "description": "Function location."
94 | }
95 | },
96 | "StorageAccountNameFunction": {
97 | "defaultValue": "aisafunctionapp2024",
98 | "type": "string",
99 | "metadata": {
100 | "description": "Storage account name for the function app. The name must be unique."
101 | }
102 | }
103 | },
104 | "resources": [
105 | {
106 | "type": "Microsoft.Resources/resourceGroups",
107 | "apiVersion": "2022-09-01",
108 | "name": "[parameters('openAIResourceGroup')]",
109 | "location": "[parameters('openAILocation')]",
110 | "properties": {}
111 | },
112 | {
113 | "type": "Microsoft.Resources/deployments",
114 | "apiVersion": "2022-09-01",
115 | "name": "DeployOpenAI",
116 | "resourceGroup": "[parameters('openAIResourceGroup')]",
117 | "properties": {
118 | "mode": "Incremental",
119 | "templateLink": {
120 | "uri": "https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/refs/heads/main/OpenAI-CoreIntegrationLZ/templateOpenAI.json",
121 | "contentVersion": "1.0.0.0"
122 | },
123 | "parameters": {
124 | "name": {
125 | "value": "[parameters('openAIName')]"
126 | },
127 | "vnet": {
128 | "value": {}
129 | },
130 | "location": {
131 | "value": "[parameters('openAILocation')]"
132 | },
133 | "sku": {
134 | "value": "S0"
135 | },
136 | "virtualNetworkType": {
137 | "value": "None"
138 | },
139 | "resourceGroupName": {
140 | "value": "[parameters('openAIResourceGroup')]"
141 | },
142 | "resourceGroupId": {
143 | "value": "[subscriptionResourceId('Microsoft.Resources/resourceGroups', parameters('openAIResourceGroup'))]"
144 | },
145 | "ipRules": {
146 | "value": []
147 | },
148 | "privateEndpoints": {
149 | "value": []
150 | },
151 | "privateDnsZone": {
152 | "value": "privatelink.openai.azure.com"
153 | },
154 | "tagValues": {
155 | "value": {}
156 | }
157 | }
158 | },
159 | "dependsOn": [
160 | "[resourceId('Microsoft.Resources/resourceGroups', parameters('openAIResourceGroup'))]"
161 | ]
162 | },
163 | {
164 | "type": "Microsoft.Resources/resourceGroups",
165 | "apiVersion": "2022-09-01",
166 | "name": "[parameters('LogicAppsRG')]",
167 | "location": "[parameters('logicAppsLocation')]",
168 | "properties": {}
169 | },
170 | {
171 | "type": "Microsoft.Resources/deployments",
172 | "apiVersion": "2019-10-01",
173 | "name": "DeploySQLBPA",
174 | "resourceGroup": "[parameters('LogicAppsRG')]",
175 | "properties": {
176 | "mode": "Incremental",
177 | "templateLink": {
178 | "uri": "https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/refs/heads/main/OpenAI-CoreIntegrationLZ/SQLBPAV2.json",
179 | "contentVersion": "1.0.0.0"
180 | },
181 | "parameters": {
182 | "workflows_SQL_BPA_ReadLink_Generalized_name": {
183 | "value": "[parameters('workflows_SQL_BPA_ReadLink_Generalized_name')]"
184 | },
185 | "connections_azuremonitorlogs_externalid": {
186 | "value": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('LogicAppsRG'), '/providers/Microsoft.Web/connections/azuremonitorlogs')]"
187 | },
188 | "connections_office365_externalid": {
189 | "value": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', parameters('LogicAppsRG'), '/providers/Microsoft.Web/connections/office365')]"
190 | },
191 | "location": {
192 | "value": "[parameters('logicAppsLocation')]"
193 | }
194 | }
195 | },
196 | "dependsOn": [
197 | "[resourceId('Microsoft.Resources/resourceGroups', parameters('LogicAppsRG'))]"
198 | ]
199 | },
200 | {
201 | "type": "Microsoft.Resources/deployments",
202 | "apiVersion": "2019-10-01",
203 | "name": "DeployCostMonthlyCheck",
204 | "resourceGroup": "[parameters('LogicAppsRG')]",
205 | "properties": {
206 | "mode": "Incremental",
207 | "templateLink": {
208 | "uri": "https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/refs/heads/main/OpenAI-CoreIntegrationLZ/CostMonthlyCheck.json",
209 | "contentVersion": "1.0.0.0"
210 | },
211 | "parameters": {
212 | "workflows_OpenAICostMngmtMonthlyCheck_name": {
213 | "value": "[parameters('workflows_OpenAICostMngmtMonthlyCheck_name')]"
214 | },
215 | "location": {
216 | "value": "[parameters('logicAppsLocation')]"
217 | }
218 | }
219 | },
220 | "dependsOn": [
221 | "[resourceId('Microsoft.Resources/resourceGroups', parameters('LogicAppsRG'))]"
222 | ]
223 | },
224 | {
225 | "type": "Microsoft.Resources/deployments",
226 | "apiVersion": "2019-10-01",
227 | "name": "DeployUpdateManagement",
228 | "resourceGroup": "[parameters('LogicAppsRG')]",
229 | "properties": {
230 | "mode": "Incremental",
231 | "templateLink": {
232 | "uri": "https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/refs/heads/main/OpenAI-CoreIntegrationLZ/UpdateManagement.json",
233 | "contentVersion": "1.0.0.0"
234 | },
235 | "parameters": {
236 | "workflows_OpenAIsmartupdate_name": {
237 | "value": "[parameters('workflows_OpenAIsmartupdate_name')]"
238 | },
239 | "location": {
240 | "value": "[parameters('logicAppsLocation')]"
241 | }
242 | }
243 | },
244 | "dependsOn": [
245 | "[resourceId('Microsoft.Resources/resourceGroups', parameters('LogicAppsRG'))]"
246 | ]
247 | },
248 | {
249 | "type": "Microsoft.Resources/deployments",
250 | "apiVersion": "2019-10-01",
251 | "name": "DeployAnomaliesDetection",
252 | "resourceGroup": "[parameters('LogicAppsRG')]",
253 | "properties": {
254 | "mode": "Incremental",
255 | "templateLink": {
256 | "uri": "https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/refs/heads/main/OpenAI-CoreIntegrationLZ/AnomaliesDetection.json",
257 | "contentVersion": "1.0.0.0"
258 | },
259 | "parameters": {
260 | "workflows_OpenAIAnomalyDetectionAD_gen_name": {
261 | "value": "[parameters('workflows_AnomaliesDetection_name')]"
262 | },
263 | "location": {
264 | "value": "[parameters('logicAppsLocation')]"
265 | }
266 | }
267 | },
268 | "dependsOn": [
269 | "[resourceId('Microsoft.Resources/resourceGroups', parameters('LogicAppsRG'))]"
270 | ]
271 | },
272 | {
273 | "type": "Microsoft.Resources/resourceGroups",
274 | "apiVersion": "2022-09-01",
275 | "name": "[parameters('FunctionRG')]",
276 | "location": "[parameters('FunctionRGLocation')]",
277 | "properties": {}
278 | },
279 | {
280 | "type": "Microsoft.Resources/deployments",
281 | "apiVersion": "2019-10-01",
282 | "name": "DeployFunction",
283 | "resourceGroup": "[parameters('FunctionRG')]",
284 | "properties": {
285 | "mode": "Incremental",
286 | "templateLink": {
287 | "uri": "https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/refs/heads/main/OpenAI-CoreIntegrationLZ/CreateFunction.json",
288 | "contentVersion": "1.0.0.0"
289 | },
290 | "parameters": {
291 | "subscriptionId": {
292 | "value": "[subscription().subscriptionId]"
293 | },
294 | "name": {
295 | "value": "[parameters('FunctionName')]"
296 | },
297 | "location": {
298 | "value": "[parameters('FunctionLocation')]"
299 | },
300 | "ftpsState": {
301 | "value": "FtpsOnly"
302 | },
303 | "storageAccountName": {
304 | "value": "[parameters('StorageAccountNameFunction')]"
305 | },
306 | "sku": {
307 | "value": "Dynamic"
308 | },
309 | "skuCode": {
310 | "value": "Y1"
311 | },
312 | "workerSize": {
313 | "value": "0"
314 | },
315 | "workerSizeId": {
316 | "value": "0"
317 | },
318 | "numberOfWorkers": {
319 | "value": "1"
320 | },
321 | "use32BitWorkerProcess": {
322 | "value": false
323 | },
324 | "linuxFxVersion": {
325 | "value": "Python|3.11"
326 | },
327 | "hostingPlanName": {
328 | "value": "ASP-OpenAIFunctionApps-b7a4"
329 | },
330 | "serverFarmResourceGroup": {
331 | "value": "[parameters('FunctionRG')]"
332 | },
333 | "alwaysOn": {
334 | "value": false
335 | }
336 | }
337 | },
338 | "dependsOn": [
339 | "[resourceId('Microsoft.Resources/resourceGroups', parameters('FunctionRG'))]"
340 | ]
341 | }
342 | ],
343 | "outputs": {
344 | "openAIResourceGroup": {
345 | "type": "string",
346 | "value": "[parameters('openAIResourceGroup')]"
347 | },
348 | "FunctionRG": {
349 | "type": "string",
350 | "value": "[parameters('FunctionRG')]"
351 | },
352 | "openAILocation": {
353 | "type": "string",
354 | "value": "[parameters('openAILocation')]"
355 | },
356 | "sqlBPAResourceGroup": {
357 | "type": "string",
358 | "value": "[parameters('LogicAppsRG')]"
359 | }
360 | }
361 | }
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/AnomaliesDetection.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "workflows_OpenAIAnomalyDetectionAD_gen_name": {
6 | "defaultValue": "OpenAIAnomalyDetectionAD",
7 | "type": "String"
8 | },
9 | "connections_azuremonitorlogs_1_externalid": {
10 | "defaultValue": "[concat('/subscriptions/', subscription().subscriptionId, '/resourceGroups/', resourceGroup().name, '/providers/Microsoft.Web/connections/office365')]",
11 | "type": "String"
12 | },
13 | "location": {
14 | "defaultValue": "westeurope",
15 | "type": "String"
16 | }
17 | },
18 | "variables": {},
19 | "resources": [
20 | {
21 | "type": "Microsoft.Logic/workflows",
22 | "apiVersion": "2017-07-01",
23 | "name": "[parameters('workflows_OpenAIAnomalyDetectionAD_gen_name')]",
24 | "location": "[resourceGroup().location]",
25 | "identity": {
26 | "type": "SystemAssigned"
27 | },
28 | "properties": {
29 | "state": "Disabled",
30 | "definition": {
31 | "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
32 | "contentVersion": "1.0.0.0",
33 | "parameters": {
34 | "$connections": {
35 | "defaultValue": {},
36 | "type": "Object"
37 | }
38 | },
39 | "triggers": {
40 | "Recurrence": {
41 | "recurrence": {
42 | "frequency": "Day",
43 | "interval": 1,
44 | "timeZone": "W. Europe Standard Time",
45 | "schedule": {
46 | "hours": [
47 | "9"
48 | ]
49 | }
50 | },
51 | "evaluatedRecurrence": {
52 | "frequency": "Day",
53 | "interval": 1,
54 | "timeZone": "W. Europe Standard Time",
55 | "schedule": {
56 | "hours": [
57 | "9"
58 | ]
59 | }
60 | },
61 | "type": "Recurrence"
62 | }
63 | },
64 | "actions": {
65 | "Api-Key": {
66 | "runAfter": {
67 | "Run_query_and_list_results_V2_(Preview)": [
68 | "Succeeded"
69 | ]
70 | },
71 | "type": "InitializeVariable",
72 | "inputs": {
73 | "variables": [
74 | {
75 | "name": "Api-Key",
76 | "type": "string",
77 | "value": "replace with your OpenAI api key"
78 | }
79 | ]
80 | }
81 | },
82 | "Compose": {
83 | "runAfter": {
84 | "Clean_Result_III": [
85 | "Succeeded"
86 | ]
87 | },
88 | "type": "Compose",
89 | "inputs": "\n\n
Sistema automatico di segnalazione anomalie in ambiente AD- SiverzaLab Environment
\n
\nSalve, a seguito di un analisi all'interno dell'infrastruttura monitorata, è stato evidenziata la seguente anomalia:
\n-------------------------------------------------------------------------------------
\n\n@{variables('ReportIII')}\n
\n\n
\n\n(*) Il sistema genera i dati sfruttando l'OpenAI pertando protrebbero verificarsi delle anomalie nel testo inerenti alla formattazione.
\n
\n\n"
90 | },
91 | "For_each_result": {
92 | "foreach": "@body('Run_query_and_list_results_V2_(Preview)')?['value']",
93 | "actions": {
94 | "Update_variable_Question": {
95 | "type": "SetVariable",
96 | "inputs": {
97 | "name": "Question",
98 | "value": "E' stata identificata la seguente anomalia da un sistema di monitoraggio. Dai qualche info in più su quando è stato identificato il messaggio, che EventID è con informazioni relative all'errore e la risorsa di riferimento, nient'altro:TimeGenerated=\n@{item()?['TimeGenerated']};@{item()?['ActualUsage']};@{item()?['ExpectedUsage']};@{item()?['AnomalyScore']};EvendID=@{item()?['EventID']};DC=@{item()?['Computer']}\nSegui questo esempio e usa \";\" come separatore:\nIl giorno 24 novembre 2024 alle ore 15 è stata segnalata un'anomalia sul sistema @{item()?['Computer']} con eventID @{item()?['EventID']}; L'event ID indica problemi di autenticazione utente;Alcuni step per il troublescooting:;Verifica Event Viewer; Verifica accessi anomali all'infrastruttura; Controlla le performance dell'applicazione;\n\n "
99 | }
100 | },
101 | "Ask_to_OpenAI": {
102 | "runAfter": {
103 | "Update_variable_Question": [
104 | "Succeeded"
105 | ]
106 | },
107 | "type": "Http",
108 | "inputs": {
109 | "uri": "https://changeendpointname.openai.azure.com/openai/deployments/changemodelname/chat/completions?api-version=2024-02-15-preview",
110 | "method": "POST",
111 | "headers": {
112 | "Content-Type": "application/json",
113 | "api-key": "@variables('Api-Key')"
114 | },
115 | "body": {
116 | "max_tokens": 600,
117 | "temperature": 0.3,
118 | "messages": [
119 | {
120 | "content": "Sei un assistente che elenca le anomalie avvenute sui Domain Controllers di Microsoft Active Directory.",
121 | "role": "user"
122 | },
123 | {
124 | "content": "@{variables('Question')}",
125 | "role": "user"
126 | }
127 | ]
128 | }
129 | }
130 | },
131 | "Parse_OpenAI_response": {
132 | "runAfter": {
133 | "Ask_to_OpenAI": [
134 | "Succeeded"
135 | ]
136 | },
137 | "type": "ParseJson",
138 | "inputs": {
139 | "content": "@body('Ask_to_OpenAI')",
140 | "schema": {
141 | "properties": {
142 | "body": {
143 | "properties": {
144 | "choices": {
145 | "items": {
146 | "properties": {
147 | "content_filter_results": {
148 | "properties": {
149 | "hate": {
150 | "properties": {
151 | "filtered": {
152 | "type": "boolean"
153 | },
154 | "severity": {
155 | "type": "string"
156 | }
157 | },
158 | "type": "object"
159 | },
160 | "self_harm": {
161 | "properties": {
162 | "filtered": {
163 | "type": "boolean"
164 | },
165 | "severity": {
166 | "type": "string"
167 | }
168 | },
169 | "type": "object"
170 | },
171 | "sexual": {
172 | "properties": {
173 | "filtered": {
174 | "type": "boolean"
175 | },
176 | "severity": {
177 | "type": "string"
178 | }
179 | },
180 | "type": "object"
181 | },
182 | "violence": {
183 | "properties": {
184 | "filtered": {
185 | "type": "boolean"
186 | },
187 | "severity": {
188 | "type": "string"
189 | }
190 | },
191 | "type": "object"
192 | }
193 | },
194 | "type": "object"
195 | },
196 | "finish_reason": {
197 | "type": "string"
198 | },
199 | "index": {
200 | "type": "integer"
201 | },
202 | "message": {
203 | "properties": {
204 | "content": {
205 | "type": "string"
206 | },
207 | "role": {
208 | "type": "string"
209 | }
210 | },
211 | "type": "object"
212 | }
213 | },
214 | "required": [
215 | "index",
216 | "finish_reason",
217 | "message",
218 | "content_filter_results"
219 | ],
220 | "type": "object"
221 | },
222 | "type": "array"
223 | },
224 | "created": {
225 | "type": "integer"
226 | },
227 | "id": {
228 | "type": "string"
229 | },
230 | "model": {
231 | "type": "string"
232 | },
233 | "object": {
234 | "type": "string"
235 | },
236 | "prompt_filter_results": {
237 | "items": {
238 | "properties": {
239 | "content_filter_results": {
240 | "properties": {
241 | "hate": {
242 | "properties": {
243 | "filtered": {
244 | "type": "boolean"
245 | },
246 | "severity": {
247 | "type": "string"
248 | }
249 | },
250 | "type": "object"
251 | },
252 | "self_harm": {
253 | "properties": {
254 | "filtered": {
255 | "type": "boolean"
256 | },
257 | "severity": {
258 | "type": "string"
259 | }
260 | },
261 | "type": "object"
262 | },
263 | "sexual": {
264 | "properties": {
265 | "filtered": {
266 | "type": "boolean"
267 | },
268 | "severity": {
269 | "type": "string"
270 | }
271 | },
272 | "type": "object"
273 | },
274 | "violence": {
275 | "properties": {
276 | "filtered": {
277 | "type": "boolean"
278 | },
279 | "severity": {
280 | "type": "string"
281 | }
282 | },
283 | "type": "object"
284 | }
285 | },
286 | "type": "object"
287 | },
288 | "prompt_index": {
289 | "type": "integer"
290 | }
291 | },
292 | "required": [
293 | "prompt_index",
294 | "content_filter_results"
295 | ],
296 | "type": "object"
297 | },
298 | "type": "array"
299 | },
300 | "usage": {
301 | "properties": {
302 | "completion_tokens": {
303 | "type": "integer"
304 | },
305 | "prompt_tokens": {
306 | "type": "integer"
307 | },
308 | "total_tokens": {
309 | "type": "integer"
310 | }
311 | },
312 | "type": "object"
313 | }
314 | },
315 | "type": "object"
316 | }
317 | },
318 | "type": "object"
319 | }
320 | }
321 | },
322 | "For_each": {
323 | "foreach": "@outputs('Parse_OpenAI_response')?['body']?['choices']",
324 | "actions": {
325 | "Append_to_array_variable": {
326 | "type": "AppendToArrayVariable",
327 | "inputs": {
328 | "name": "Anomalies",
329 | "value": "@items('For_each')?['message']?['content']"
330 | }
331 | }
332 | },
333 | "runAfter": {
334 | "Parse_OpenAI_response": [
335 | "Succeeded"
336 | ]
337 | },
338 | "type": "Foreach"
339 | }
340 | },
341 | "runAfter": {
342 | "Set_Variable_Anomaly_Detection": [
343 | "Succeeded"
344 | ]
345 | },
346 | "type": "Foreach",
347 | "runtimeConfiguration": {
348 | "concurrency": {
349 | "repetitions": 1
350 | }
351 | }
352 | },
353 | "Run_query_and_list_results_V2_(Preview)": {
354 | "runAfter": {},
355 | "type": "ApiConnection",
356 | "inputs": {
357 | "host": {
358 | "connection": {
359 | "name": "@parameters('$connections')['azuremonitorlogs-1']['connectionId']"
360 | }
361 | },
362 | "method": "post",
363 | "body": {
364 | "query": "let starttime = 7d; \nlet endtime = 0d;\nlet timeframe = 60m;\nEvent \n| where TimeGenerated between (startofday(ago(starttime)) .. startofday(ago(endtime))) \n| where Computer startswith \"DC\"\n| where RenderedDescription contains \"error\" \n| summarize count() by bin(TimeGenerated, 60s), Computer, EventID \n| make-series ActualUsage=avg(count_) default = 0 on TimeGenerated from startofday(ago(starttime)) \tto startofday(ago(endtime)) step timeframe by Computer, EventID \n| extend(Anomalies, AnomalyScore, ExpectedUsage) = series_decompose_anomalies(ActualUsage) \n| mv-expand\n ActualUsage to typeof(double),\n TimeGenerated to typeof(datetime),\n Anomalies to typeof(double),\n AnomalyScore to typeof(double),\n ExpectedUsage to typeof(long)\n| where abs(AnomalyScore) > 7 and abs(ActualUsage - ExpectedUsage) / ActualUsage > 0.5 \n| project TimeGenerated, ActualUsage, ExpectedUsage, abs(AnomalyScore), EventID, Computer\n| sort by abs(AnomalyScore) desc",
365 | "timerangetype": "3"
366 | },
367 | "path": "/queryDataV2",
368 | "queries": {
369 | "subscriptions": "replacewithsubid",
370 | "resourcegroups": "replacewithR",
371 | "resourcetype": "Log Analytics Workspace",
372 | "resourcename": "replacewithRN"
373 | }
374 | }
375 | },
376 | "Set_Variable_Question": {
377 | "runAfter": {
378 | "Api-Key": [
379 | "Succeeded"
380 | ]
381 | },
382 | "type": "InitializeVariable",
383 | "inputs": {
384 | "variables": [
385 | {
386 | "name": "Question",
387 | "type": "string"
388 | }
389 | ]
390 | }
391 | },
392 | "Set_Variable_Anomaly_Detection": {
393 | "runAfter": {
394 | "Set_Variable_Question": [
395 | "Succeeded"
396 | ]
397 | },
398 | "type": "InitializeVariable",
399 | "inputs": {
400 | "variables": [
401 | {
402 | "name": "Anomalies",
403 | "type": "array"
404 | }
405 | ]
406 | }
407 | },
408 | "Clean_Result_I": {
409 | "runAfter": {
410 | "For_each_result": [
411 | "Succeeded"
412 | ]
413 | },
414 | "type": "InitializeVariable",
415 | "inputs": {
416 | "variables": [
417 | {
418 | "name": "Report",
419 | "type": "string",
420 | "value": "@replace(string(variables('Anomalies')), '[\"','
')"
421 | }
422 | ]
423 | }
424 | },
425 | "Clean_Result_II": {
426 | "runAfter": {
427 | "Clean_Result_I": [
428 | "Succeeded"
429 | ]
430 | },
431 | "type": "InitializeVariable",
432 | "inputs": {
433 | "variables": [
434 | {
435 | "name": "ReportII",
436 | "type": "string",
437 | "value": "@replace(variables('Report'), '\",\"','
')"
438 | }
439 | ]
440 | }
441 | },
442 | "Clean_Result_III": {
443 | "runAfter": {
444 | "Clean_Result_II": [
445 | "Succeeded"
446 | ]
447 | },
448 | "type": "InitializeVariable",
449 | "inputs": {
450 | "variables": [
451 | {
452 | "name": "ReportIII",
453 | "type": "string",
454 | "value": "@replace(variables('ReportII'), '\"]','
')"
455 | }
456 | ]
457 | }
458 | }
459 | },
460 | "outputs": {}
461 | },
462 | "parameters": {
463 | "$connections": {
464 | "value": {
465 |
466 | }
467 | }
468 | }
469 | }
470 | }
471 | ]
472 | }
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/CreateFunction.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "subscriptionId": {
6 | "type": "string"
7 | },
8 | "name": {
9 | "type": "string"
10 | },
11 | "location": {
12 | "type": "string"
13 | },
14 | "use32BitWorkerProcess": {
15 | "type": "bool"
16 | },
17 | "ftpsState": {
18 | "type": "string"
19 | },
20 | "storageAccountName": {
21 | "type": "string"
22 | },
23 | "linuxFxVersion": {
24 | "type": "string"
25 | },
26 | "sku": {
27 | "type": "string"
28 | },
29 | "skuCode": {
30 | "type": "string"
31 | },
32 | "workerSize": {
33 | "type": "string"
34 | },
35 | "workerSizeId": {
36 | "type": "string"
37 | },
38 | "numberOfWorkers": {
39 | "type": "string"
40 | },
41 | "hostingPlanName": {
42 | "type": "string"
43 | },
44 | "serverFarmResourceGroup": {
45 | "type": "string"
46 | },
47 | "alwaysOn": {
48 | "type": "bool"
49 | }
50 | },
51 | "variables": {
52 | "contentShare": "openaidocscreator855a"
53 | },
54 | "resources": [
55 | {
56 | "apiVersion": "2022-03-01",
57 | "name": "[parameters('name')]",
58 | "type": "Microsoft.Web/sites",
59 | "kind": "functionapp,linux",
60 | "location": "[parameters('location')]",
61 | "tags": {},
62 | "dependsOn": [
63 | "[concat('Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]",
64 | "[concat('Microsoft.Storage/storageAccounts/', parameters('storageAccountName'))]"
65 | ],
66 | "properties": {
67 | "name": "[parameters('name')]",
68 | "siteConfig": {
69 | "appSettings": [
70 | {
71 | "name": "FUNCTIONS_EXTENSION_VERSION",
72 | "value": "~4"
73 | },
74 | {
75 | "name": "FUNCTIONS_WORKER_RUNTIME",
76 | "value": "python"
77 | },
78 | {
79 | "name": "AzureWebJobsStorage",
80 | "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
81 | },
82 | {
83 | "name": "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING",
84 | "value": "[concat('DefaultEndpointsProtocol=https;AccountName=',parameters('storageAccountName'),';AccountKey=',listKeys(resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName')), '2019-06-01').keys[0].value,';EndpointSuffix=','core.windows.net')]"
85 | },
86 | {
87 | "name": "WEBSITE_CONTENTSHARE",
88 | "value": "[variables('contentShare')]"
89 | }
90 | ],
91 | "cors": {
92 | "allowedOrigins": [
93 | "https://portal.azure.com"
94 | ]
95 | },
96 | "use32BitWorkerProcess": "[parameters('use32BitWorkerProcess')]",
97 | "ftpsState": "[parameters('ftpsState')]",
98 | "linuxFxVersion": "[parameters('linuxFxVersion')]"
99 | },
100 | "clientAffinityEnabled": false,
101 | "virtualNetworkSubnetId": null,
102 | "publicNetworkAccess": "Enabled",
103 | "httpsOnly": true,
104 | "serverFarmId": "[concat('/subscriptions/', parameters('subscriptionId'),'/resourcegroups/', parameters('serverFarmResourceGroup'), '/providers/Microsoft.Web/serverfarms/', parameters('hostingPlanName'))]"
105 | },
106 | "resources": [
107 | {
108 | "type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
109 | "apiVersion": "2022-09-01",
110 | "name": "[concat(parameters('name'), '/scm')]",
111 | "properties": {
112 | "allow": false
113 | },
114 | "dependsOn": [
115 | "[resourceId('Microsoft.Web/Sites', parameters('name'))]"
116 | ]
117 | },
118 | {
119 | "type": "Microsoft.Web/sites/basicPublishingCredentialsPolicies",
120 | "apiVersion": "2022-09-01",
121 | "name": "[concat(parameters('name'), '/ftp')]",
122 | "properties": {
123 | "allow": false
124 | },
125 | "dependsOn": [
126 | "[resourceId('Microsoft.Web/Sites', parameters('name'))]"
127 | ]
128 | }
129 | ]
130 | },
131 | {
132 | "apiVersion": "2018-11-01",
133 | "name": "[parameters('hostingPlanName')]",
134 | "type": "Microsoft.Web/serverfarms",
135 | "location": "[parameters('location')]",
136 | "kind": "linux",
137 | "tags": {},
138 | "dependsOn": [],
139 | "properties": {
140 | "name": "[parameters('hostingPlanName')]",
141 | "workerSize": "[parameters('workerSize')]",
142 | "workerSizeId": "[parameters('workerSizeId')]",
143 | "numberOfWorkers": "[parameters('numberOfWorkers')]",
144 | "reserved": true
145 | },
146 | "sku": {
147 | "Tier": "[parameters('sku')]",
148 | "Name": "[parameters('skuCode')]"
149 | }
150 | },
151 | {
152 | "apiVersion": "2022-05-01",
153 | "type": "Microsoft.Storage/storageAccounts",
154 | "name": "[parameters('storageAccountName')]",
155 | "dependsOn": [],
156 | "location": "[parameters('location')]",
157 | "tags": {},
158 | "sku": {
159 | "name": "Standard_LRS"
160 | },
161 | "properties": {
162 | "supportsHttpsTrafficOnly": true,
163 | "minimumTlsVersion": "TLS1_2",
164 | "defaultToOAuthAuthentication": true
165 | }
166 | }
167 | ]
168 | }
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/README.md:
--------------------------------------------------------------------------------
1 | AI for Operation Framework LZ
2 |
3 | | **Parameters/Requirements** | **Information** | **Note** |
4 | | ------------- | ------------- | ------------- |
5 | | Region | The Default Region used for the deployment | Select the Region |
6 | | Open AI Resource Group | Create the Resource Group for OpenAI resource | Replace with RG Name |
7 | | Logic Apps Resource Group | Create the Resource Group for Logic Apps resource | Replace with RG Name |
8 | | Open AI Location | Insert the Location for the deployment of Azure OpenAI | Replace with the location |
9 | | Logic Apps Location | Insert the Location for the Logic Apps Deployment | Replace with the location |
10 | | Open AI Name | Insert the name for the Open AI Deployed resource | Replace with the name. Must be Globally unique |
11 | | LogicApp_SQL_BPA_AI_name | Insert the name for the SQL BPA Logic App Deployed | Replace with the required name |
12 | | LogicApp_Open AI Cost Monthly Check_name | Insert the name for the Cost Mgmt Logic App Deployed | Replace with the required name |
13 | | LogicApp_Open AI SmartUpdate | Insert the name for the SmartUpdate Logic App Deployed | Replace with the required name |
14 | | LogicApp_Open AI AnomaliesDetection | Insert the name for the AnomaliesDetection Logic App Deployed | Replace with the required name |
15 | | Function RG | Insert the name for the Function App Resource Group | Replace with the required name |
16 | | Function RG Location | Insert the location for the RG where the Function will be placed | Replace with the location |
17 | | Function Name | Insert the name Function App Deployed | Replace with the required name. Must be Globally unique |
18 | | Function Location | Insert the location for the Function App Deployed | Replace with the location |
19 | | Storage Account Name Function | Insert the name for the Storage Account | The Storage Account is a mandatory resource for the Function App. Name Must be Globally unique |
20 |
21 | Important
22 | The following deployment require a dedicated Subscription already in-place. This subscription, following the Enterprise Scale Diagram, must be placed in a identified Management Group
23 |
24 | Reference:
25 | [Azure Enterprise Scale Reference](https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/#azure-landing-zone-architecture)
26 |
27 | Architectural Overview
28 |
29 | 
30 |
31 | Deploy
32 |
33 | Configuration
34 |
35 |
36 |
37 |
38 |
39 |
40 | When you deploy, replace all the parameters with the required information
41 |
42 | 
43 |
44 | If the information provided are correct, the deployment will proceed
45 |
46 | 
47 |
48 | Post Deployment
49 |
50 | When the deployment is completed, to view all the resources go to Azure Portal > Subscription > Select the subscription used during the deployment > Resources
51 |
52 | or click on the "Go to subscription" button:
53 |
54 | 
55 |
56 | Solution Configuration
57 |
58 | Each solution created in the initiative have a dedicated configuration flow:
59 |
60 | - [SQL BPA Enhanced Assessment Logic App](../Arc-SQL%20BPA/README.md)
61 | - [Cost Monthly Check Logic App](../CostMonthlyCheck/README.md)
62 | - [Update Management Logic App](../UpdateManagement/README.md)
63 | - [Anomalies Detection Logic App](../AnomaliesDetection/README.md)
64 | - [Function App](../FunctionAppSmartDocs/README.md): An empty box ready to be used for deploy custom Script\Application integrated with OpenAI. (Some example will be provided during the engagement. An App Developer skilled on Azure Function Customization and Deployment is needed).
65 |
66 | Please reach your CSA for be followed during the configuration.
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/images/OpenAI-CoreIntegration_page-0001.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/OpenAI-CoreIntegrationLZ/images/OpenAI-CoreIntegration_page-0001.jpg
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/images/deploy.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/OpenAI-CoreIntegrationLZ/images/deploy.jpeg
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/images/deployment_complete.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/OpenAI-CoreIntegrationLZ/images/deployment_complete.jpeg
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/images/start_deployment.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/OpenAI-CoreIntegrationLZ/images/start_deployment.jpeg
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/templateBingSearch.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "name": {
6 | "type": "string"
7 | },
8 | "location": {
9 | "type": "string"
10 | },
11 | "sku": {
12 | "type": "string"
13 | },
14 | "tagValues": {
15 | "type": "object"
16 | }
17 | },
18 | "resources": [
19 | {
20 | "apiVersion": "2020-06-10",
21 | "name": "[parameters('name')]",
22 | "location": "[parameters('location')]",
23 | "type": "Microsoft.Bing/accounts",
24 | "kind": "Bing.Search.v7",
25 | "tags": "[if(contains(parameters('tagValues'), 'Microsoft.Bing/accounts'), parameters('tagValues')['Microsoft.Bing/accounts'], json('{}'))]",
26 | "sku": {
27 | "name": "[parameters('sku')]"
28 | }
29 | }
30 | ]
31 | }
--------------------------------------------------------------------------------
/OpenAI-CoreIntegrationLZ/templateOpenAI.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "name": {
6 | "type": "string"
7 | },
8 | "location": {
9 | "type": "string"
10 | },
11 | "sku": {
12 | "type": "string"
13 | },
14 | "tagValues": {
15 | "type": "object"
16 | },
17 | "virtualNetworkType": {
18 | "type": "string"
19 | },
20 | "vnet": {
21 | "type": "object"
22 | },
23 | "ipRules": {
24 | "type": "array"
25 | },
26 | "privateEndpoints": {
27 | "type": "array"
28 | },
29 | "privateDnsZone": {
30 | "type": "string"
31 | },
32 | "resourceGroupName": {
33 | "type": "string"
34 | },
35 | "resourceGroupId": {
36 | "type": "string"
37 | },
38 | "uniqueId": {
39 | "type": "string",
40 | "defaultValue": "[newGuid()]"
41 | }
42 | },
43 | "resources": [
44 | {
45 | "type": "Microsoft.Resources/deployments",
46 | "apiVersion": "2017-05-10",
47 | "name": "deployVnet",
48 | "properties": {
49 | "mode": "Incremental",
50 | "template": {
51 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
52 | "contentVersion": "1.0.0.0",
53 | "parameters": {},
54 | "variables": {},
55 | "resources": [
56 | {
57 | "type": "Microsoft.Network/virtualNetworks",
58 | "apiVersion": "2020-04-01",
59 | "name": "[if(equals(parameters('virtualNetworkType'), 'External'), parameters('vnet').name, variables('defaultVNetName'))]",
60 | "location": "[parameters('location')]",
61 | "properties": {
62 | "addressSpace": {
63 | "addressPrefixes": "[if(equals(parameters('virtualNetworkType'), 'External'), parameters('vnet').addressPrefixes, json(concat('[{\"', variables('defaultAddressPrefix'),'\"}]')))]"
64 | },
65 | "subnets": [
66 | {
67 | "name": "[if(equals(parameters('virtualNetworkType'), 'External'), parameters('vnet').subnets.subnet.name, variables('defaultSubnetName'))]",
68 | "properties": {
69 | "serviceEndpoints": [
70 | {
71 | "service": "Microsoft.CognitiveServices",
72 | "locations": [
73 | "[parameters('location')]"
74 | ]
75 | }
76 | ],
77 | "addressPrefix": "[if(equals(parameters('virtualNetworkType'), 'External'), parameters('vnet').subnets.subnet.addressPrefix, variables('defaultAddressPrefix'))]"
78 | }
79 | }
80 | ]
81 | }
82 | }
83 | ]
84 | },
85 | "parameters": {}
86 | },
87 | "condition": "[and(and(not(empty(parameters('vnet'))), equals(parameters('vnet').newOrExisting, 'new')), equals(parameters('virtualNetworkType'), 'External'))]"
88 | },
89 | {
90 | "apiVersion": "2022-03-01",
91 | "name": "[parameters('name')]",
92 | "location": "[parameters('location')]",
93 | "type": "Microsoft.CognitiveServices/accounts",
94 | "kind": "OpenAI",
95 | "tags": "[if(contains(parameters('tagValues'), 'Microsoft.CognitiveServices/accounts'), parameters('tagValues')['Microsoft.CognitiveServices/accounts'], json('{}'))]",
96 | "sku": {
97 | "name": "[parameters('sku')]"
98 | },
99 | "properties": {
100 | "customSubDomainName": "[toLower(parameters('name'))]",
101 | "publicNetworkAccess": "[if(equals(parameters('virtualNetworkType'), 'Internal'), 'Disabled', 'Enabled')]",
102 | "networkAcls": {
103 | "defaultAction": "[if(equals(parameters('virtualNetworkType'), 'External'), 'Deny', 'Allow')]",
104 | "virtualNetworkRules": "[if(equals(parameters('virtualNetworkType'), 'External'), json(concat('[{\"id\": \"', concat(subscription().id, '/resourceGroups/', parameters('vnet').resourceGroup, '/providers/Microsoft.Network/virtualNetworks/', parameters('vnet').name, '/subnets/', parameters('vnet').subnets.subnet.name), '\"}]')), json('[]'))]",
105 | "ipRules": "[if(or(empty(parameters('ipRules')), empty(parameters('ipRules')[0].value)), json('[]'), parameters('ipRules'))]"
106 | }
107 | },
108 | "dependsOn": [
109 | "[concat('Microsoft.Resources/deployments/', 'deployVnet')]"
110 | ]
111 | },
112 | {
113 | "apiVersion": "2018-05-01",
114 | "name": "[concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]",
115 | "type": "Microsoft.Resources/deployments",
116 | "resourceGroup": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name]",
117 | "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]",
118 | "dependsOn": [
119 | "[concat('Microsoft.CognitiveServices/accounts/', parameters('name'))]"
120 | ],
121 | "condition": "[equals(parameters('virtualNetworkType'), 'Internal')]",
122 | "copy": {
123 | "name": "privateendpointscopy",
124 | "count": "[length(parameters('privateEndpoints'))]"
125 | },
126 | "properties": {
127 | "mode": "Incremental",
128 | "template": {
129 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
130 | "contentVersion": "1.0.0.0",
131 | "resources": [
132 | {
133 | "location": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.location]",
134 | "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name]",
135 | "type": "Microsoft.Network/privateEndpoints",
136 | "apiVersion": "2021-05-01",
137 | "properties": {
138 | "subnet": {
139 | "id": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.subnet.id]"
140 | },
141 | "privateLinkServiceConnections": [
142 | {
143 | "name": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name]",
144 | "properties": {
145 | "privateLinkServiceId": "[concat(parameters('resourceGroupId'), '/providers/Microsoft.CognitiveServices/accounts/', parameters('name'))]",
146 | "groupIds": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.privateLinkServiceConnections[0].properties.groupIds]"
147 | }
148 | }
149 | ],
150 | "customNetworkInterfaceName": "[concat(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name, '-nic')]"
151 | },
152 | "tags": {}
153 | }
154 | ]
155 | }
156 | }
157 | },
158 | {
159 | "apiVersion": "2018-05-01",
160 | "name": "[concat('deployDnsZoneGroup-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]",
161 | "type": "Microsoft.Resources/deployments",
162 | "resourceGroup": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name]",
163 | "subscriptionId": "[parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId]",
164 | "dependsOn": [
165 | "[concat('deployPrivateEndpoint-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]"
166 | ],
167 | "condition": "[and(equals(parameters('virtualNetworkType'), 'Internal'), parameters('privateEndpoints')[copyIndex()].privateDnsZoneConfiguration.integrateWithPrivateDnsZone)]",
168 | "copy": {
169 | "name": "privateendpointdnscopy",
170 | "count": "[length(parameters('privateEndpoints'))]"
171 | },
172 | "properties": {
173 | "mode": "Incremental",
174 | "template": {
175 | "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
176 | "contentVersion": "1.0.0.0",
177 | "resources": [
178 | {
179 | "type": "Microsoft.Network/privateDnsZones",
180 | "apiVersion": "2018-09-01",
181 | "name": "[parameters('privateDnsZone')]",
182 | "location": "global",
183 | "tags": {},
184 | "properties": {}
185 | },
186 | {
187 | "type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
188 | "apiVersion": "2018-09-01",
189 | "name": "[concat(parameters('privateDnsZone'), '/', replace(uniqueString(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.subnet.id), '/subnets/default', ''))]",
190 | "location": "global",
191 | "dependsOn": [
192 | "[parameters('privateDnsZone')]"
193 | ],
194 | "properties": {
195 | "virtualNetwork": {
196 | "id": "[split(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.properties.subnet.id, '/subnets/')[0]]"
197 | },
198 | "registrationEnabled": false
199 | }
200 | },
201 | {
202 | "apiVersion": "2017-05-10",
203 | "name": "[concat('EndpointDnsRecords-', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name)]",
204 | "type": "Microsoft.Resources/deployments",
205 | "dependsOn": [
206 | "[parameters('privateDnsZone')]"
207 | ],
208 | "properties": {
209 | "mode": "Incremental",
210 | "templatelink": {
211 | "uri": "https://go.microsoft.com/fwlink/?linkid=2264916"
212 | },
213 | "parameters": {
214 | "privateDnsName": {
215 | "value": "[parameters('privateDnsZone')]"
216 | },
217 | "privateEndpointNicResourceId": {
218 | "value": "[concat('/subscriptions/', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.subscription.subscriptionId, '/resourceGroups/', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.resourceGroup.value.name, '/providers/Microsoft.Network/networkInterfaces/', parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name, '-nic')]"
219 | },
220 | "nicRecordsTemplateUri": {
221 | "value": "https://go.microsoft.com/fwlink/?linkid=2264719"
222 | },
223 | "ipConfigRecordsTemplateUri": {
224 | "value": "https://go.microsoft.com/fwlink/?linkid=2265018"
225 | },
226 | "uniqueId": {
227 | "value": "[parameters('uniqueId')]"
228 | },
229 | "existingRecords": {
230 | "value": {}
231 | }
232 | }
233 | }
234 | },
235 | {
236 | "type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
237 | "apiVersion": "2020-03-01",
238 | "name": "[concat(parameters('privateEndpoints')[copyIndex()].privateEndpointConfiguration.privateEndpoint.name, '/', 'default')]",
239 | "location": "[parameters('location')]",
240 | "dependsOn": [
241 | "[parameters('privateDnsZone')]"
242 | ],
243 | "properties": {
244 | "privateDnsZoneConfigs": [
245 | {
246 | "name": "privatelink-cognitiveservices",
247 | "properties": {
248 | "privateDnsZoneId": "[concat(parameters('resourceGroupId'), '/providers/Microsoft.Network/privateDnsZones/', parameters('privateDnsZone'))]"
249 | }
250 | }
251 | ]
252 | }
253 | }
254 | ]
255 | }
256 | }
257 | }
258 | ]
259 | }
--------------------------------------------------------------------------------
/Prereq.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/Prereq.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | Welcome to the **Microsoft Azure AI for Operation Framework** repo! The purpose of this site is to provide sample OpenAI integration with LogicApp
4 |
5 | **Solution Name** | **Information** | **Configuration** |
6 | | ------------- | ------------- | ------------- |
7 | | Arc-SQL BPA | Logic App used to Asses with Azure OpenAI your DBs on Azure ARC Solution | [Configuration Link](./Arc-SQL%20BPA/README.md) |
8 | | UpdateManager Integration | Logic App used to Integrate Azure UM with OpenAI comment | [Configuration Link](./UpdateManagement/README.md) |
9 | | CostMonthlyCheck Integration | Logic App used to Monitor Cost Monthly with OpenAI comment | [Configuration Link](./CostMonthlyCheck/README.md) |
10 | | Anomalies Detection Integration | Logic App used to Monitor Anomalies Detection | [Configuration Link](./AnomaliesDetection/README.md) |
11 | | AI for Operation Framework LZ | Foundation - ARM template for AI for Op Landing Zone | [Configuration Link](./OpenAI-CoreIntegrationLZ/README.md) |
12 |
13 | Learning Resources
14 |
15 |
16 |
17 | Explore detailed resources and guides on key Azure technologies and OpenAI Landing Zone Architectural Reference in the [Learning Folder](./Learning/README.md). This folder includes insights on:
18 | - OpenAI integration with Azure
19 | - Building workflows with Logic Apps
20 | - Managing APIs with Azure API Management
21 | - Using AI and Machine Learning on Azure
22 | - Other essential Azure technologies
23 |
24 |
25 | Prerequisites
26 |
27 |
28 | Enable Azure OpenAI service and configure LLM model. Please be aware that some solutions may require some specific Azure OpenAI model. If you choose the Landing Zone Deployment that resource will be created automatically.
29 |
30 | 
31 |
32 | Arc-SQL BestPracticesAssessment OpenAI integration
33 |
34 |
35 | This template can be used for the deployment of a Logic App of SQL BPA with OpenAI report.
36 |
37 |
38 |
39 |
40 |
41 |
42 | Azure UpdateManager OpenAI integration
43 |
44 |
45 | This template can be used for the deployment of a Logic App to send UpdateManager report with OpenAI Comment of Pending security fix.
46 |
47 |
48 |
49 |
50 |
51 | Azure Cost Monthly Check OpenAI integration
52 |
53 | This template can be used for the deployment of a Logic App to send Monthly Cost Monitor report with OpenAI Comment.
54 |
55 |
56 |
57 |
58 |
59 | Azure Anomalies Detection
60 |
61 | This template can be used for the deployment of a Logic App to monitor anomalies on AD and other scenario.
62 |
63 |
64 |
65 |
66 |
67 |
68 | ## Contributing
69 |
70 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
71 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
72 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
73 |
74 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide
75 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
76 | provided by the bot. You will only need to do this once across all repos using our CLA.
77 |
78 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
79 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
80 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
81 |
82 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Security
4 |
5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet) and [Xamarin](https://github.com/xamarin).
6 |
7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below.
8 |
9 | ## Reporting Security Issues
10 |
11 | **Please do not report security vulnerabilities through public GitHub issues.**
12 |
13 | Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report).
14 |
15 | If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp).
16 |
17 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
18 |
19 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
20 |
21 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
22 | * Full paths of source file(s) related to the manifestation of the issue
23 | * The location of the affected source code (tag/branch/commit or direct URL)
24 | * Any special configuration required to reproduce the issue
25 | * Step-by-step instructions to reproduce the issue
26 | * Proof-of-concept or exploit code (if possible)
27 | * Impact of the issue, including how an attacker might exploit the issue
28 |
29 | This information will help us triage your report more quickly.
30 |
31 | If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs.
32 |
33 | ## Preferred Languages
34 |
35 | We prefer all communications to be in English.
36 |
37 | ## Policy
38 |
39 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd).
40 |
41 |
42 |
--------------------------------------------------------------------------------
/SUPPORT.md:
--------------------------------------------------------------------------------
1 | # TODO: The maintainer of this repo has not yet edited this file
2 |
3 | **REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?
4 |
5 | - **No CSS support:** Fill out this template with information about how to file issues and get help.
6 | - **Yes CSS support:** Fill out an intake form at [aka.ms/onboardsupport](https://aka.ms/onboardsupport). CSS will work with/help you to determine next steps.
7 | - **Not sure?** Fill out an intake as though the answer were "Yes". CSS will help you decide.
8 |
9 | *Then remove this first heading from this SUPPORT.MD file before publishing your repo.*
10 |
11 | # Support
12 |
13 | ## How to file issues and get help
14 |
15 | This project uses GitHub Issues to track bugs and feature requests. Please search the existing
16 | issues before filing new issues to avoid duplicates. For new issues, file your bug or
17 | feature request as a new Issue.
18 |
19 | For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
20 | FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
21 | CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
22 |
23 | ## Microsoft Support Policy
24 |
25 | Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
26 |
--------------------------------------------------------------------------------
/UpdateManagement/README.md:
--------------------------------------------------------------------------------
1 | Azure UpdateManager OpenAI integration: Configuration
2 |
3 | | **Parameters** | **Information** | **Note** |
4 | | ------------- | ------------- | ------------- |
5 | | replacewithsubid | Connection setting during deployment | Replace with your Subscription ID |
6 | | repreplacewithRG | Connection setting during deployment | Replace with the selected RG Name for the deployment |
7 | | api-key | The API code for manage your OpenAI service | The parameter is inside the second "Initialize Variable". Put your question in the "value" attribute |
8 | | changeendpointname | Insert the OpenAI endpoint name | You can found the value inside the OpenAI resource inside Azure Cognitive Service |
9 | | changemodelname | Insert the model name | You can found the value inside the OpenAI resource inside Azure Cognitive Service |
10 |
11 | Important
12 | This LogApp and the following changes are an example of integrating UpdateManager results with OpenAI, creating a report send via Email with OpenAI comment of pending Security Update of your environment.
13 |
14 |
15 | Required Identity
16 | Managed Identity
17 |
18 | Now configure the HTTP request to the Graph Explorer enabling the authentication via System Assigned Managed Identity. Please remind that the Managed Identity need to have the righ permission on the subscription for read the resources:
19 |
20 |
21 | 
22 |
23 |
24 | Deployment and Result
25 |
26 | After deployment completed, please follow the documentation:
27 |
28 |
29 | As first step please configure the required recurrence:
30 |
31 | 
32 |
33 |
34 | Configure the Api Key with the value inside your OpenAI Service:
35 |
36 | 
37 |
38 | At this point we need to configure the Ask to OpenAI module replacing the required parameters:
39 |
40 | 
41 |
42 | Now we have 2 posibilities:
43 | - Modify the body of the e-mail using a "Compose" module
44 | - Use the body inside the "Send Email V2" module. The choice is up to you.
45 |
46 | In case you choose the first option below an example:
47 |
48 | 
49 |
50 | Last Replace variable:
51 |
52 | ```Compose
53 | replace(variables('Remove square II'), '\n','')
54 | ```
55 |
56 | Last step is to add a notification section.
57 | In the example below we have a "Send Email V2" connector for send the final report to the required people or to a Teams channel . If you want to follow the same approach configure the module following the same example adding them at the end of the Logic App. Make sure to use the correct variable in the body of the email in order to have them correctly formatted:
58 |
59 | 
60 |
61 | P.S. if you need an attachment, remember to convert the output file in base 64 using the example below:
62 |
63 | ```Compose
64 | {
65 | "ContentBytes": "@{base64(body('Create_CSV_table'))}",
66 | "Name": "attachment.csv"
67 | }
68 | ```
--------------------------------------------------------------------------------
/UpdateManagement/images/ApiKey.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/UpdateManagement/images/ApiKey.jpg
--------------------------------------------------------------------------------
/UpdateManagement/images/Compose.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/UpdateManagement/images/Compose.jpeg
--------------------------------------------------------------------------------
/UpdateManagement/images/OpenAI.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/UpdateManagement/images/OpenAI.jpg
--------------------------------------------------------------------------------
/UpdateManagement/images/example-notification.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/UpdateManagement/images/example-notification.jpg
--------------------------------------------------------------------------------
/UpdateManagement/images/identity.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/UpdateManagement/images/identity.jpg
--------------------------------------------------------------------------------
/UpdateManagement/images/recurrence.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/microsoft/AI-for-Operations-Framework/f31c8c3b06e53b3d532499abd21cf14abdece942/UpdateManagement/images/recurrence.jpg
--------------------------------------------------------------------------------