Running inspec on Azure DevOps

InSpec is an open source audit and automated testing framework tool that can be used to check cloud infrastructure compliancy.

Running InSpec locally

In order to run inspec locally, you need the following:

  • InSpec installed
  • Terraform installed
  • An update to your inspec.yml file to include a reference to the InSpec Azure Resource Pack
  • An Azure service principal configured with Reader rights on your Azure subscription
  • A ~/.azure/credentials file defining your Azure service principal credentials

Note that the InSpec Azure Resource Pack suggests your service principal has Contributor rights on your subscription. However, given the principal of least privilege, it is better to start with Reader rights and increase if necessary.

To get started with InSpec, you can either clone an existing sample repository:

git clone https://github.com/learn-chef/auditd.git

or use the InSpec cli to create a new profile:

inspec init profile foo

In order to test against Azure, you can use the InSpec Azure Resource Pack. This requires both an update to your inspec.yml file, and your Azure service principal credentials within a file at ~/.azure/credentials.

Update your inspec.yml to add a reference to the InSpec Azure Resource Pack:

name: inspec-azure-demo
title: InSpec Azure Demo
maintainer: foo
copyright: foo
copyright_email: test@domain.com
license: Apache-2.0
summary: An InSpec Azure Profile Demo
version: 0.1.0
depends:
  - name: inspec-azure
    url: https://github.com/inspec/inspec-azure/archive/master.tar.gz
supports:
  platform: azure

To create the ~/.azure/credentials file, you can edit that file, for example if you use Visual Studio Code:

code ~/.azure/credentials

Within the file, enter the service principal credentials:

[<subscription_id>]
client_id = "<client_id>"
client_secret = "<client_secret>"
tenant_id = "<tenant_id>"

To login to Azure within PowerShell you can run:

az login --service-principal --username <client_id> --password <client_secret> --tenant <tenant_id>

To execute the InSpec tests within PowerShell run the following from your root InSpec project folder (that contains inspec.yml):

inspec exec . -t azure://

Running InSpec within Azure DevOps

To execute the InSpec tests within Azure DevOps, you can define the following build steps within your azure-pipelines.yml file:

# The following variables need defining in Azure DevOps:
# inspec.clientId
# inspec.clientSecret
# inspec.subscriptionId
# inspec.tenantId

pool:
  vmImage: "Ubuntu-16.04"

steps:
  - task: UseRubyVersion@0
    displayName: "Install Ruby"
    inputs:
      versionSpec: ">= 2.5"
      addToPath: true

  - script: gem install inspec
    displayName: "Install inspec"

  - task: Bash@3
    displayName: "Run inspec tests"
    inputs:
      targetType: inline
      script: |
        export AZURE_SUBSCRIPTION_ID="$(inspec.subscriptionId)"
        export AZURE_CLIENT_ID="$(inspec.clientId)"
        export AZURE_CLIENT_SECRET="$(inspec.clientSecret)"
        export AZURE_TENANT_ID="$(inspec.tenantId)"
        inspec exec . -t azure:// --reporter cli junit:testresults.xml html:report.html

  - task: PublishTestResults@2
    displayName: Publish inspec test results
    condition: succeededOrFailed()
    inputs:
      testResultsFiles: "**/testresults.xml"
      mergeTestResults: true

  - task: PublishBuildArtifacts@1
    displayName: Publish inspec HTML report
    condition: succeededOrFailed()
    inputs:
      pathtoPublish: "report.html"
      artifactName: "report"

These steps perform the following:

  • Install Ruby (required by InSpec)
  • Install InSpec via Ruby
  • Configure environment variables containing your Azure service principal credentials (export VAR=VALUE), these are required by the InSpec Azure Resource Pack
  • Execute the InSpec tests via inspec exec, here we pass in reporter parameters to output the test results in the CLI, as a JUnit XML file, and as an HTML file
  • Publish the JUnit XML test results to Azure DevOps (so that the tests show up in the Azure DevOps UI)
  • Create a build artefact containing the HTML report file

The test result publish and build artefact tasks are configured to run on a successful or failed build. This means that if an InSpec test fails, the build will fail, but the test results and report will still be generated.

To run the Azure DevOps build, you will need to define the following build variables for your service principal credentials:

  • inspec.clientId
  • inspec.clientSecret
  • inspec.subscriptionId
  • inspec.tenantId

This build process can be scheduled (currently not configurable within YAML) to run e.g. nightly, so that every night your Azure environment is tested for compliance.