Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#14 as an operator I can provision a bootrap vpn server via pipeline #15

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 26 additions & 19 deletions .github/workflows/add-vpn-user.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@ name: Add VPN User
on:
workflow_dispatch:
inputs:
wireguard_vpn_ip_address:
description: 'wireguard_vpn_ip_address'
ansible_vault_password:
description: 'ansible_vault_password'
required: true
default: '192.0.2.1'

ssh_username:
description: 'ssh_username'
required: true
default: 'root'

PSONO_SECRET_ID:
description: 'PSONO_SECRET_ID'
Expand All @@ -23,21 +17,34 @@ jobs:

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Setting up SSH key
uses: webfactory/[email protected]
with:
ssh-private-key: ${{ secrets.VPN_SSH_PRIVATE_KEY }}
uses: actions/checkout@v4

- name: SSH into remote host
- name: Setup ansible
run: |
ssh -o StrictHostKeyChecking=no ${{ inputs.ssh_username }}@${{ inputs.wireguard_vpn_ip_address }} "date"
pip3 install ansible
ansible-galaxy collection install --requirements-file ./src/vpn/requirements.yml

- name: Generate new vpn peer config & Add save client config to password manager
run: |
ssh -o StrictHostKeyChecking=no ${{ inputs.ssh_username }}@${{ inputs.wireguard_vpn_ip_address }} -C "cd /etc/wireguard && PSONO_CI_API_KEY_ID=${{ secrets.PSONO_CI_API_KEY_ID }} PSONO_CI_API_SECRET_KEY_HEX=${{ secrets.PSONO_CI_API_SECRET_KEY_HEX }} PSONO_CI_SERVER_URL=${{ secrets.PSONO_CI_SERVER_URL }} PSONO_SECRET_ID=${{ inputs.PSONO_SECRET_ID }} ./add-vpn-user.sh"

- name: Run ansible
run: |
cd src/vpn
echo Creating ANSIBLE_VAULT_PASSWORD_FILE
TMPFILE=$(mktemp)
trap "rm -f ${TMPFILE@Q}" EXIT
echo -n "${{ inputs.ansible_vault_password }}" > $TMPFILE
export ANSIBLE_VAULT_PASSWORD_FILE=$TMPFILE

echo About to run playbook add-vpn-user.yml

# Bend over backwards to keep storing secrets in ansible vault rather than a specific CI/CD runner.
# note this uses dynamic inventory. Since you can't set/get group_vars from a dynamic inventory,
# this is an 'inventive' way using 'localhost' group_vars to the vpn hosts (in this case hetzer VM(s))
# api token out of ansible vault. The api token is stord in group_vars/localhost.yml (where in fact)
# the api token is used on other host groups.
# The dynamic vpn hosts inventory is using the dynamic inventory file inventory-vpn-servers-hcloud.yml

PSONO_SECRET_ID=${{ inputs.PSONO_SECRET_ID }} ansible-playbook --extra-vars _vault_hetzner_cloud_token=$(ANSIBLE_LOAD_CALLBACK_PLUGINS=1 ANSIBLE_STDOUT_CALLBACK=ansible.posix.json ansible localhost -i inventory.ini -m debug -a "msg={{ hostvars[inventory_hostname].hetzner_hcloud_token }}" | jq '.plays[0]["tasks"][0]["hosts"]["localhost"]["msg"]') -i inventory-vpn-servers-hcloud.yml playbooks/add-vpn-user.yml
rm $TMPFILE

# Enable tmate debugging of manually-triggered workflows if the input option was provided
- name: Setup tmate session
Expand Down
51 changes: 51 additions & 0 deletions .github/workflows/deploy-vpn-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Deploy VPN server(s)

on:
workflow_dispatch:
inputs:
ansible_vault_password:
description: 'ansible_vault_password'
required: true

jobs:
build:
runs-on: ubuntu-latest

steps:

- id: mask-ansible_vault_password
name: Mask ansible_vault_password
run: |
the_secret=${{ inputs.ansible_vault_password }}
echo "::add-mask::$the_secret"
echo "ansible_vault_password=$the_secret" >> "$GITHUB_OUTPUT"

- name: Verify ansible_vault_password mask
run: |
echo "the ansible_vault_password is ${{ steps.mask-ansible_vault_password.outputs.ansible_vault_password }}"

- name: Checkout code
uses: actions/checkout@v4

- name: Setup ansible
run: |
pip3 install ansible
ansible-galaxy collection install --requirements-file ./src/vpn/requirements.yml

- name: Run ansible
run: |
cd src/vpn
echo Creating ANSIBLE_VAULT_PASSWORD_FILE
TMPFILE=$(mktemp)
trap "rm -f ${TMPFILE@Q}" EXIT
echo -n "${{ inputs.ansible_vault_password }}" > $TMPFILE
export ANSIBLE_VAULT_PASSWORD_FILE=$TMPFILE

echo Run deploy vpn playbook
ansible-playbook -i inventory.ini -i inventory-vpn-servers-hcloud.yml playbooks/create-rebuild-vpn-server.yml
rm $TMPFILE

# Enable tmate debugging of manually-triggered workflows if the input option was provided
- name: Setup tmate session
uses: mxschmitt/action-tmate@v3
if: ${{ failure() }}
70 changes: 0 additions & 70 deletions .github/workflows/deploy-vpn.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/git-auto-issue-branch-creation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Get issue number and title
id: issue
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'ci skip') && !contains(github.event.head_commit.message, 'skip ci')"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- name: Prepare repository
run: git fetch --unshallow --tags
Expand Down
12 changes: 11 additions & 1 deletion vpn-client/README.md → src/vpn/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,18 @@ _*which you may not have a lot of control or say over the running of._
# Quickstart

### To re-deploy VPN server/client from scratch
```
python3 -m venv venv
source ./venv/bin/activate
pip install -r requirements.txt
ansible-galaxy collection install --force --collections-path ./ --requirements-file requirements.yml

# Run playbook to create/rebuild fresh vpn server
ansible-playbook -i inventory.ini --ask-vault-pass -i inventory-vpn-servers-hcloud.yml playbooks/create-rebuild-vpn-server.yml

```

1. Create Ubuntu server (Ubuntu 20.04 has been tested)
1. Run playbook to create Ubuntu server (Ubuntu 20.04 has been tested)
2. Run [Deploy VPN Client pipeline](https://github.com/KarmaComputing/server-bootstrap/actions/workflows/deploy-vpn.yml) to deploy IPsec and Wireguard tunnel

### To add a new user to VPN:
Expand Down
40 changes: 40 additions & 0 deletions src/vpn/group_vars/localhost.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
hetzner_hcloud_token: !vault |
$ANSIBLE_VAULT;1.1;AES256
36656132616562636233636561323834326638636239303662393033636234396634303434613534
3138636663323563663464643863376662353330363061370a613736303136376434366137636234
36656263643331663335353764613630313530363065323366343734323031366334643137303066
3562613265336537370a333131306362336464393762656238666262346438376362343866373932
35643639376231323736336438346262346137613866366133636232363333323065326365326232
37343634613861616566653037396566646465386439653133363361306639363233643064316462
38393735646365363465313663616264323233653230383837616263313735316135386165393935
38323439613635323738
server_bootstrap_public_ssh_key: |
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINJ1bghgIXT9CQu+stzt+XA+0U8kF7xruvL9Hhiij55A

server_bootstrap_private_ssh_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
64336662363563336435633939333333303634323337346237396533393334313435633139363363
6230666131326566333265366661323230666634383336610a633739663661386632633361336632
65343866343464656133333635303835623863343836663166323538366130313064316330646162
3038623438303630340a316163386161386637373334353836623230373830623637363363393930
36663366666239613862656331646536643464346563373135616531323063396464386564383631
65353735376637346530313530383264633135643263653961646637303831626238643466373465
63396238623230646535346333393336613461656332666632613330633830353134383234643633
65383230383133653534616536653238643639356262353431326439353735656361323730643830
32393736306161343666323238356630636465343065613165613031613736333730303765636134
35643466663761336533386634376131613034313131323762653965323165633432666165343363
37303034333061326130306566663438656332656436323832636630373863656265326263376163
66323662633762356238656263333839653331626564663733376464356436306436313739616238
36383633333664386661636338326235653265363332383039326138303839326639363466613334
35333635313761313839353665306436383434636232333831383662343830343136643064363765
63376638333031646165656163313963343634626433666334313935346338356630643666383134
30616630313034363565346438653264653462643661333930366138363638656265323237393434
38616131363136316237646136643366393037363639663264666266616264363039366235343637
30343534393633646336373536636339656135353262633134616231663030373964656137613533
34306134363833366564323436666233613662376337376436373338643266353933396164323963
61656431643461316637313638316235343436333230383334663137663534393063316365646363
39323963656631623165303664663634666536323436333965383762613837393065323866613564
62623930343230346561653466663536623031323738663263353564393333363766623164386637
39356661376132616264383133346331623134333932646132393264373461313438336330373237
30366431363238326530303161306534306264363630646236323632353233346430626136303534
3463
68 changes: 68 additions & 0 deletions src/vpn/group_vars/vpn_servers.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
vpn_server_ip: !vault |
$ANSIBLE_VAULT;1.1;AES256
38373966383732353136373535633264373038666161613839323965316237316665353363626335
3065613461373662376534633130343166306130396531650a386632366162323238366539613830
61616232386133633735346366393235636132373265323335366635393565393866666235393635
3838376266613236320a306363363531623537373532636434316334356530636664663934383232
3438
vpn_user: !vault |
$ANSIBLE_VAULT;1.1;AES256
62363862353138623164393733313666366263386338303861316338646530363862366262353230
3463373963363063653961356164613162353233366362330a633164373362333133316436643464
35656432613739333839393539633561356565313361643231633539393565333638663163366432
3638336236656561310a393934623061373534343662333830636338343761353736323735363562
64343732353539373738366233653530396437343331653339396462343534643536
vpn_pass: !vault |
$ANSIBLE_VAULT;1.1;AES256
30623264313461383163363235346563373331346261363362393362346131323737366661663932
3136383662363331336232396163613332343932313066640a323339346532313030396633633737
64343231353330336632336439666537386465363038323432363330303961633662336662336462
3633333461383534320a663664656664303133613833376262336366386630306332336339343132
3166
local_ip_gateway: !vault |
$ANSIBLE_VAULT;1.1;AES256
35396435306462313733313831363964626665643062366363643966636666613661663133663639
3232653633316532663336343863386463666139333764650a323737613637633531663563343166
34383861313737633834663535373339633538623136383936306463336531396462346236393666
3966363966626334370a356161646431383531316563303634633837646261363863376532346531
3538
pre_shared_key: !vault |
$ANSIBLE_VAULT;1.1;AES256
37326530303136656632636632376566316432333863333739396334613933326437313566336438
6133326233393762623966326337396530613935643431310a626137313765643965653938633330
66303765343136356335356465366636383864633737363834343035373265396132343734656363
6233633236643633650a623235313436646363326235366335623062626366343366383564663262
3136
PSONO_CI_API_KEY_ID: !vault |
$ANSIBLE_VAULT;1.1;AES256
33373631353266333337623231343734336665636166363066343464386135333261666636653836
6334333730323461316336333933376566626238636139350a633464613163343330313461316431
32613237663131363132313835316666613337616366336434376130613030306439353637313936
6163313961363539370a636538313834353863633932346534643962376633313139383962386539
64333236623331623763636639303735373865333633663334373031386330333739323431383462
6662323466356331656662613336633430373364383762623866
PSONO_CI_API_SECRET_KEY_HEX: !vault |
$ANSIBLE_VAULT;1.1;AES256
62613332393430643634626561613131373439383361366438373932353562333333303137386633
6565396466373063633433393835306561623562326331370a306664343665643764633264356333
37613437393763326336313332313262656364323936343138323237373331636137636461636235
3537343538376564300a306338616237653363356437666463323764653131643635656566383663
33326464313135396265663865666235393334386139366361643132373132333435333135333631
38613338333761396132666233653635363663646263646663353132626532346539346234636137
30306438653836623166393232333666653437316636346562386465333865656464616365393262
65366164326432646632
PSONO_CI_SERVER_URL: !vault |
$ANSIBLE_VAULT;1.1;AES256
38303337616639666337663835616439363566333562653466326534376336303665343731656466
3933353036316538333934363461373239346466366332360a373564336361303463393363376664
61613138636133346435353938323831653435343666613534343937363237636333313431346162
6131343833386163380a383330383861666636623662326437303933376636396661333332646237
30356337653463303662653036646132643063633163373464323235306338656339
ansible_user: !vault |
$ANSIBLE_VAULT;1.1;AES256
61623135363936396665323961303463353733633166306536653034366366323761316138313638
3832333831643664353032366233313938393132613863300a373266363637633431373362366230
36623833613830613938666161656534313534616639386230333232396435326335326264396164
3836383031353335660a303563643337346537646130653934373635646136373131313339636134
3434
ansible_ssh_private_key_file: ~/.ssh/id_ed25519_server_bootstrap
6 changes: 6 additions & 0 deletions src/vpn/inventory-vpn-servers-hcloud.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
plugin: hetzner.hcloud.hcloud
api_token: "{{ _vault_hetzner_cloud_token }}"
groups:
# Get only instances named 'vpn-server'
vpn_servers: name == 'vpn-server'

5 changes: 5 additions & 0 deletions src/vpn/inventory.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[vpn_servers]
changeme ansible_user=changeme

[localhost]
localhost ansible_connection=local
19 changes: 19 additions & 0 deletions src/vpn/playbooks/add-vpn-user.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
- name: Add a new VPN wireguard user & publish to psono via add-vpn-user.sh
hosts: "{{ vpn_servers | default('vpn_servers') }}"
become: yes
vars:
wireguard_dir: "/etc/wireguard/"

tasks:

# - name: Set PSONO_SECRET_ID from local (runner) environment
# ansible.builtin.set_fact: PSONO_SECRET_ID="{{ lookup('PSONO_SECRET_ID')}}"
# delegate_to: localhost

- name: Run add-vpn-user.sh
ansible.builtin.shell: "PSONO_CI_API_KEY_ID={{ PSONO_CI_API_KEY_ID }} PSONO_CI_API_SECRET_KEY_HEX={{ PSONO_CI_API_SECRET_KEY_HEX }} PSONO_CI_SERVER_URL={{ PSONO_CI_SERVER_URL }} PSONO_SECRET_ID={{ lookup('ansible.builtin.env', 'PSONO_SECRET_ID') }} {{ wireguard_dir }}add-vpn-user.sh"
args:
chdir: "{{ wireguard_dir }}"
tags: [ wireguard ]

Loading