How to use OpenVPN in GitHub Action workflows?

One of our clients requires a VPN connection to access their servers and we want to auto-deploy the app with a GitHub Action workflow. So let's dig in and fix it.

Prepare the .ovpn File

The approach involves separating credentials from configuration. Rather than committing credentials directly, external files are referenced in the .ovpn file:

  • Replace <ca>...</ca> with ca ca.crt (store content in CA_CRT secret)
  • Replace <cert>...</cert> with cert user.crt (store content in USER_CRT secret)
  • Replace <key>...</key> with key user.key (store content in USER_KEY secret)
  • Replace <tls-auth>...</tls-auth> with tls-auth tls.key (store content in TLS_KEY secret)

For authentication, add:

auth-user-pass secret.txt

Workflow Implementation

Step 1: Install OpenVPN

- name: Install OpenVPN
  run: |
    sudo apt-get update
    sudo apt-get --assume-yes --no-install-recommends install openvpn

Step 2: Setup VPN Config

- name: Setup VPN config
  run: |
    echo "${{ secrets.CA_CRT }}" > ca.crt
    echo "${{ secrets.USER_CRT }}" > user.crt
    echo "${{ secrets.USER_KEY }}" > user.key
    echo "${{ secrets.SECRET_USERNAME_PASSWORD }}" > secret.txt
    echo "${{ secrets.TLS_KEY }}" > tls.key

Step 3: Connect VPN

- name: Connect VPN
  run: sudo openvpn --config ".github/vpn/config.ovpn" --log "vpn.log" --daemon

The --daemon flag runs OpenVPN in the background. The --log flag captures output to a file.

Step 4: Wait for VPN Connection

- name: Wait for a VPN connection
  timeout-minutes: 1
  run: until ping -c1 your-server-address; do sleep 2; done

Step 5: Deploy

- name: Deploy
  run: some-command

Step 6: Cleanup

- name: Kill VPN connection
  if: always()
  run: |
    sudo chmod 777 vpn.log
    sudo killall openvpn

The if: always() condition ensures execution regardless of previous step outcomes.

Step 7: Upload Logs

- name: Upload VPN logs
  uses: actions/upload-artifact@v2
  if: always()
  with:
    name: VPN logs
    path: vpn.log

Makes VPN logs available as build artifacts for debugging.

Originally published on norday.tech.