DEV Community

Cover image for Using bicep-deploy in GitHub action, part 2, deploymentStack
Olivier Miossec
Olivier Miossec

Posted on

Using bicep-deploy in GitHub action, part 2, deploymentStack

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'
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

This will delete the deploymentStack object on the resource group and remove all resources associated with this stack.

Warp.dev image

The best coding agent. Backed by benchmarks.

Warp outperforms every other coding agent on the market, and gives you full control over which model you use. Get started now for free, or upgrade and unlock 2.5x AI credits on Warp's paid plans.

Download Warp

Top comments (0)

Runner H image

Automate Your Workflow in Slack, Gmail, Notion & more

Runner H connects to your favorite tools and handles repetitive tasks for you. Save hours daily. Try it free while it’s in beta.

Try for Free

AWS GenAI LIVE!

GenAI LIVE! is a dynamic live-streamed show exploring how AWS and our partners are helping organizations unlock real value with generative AI.

Tune in to the full event

DEV is partnering to bring live events to the community. Join us or dismiss this billboard if you're not interested. ❤️