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

Optional prometheus #8

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
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
19 changes: 10 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# terraform-aws-wireguard

A Terraform module to deploy a WireGuard VPN server on AWS. It can also be used to run one or more servers behind a loadbalancer, for redundancy.
A Terraform module to deploy a WireGuard VPN server on AWS. It can also be used to run one or more servers behind a loadbalancer, for redundancy.

The module is "Terragrunt ready" & supports multi region deployment & values in yaml format. Please see example here: [example/](example/)
The module is "Terragrunt ready" & supports multi region deployment & values in yaml format. Please see example here: [example/](example/)

## Prerequisites
Before using this module, you'll need to generate a key pair for your server and client, which cloud-init will source and add to WireGuard's configuration.
Expand All @@ -21,9 +21,8 @@ Before using this module, you'll need to generate a key pair for your server and
|`ssh_key_id`|`string`|Yes|A SSH public key ID to add to the VPN instance.|
|`vpc_id`|`string`|Yes|The VPC ID in which Terraform will launch the resources.|
|`env`|`string`|Optional - defaults to `prod`|The name of environment for WireGuard. Used to differentiate multiple deployments.|
|`use_eip`|`bool`|Optional|Whether to attach an [Elastic IP](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) address to the VPN server. Useful for avoiding changing IPs.|
|`eip_id`|`string`|Optional|When `use_eip` is enabled, specify the ID of the Elastic IP to which the VPN server will attach.|
|`use_ssm`|`bool`|Optional|Use SSM Parameter Store for the VPN server Private Key.|
|`use_eip`|`bool`|Optional - defaults to `false`|Whether to create and attach an [Elastic IP](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/elastic-ip-addresses-eip.html) address to the VPN server. Useful for avoiding changing IPs.|
|`use_ssm`|`bool`|Optional - defaults to `false`|Use SSM Parameter Store for the VPN server Private Key.|
|`wg_server_private_key`|`string`|Yes - defaults to static value in `/etc/wireguard/wg0.conf`| Static value or The Parameter Store key to use for the VPN server Private Key.|
|`target_group_arns`|`string`|Optional|The Loadbalancer Target Group to which the vpn server ASG will attach.|
|`additional_security_group_ids`|`list`|Optional|Used to allow added access to reach the WG servers or allow loadbalancer health checks.|
Expand All @@ -37,10 +36,12 @@ Before using this module, you'll need to generate a key pair for your server and
|`wg_persistent_keepalive`|`integer`|Optional - defaults to `25`|Regularity of Keepalives, useful for NAT stability.|
|`ami_id`|`string`|Optional - defaults to the newest Ubuntu 20.04 AMI|AMI to use for the VPN server.|
|`wg_server_interface`|`string`|Optional - defaults to eth0|Server interface to route traffic to for installations forwarding traffic to private networks.|
|`use_route53`|`bool`|Optional|Create Route53 record for Wireguard server.|
|`route53_hosted_zone_id`|`string`|Optional - if use_route53 is not used.|Route53 Hosted zone ID for Wireguard server Route53 record.|
|`route53_record_name`|`string`|Optional - if use_route53 is not used.|Route53 Record Name for Wireguard server.|

|`use_route53`|`bool`|Optional - default to `false`|Create Route53 record for Wireguard server (requires `use_eip` to be `true`).|
|`route53_hosted_zone_id`|`string`|Optional - if `use_route53` is not used.|Route53 Hosted zone ID for Wireguard server Route53 record.|
|`route53_record_name`|`string`|Optional - if `use_route53` is not used.|Route53 Record Name for Wireguard server.|
|`use_prometheus`|`bool`|Optional - defaults to `false`.|Install and use the promethus node exporting tools.|
|`prometheus_server_ip`|`string`|Optional - defaults to `0.0.0.0/0`.|The CIDR block of the prometheus server.|

If the `wg_server_private_key` contains certain characters like slashes & etc then it needs additional pre-processing before entering it into `values.yaml`. Example:
```
export ESCAPED_WG_SERVER_PRIVATE_KEY=$(printf '%s\n' "$WG_SERVER_PRIVATE_KEY" | sed -e 's/[\/&]/\\&/g')
Expand Down
1 change: 1 addition & 0 deletions example/eu-central-1/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ route53_record_name: vpn.example.com
route53_geo:
policy:
- continent: EU
use_prometheus: true
prometheus_server_ip: 0.0.0.0/0
wg_server_net: 10.8.0.1/24
wg_server_private_key: YOUR_SERVER_PRIVATE_KEY_HERE
Expand Down
1 change: 1 addition & 0 deletions example/us-east-1/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ route53_record_name: vpn.example.com
route53_geo:
policy:
- continent: NA
use_prometheus: true
prometheus_server_ip: 0.0.0.0/0
wg_server_net: 10.8.0.1/24
wg_server_private_key: YOUR_SERVER_PRIVATE_KEY_HERE
Expand Down
11 changes: 7 additions & 4 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
resource "aws_eip" "wireguard" {
count = var.use_eip ? 1 : 0

vpc = true
tags = {
Name = "wireguard"
}
}

resource "aws_route53_record" "wireguard" {
count = var.use_route53 ? 1 : 0
count = var.use_route53 && var.use_eip ? 1 : 0
allow_overwrite = true
set_identifier = "wireguard-${var.region}"
zone_id = var.route53_hosted_zone_id
name = var.route53_record_name
type = "A"
ttl = "60"
records = [aws_eip.wireguard.public_ip]
records = [aws_eip.wireguard[0].public_ip]

dynamic "geolocation_routing_policy" {
for_each = try(length(var.route53_geo.policy) > 0 ? var.route53_geo.policy : tomap(false), {})
Expand Down Expand Up @@ -57,13 +59,14 @@ resource "aws_launch_configuration" "wireguard_launch_config" {
iam_instance_profile = (var.use_eip ? aws_iam_instance_profile.wireguard_profile[0].name : null)
user_data = templatefile("${path.module}/templates/user-data.txt", {
wg_server_private_key = var.use_ssm ? "AWS_SSM_PARAMETER" : var.wg_server_private_key,
wg_server_private_key_aws_ssm_name = var.use_ssm ? aws_ssm_parameter.wireguard_server_private_key[0].name : null,
wg_server_private_key_aws_ssm_name = var.use_ssm ? aws_ssm_parameter.wireguard_server_private_key[0].name : "",
wg_server_net = var.wg_server_net,
wg_server_port = var.wg_server_port,
peers = join("\n", data.template_file.wg_client_data_json.*.rendered),
use_eip = var.use_eip ? "enabled" : "disabled",
eip_id = aws_eip.wireguard.id,
eip_id = var.use_eip ? aws_eip.wireguard[0].id : "",
use_ssm = var.use_ssm ? "true" : "false",
use_prometheus = var.use_prometheus ? "true" : "false",
wg_server_interface = var.wg_server_interface
})
security_groups = [aws_security_group.sg_wireguard.id]
Expand Down
4 changes: 4 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output "eip_id" {
value = var.use_eip ? aws_eip.wireguard[0].id : null
description = "The elastic IP id (if `use_eip` is enabled)"
}
21 changes: 9 additions & 12 deletions sg.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,15 @@ resource "aws_security_group" "sg_wireguard" {
cidr_blocks = ["0.0.0.0/0"]
}

ingress {
from_port = 9586
to_port = 9586
protocol = "tcp"
cidr_blocks = [var.prometheus_server_ip]
}
dynamic "ingress" {
for_each = var.use_prometheus ? [9586, 9100] : []

ingress {
from_port = 9100
to_port = 9100
protocol = "tcp"
cidr_blocks = [var.prometheus_server_ip]
content {
from_port = ingress.value
to_port = ingress.value
protocol = "tcp"
cidr_blocks = [var.prometheus_server_ip]
}
}

egress {
Expand All @@ -44,4 +41,4 @@ resource "aws_security_group" "sg_wireguard" {
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
}
77 changes: 41 additions & 36 deletions templates/user-data.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,15 @@ do
sleep 1
done

# Install prometheus_wireguard_exporter
wget https://github.com/vainkop/terraform-aws-wireguard/releases/download/v1.3.0/prometheus_wireguard_exporter_v3.4.2.tar.gz && \
tar -zxvf prometheus_wireguard_exporter_v3.4.2.tar.gz prometheus_wireguard_exporter && \
rm -fv prometheus_wireguard_exporter_v3.4.2.tar.gz && \
mv prometheus_wireguard_exporter /usr/local/bin/prometheus_wireguard_exporter && \
chmod +x /usr/local/bin/prometheus_wireguard_exporter

cat <<EOF | tee /etc/systemd/system/prometheus_wireguard_exporter.service
if [[ "${use_prometheus}" == "true" ]]; then
# Install prometheus_wireguard_exporter
wget https://github.com/vainkop/terraform-aws-wireguard/releases/download/v1.3.0/prometheus_wireguard_exporter_v3.4.2.tar.gz && \
tar -zxvf prometheus_wireguard_exporter_v3.4.2.tar.gz prometheus_wireguard_exporter && \
rm -fv prometheus_wireguard_exporter_v3.4.2.tar.gz && \
mv prometheus_wireguard_exporter /usr/local/bin/prometheus_wireguard_exporter && \
chmod +x /usr/local/bin/prometheus_wireguard_exporter

cat <<EOF | tee /etc/systemd/system/prometheus_wireguard_exporter.service
[Unit]
Description=Prometheus WireGuard Exporter
Wants=network-online.target
Expand All @@ -96,25 +97,26 @@ ExecStart=/usr/local/bin/prometheus_wireguard_exporter -a -n /etc/wireguard/wg0.
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && \
systemctl start prometheus_wireguard_exporter.service && \
systemctl enable prometheus_wireguard_exporter.service

until systemctl is-active --quiet prometheus_wireguard_exporter.service
do
sleep 1
done

# Install node_exporter
useradd -rs /bin/false node_exporter && \
wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz && \
tar -zxvf node_exporter-1.1.2.linux-amd64.tar.gz node_exporter-1.1.2.linux-amd64/node_exporter && \
rm -fv node_exporter-1.1.2.linux-amd64.tar.gz && \
mv node_exporter-1.1.2.linux-amd64/node_exporter /usr/local/bin/node_exporter && \
chmod +x /usr/local/bin/node_exporter && \
chown node_exporter:node_exporter /usr/local/bin/node_exporter

cat <<EOF | tee /etc/systemd/system/node_exporter.service
systemctl daemon-reload && \
systemctl start prometheus_wireguard_exporter.service && \
systemctl enable prometheus_wireguard_exporter.service

until systemctl is-active --quiet prometheus_wireguard_exporter.service
do
sleep 1
done

# Install node_exporter
useradd -rs /bin/false node_exporter && \
wget https://github.com/prometheus/node_exporter/releases/download/v1.1.2/node_exporter-1.1.2.linux-amd64.tar.gz && \
tar -zxvf node_exporter-1.1.2.linux-amd64.tar.gz node_exporter-1.1.2.linux-amd64/node_exporter && \
rm -fv node_exporter-1.1.2.linux-amd64.tar.gz && \
mv node_exporter-1.1.2.linux-amd64/node_exporter /usr/local/bin/node_exporter && \
chmod +x /usr/local/bin/node_exporter && \
chown node_exporter:node_exporter /usr/local/bin/node_exporter

cat <<EOF | tee /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
Expand All @@ -130,17 +132,20 @@ ExecStart=/usr/local/bin/node_exporter --web.listen-address=":9100"
WantedBy=multi-user.target
EOF

systemctl daemon-reload && \
systemctl start node_exporter && \
systemctl enable node_exporter
systemctl daemon-reload && \
systemctl start node_exporter && \
systemctl enable node_exporter

until systemctl is-active --quiet node_exporter.service
do
sleep 1
done
until systemctl is-active --quiet node_exporter.service
do
sleep 1
done

# allow exporter through firewall
ufw allow 9586
ufw allow 9100
fi

ufw allow ssh
ufw allow ${wg_server_port}/udp
ufw allow 9586
ufw allow 9100
ufw --force enable
ufw --force enable
12 changes: 9 additions & 3 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ variable "wg_persistent_keepalive" {
variable "use_eip" {
type = bool
default = false
description = "Whether to enable Elastic IP switching code in user-data on wg server startup. If true, eip_id must also be set to the ID of the Elastic IP."
description = "Create and use an Elastic IP in user-data on wg server startup."
}

variable "use_ssm" {
Expand Down Expand Up @@ -94,10 +94,16 @@ variable "wg_server_interface" {
description = "The default interface to forward network traffic to."
}

variable "use_prometheus" {
type = bool
default = false
description = "Whether to setup and use prometheus node metrics export or not."
}

variable "prometheus_server_ip" {
type = string
default = null
description = "Prometheus server IP."
default = "0.0.0.0/0"
description = "Prometheus server CIDR block."
}

variable "use_route53" {
Expand Down
4 changes: 0 additions & 4 deletions versions.tf
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,3 @@ terraform {
}
}
}

provider "aws" {
region = var.region
}