Code Monkey home page Code Monkey logo

terraform-aws-wireguard's Introduction

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.

The module is "Terragrunt ready" & supports multi region deployment & values in yaml format. Please see example here: 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.

  • Install the WireGuard tools for your OS: https://www.wireguard.com/install/
  • Generate a key pair for each client
    • wg genkey | tee client1-privatekey | wg pubkey > client1-publickey
  • Generate a key pair for the server
    • wg genkey | tee server-privatekey | wg pubkey > server-publickey
  • Add each client's public key, along with the next available IP address to the wg_clients list. See Usage for details.

Variables

Variable Name Type Required Description
subnet_ids list Yes A list of subnets for the Autoscaling Group to use for launching instances. May be a single subnet, but it must be an element in a list.
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 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.
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.
asg_min_size integer Optional - default to 1 Number of VPN servers to permit minimum, only makes sense in loadbalanced scenario.
asg_desired_capacity integer Optional - default to 1 Number of VPN servers to maintain, only makes sense in loadbalanced scenario.
asg_max_size integer Optional - default to 1 Number of VPN servers to permit maximum, only makes sense in loadbalanced scenario.
instance_type string Optional - defaults to t2.micro Instance Size of VPN server.
wg_server_net cidr address and netmask Yes The server ip allocation and net - wg_clients entries MUST be in this netmask range.
wg_clients list Yes List of client objects with IP and public key. See Usage for details. See Examples for formatting.
wg_server_port integer Optional - defaults to 51820 Port to run wireguard service on, wireguard standard is 51820.
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.

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')
sed -i "s/WG_SERVER_PRIVATE_KEY/$ESCAPED_WG_SERVER_PRIVATE_KEY/g" values.yaml

terraform-aws-wireguard's People

Contributors

atrull avatar exolab avatar hlarsen avatar jmhale avatar marcmeszaros avatar sheeeng avatar vainkop avatar wheller avatar wpietri avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

terraform-aws-wireguard's Issues

Null prometheus server ip causes security group resource issue

If you don't specify a prometheus server IP in the module variables, you get an error provisioning the security group.

│ Error: Null value found in list
│ 
│   with module.wireguard.aws_security_group.sg_wireguard,
│   on .terraform/modules/wireguard/sg.tf line 1, in resource "aws_security_group" "sg_wireguard":
│    1: resource "aws_security_group" "sg_wireguard" {
│ 
│ Null values are not allowed for this attribute value.

Q: is the prometheus server a hard requirement? We don't use prometheus, can it be optional?

The use_eip variable description doesn't seem to match actual implementation

The description for use_eip in variables.tf:

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.

In the README there is a mention of eip_id with this description:

When 'use_eip' is enabled, specify the ID of the Elastic IP to which the VPN server will attach.

But the eip_id is never declared in variables.tf and thus never actually used inside main.tf.

By default use_eip = false but when you look at main.tf it will always create the elastic IP internally inside the module. There is no count = var.use_eip ? 1 : 0 as would be expected if the intent is to make it optional.

There is a discrepancy between the README/docs and that main.tf is actually doing.

Q: Is the used expected to create an elastic IP outside the module and pass it in or is the module responsible for managing the elastic IP when use_eip is set to true?

slashes in server private key

hi, if server private key contains slashes - sed will stop working, one way to avoid that is to use @ as delimiters or escape the replacement string

When use_ssm is off there is a template issue in user-data.txt

By default use_ssm = false. This causes template rendering to fail (in terraform v0.15.0+ at least).

│ Error: Error in function call
│ 
│   on .terraform/modules/wireguard/main.tf line 58, in resource "aws_launch_configuration" "wireguard_launch_config":
│   58:   user_data = templatefile("${path.module}/templates/user-data.txt", {
│   59:     wg_server_private_key              = var.use_ssm ? "AWS_SSM_PARAMETER" : var.wg_server_private_key,
│   60:     wg_server_private_key_aws_ssm_name = var.use_ssm ? aws_ssm_parameter.wireguard_server_private_key[0].name : null,
│   61:     wg_server_net                      = var.wg_server_net,
│   62:     wg_server_port                     = var.wg_server_port,
│   63:     peers                              = join("\n", data.template_file.wg_client_data_json.*.rendered),
│   64:     use_eip                            = var.use_eip ? "enabled" : "disabled",
│   65:     eip_id                             = aws_eip.wireguard.id,
│   66:     use_ssm                            = var.use_ssm ? "true" : "false",
│   67:     wg_server_interface                = var.wg_server_interface
│   68:   })
│     ├────────────────
│     │ aws_eip.wireguard.id is "eipalloc-2fb2cd18"
│     │ aws_ssm_parameter.wireguard_server_private_key is empty tuple
│     │ data.template_file.wg_client_data_json is tuple with 1 element
│     │ path.module is ".terraform/modules/wireguard"
│     │ var.use_eip is false
│     │ var.use_ssm is false
│     │ var.wg_server_interface is "eth0"
│     │ var.wg_server_net is "172.25.5.0/24"
│     │ var.wg_server_port is 51820
│     │ var.wg_server_private_key is "<redacted>"
│ 
│ Call to function "templatefile" failed:
│ .terraform/modules/wireguard/templates/user-data.txt:60,47-81: Invalid
│ template interpolation value; The expression result is null. Cannot include
│ a null value in a string template., and 1 other diagnostic(s).

Solution

Use empty string instead of null when passing in template variables even if the variable isn't actually used in the user-data script.

  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 : "",
    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,
    use_ssm                            = var.use_ssm ? "true" : "false",
    wg_server_interface                = var.wg_server_interface
  })

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.