CI/CD Configuration | Twingate

CI/CD Configuration

Production Environments

The information in this article should be used as a guide only. If you are deploying this method into a production environment, we recommend that you also follow all security and configuration best practices.

Images and code samples in this guide may contain references to specific versions of software or container images that may not be the latest versions available. Please refer to the official documentation for that software or container image for the most up-to-date information.

To help you incorporate the Twingate Services and Clients in headless mode into your CI/CD pipelines, we’ve included some sample configurations in a public GitHub repository, which are included in our automated testing.

marketplace github action permalink Marketplace: GitHub Action

→ “Connect to Twingate” Action on GitHub Marketplace

We’ve published a simple GitHub Action to connect to Twingate that you can incorporate into any GitHub workflow.

The action will:

At the end of this process, your workflow will be connected to Twingate and be able to access the Resources assigned to the Service.

Example github-actions-demo.yaml file:

name: Twingate on GitHub Actions Demo
on: [push]
jobs:
  Twingate-GitHub-Actions:
    runs-on: ubuntu-latest
    steps:
      - name: Install Twingate
        run: |
          echo "deb [trusted=yes] https://packages.twingate.com/apt/ /" | sudo tee /etc/apt/sources.list.d/twingate.list
          sudo apt update -yq
          sudo apt install -yq twingate

- name: Setup and start Twingate
        env:
          TWINGATE_SERVICE_KEY: ${{ secrets.SERVICE_KEY }}
        run: |
          echo $TWINGATE_SERVICE_KEY | sudo twingate setup --headless=-
          sudo twingate start

- name: (optional) Twingate status
        run: twingate status

- name: (optional) Twingate logs
        run: journalctl -u twingate

- name: Access a secure resource
        env:
          TEST_URL: http://business.prod.beamreachinc.int/
        run: |
          echo Calling $TEST_URL 🚀
          curl -v $TEST_URL

- name: Access a public resource
        env:
          TEST_URL: https://www.twingate.com/
        run: |
          echo Calling $TEST_URL 🚀
          curl -v $TEST_URL

- run: echo "SUCCESS!!! 🤩 This job's status is ${{ job.status }}."

- name: Stop Twingate
        run: sudo twingate stop

example circleci permalink Example: CircleCI

We’ve included three steps to install & start, test, and then stop the Twingate Client in headless mode.

Example config.yaml file:

version: 2.1

jobs:
  headless_client:
    machine:
      image: ubuntu:jammy-20250530
    steps:
      - run:
          name: Start Twingate
          command: |
            # install
            sudo apt update -yq
            sudo apt install -yq ca-certificates
            echo "deb [trusted=yes] https://packages.twingate.com/apt/ /" | sudo tee /etc/apt/sources.list.d/twingate.list
            sudo apt update -yq
            sudo apt install -yq twingate
            # setup and start
            echo "$SERVICE_KEY" | base64 --decode | sudo twingate setup --headless=-
            sudo twingate start
            # collect logs
            sudo journalctl -u twingate --no-pager | tail -n 20
      - run:
          name: Test Access
          command: |
            # test protected resource
            curl -v -m 10 "$TEST_URL" > /dev/null
            # test public resource
            curl -v -m 10 http://twingate.com > /dev/null
      - run:
          name: Stop Twingate
          command: |
            # stop
            sudo twingate stop
            # test public resource after stop
            curl -v -m 10 http://twingate.com > /dev/null
workflows:
  test:
    jobs:
      - headless_client