Skip to content

lagebj/AzBuilder

Repository files navigation

AzBuilder

AzBuilder is a PowerShell module that enables you to manage your Azure infrastructure using a "Bring-Your-Own-ARM-Template" approach. It allows you to organize the template files in a folder hierarchy adapted to your business context. It is well suited to be used in CI/CD pipelines.

How it works

AzBuilder enumerates a folder structure and determines based on existing Azure environment and contents of the folder what to deploy.

The functions

Build-AzBuilderTemplate

This function prepares the ARM templates for deployment.

Invoke-AzBuilderDeployment

This function invokes the deployment of ARM templates.

Move-AzBuilderTemplate

This function moves successfully deployed ARM templates to a .deployments folder in the respective scope.

Folder structure

A folder structure is enumerated by AzBuilder and it interpretes the hierarchy based on how the folder structure is set up. For AzBuilder to be successful in interpreting the hierarchy, there are a couple of rules to follow:

  • Folders representing subscriptions must be named the same as the subscription ID it represents.
    • Example subscription folder name: b8701a61-1dad-42cc-92db-caa52415ca8c
  • Folders representing resource groups must have the resource group location in parenthesis in the folder name.
    • Example resource group folder name: rg-mgmt (westeurope)

AzBuilder interpretes the folder structure in the following manner:

  • The root folder is interpreted as the default Tenant Root Group.
  • Any folders containing a GUID is considered a subscription representation.
  • Any folder containing parenthesis is considered a resource group representation.

AzBuilder checks current Azure environment and verifies if management groups and resource groups exists. If management groups and/or resource groups defined in the hierarchy does not exist in Azure, these are automatically deployed without needing to add ARM templates for them.

Example folder structure

📦c:\temp\AzBuilder-root
┣ 📂azb
┃ ┣ 📂azb-decommissioned
┃ ┣ 📂azb-landingzones
┃ ┃ ┣ 📂azb-corp
┃ ┃ ┃ ┗ 📂b6d0fd4f-30b4-4cc4-88dd-39d84c5d881a
┃ ┃ ┃ ┃ ┗ 📂rg-app (westeurope)
┃ ┃ ┗ 📂azb-online
┃ ┣ 📂azb-platform
┃ ┃ ┣ 📂azb-connectivity
┃ ┃ ┣ 📂azb-identity
┃ ┃ ┗ 📂azb-management
┃ ┃ ┃ ┣ 📂1fb67e23-8f99-41e9-99bf-33236d129fba
┃ ┃ ┃ ┃ ┣ 📂rg-mgmt (northeurope)
┃ ┃ ┃ ┃ ┃ ┣ 📜solution_AgentHealthAssessment.json
┃ ┃ ┃ ┃ ┃ ┗ 📜solution_AgentHealthAssessment.parameters.json
┃ ┃ ┃ ┣ 📜policyAssignment_Deploy-LogAnalytics.json
┃ ┃ ┃ ┣ 📜policyAssignment_Deploy-LogAnalytics.parameters.json
┃ ┃ ┃ ┣ 📜roleAssignment_Deploy-LogAnalytics.json
┃ ┃ ┃ ┗ 📜roleAssignment_Deploy-LogAnalytics.parameters.json
┃ ┣ 📂azb-sandboxes
┃ ┣ 📜policyDefinition_Deploy-ASC-Standard.json
┃ ┣ 📜policyDefinition_Deploy-ASC-Standard.parameters.json
┃ ┣ 📜policyDefinition_Deploy-LogAnalytics.json
┗ ┗ 📜policyDefinition_Deploy-LogAnalytics.parameters.json\

In the example above, the root folder is c:\temp\AzBuilder-root and is considered as Tenant Root Group. The folder azb is considered a management group and subfolders azb-decommissioned, azb-landingzones, azb-platform and azb-sandboxes are considered child management groups to azb.

Folders azb-corp and azb-online are considered child management groups to azb-landingzones and azb-connectivity, azb-identity and azb-management are considered child management groups to azb-platform.

Folders b6d0fd4f-30b4-4cc4-88dd-39d84c5d881a and 1fb67e23-8f99-41e9-99bf-33236d129fba represents two different subscriptions and are child subscriptions to azb-corp and azb-management respectively.

Folders rg-app (westeurope) and rg-mgmt (northeurope) represents resource groups in subscriptions b6d0fd4f-30b4-4cc4-88dd-39d84c5d881a and 1fb67e23-8f99-41e9-99bf-33236d129fba.

The ARM templates in the example will be provisioned at the scope they are represented in the hierarchy. That means that templates policyDefinition_Deploy-ASC-Standard.json and policyDefinition_Deploy-LogAnalytics.json will be deployed to management group azb. Template files policyAssignment_Deploy-LogAnalytics.json and roleAssignment_Deploy-LogAnalytics.json will be deployed to management group azb-management. Template solution_AgentHealthAssessment.json will be deployed to resource group rg-mgmt.

Excluded folder

AzBuilder excludes any folder named .deployments to make it easier to keep all your already deployed ARM templates without having to deploy all ARM templates every time or delete them. A .deployments folder can be created under every subfolder to make it easier to keep track of which ARM templates have been deployed where.

If we take a look at the same folder structure as in the example above and add a .deployments folders where applicable it would look like below. In this example all ARM templates will be skipped because they are located in a .deployments folder. AzBuilder provides the function Move-AzBuilderTemplate to automatically move any ARM templates that have been successfully deployed to their respective .deployments folder.

📦c:\temp\AzBuilder-root
┣ 📂azb
┃ ┣ 📂.deployments
┃ ┃ ┣ 📜policyDefinition_Deploy-ASC-Standard.json
┃ ┃ ┣ 📜policyDefinition_Deploy-ASC-Standard.parameters.json
┃ ┃ ┣ 📜policyDefinition_Deploy-LogAnalytics.json
┃ ┃ ┗ 📜policyDefinition_Deploy-LogAnalytics.parameters.json
┃ ┣ 📂azb-decommissioned
┃ ┣ 📂azb-landingzones
┃ ┃ ┣ 📂azb-corp
┃ ┃ ┃ ┗ 📂b6d0fd4f-30b4-4cc4-88dd-39d84c5d881a
┃ ┃ ┃ ┃ ┗ 📂rg-app (westeurope)
┃ ┃ ┗ 📂azb-online
┃ ┣ 📂azb-platform
┃ ┃ ┣ 📂azb-connectivity
┃ ┃ ┣ 📂azb-identity
┃ ┃ ┗ 📂azb-management
┃ ┃ ┃ ┣ 📂1fb67e23-8f99-41e9-99bf-33236d129fba
┃ ┃ ┃ ┃ ┣ 📂.deployments
┃ ┃ ┃ ┃ ┃ ┣ 📜policyAssignment_Deploy-LogAnalytics.json
┃ ┃ ┃ ┃ ┃ ┣ 📜policyAssignment_Deploy-LogAnalytics.parameters.json
┃ ┃ ┃ ┃ ┃ ┣ 📜roleAssignment_Deploy-LogAnalytics.json
┃ ┃ ┃ ┃ ┃ ┗ 📜roleAssignment_Deploy-LogAnalytics.parameters.json
┃ ┃ ┃ ┃ ┣ 📂rg-mgmt (northeurope)
┃ ┃ ┃ ┃ ┃ ┣ 📂.deployments
┃ ┃ ┃ ┃ ┃ ┃ ┣ 📜solution_AgentHealthAssessment.json
┃ ┃ ┃ ┃ ┃ ┃ ┗ 📜solution_AgentHealthAssessment.parameters.json
┗ ┗ 📂azb-sandboxes\

ARM templates

AzBuilder parses all template files in the hierarchy and deploys them at their respective scope. It expects to have a parameters.json file accompanying all templates and skips any templates that does not have an accompanying parameters file. That means that you have to have a parameters file even thought your ARM template does not have any parameters, in that case the parameters file does not need to have any parameters specified either.

Dependencies

You can specify dependencies to resources that will be deployed at the same scope in the same operation by specifying the template file name without the .json extension.

If you need delays between deployments for some reason, you can specify a dependency named DeploymentDelay_<some integer>, where <some integer> is a number of your choice, iex: DeploymentDelay_20. When this is specified in a dependsOn block, an empty resource will be deployed the amount of times you specified in <some integer>. This can be useful if you encounter errors when another dependent resource has successfully been deployed, but it is not yet recognized in Azure.

Example

{
  "$schema": "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "managementGroupName": {
      "type": "string"
    }
  },
  "variables": {},
  "resources": [
    {
      "name": "[guid(concat(parameters('managementGroupName'), 'Deploy-LogAnalytics'))]",
      "type": "Microsoft.Authorization/roleAssignments",
      "apiVersion": "2020-04-01-preview",
      "dependsOn": [
        "policyAssignment_Deploy-LogAnalytics",
        "DeploymentDelay_20"
      ],
      "properties": {
        "principalType": "ServicePrincipal",
        "roleDefinitionId": "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635",
        "principalId": "[toLower(reference(extensionResourceId(tenantResourceId('Microsoft.Management/managementGroups', parameters('managementGroupName')), 'Microsoft.Authorization/policyAssignments', 'Deploy-LogAnalytics'), '2018-05-01', 'Full').identity.principalId)]"
      }
    }
  ]
}

Getting Started

Install from the PSGallery and import the module.

Install-Module AzBuilder
Import-Module AzBuilder

Limitations

There are some limitations when using AzBuilder for deployment. Any help on these are greatly appreciated, please feel free to contribute.

  • AzBuilder does not support creation of subscriptions. This means that subsciptions will have to be created by other means before AzBuilder can be used to deploy resources at subscription or resource group level.
  • AzBuilder does not support tagging of Resource Groups.
  • ARM Template can not contain a parameter named input.

More Information

For more information

This project was generated using Lage Berger Jensen's Plastered Plaster Template.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published