Last active
October 25, 2020 05:42
-
-
Save pkhabazi/5d815820a689e7cddcebcd583366ee9c to your computer and use it in GitHub Desktop.
Deploying and Managing Azure Sentinel – Ninja style
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Describe "Azure Sentinel AlertRules Tests" { | |
$TestFiles = Get-ChildItem -Path .\SettingFiles\AlertRules.json -File -Recurse | ForEach-Object -Process { | |
@{ | |
File = $_.FullName | |
ConvertedJson = (Get-Content -Path $_.FullName | ConvertFrom-Json) | |
Path = $_.DirectoryName | |
Name = $_.Name | |
} | |
} | |
It 'Converts from JSON | <File>' -TestCases $TestFiles { | |
param ( | |
$File, | |
$ConvertedJson | |
) | |
$ConvertedJson | Should -Not -Be $null | |
} | |
It 'Schedueled rules have the minimum elements' -TestCases $TestFiles { | |
param ( | |
$File, | |
$ConvertedJson | |
) | |
$expected_elements = @( | |
'displayName', | |
'description', | |
'severity', | |
'enabled', | |
'query', | |
'queryFrequency', | |
'queryPeriod', | |
'triggerOperator', | |
'triggerThreshold', | |
'suppressionDuration', | |
'suppressionEnabled', | |
'tactics', | |
'playbookName' | |
) | |
$rules = $ConvertedJson.Scheduled | |
$rules.ForEach{ | |
$expected_elements | Should -BeIn $_.psobject.Properties.Name | |
} | |
} | |
It 'Fusion rules have the minimum elements' -TestCases $TestFiles { | |
param ( | |
$File, | |
$ConvertedJson | |
) | |
$expected_elements = @( | |
'displayName', | |
'enabled', | |
'alertRuleTemplateName' | |
) | |
$rules = $ConvertedJson.Fusion | |
$rules.ForEach{ | |
$expected_elements | Should -BeIn $_.psobject.Properties.Name | |
} | |
} | |
It 'MLBehaviorAnalytics rules have the minimum elements' -TestCases $TestFiles { | |
param ( | |
$File, | |
$ConvertedJson | |
) | |
$expected_elements = @( | |
'displayName', | |
'enabled', | |
'alertRuleTemplateName' | |
) | |
$rules = $ConvertedJson.MLBehaviorAnalytics | |
$rules.ForEach{ | |
$expected_elements | Should -BeIn $_.psobject.Properties.Name | |
} | |
} | |
It 'MicrosoftSecurityIncidentCreation rules have the minimum elements' -TestCases $TestFiles { | |
param ( | |
$File, | |
$ConvertedJson | |
) | |
$expected_elements = @( | |
'displayName', | |
'enabled', | |
'description', | |
'productFilter', | |
'severitiesFilter', | |
'displayNamesFilter' | |
) | |
$rules = $ConvertedJson.MicrosoftSecurityIncidentCreation | |
$rules.ForEach{ | |
$expected_elements | Should -BeIn $_.psobject.Properties.Name | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is the main pipelien which covers all the stages | |
# The tasks are stored in pipelines/steps.yml | |
stages: | |
- stage: Dev | |
displayName: 'Deploying to Development environment' | |
jobs: | |
- template: pipelines/steps.yml | |
parameters: | |
environment: Dev | |
azureSubscription: '' | |
WorkspaceName: '' # Enter the Azure Sentinel Workspace name | |
SubscriptionId: 'cd466daa-3528-481e-83f1-7a7148706287' | |
ResourceGroupName: '' | |
ResourceGroupLocation: 'westeurope' | |
EnableSentinel: true | |
analyticsRulesFile: SettingFiles/AlertRules.json # leave empty if you dont want to configure Analytic rules | |
huntingRulesFile: SettingFiles/HuntingRules.json # leave empty if you dont want to configure Hunting rules | |
PlaybooksFolder: Playbooks/ # leave empty if you dont want to configure Playbooks | |
ConnectorsFile: SettingFiles/DataConnectors.json # leave empty if you dont want to configure Connectors | |
WorkbooksFolder: Workbooks/ | |
WorkbookSourceId: '' # leave empty if you dont want to configure Workbook | |
- stage: Staging | |
displayName: 'Deploying to Acceptance environment' | |
condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/release')) | |
dependsOn: Dev # this stage runs after Dev | |
jobs: | |
- template: pipelines/steps.yml | |
parameters: | |
environment: Staging | |
azureSubscription: '' | |
WorkspaceName: '' # Enter the Azure Sentinel Workspace name | |
SubscriptionId: 'cd466daa-3528-481e-83f1-7a7148706287' | |
ResourceGroupName: '' | |
ResourceGroupLocation: 'westeurope' | |
EnableSentinel: true | |
analyticsRulesFile: SettingFiles/AlertRules.json # leave empty if you dont want to configure Analytic rules | |
huntingRulesFile: SettingFiles/HuntingRules.json # leave empty if you dont want to configure Hunting rules | |
PlaybooksFolder: Playbooks/ # leave empty if you dont want to configure Playbooks | |
ConnectorsFile: SettingFiles/DataConnectors.json # leave empty if you dont want to configure Connectors | |
WorkbooksFolder: Workbooks/ | |
WorkbookSourceId: '' # leave empty if you dont want to configure Workbook | |
- stage: Production | |
displayName: 'Deploying to Production environment' | |
condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/master')) | |
dependsOn: Dev # this stage runs after Dev | |
jobs: | |
- template: pipelines/steps.yml | |
parameters: | |
environment: Production | |
azureSubscription: '' | |
WorkspaceName: '' # Enter the Azure Sentinel Workspace name | |
SubscriptionId: 'cd466daa-3528-481e-83f1-7a7148706287' | |
ResourceGroupName: '' | |
ResourceGroupLocation: 'westeurope' | |
EnableSentinel: true | |
analyticsRulesFile: SettingFiles/AlertRules.json # leave empty if you dont want to configure Analytic rules | |
huntingRulesFile: SettingFiles/HuntingRules.json # leave empty if you dont want to configure Hunting rules | |
PlaybooksFolder: Playbooks/ # leave empty if you dont want to configure Playbooks | |
ConnectorsFile: SettingFiles/DataConnectors.json # leave empty if you dont want to configure Connectors | |
WorkbooksFolder: Workbooks/ | |
WorkbookSourceId: '' # leave empty if you dont want to configure Workbook |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Build Validation pipeline | |
# This Pipeline is used to trigger teh Pester test files when a PR is created | |
trigger: none | |
pool: | |
vmImage: 'ubuntu-latest' | |
steps: | |
- task: PowerShell@2 | |
inputs: | |
targetType: 'inline' | |
script: 'Invoke-Pester *.tests.ps1 -OutputFile ./test-results.xml -OutputFormat NUnitXml' | |
errorActionPreference: 'continue' | |
pwsh: true | |
- task: PublishTestResults@2 | |
inputs: | |
testResultsFormat: 'NUnit' | |
testResultsFiles: '**/test-results.xml' | |
failTaskOnFailedTests: true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is the Template that is used from the Main pipeline | |
# This template contains all the required steps | |
parameters: | |
- name: environment | |
displayName: environment name | |
type: string | |
- name: azureSubscription | |
displayName: Enter the Azure Serviceconntion | |
type: string | |
- name: SubscriptionId | |
displayName: Enter the Subscription id where the Azure sentinel workspace is deployed | |
type: string | |
- name: WorkspaceName | |
displayName: Enter the Azure Sentinel Workspace name | |
type: string | |
- name: EnableSentinel | |
displayName: Enable Azure Sentinel if not enabled | |
type: boolean | |
- name: analyticsRulesFile | |
displayName: path to Azure Sentinel Analytics ruile file | |
type: string | |
- name: huntingRulesFile | |
displayName: path to Azure Sentinel Hunting ruile file | |
type: string | |
- name: PlaybooksFolder | |
displayName: The path to the fodler with the playbook JSON files | |
type: string | |
- name: ConnectorsFile | |
displayName: The path to DataConnector json file | |
type: string | |
- name: WorkbooksFolder | |
displayName: The path to the folder which contains the Workbooks JSON files | |
type: string | |
- name: WorkbookSourceId | |
displayName: The id of resource instance to which the workbook will be associated | |
type: string | |
- name: ResourceGroupName | |
displayName: Enter the Resource group name for Playbooks and Workbooks | |
type: string | |
- name: ResourceGroupLocation | |
displayName: Enter the Resource group location for Playbooks and Workbooks | |
type: string | |
jobs: | |
- deployment: 'Sentinel' | |
displayName: DeploySentinelSolution | |
pool: | |
vmImage: 'ubuntu-latest' | |
environment: ${{ parameters.environment }} | |
strategy: | |
runOnce: | |
deploy: | |
steps: | |
- checkout: self | |
- task: PowerShell@2 | |
displayName: 'Prepare environemnt' | |
inputs: | |
targetType: 'Inline' | |
script: | | |
Install-Module AzSentinel -Scope CurrentUser -Force | |
Import-Module AzSentinel | |
pwsh: true | |
- ${{ if eq(parameters.EnableSentinel, true) }}: | |
- task: AzurePowerShell@5 | |
displayName: 'Enable and configure Azure Sentinel' | |
inputs: | |
azureSubscription: ${{ parameters.azureSubscription }} | |
ScriptType: 'InlineScript' | |
Inline: | | |
Set-AzSentinel -SubscriptionId ${{ parameters.SubscriptionId }} -WorkspaceName ${{ parameters.WorkspaceName }} -Confirm:$false | |
azurePowerShellVersion: 'LatestVersion' | |
pwsh: true | |
- ${{ if ne(parameters.PlaybooksFolder, '') }}: | |
- task: AzurePowerShell@4 | |
displayName: 'Create and Update Playbooks' | |
inputs: | |
azureSubscription: ${{ parameters.azureSubscription }} | |
ScriptType: 'InlineScript' | |
Inline: | | |
$armTemplateFiles = Get-ChildItem -Path ${{ parameters.PlaybooksFolder }} -Filter *.json | |
$rg = Get-AzResourceGroup -ResourceGroupName ${{ parameters.ResourceGroupName }} -ErrorAction SilentlyContinue | |
if ($null -eq $rg) { | |
New-AzResourceGroup -ResourceGroupName ${{ parameters.ResourceGroupName }} -Location ${{ parameters.ResourceGroupLocation }} | |
} | |
foreach ($armTemplate in $armTemplateFiles) { | |
New-AzResourceGroupDeployment -ResourceGroupName ${{ parameters.ResourceGroupName }} -TemplateFile $armTemplate | |
} | |
azurePowerShellVersion: LatestVersion | |
pwsh: true | |
- ${{ if ne(parameters.analyticsRulesFile, '') }}: | |
- task: AzurePowerShell@5 | |
displayName: 'Create and Update Alert Rules' | |
inputs: | |
azureSubscription: ${{ parameters.azureSubscription }} | |
ScriptType: 'InlineScript' | |
Inline: | | |
Import-AzSentinelAlertRule -SubscriptionId ${{ parameters.SubscriptionId }} -WorkspaceName ${{ parameters.WorkspaceName }} -SettingsFile ${{ parameters.analyticsRulesFile }} | |
azurePowerShellVersion: 'LatestVersion' | |
pwsh: true | |
- ${{ if ne(parameters.huntingRulesFile, '') }}: | |
- task: AzurePowerShell@5 | |
displayName: 'Create and Update Hunting Rules' | |
inputs: | |
azureSubscription: ${{ parameters.azureSubscription }} | |
ScriptType: 'InlineScript' | |
Inline: | | |
Import-AzSentinelHuntingRule -SubscriptionId ${{ parameters.SubscriptionId }} -WorkspaceName ${{ parameters.WorkspaceName }} -SettingsFile ${{ parameters.huntingRulesFile }} | |
azurePowerShellVersion: 'LatestVersion' | |
pwsh: true | |
- ${{ if ne(parameters.ConnectorsFile, '') }}: | |
- task: AzurePowerShell@5 | |
displayName: 'Create and Update Connectors' | |
inputs: | |
azureSubscription: ${{ parameters.azureSubscription }} | |
ScriptType: 'InlineScript' | |
Inline: | | |
Import-AzSentinelDataConnector -SubscriptionId ${{ parameters.SubscriptionId }} -Workspace ${{ parameters.WorkspaceName }} -SettingsFile ${{ parameters.ConnectorsFile }} | |
azurePowerShellVersion: LatestVersion | |
pwsh: true | |
- ${{ if ne(parameters.WorkbooksFolder, '')}}: | |
- task: AzurePowerShell@4 | |
displayName: 'Create and Update Workbooks' | |
inputs: | |
azureSubscription: ${{ parameters.azureSubscription }} | |
ScriptType: 'InlineScript' | |
Inline: | | |
$armTemplateFiles = Get-ChildItem -Path ${{ parameters.WorkbooksFolder }} -Filter *.json | |
$rg = Get-AzResourceGroup -ResourceGroupName ${{ parameters.ResourceGroupName }} -ErrorAction SilentlyContinue | |
if ($null -eq $rg) { | |
New-AzResourceGroup -ResourceGroupName ${{ parameters.ResourceGroupName }} -Location ${{ parameters.ResourceGroupLocation }} | |
} | |
foreach ($armTemplate in $armTemplateFiles) { | |
New-AzResourceGroupDeployment -ResourceGroupName ${{ parameters.ResourceGroupName }} -TemplateFile $armTemplate -WorkbookSourceId ${{ parameters.WorkbookSourceId }} | |
} | |
azurePowerShellVersion: LatestVersion | |
pwsh: true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment