Skip to content

tomdesair/DevOps-Toolkit

 
 

Repository files navigation

DevOps-Toolkit

This repository is a one-stop shop for Code Quality tools and Development Environment setup, specifically DevContainers. It offers a complete suite of DevContainer configurations, standardized scripts for Code Quality tools, and Azure DevOps pipeline templates.

📝 Related blog posts

  • 📈 Automatically Generate and Visualize Python Code Coverage in VSCode krijnvanderburg.github.io | medium
    Learn how I automated my Python code coverage in VSCode! Instantly visualize coverage data in the editor for faster, more efficient development.

  • 👮‍♂️ How to enforce Code Quality standards using CI/CD krijnvanderburg.github.io | medium
    Learn how to enforce code quality standards with CI/CD pipelines for tools like Ruff, ensuring consistency and security in your software development.

  • 🤖 DevContainers Mastered: Automating Manual Workflows with VSCode Tasks - Part 3/3 krijnvanderburg.github.io | medium
    Automate your local development workflows with VSCode tasks and DevContainers akin to CICD. Remove all manual forms testing, dependencies, and more!

  • 🛡️ DevContainers Improved: Integrating Code Quality Checks for Continuous Feedback - Part 2/3 krijnvanderburg.github.io | medium
    Improve your workflow with DevContainers! Integrate code quality checks in VSCode for real-time feedback and error-free code. Boost productivity now!

  • 👨‍💻 DevContainers Introduction: The Ideal Standardized Team Development Environment — Part 1/3 krijnvanderburg.github.io | medium
    Discover how DevContainers streamline team workflows, ensure consistent environments, and automate setups for faster development and easier onboarding.

  • 🚀 Distribute Tests with Pytest-Split for Faster CI/CD Execution krijnvanderburg.github.io | medium
    Speed up your CI/CD with pytest-split! Learn how to distribute tests across agents for faster execution in Azure Pipelines and other platforms.

Getting Started

Clone this repository and test its implementations, ensuring to respect the copyright and license. No additional configuration is required. Works only with VS code and Azure DevOps pipelines.

  1. Refer to the DevContainers section for setup instructions.
  2. Create an Azure pipeline using the provided azure-pipelines.yml file.

For a practical demonstration of these v1/templates in action, refer to the live pipeline example: https://krijnvdburg.visualstudio.com/public/_build?definitionId=11

DevContainer

  1. ctrl + shift + P or F1: Dev Containers: Build Container
  2. Select the respective Devcontainer. The .devcontainer folder contains subfolder for each monorepo product.
  3. Open VScode folder in Dev Container via either:
    • ctrl + shift + P : Dev Containers: Open Container
    • Click on remote window button, light blue in bottom-left corner of VScode.

Known limitations

https://code.visualstudio.com/docs/devcontainers/containers#_dev-containers-limitations

  • Windows container images are not supported.
  • Local proxy settings are not reused inside the container, which can prevent extensions from working unless the appropriate proxy information is configured (for example global HTTP_PROXY or HTTPS_PROXY environment variables with the appropriate proxy information).

WSL config

Dev containers use WSL2. This can use a lot of resources, limits can be defined in .wslconfig and placed in C:\Users\<username>\.wslconfig. See ./.devcontainer/.wslconfig for example config.

Code Quality tools

Sorted alphabetically (mostly). Recommended tool:

Ruff, Flake8, Pylance, Pylint, Mypy, Pyright, Bandit, Semgrep, Gitleaks, Trufflehog, Ossaudit, OWASP, Pytest, Pytest coverage, Sphinx.

Formatters

Linters

Type checker

  • Mypy Docs | Github | Pypi | VS Code Marketplace - Mypy is an optional static type checker for Python that aims to combine the benefits of dynamic (or "duck") typing and static typing. Mypy combines the expressive power and convenience of Python with a powerful type system and compile-time type checking. Mypy type checks standard Python programs; run them using any Python VM with basically no runtime overhead. Config file | AzDO pipeline | DevContainer config

  • Pyre Docs | Github | Pypi - Pyre is a performant type checker for Python compliant with PEP 484. Pyre can analyze codebases with millions of lines of code incrementally – providing instantaneous feedback to developers as they write code. You can try it out on examples in the Pyre Playground. Config file | AzDO pipeline

  • Pyright Docs | Github | Pypi | VS Code Marketplace - Pyright is a full-featured, standards-based static type checker for Python. It is designed for high performance and can be used with large Python source bases. Config file | AzDO pipeline

Scanner

  • Bandit Docs | Github | Pypi | VS Code Marketplace - Bandit is a tool designed to find common security issues in Python code. To do this, Bandit processes each file, builds an AST from it, and runs appropriate plugins against the AST nodes. Once Bandit has finished scanning all the files, it generates a report. Config file | AzDO pipeline | DevContainer config

  • Semgrep (free version, limited rules) Docs | Github | Pypi | VS Code Marketplace - Semgrep OSS is a fast, open-source, static analysis tool for searching code, finding bugs, and enforcing code standards at editor, commit, and CI time. (Poor CICD support, see AzDO template internal notes) Config file | AzDO pipeline

  • SonarQube (TODO) Docs | Github - Sonar's Clean Code solutions help developers deliver high-quality, efficient code standards that benefit the entire team or organization. Config file | AzDO pipeline

  • Vulture Github | Pypi - Vulture finds unused code in Python programs. This is useful for cleaning up and finding errors in large code bases. If you run Vulture on both your library and test suite you can find untested code.Config file | AzDO pipeline | DevContainer config

  • DevSkim Docs | Github | Download - DevSkim is a framework of IDE extensions and language analyzers that provide inline security analysis in the dev environment as the developer writes code. It has a flexible rule model that supports multiple programming languages. The goal is to notify the developer as they are introducing a security vulnerability in order to fix the issue at the point of introduction, and to help build awareness for the developer. [VS code extension has no option to load config file] Config file | AzDO pipeline | DevContainer config

Credentials scanner

  • Gitleaks Github - Gitleaks is a SAST tool for detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos. Gitleaks is an easy-to-use, all-in-one solution for detecting secrets, past or present, in your code. Config file | AzDO pipeline

  • Trufflehog Github - TruffleHog™ is a secrets scanning tool that digs deep into your code repositories to find secrets, passwords, and sensitive keys. Config file | AzDO pipeline

Dependency scanner

  • Ossaudit Github | Pypi - Ossaudit uses Sonatype OSS Index to audit Python packages for known vulnerabilities. Config file | AzDO pipeline

  • OWASP dependency-check Docs | Github | Pypi - Dependency-Check is a Software Composition Analysis (SCA) tool that attempts to detect publicly disclosed vulnerabilities contained within a project’s dependencies. It does this by determining if there is a Common Platform Enumeration (CPE) identifier for a given dependency. If found, it will generate a report linking to the associated CVE entries. Config file | AzDO pipeline

  • Safety (Paid tool, not implemented) Docs | Github | Pypi - Safety CLI is a Python dependency vulnerability scanner designed to enhance software supply chain security by detecting packages with known vulnerabilities and malicious packages in local development environments, CI/CD, and production systems. Safety CLI can be deployed in minutes and provides clear, actionable recommendations for remediation of detected vulnerabilities.

Testing

Dependency management

  • Poetry Docs | Github | Pypi - Poetry helps you declare, manage and install dependencies of Python projects, ensuring you have the right stack everywhere. AzDO pipeline

  • Pip Docs | Github | Pypi - pip is the package installer for Python. You can use pip to install packages from the Python Package Index and other indexes. AzDO pipeline

Packaging

  • Python Build Website | Docs | Pypi - A simple, correct Python packaging build frontend. AzDO pipeline

  • Twine Docs | Github | Pypi - Twine is a utility for publishing Python packages on PyPI. It provides build system independent uploads of source and binary distribution artifacts for both new and existing projects. AzDO pipeline

Profilers (TODO)

  • cProfile: Profiles Python code with cProfile. cProfile
  • py_spy: Profiles Python code with py-spy. py-spy
  • line_profiler: Profiles Python code with line_profiler. line_profiler
  • memory_profiler: Profiles memory usage of Python code with memory-profiler. memory-profiler
  • plop: Profiles Python code with Plop. Plop
  • vprof: Profiles Python code with vprof. vprof
  • yappi: Profiles Python code with Yappi. Yappi

Documentation

TODO

  • Docker Linter (TODO)
  • hadolint (TODO)
  • dockerlint (TODO)
  • dive (TODO)
  • docker-bench-security (TODO)
  • dockle (TODO)
  • snyk (TODO) Checks dependencies for vulnerabilities with Snyk. Snyk
  • scanner_anchore (TODO) Analyzes Docker images for vulnerabilities with Anchore. Anchore
  • trivy (TODO) A Simple and Comprehensive Vulnerability Scanner for Containers and other Artifacts, Suitable for CI. Trivy
  • clair (TODO) Vulnerability Static Analysis for Containers. Clair

DevContainers

DevContainers in Visual Studio Code provide a fully configured and isolated development environment inside a container. This allows you to maintain a consistent, reproducible, and platform-independent setup, which can be beneficial for teams.

  1. Install Docker: Ensure Docker is installed on your machine. You can download it from the official Docker website.

  2. Install the Remote - Containers extension in VS Code: This extension is necessary to work with DevContainers. You can install it from the VS Code marketplace.

  3. Configure your DevContainer: Create a .devcontainer directory in your project root. Inside this directory, you'll need a devcontainer.json file to configure your DevContainer, and optionally a Dockerfile to define the container itself.

    This implementation utilizes a docker-compose.yml file specified in the devcontainer.json. The Docker Compose process uses a local Dockerfile located in the .devcontainer directory, which installs all the necessary tools for development. Docker Compose is employed due to its ability to effortlessly add additional supporting containers as needed. This can include Spark nodes, Azurite, or Airflow, depending on your code's dependencies.

  4. Add the following lines to .gitattributes file in project root. This prevents git from thinking ALL files changed due to different line endings when opening devcontainer from windows machine.

    * text=auto
    *.sh text eol=lf
    *.conf text eol=lf
  5. Optional: Dev containers use WSL2. This can use a lot of resources, limits can be defined in .wslconfig and placed in C:\Users\<username>\.wslconfig. See ./.devcontainer/.wslconfig for example config.

    [wsl2]
    # Limits VM memory to use no more than 4 GB, this can be set as whole numbers using GB or MB
    memory=6GB 
    # Sets the VM to use two virtual processors
    processors=4
    # Sets amount of swap storage space to 8GB, default is 25% of available RAM
    swap=8GB
    # Disable (false) page reporting so WSL retains all allocated memory claimed from Windows and releases none back when free
    pageReporting=true
  6. Open your project in a DevContainer: With your project open in VS Code, press F1 to open the command palette, then select the "Remote-Containers: Reopen in Container" command. VS Code will build (if necessary) and start your DevContainer, then reopen your project inside it.

For more detailed information, refer to the official VS Code DevContainers documentation.

DevContainer VSCode Extensions

Ruff

Code formatter combining Black, isort, pylint and flake8 all together in one tool with near rules parity and extremely fast. Automatically runs on file save action for opened file.

Using Ruff in combination with said tools it replaces makes no sense unless ruff does not have certian specific rules implemented.

"extensions": [
    "charliermarsh.ruff"
],
"settings": {
    "[python]": {
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.fixAll": "explicit",
            "source.organizeImports": "explicit"
        },
        "editor.defaultFormatter": "charliermarsh.ruff"
    },
    "ruff.lint.args": [
        "--config=${workspaceFolder}/path/to/.ruff.toml"
    ],
    "ruff.format.args": [
        "--config=${workspaceFolder}/path/to/.ruff.toml"
    ],
},

Black

Code formatter of pep8. Automatically runs on file save action for opened file.

"extensions": [
    "ms-python.black-formatter"
],
"settings": {
    "[python]": {
        "editor.defaultFormatter": "ms-python.black-formatter",
        "editor.formatOnSave": true,
    },
    "black-formatter.args": [
        "--config",
        "${workspaceFolder}/path/to/.black"
    ],
    "black-formatter.cwd": "${workspaceFolder}",
    "black-formatter.enabled": true,
    "black-formatter.showNotification": "onError"
},

Isort

Import organizer of Pep8. Automatically runs on file save action for opened file. Press Alt+shift+O to manually run for currently open file.

"extensions": [
    "ms-python.isort"
],
"settings": {
    "[python]": {
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.organizeImports": "explicit"
        }
    },
    "isort.args": [
        "--settings-path",
        "${workspaceFolder}/path/to/.isort.cfg"
    ],
    "isort.serverEnabled": false,
    "isort.check": false,
    "isort.showNotification": "onError"
},

Pylint

Code formatter of Pep8 and more. Automatically runs on file save action for opened file. Shows its result in code UI and in the problems section of VScode integrated terminal.

"extensions": [
    "ms-python.pylint"
],
"settings": {

    "pylint.args": [
        "--rcfile",
        "${workspaceFolder}/path/to/.pylintrc"
    ],
    "pylint.cwd": "${workspaceFolder}",
    "pylint.enabled": true,
    "pylint.showNotification": "onError",
    "pylint.lintOnChange": true,
},

Flake8

Linter of Pep8 and more. Automatically runs on file save action for opened file. Shows its result in code UI and in the problems section of VScode integrated terminal.

"extensions": [
    "ms-python.flake8"
],
"settings": {
    "flake8.args": [
        "--config",
        "${workspaceFolder}/path/to/.flake8" 
    ],
    "flake8.cwd": "${workspaceFolder}",
    "flake8.showNotification": "onError",
    "flake8.enabled": true,
},

Bandit

Code scanner of vulnerabilities and code quality. Automatically runs on file save action for opened file. Shows its result in code UI and in the problems section of VScode integrated terminal.

"extensions": [
    "nwgh.bandit"
],
"settings": {
    "bandit.args": [
        "-c",
        "${workspaceFolder}/path/to/.bandit"
    ],
    "bandit.cwd": "${workspaceFolder}",
    "bandit.logLevel": "warning",
    "bandit.enabled": true,
    "bandit.showNotification": "onError"
},

DevSkim

Code scanner of vulnerabilities and code quality. Automatically runs on file save action for opened file. Shows its result in code UI and in the problems section of VScode integrated terminal.

Cannot find proper documentation on settings, cant find a way to use config file either. Personally I am not a fan of this tool and don't recommend it.

"extensions": [
    "ms-cst-e.vscode-devskim"
],
"settings": {},

Mypy

Type checker and type hinting. Automatically runs on file save action for opened file. Shows its result in code UI and in the problems section of VScode integrated terminal.

"extensions": [
    "ms-python.flake8"
],
"settings": {
    "flake8.args": [
        "--config",
        "${workspaceFolder}/path/to/.flake8"
    ],
    "flake8.cwd": "${workspaceFolder}",
    "flake8.showNotification": "onError",
    "flake8.enabled": true,
    // ...
},

Pytest

Automatically discovers unit tests and can run them via extension pytest tab.

"extensions": [],
"settings": {
    "python.testing.unittestEnabled": false,
    "python.testing.pytestEnabled": true,
    "python.testing.pytestArgs": [
        "-c",
        "${workspaceFolder}/path/to/pytest.ini"
    ],
    "python.languageServer": "Default",

Pylance

Code validator and type checker. Runs automatically for all files. Shows its result in the problems section of VScode integrated terminal.

"extensions": [
    "ms-python.vscode-pylance"
],
"settings": {
    "python.analysis.typeCheckingMode": "strict",
    "python.analysis.diagnosticMode": "workspace",
    "python.analysis.diagnosticSeverityOverrides": {
        "reportUnknownParameterType": false,
        "reportUnknownArgumentType": false,
        "reportUnknownVariableType": false,
        "reportUnknownMemberType": false,
        "reportMissingParameterType": false,
        "reportMissingTypeArgument": false,
        "reportGeneralTypeIssues": false
    },
    "python.analysis.completeFunctionParens": true,
    "python.analysis.inlayHints.variableType": true,
    "python.analysis.inlayHints.functionReturnTypes": true,
    "python.analysis.inlayHints.callArgumentName": true,
    "python.analysis.inlayHints.pytestParameters": true,
},

SonarLint

Code linter by SonarQube/SonarCloud. Runs automatically for files. Shows its results in the problems section of VScode integrated terminal.

Gives error popup when opening Json files: SonarLint failed to analyze JSON code: Node.js runtime version 18.17.0 or later is required. This devcontainer will not have a node.js configured simply because its a lot just for json files scanning for 1 extension. Just click 'do not show again' once.

"extensions": [
    "sonarsource.sonarlint-vscode"
],
"settings": {
    "sonarlint.rules": {},
    "sonarlint.testFilePattern": "**/tests/**,test_*.py, *_test.py",
    "sonarlint.disableTelemetry": true,
    "sonarlint.output.showAnalyzerLogs": true,
    // "sonarlint.connectedMode.project": {},
    // "sonarlint.connectedMode.connections.sonarqube": [
    //     {
    //         "connectionId": "",
    //         "serverUrl": "",
    //         "token": ""
    //     }
    // ],
    // "sonarlint.connectedMode.connections.sonarcloud": [],
},

Coverage Gutter

  1. Generate a code coverage. This can be automated by providing additional args in the pytest extension and by configuring a vscode task to run coverage on folder open.

    pytest ./ -s --cache-clear -c ./path/to/pytest.ini --cov ./ --cov-report xml:./coverage.xml --cov-config ./path/to/.coveragerc

    (requires pytest, pytest-cov)

  2. ctrl + shift + P: Coverage Gutter: Display Coverage. Or toggle Coverage Gutter: Watch, this will watch the coverage.xml for changes.

    Though this might give error pop-ups as it might try to read while coverage.xml is still being generated.

If no coverage.xml is generated then its likely an issue with .coveragerc.

VSCode tasks

Copyright

This work is copyright © 2024 by Krijn van der Burg. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. For the full license text, see the LICENSE file. For inquiries, contact Krijn van der Burg on linkedin.com/in/krijnvanderburg/.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Shell 61.9%
  • Python 26.9%
  • Dockerfile 7.2%
  • Batchfile 2.2%
  • Makefile 1.8%