Skip to content

Commit 89de262

Browse files
simonbMSSimone BertacciniAlexanderSehreriqua
authored
#763 wiki update for removal step (#833)
* #763 resource removal documentation * Minor fixes * helper folder Co-authored-by: Alexander Sehr <ASehr@hotmail.de> * Wave 1 comments integration * Add custom removal action * Move removal to pipeline section * Level 1 titles * Include subpages links * remove extension from link Co-authored-by: Alexander Sehr <ASehr@hotmail.de> * Point to dedicated page for details Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com> * Remove duplicate content Co-authored-by: Simone Bertaccini <simonb@microsoft.com> Co-authored-by: Alexander Sehr <ASehr@hotmail.de> Co-authored-by: Erika Gressi <56914614+eriqua@users.noreply.github.com>
1 parent c22abf9 commit 89de262

9 files changed

Lines changed: 82 additions & 10 deletions

docs/wiki/Home.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ If you're unfamiliar with Infrastructure as Code, or wonder how you can use the
2424
- [Bicep to ARM conversion script](./UtilitiesConversionScript)
2525
- [Pipelines](./Pipelines)
2626
- [Design](./PipelinesDesign)
27+
- [Parameter File Tokens](./ParameterFileTokens)
28+
- [Removal action](./PipelineRemovalAction)
2729
- [Usage](./PipelinesUsage)
2830
- [Contribution Guide](./ContributionGuide)
2931
- [Known Issues](./KnownIssues)

docs/wiki/ModulesDesign.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -499,9 +499,6 @@ While exceptions might be needed, the following guidance should be followed as m
499499
> name: '${deployment().name}-Table-${index}'
500500
> ```
501501
502-
503-
504-
505502
## Outputs
506503
507504
- Output names are in camelCase, i.e `storageAccountResourceId`

docs/wiki/PipelineRemovalAction.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Removal action
2+
3+
This section describes how the removal of resources deployed by a module is performed and how to modify the default behaviour if a specific module or resource type needs it.
4+
5+
---
6+
7+
### _Navigation_
8+
9+
- [Overview](#Overview)
10+
- [How it works](#how-it-works)
11+
- [Create a specialized removal procedure](#create-a-specialized-removal-procedure)
12+
13+
---
14+
15+
# Overview
16+
17+
The Removal action is triggered after the deployment completes. This is used for several reasons:
18+
- Make sure to keep the validation subscription cost as low as possible.
19+
- Enable testing of the full module deployment at every run.
20+
21+
The default removal procedure works fine for most of the modules created so far, so it's likely you won't have to change anything to make the module you're editing to be removed correctly after deployment.
22+
23+
# How it works
24+
25+
The removal process will remove all resources created during deployment. The list is identified by:
26+
27+
1. Recursively fetching the list of resource IDs created through your deployment (resources created by deployments created by the parent one will be fetched too)
28+
1. Ordering the list based on resource IDs segment count (ensures child resources are removed first. E.g. `storageAccount/blobServices` comes before `storageAccount` as it has one more segments delimited by `/`)
29+
1. Filtering out from the list any resource used as dependencies for different modules (e.g. the commonly used Log Analytics workspace)
30+
1. Moving specific resource types to the top of the list (if a certain order is required). For example `vWAN` requires its `Virtual Hubs` to be removed first, even though they are no child-resources.
31+
32+
After a resource is removed (this happens after each resource in the list), the script will execute, if defined, a **post removal operation**. This can be used for those resource types that requires a post processing, like purging a soft-deleted key vault.
33+
34+
The procedure is initiated by the script `/utilities/pipelines/resourceRemoval/Initialize-DeploymentRemoval.ps1`, run during deployment by:
35+
- (Azure DevOps) `/.azuredevops/pipelineTemplates/module.jobs.deploy.yml`
36+
- (GitHub) `/.github/actions/templates/validateModuleDeployment/action.yml`
37+
38+
It uses several helper scripts that can be found in the `/utilities/pipelines/resourceRemoval/helper` folder
39+
# Create a specialized removal procedure
40+
41+
You can define a custom removal procedure by:
42+
1. influencing the **order** in which resources are removed by prioritizing specific resource types
43+
> **Example** Removing a _Virtual WAN_ resource requires related resources to be deleted in a specific order
44+
1. defining a **custom removal action** to remove a resource of a _specific resource type_
45+
> **Example** A _Recovery Services Vault_ resource requires some protected items to be identified and removed beforehand
46+
1. defining a custom **post-removal action** to be run after removing a resource of a _specific resource type_
47+
> **Example** A _Key Vault_ resource needs to be purged when soft deletion is enforced
48+
49+
Those methods can be combined independently.
50+
51+
> **Important**: _custom_ and _post-removal_ actions will be executed when a resource of the type you specify is removed **regardless** of which deployment triggered the deployment. Make sure you do not assume the resource is in a particular state defined by your module.
52+
53+
To modify the resource types removal **order**:
54+
1. Open the `/utilities/pipelines/resourceRemoval/Initialize-DeploymentRemoval.ps1` file.
55+
1. Look for the following comment: `### CODE LOCATION: Add custom removal sequence here`
56+
1. Add a case value that matches your module name
57+
1. In the case block, update the `$removalSequence` variable value to accommodate your module requirements
58+
1. Remember to add the `break` statement.
59+
60+
To defina a **custom removal** action:
61+
1. Open the `/utilities/pipelines/resourceRemoval/helper/Invoke-ResourceRemoval.ps1` file.
62+
1. Look for the following comment: `### CODE LOCATION: Add custom removal action here`
63+
1. Add a case value that matches the resource type you want to modify the removal action for
64+
1. In the case block, define the resource-type-specific removal action
65+
66+
To add a **post-removal** step:
67+
1. Open the `/utilities/pipelines/resourceRemoval/helper/Invoke-ResourcePostRemoval.ps1` file.
68+
1. Look for the following comment: `### CODE LOCATION: Add custom post-removal operation here`
69+
1. Add a case value that matches the resource type you want to add a post-removal operation for
70+
1. In the case block, define the resource-type-specific post removal action

docs/wiki/PipelinesDesign.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ Note that, for the deployments we have to account for certain [prerequisites](#p
9393

9494
#### Removal
9595

96-
The removal phase is strongly coupled with the previous deployment phase. Fundamentally, we want to remove any test-deployed resource after its test concluded. If we would not, we would generate unnecessary costs and may temper with any subsequent test. Some resources may require a dedicated logic to be removed. This logic should be stored alongside the generally utilized removal script in the `.utilities/pipelines/resourceRemoval` folder and be referenced by the `Initialize-DeploymentRemoval.ps1` script that orchestrates the removal.
96+
The removal phase takes care of removing all resources deployed as part of the previous deployment phase. The reason is twofold: keeping validation subscriptions costs down and allow deployments from scratch at every run.
9797

98-
Most of the removal scripts rely on the deployment name used during the preceding deployment step. Based on this name in combination with the template file path, the removal script find the corresponding deployment and removes all contained resources.
98+
For additional details on how removal works please refer to the dedicated [Removal action](PipelineRemovalAction) page.
9999

100100
### Publish
101101

@@ -104,7 +104,7 @@ The publish phase concludes each module's pipeline. If all previous tests succee
104104
- _private bicep registry_
105105

106106
By the time of this writing, the publishing experience works as follows:
107-
1. A user can optionally specific a specific version in the module's pipeline file, or during runtime. If the user does not, a default version is used
107+
1. A user can optionally specify a version in the module's pipeline file, or during runtime. If the user does not, a default version is used
108108
1. No matter what publishing location we enabled, the corresponding logic will
109109
1. Fetch the latest version of this module in the target location (if available)
110110
1. Compare it with any specified custom version the user optionally provided

utilities/pipelines/resourceRemoval/Initialize-DeploymentRemoval.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ function Initialize-DeploymentRemoval {
7272
)
7373
break
7474
}
75+
### CODE LOCATION: Add custom removal sequence here
7576
}
7677

7778
# Invoke removal

utilities/pipelines/resourceRemoval/helper/Get-ResourceIdsOfDeployment.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ function Get-ResourceIdsOfDeploymentInner {
5151
'resourcegroup' {
5252
if (Get-AzResourceGroup -Name $resourceGroupName -ErrorAction 'SilentlyContinue') {
5353
[array]$deploymentTargets = (Get-AzResourceGroupDeploymentOperation -DeploymentName $name -ResourceGroupName $resourceGroupName).TargetResource | Where-Object { $_ -ne $null }
54-
foreach ($deployment in ($deploymentTargets | Where-Object { $_ -notmatch '/deployments/' } )) {
55-
Write-Verbose ('Found deployment [{0}]' -f $deployment) -Verbose
56-
[array]$resultSet += $deployment
54+
foreach ($resourceId in ($deploymentTargets | Where-Object { $_ -notmatch '/deployments/' } )) {
55+
Write-Verbose ('Found resource [{0}]' -f $resourceId) -Verbose
56+
[array]$resultSet += $resourceId
5757
}
5858
foreach ($deployment in ($deploymentTargets | Where-Object { $_ -match '/deployments/' } )) {
5959
$name = Split-Path $deployment -Leaf

utilities/pipelines/resourceRemoval/helper/Invoke-ResourcePostRemoval.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,6 @@ function Invoke-ResourcePostRemoval {
109109
# Undo a potential soft delete state change
110110
$null = Set-AzRecoveryServicesVaultProperty -VaultId $vaultId -SoftDeleteFeatureState $softDeleteStatus.TrimEnd('d')
111111
}
112+
### CODE LOCATION: Add custom post-removal operation here
112113
}
113114
}

utilities/pipelines/resourceRemoval/helper/Invoke-ResourceRemoval.ps1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ function Invoke-ResourceRemoval {
9595
# --------------
9696
$null = Remove-AzResource -ResourceId $resourceId -Force -ErrorAction 'Stop'
9797
}
98+
### CODE LOCATION: Add custom removal action here
9899
Default {
99100
$null = Remove-AzResource -ResourceId $resourceId -Force -ErrorAction 'Stop'
100101
}

utilities/pipelines/resourceRemoval/helper/Remove-Deployment.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Optional. The time to wait in between the search for resources via their remove
2222
Optional. The deployment name to use for the removal
2323
2424
.PARAMETER TemplateFilePath
25-
Optional. The path to the deployment file
25+
Mandatory. The path to the deployment file
2626
2727
.PARAMETER RemovalSequence
2828
Optional. The order of resource types to apply for deletion

0 commit comments

Comments
 (0)