Home
%3CLINGO-SUB%20id%3D%22lingo-sub-1131928%22%20slang%3D%22en-US%22%3EDeploying%20and%20Managing%20Azure%20Sentinel%20as%20Code%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1131928%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F167679i8C61546891B9EE52%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_1.png%22%20title%3D%22clipboard_image_1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CEM%3EThis%20blog%20post%20is%20co-authored%20by%20%3CA%20href%3D%22https%3A%2F%2Fwww.linkedin.com%2Fin%2Fphilippe-zenhaeusern%2F%22%20target%3D%22_self%22%20rel%3D%22nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EPhilippe%20Zenhaeusern%3C%2FA%3E%20and%20%3CA%20href%3D%22https%3A%2F%2Fwww.linkedin.com%2Fin%2Fsorianojavier%2F%22%20target%3D%22_self%22%20rel%3D%22nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EJavier%20Soriano%3C%2FA%3E%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EIn%20the%20last%20few%20months%20working%20on%20Azure%20Sentinel%20we%20have%20talked%20to%20many%20partners%20and%20customers%20about%20ways%20to%20automate%20Azure%20Sentinel%20deployment%20and%20operations.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThese%20are%20some%20of%20the%20typical%20questions%3A%20How%20can%20I%20automate%20customer%20onboarding%20into%20Sentinel%3F%20How%20can%20I%20programmatically%20configure%20connectors%3F%20As%20a%20partner%2C%20how%20do%20I%20push%20to%20my%20new%20customer%20all%20the%20custom%20analytics%20rules%2Fworkbooks%2Fplaybooks%20that%20I%20have%20created%20for%20other%20customers%3F%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EIn%20this%20post%20we%20are%20going%20to%20try%20to%20answer%20all%20these%20questions%2C%20not%20only%20describing%20how%20to%20do%20it%2C%20but%20also%20giving%20you%20some%20of%20the%20work%20done%20with%20a%20repository%20that%20contains%20a%20minimum%20viable%20product%20(MVP)%20around%20how%20to%20build%20a%20full%20Sentinel%20as%20Code%20environment.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20post%20will%20follow%20this%20structure%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3E%26nbsp%3BInfrastructure%20as%20Code%3C%2FLI%3E%0A%3CLI%3E%26nbsp%3BAzure%20Sentinel%20Automation%20Overview%3C%2FLI%3E%0A%3CLI%3E%26nbsp%3BAutomating%20the%20deployment%20of%20specific%20Azure%20Sentinel%20components%3C%2FLI%3E%0A%3CLI%3E%26nbsp%3BBuilding%20your%20Sentinel%20as%20Code%20in%20Azure%20DevOps%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3EWe%20recommend%20you%20going%20one%20by%20one%20in%20order%20to%20fully%20understand%20how%20it%20works.%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--1413636232%22%20id%3D%22toc-hId--1413636232%22%20id%3D%22toc-hId--1413636232%22%20id%3D%22toc-hId--1413636232%22%20id%3D%22toc-hId--1413636232%22%20id%3D%22toc-hId--1413636232%22%20id%3D%22toc-hId--1413636232%22%3E%26nbsp%3B%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId-1073876601%22%20id%3D%22toc-hId-1073876601%22%20id%3D%22toc-hId-1073876601%22%20id%3D%22toc-hId-1073876601%22%20id%3D%22toc-hId-1073876601%22%20id%3D%22toc-hId-1073876601%22%20id%3D%22toc-hId-1073876601%22%3EInfrastructure%20as%20Code%3C%2FH2%3E%0A%3CP%3E%3CSPAN%3EYou%20might%20be%20familiar%20with%20Infrastructure%20as%20Code%20concept.%20Have%20you%20heard%20about%20Azure%20Resource%20Manager%2C%20Terraform%20or%20AWS%20Cloud%20Formation%3F%20Well%2C%20they%20are%20all%20ways%20to%20describe%20your%20infrastructure%20as%20code%2C%20so%20you%20can%20treat%20it%20as%20such%E2%80%A6put%20it%20under%20source%20control%20(eg.%20git%2C%20svn)%20so%20you%20can%20track%20changes%20to%20your%20infrastructure%20the%20same%20way%20you%20track%20changes%20in%20your%20code.%26nbsp%3B%3C%2FSPAN%3E%3CSPAN%3EYou%20can%20use%20any%20source%20control%20platform%2C%20but%20in%20this%20article%2C%20we%20will%20use%20%3CSTRONG%3EGithub%3C%2FSTRONG%3E.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EBesides%20treating%20your%20infrastructure%20as%20code%2C%20you%20can%20also%20use%20DevOps%20tooling%20to%20test%20that%20code%20and%20deploy%20that%20infrastructure%20into%20your%20environment%2C%20all%20in%20a%20programmatic%20way.%20This%20is%20also%20referred%20as%20Continuous%20Integration%2FContinuous%20Delivery%20(CICD).%26nbsp%3B%3C%2FSPAN%3EPlease%20take%20a%20look%20at%20%3CA%20style%3D%22background-color%3A%20%23ffffff%3B%22%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Flearn%2Fwhat-is-infrastructure-as-code%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ethis%20article%3C%2FA%3E%20if%20you%20want%20to%20know%20more.%26nbsp%3B%3CSPAN%3EIn%20this%20post%20we%20will%20use%20%3CSTRONG%3EAzure%20DevOps%20%3C%2FSTRONG%3Eas%20our%20DevOps%20tool%2C%20but%20the%20concepts%20are%20the%20same%20for%20any%20other%20tool.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EIn%20the%20Sentinel%20context%2C%20the%20whole%20idea%20is%20to%20codify%20your%20Azure%20Sentinel%20deployment%20and%20put%20it%20in%20a%20code%20repository.%20Every%20time%20there%20is%20a%20change%20in%20the%20files%20that%20define%20this%20Sentinel%20environment%2C%20this%20change%20will%20trigger%20a%20pipeline%20that%20will%20verify%20the%20changes%20and%20deploys%20them%20into%20your%20Sentinel%20environment.%20But%20how%20do%20we%20programmatically%20make%20these%20changes%20into%20Sentinel%3F%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--733577862%22%20id%3D%22toc-hId--733577862%22%20id%3D%22toc-hId--733577862%22%20id%3D%22toc-hId--733577862%22%20id%3D%22toc-hId--733577862%22%20id%3D%22toc-hId--733577862%22%20id%3D%22toc-hId--733577862%22%3E%3CSPAN%3EAzure%20Sentinel%20Automation%20Overview%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CP%3E%3CSPAN%3EAs%20you%20probably%20know%2C%20there%20are%20different%20components%20inside%20Azure%20Sentinel%E2%80%A6we%20have%20Connectors%2C%20Analytics%20Rules%2C%20Workbooks%2C%20Playbooks%2C%20Hunting%20Queries%2C%20Notebooks%20and%20so%20on.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAll%20these%20components%20can%20be%20managed%20easily%20through%20the%20Azure%20Portal%2C%20but%20what%20can%20I%20use%20to%20programmatically%20modify%20all%20these%3F%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EHere%20is%20a%20table%20that%20summarizes%20what%20can%20be%20used%20for%20each%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CTABLE%20style%3D%22border-style%3A%20solid%3B%20margin-left%3A%20auto%3B%20margin-right%3A%20auto%3B%22%3E%0A%3CTBODY%3E%0A%3CTR%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSTRONG%3EComponent%3C%2FSTRONG%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSTRONG%3EAutomated%20with%3C%2FSTRONG%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3C%2FTR%3E%0A%3CTR%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSTRONG%3EOnboarding%3C%2FSTRONG%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3EAPI%2C%20Powershell%2C%20ARM%3C%2FP%3E%0A%3C%2FTD%3E%0A%3C%2FTR%3E%0A%3CTR%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSTRONG%3E%3CSPAN%3EAlert%20Rules%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSPAN%3EAPI%2C%20Powershell%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3C%2FTR%3E%0A%3CTR%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSTRONG%3EHunting%20Queries%3C%2FSTRONG%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3EAPI%2C%20Powershell%3C%2FP%3E%0A%3C%2FTD%3E%0A%3C%2FTR%3E%0A%3CTR%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSTRONG%3E%3CSPAN%3EPlaybooks%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSPAN%3EARM%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3C%2FTR%3E%0A%3CTR%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSTRONG%3EWorkbooks%3C%2FSTRONG%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3EARM%3C%2FP%3E%0A%3C%2FTD%3E%0A%3C%2FTR%3E%0A%3CTR%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSTRONG%3E%3CSPAN%3EConnectors%3C%2FSPAN%3E%3C%2FSTRONG%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3CTD%20width%3D%22189%22%3E%3CP%3E%3CSPAN%3EAPI%3C%2FSPAN%3E%3C%2FP%3E%0A%3C%2FTD%3E%0A%3C%2FTR%3E%0A%3C%2FTBODY%3E%0A%3C%2FTABLE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3E%3CSTRONG%3E%3CSPAN%3EPowershell%3C%2FSPAN%3E%3C%2FSTRONG%3E%3CSPAN%3E%3A%20Special%20thanks%20to%20Wortell%20for%20writing%20the%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fwortell%2FAZSentinel%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EAzSentinel%3C%2FA%3E%20module%2C%20which%20greatly%20facilitates%20many%20of%20the%20tasks.%20We%20will%20use%20it%20in%20the%20three%20components%20that%20support%20it%20(Onboarding%2C%20Alert%20Rules%2C%20Hunting%20Queries).%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3E%3CSPAN%3EAPI%3C%2FSPAN%3E%3C%2FSTRONG%3E%3CSPAN%3E%3A%20There%20are%20some%20components%20that%20don%E2%80%99t%20currently%20have%20a%20Powershell%20module%20and%20can%20only%20be%20configured%20programmatically%20via%20API.%20The%20API%20is%20still%20in%20preview%20but%20it%20can%20be%20found%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FAzure%2Fazure-rest-api-specs%2Ftree%2Fmaster%2Fspecification%2Fsecurityinsights%2Fresource-manager%2FMicrosoft.SecurityInsights%2Fpreview%2F2019-01-01-preview%2Fexamples%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%20We%20will%20use%20it%20partially%20in%20Alert%20Rules%20and%20in%20Connectors.%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3E%3CSTRONG%3E%3CSPAN%3EARM%3C%2FSPAN%3E%3C%2FSTRONG%3E%3CSPAN%3E%3A%20This%20is%20Azure%E2%80%99s%20native%20management%20and%20deployment%20service.%20You%20can%20use%20ARM%20templates%20to%20define%20Azure%20resources%20as%20code.%20We%20will%20use%20it%20for%20Playbooks%20and%20Workbooks.%3C%2FSPAN%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CH3%20id%3D%22toc-hId--43016388%22%20id%3D%22toc-hId--43016388%22%20id%3D%22toc-hId--43016388%22%20id%3D%22toc-hId--43016388%22%20id%3D%22toc-hId--43016388%22%20id%3D%22toc-hId--43016388%22%20id%3D%22toc-hId--43016388%22%3E%3CSPAN%3EHow%20to%20structure%20your%20Sentinel%20code%20repository%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EHere%20we%20would%20like%20to%20show%20what%20we%20think%20is%20the%20recommended%20way%20to%20structure%20your%20repository.%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3E%7C%0A%7C-%20contoso%2F%20%20________________________%20%23%20Root%20folder%20for%20customer%0A%7C%20%20%7C-%20AnalyticsRules%2F%20%20______________________%20%23%20Subfolder%20for%20Analytics%20Rules%0A%7C%20%20%20%20%20%7C-%20analytics-rules.json%20_________________%20%23%20Analytics%20Rules%20definition%20file%20(JSON)%0A%7C%0A%7C%20%20%7C-%20Connectors%2F%20%20______________________%20%23%20Subfolder%20for%20Connectors%0A%7C%20%20%20%20%20%7C-%20connectors.json%20_________________%20%23%20Connectors%20definition%20file%20(JSON)%0A%7C%0A%7C%20%20%7C-%20HuntingRules%2F%20_____________________%20%23%20%0A%7C%20%20%20%20%20%7C-%20hunting-rules.json%20_______________%20%23%20Hunting%20Rules%20definition%20file%20(JSON)%0A%7C%0A%7C%20%20%7C-%20Onboard%2F%20%20______________________%20%23%20Subfolder%20for%20Onboarding%0A%7C%20%20%20%20%20%7C-%20onboarding.json%20_________________%20%23%20Onboarding%20definition%20file%20(JSON)%0A%7C%0A%7C%20%20%7C-%20Pipelines%2F%20_____________________%20%23%20Subfolder%20for%20Pipelines%20%0A%7C%20%20%20%20%20%7C-%20pipeline.yml%20_______________%20%23%20Pipeline%20definition%20files%20(YAML)%0A%7C%0A%7C%20%20%7C-%20Playbooks%2F%20%20______________________%20%23%20Subfolder%20for%20Playbooks%0A%7C%20%20%20%20%20%7C-%20playbook.json%20_________________%20%23%20Playbooks%20definition%20files%20(ARM)%0A%7C%0A%7C%20%20%7C-%20Scripts%2F%20_____________________%20%23%20Subfolder%20for%20script%20helpers%20%0A%7C%20%20%20%20%20%7C-%20CreateAnalyticsRules.ps1%20_______________%20%23%20Script%20files%20(PowerShell)%0A%7C%0A%7C%20%20%7C-%20Workbooks%2F%20%20______________________%20%23%20Subfolder%20for%20Workbooks%0A%7C%20%20%20%20%20%7C-%20workbook-sample.json%20_________________%20%23%20Workbook%20definition%20files%20(ARM)%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EYou%20can%20find%20a%20sample%20repository%20with%20this%20structure%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EWe%20will%20use%20this%20same%20repository%20throughout%20this%20post%20as%20we%20have%20placed%20there%20the%20whole%20testing%20environment.%20%3CFONT%20color%3D%22%23FF0000%22%3E%3CSTRONG%3E%3CEM%3ENote%3C%2FEM%3E%3C%2FSTRONG%3E%3C%2FFONT%3E%3A%20take%20into%20account%20that%20this%20is%20just%20a%20Minimum%20Viable%20Product%20and%20is%20subject%20to%20improvements.%20Feel%20free%20to%20clone%20it%20and%20enhance%20it.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--53519492%22%20id%3D%22toc-hId--53519492%22%20id%3D%22toc-hId--53519492%22%20id%3D%22toc-hId--53519492%22%20id%3D%22toc-hId--53519492%22%20id%3D%22toc-hId--53519492%22%20id%3D%22toc-hId--53519492%22%3E%3CA%20target%3D%22_blank%22%20name%3D%22_Toc31035036%22%3E%3C%2FA%3E%3CSPAN%3EAutomating%20deployment%20of%20specific%20Azure%20Sentinel%20components%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CP%3E%3CSPAN%3ENow%20that%20we%20have%20clear%20view%20on%20what%20to%20use%20to%20automate%20what%20and%20how%20to%20structure%20our%20code%20repository%2C%20we%20can%20start%20creating%20things.%20Let%E2%80%99s%20go%20component%20by%20component%20detailing%20how%20to%20automate%20its%20deployment%20and%20operation.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-637041982%22%20id%3D%22toc-hId-637041982%22%20id%3D%22toc-hId-637041982%22%20id%3D%22toc-hId-637041982%22%20id%3D%22toc-hId-637041982%22%20id%3D%22toc-hId-637041982%22%20id%3D%22toc-hId-637041982%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId--1170412481%22%20id%3D%22toc-hId--1170412481%22%20id%3D%22toc-hId--1170412481%22%20id%3D%22toc-hId--1170412481%22%20id%3D%22toc-hId--1170412481%22%20id%3D%22toc-hId--1170412481%22%20id%3D%22toc-hId--1170412481%22%3E%3CSPAN%3EOnboarding%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EThanks%20to%20the%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fwortell%2FAZSentinel%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EAzSentinel%20Powershell%20module%3C%2FA%3E%20by%20Wortell%2C%20we%20have%20a%20command%20that%20simplifies%20this%20process.%20We%20just%20need%20to%20execute%20the%20following%20command%20to%20enable%20Sentinel%20on%20a%20given%20Log%20Analytics%20workspace%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3ESet-AzSentinel%20%5B-SubscriptionId%20%26lt%3BString%26gt%3B%5D%20-WorkspaceName%20%26lt%3BString%26gt%3B%20%5B-WhatIf%5D%20%5B-Confirm%5D%20%5B%26lt%3BCommonParameters%26gt%3B%5D%3C%2FPRE%3E%0A%3CP%3E%3CSPAN%3EWe%20have%20a%20created%20a%20script%20(%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%2Fblob%2Fmaster%2FScripts%2FInstallSentinel.ps1%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EInstallSentinel.ps1%3C%2FA%3E)%20with%20some%20more%20logic%20in%20it%2C%20so%20we%20can%20use%20it%20in%20our%20pipelines.%20This%20script%20takes%20a%20configuration%20file%20(JSON)%20as%20an%20input%20where%20we%20specify%20the%20different%20workspaces%20where%20the%20Sentinel%20(SecurityInsights)%20solution%20should%20be%20enabled.%20The%20file%20has%20the%20following%20format%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3E%7B%0A%20%20%20%20%22deployments%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22resourcegroup%22%3A%20%22%3CRGNAME%3E%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22workspace%22%3A%20%22%3CWORKSPACENAME%3E%22%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22resourcegroup%22%3A%20%22%3CRGNAME2%3E%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22workspace%22%3A%20%22%3CWORKSPACENAME2%3E%22%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%0A%7D%3C%2FWORKSPACENAME2%3E%3C%2FRGNAME2%3E%3C%2FWORKSPACENAME%3E%3C%2FRGNAME%3E%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20InstallSentinel.ps1%20script%20is%20located%20in%20our%20repo%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%2Fblob%2Fmaster%2FScripts%2FInstallSentinel.ps1%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E%26nbsp%3Band%20has%20the%20following%20syntax%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3EInstallSentinel.ps1%20-OnboardingFile%20%26lt%3BString%26gt%3B%3C%2FPRE%3E%0A%3CP%3E%3CSPAN%3EWe%20will%20use%20this%20script%20in%20our%20pipeline.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-1317100352%22%20id%3D%22toc-hId-1317100352%22%20id%3D%22toc-hId-1317100352%22%20id%3D%22toc-hId-1317100352%22%20id%3D%22toc-hId-1317100352%22%20id%3D%22toc-hId-1317100352%22%20id%3D%22toc-hId-1317100352%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId--490354111%22%20id%3D%22toc-hId--490354111%22%20id%3D%22toc-hId--490354111%22%20id%3D%22toc-hId--490354111%22%20id%3D%22toc-hId--490354111%22%20id%3D%22toc-hId--490354111%22%20id%3D%22toc-hId--490354111%22%3EConnectors%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3ESentinel%20Data%20Connectors%20can%20currently%20only%20be%20automated%20over%20the%20API%20which%20is%20not%20officially%20documented%20yet.%20However%2C%20with%20Developer%20Tools%20enabled%20in%20your%20browser%20it%20is%20quite%20easy%20to%20catch%20the%20related%20connector%20calls.%20Please%20take%20into%20account%20that%20this%20API%20might%20change%20in%20the%20future%20without%20notice%2C%20so%20be%20cautious%20when%20using%20it.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20following%20script%20runs%20through%20an%20example%20that%20connects%20to%20%E2%80%9CAzure%20Security%20Center%E2%80%9D%20and%20%E2%80%9CAzure%20Activity%20Logs%E2%80%9D%20to%20the%20Sentinel%20workspace%2C%20both%20are%20very%20common%20connectors%20to%20collect%20data%20from%20your%20Azure%20environments.%20(Be%20aware%20that%20some%20connectors%20will%20require%20additional%20rights%2C%20connecting%20%E2%80%9CAzure%20Active%20Directory%E2%80%9D%20source%20for%20instance%20will%20require%20additional%20AAD%20Diagnostic%20Settings%20permissions%20besides%20the%20%E2%80%9CGlobal%20Administrator%E2%80%9D%20or%20%E2%80%9CSecurity%20Administrator%E2%80%9D%20permissions%20on%20your%20Azure%20tenant.)%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20%E2%80%9CEnableConnectorsAPI.ps1%E2%80%9D%20script%20is%20located%20inside%20our%20repo%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%2Fblob%2Fmaster%2FScripts%2FEnableConnectorsAPI.ps1%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E%20and%20has%20the%20following%20syntax%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%3EEnableConnectorsAPI.ps1%20-TenantId%20%26lt%3BString%26gt%3B%20-ClientId%20%26lt%3BString%26gt%3B%20-ClientSecret%20%26lt%3BString%26gt%3B%20-SubscriptionId%20%26lt%3BString%26gt%3B%20-ResourceGroup%20%26lt%3BString%26gt%3B%20-Workspace%20%26lt%3BString%26gt%3B%20-ConnectorsFile%20%26lt%3BString%26gt%3B%3C%2FPRE%3E%0A%3CP%3E%3CSPAN%3EThe%20ConnectorsFile%20parameter%20references%20a%20JSON%20file%20which%20specifies%20all%20the%20data%20sources%20you%20want%20to%20connect%20to%20your%20Sentinel%20workspace.%20Here%20is%20a%20sample%20file%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3E%7B%0A%20%20%20%20%22connectors%22%3A%20%5B%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22AzureSecurityCenter%22%2C%0A%20%20%20%20%20%20%20%20%22properties%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22subscriptionId%22%3A%20%22subscriptionId%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22dataTypes%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22alerts%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22state%22%3A%20%22Enabled%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%7D%2C%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22AzureActivityLog%22%2C%0A%20%20%20%20%20%20%20%20%22properties%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22linkedResourceId%22%3A%20%22%2Fsubscriptions%2FsubscriptionId%2Fproviders%2Fmicrosoft.insights%2Feventtypes%2Fmanagement%22%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%5D%0A%7D%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20script%20will%20iterate%20through%20this%20JSON%20file%20and%20enable%20the%20data%20connectors%20one%20by%20one.%20This%20JSON%20file%20should%20be%20placed%20into%20the%20Connectors%20directory%20so%20the%20script%20can%20read%20it.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20you%20can%20imagine%2C%20there%20are%20some%20connectors%20that%20cannot%20be%20automated%2C%20like%20all%20the%20ones%20based%20on%20Syslog%2FCEF%20as%20they%20require%20installing%20an%20agent.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-1997158722%22%20id%3D%22toc-hId-1997158722%22%20id%3D%22toc-hId-1997158722%22%20id%3D%22toc-hId-1997158722%22%20id%3D%22toc-hId-1997158722%22%20id%3D%22toc-hId-1997158722%22%20id%3D%22toc-hId-1997158722%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId--505459220%22%20id%3D%22toc-hId--505459220%22%20id%3D%22toc-hId--505459220%22%20id%3D%22toc-hId--505459220%22%20id%3D%22toc-hId--505459220%22%20id%3D%22toc-hId--505459220%22%20id%3D%22toc-hId--505459220%22%3E%3CSPAN%3EAnalytics%20Rules%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EAzSentinel%20PS%20module%20provides%20a%20command%20to%20be%20able%20to%20create%20new%20Analytics%20Rules%20(New-AzSentinelAlertRule)%2C%20but%20it%20only%20supports%20rules%20that%20are%20of%20type%20%3CEM%3EScheduled%3C%2FEM%3E.%20Ideally%2C%20we%20want%20to%20be%20able%20to%20deploy%20a%20Sentinel%20environment%20where%20other%20types%20of%20rules%20(Microsoft%20Security%2C%20Fusion%20or%20ML%20Behavior%20Analytics)%20are%20deployed.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EFor%20that%2C%20we%20have%20created%20a%20script%20that%20uses%20a%20combination%20of%20AzSentinel%20and%20API%20calls%20to%20be%20able%20to%20create%20any%20kind%20of%20analytic%20rule.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20script%20is%20located%20inside%20our%20repo%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%2Fblob%2Fmaster%2FScripts%2FCreateAnalyticsRulesAPI.ps1%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E%20and%20has%20the%20following%20syntax%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CPRE%3ECreateAnalyticsRulesAPI.ps1%20-TenantId%20%26lt%3BString%26gt%3B%20-ClientId%20%26lt%3BString%26gt%3B%20-ClientSecret%20%26lt%3BString%26gt%3B%20-SubscriptionId%20%26lt%3BString%26gt%3B%20-ResourceGroup%20%26lt%3BString%26gt%3B%20-Workspace%20%26lt%3BString%26gt%3B%20-RulesFile%20%26lt%3BString%26gt%3B%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20you%20can%20see%2C%20one%20of%20the%20parameters%20is%20a%20rules%20file%20(in%20JSON%20format)%20where%20you%20will%20specify%20all%20the%20rules%20(of%20any%20type)%20that%20need%20to%20be%20added%20to%20your%20Sentinel%20environment.%20Here%20is%20a%20sample%20file%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3E%7B%0A%20%20%20%20%22analytics%22%3A%20%5B%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22Scheduled%22%2C%0A%20%20%20%20%20%20%20%20%22displayName%22%3A%20%22AlertRule01%22%2C%0A%20%20%20%20%20%20%20%20%22description%22%3A%20%22test%22%2C%0A%20%20%20%20%20%20%20%20%22severity%22%3A%20%22Low%22%2C%0A%20%20%20%20%20%20%20%20%22enabled%22%3A%20true%2C%0A%20%20%20%20%20%20%20%20%22query%22%3A%20%22SecurityEvent%20%7C%20where%20EventID%20%3D%3D%20%5C%224688%5C%22%20%7C%20where%20CommandLine%20contains%20%5C%22-noni%20-ep%20bypass%20%24%5C%22%22%2C%0A%20%20%20%20%20%20%20%20%22queryFrequency%22%3A%20%225H%22%2C%0A%20%20%20%20%20%20%20%20%22queryPeriod%22%3A%20%226H%22%2C%0A%20%20%20%20%20%20%20%20%22triggerOperator%22%3A%20%22GreaterThan%22%2C%0A%20%20%20%20%20%20%20%20%22triggerThreshold%22%3A%205%2C%0A%20%20%20%20%20%20%20%20%22suppressionDuration%22%3A%20%226H%22%2C%0A%20%20%20%20%20%20%20%20%22suppressionEnabled%22%3A%20false%2C%0A%20%20%20%20%20%20%20%20%22tactics%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%22Persistence%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22LateralMovement%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22Collection%22%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22Scheduled%22%2C%0A%20%20%20%20%20%20%20%20%22displayName%22%3A%20%22AlertRule02%22%2C%0A%20%20%20%20%20%20%20%20%22description%22%3A%20%22test%22%2C%0A%20%20%20%20%20%20%20%20%22severity%22%3A%20%22High%22%2C%0A%20%20%20%20%20%20%20%20%22enabled%22%3A%20true%2C%0A%20%20%20%20%20%20%20%20%22query%22%3A%20%22SecurityEvent%20%7C%20where%20EventID%20%3D%3D%20%5C%224688%5C%22%20%7C%20where%20CommandLine%20contains%20%5C%22-noni%20-ep%20bypass%20%24%5C%22%22%2C%0A%20%20%20%20%20%20%20%20%22queryFrequency%22%3A%20%225H%22%2C%0A%20%20%20%20%20%20%20%20%22queryPeriod%22%3A%20%226H%22%2C%0A%20%20%20%20%20%20%20%20%22triggerOperator%22%3A%20%22GreaterThan%22%2C%0A%20%20%20%20%20%20%20%20%22triggerThreshold%22%3A%205%2C%0A%20%20%20%20%20%20%20%20%22suppressionDuration%22%3A%20%226H%22%2C%0A%20%20%20%20%20%20%20%20%22suppressionEnabled%22%3A%20false%2C%0A%20%20%20%20%20%20%20%20%22tactics%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%22Persistence%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22LateralMovement%22%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22MicrosoftSecurityIncidentCreation%22%2C%0A%20%20%20%20%20%20%20%20%22displayName%22%3A%20%22Create%20incidents%20based%20on%20Azure%20Active%20Directory%20Identity%20Protection%20alerts%22%2C%0A%20%20%20%20%20%20%20%20%22description%22%3A%20%22Create%20incidents%20based%20on%20all%20alerts%20generated%20in%20Azure%20Active%20Directory%20Identity%20Protection%22%2C%0A%20%20%20%20%20%20%20%20%22enabled%22%3A%20true%2C%0A%20%20%20%20%20%20%20%20%22productFilter%22%3A%20%22Microsoft%20Cloud%20App%20Security%22%2C%0A%20%20%20%20%20%20%20%20%22severitiesFilter%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%22High%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22Medium%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22Low%22%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%22displayNamesFilter%22%3A%20null%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22Fusion%22%2C%0A%20%20%20%20%20%20%20%20%22displayName%22%3A%20%22Advanced%20Multistage%20Attack%20Detection%22%2C%0A%20%20%20%20%20%20%20%20%22enabled%22%3A%20true%2C%0A%20%20%20%20%20%20%20%20%22alertRuleTemplateName%22%3A%20%22f71aba3d-28fb-450b-b192-4e76a83015c8%22%0A%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%22kind%22%3A%20%22MLBehaviorAnalytics%22%2C%0A%20%20%20%20%20%20%20%20%22displayName%22%3A%20%22(Preview)%20Anomalous%20SSH%20Login%20Detection%22%2C%0A%20%20%20%20%20%20%20%20%22enabled%22%3A%20true%2C%0A%20%20%20%20%20%20%20%20%22alertRuleTemplateName%22%3A%20%22fa118b98-de46-4e94-87f9-8e6d5060b60b%22%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%5D%0A%20%20%7D%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20you%20can%20see%20Fusion%20and%20MLBehaviorAnalytics%20rules%20need%20a%20field%20called%20alertRuleTemplateName.%20This%20is%20an%20ID%20that%20is%20consistent%20across%20all%20Sentinel%20environments%2C%20so%20you%20should%20use%20the%20same%20values%20in%20your%20own%20files.%20As%20of%20today%2C%20there%E2%80%99s%20only%20one%20alert%20of%20each%20of%20these%20kinds%2C%20so%20you%20shouldn%E2%80%99t%20need%20anything%20else%20here.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20script%20will%20iterate%20through%20this%20JSON%20file%20and%20create%2Fenable%20the%20analytics%20rule%20alerts%20one%20by%20one.%20The%20script%20also%20supports%20updating%20existing%20alerts%20that%20are%20already%20enabled.%20This%20JSON%20file%20should%20be%20placed%20into%20the%20Analytics%20Rules%20directory%20so%20the%20script%20can%20read%20it.%26nbsp%3B%3C%2FSPAN%3E%3CSPAN%3ECurrently%2C%20the%20script%20doesn%E2%80%99t%20support%20attaching%20a%20playbook%20to%20an%20Analytics%20Rule%20alert.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-1982053613%22%20id%3D%22toc-hId-1982053613%22%20id%3D%22toc-hId-1982053613%22%20id%3D%22toc-hId-1982053613%22%20id%3D%22toc-hId-1982053613%22%20id%3D%22toc-hId-1982053613%22%20id%3D%22toc-hId-1982053613%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId-174599150%22%20id%3D%22toc-hId-174599150%22%20id%3D%22toc-hId-174599150%22%20id%3D%22toc-hId-174599150%22%20id%3D%22toc-hId-174599150%22%20id%3D%22toc-hId-174599150%22%20id%3D%22toc-hId-174599150%22%3E%3CSPAN%3EWorkbooks%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EWorkbooks%20are%20a%20native%20object%20in%20Azure%2C%20and%20therefore%2C%20can%20be%20created%20through%20an%20ARM%20template.%20The%20idea%20is%20that%20you%20would%20place%20all%20the%20custom%20workbooks%20that%20you%20have%20developed%20inside%20the%20Workbooks%20folder%20in%20your%20repo%2C%20and%20any%20change%20on%20these%20will%20trigger%20a%20pipeline%20that%20creates%20them%20in%20your%20Sentinel%20environment.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EWe%20have%20created%20a%20script%20(placed%20in%20the%20same%20repo%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%2Fblob%2Fmaster%2FScripts%2FCreateWorkbooks.ps1%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E)%20that%20can%20be%20used%20to%20automate%20this%20process.%20It%20has%20the%20following%20syntax%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CPRE%3ECreateWorkbooks.ps1%20-ResourceGroup%20%26lt%3BString%26gt%3B%20-WorkbooksFolder%20%26lt%3BString%26gt%3B%20-WorkbooksSourceId%20%26lt%3BString%26gt%3B%3C%2FPRE%3E%0A%3CP%3E%3CSPAN%3EThe%20script%20will%20iterate%20through%20all%20the%20workbooks%20in%20the%20WorksbooksFolder%20and%20deploy%20them%20into%20Sentinel.%20You%20also%20need%20to%20specify%20as%20a%20parameter%20the%20WorkbookSourceId.%20This%20is%20need%20to%20indicate%20ARM%20that%20the%20location%20of%20the%20workbook%20will%20be%20inside%20Azure%20Sentinel.%20WorkbookSourceId%20has%20the%20following%20format%3A%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3CPRE%3E%3CSPAN%3E%2Fsubscriptions%2F%3CSUBSCRIPTIONID%3E%2Fresourcegroups%2F%3CRESOURCEGROUP%3E%2Fproviders%2Fmicrosoft.operationalinsights%2Fworkspaces%2F%3CWORKSPACENAME%3E%3C%2FWORKSPACENAME%3E%3C%2FRESOURCEGROUP%3E%3C%2FSUBSCRIPTIONID%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAlso%20take%20into%20account%20that%20the%20deployment%20will%20fail%20if%20a%20workbook%20with%20the%20same%20name%20already%20exists.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--1632855313%22%20id%3D%22toc-hId--1632855313%22%20id%3D%22toc-hId--1632855313%22%20id%3D%22toc-hId--1632855313%22%20id%3D%22toc-hId--1632855313%22%20id%3D%22toc-hId--1632855313%22%20id%3D%22toc-hId--1632855313%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId-854657520%22%20id%3D%22toc-hId-854657520%22%20id%3D%22toc-hId-854657520%22%20id%3D%22toc-hId-854657520%22%20id%3D%22toc-hId-854657520%22%20id%3D%22toc-hId-854657520%22%20id%3D%22toc-hId-854657520%22%3E%3CSPAN%3EHunting%20Rules%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EIn%20order%20to%20automate%20the%20deployment%20of%20Hunting%20Rules%2C%20we%20will%20use%20AzSentinel%20module.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EWe%20have%20a%20created%20another%20script%20that%20takes%20as%20an%20input%20a%20JSON%20file%20where%20all%20the%20Hunting%20Rules%20are%20defined.%20The%20script%20will%20iterate%20over%20them%20and%20create%2Fupdate%20them%20accordingly.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20syntax%20for%20this%20script%20is%20the%20following%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CPRE%3ECreateHuntingRulesAPI.ps1%20-Workspace%20%26lt%3BString%26gt%3B%20-RulesFile%20%26lt%3BString%26gt%3B%3C%2FPRE%3E%0A%3CH3%20id%3D%22toc-hId--952796943%22%20id%3D%22toc-hId--952796943%22%20id%3D%22toc-hId--952796943%22%20id%3D%22toc-hId--952796943%22%20id%3D%22toc-hId--952796943%22%20id%3D%22toc-hId--952796943%22%20id%3D%22toc-hId--952796943%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId-1534715890%22%20id%3D%22toc-hId-1534715890%22%20id%3D%22toc-hId-1534715890%22%20id%3D%22toc-hId-1534715890%22%20id%3D%22toc-hId-1534715890%22%20id%3D%22toc-hId-1534715890%22%20id%3D%22toc-hId-1534715890%22%3EPlaybooks%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EThis%20will%20work%20the%20same%20way%20as%20Workbooks.%20Playbooks%20use%20Azure%20Logic%20Apps%20in%20order%20to%20automatically%20respond%20to%20incidents.%20Logic%20Apps%20are%20a%20native%20resource%20in%20ARM%2C%20and%20therefore%20we%20can%20automate%20its%20deployment%20with%20ARM%20templates.%20The%20idea%20is%20that%20you%20would%20place%20all%20the%20custom%20playbooks%20that%20you%20have%20developed%20inside%20the%20Playbooks%20folder%20in%20your%20repo%2C%20and%20any%20change%20on%20these%20will%20trigger%20a%20pipeline%20that%20creates%20them%20in%20your%20Sentinel%20environment.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EWe%20have%20created%20a%20script%20(placed%20in%20the%20same%20repo%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%2Fblob%2Fmaster%2FScripts%2FCreatePlaybooks.ps1%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E)%20that%20can%20be%20used%20to%20automate%20this%20process.%20It%20has%20the%20following%20syntax%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CPRE%3E%3CSPAN%3ECreatePlaybooks.ps1%20-ResourceGroup%20%3CSTRING%3E%20-PlaybooksFolder%20%3CSTRING%3E%3C%2FSTRING%3E%3C%2FSTRING%3E%3C%2FSPAN%3E%3C%2FPRE%3E%0A%3CP%3E%3CSPAN%3EThis%20script%20will%20succeed%20even%20if%20the%20playbooks%20are%20already%20there.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--401821292%22%20id%3D%22toc-hId--401821292%22%20id%3D%22toc-hId--401821292%22%20id%3D%22toc-hId--401821292%22%20id%3D%22toc-hId--401821292%22%20id%3D%22toc-hId--401821292%22%20id%3D%22toc-hId--401821292%22%3E%26nbsp%3B%3C%2FH2%3E%0A%3CH2%20id%3D%22toc-hId-2085691541%22%20id%3D%22toc-hId-2085691541%22%20id%3D%22toc-hId-2085691541%22%20id%3D%22toc-hId-2085691541%22%20id%3D%22toc-hId-2085691541%22%20id%3D%22toc-hId-2085691541%22%20id%3D%22toc-hId-2085691541%22%3E%3CA%20target%3D%22_blank%22%20name%3D%22_Toc31035037%22%3E%3C%2FA%3E%3CSPAN%3EBuilding%20your%20Sentinel%20as%20Code%20in%20Azure%20DevOps%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CP%3E%3CSPAN%3ENow%20that%20we%20have%20clear%20view%20on%20how%20to%20structure%20our%20code%20repository%20and%20what%20to%20use%20to%20automate%20each%20Sentinel%20component%2C%20we%20can%20start%20creating%20things%20in%20Azure%20DevOps.%20This%20is%20a%20high-level%20list%20of%20tasks%20that%20we%20will%20perform%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CUL%3E%0A%3CLI%3E%3CSPAN%3ECreate%20an%20Azure%20DevOps%20organization%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3E%3CSPAN%3ECreate%20a%20project%20in%20Azure%20DevOps%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3E%3CSPAN%3ECreate%20a%20service%20connection%20to%20your%20Azure%20environment%2Fs%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3E%3CSPAN%3ECreate%20variables%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3E%3CSPAN%3EConnect%20your%20existing%20code%20repository%20with%20your%20Az%20DevOps%20project%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3E%3CSPAN%3ECreate%20pipelines%3C%2FSPAN%3E%3C%2FLI%3E%0A%3C%2FUL%3E%0A%3CP%3E%3CSPAN%3ELet%E2%80%99s%20review%20them%20one%20by%20one.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-407319797%22%20id%3D%22toc-hId-407319797%22%20id%3D%22toc-hId-407319797%22%20id%3D%22toc-hId-407319797%22%20id%3D%22toc-hId-407319797%22%20id%3D%22toc-hId-407319797%22%20id%3D%22toc-hId-407319797%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId--701972725%22%20id%3D%22toc-hId--701972725%22%20id%3D%22toc-hId--701972725%22%20id%3D%22toc-hId--701972725%22%20id%3D%22toc-hId--701972725%22%20id%3D%22toc-hId--701972725%22%20id%3D%22toc-hId--701972725%22%3E%3CSPAN%3ECreate%20an%20Azure%20DevOps%20organization%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EThis%20is%20the%20first%20step%20in%20order%20to%20have%20your%20Azure%20DevOps%20environment.%20You%20can%20see%20the%20details%20on%20how%20to%20do%20this%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Forganizations%2Faccounts%2Fcreate-organization%3Fview%3Dazure-devops%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-1785540108%22%20id%3D%22toc-hId-1785540108%22%20id%3D%22toc-hId-1785540108%22%20id%3D%22toc-hId-1785540108%22%20id%3D%22toc-hId-1785540108%22%20id%3D%22toc-hId-1785540108%22%20id%3D%22toc-hId-1785540108%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId--21914355%22%20id%3D%22toc-hId--21914355%22%20id%3D%22toc-hId--21914355%22%20id%3D%22toc-hId--21914355%22%20id%3D%22toc-hId--21914355%22%20id%3D%22toc-hId--21914355%22%20id%3D%22toc-hId--21914355%22%3E%3CSPAN%3ECreate%20a%20project%20in%20Azure%20DevOps%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EA%20project%20provides%20a%20repository%20for%20source%20code%20and%20a%20place%20for%20a%20group%20of%20people%20to%20plan%2C%20track%20progress%2C%20and%20collaborate%20on%20building%20software%20solutions.%20It%20will%20be%20the%20container%20for%20your%20code%20repository%2C%20pipelines%2C%20boards%2C%20etc.%20See%20instructions%20on%20how%20to%20create%20it%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Forganizations%2Fprojects%2Fabout-projects%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--1829368818%22%20id%3D%22toc-hId--1829368818%22%20id%3D%22toc-hId--1829368818%22%20id%3D%22toc-hId--1829368818%22%20id%3D%22toc-hId--1829368818%22%20id%3D%22toc-hId--1829368818%22%20id%3D%22toc-hId--1829368818%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId-658144015%22%20id%3D%22toc-hId-658144015%22%20id%3D%22toc-hId-658144015%22%20id%3D%22toc-hId-658144015%22%20id%3D%22toc-hId-658144015%22%20id%3D%22toc-hId-658144015%22%20id%3D%22toc-hId-658144015%22%3E%3CSPAN%3ECreate%20a%20service%20connection%20to%20your%20Azure%20environment%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EIn%20order%20to%20talk%20to%20our%20Azure%20environment%2C%20we%20need%20to%20create%20connection%20with%20specific%20Azure%20credentials.%20In%20Azure%20DevOps%20this%20is%20called%20Service%20connection.%20The%20credentials%20that%20you%20will%20use%20to%20create%20this%20service%20connection%20are%20typically%20a%20service%20principal%20account%20defined%20on%20Azure.%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EYou%20have%20full%20details%20on%20how%20to%20create%20a%20service%20connection%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Fpipelines%2Flibrary%2Fservice-endpoints%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThese%20are%20the%20fields%20you%20need%20to%20provide%20to%20create%20your%20service%20connection%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F167598i565C8CBEEB5910EC%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_0.png%22%20title%3D%22clipboard_image_0.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3ETake%20a%20note%20of%20the%20%3CEM%3EConnection%20name%3C%2FEM%3E%20you%20provide%2C%20as%20you%20will%20need%20to%20use%20this%20name%20in%20your%20pipelines.%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--1149310448%22%20id%3D%22toc-hId--1149310448%22%20id%3D%22toc-hId--1149310448%22%20id%3D%22toc-hId--1149310448%22%20id%3D%22toc-hId--1149310448%22%20id%3D%22toc-hId--1149310448%22%20id%3D%22toc-hId--1149310448%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId-1338202385%22%20id%3D%22toc-hId-1338202385%22%20id%3D%22toc-hId-1338202385%22%20id%3D%22toc-hId-1338202385%22%20id%3D%22toc-hId-1338202385%22%20id%3D%22toc-hId-1338202385%22%20id%3D%22toc-hId-1338202385%22%3E%3CSPAN%3ECreate%20variables%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EWe%20are%20going%20to%20need%20several%20variables%20defined%20in%20the%20Azure%20DevOps%20environment%20so%20they%20can%20be%20passed%20to%20our%20scripts%20to%20specify%20the%20Sentinel%20workspace%2C%20resource%20group%2C%20config%20files%20and%20API%20connection%20information.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20we%20are%20going%20to%20need%20these%20variables%20across%20all%20our%20pipelines%2C%20the%20best%20thing%20to%20do%20is%20to%20create%20a%20variable%20group%20in%20Azure%20DevOps.%20With%20this%2C%20we%20can%20define%20the%20variable%20group%20once%20and%20then%20reuse%20it%20in%20different%20pipelines%20across%20our%20project.%26nbsp%3B%3C%2FSPAN%3E%3CSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Fpipelines%2Flibrary%2Fvariable-groups%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EHere%3C%2FA%3E%20you%20have%20instructions%20on%20how%20to%20do%20it.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EWe%20have%20called%20our%20variable%20group%20%E2%80%9CAz%20connection%20settings%E2%80%9D%3B%20this%20is%20important%20because%20we%20will%20reference%20this%20name%20in%20our%20pipelines.%20Here%20is%20a%20screenshot%20of%20the%20variables%20that%20we%20will%20need%20to%20define%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F167599i52F7A636EDCB6900%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_1.png%22%20title%3D%22clipboard_image_1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--469252078%22%20id%3D%22toc-hId--469252078%22%20id%3D%22toc-hId--469252078%22%20id%3D%22toc-hId--469252078%22%20id%3D%22toc-hId--469252078%22%20id%3D%22toc-hId--469252078%22%20id%3D%22toc-hId--469252078%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId-2018260755%22%20id%3D%22toc-hId-2018260755%22%20id%3D%22toc-hId-2018260755%22%20id%3D%22toc-hId-2018260755%22%20id%3D%22toc-hId-2018260755%22%20id%3D%22toc-hId-2018260755%22%20id%3D%22toc-hId-2018260755%22%3E%3CSPAN%3EConnect%20your%20existing%20code%20repository%20with%20your%20Az%20DevOps%20project%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EIn%20this%20article%20you%20can%20see%20how%20to%20import%20an%20existing%20repo%20into%20Az%20DevOps.%20It%20works%20for%20Gihub%2C%20Bitbucket%2C%20Gitlab%20and%20other%20locations.%20See%20instructions%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Frepos%2Fgit%2Fimport-git-repository%3Fview%3Dazure-devops%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-210806292%22%20id%3D%22toc-hId-210806292%22%20id%3D%22toc-hId-210806292%22%20id%3D%22toc-hId-210806292%22%20id%3D%22toc-hId-210806292%22%20id%3D%22toc-hId-210806292%22%20id%3D%22toc-hId-210806292%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId--898486230%22%20id%3D%22toc-hId--898486230%22%20id%3D%22toc-hId--898486230%22%20id%3D%22toc-hId--898486230%22%20id%3D%22toc-hId--898486230%22%20id%3D%22toc-hId--898486230%22%20id%3D%22toc-hId--898486230%22%3E%3CSPAN%3ECreate%20pipelines%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EThere%20are%20two%20ways%20to%20create%20our%20Azure%20Pipelines%3A%20in%20classic%20mode%20or%20as%20YAML%20files.%20We%20are%20going%20to%20create%20them%20as%20YAML%20files%2C%20because%20that%20way%20we%20can%20place%20them%20into%20our%20code%20repository%20so%20they%20can%20be%20easily%20tracked%20and%20reused%20anywhere.%26nbsp%3B%3C%2FSPAN%3E%3CSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Fpipelines%2Fcreate-first-pipeline%3Fview%3Dazure-devops%26amp%3Btabs%3Dbrowser%252Ctfs-2018-2%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EHere%3C%2FA%3E%20you%20have%20the%20basic%20steps%20to%20create%20a%20new%20pipeline.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EIn%20the%20new%20pipeline%20wizard%2C%20select%20Github%20YAML%20in%20the%20%3CEM%3EConnect%3C%2FEM%3E%20step%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F167600iA103F82E704479EF%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_2.png%22%20title%3D%22clipboard_image_2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThen%20select%20your%20repository%20and%20then%20choose%20%3CEM%3EStarter%20pipeline%3C%2FEM%3E%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F167601i466F86BAAB76BCA7%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_3.png%22%20title%3D%22clipboard_image_3.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EWe%20are%20going%20to%20create%20one%20CI%20(build)%20pipeline%20for%20Scripts%20and%20several%20CICD%20(build%2Bdeploy)%20pipelines%20(one%20for%20each%20Sentinel%20component).%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId-1589026603%22%20id%3D%22toc-hId-1589026603%22%20id%3D%22toc-hId-1589026603%22%20id%3D%22toc-hId-1589026603%22%20id%3D%22toc-hId-1589026603%22%20id%3D%22toc-hId-1589026603%22%20id%3D%22toc-hId-1589026603%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId--218427860%22%20id%3D%22toc-hId--218427860%22%20id%3D%22toc-hId--218427860%22%20id%3D%22toc-hId--218427860%22%20id%3D%22toc-hId--218427860%22%20id%3D%22toc-hId--218427860%22%20id%3D%22toc-hId--218427860%22%3E%3CSPAN%3ECreate%20a%20CI%20pipeline%20for%20Scripts%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EWe%20will%20treat%20Scripts%20slightly%20different%20than%20the%20rest.%20This%20is%20because%20it%20is%20not%20a%20Sentinel%20component%2C%20and%20the%20scripts%20themselves%20won%E2%80%99t%20get%20deployed%20to%20Azure%2C%20we%20will%20just%20use%20them%20to%20deploy%20other%20things.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EBecause%20of%20this%2C%20the%20only%20thing%20we%20need%20to%20do%20with%20scripts%20is%20make%20sure%20they%20are%20available%20in%20the%20other%20pipelines%20to%20be%20used%20as%20artifacts.%20To%20accomplish%20this%2C%20we%20just%20need%20two%20tasks%20in%20our%20CI%20pipeline%3A%20Copy%20Files%20and%20Publish%20Pipeline%20Artifact%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EHere%20is%20an%20example%20of%20the%20YAML%20code%20that%20will%20define%20this%20pipeline%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Etrigger%3A%0A%20paths%3A%0A%20%20%20include%3A%0A%20%20%20%20%20-%20Scripts%2F*%0A%0Apool%3A%0A%20%20vmImage%3A%20'ubuntu-latest'%0A%0Asteps%3A%0A-%20task%3A%20CopyFiles%402%0A%20%20displayName%3A%20'Copy%20Scripts'%0A%20%20inputs%3A%0A%20%20%20%20SourceFolder%3A%20Scripts%0A%20%20%20%20TargetFolder%3A%20'%24(build.artifactstagingdirectory)'%0A%0A-%20task%3A%20PublishPipelineArtifact%401%0A%20%20displayName%3A%20'Publish%20Pipeline%20Artifact'%0A%20%20inputs%3A%0A%20%20%20%20targetPath%3A%20Scripts%0A%20%20%20%20artifact%3A%20Scripts%0A%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20you%20can%20see%2C%20we%20have%20added%20two%20steps%2C%20one%20to%20copy%20the%20script%20files%20and%20another%20to%20publish%20the%20pipeline%20artifacts.%26nbsp%3B%3C%2FSPAN%3E%3CSPAN%3EYou%20can%20find%20this%20pipeline%20in%20our%20Github%20repo%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%2Fblob%2Fmaster%2FPipelines%2FbuildScripts.yml%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH3%20id%3D%22toc-hId--2025882323%22%20id%3D%22toc-hId--2025882323%22%20id%3D%22toc-hId--2025882323%22%20id%3D%22toc-hId--2025882323%22%20id%3D%22toc-hId--2025882323%22%20id%3D%22toc-hId--2025882323%22%20id%3D%22toc-hId--2025882323%22%3E%26nbsp%3B%3C%2FH3%3E%0A%3CH3%20id%3D%22toc-hId-461630510%22%20id%3D%22toc-hId-461630510%22%20id%3D%22toc-hId-461630510%22%20id%3D%22toc-hId-461630510%22%20id%3D%22toc-hId-461630510%22%20id%3D%22toc-hId-461630510%22%20id%3D%22toc-hId-461630510%22%3E%3CSPAN%3ECreate%20CICD%20pipelines%20for%20each%20Sentinel%20component%3C%2FSPAN%3E%3C%2FH3%3E%0A%3CP%3E%3CSPAN%3EWith%20the%20Scripts%20now%20available%20as%20an%20artifact%2C%20we%20can%20now%20use%20them%20into%20our%20Sentinel%20component%20pipelines.%20These%20pipelines%20will%20be%20different%20from%20the%20previous%20one%2C%20because%20we%20will%20do%20CI%20and%20CD%20(build%2Bdeploy).%20We%20define%20these%20in%20our%20YAML%20pipeline%20file%20as%20%3CEM%3Estages%3C%2FEM%3E.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EHere%20is%20one%20sample%20pipeline%20for%20Analytics%20Rules%3A%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Ename%3A%20build%20and%20deploy%20Alert%20Rules%0Aresources%3A%0A%20pipelines%3A%0A%20%20%20-%20pipeline%3A%20Scripts%0A%20%20%20%20%20source%3A%20'scriptsCI'%0Atrigger%3A%0A%20paths%3A%0A%20%20%20include%3A%0A%20%20%20%20%20-%20AnalyticsRules%2F*%0A%0Astages%3A%0A-%20stage%3A%20build_alert_rules%0A%0A%20%20jobs%3A%0A%20%20%20%20-%20job%3A%20AgentJob%0A%20%20%20%20%20%20pool%3A%0A%20%20%20%20%20%20%20name%3A%20Azure%20Pipelines%0A%20%20%20%20%20%20%20vmImage%3A%20'vs2017-win2016'%0A%20%20%20%20%20%20steps%3A%0A%20%20%20%20%20%20%20-%20task%3A%20CopyFiles%402%0A%20%20%20%20%20%20%20%20%20displayName%3A%20'Copy%20Alert%20Rules'%0A%20%20%20%20%20%20%20%20%20inputs%3A%0A%20%20%20%20%20%20%20%20%20%20SourceFolder%3A%20AnalyticsRules%0A%20%20%20%20%20%20%20%20%20%20TargetFolder%3A%20'%24(Pipeline.Workspace)'%0A%0A%20%20%20%20%20%20%20-%20task%3A%20PublishBuildArtifacts%401%0A%20%20%20%20%20%20%20%20%20displayName%3A%20'Publish%20Artifact%3A%20RulesFile'%0A%20%20%20%20%20%20%20%20%20inputs%3A%0A%20%20%20%20%20%20%20%20%20%20PathtoPublish%3A%20'%24(Pipeline.Workspace)'%0A%20%20%20%20%20%20%20%20%20%20ArtifactName%3A%20RulesFile%0A%0A-%20stage%3A%20deploy_alert_rules%0A%20%20jobs%3A%0A%20%20%20%20-%20job%3A%20AgentJob%0A%20%20%20%20%20%20pool%3A%0A%20%20%20%20%20%20%20name%3A%20Azure%20Pipelines%0A%20%20%20%20%20%20%20vmImage%3A%20'windows-2019'%0A%20%20%20%20%20%20variables%3A%20%0A%20%20%20%20%20%20-%20group%3A%20Az%20connection%20settings%0A%20%20%20%20%20%20steps%3A%0A%20%20%20%20%20%20-%20download%3A%20current%0A%20%20%20%20%20%20%20%20artifact%3A%20RulesFile%0A%20%20%20%20%20%20-%20download%3A%20Scripts%0A%20%20%20%20%20%20%20%20patterns%3A%20'*.ps1'%0A%20%20%20%20%20%20-%20task%3A%20AzurePowerShell%404%0A%20%20%20%20%20%20%20%20displayName%3A%20'Create%20and%20Update%20Alert%20Rules'%0A%20%20%20%20%20%20%20%20inputs%3A%0A%20%20%20%20%20%20%20%20%20azureSubscription%3A%20'Soricloud%20Visual%20Studio'%0A%20%20%20%20%20%20%20%20%20ScriptPath%3A%20'%24(Pipeline.Workspace)%2FScripts%2FScripts%2FCreateAnalyticsRulesAPI.ps1'%0A%20%20%20%20%20%20%20%20%20ScriptArguments%3A%20'-TenantId%20%24(TenantId)%20-ClientId%20%24(ClientId)%20-ClientSecret%20%24(ClientSecret)%20-SubscriptionId%20%24(SubscriptionId)%20-ResourceGroup%20%24(ResourceGroup)%20-Workspace%20%24(Workspace)%20-RulesFile%20analytics-rules.json'%0A%20%20%20%20%20%20%20%20%20azurePowerShellVersion%3A%20LatestVersion%0A%20%20%20%20%20%20%20%20%20pwsh%3A%20true%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20you%20can%20see%2C%20we%20have%20now%20two%20stages%3A%20build%20and%20deploy.%20We%20also%20had%20to%20define%20resources%2C%20to%20reference%20the%20artifact%20that%20we%20need%20from%20our%20Scripts%20build%20pipeline.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThe%20build%20stage%20is%20the%20same%20the%20one%20we%20did%20for%20script%2C%20so%20we%20won%E2%80%99t%20explain%20it%20again.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EIn%20the%20deploy%20stage%20we%20have%20a%20couple%20of%20new%20things.%20First%2C%20we%20are%20going%20the%20variables%20that%20we%20defined%20some%20minutes%20ago%2C%20for%20that%20we%20use%20variables.%20Then%20we%20need%20to%20download%20the%20artifacts%20that%20we%20will%20use%20in%20our%20deployment%20task%2C%20for%20that%20we%20use%20download.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20the%20last%20step%20in%20our%20CICD%20pipeline%2C%20we%20are%20going%20use%20an%20Azure%20Powershell%20task%20where%20we%20will%20point%20to%20our%20script%20and%20specify%20any%20parameters%20needed.%20As%20you%20can%20see%2C%20we%20reference%20the%20imported%20variables%20here.%20One%20last%20peculiarity%20of%20this%20pipeline%20is%20that%20we%20need%20to%20use%20Powershell%20Core%20(required%20by%20AzSentinel)%2C%20so%20we%20need%20to%20specify%20that%20with%20pwsh.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EIf%20everything%20went%20correctly%2C%20we%20will%20be%20able%20to%20run%20this%20pipeline%20now%20and%20verify%20that%20our%20Sentinel%20analytics%20rules%20were%20deployed%20automatically%20%3C%2FSPAN%3E%3Asmiling_face_with_smiling_eyes%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EThis%20and%20all%20the%20other%20pipelines%20for%20the%20rest%20of%20components%20are%20in%20our%20repo%20inside%20the%20Pipelines%20folder.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EFor%20Onboarding%2C%20the%20pipeline%20has%20no%20automatic%20triggers%2C%20as%20we%20consider%20that%20this%20would%20be%20executed%20only%20once%20at%20installation%20time.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CH2%20id%3D%22toc-hId--1474906672%22%20id%3D%22toc-hId--1474906672%22%20id%3D%22toc-hId--1474906672%22%20id%3D%22toc-hId--1474906672%22%20id%3D%22toc-hId--1474906672%22%20id%3D%22toc-hId--1474906672%22%20id%3D%22toc-hId--1474906672%22%3E%26nbsp%3B%3C%2FH2%3E%0A%3CH2%20id%3D%22toc-hId-1012606161%22%20id%3D%22toc-hId-1012606161%22%20id%3D%22toc-hId-1012606161%22%20id%3D%22toc-hId-1012606161%22%20id%3D%22toc-hId-1012606161%22%20id%3D%22toc-hId-1012606161%22%20id%3D%22toc-hId-1012606161%22%3E%3CA%20target%3D%22_blank%22%20name%3D%22_Toc31035038%22%3E%3C%2FA%3E%3CSPAN%3EWorking%20with%20multiple%20workspaces%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CP%3E%3CSPAN%3EWhether%20you%20are%20a%20customer%20with%20an%20Azure%20Sentinel%20environment%20that%20contains%20multiple%20workspaces%20or%20you%E2%80%99re%20a%20partner%20that%20needs%20to%20operate%20several%20customers%2C%20you%20need%20to%20have%20a%20strategy%20to%20manage%20more%20than%20one%20workspace.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAs%20you%20have%20seen%20during%20the%20article%2C%20we%20have%20used%20a%20variable%20group%20to%20store%20details%20like%20resource%20group%20and%20workspace%20name.%20These%20values%20will%20change%20if%20we%20need%20to%20manage%20multiple%20workspaces%2C%20so%20we%20would%20need%20more%20than%20one%20variable%20group.%20For%20example%2C%20one%20for%20customer%20A%20and%20another%20for%20customer%20B%2C%20or%20one%20for%20Europe%20and%20one%20for%20Asia.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EAfter%20that%E2%80%99s%20done%2C%20we%20can%20choose%20between%20two%20approaches%3A%20%3C%2FSPAN%3E%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3E%3CSPAN%3EAdd%20more%20stages%20to%20your%20current%20pipelines.%20Until%20now%2C%20we%20only%20had%20one%20deploy%20stage%20that%20deployed%20to%20our%20only%20Sentinel%20environment%2C%20but%20now%20we%20can%20add%20additional%20stages%20(with%20the%20same%20steps%20and%20tasks)%20that%20deploy%20to%20other%20resource%20groups%20and%20workspaces.%3C%2FSPAN%3E%3C%2FLI%3E%0A%3CLI%3E%3CSPAN%3ECreate%20new%20pipelines.%20We%20can%20just%20clone%20our%20existing%20pipelines%20and%20just%20modify%20the%20variable%20group%20to%20point%20to%20a%20different%20target%20environment.%3C%2FSPAN%3E%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CH2%20id%3D%22toc-hId--794848302%22%20id%3D%22toc-hId--794848302%22%20id%3D%22toc-hId--794848302%22%20id%3D%22toc-hId--794848302%22%20id%3D%22toc-hId--794848302%22%20id%3D%22toc-hId--794848302%22%20id%3D%22toc-hId--794848302%22%3E%26nbsp%3B%3C%2FH2%3E%0A%3CH2%20id%3D%22toc-hId-1692664531%22%20id%3D%22toc-hId-1692664531%22%20id%3D%22toc-hId-1692664531%22%20id%3D%22toc-hId-1692664531%22%20id%3D%22toc-hId-1692664531%22%20id%3D%22toc-hId-1692664531%22%20id%3D%22toc-hId-1692664531%22%3E%3CA%20target%3D%22_blank%22%20name%3D%22_Toc31035039%22%3E%3C%2FA%3E%3CSPAN%3EIn%20Summary%3C%2FSPAN%3E%3C%2FH2%3E%0A%3CP%3E%3CSPAN%3EWe%20have%20shown%20you%20how%20to%20describe%20you%20Azure%20Sentinel%20deployment%20using%20code%20and%20then%20use%20a%20DevOps%20tool%20to%20deploy%20that%20code%20into%20your%20Azure%20environment.%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-1131928%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%3EDo%20you%20want%20to%20learn%20how%20to%20deploy%20and%20operate%26nbsp%3B%3C%2FSPAN%3E%3CSPAN%20class%3D%22hashtag-a11y%20ember-view%22%3E%3CSPAN%20class%3D%22hashtag-a11y__name%22%3EAzure%20Sentinel%3C%2FSPAN%3E%3C%2FSPAN%3E%26nbsp%3B%3CSPAN%3Eas%20code%3F%20In%20this%20post%20we%20explain%20the%20end-to-end%20process%20and%20also%20provide%20you%20with%20a%20working%20prototype%20for%20use%20to%20reuse%20and%20extend.%26nbsp%3B%3C%2FSPAN%3E%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1131928%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%20Sentinel%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ESecurity%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1134321%22%20slang%3D%22en-US%22%3ERe%3A%20Deploying%20and%20Managing%20Azure%20Sentinel%20as%20Code%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1134321%22%20slang%3D%22en-US%22%3E%3CP%3EGreat%20article!%20Regarding%20Connector%20you%20can%20use%20this%20script%20here%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fazsec%2Fazure-sentinel-tools%2Fblob%2Fmaster%2Fscripts%2FConnect-AzureSecurityCenter.ps1%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttps%3A%2F%2Fgithub.com%2Fazsec%2Fazure-sentinel-tools%2Fblob%2Fmaster%2Fscripts%2FConnect-AzureSecurityCenter.ps1%3C%2FA%3E%20to%20connect%20all%20ASCs%20from%20a%20list%20of%20target%20subscription.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20hope%20API%20will%20be%20released%20soon.%20The%20real-world%20issue%20is%20not%20the%20creation%20but%20the%20update%20and%20continuous%20change%20on%20Analytics%20rule%20that%20require%20a%20little%20tricky%20in%20the%20pipeline.%20A%20use%20case%20if%20that%20you%20would%20want%20to%20tune%20the%20analytics%20rule%20to%20increase%20fidelity%20-%20so%20having%20a%20fixed%20rule%20is%20not%20something%20we%20expect.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI'm%20not%20sure%20if%20you%20have%20tested%20Update%20case%3F%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1134354%22%20slang%3D%22en-US%22%3ERe%3A%20Deploying%20and%20Managing%20Azure%20Sentinel%20as%20Code%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1134354%22%20slang%3D%22en-US%22%3E%3CP%3EThanks%20for%20the%20comments%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F536280%22%20target%3D%22_blank%22%3E%40azsec%3C%2FA%3E%26nbsp%3B!%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EYes%2C%20we%20have%20tested%20the%20update%20of%20Analytics%20Rules%20and%20it%20works.%20Of%20course%20there%20might%20be%20corner%20cases%20where%20it%20doesn't%20work...but%20in%20general%20you%20can%20just%20update%20the%20json%20file%2C%20the%20pipeline%20will%20trigger%20automatically%2C%20identify%20that%20the%20rule%20already%20exists%20and%20update%20accordingly.%20Take%20a%20look%20at%20lines%2054%20to%20172%20in%20the%20script%20%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fjaviersoriano%2Fsentinelascode%2Fblob%2Fmaster%2FScripts%2FCreateAnalyticsRulesAPI.ps1%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehere%3C%2FA%3E%2C%20this%20is%20where%20existing%20rules%20are%20handled.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20any%20case%2C%20as%20we%20say%20in%20the%20post%2C%20this%20is%20an%20MVP%20and%20for%20sure%20it%20can%20be%20improved.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ERegards%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1134374%22%20slang%3D%22en-US%22%3ERe%3A%20Deploying%20and%20Managing%20Azure%20Sentinel%20as%20Code%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1134374%22%20slang%3D%22en-US%22%3E%3CP%3EThank%20you%20for%20replies.%20In%20the%20real-world%20deployment%20you%20would%20probably%20name%20your%20rule%20with%20a%20unique%20ID%20(GUID)%20and%20when%20performing%20an%20update%20the%20pipeline%20should%20know%20which%20rule%20it%20needs%20to%20update.%20This%20would%20sound%20like%20an%20egg-and-chicken%20story.%20Otherwise%20the%20pipeline%20checks%20the%20display%20name%20and%20get%20its%20unique%20ID%20(aka%20name).%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1136524%22%20slang%3D%22en-US%22%3ERe%3A%20Deploying%20and%20Managing%20Azure%20Sentinel%20as%20Code%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1136524%22%20slang%3D%22en-US%22%3E%3CP%3EAwesome%20blogpost%26nbsp%3B%3CIMG%20class%3D%22lia-deferred-image%20lia-image-emoji%22%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Fhtml%2Fimages%2Femoticons%2Fcool_40x40.gif%22%20alt%3D%22%3Acool%3A%22%20title%3D%22%3Acool%3A%22%20%2F%3E%20Thanks%20for%20Sharing%20with%20the%20Community!%3C%2FP%3E%3C%2FLINGO-BODY%3E
Microsoft

clipboard_image_1.png

 

This blog post is co-authored by Philippe Zenhaeusern and Javier Soriano

 

In the last few months working on Azure Sentinel we have talked to many partners and customers about ways to automate Azure Sentinel deployment and operations.

 

These are some of the typical questions: How can I automate customer onboarding into Sentinel? How can I programmatically configure connectors? As a partner, how do I push to my new customer all the custom analytics rules/workbooks/playbooks that I have created for other customers?

 

In this post we are going to try to answer all these questions, not only describing how to do it, but also giving you some of the work done with a repository that contains a minimum viable product (MVP) around how to build a full Sentinel as Code environment.

 

The post will follow this structure:

 

  1.  Infrastructure as Code
  2.  Azure Sentinel Automation Overview
  3.  Automating the deployment of specific Azure Sentinel components
  4.  Building your Sentinel as Code in Azure DevOps

We recommend you going one by one in order to fully understand how it works.

 

 

Infrastructure as Code

You might be familiar with Infrastructure as Code concept. Have you heard about Azure Resource Manager, Terraform or AWS Cloud Formation? Well, they are all ways to describe your infrastructure as code, so you can treat it as such…put it under source control (eg. git, svn) so you can track changes to your infrastructure the same way you track changes in your code. You can use any source control platform, but in this article, we will use Github.

 

Besides treating your infrastructure as code, you can also use DevOps tooling to test that code and deploy that infrastructure into your environment, all in a programmatic way. This is also referred as Continuous Integration/Continuous Delivery (CICD). Please take a look at this article if you want to know more. In this post we will use Azure DevOps as our DevOps tool, but the concepts are the same for any other tool.

 

In the Sentinel context, the whole idea is to codify your Azure Sentinel deployment and put it in a code repository. Every time there is a change in the files that define this Sentinel environment, this change will trigger a pipeline that will verify the changes and deploys them into your Sentinel environment. But how do we programmatically make these changes into Sentinel?

 

Azure Sentinel Automation Overview

As you probably know, there are different components inside Azure Sentinel…we have Connectors, Analytics Rules, Workbooks, Playbooks, Hunting Queries, Notebooks and so on.

All these components can be managed easily through the Azure Portal, but what can I use to programmatically modify all these?

 

Here is a table that summarizes what can be used for each:

 

Component

Automated with

Onboarding

API, Powershell, ARM

Alert Rules

API, Powershell

Hunting Queries

API, Powershell

Playbooks

ARM

Workbooks

ARM

Connectors

API

 

  • Powershell: Special thanks to Wortell for writing the AzSentinel module, which greatly facilitates many of the tasks. We will use it in the three components that support it (Onboarding, Alert Rules, Hunting Queries).
  • API: There are some components that don’t currently have a Powershell module and can only be configured programmatically via API. The API is still in preview but it can be found here. We will use it partially in Alert Rules and in Connectors.
  • ARM: This is Azure’s native management and deployment service. You can use ARM templates to define Azure resources as code. We will use it for Playbooks and Workbooks.

How to structure your Sentinel code repository

Here we would like to show what we think is the recommended way to structure your repository.

 

 

 

 

 

|
|- contoso/  ________________________ # Root folder for customer
|  |- AnalyticsRules/  ______________________ # Subfolder for Analytics Rules
|     |- analytics-rules.json _________________ # Analytics Rules definition file (JSON)
|
|  |- Connectors/  ______________________ # Subfolder for Connectors
|     |- connectors.json _________________ # Connectors definition file (JSON)
|
|  |- HuntingRules/ _____________________ # 
|     |- hunting-rules.json _______________ # Hunting Rules definition file (JSON)
|
|  |- Onboard/  ______________________ # Subfolder for Onboarding
|     |- onboarding.json _________________ # Onboarding definition file (JSON)
|
|  |- Pipelines/ _____________________ # Subfolder for Pipelines 
|     |- pipeline.yml _______________ # Pipeline definition files (YAML)
|
|  |- Playbooks/  ______________________ # Subfolder for Playbooks
|     |- playbook.json _________________ # Playbooks definition files (ARM)
|
|  |- Scripts/ _____________________ # Subfolder for script helpers 
|     |- CreateAnalyticsRules.ps1 _______________ # Script files (PowerShell)
|
|  |- Workbooks/  ______________________ # Subfolder for Workbooks
|     |- workbook-sample.json _________________ # Workbook definition files (ARM)

 

 

 

 

You can find a sample repository with this structure here.

 

We will use this same repository throughout this post as we have placed there the whole testing environment. Note: take into account that this is just a Minimum Viable Product and is subject to improvements. Feel free to clone it and enhance it.

 

Automating deployment of specific Azure Sentinel components

Now that we have clear view on what to use to automate what and how to structure our code repository, we can start creating things. Let’s go component by component detailing how to automate its deployment and operation.

 

Onboarding

Thanks to the AzSentinel Powershell module by Wortell, we have a command that simplifies this process. We just need to execute the following command to enable Sentinel on a given Log Analytics workspace:

 

Set-AzSentinel [-SubscriptionId <String>] -WorkspaceName <String> [-WhatIf] [-Confirm] [<CommonParameters>]

We have a created a script (InstallSentinel.ps1) with some more logic in it, so we can use it in our pipelines. This script takes a configuration file (JSON) as an input where we specify the different workspaces where the Sentinel (SecurityInsights) solution should be enabled. The file has the following format:

 

 

 

 

{
    "deployments": [
        {
            "resourcegroup": "<rgname>",
            "workspace": "<workspacename>"
        },
        {
            "resourcegroup": "<rgname2>",
            "workspace": "<workspacename2>"
        }
    ]
}

 

 

 

 

The InstallSentinel.ps1 script is located in our repo here and has the following syntax:

 

InstallSentinel.ps1 -OnboardingFile <String>

We will use this script in our pipeline.

 

Connectors

Sentinel Data Connectors can currently only be automated over the API which is not officially documented yet. However, with Developer Tools enabled in your browser it is quite easy to catch the related connector calls. Please take into account that this API might change in the future without notice, so be cautious when using it.

 

The following script runs through an example that connects to “Azure Security Center” and “Azure Activity Logs” to the Sentinel workspace, both are very common connectors to collect data from your Azure environments. (Be aware that some connectors will require additional rights, connecting “Azure Active Directory” source for instance will require additional AAD Diagnostic Settings permissions besides the “Global Administrator” or “Security Administrator” permissions on your Azure tenant.)

The “EnableConnectorsAPI.ps1” script is located inside our repo here and has the following syntax:

 

EnableConnectorsAPI.ps1 -TenantId <String> -ClientId <String> -ClientSecret <String> -SubscriptionId <String> -ResourceGroup <String> -Workspace <String> -ConnectorsFile <String>

The ConnectorsFile parameter references a JSON file which specifies all the data sources you want to connect to your Sentinel workspace. Here is a sample file:

 

 

 

 

{
    "connectors": [
    {
        "kind": "AzureSecurityCenter",
        "properties": {
            "subscriptionId": "subscriptionId",
            "dataTypes": {
                "alerts": {
                    "state": "Enabled"
                }
            }
        },
    },
    {
        "kind": "AzureActivityLog",
        "properties": {
            "linkedResourceId": "/subscriptions/subscriptionId/providers/microsoft.insights/eventtypes/management"
        }
    }]
}

 

 

 

 

The script will iterate through this JSON file and enable the data connectors one by one. This JSON file should be placed into the Connectors directory so the script can read it.

 

As you can imagine, there are some connectors that cannot be automated, like all the ones based on Syslog/CEF as they require installing an agent.

 

Analytics Rules

AzSentinel PS module provides a command to be able to create new Analytics Rules (New-AzSentinelAlertRule), but it only supports rules that are of type Scheduled. Ideally, we want to be able to deploy a Sentinel environment where other types of rules (Microsoft Security, Fusion or ML Behavior Analytics) are deployed.

 

For that, we have created a script that uses a combination of AzSentinel and API calls to be able to create any kind of analytic rule.

 

The script is located inside our repo here and has the following syntax:

CreateAnalyticsRulesAPI.ps1 -TenantId <String> -ClientId <String> -ClientSecret <String> -SubscriptionId <String> -ResourceGroup <String> -Workspace <String> -RulesFile <String>

 

As you can see, one of the parameters is a rules file (in JSON format) where you will specify all the rules (of any type) that need to be added to your Sentinel environment. Here is a sample file:

 

 

 

 

{
    "analytics": [
      {
        "kind": "Scheduled",
        "displayName": "AlertRule01",
        "description": "test",
        "severity": "Low",
        "enabled": true,
        "query": "SecurityEvent | where EventID == \"4688\" | where CommandLine contains \"-noni -ep bypass $\"",
        "queryFrequency": "5H",
        "queryPeriod": "6H",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 5,
        "suppressionDuration": "6H",
        "suppressionEnabled": false,
        "tactics": [
          "Persistence",
          "LateralMovement",
          "Collection"
        ]
      },
      {
        "kind": "Scheduled",
        "displayName": "AlertRule02",
        "description": "test",
        "severity": "High",
        "enabled": true,
        "query": "SecurityEvent | where EventID == \"4688\" | where CommandLine contains \"-noni -ep bypass $\"",
        "queryFrequency": "5H",
        "queryPeriod": "6H",
        "triggerOperator": "GreaterThan",
        "triggerThreshold": 5,
        "suppressionDuration": "6H",
        "suppressionEnabled": false,
        "tactics": [
          "Persistence",
          "LateralMovement"
        ]
      },
      {
        "kind": "MicrosoftSecurityIncidentCreation",
        "displayName": "Create incidents based on Azure Active Directory Identity Protection alerts",
        "description": "Create incidents based on all alerts generated in Azure Active Directory Identity Protection",
        "enabled": true,
        "productFilter": "Microsoft Cloud App Security",
        "severitiesFilter": [
          "High",
          "Medium",
          "Low"
        ],
        "displayNamesFilter": null
      },
      {
        "kind": "Fusion",
        "displayName": "Advanced Multistage Attack Detection",
        "enabled": true,
        "alertRuleTemplateName": "f71aba3d-28fb-450b-b192-4e76a83015c8"
      },
      {
        "kind": "MLBehaviorAnalytics",
        "displayName": "(Preview) Anomalous SSH Login Detection",
        "enabled": true,
        "alertRuleTemplateName": "fa118b98-de46-4e94-87f9-8e6d5060b60b"
      }
    ]
  }

 

 

 

 

As you can see Fusion and MLBehaviorAnalytics rules need a field called alertRuleTemplateName. This is an ID that is consistent across all Sentinel environments, so you should use the same values in your own files. As of today, there’s only one alert of each of these kinds, so you shouldn’t need anything else here.

 

The script will iterate through this JSON file and create/enable the analytics rule alerts one by one. The script also supports updating existing alerts that are already enabled. This JSON file should be placed into the Analytics Rules directory so the script can read it. Currently, the script doesn’t support attaching a playbook to an Analytics Rule alert.

 

Workbooks

Workbooks are a native object in Azure, and therefore, can be created through an ARM template. The idea is that you would place all the custom workbooks that you have developed inside the Workbooks folder in your repo, and any change on these will trigger a pipeline that creates them in your Sentinel environment.

 

We have created a script (placed in the same repo here) that can be used to automate this process. It has the following syntax:

CreateWorkbooks.ps1 -ResourceGroup <String> -WorkbooksFolder <String> -WorkbooksSourceId <String>

The script will iterate through all the workbooks in the WorksbooksFolder and deploy them into Sentinel. You also need to specify as a parameter the WorkbookSourceId. This is need to indicate ARM that the location of the workbook will be inside Azure Sentinel. WorkbookSourceId has the following format:

/subscriptions/<subscriptionid>/resourcegroups/<resourcegroup>/providers/microsoft.operationalinsights/workspaces/<workspacename>

 

Also take into account that the deployment will fail if a workbook with the same name already exists.

 

Hunting Rules

In order to automate the deployment of Hunting Rules, we will use AzSentinel module.

We have a created another script that takes as an input a JSON file where all the Hunting Rules are defined. The script will iterate over them and create/update them accordingly.

 

The syntax for this script is the following:

CreateHuntingRulesAPI.ps1 -Workspace <String> -RulesFile <String>

 

Playbooks

This will work the same way as Workbooks. Playbooks use Azure Logic Apps in order to automatically respond to incidents. Logic Apps are a native resource in ARM, and therefore we can automate its deployment with ARM templates. The idea is that you would place all the custom playbooks that you have developed inside the Playbooks folder in your repo, and any change on these will trigger a pipeline that creates them in your Sentinel environment.

 

We have created a script (placed in the same repo here) that can be used to automate this process. It has the following syntax:

CreatePlaybooks.ps1 -ResourceGroup <String> -PlaybooksFolder <String>

This script will succeed even if the playbooks are already there.

 

Building your Sentinel as Code in Azure DevOps

Now that we have clear view on how to structure our code repository and what to use to automate each Sentinel component, we can start creating things in Azure DevOps. This is a high-level list of tasks that we will perform:

 

  • Create an Azure DevOps organization
  • Create a project in Azure DevOps
  • Create a service connection to your Azure environment/s
  • Create variables
  • Connect your existing code repository with your Az DevOps project
  • Create pipelines

Let’s review them one by one.

 

Create an Azure DevOps organization

This is the first step in order to have your Azure DevOps environment. You can see the details on how to do this here.

 

Create a project in Azure DevOps

A project provides a repository for source code and a place for a group of people to plan, track progress, and collaborate on building software solutions. It will be the container for your code repository, pipelines, boards, etc. See instructions on how to create it here.

 

Create a service connection to your Azure environment

In order to talk to our Azure environment, we need to create connection with specific Azure credentials. In Azure DevOps this is called Service connection. The credentials that you will use to create this service connection are typically a service principal account defined on Azure.

 

You have full details on how to create a service connection here.

 

These are the fields you need to provide to create your service connection:

 

clipboard_image_0.png

Take a note of the Connection name you provide, as you will need to use this name in your pipelines.

 

Create variables

We are going to need several variables defined in the Azure DevOps environment so they can be passed to our scripts to specify the Sentinel workspace, resource group, config files and API connection information.

 

As we are going to need these variables across all our pipelines, the best thing to do is to create a variable group in Azure DevOps. With this, we can define the variable group once and then reuse it in different pipelines across our project. Here you have instructions on how to do it.

 

We have called our variable group “Az connection settings”; this is important because we will reference this name in our pipelines. Here is a screenshot of the variables that we will need to define:

clipboard_image_1.png

 

Connect your existing code repository with your Az DevOps project

In this article you can see how to import an existing repo into Az DevOps. It works for Gihub, Bitbucket, Gitlab and other locations. See instructions here.

 

Create pipelines

There are two ways to create our Azure Pipelines: in classic mode or as YAML files. We are going to create them as YAML files, because that way we can place them into our code repository so they can be easily tracked and reused anywhere. Here you have the basic steps to create a new pipeline.

 

In the new pipeline wizard, select Github YAML in the Connect step:

clipboard_image_2.png

Then select your repository and then choose Starter pipeline:

clipboard_image_3.png

We are going to create one CI (build) pipeline for Scripts and several CICD (build+deploy) pipelines (one for each Sentinel component).

 

Create a CI pipeline for Scripts

We will treat Scripts slightly different than the rest. This is because it is not a Sentinel component, and the scripts themselves won’t get deployed to Azure, we will just use them to deploy other things.

Because of this, the only thing we need to do with scripts is make sure they are available in the other pipelines to be used as artifacts. To accomplish this, we just need two tasks in our CI pipeline: Copy Files and Publish Pipeline Artifact

 

Here is an example of the YAML code that will define this pipeline:

 

 

 

 

trigger:
 paths:
   include:
     - Scripts/*

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: CopyFiles@2
  displayName: 'Copy Scripts'
  inputs:
    SourceFolder: Scripts
    TargetFolder: '$(build.artifactstagingdirectory)'

- task: PublishPipelineArtifact@1
  displayName: 'Publish Pipeline Artifact'
  inputs:
    targetPath: Scripts
    artifact: Scripts

 

 

 

 

As you can see, we have added two steps, one to copy the script files and another to publish the pipeline artifacts. You can find this pipeline in our Github repo here.

 

Create CICD pipelines for each Sentinel component

With the Scripts now available as an artifact, we can now use them into our Sentinel component pipelines. These pipelines will be different from the previous one, because we will do CI and CD (build+deploy). We define these in our YAML pipeline file as stages.

 

Here is one sample pipeline for Analytics Rules:

 

 

 

 

name: build and deploy Alert Rules
resources:
 pipelines:
   - pipeline: Scripts
     source: 'scriptsCI'
trigger:
 paths:
   include:
     - AnalyticsRules/*

stages:
- stage: build_alert_rules

  jobs:
    - job: AgentJob
      pool:
       name: Azure Pipelines
       vmImage: 'vs2017-win2016'
      steps:
       - task: CopyFiles@2
         displayName: 'Copy Alert Rules'
         inputs:
          SourceFolder: AnalyticsRules
          TargetFolder: '$(Pipeline.Workspace)'

       - task: PublishBuildArtifacts@1
         displayName: 'Publish Artifact: RulesFile'
         inputs:
          PathtoPublish: '$(Pipeline.Workspace)'
          ArtifactName: RulesFile

- stage: deploy_alert_rules
  jobs:
    - job: AgentJob
      pool:
       name: Azure Pipelines
       vmImage: 'windows-2019'
      variables: 
      - group: Az connection settings
      steps:
      - download: current
        artifact: RulesFile
      - download: Scripts
        patterns: '*.ps1'
      - task: AzurePowerShell@4
        displayName: 'Create and Update Alert Rules'
        inputs:
         azureSubscription: 'Soricloud Visual Studio'
         ScriptPath: '$(Pipeline.Workspace)/Scripts/Scripts/CreateAnalyticsRulesAPI.ps1'
         ScriptArguments: '-TenantId $(TenantId) -ClientId $(ClientId) -ClientSecret $(ClientSecret) -SubscriptionId $(SubscriptionId) -ResourceGroup $(ResourceGroup) -Workspace $(Workspace) -RulesFile analytics-rules.json'
         azurePowerShellVersion: LatestVersion
         pwsh: true

 

 

 

 

As you can see, we have now two stages: build and deploy. We also had to define resources, to reference the artifact that we need from our Scripts build pipeline.

 

The build stage is the same the one we did for script, so we won’t explain it again.

 

In the deploy stage we have a couple of new things. First, we are going the variables that we defined some minutes ago, for that we use variables. Then we need to download the artifacts that we will use in our deployment task, for that we use download.

 

As the last step in our CICD pipeline, we are going use an Azure Powershell task where we will point to our script and specify any parameters needed. As you can see, we reference the imported variables here. One last peculiarity of this pipeline is that we need to use Powershell Core (required by AzSentinel), so we need to specify that with pwsh.

 

If everything went correctly, we will be able to run this pipeline now and verify that our Sentinel analytics rules were deployed automatically :smiling_face_with_smiling_eyes:

 

This and all the other pipelines for the rest of components are in our repo inside the Pipelines folder.

For Onboarding, the pipeline has no automatic triggers, as we consider that this would be executed only once at installation time.

 

Working with multiple workspaces

Whether you are a customer with an Azure Sentinel environment that contains multiple workspaces or you’re a partner that needs to operate several customers, you need to have a strategy to manage more than one workspace.

 

As you have seen during the article, we have used a variable group to store details like resource group and workspace name. These values will change if we need to manage multiple workspaces, so we would need more than one variable group. For example, one for customer A and another for customer B, or one for Europe and one for Asia.

 

After that’s done, we can choose between two approaches:

  1. Add more stages to your current pipelines. Until now, we only had one deploy stage that deployed to our only Sentinel environment, but now we can add additional stages (with the same steps and tasks) that deploy to other resource groups and workspaces.
  2. Create new pipelines. We can just clone our existing pipelines and just modify the variable group to point to a different target environment.

 

In Summary

We have shown you how to describe you Azure Sentinel deployment using code and then use a DevOps tool to deploy that code into your Azure environment.

4 Comments
Occasional Visitor

Great article! Regarding Connector you can use this script here https://github.com/azsec/azure-sentinel-tools/blob/master/scripts/Connect-AzureSecurityCenter.ps1 to connect all ASCs from a list of target subscription.

 

I hope API will be released soon. The real-world issue is not the creation but the update and continuous change on Analytics rule that require a little tricky in the pipeline. A use case if that you would want to tune the analytics rule to increase fidelity - so having a fixed rule is not something we expect.

 

I'm not sure if you have tested Update case?

Microsoft

Thanks for the comments @azsec !

 

Yes, we have tested the update of Analytics Rules and it works. Of course there might be corner cases where it doesn't work...but in general you can just update the json file, the pipeline will trigger automatically, identify that the rule already exists and update accordingly. Take a look at lines 54 to 172 in the script here, this is where existing rules are handled.

 

In any case, as we say in the post, this is an MVP and for sure it can be improved.

 

Regards

Occasional Visitor

Thank you for replies. In the real-world deployment you would probably name your rule with a unique ID (GUID) and when performing an update the pipeline should know which rule it needs to update. This would sound like an egg-and-chicken story. Otherwise the pipeline checks the display name and get its unique ID (aka name).

Awesome blogpost :cool: Thanks for Sharing with the Community!