Skip to content

Latest commit

 

History

History
265 lines (173 loc) · 13.2 KB

README.md

File metadata and controls

265 lines (173 loc) · 13.2 KB

Manage Azure Policy Action

With Manage Azure Policy Action you can now create or update Azure policies from your GitHub Workflows. Since workflows are totally customizable, you can have a complete control over the sequence in which Azure policies are rolled out. Its now even easier to follow safe deployment practices and catch regressions or bugs well before policies are applied on critical resources.

New to Azure Policy? Its an Azure service that lets you enforce organizational standards and asses compliance at scale. To know more check out: Azure Policies - Overview

The definition of this Github Action is in action.yml

Pre-requisites:

  • Azure Login Action: Authenticate using Azure Login action. The Manage Azure Policy action assumes that Azure Login is done using an Azure service principal that has sufficient permissions to write policy on selected scopes. Once login is done, the next set of actions in the workflow can perform tasks such as creating policies or updating them. For more details on permissions, checkout 'Configure credentials for Azure login action' section in this page or alternatively you can refer the full documentation of Azure Login Action.
  • Azure Checkout Action: All policies files should be downloaded from the GitHub repository to the GitHub runner. You can use checkout action for doing so. Refer the 'End-to-End Sample Workflows' section in this page for examples.
  • Azure Policy files should be present in the following directory structure. You can also export policies from Azure portal. (Go to Definitions section in Azure Policy and Click on Export definitions button)
.
|
|- policies/  ____________________________ # Root folder for policies
|  |- <policy1_name>/  ___________________ # Subfolder for a policy
|     |- policy.json _____________________ # Policy definition
|     |- assign.<name1>.json _____________ # Assignment1 for the policy definition in this folder
|     |- assign.<name2>.json _____________ # Assignment2 for the policy definition in this folder
|     |- assign.<name3>.json _____________ # Assignment3 for the policy definition in this folder
|
|  |- <policy2_name>/  ___________________ # Subfolder for another policy
|     |- policy.json _____________________ # Policy definition
|     |- assign.<name1>.json _____________ # Assignment1 for the policy definition in this folder
|     |- assign.<name2>.json _____________ # Assignment2 for the policy definition in this folder
|     |- assign.<name3>.json _____________ # Assignment3 for the policy definition in this folder
|     |- assign.<name4>.json _____________ # Assignment4 for the policy definition in this folder
|     |- assign.<name5>.json _____________ # Assignment5 for the policy definition in this folder

Inputs for the Action

  • paths: mandatory. The path(s) to the directory that contains Azure policy files. The files present only in these directories will be considered by this action for updating policies in Azure. You can use wild card characters as mentioned * or ** for specifying sub folders in a path. For more details on the use of the wild cards check glob wildcard patterns. Note that a definition file should be named as 'policy.json' and assignment filenames should start with 'assign' keyword.
  • ignore-paths: Optional. These are the directory paths that will be ignored by the action. If you have a specific policy folder that is not ready to be applied yet, specify the path here. Note that ignore-paths has a higher precedence compared to paths parameter.
  • assignments: Optional. These are policy assignment files that would be considered by the action. This parameter is especially useful if you want to apply only those assignments that correspond to a specific environment for following a safe deployment practice. E.g. assign.AllowedVMSKUs-dev-rg.json. You can use wild card character '*' to match multiple file names. E.g. assign.*dev*.json. If this parameter is not specified, the action will consider all assignment files that are present in the directories mentioned in paths parameter.
  • mode: Optional. There are 2 modes for this action - incremental and complete. If not specified, the action will use incremental mode by default. In incremental mode, the action will compare already exisiting policy in azure with the contents of policy provided in repository file. It will apply the policy only if there is a mismatch. On the contrary, the complete mode will apply all the files present in the specified paths irrespective of whether or not repository policy file has been updated.

End-to-End Sample Workflows

Sample workflow to apply all policy file changes in a given directory to Azure Policy

# File: .github/workflows/workflow.yml

on: push

jobs:
  apply-azure-policy:    
    runs-on: ubuntu-latest
    steps:
    # Azure Login       
    - name: Login to Azure
      uses: azure/login@v1
      with:
        creds: ${{secrets.AZURE_CREDENTIALS}}

    - name: Checkout
      uses: actions/checkout@v2 

    - name: Create or Update Azure Policies
      uses: azure/manage-azure-policy@v0
      with:      
        paths:  |                  
          policies/**
        

The above workflow will apply policy files changees in policies/** (see pattern syntax) directory to Azure Policy.

Sample workflow to apply only a subset of assignments from a given directory to Azure Policy

# File: .github/workflows/workflow.yml

on: push

jobs:
  apply-azure-policy:    
    runs-on: ubuntu-latest
    steps:
    # Azure Login
    - name: Login to Azure
      uses: azure/login@v1
      with:
        creds: ${{secrets.AZURE_CREDENTIALS}}

    - name: Checkout
      uses: actions/checkout@v2 

    - name: Create or Update Azure Policies
      uses: azure/manage-azure-policy@v0
      with:      
        paths:  |                
          policies/**
        assignments:  |
          assign.*_testRG_*.json
        

The above workflow will apply policy files changes only in policies/** directory. For each directory, the action will first apply the definition and then assignments that have 'testRG' in their filename. This assignment field is especially useful for risk mitigation scenarios, where you first want to apply assignments corresponding to a specific environment like 'test'.

Sample workflow to apply policies at Management Group scope

# File: .github/workflows/workflow.yml

on: push

jobs:
  apply-azure-policy:    
    runs-on: ubuntu-latest
    steps:
    # Azure Login at management group scope requires allow-no-subscriptions to be set to true
    - name: Login to Azure
      uses: azure/login@v1
      with:
        creds: ${{secrets.AZURE_CREDENTIALS}}
        allow-no-subscriptions: true

    - name: Checkout
      uses: actions/checkout@v2 

    - name: Create or Update Azure Policies
      uses: azure/manage-azure-policy@v0
      with:      
        paths:  |                
          policies/**
        

For deploying policies or initiatives at a management group level, the azure login action should have input allow-no-subscriptions set to true.

Manage Azure Policy Action is supported for the Azure public cloud as well as Azure government clouds ('AzureUSGovernment' or 'AzureChinaCloud') and Azure Stack ('AzureStack') Hub. Before running this action, login to the respective Azure Cloud using Azure Login by setting appropriate value for the environment parameter.

Quickstart Video Tutorials:

  1. Export Azure Policy resources to GitHub Repository
  2. Deploy Azure Policies with GitHub workflows

Configure credentials for Azure login action:

With the Azure login Action, you can perform an Azure login using Azure service principal. The credentials of Azure Service Principal can be added as secrets in the GitHub repository and then used in the workflow. Follow the below steps to generate credentials and store in github.

  • Prerequisite: You should have installed Azure cli on your local machine to run the command or use the cloudshell in the Azure portal. To install Azure cli, follow Install Azure Cli. To use cloudshell, follow CloudShell Quickstart. After you have one of the above ready, follow these steps:

  • To create service principal that has access over subscription scope, run the below Azure CLI command and copy the output JSON object to your clipboard.

  
   az ad sp create-for-rbac --name "myApp" --role "Resource Policy Contributor"  \
                            --scopes /subscriptions/{subscription-id} \
                            --sdk-auth
                            
  # Replace {subscription-id} with the subscription identifiers
  
  # The command should output a JSON object similar to this:

  {
    "clientId": "<GUID>",
    "clientSecret": "<GUID>",
    "subscriptionId": "<GUID>",
    "tenantId": "<GUID>",
    (...)
  }
  
  • Alternatively, to create service principal that has access over atleast one management group scope, run the below Azure CLI command.
  
   az ad sp create-for-rbac --name "myApp" --role "Resource Policy Contributor"  \
                            --scopes  /providers/Microsoft.Management/managementGroups/{management-group-id} \

                            
  # Replace {management-group-name} with the management group identifier
  
  # The command should output a JSON object similar to this:

  {
    "appId": "<GUID>",
    "displayName": "<display-name>",
    "name": "<url>",
    "password": "<GUID>",
    "tenant": "<GUID>"
  }
  
  # copy the GUID values for appId, password and tenant from above JSON and replace them in the following JSON. Once replaced, copy the JSON to clipboard
   
  {
    "clientId": "<appId>",
    "clientSecret": "<password>",  
    "tenantId": "<tenant>"
  }
  
  
  
  • Define a 'New secret' under your GitHub repository settings -> 'Secrets' menu. Lets name it 'AZURE_CREDENTIALS'.
  • Paste the contents of the clipboard as the value of the above secret variable.
  • Use the secret variable in the Azure Login Action(Refer the End-to-End Sample Workflows section )

If needed, you can modify the Azure CLI command to further reduce the scope for which permissions are provided. Here is the command that gives contributor access to only a resource group.

  
   az ad sp create-for-rbac --name "myApp" --role "Resource Policy Contributor"  \
                            --scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group} \
                            --sdk-auth
                            
  # Replace {subscription-id}, {resource-group} with the subscription and resource group identifiers.
  

You can also provide permissions to multiple scopes using the Azure CLI command:

  
   az ad sp create-for-rbac --name "myApp" --role "Resource Policy Contributor"  \
                            --scopes /subscriptions/{subscription-id}/resourceGroups/{resource-group1} \
                            /subscriptions/{subscription-id}/resourceGroups/{resource-group2} \
                            --sdk-auth
                            
  # Replace {subscription-id}, {resource-group1}, {resource-group2} with the subscription and resource group identifiers.
  

Feedback

If you have any changes you’d like to see or suggestions for this action, we’d love your feedback ❤️ . Please feel free to raise a GitHub issue in this repository describing your suggestion. This would enable us to label and track it properly. You can do the same if you encounter a problem with the feature as well.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.