Azure Conditional Access Policies as Code with Graph API, Part 3: Apply

In the third and final part of our Azure Conditional Access Policies as Code with Graph API series, we'll be covering the Apply phase of our policies.

You can check out the other parts from the links below:

We've been able to compare our local policy configuration changes with that of the remote and produced a plan of actions to take. Now we need to deploy said actions and push the local configuration to Azure. Below is a PowerShell script to help us do this.

PowerShell script:

The script to deploy the configuration changes is [here]

  • The script imports the graph token module and fetches the API token

  • Creates an array of properties to remove from the JSON configuration before making the API request

  • Checks each directory (new, remove, update) for any policy files created from the previous stage

  • If there are files in the directories, begin taking the appropriate action based on the directory the file is in

  • Sets variables for the Invoke-WebRequest cmdlet and removes read-only properties using the array previously created

  • The API request is then made and any errors are caught and logged

Pipeline:

Let's add the final stage to our pipeline and use this script within it

The full pipeline code can be found [here]

  - stage: Apply
    dependsOn: [Plan]
    condition: |
      and(
      succeeded('Plan'),
      eq(variables['isMain'], true),
      eq('${{ parameters.Action }}', 'Apply')
      )
    jobs:
    - deployment: apply
      environment: 'Production'
      strategy:
        runOnce:
          deploy:
            steps:
            - checkout: self
            - task: DownloadPipelineArtifact@2
              inputs:
                source: current
                path: '$(Build.SourcesDirectory)'
            - task: PowerShell@2
              displayName: 'apply policies'
              inputs:
                filePath: '$(Build.SourcesDirectory)/scripts/apply-conditional-access-policies.ps1'
                arguments: '-clientID $(clientID) -clientSecret $(clientSecret) -tenantID $(tenantID)'

I've included an approval gate in the pipeline as an added layer of security so an approver can review the plan prior to apply stage running.

There is a step to download the directories produced from the previous stage which is then used in the PowerShell script.

This stage has a dependency on Plan stage and it's required to be run off the main branch with the Apply parameter set.

Running the pipeline now has the below output:

Awesome, thanks for checking out this series and hope it was helpful on how you can manage your Azure Conditional Access Policies as Code with Graph API