add migrating vaultwarden blog article
This commit is contained in:
parent
ab98209fad
commit
dcf6c443b4
1 changed files with 172 additions and 0 deletions
172
content/blog/ansible/vaultwarden.md
Normal file
172
content/blog/ansible/vaultwarden.md
Normal file
|
@ -0,0 +1,172 @@
|
|||
---
|
||||
title: 'Migrating vaultwarden from nixos to Debian'
|
||||
description: 'How I am deploying vaultwarden with ansible'
|
||||
date: '2024-12-31'
|
||||
tags:
|
||||
- ansible
|
||||
- vaultwarden
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
I am migrating several services from a NixOS server (dalinar.adyxax.org) to a Debian server (lore.adyxax.org). Here is how I performed the operation for my self hosted [vaultwarden](https://github.com/dani-garcia/vaultwarden).
|
||||
|
||||
## Ansible role
|
||||
|
||||
### Meta
|
||||
|
||||
The `meta/main.yaml` contains the role dependencies:
|
||||
|
||||
``` yaml
|
||||
---
|
||||
dependencies:
|
||||
- role: 'borg'
|
||||
- role: 'nginx'
|
||||
- role: 'podman'
|
||||
- role: 'postgresql'
|
||||
```
|
||||
|
||||
### Tasks
|
||||
|
||||
The `tasks/main.yaml` just creates a data directory and fetches the admin secret token from a terraform state. All the heavy lifting is then done by calling other roles:
|
||||
|
||||
``` yaml
|
||||
---
|
||||
- name: 'Make vaultwarden data directory'
|
||||
file:
|
||||
path: '/srv/vaultwarden'
|
||||
owner: 'root'
|
||||
group: 'root'
|
||||
mode: '0750'
|
||||
state: 'directory'
|
||||
|
||||
- include_role:
|
||||
name: 'postgresql'
|
||||
tasks_from: 'database'
|
||||
vars:
|
||||
postgresql:
|
||||
name: 'vaultwarden'
|
||||
|
||||
- name: 'Load the tofu state to read the database encryption key'
|
||||
include_vars:
|
||||
file: '../tofu/04-apps/terraform.tfstate' # TODO use my http backend instead
|
||||
name: 'tofu_state_vaultwarden'
|
||||
|
||||
- set_fact:
|
||||
vaultwarden_argon2_token: "{{ tofu_state_vaultwarden | json_query(\"resources[?type=='random_password'&&name=='vaultwarden_argon2_token'].instances[0].attributes.result\") }}"
|
||||
|
||||
- include_role:
|
||||
name: 'podman'
|
||||
tasks_from: 'container'
|
||||
vars:
|
||||
container:
|
||||
name: 'vaultwarden'
|
||||
env_vars:
|
||||
- name: 'ADMIN_TOKEN'
|
||||
value: "'{{ vaultwarden_argon2_token[0] }}'"
|
||||
- name: 'DATABASE_MAX_CONNS'
|
||||
value: '2'
|
||||
- name: 'DATABASE_URL'
|
||||
value: 'postgres://vaultwarden:{{ ansible_local.postgresql_vaultwarden.password }}@10.88.0.1/vaultwarden?sslmode=disable'
|
||||
image: '{{ versions.vaultwarden.image }}:{{ versions.vaultwarden.tag }}'
|
||||
publishs:
|
||||
- container_port: '80'
|
||||
host_port: '8083'
|
||||
ip: '127.0.0.1'
|
||||
volumes:
|
||||
- dest: '/data'
|
||||
src: '/srv/vaultwarden'
|
||||
|
||||
- include_role:
|
||||
name: 'nginx'
|
||||
tasks_from: 'vhost'
|
||||
vars:
|
||||
vhost:
|
||||
name: 'vaultwarden'
|
||||
path: 'roles/vaultwarden/files/nginx-vhost.conf'
|
||||
|
||||
- include_role:
|
||||
name: 'borg'
|
||||
tasks_from: 'client'
|
||||
vars:
|
||||
client:
|
||||
jobs:
|
||||
- name: 'data'
|
||||
paths:
|
||||
- '/srv/vaultwarden'
|
||||
- name: 'postgres'
|
||||
command_to_pipe: "su - postgres -c '/usr/bin/pg_dump -b -c -C -d vaultwarden'"
|
||||
name: 'vaultwarden'
|
||||
server: '{{ vaultwarden.borg }}'
|
||||
```
|
||||
|
||||
### Files
|
||||
|
||||
There is only the nginx vhost file, fairly straightforward:
|
||||
|
||||
``` nginx
|
||||
###############################################################################
|
||||
# \_o< WARNING : This file is being managed by ansible! >o_/ #
|
||||
# ~~~~ ~~~~ #
|
||||
###############################################################################
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name pass.adyxax.org;
|
||||
location / {
|
||||
return 308 https://$server_name$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
server_name pass.adyxax.org;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8083;
|
||||
}
|
||||
ssl_certificate adyxax.org.fullchain;
|
||||
ssl_certificate_key adyxax.org.key;
|
||||
}
|
||||
```
|
||||
|
||||
## Migration process
|
||||
|
||||
The first step is to deploy this new configuration to the server:
|
||||
|
||||
``` shell
|
||||
make run limit=lore.adyxax.org tags=vaultwarden
|
||||
```
|
||||
|
||||
After that I manually backup the vaultwarden data with:
|
||||
|
||||
``` shell
|
||||
ssh root@dalinar.adyxax.org systemctl stop podman-vaultwarden
|
||||
ssh root@dalinar.adyxax.org /run/current-system/sw/bin/pg_dump -b -c -C -h localhost -U vaultwarden -d vaultwarden > /tmp/vaultwarden.sql
|
||||
ssh root@dalinar.adyxax.org tar czf /tmp/vaultwarden.tar.gz /srv/vaultwarden/
|
||||
```
|
||||
|
||||
I retrieve then migrate these backups with:
|
||||
``` shell
|
||||
scp root@dalinar.adyxax.org:/tmp/vaultwarden.{sql,tar.gz} .
|
||||
ssh root@dalinar.adyxax.org rm vaultwarden.{sql,tar.gz}
|
||||
scp vaultwarden.{sql,tar.gz} root@lore.adyxax.org:
|
||||
rm vaultwarden.{sql,tar.gz}
|
||||
```
|
||||
|
||||
On the new server, restoring the backup is done with:
|
||||
``` shell
|
||||
ssh root@lore.adyxax.org systemctl stop podman-vaultwarden
|
||||
ssh root@lore.adyxax.org "cat vaultwarden.sql | su - postgres -c 'psql'"
|
||||
ssh root@lore.adyxax.org tar -xzf vaultwarden.tar.gz -C /srv/vaultwarden/
|
||||
ssh root@lore.adyxax.org rm vaultwarden.{sql,tar.gz}
|
||||
ssh root@lore.adyxax.org systemctl start podman-vaultwarden
|
||||
```
|
||||
|
||||
I then test the new server by setting the record in my `/etc/hosts` file. Since it all works well, I rollback my change to `/etc/hosts` and update the DNS record using OpenTofu.
|
||||
|
||||
## Conclusion
|
||||
|
||||
I did all this in early October and performed several vaultwarden upgrades since then. It all works well!
|
Loading…
Add table
Reference in a new issue