This project is intended for use as a model to play with some more DevSecOps principles in a practical way.
This exercise will take you through setting up a simple DevSecOps pipeline for a Python project. The example Python project is a simple client that interacts with the OpenWeatherMap API. The project contains some limited tests.
In the course of this exercise, you will set up your own copy of the repo to build in TravisCI, using pytest to perform automated testing and coverage analysis, SonarCloud to perform security scanning and reporting, and Coveralls.io to provide coverage reporting.
After setting up the pipeline, there are some opportunities to improve the project's performance in the pipeline.
- Python 3.7+ (tested against 3.9)
- Python virtual environment module (I use
virtualenv
(pip3 install virtualenv
)) - Github account
- travis-ci.com account (https://travis-ci.com, sign in with your Github account, choose the free plan, don't add any projects yet)
- coveralls.io account (https://coveralls.io, sign in with your Github account, choose the free plan, don't add any projects yet)
- sonarcloud.io account (https://sonarcloud.io, sign in with your Github account, choose the free plan, don't add any projects yet)
- Fork the repo 'https://[email protected]/jeffgennari/lg23devsecops to your own Github account
- Go into your Github user settings
- Scroll down to select "Applications". You should see TravisCI and SonarCloud here.
- Click "Configure" for TravisCI.
- Under Repository Access, choose "Only select repositories", and select your fork of the 2023-devsecops-example repository from the drop-down.
- Read and click through any approval prompts.
- Click Save.
- You will be redirected to the TravisCI page to finish configuration. After a few moments, you should see the page refresh and your repository will be listed.
- Go back to Github Settings, and click again on "Applications" on the left bar.
- Click "Configure" for SonarCloud.
- Under Repository Access, choose "Only select repositories", and select your fork of the 2023-devsecops-example repository from the drop-down.
- Read and click through any approval prompts.
- Click Save.
- You will be redirected to the SonarCloud site to finish configuration. It is OK to click back to Github at this point.
- Clone your forked repository to your development machine.
- cd into the 2023-devsecops-example directory.
- Create a virtual environment for testing:
virtualenv -p python3 venv
- Activate the virtual environment:
. venv/bin/activate
orvenv\Scripts\activate
on Windows. - Install the Python requirements:
pip3 install -r requirements.txt
Run local tests: py.test --cov --cov-report=xml owm tests -vv
All tests should complete successfully.
This is not required, but if you would like to see the client in action,
you will need to sign up under the free plan for the OpenWeatherMap API.
Once you have signed up, get your API key, and paste it into a file in the
repository root named .apikey
. Once this is done, you should be able
to run test.py
to see the weather in Pittsburgh and at a nearby
location.
- Go to your SonarCloud.io account.
- Use the "+" menu at the top right to add a new project.
- You should see your repo listed here. Select it to import the project.
- When asked to choose your analysis method, pick "With Travis CI".
- Copy the "SONAR_TOKEN" key listed. We will use this in a future step.
- Click Next.
- Under "Edit your .travis.yml file," choose Other.
- Click "Continue." We will edit the .travis.yml file later.
- Copy the
sonar.projectKey
andsonar.organization
lines. We will use these in a future step. - Click your profile photo in the top right, then go to the Security tab.
- Create a token. The name does not matter. Copy the token. We will use this in a future step.
- Go to your TravisCI account.
- Select your 2023-devsecops-example repository.
- From the menu at the right, choose "Settngs".
- Under Environment Variables, enter a new variable named "SONAR_TOKEN", and paste in the security token you copied in step 5.
- Click "Add" to add the variable.
- In the repository directory, edit the
.travis.yml
file. This is the TravisCI configuration file. - Locate the "organization" value under "sonarcloud". It is set to "jwoytek" by default. Change this to the value of
sonar.organization
copied in step 9. - Save the
.travis.yml
file. - Edit the
sonar-project.properties
file. This is the SonarCloud configuration file. - Change the value of the
sonar.projectKey
andsonar.organization
to those copied in steap 9. - Save the
sonar-project.properties
file. - Go to your coveralls.io account.
- Click the "+" to add a repo.
- Locate your repo in the list and click the switch to "on". You may have to click "Sync Repos" if your repo does not appear.
TravisCI will build whenever a commit is pushed to your repo. You can also trigger a build manually from within TravisCI. Here, we are going to commit the changes to the TravisCI and SonarCloud files, which will trigger a build, and should execute all of the steps to test, scan, and report scan and coverage results if all went well.
Commit the two modified configuration files in your repo, and push them to github. This will trigger an automatic build cycle in TravisCI.
Go to your TravisCI account, and in the dashboard you should see a new job running.
Follow along in the log, and you should see TravisCI set up the the environment, execute the python tests, execute the SonarCloud scan, report the SonarCloud results, and then upload the coverage results to coveralls.io.
Once the build is complete and if it succeeds, you should see the build job logs in TravisCI, Github should show a green check on the project by the latest commit, SonarCloud.io should show a report on the project scan, and coveralls.io should show a report on code coverage from the tests.
Travis CI's free plan may still require you to enter personal information. Ïf you would like to try a different pipeline, GitHub Actions is configured for this project. GitHub Actions are composed of apps that you can find in a marketplace (https://github.com/marketplace). You compose these apps in the YML file within the .github/workflows/
directory. You can set a number of different triggers for GitHub Actions, such as on commit. For this project manual build are configured. using the file: .github/workflows/manual.yml
. This pipeline is run by pressing Actions > Run Workflow
from the repository page. You should inspect the manual.yml
file because it has a number of dependencies that must be satisfied. In particular, SonarCloud you to set a SONAR_TOKEN for the project. To set this token, do the following:
- In your GitHub repository, go to
Settings > Secrets > Actions
and create a new secret with the following details: - In the Name field, enter SONAR_TOKEN
- in the Value field, enter the hash that Jeff provides via the meeting chat.
When you run the workflow, you will see the SonarCloud analysis in SonarCloud (e.g. https://sonarcloud.io/summary/overall?id=jgennari-2023-devsecops-example). Simiarlly, you will see the Coveralls report in the Coveralls website (e.g. https://coveralls.io/github/jeffgennari/lg23devsecops). The specific URLs may change to reflect your account.
One of the nice things about GitHub actions is that we can see results for public repositories.
You should notice that the code is not 100% covered by tests. Use the reporting in coveralls.io to locate the code that is not covered by tests, and create tests such that coverage reaches 100%.
SonarCloud.io will show some "code smells", pointing out some things that could be improved in the code. Attempt to fix these inefficiencies.
Create a branch and made some modifications to the branch, then create a pull request. Observe the automatic testing and reporting that Github will show during the TravisCI pipeline run to assist in evaluating a pull request prior to merging.
As a second extension, install an additional security-related GitHub Action from the marketplace (https://github.com/marketplace?type=actions).
Credit to Jonathan Woytek for this exercise.