Running cfn_nag on windows inside vscode

In an effort to move shift Security ‘further left’ in a software development lifecycle, testing for security misconfigurations is critical. Detecting these misconfigurations earlier reduces the amount of time and effort required to fix any issues downstream and increases the velocity and release cadence by removing the potential need to apply these fixes later.

Tools such as cfn_nag look for patterns in CloudFormation templates that may indicate insecure infrastructure. Providing tools to developers enables them to run these tests locally, identifying and resolving any findings before committing the Infrastructure-as-code to source control.

Running repeatable tests requires some additional work upfront.

Step 1 – Install Windows Subsystem for Linux

cfn_nag runs on Ruby

Install Windows Subsystem for Linux. You can get more details in the Microsoft Documentation.

From an elevated PowerShell session run:

dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
wsl --list --online

Choose your Linux Distribution, in this example I choose Ubuntu 20.04 LTS. Install the distribution and update the install packages.

wsl --install -d Ubuntu-20.04
sudo apt update && upgrade -y
Step 2 – Install Ruby and cfn_-nag gem

Install Ruby using the package manager. once Ruby is installed you can install the cfn_nag Ruby gem

sudo apt install ruby -y
sudo gem install cfn-nag

We now have cfn_nag installed inside the WSL Ubuntu distribution and can run the cfn_nag_scan command line tool. Next we’ll add the newly added linux distro to the vscode integrated terminal.

Set 3 – Set up the new WSL distribution as a terminal in vscode

vscode does automatically detect the installed terminal we added in step 1, but I prefer to manually configure these terminals. Adding them manually provides more customisation options and this comes down to personal preference.

To add this new terminal configuration you can add these setting to your global vscode settings, or configure these at the project level.

We have two options for setiings, global and project level.

  • global settings are configured using File -> Preferences -> Settings, and opening the settings.json file.
  • per-project settings are configured using the .vscode/settings.json file in your workspace root

For this example I’ll add the new terminal to my project settings file. We are adding the settings below to “terminal.integrated.profiles.windows”. I have also declared this new profile as the default terminal for this project using “terminal.integrated.defaultProfile.windows”: “Ubuntu-20.04 (WSL)”.

{
    "terminal.integrated.profiles.windows": {
        "PowerShell": {
            "source": "PowerShell",
            "icon": "terminal-powershell"
        },
        "Command Prompt": {
            "path": [
                "${env:windir}\\Sysnative\\cmd.exe",
                "${env:windir}\\System32\\cmd.exe"
            ],
            "args": [],
            "icon": "terminal-cmd"
        },
        "Git Bash": {
            "source": "Git Bash"
        },
        "Ubuntu-20.04 (WSL)": {
            "path": "C:\\WINDOWS\\System32\\wsl.exe",
            "args": [
                "-d",
                "Ubuntu-20.04"
            ],
            "color": "terminal.ansiRed",
            "icon": "terminal-ubuntu",
            "overrideName": true
        }
    },
    "terminal.integrated.defaultProfile.windows": "Ubuntu-20.04 (WSL)"
}
Resulting vscode integrated terminal

Now we have Ubuntu, Ruby and cfn_nag available in vscode, how do we create a repeatable scan of our project files?

Step 4 -Set up a vscode Task to run cfn-nag using the new vscode terminal

Tasks in VS Code can be configured to run scripts and start processes so that many of these existing tools can be used from within VS Code without having to enter a command line or write new code. Workspace or folder specific tasks are configured from the tasks.json file in the .vscode folder for a workspace.

https://code.visualstudio.com/docs/editor/tasks

We add a Task to our project but adding the following in our .vscode/tasks.json file in the root of our project. The highlighted code block below runs the ‘cfn_nag_scan –input-path .‘ cli command in our ‘Ubuntu-20.04‘ integrated terminal.

"tasks": [
        {
            "label": "Run CF_nag",
            "command": "cfn_nag_scan --input-path .",
            "windows": {
                "options": {
                    "shell": {
                        "executable": "C:\\WINDOWS\\System32\\wsl.exe",
                        "args": [
                            "-d",
                            "Ubuntu-20.04"
                        ]
                    }
                }
            },
            "type": "shell",
            "presentation": {
                "group": "tests",
                "panel": "shared"
            }
        }
    ]

We can run our new task from Terminal -> Run Task, and selecting the task from the available options. This task will run the cfn_nad_scan cli command in your wsl-ubuntu integrated terminal.

Run the configured cfn_nag_scan cli command

Rich Carpenter

Richard is an Information Security Expert, focussed on the implementation and architecture of Digital Transformation and Public Cloud adoption at forward thinking organisations.