Terraform module for deploying a cheap yet stable vaultwarden (formerly bitwarden_rs) to AWS.
- Prerequisites
- Features
- How it works
- Usage
- TODO
- Contributions
- Requirements
- Providers
- Modules
- Resources
- Inputs
- Outputs
- Route53 hosted zone
- SMTP credentials
- EC2 key pair
- KMS key
- HTTPS using LetsEncrypt
- Backups to S3 (daily by default)
- fail2ban and logrotate
- Auto healing using an auto scaling group
- Saving cost using a spot instance
- By default, it uses
t2.microandt2.smallas instances, and it launches the cheapest one - Fixed source IP address by reattaching ENI
- Encrypted secrets using mozilla/sops
This module provisions the following resources:
- Auto Scaling Group with mixed instances policy
- Launch Template
- Elastic IP
- Elastic Network Interface
- Security Group
- IAM Role for ENI and EBS attachment and S3 for file operations
By default, an instance of the latest Amazon Linux 2 is launched. The instance will run init.sh to:
- Attach the ENI to
eth1 - Attach the EBS volume as
/dev/xvdfand mount it - Install and configure
docker,docker-compose,sops,fail2ban - Start
Bitwarden - Switch the default route to
eth1
The secrets are encrypted and stored in the env.enc file.
The file format is:
acme_email=email@example.com
signups_allowed=false
domain=bitwarden.example.com
smtp_host=smtp.gmail.com
smtp_port=587
smtp_ssl=true
smtp_username=username@gmail.com
smtp_password="V3ryStr0ngPa$sw0rd!"
enable_admin_page=true
admin_token=0YakKKYV01Qyz2Y3ynrJVYhw4fy1HtH+oCyVK8k3LhvnpawvkmUT/LZAibYJp3Eq
bucket=bitwarden-bucket
db_user=bitwarden
db_user_password=ChangeThisVeryStrongPassword
db_root_password=ReplaceThisEvenStrongerPasswordNOTE: I strongly advise NOT to enable the Admin Page, hence to remove
the lines containing enable_admin_page and admin_token. If you still want
to enable it, you should at least generate a 48 char long password.
$ openssl rand -base64 48Once the env.enc file is populated with the correct secrets it must be
encrypted. This file should never be left unencrypted.
$ SOPS_KMS_ARN="KMS_KEY_ARN" sops -e -i data/env.encreplace KMS_KEY_ARN with the ARN of the KMS you want to use
provider "aws" {
region = "eu-west-1"
}
data "local_file" "this" {
filename = "${path.module}/env.enc"
}
data "aws_kms_key" "this" {
key_id = "alias/bitwarden-sops-encryption-key-prod"
}
module "bitwarden" {
source = "../"
name = "bitwarden"
domain = "bitwarden.example.org"
environment = "prod"
route53_zone = "example.org."
ssh_cidr = ["212.178.73.60/32"]
env_file = data.local_file.this.content
instance_types = ["t2.micro", "t2.small", "t2.medium", "t2.large"]
}Add a restore scriptManage dependencies with renovate-botImplement a retry mechanism when attaching ENI and EBSDetect if the EBS volume has been formatted or notAdd logrotate for Traefik logsCatch the spot instance termination event and trigger a backup- Verify that the application has properly launched by logging in as a dummy user
This is an open source software. Feel free to open issues and pull requests.
| Name | Version |
|---|---|
| terraform | >= 0.13.1 |
| aws | >= 3.56.0 |
| local | >= 1.4 |
| Name | Version |
|---|---|
| aws | >= 3.56.0 |
No modules.
| Name | Description | Type | Default | Required |
|---|---|---|---|---|
| additional_tags | Additional tags to apply to resources created with this module | map(string) |
{} |
no |
| backup_schedule | A cron expression to describe how often your data is backed up | string |
"0 9 * * *" |
no |
| bucket_version_expiration_days | Specifies when noncurrent object versions expire | number |
30 |
no |
| domain | The domain name for the Bitwarden instance | string |
n/a | yes |
| env_file | The name of the default docker-compose encrypted env file | string |
n/a | yes |
| environment | The environment to deploy to | string |
n/a | yes |
| instance_types | Instance types in the Launch Template. The first instance in the list will have the | list(string) |
[ |
no |
| name | Name to be used as identifier | string |
"bitwarden" |
no |
| route53_zone | The zone in which the DNS record will be created | string |
n/a | yes |
| ssh_cidr | The IP ranges from where the SSH connections will be allowed | list(any) |
[] |
no |
| tags | Tags applied to resources created with this module | map(any) |
{} |
no |
| Name | Description |
|---|---|
| iam_role_name | The IAM role for the Bitwarden Instance |
| public_ip | The public IP address the Bitwarden instance will have |
| s3_bucket | The S3 bucket where the backups will be stored |
| s3_resources | The S3 bucket where all the resource files will be stored |
| sg_id | ID of the security group |
| url | The URL where the Bitwarden Instance can be accessed |
| volume_id | The volume ID |