Search code examples
azuregithub-actionsazure-bicepbicep

Azure Bicep structure for new project


So we are starting to work on a new project to deploy azure resources using github actions and Bicep. We already have some modules that are bein used for deploying multiple resources. Eventhub, comsos, webapp, function, storage account, etc. We also have different environments: dev, qa, stg, prd. So question would be wow should we structure the bicep code to deploy resources into the 4 different enviornments with a github actions flow? .

I was thinking to have an env folder and isnide: dev/dev.bicepparam, qa/qa.bicepparam...and so on for the other environments. How should I configure rest of infra code? Should I have different folder with name of resources and inside a main.bicep? For example:

env
 dev/dev.bicepparam
 qa/qa.bicepparam
 stg/stg.bicepparam
 prd/prd.bicepparam

storage-account/main.bicep --> calling storage module inside
webapp/main.bicep --> calling webapp module
functionapp/main.bicep  --> calling webapp module

.... ret of resources

If I for example want to deploy a webapp into dev environment how would that be?

I was thinking also that in github actions I can have input with the 4 environments and before running pipeline I can choose: [dev,qa,stg,prd] and deploy the new resource into dev RG.


Solution

  • I will keep the file structure as simple as possible. With a folder for required modules for a service, main.bicep and required parameter file for each environment.

    .
    ├── modules
    │   ├── storage-account.bicep
    │   ├── resource-group.bicep
    │   ├── webapp.bicep
    │   ├── functionapp.bicep
    │   └── cosmosdb.bicep
    ├── main.bicep
    └── env
        ├── dev.parameters.json
        ├── qa.parameters.json
        ├── stg.parameters.json
        └── prd.parameters.json
    

    main.bicep should contain the name of the service, with option passing the parameters to be added from the parameter file per environment.

    param storageAccountParams object
    //rest parameter expected
    
    var serviceName = 'prettyservice'
    
    module storageAccount 'modules/storage-account.bicep' = {
      name: '${serviceName}--storage-account'
      params: {
        storageAccount: storageAccountParams
        /// other expected parameters for storage-account module
      }
    }
    
    // other resource definition referencing the modules like the storage account above
    

    then your parameter files for each environment: example dev.parameters.json

    using './main.bicep'
    
    param storageAccountParams = {
      name: "bvtprettystorweu"
      type: "Standard_LRS"
    /// other values for the object expected by the storage module
    }
    

    Don't use one single repository to host all infrastructure you manage, but rather one repository per application/service. For instance the above are infrastructure is related to one service 'prettyservice. This helps simplify management and often avoid breaking things.

    Your pipeline for deployment if targeting resource group will be such as pointing the the specific parameter for an environment.

    az deployment group create \
      --name $DEPLOYMENT_NAME \
      --resource-group $RESOURCE_GROUP \
      --template-file $TEMPLATE_FILE \
      --parameters @$PARAMETERS_FILE
    

    With this in place we are ready to deploy using GitHub action. Review the page: