From 4c0d49e49fb3476c30268e317f6d41430c4379ff Mon Sep 17 00:00:00 2001 From: James Hale Date: Thu, 28 Feb 2019 09:43:38 -0500 Subject: [PATCH 1/9] Generate list of Peer blocks from variable --- main.tf | 12 +++++++++++- templates/client-data.json.tpl | 3 +++ templates/user-data.tpl | 4 +--- variables.tf | 17 +++++++++++++++++ wireguard-ssm.tf | 4 ---- 5 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 templates/client-data.json.tpl diff --git a/main.tf b/main.tf index 603309f..5480fdd 100644 --- a/main.tf +++ b/main.tf @@ -3,11 +3,21 @@ data "template_file" "user_data" { vars { wg_server_private_key = "${data.aws_ssm_parameter.wg_server_private_key.value}" - wg_laptop_public_key = "${data.aws_ssm_parameter.wg_laptop_public_key.value}" + peers = "${join(",", data.template_file.wg_client_data_json.*.rendered)}" eip_id = "${aws_eip.wireguard_eip.id}" } } +data "template_file" "wg_client_data_json" { + template = "${file("${path.module}/client-data.json.tpl")}" + count = "${length(var.wg_client_public_keys)}" + + vars { + client_pub_key = "${element(values(var.wg_client_public_keys[count.index]), 0)}" + client_ip = "${element(keys(var.wg_client_public_keys[count.index]), 0)}" + } +} + data "template_cloudinit_config" "config" { part { content_type = "text/cloud-config" diff --git a/templates/client-data.json.tpl b/templates/client-data.json.tpl new file mode 100644 index 0000000..c147ae8 --- /dev/null +++ b/templates/client-data.json.tpl @@ -0,0 +1,3 @@ +[Peer] +PublicKey = "${client_pub_key}" +AllowedIPs = "${client_ip}" diff --git a/templates/user-data.tpl b/templates/user-data.tpl index 955f320..6022ff7 100644 --- a/templates/user-data.tpl +++ b/templates/user-data.tpl @@ -17,9 +17,7 @@ write_files: PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE - [Peer] - PublicKey = ${wg_laptop_public_key} - AllowedIPs = 192.168.2.2/32 + ${peers} runcmd: - export INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id) - export REGION=$(curl -s http://169.254.169.254/latest/dynamic/instance-identity/document | grep -oP '\"region\"[[:space:]]*:[[:space:]]*\"\K[^\"]+') diff --git a/variables.tf b/variables.tf index ef10ae7..c459635 100644 --- a/variables.tf +++ b/variables.tf @@ -1,4 +1,5 @@ variable "ssh_key_id" {} + variable "vpc_id" {} variable "ami_id" { @@ -8,3 +9,19 @@ variable "ami_id" { variable "public_subnet_ids" { type = "list" } + +variable "wg_client_public_keys" { + type = "list" + + default = [ + { + "192.168.2.2/32" = "ABCDEFG" + }, + { + "192.168.2.3/32" = "ABCDEFG" + }, + { + "192.168.2.4/32" = "ABCDEFG" + }, + ] +} diff --git a/wireguard-ssm.tf b/wireguard-ssm.tf index 9d435f3..40aac2b 100644 --- a/wireguard-ssm.tf +++ b/wireguard-ssm.tf @@ -1,7 +1,3 @@ data "aws_ssm_parameter" "wg_server_private_key" { name = "/wireguard/wg-server-private-key" } - -data "aws_ssm_parameter" "wg_laptop_public_key" { - name = "/wireguard/wg-laptop-public-key" -} From 1fe2019805a13e9f1f8d997c033b9ef4e31bed08 Mon Sep 17 00:00:00 2001 From: James Hale Date: Thu, 28 Feb 2019 09:43:46 -0500 Subject: [PATCH 2/9] Remove TODO comment --- wireguard-iam.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wireguard-iam.tf b/wireguard-iam.tf index 8cf953b..0028dc0 100644 --- a/wireguard-iam.tf +++ b/wireguard-iam.tf @@ -17,7 +17,7 @@ data "aws_iam_policy_document" "wireguard_policy_doc" { "ec2:AssociateAddress", ] - resources = ["*"] ## TODO: See if we can scope this to wireguard_eip + resources = ["*"] } } From 0a2937b0ccddfa371e8265566673873ce2d3f513 Mon Sep 17 00:00:00 2001 From: James Hale Date: Thu, 28 Feb 2019 09:45:36 -0500 Subject: [PATCH 3/9] Rename client-data template file --- templates/{client-data.json.tpl => client-data.tpl} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename templates/{client-data.json.tpl => client-data.tpl} (100%) diff --git a/templates/client-data.json.tpl b/templates/client-data.tpl similarity index 100% rename from templates/client-data.json.tpl rename to templates/client-data.tpl From 93dd50b89344713178ffdb9f5b775ba10f77b595 Mon Sep 17 00:00:00 2001 From: James Hale Date: Thu, 28 Feb 2019 09:45:49 -0500 Subject: [PATCH 4/9] Change join statement --- main.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.tf b/main.tf index 5480fdd..e3fb710 100644 --- a/main.tf +++ b/main.tf @@ -3,13 +3,13 @@ data "template_file" "user_data" { vars { wg_server_private_key = "${data.aws_ssm_parameter.wg_server_private_key.value}" - peers = "${join(",", data.template_file.wg_client_data_json.*.rendered)}" + peers = "${join("\n", data.template_file.wg_client_data_json.*.rendered)}" eip_id = "${aws_eip.wireguard_eip.id}" } } data "template_file" "wg_client_data_json" { - template = "${file("${path.module}/client-data.json.tpl")}" + template = "${file("${path.module}/client-data.tpl")}" count = "${length(var.wg_client_public_keys)}" vars { From 8aacf9f9678c8d2828963f1c6e275ad849f8f89f Mon Sep 17 00:00:00 2001 From: James Hale Date: Sat, 2 Mar 2019 10:59:24 -0400 Subject: [PATCH 5/9] Fix template path --- main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.tf b/main.tf index e3fb710..fbe9c46 100644 --- a/main.tf +++ b/main.tf @@ -9,7 +9,7 @@ data "template_file" "user_data" { } data "template_file" "wg_client_data_json" { - template = "${file("${path.module}/client-data.tpl")}" + template = "${file("${path.module}/templates/client-data.tpl")}" count = "${length(var.wg_client_public_keys)}" vars { From 857e2d4553f1ef3cb6de6ba6da82708b09c0d656 Mon Sep 17 00:00:00 2001 From: James Hale Date: Sat, 2 Mar 2019 10:59:48 -0400 Subject: [PATCH 6/9] Add env variable to support multiple deployments --- variables.tf | 4 ++++ wireguard-iam.tf | 6 +++--- wireguard-securitygroups.tf | 10 ++++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/variables.tf b/variables.tf index c459635..56a958d 100644 --- a/variables.tf +++ b/variables.tf @@ -25,3 +25,7 @@ variable "wg_client_public_keys" { }, ] } + +variable "env" { + default = "prod" +} diff --git a/wireguard-iam.tf b/wireguard-iam.tf index 0028dc0..3856c75 100644 --- a/wireguard-iam.tf +++ b/wireguard-iam.tf @@ -22,13 +22,13 @@ data "aws_iam_policy_document" "wireguard_policy_doc" { } resource "aws_iam_policy" "wireguard_policy" { - name = "tf-wireguard" + name = "tf-wireguard-${var.env}" description = "Terraform Managed. Allows Wireguard instance to attach EIP." policy = "${data.aws_iam_policy_document.wireguard_policy_doc.json}" } resource "aws_iam_role" "wireguard_role" { - name = "tf-wireguard" + name = "tf-wireguard-${var.env}" description = "Terraform Managed. Role to allow Wireguard instance to attach EIP." path = "/" assume_role_policy = "${data.aws_iam_policy_document.ec2_assume_role.json}" @@ -40,6 +40,6 @@ resource "aws_iam_role_policy_attachment" "wireguard_roleattach" { } resource "aws_iam_instance_profile" "wireguard_profile" { - name = "tf-wireguard" + name = "tf-wireguard-${var.env}" role = "${aws_iam_role.wireguard_role.name}" } diff --git a/wireguard-securitygroups.tf b/wireguard-securitygroups.tf index 1596845..b3dca27 100644 --- a/wireguard-securitygroups.tf +++ b/wireguard-securitygroups.tf @@ -1,12 +1,13 @@ resource "aws_security_group" "sg_wireguard_external" { - name = "wireguard-external" + name = "wireguard-${var.env}-external" description = "Terraform Managed. Allow Wireguard client traffic from internet." vpc_id = "${var.vpc_id}" tags { - Name = "wireguard-external" + Name = "wireguard-${var.env}-external" Project = "wireguard" tf-managed = "True" + env = "${var.env}" } ingress { @@ -25,14 +26,15 @@ resource "aws_security_group" "sg_wireguard_external" { } resource "aws_security_group" "sg_wireguard_admin" { - name = "wireguard-admin" + name = "wireguard-${var.env}-admin" description = "Terraform Managed. Allow admin traffic to internal resources from VPN" vpc_id = "${var.vpc_id}" tags { - Name = "wireguard-admin" + Name = "wireguard-${var.env}-admin" Project = "vpn" tf-managed = "True" + env = "${var.env}" } ingress { From e2f0663fdc9e7770753a9a90babf3ec33c1b5101 Mon Sep 17 00:00:00 2001 From: James Hale Date: Sat, 2 Mar 2019 11:15:02 -0400 Subject: [PATCH 7/9] Add env var to remaining resources and README --- README.md | 1 + main.tf | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a4a1e25..a9e3869 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Before using this module, you'll need to generate a key pair for your server and |`vpc_id`|`string`|Yes|The VPC ID in which Terraform will launch the resources.| |`ingress_security_group_id`|`string`|Yes|The ID of the Security Group to allow SSH access from.| |`ami_id`|`string`|No. Defaults to Ubuntu 16.04 AMI in us-east-1|The AMI ID to use.| +|`env`|`string`|No. Defaults "prod"|The environment for WireGuard| ## Usage ``` diff --git a/main.tf b/main.tf index fbe9c46..6077547 100644 --- a/main.tf +++ b/main.tf @@ -30,7 +30,7 @@ resource "aws_eip" "wireguard_eip" { } resource "aws_launch_configuration" "wireguard_launch_config" { - name_prefix = "wireguard-lc-" + name_prefix = "wireguard-${var.env}-lc-" image_id = "${var.ami_id}" instance_type = "t2.micro" key_name = "${var.ssh_key_id}" @@ -45,7 +45,7 @@ resource "aws_launch_configuration" "wireguard_launch_config" { } resource "aws_autoscaling_group" "wireguard_asg" { - name_prefix = "wireguard-asg-" + name_prefix = "wireguard-${var.env}-asg-" max_size = 1 min_size = 1 launch_configuration = "${aws_launch_configuration.wireguard_launch_config.name}" @@ -60,7 +60,7 @@ resource "aws_autoscaling_group" "wireguard_asg" { tags = [ { key = "Name" - value = "wireguard" + value = "wireguard-${var.env}" propagate_at_launch = true }, { From a20dd90ee9c5700b651d6f892127235c08233413 Mon Sep 17 00:00:00 2001 From: James Hale Date: Sat, 2 Mar 2019 11:17:00 -0400 Subject: [PATCH 8/9] Finish up fixing pub key variable --- README.md | 6 ++++++ templates/client-data.tpl | 6 +++--- variables.tf | 12 ------------ 3 files changed, 9 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index a9e3869..87a1afc 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ Before using this module, you'll need to generate a key pair for your server and |`ingress_security_group_id`|`string`|Yes|The ID of the Security Group to allow SSH access from.| |`ami_id`|`string`|No. Defaults to Ubuntu 16.04 AMI in us-east-1|The AMI ID to use.| |`env`|`string`|No. Defaults "prod"|The environment for WireGuard| +|`wg_client_public_keys`|`list`|Yes.|List of maps of client IPs and public keys. See Usage for details.| ## Usage ``` @@ -33,6 +34,11 @@ module "wireguard" { ssh_key_id = "ssh-key-id-0987654" vpc_id = "vpc-01234567" public_subnet_ids = ["subnet-01234567"] + wg_client_public_keys = [ + {"192.168.2.2/32" = "QFX/DXxUv56mleCJbfYyhN/KnLCrgp7Fq2fyVOk/FWU="}, + {"192.168.2.3/32" = "+IEmKgaapYosHeehKW8MCcU65Tf5e4aXIvXGdcUlI0Q="}, + {"192.168.2.4/32" = "WO0tKrpUWlqbl/xWv6riJIXipiMfAEKi51qvHFUU30E="}, + ] } ``` diff --git a/templates/client-data.tpl b/templates/client-data.tpl index c147ae8..de7c4c4 100644 --- a/templates/client-data.tpl +++ b/templates/client-data.tpl @@ -1,3 +1,3 @@ -[Peer] -PublicKey = "${client_pub_key}" -AllowedIPs = "${client_ip}" + [Peer] + PublicKey = ${client_pub_key} + AllowedIPs = ${client_ip} diff --git a/variables.tf b/variables.tf index 56a958d..312edd2 100644 --- a/variables.tf +++ b/variables.tf @@ -12,18 +12,6 @@ variable "public_subnet_ids" { variable "wg_client_public_keys" { type = "list" - - default = [ - { - "192.168.2.2/32" = "ABCDEFG" - }, - { - "192.168.2.3/32" = "ABCDEFG" - }, - { - "192.168.2.4/32" = "ABCDEFG" - }, - ] } variable "env" { From 3ea846f4d1df15129c5dcdcf153787d01e17391e Mon Sep 17 00:00:00 2001 From: James Hale Date: Sat, 2 Mar 2019 13:32:19 -0400 Subject: [PATCH 9/9] Update README and add CHANGELOG --- CHANGELOG.md | 13 +++++++++++++ README.md | 8 +++----- 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..9ef861b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,13 @@ +# Changelog +All notable changes to this project will be documented in this file. + +## [0.0.2] - 2019-03-02 +### Added +- Multi-client support via the module variable. +- This CHANGELOG +### Removed +- Single-client public key via AWS SSM as it now conflicts with the module variable method. + +## [0.0.1] - 2019-02-24 +### Added +- Working module to deploy WireGuard with single client support. diff --git a/README.md b/README.md index 87a1afc..bdf7606 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,13 @@ A Terraform module to deploy a WireGuard VPN server on AWS. Before using this module, you'll need to generate a key pair for your server and client, and store the server's private key and client's public key in AWS SSM, 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 the client - - `wg genkey | tee client-privatekey | wg pubkey > client-publickey` +- 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 the client public key to the AWS SSM parameter: `/wireguard/wg-laptop-public-key` - - `aws ssm put-parameter --name /wireguard/wg-laptop-public-key --type SecureString --value $ClientPublicKeyValue` - Add the server private key to the AWS SSM parameter: `/wireguard/wg-server-private-key` - `aws ssm put-parameter --name /wireguard/wg-server-private-key --type SecureString --value $ServerPrivateKeyValue` +- Add each client's public key, along with the next available IP address as a key:value pair to the wg_client_public_keys map. See Usage for details. ## Variables | Variable Name | Type | Required |Description |