Integrate with Azure DevOps Pipeline

You can integrate an Azure DevOps pipeline with Tenable Cloud Security to scan for violations and to break the pipeline if Tenable Cloud Security finds high severity violations in the code.

Before you begin:

Configure the following:

  • Azure Account to host the infrastructure provisioned by IaC

  • Azure DevOps Organization and Project to host one or more Azure DevOps pipelines and IaC repositories

  • Azure DevOps Pipeline

To integrate Azure DevOps Pipeline with Tenable Cloud Security:

  1. Log in to the Azure DevOps console.

  2. Open the Azure DevOps project and the IaC repository that you want to integrate with Tenable Cloud Security.

  3. From the root folder of the repository, open the YAML file for the pipeline, usually named azure-pipelines.yml, and add the following block of code in the script block under the steps parameter.

    With the plan command:

    Copy
    script: |
      export ARM_SUBSCRIPTION_ID=$(azSubID)
      export ARM_TENANT_ID=$(azTenantID)
      export ARM_CLIENT_ID=$(azClientID)
      export ARM_CLIENT_SECRET=$(azClientSecret)
      # Download Tenable Cloud Security CLI
      wget https://www.tenable.com/downloads/api/v2/pages/cloud-security/files/accurics-cli_latest_linux_x86_64.tar.gz -O tcs-iac-scanner
      chmod +x tcs-iac-scanner
      ./tcs-iac-scanner init
      ./tcs-iac-scanner plan -mode=pipeline -appurl=https://cloud.tenable.com/cns -token=<tcs_api_token> -fail -project=<project_id>

    With the scan command:

    Copy
    script: |
      export ARM_SUBSCRIPTION_ID=$(azSubID)
      export ARM_TENANT_ID=$(azTenantID)
      export ARM_CLIENT_ID=$(azClientID)
      export ARM_CLIENT_SECRET=$(azClientSecret)
      # Download Tenable CS CLI
      wget https://www.tenable.com/downloads/api/v2/pages/cloud-security/files/accurics-cli_latest_linux_x86_64.tar.gz -O tcs-iac-scanner
      chmod +x tcs-iac-scanner
      ./tcs-iac-scanner init
      ./tcs-iac-scanner scan -mode=pipeline -appurl=https://cloud.tenable.com/cns -token=<tcs_api_token> -fail -project=<project_id>

    where:

    • tcs_api_token: Specify the API token to authenticate with Tenable Cloud Security.

      For more information, see Generate API Tokens.

    • -fail: (Optional) Specify this parameter to fail the pipeline if Tenable Cloud Security finds a High severity policy failure.

    • project_id: (Optional) Specify the Tenable Cloud Security project ID to which you want to add the Azure DevOps pipeline repository.

      Note: If you do not specify the project, Tenable Cloud Security creates a default project called DEFAULT_AZURE for the repository.
Note: To use the CLI in the plan mode, ensure the required Azure credentials are available.

Example

Copy
trigger: 
  - main
        
pool:
  vmImage: ubuntu-latest

variables:
  - name: azSubID
    value: 5XXXXXXXX-XXX4-1XXX-XXX6-9XXXXXXXXXXXX
  - name: azTenantID
    value: 5XXXXXXXX-XXX4-1XXX-XXX6-9XXXXXXXXXXXX
  - name: azClientID
    value: 5XXXXXXXX-XXX4-1XXX-XXX6-9XXXXXXXXXXXX
  - name: azClientSecret
    value: 5XXXXXXXX-XXX4-1XXX-XXX6-9XXXXXXXXXXXX
  - name: tcsCLIVersion
    value: latest
  - name: tfVersion
    value: 1.0.11
  - name: tfPlanOutFilePrefix
    value: tfplan
  - name: tcsURL
    value: https://cloud.tenable.com/cns
  - name: apiToken
    value: bd91db85-f431-4b3e-93c4-ae3249047399
  - name: do_plan_or_scan
    value: plan

steps:
- task: CmdLine@2
  inputs:
    script: |
      export ARM_SUBSCRIPTION_ID=$(azSubID)
      export ARM_TENANT_ID=$(azTenantID)
      export ARM_CLIENT_ID=$(azClientID)
      export ARM_CLIENT_SECRET=$(azClientSecret)
      if [ $(do_plan_or_scan) == plan ]; then
        echo Installing terraform..
        sudo apt-get update && sudo apt-get install -y gnupg software-properties-common curl
        curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
        sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
        sudo apt-get update && sudo apt-get install terraform=$(tfVersion)
        curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
        terraform init
        echo ~~~~~GENERATING PLAN OUTPUT..
        terraform plan -out $(tfPlanOutFilePrefix)_$(Build.BuildNumber).out
        echo ~~~~~GENERATING PLAN JSON..
        terraform show -json $(tfPlanOutFilePrefix)_$(Build.BuildNumber).out > $(tfPlanOutFilePrefix)_$(Build.BuildNumber).json
      elif [ $(do_plan_or_scan) == scan ]; then
        echo Installing terrascan..
        curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E "https://.+?_Linux_x86_64.tar.gz")" > terrascan.tar.gz
        tar -xf terrascan.tar.gz terrascan && rm terrascan.tar.gz
        install terrascan /usr/local/bin && rm terrascan
      fi
      echo ~~~~~Downloading Tenable CS cli..
      wget https://www.tenable.com/downloads/api/v2/pages/cloud-security/files/accurics-cli_latest_linux_x86_64.tar.gz/$(tcsCLIVersion)/accurics -O tcs-iac-scanner
      chmod +x tcs-iac-scanner
      echo ~~~~~Getting Tenable CS cli verison..
      ./tcs-iac-scanner version
  displayName: 'Install T.CS dependencies'

- task: CmdLine@2
  inputs:
    script: |
      if [ $(do_plan_or_scan) == plan ]; then
        echo ~~~~~RUNNING Tenable CS assessment with pre-cooked plan..
        ./tcs-iac-scanner plan -mode=pipeline -appurl=$(tcsURL) -token=$(apiToken) -planjson=$(tfPlanOutFilePrefix)_$(Build.BuildNumber).json
      elif [ $(do_plan_or_scan) == scan ]; then
        echo ~~~~~RUNNING Tenable CS non plan based assessment..
        ./tcs-iac-scanner scan -mode=pipeline -appurl=$(tcsURL) -token=$(apiToken)
      fi
  displayName: 'Tenable CS Assessment - CLI'
  env:
    REPO_URL: $(Build.Repository.Uri)
    GIT_BRANCH: $(Build.SourceBranchName)
    GIT_COMMIT: $(Build.SourceVersion)

- task: CopyFiles@2
  inputs:
    Contents: |
      **/*.json
      **/*.html
      **/*.out
      **/*.tfstate
    TargetFolder: '$(Build.ArtifactStagingDirectory)'
  condition: always()
  
- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: $(Build.ArtifactStagingDirectory)
    artifactName: drop
  condition: always()

- task: DownloadBuildArtifacts@0
  inputs:
    buildType: 'current'
    downloadType: 'single'
    artifactName: 'drop'
    downloadPath: '$(System.ArtifactsDirectory)'
  condition: always()

In this example, Tenable Cloud Security creates a new project called DEFAULT_AZURE and publishes the scan results in that project.