A few weeks ago, I presented the Bicep-Deploy GitHub Action that could test and deploy Bicep templates and validate, deploy, and delete deploymentStacks. The first part was about Bicep templates, the second is for deploymentStack.
With DeploymentStack you can perform these operations with bicep-deploy
- Validate, to lint the code.
- Create, to create a stack at the Management Group, Subscription, or Resource Group level.
- Delete, to delete a stack.
To illustrate this post, I will use a simple resource group-level template, creating a network infrastructure (a VNET with its subnets, and a Network Security Group.
param location string = resourceGroup().location param vnetName string = 'mainVnet' var vnetTags object = { environment: 'production' owner: 'admin' } var nsgRules = [ { name: 'default-nsg' rules: [ { name: 'rule-deny-all' properties: { description: 'description' protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '*' sourceAddressPrefix: '*' destinationAddressPrefix: '*' access: 'Deny' priority: 3000 direction: 'Inbound' } } { name: 'rule-allow-rdp' properties: { description: 'description' protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '3389' sourceAddressPrefix: '*' destinationAddressPrefix: '*' access: 'Allow' priority: 150 direction: 'Inbound' } } { name: 'rule-allow-ssh' properties: { description: 'description' protocol: 'Tcp' sourcePortRange: '*' destinationPortRange: '22' sourceAddressPrefix: '*' destinationAddressPrefix: '*' access: 'Allow' priority: 110 direction: 'Inbound' } } ] } ] resource NetworkSecurityGroups 'Microsoft.Network/networkSecurityGroups@2024-07-01' = [for rule in nsgRules: { name: rule.name location: resourceGroup().location properties: { securityRules: rule.rules } }] resource virtualNetwork 'Microsoft.Network/virtualNetworks@2024-07-01' = { name: vnetName location: location properties: { addressSpace: { addressPrefixes: [ '10.0.0.0/16' ] } subnets: [ { name: 'Subnet-1' properties: { addressPrefix: '10.0.0.0/24' } } { name: 'Subnet-2' properties: { addressPrefix: '10.0.1.0/24' } } ] } } resource crutialSubnet 'Microsoft.Network/virtualNetworks/subnets@2024-07-01' = { name: 'crucial' parent: virtualNetwork properties: { addressPrefix: '10.0.2.0/24' } }
But first, let’s build the workflow. I will reuse the workflow from the first part for the connection.
name: Bicep-deploy stack demo on: push: branches: - main permissions: id-token: write contents: read jobs: Bicep-deploy-demo: name: Bicep-Deploy Stack runs-on: ubuntu-latest environment: DevTo-Demo steps: - name: Checkout uses: actions/checkout@v4 - name: login to Azure uses: azure/login@v2 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} enable-AzPSSession: true
Validating a deployment stack is similar to validating a Bicep code.
Before trying to validate a deploymentStack we need to make sure that the identity running the pipeline has the privilege to manage deploymentStack, including the deny settings; Azure Deployment Stack Contributor. Without this role, you will not be able to validate the stack.
- name: Validate deploymentStack Code in GitHub uses: azure/bicep-deploy@v2 with: type: deploymentStack operation: validate name: Validate-code scope: resourceGroup subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} resource-group-name: bicep-deploy template-file: ./Stack/vnet.bicep action-on-unmanage-resources: delete deny-settings-mode: denyWriteAndDelete
You will need to give the deploymentStack type, the operation, the scope (here at the resource group level), and what will happen to unmanaged resources (delete or detach) and deny settings (none, denyDelete or denyWriteAndDelete).
You can customize the validation by adding a bicepconfig.json file in the same directory. You can trigger an error if the validation finds unused variables or parameters. See
There is no whatif operation for deploymentStack to test what will be deployed, there are only two other operations create and delete.
The “Create” operation creates the deployment stack in the scope defined by the scope parameter (Management Group, Subscription, or resource group).
Here’s an example
- name: Validate deploymentStack Code in GitHub uses: azure/bicep-deploy@v2 with: type: deploymentStack operation: create name: create-stack scope: resourceGroup subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} resource-group-name: bicep-deploy template-file: ./Stack/vnet.bicep action-on-unmanage-resources: delete deny-settings-mode: denyWriteAndDelete
The same code we use to validate is used to deploy the Stack. In this example, the unmanaged resources are deleted, and users are not allowed to update or delete resources deployed by the stack. You can also use the deny-settings-excluded-actions to exclude action from the deny settings and deny-settings-excluded-principals to exclude a list of users/applications from the deny settings. Check this post for more details
Running the pipeline will create the deploymentStack create-stack.
The last operation that we can do with the bicep-deploy action. The delete operation is similar to the create operation. It takes the same parameters; you need to provide the name of the deployment, the scope, the template you used to deploy the stack (and parameters if any), the action-on-unmanage-resources and deny-settings-mode parameters (if you omit then you will have an error).
- name: Validate deploymentStack Code in GitHub uses: azure/bicep-deploy@v2 with: type: deploymentStack operation: delete name: create-stack scope: resourceGroup subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} resource-group-name: bicep-deploy template-file: ./Stack/vnet.bicep action-on-unmanage-resources: delete deny-settings-mode: denyWriteAndDelete
This will delete the deploymentStack object on the resource group and remove all resources associated with this stack.
Top comments (0)