From 697d1781b5ab0155ad8edd7cfa5ea21c8e746521 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Tue, 3 Jun 2025 15:52:39 +0200 Subject: [PATCH 1/6] initial terraform --- .gitignore | 3 + terraform/main.tf | 334 ++++++++++++++++++++++++ terraform/modules/core/main.tf | 35 +++ terraform/modules/core/outputs.tf | 0 terraform/modules/core/setup.sh | 73 ++++++ terraform/modules/core/variables.tf | 94 +++++++ terraform/modules/database/main.tf | 28 ++ terraform/modules/database/outputs.tf | 4 + terraform/modules/database/variables.tf | 29 ++ terraform/modules/gateway/main.tf | 26 ++ terraform/modules/gateway/outputs.tf | 0 terraform/modules/gateway/setup.sh | 131 ++++++++++ terraform/modules/gateway/variables.tf | 57 ++++ terraform/modules/proxy/main.tf | 22 ++ terraform/modules/proxy/outputs.tf | 4 + terraform/modules/proxy/setup.sh | 45 ++++ terraform/modules/proxy/variables.tf | 41 +++ terraform/outputs.tf | 29 ++ terraform/terraform.tfvars | 38 +++ terraform/variables.tf | 90 +++++++ 20 files changed, 1083 insertions(+) create mode 100644 terraform/main.tf create mode 100644 terraform/modules/core/main.tf create mode 100644 terraform/modules/core/outputs.tf create mode 100755 terraform/modules/core/setup.sh create mode 100644 terraform/modules/core/variables.tf create mode 100644 terraform/modules/database/main.tf create mode 100644 terraform/modules/database/outputs.tf create mode 100644 terraform/modules/database/variables.tf create mode 100644 terraform/modules/gateway/main.tf create mode 100644 terraform/modules/gateway/outputs.tf create mode 100644 terraform/modules/gateway/setup.sh create mode 100644 terraform/modules/gateway/variables.tf create mode 100644 terraform/modules/proxy/main.tf create mode 100644 terraform/modules/proxy/outputs.tf create mode 100644 terraform/modules/proxy/setup.sh create mode 100644 terraform/modules/proxy/variables.tf create mode 100644 terraform/outputs.tf create mode 100644 terraform/terraform.tfvars create mode 100644 terraform/variables.tf diff --git a/.gitignore b/.gitignore index e5c0d50..5a34aae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ docker-compose/.env docker-compose/.volumes .idea +terraform/terraform.tfstate +terraform/terraform.tfstate.backup +terraform/.* diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000..8469516 --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,334 @@ +locals { + region = "eu-north-1" + azs = ["eu-north-1a", "eu-north-1b"] +} + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + +data "aws_ami_ids" "ubuntu" { + owners = ["099720109477"] + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"] + } +} + +provider "aws" { + region = local.region + access_key = var.aws_access_key + secret_key = var.aws_secret_key +} + +resource "random_password" "gateway_secret" { + length = 64 + special = false +} + +module "defguard_core_db" { + source = "./modules/database" + subnet_ids = module.vpc.private_subnets + vpc_id = module.vpc.vpc_id + sg_ids = [aws_security_group.defguard_db_sg.id] + db_details = { + name = var.db_name + username = var.db_username + password = var.db_password + port = var.db_port + } + + allocated_storage = 20 +} + +module "defguard_core" { + source = "./modules/core" + core_url = var.core_url + proxy_address = module.defguard_proxy.proxy_private_address + proxy_grpc_port = var.proxy_grpc_port + proxy_url = var.proxy_url + grpc_port = var.core_grpc_port + gateway_secret = random_password.gateway_secret.result + network_interface_id = aws_network_interface.defguard_core_network_interface.id + http_port = var.core_http_port + cookie_insecure = var.core_cookie_insecure + vpn_networks = [for network in var.vpn_networks : { + id = network.id + name = network.name + address = network.address + port = network.port + endpoint = aws_eip.defguard_gateway_endpoint[network.id - 1].public_ip + }] + db_details = { + name = var.db_name + username = var.db_username + password = var.db_password + port = var.db_port + address = module.defguard_core_db.db_address + } + # instance_type = "t3.micro" + ami = data.aws_ami_ids.ubuntu.ids[0] + + # Version of the Defguard core package + package_version = "1.3.2-alpha2" + + # Supported values: "x86_64", "aarch64" + arch = "x86_64" +} + +module "defguard_proxy" { + source = "./modules/proxy" + grpc_port = var.proxy_grpc_port + http_port = var.proxy_http_port + proxy_url = var.proxy_url + network_interface_id = aws_network_interface.defguard_proxy_network_interface.id + # instance_type = "t3.micro" + ami = data.aws_ami_ids.ubuntu.ids[0] + + # Version of the Defguard proxy package + package_version = "1.2.0" + + # Supported values: "x86_64", "aarch64" + arch = "x86_64" +} + +module "defguard_gateway" { + count = length(var.vpn_networks) + source = "./modules/gateway" + gateway_secret = random_password.gateway_secret.result + network_id = var.vpn_networks[count.index].id + network_interface_id = aws_network_interface.defguard_gateway_network_interface[count.index].id + defguard_core_address = aws_network_interface.defguard_core_network_interface.private_ip + defguard_core_grpc_port = var.core_grpc_port + nat = var.vpn_networks[count.index].nat + # instance_type = "t3.micro" + ami = data.aws_ami_ids.ubuntu.ids[0] + + # Version of the Defguard gateway package + package_version = "1.3.0" + + # Supported values: "x86_64", "aarch64" + arch = "x86_64" +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + + name = "defguard" + cidr = "10.0.0.0/16" + + azs = local.azs + private_subnets = ["10.0.2.0/24", "10.0.3.0/24"] + public_subnets = ["10.0.1.0/24"] + + enable_dns_hostnames = true + + tags = { + Name = "defguard-vpc" + } +} + +# +# Core network configuration +# + +resource "aws_eip" "defguard_core_endpoint" { + domain = "vpc" +} + +resource "aws_eip_association" "defguard_core_endpoint_association" { + network_interface_id = aws_network_interface.defguard_core_network_interface.id + allocation_id = aws_eip.defguard_core_endpoint.id +} + +resource "aws_security_group" "defguard_core_sg" { + name = "defguard-core-sg" + description = "Core access" + vpc_id = module.vpc.vpc_id + + # SSH access + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + # HTTP access to the Defguard core web UI + ingress { + from_port = var.core_http_port + to_port = var.core_http_port + protocol = "tcp" + # allow access from every eip of the Defguard gateways + cidr_blocks = [ + for eip in aws_eip.defguard_gateway_endpoint : "${eip.public_ip}/32" + ] + } + + # Internal communication with Defguard gateways + ingress { + from_port = var.core_grpc_port + to_port = var.core_grpc_port + protocol = "tcp" + security_groups = [ + for sg in aws_security_group.defguard_gateway_sg : sg.id + ] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_network_interface" "defguard_core_network_interface" { + subnet_id = module.vpc.public_subnets[0] + security_groups = [aws_security_group.defguard_core_sg.id] + + tags = { + Name = "defguard-core-network-interface" + } +} + +# +# Gateway network configuration +# + +resource "aws_eip" "defguard_gateway_endpoint" { + count = length(var.vpn_networks) + domain = "vpc" +} + +resource "aws_eip_association" "defguard_gateway_endpoint_association" { + count = length(var.vpn_networks) + network_interface_id = aws_network_interface.defguard_gateway_network_interface[count.index].id + allocation_id = aws_eip.defguard_gateway_endpoint[count.index].id +} + +resource "aws_security_group" "defguard_gateway_sg" { + count = length(var.vpn_networks) + name = "defguard-gateway-sg-${count.index}" + description = "Gateway access" + vpc_id = module.vpc.vpc_id + + # VPN traffic coming from connected clients + ingress { + from_port = var.vpn_networks[count.index].port + to_port = var.vpn_networks[count.index].port + protocol = "udp" + cidr_blocks = ["0.0.0.0/0"] + } + + # SSH access + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_network_interface" "defguard_gateway_network_interface" { + count = length(var.vpn_networks) + subnet_id = module.vpc.public_subnets[0] + security_groups = [aws_security_group.defguard_gateway_sg[count.index].id] + + tags = { + Name = "defguard-gateway-network-interface-${count.index}" + } +} + +# +# Proxy network configuration +# + +resource "aws_eip" "defguard_proxy_endpoint" { + domain = "vpc" +} + +resource "aws_eip_association" "defguard_proxy_endpoint_association" { + network_interface_id = aws_network_interface.defguard_proxy_network_interface.id + allocation_id = aws_eip.defguard_proxy_endpoint.id +} + +resource "aws_security_group" "defguard_proxy_sg" { + name = "defguard-proxy-sg" + description = "Proxy access" + vpc_id = module.vpc.vpc_id + + # Internal communication with Defguard core + ingress { + from_port = var.proxy_grpc_port + to_port = var.proxy_grpc_port + protocol = "tcp" + security_groups = [aws_security_group.defguard_core_sg.id] + } + + # SSH access + ingress { + from_port = 22 + to_port = 22 + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + # HTTP access to the proxy service + ingress { + from_port = var.proxy_http_port + to_port = var.proxy_http_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_network_interface" "defguard_proxy_network_interface" { + subnet_id = module.vpc.public_subnets[0] + security_groups = [aws_security_group.defguard_proxy_sg.id] + + tags = { + Name = "defguard-proxy-network-interface" + } +} + +# +# Database network configuration +# + +resource "aws_security_group" "defguard_db_sg" { + name = "defguard-db-sg" + description = "Access to the database" + vpc_id = module.vpc.vpc_id + + # Allow access from the Defguard core instance + ingress { + from_port = var.db_port + to_port = var.db_port + protocol = "tcp" + security_groups = [aws_security_group.defguard_core_sg.id] + } + + tags = { + Name = "defguard-db-sg" + } +} diff --git a/terraform/modules/core/main.tf b/terraform/modules/core/main.tf new file mode 100644 index 0000000..80f416b --- /dev/null +++ b/terraform/modules/core/main.tf @@ -0,0 +1,35 @@ +resource "aws_instance" "defguard_core" { + ami = var.ami + instance_type = var.instance_type + + user_data = templatefile("${path.module}/setup.sh", { + db_address = var.db_details.address + db_password = var.db_details.password + db_username = var.db_details.username + db_name = var.db_details.name + db_port = var.db_details.port + core_url = var.core_url + proxy_address = var.proxy_address + proxy_grpc_port = var.proxy_grpc_port + proxy_url = var.proxy_url + grpc_port = var.grpc_port + gateway_secret = var.gateway_secret + vpn_networks = var.vpn_networks + package_version = var.package_version + arch = var.arch + http_port = var.http_port + default_admin_password = var.default_admin_password + cookie_insecure = var.cookie_insecure + }) + user_data_replace_on_change = true + + network_interface { + network_interface_id = var.network_interface_id + device_index = 0 + } + + tags = { + Name = "defguard-core-instance" + } +} + diff --git a/terraform/modules/core/outputs.tf b/terraform/modules/core/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/terraform/modules/core/setup.sh b/terraform/modules/core/setup.sh new file mode 100755 index 0000000..4a3cafe --- /dev/null +++ b/terraform/modules/core/setup.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash +set -e + +LOG_FILE="/var/log/defguard.log" + +log() { + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG_FILE" +} + +generate_secret_inner() { + local length="$1" + openssl rand -base64 $${length} | tr -d "=+/" | tr -d '\n' | cut -c1-$${length-1} +} + +log "Updating apt repositories..." +sudo apt update | tee -a "$LOG_FILE" + +log "Installing curl..." +sudo apt install -y curl | tee -a "$LOG_FILE" + +log "Downloading defguard-core package..." +curl -fsSL -o /tmp/defguard-core.deb https://github.com/DefGuard/defguard/releases/download/v${package_version}/defguard-${package_version}-${arch}-unknown-linux-gnu.deb | tee -a "$LOG_FILE" + +log "Installing defguard-core package..." +sudo dpkg -i /tmp/defguard-core.deb | tee -a "$LOG_FILE" + +log "Writing core configuration to /etc/defguard/core.conf..." +sudo tee /etc/defguard/core.conf <> "$LOG_FILE" 2>&1 +log "Created VPN location ${network.name} with address ${network.address} and endpoint ${network.endpoint} and port ${network.port}" +%{ endfor ~} + +log "Cleaning up after installing Defguard core..." +rm -f /tmp/defguard-core.deb | tee -a "$LOG_FILE" + +log "Setup completed." diff --git a/terraform/modules/core/variables.tf b/terraform/modules/core/variables.tf new file mode 100644 index 0000000..e1a60b3 --- /dev/null +++ b/terraform/modules/core/variables.tf @@ -0,0 +1,94 @@ +variable "ami" { + description = "AMI ID for the instance" + type = string +} + +variable "instance_type" { + description = "Instance type for the instance" + type = string + default = "t3.micro" +} + +variable "db_details" { + description = "Details of the database connection" + type = object({ + name = string + username = string + password = string + port = number + address = string + }) +} + +variable "core_url" { + description = "URL of the Defguard instance" + type = string +} + +variable "proxy_address" { + description = "The IP address of the Defguard proxy instance" + type = string +} + +variable "proxy_grpc_port" { + description = "Port to be used to communicate with Defguard proxy" + type = string +} + +variable "proxy_url" { + description = "The URL of the Defguard proxy instance where enrollment is performed" + type = string +} + +variable "grpc_port" { + description = "Port to be used to communicate with Defguard core" + type = number +} + +variable "http_port" { + description = "Port to be used to access Defguard core via HTTP" + type = number + default = 8000 +} + +variable "gateway_secret" { + description = "Secret for the Defguard gateway" + type = string +} + +variable "network_interface_id" { + description = "Network interface ID for the instance" + type = string +} + +variable "vpn_networks" { + description = "List of VPN networks" + type = list(object({ + name = string + address = string + port = number + endpoint = string + id = number + })) +} + +variable "package_version" { + description = "Version of the Defguard core package to be installed" + type = string +} + +variable "arch" { + description = "Architecture of the Defguard core package to be installed" + type = string +} + +variable "default_admin_password" { + description = "Default admin password for the Defguard core" + type = string + default = "pass123" +} + +variable "cookie_insecure" { + description = "Whether to use insecure cookies for the Defguard core" + type = bool +} diff --git a/terraform/modules/database/main.tf b/terraform/modules/database/main.tf new file mode 100644 index 0000000..dd9da33 --- /dev/null +++ b/terraform/modules/database/main.tf @@ -0,0 +1,28 @@ +resource "aws_db_instance" "defguard_core_db" { + engine = "postgres" + instance_class = "db.t3.micro" + username = var.db_details.username + password = var.db_details.password + db_name = var.db_details.name + port = var.db_details.port + skip_final_snapshot = true + allocated_storage = var.allocated_storage + db_subnet_group_name = aws_db_subnet_group.defguard.name + vpc_security_group_ids = var.sg_ids + parameter_group_name = aws_db_parameter_group.defguard_db_parameter_group.name +} + +resource "aws_db_parameter_group" "defguard_db_parameter_group" { + name = "defguard-db-parameter-group" + family = "postgres17" + + parameter { + name = "rds.force_ssl" + value = "0" + } +} + +resource "aws_db_subnet_group" "defguard" { + name = "defguard-db-subnet-group" + subnet_ids = var.subnet_ids +} diff --git a/terraform/modules/database/outputs.tf b/terraform/modules/database/outputs.tf new file mode 100644 index 0000000..5b1249f --- /dev/null +++ b/terraform/modules/database/outputs.tf @@ -0,0 +1,4 @@ +output "db_address" { + value = aws_db_instance.defguard_core_db.address + sensitive = true +} diff --git a/terraform/modules/database/variables.tf b/terraform/modules/database/variables.tf new file mode 100644 index 0000000..3039e04 --- /dev/null +++ b/terraform/modules/database/variables.tf @@ -0,0 +1,29 @@ +variable "subnet_ids" { + type = list(string) + description = "List of private subnet IDs for the database instance" +} + +variable "vpc_id" { + type = string + description = "VPC ID where the database instance will be created" +} + +variable "allocated_storage" { + type = number + description = "Allocated storage for the database instance in GB" +} + +variable "db_details" { + description = "Details of the database connection" + type = object({ + name = string + username = string + password = string + port = number + }) +} + +variable "sg_ids" { + type = list(string) + description = "List of security group IDs to be associated with the database instance" +} diff --git a/terraform/modules/gateway/main.tf b/terraform/modules/gateway/main.tf new file mode 100644 index 0000000..a6931a2 --- /dev/null +++ b/terraform/modules/gateway/main.tf @@ -0,0 +1,26 @@ +resource "aws_instance" "defguard_gateway" { + ami = var.ami + instance_type = var.instance_type + + user_data = templatefile("${path.module}/setup.sh", { + gateway_port = var.gateway_port + gateway_secret = var.gateway_secret + network_id = var.network_id + defguard_core_address = var.defguard_core_address + defguard_core_grpc_port = var.defguard_core_grpc_port + package_version = var.package_version + nat = var.nat + gateway_name = "defguard-gateway-${var.network_id}" + arch = var.arch + }) + user_data_replace_on_change = true + + network_interface { + network_interface_id = var.network_interface_id + device_index = 0 + } + + tags = { + Name = "defguard-gateway-instance-${var.network_id}" + } +} diff --git a/terraform/modules/gateway/outputs.tf b/terraform/modules/gateway/outputs.tf new file mode 100644 index 0000000..e69de29 diff --git a/terraform/modules/gateway/setup.sh b/terraform/modules/gateway/setup.sh new file mode 100644 index 0000000..f325ea1 --- /dev/null +++ b/terraform/modules/gateway/setup.sh @@ -0,0 +1,131 @@ +#!/usr/bin/env bash +set -e + +LOG_FILE="/var/log/defguard.log" + +log() { + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG_FILE" +} + +log "Updating apt repositories..." +sudo apt update | tee -a "$LOG_FILE" + +log "Installing curl..." +sudo apt install -y curl | tee -a "$LOG_FILE" + +log "Downloading defguard-gateway package..." +curl -fsSL -o /tmp/defguard-gateway.deb https://github.com/DefGuard/gateway/releases/download/v${package_version}/defguard-gateway_${package_version}_${arch}-unknown-linux-gnu.deb | tee -a "$LOG_FILE" + +log "Installing defguard-gateway package..." +sudo dpkg -i /tmp/defguard-gateway.deb | tee -a "$LOG_FILE" + +base64url_encode() { + echo -n "$1" | openssl base64 -e -A | tr '+/' '-_' | tr -d '=' +} + +log "Generating gateway token..." +NETWORK_ID="${network_id}" +SECRET="${gateway_secret}" +ISSUER="DefGuard" + +HEADER='{"alg":"HS256","typ":"JWT"}' +NOW=$(date +%s) +EXPIRATION=$(($NOW + 315360000)) +PAYLOAD=$(cat < Date: Wed, 4 Jun 2025 15:29:01 +0200 Subject: [PATCH 2/6] move main.tf to examples folder --- .gitignore | 7 +- terraform/examples/basic/main.tf.example | 557 +++++++++++++++++++++++ terraform/main.tf | 334 -------------- terraform/modules/database/main.tf | 28 -- terraform/modules/database/outputs.tf | 4 - terraform/modules/database/variables.tf | 29 -- terraform/outputs.tf | 29 -- terraform/terraform.tfvars | 38 -- terraform/variables.tf | 90 ---- 9 files changed, 561 insertions(+), 555 deletions(-) create mode 100644 terraform/examples/basic/main.tf.example delete mode 100644 terraform/main.tf delete mode 100644 terraform/modules/database/main.tf delete mode 100644 terraform/modules/database/outputs.tf delete mode 100644 terraform/modules/database/variables.tf delete mode 100644 terraform/outputs.tf delete mode 100644 terraform/terraform.tfvars delete mode 100644 terraform/variables.tf diff --git a/.gitignore b/.gitignore index 5a34aae..7e33b52 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ docker-compose/.env docker-compose/.volumes .idea -terraform/terraform.tfstate -terraform/terraform.tfstate.backup -terraform/.* +terraform/**/terraform.tfstate +terraform/**/terraform.tfstate.backup +terraform/**/.* +terraform/**/*.tfvars diff --git a/terraform/examples/basic/main.tf.example b/terraform/examples/basic/main.tf.example new file mode 100644 index 0000000..baad7e3 --- /dev/null +++ b/terraform/examples/basic/main.tf.example @@ -0,0 +1,557 @@ +locals { + ############################ AWS configuration ############################ + + # The AWS region where the Defguard infrastructure will be deployed. + region = "eu-north-1" + + ############################ Core configuration ########################### + + # The URL for the Defguard core. This is the URL under which the Defguard core should be accessible. + core_url = "https://defguard.example.com" + + # The gRPC port for the Defguard core. This is the port that the core will use to communicate with Defguard gateways. + core_grpc_port = 50055 + + # The HTTP port for the Defguard core web UI. This is the port that the core will listen on for incoming HTTP requests. + core_http_port = 8000 + + # Whether to allow insecure cookies for the Defguard core web UI. Set to true if you + # are using HTTP to access the Defguard core web UI. + core_cookie_insecure = false + + # The initial password for the "admin" user. Use it to login to the Defguard core web UI for the first time. + default_admin_password = "pass123" + + # The deb package version of the Defguard core that will be installed on the instance. + # Must be a valid, released version of Defguard core. + core_package_version = "1.3.2-alpha2" + + # The architecture of the Defguard core server instance. + # Supported values: "x86_64", "aarch64" + core_arch = "x86_64" + + # The instance type for the Defguard core server. + core_instance_type = "t3.micro" + + ########################### Proxy configuration ########################### + + # The URL for the Defguard proxy. This is the URL under which the Defguard proxy should be accessible. + proxy_url = "https://proxy.example.com" + + # The gRPC port for the Defguard proxy. This is the port that the proxy will use to communicate with the Defguard core. + proxy_grpc_port = 50051 + + # The HTTP port for the Defguard proxy. This is the port that the proxy will listen on for incoming HTTP requests. + proxy_http_port = 8000 + + # The deb package version of the proxy that will be installed on the instance. + # Must be a valid, released version of Defguard proxy. + proxy_package_version = "1.2.0" + + # The architecture of the Defguard proxy server instance. + # Supported values: "x86_64", "aarch64" + proxy_arch = "x86_64" + + # The instance type for the Defguard proxy server. + proxy_instance_type = "t3.micro" + + ###################### VPN and Gateway configuration ###################### + + # List of VPN networks to be created. A gateway will be created for each network. + vpn_networks = [ + { + # The ID of the VPN network. Must start with 1 and be incremented for each new network. + # Used for modifying the network configuration later. + id = 1 + # The name of the VPN network. Displayed to the users. + name = "vpn1" + # The CIDR address of the VPN network. Clients will be assigned IP addresses from this range. + address = "10.10.10.1/24" + # The UDP port for the WireGuard VPN. Gateways will listen on this port for incoming VPN connections. + port = 51820 + # Whether to enable NAT for the VPN network. If true, the gateway will perform NAT (masquerade) for the VPN clients. + # This is useful if you want the VPN clients to access the internet through the gateway or to access other resources in the VPC. + nat = true + } + ] + + # The gateway deb package version that will be installed on the instance. + # Must be a valid, released version of Defguard gateway. + gateway_package_version = "1.3.0" + + # The architecture of the Defguard gateway server instance. + # Supported values: "x86_64", "aarch64" + gateway_arch = "x86_64" + + # The instance type for the Defguard gateway server. + gateway_instance_type = "t3.micro" + + ########################## Database configuration ######################### + + # The name of the database that will be created for the Defguard core. + db_name = "defguard" + + # The username for the database that will be created for the Defguard core. + db_username = "defguard" + + # The port on which the database will listen for incoming connections. + db_port = 5432 + + # The password for the database user. This will be used by the Defguard core to connect to the database. + db_password = "defguard" + + # The amount of storage allocated for the database in GB. The minimum amount for this example required by AWS is 20 GB. + db_storage = 20 # GB + + # The instance class for the database. This defines the performance characteristics of the database instance. + db_instance_class = "db.t3.micro" + + ############################ VPC configuration ############################ + + # The name of the VPC that will be created for the Defguard infrastructure. + vpc_name = "defguard-vpc" + + # The CIDR block for the VPC. This defines the IP address range for the VPC and its subnets. + vpc_cidr = "10.0.0.0/16" + + # The tags to be applied to the Defguard VPC. + vpc_tags = { + Name = local.vpc_name + } + + # The private subnets for the VPC. These subnets are used for the database instance. + # Note: 2 subnets are required for high availability of the database instance. + vpc_private_subnets = ["10.0.2.0/24", "10.0.3.0/24"] + + # The subnets for the VPC that will be used for the Defguard core, proxy, and gateways. + vpc_public_subnets = ["10.0.1.0/24"] + + # The availability zones for the VPC. This is used mainly for the database instance to ensure high availability. + azs = ["eu-north-1a", "eu-north-1b"] +} + +variable "aws_access_key" { + description = "AWS access key" + type = string +} + +variable "aws_secret_key" { + description = "AWS secret key" + type = string +} + +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} + +data "aws_ami_ids" "ubuntu" { + owners = ["099720109477"] + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"] + } +} + +provider "aws" { + region = local.region + access_key = var.aws_access_key + secret_key = var.aws_secret_key +} + +resource "random_password" "gateway_secret" { + length = 64 + special = false +} + +module "defguard_core" { + source = "github.com/DefGuard/deployment//terraform/modules/core?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" + instance_type = local.core_instance_type + package_version = local.core_package_version + arch = local.core_arch + core_url = local.core_url + proxy_grpc_port = local.proxy_grpc_port + proxy_url = local.proxy_url + grpc_port = local.core_grpc_port + http_port = local.core_http_port + cookie_insecure = local.core_cookie_insecure + vpn_networks = [for network in local.vpn_networks : { + id = network.id + name = network.name + address = network.address + port = network.port + endpoint = aws_eip.defguard_gateway_endpoint[network.id - 1].public_ip + }] + db_details = { + name = local.db_name + username = local.db_username + password = local.db_password + port = local.db_port + address = aws_db_instance.defguard_core_db.address + } + + ami = data.aws_ami_ids.ubuntu.ids[0] + proxy_address = module.defguard_proxy.proxy_private_address + gateway_secret = random_password.gateway_secret.result + network_interface_id = aws_network_interface.defguard_core_network_interface.id +} + +module "defguard_proxy" { + source = "github.com/DefGuard/deployment//terraform/modules/proxy?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" + + instance_type = local.proxy_instance_type + package_version = local.proxy_package_version + arch = local.proxy_arch + grpc_port = local.proxy_grpc_port + http_port = local.proxy_http_port + proxy_url = local.proxy_url + + ami = data.aws_ami_ids.ubuntu.ids[0] + network_interface_id = aws_network_interface.defguard_proxy_network_interface.id +} + +module "defguard_gateway" { + count = length(local.vpn_networks) + source = "github.com/DefGuard/deployment//terraform/modules/gateway?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" + + instance_type = local.gateway_instance_type + package_version = local.gateway_package_version + arch = local.gateway_arch + defguard_core_grpc_port = local.core_grpc_port + nat = local.vpn_networks[count.index].nat + network_id = local.vpn_networks[count.index].id + + ami = data.aws_ami_ids.ubuntu.ids[0] + gateway_secret = random_password.gateway_secret.result + network_interface_id = aws_network_interface.defguard_gateway_network_interface[count.index].id + defguard_core_address = aws_network_interface.defguard_core_network_interface.private_ip + depends_on = [module.defguard_core] +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + + name = local.vpc_name + cidr = local.vpc_cidr + azs = local.azs + private_subnets = local.vpc_private_subnets + public_subnets = local.vpc_public_subnets + + enable_dns_hostnames = true + tags = local.vpc_tags +} + +########################################################################### +####################### Core database configuration ####################### +########################################################################### + +resource "aws_db_instance" "defguard_core_db" { + engine = "postgres" + instance_class = local.db_instance_class + username = local.db_username + password = local.db_password + db_name = local.db_name + port = local.db_port + skip_final_snapshot = true + allocated_storage = local.db_storage + db_subnet_group_name = aws_db_subnet_group.defguard.name + vpc_security_group_ids = [aws_security_group.defguard_db_sg.id] + parameter_group_name = aws_db_parameter_group.defguard_db_parameter_group.name +} + +resource "aws_db_parameter_group" "defguard_db_parameter_group" { + name = "defguard-db-parameter-group" + family = "postgres17" + + parameter { + name = "rds.force_ssl" + value = "0" + } +} + +resource "aws_db_subnet_group" "defguard" { + name = "defguard-db-subnet-group" + subnet_ids = module.vpc.private_subnets +} + +########################################################################### +######################## Core network configuration ####################### +########################################################################### + +# Public IP address for the Defguard core instance +# Remove this if you want to use a private IP only +# or you are running Defguard behind a reverse proxy. +resource "aws_eip" "defguard_core_endpoint" { + domain = "vpc" +} + +resource "aws_eip_association" "defguard_core_endpoint_association" { + network_interface_id = aws_network_interface.defguard_core_network_interface.id + allocation_id = aws_eip.defguard_core_endpoint.id +} + +resource "aws_security_group" "defguard_core_sg" { + name = "defguard-core-sg" + description = "Core access" + vpc_id = module.vpc.vpc_id + + ########################### General access rules ########################## + + # (optional) SSH access to the Defguard core server instance + # ingress { + # from_port = 22 + # to_port = 22 + # protocol = "tcp" + # cidr_blocks = ["0.0.0.0/0"] + # } + + # HTTP access to the Defguard core web UI from connected VPN clients + # Remove this rule if you want to run core only behind a reverse proxy + # Note that the core access should be limited to the VPN clients and internal networks only. + ingress { + from_port = local.core_http_port + to_port = local.core_http_port + protocol = "tcp" + cidr_blocks = [ + for eip in aws_eip.defguard_gateway_endpoint : "${eip.public_ip}/32" + ] + } + + # Example access from a reverse proxy + # ingress { + # from_port = local.core_http_port + # to_port = local.core_http_port + # protocol = "tcp" + # security_groups = [ ] + # } + + ########## Security group rules essential for Defguard operation ########## + + # gRPC communication with Defguard gateways + ingress { + from_port = local.core_grpc_port + to_port = local.core_grpc_port + protocol = "tcp" + security_groups = [ + for sg in aws_security_group.defguard_gateway_sg : sg.id + ] + } + + # General egress + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_network_interface" "defguard_core_network_interface" { + subnet_id = module.vpc.public_subnets[0] + security_groups = [aws_security_group.defguard_core_sg.id] + + tags = { + Name = "defguard-core-network-interface" + } +} + +########################################################################### +###################### Gateway network configuration ###################### +########################################################################### + +# Public IP addresses for the Defguard gateway instances +# Gateways must be accessible externally to allow VPN clients to connect. + +resource "aws_eip" "defguard_gateway_endpoint" { + count = length(local.vpn_networks) + domain = "vpc" +} + +resource "aws_eip_association" "defguard_gateway_endpoint_association" { + count = length(local.vpn_networks) + network_interface_id = aws_network_interface.defguard_gateway_network_interface[count.index].id + allocation_id = aws_eip.defguard_gateway_endpoint[count.index].id +} + +resource "aws_security_group" "defguard_gateway_sg" { + count = length(local.vpn_networks) + name = "defguard-gateway-sg-${count.index}" + description = "Gateway access" + vpc_id = module.vpc.vpc_id + + ########################### General access rules ########################## + + # (optional) SSH access to the Defguard gateway server instance + # ingress { + # from_port = 22 + # to_port = 22 + # protocol = "tcp" + # cidr_blocks = ["0.0.0.0/0"] + # } + + ########## Security group rules essential for Defguard operation ########## + + # VPN traffic coming from connected clients + ingress { + from_port = local.vpn_networks[count.index].port + to_port = local.vpn_networks[count.index].port + protocol = "udp" + cidr_blocks = ["0.0.0.0/0"] + } + + # General egress + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_network_interface" "defguard_gateway_network_interface" { + count = length(local.vpn_networks) + subnet_id = module.vpc.public_subnets[0] + security_groups = [aws_security_group.defguard_gateway_sg[count.index].id] + + tags = { + Name = "defguard-gateway-network-interface-${count.index}" + } +} + +########################################################################### +####################### Proxy network configuration ####################### +########################################################################### + +# Public IP address for the Defguard proxy instance +# Remove this if you want to run proxy behind a reverse proxy +resource "aws_eip" "defguard_proxy_endpoint" { + domain = "vpc" +} + +resource "aws_eip_association" "defguard_proxy_endpoint_association" { + network_interface_id = aws_network_interface.defguard_proxy_network_interface.id + allocation_id = aws_eip.defguard_proxy_endpoint.id +} + +resource "aws_security_group" "defguard_proxy_sg" { + name = "defguard-proxy-sg" + description = "Proxy access" + vpc_id = module.vpc.vpc_id + + ########################### General access rules ########################## + + # (optional) SSH access to the Defguard proxy server instance + # ingress { + # from_port = 22 + # to_port = 22 + # protocol = "tcp" + # cidr_blocks = ["0.0.0.0/0"] + # } + + # HTTP access to the Defguard proxy web UI from anywhere + # Remove this rule if you want to run proxy behind a reverse proxy + # Note that the proxy should be accessible externally to allow Defguard clients + # to communicate through it and to allow the enrollment of new users. + ingress { + from_port = local.proxy_http_port + to_port = local.proxy_http_port + protocol = "tcp" + cidr_blocks = ["0.0.0.0/0"] + } + + # Example access from a reverse proxy + # ingress { + # from_port = local.proxy_http_port + # to_port = local.proxy_http_port + # protocol = "tcp" + # security_groups = [ ] + # } + + ########## Security group rules essential for Defguard operation ########## + + # Internal communication with Defguard core + ingress { + from_port = local.proxy_grpc_port + to_port = local.proxy_grpc_port + protocol = "tcp" + security_groups = [aws_security_group.defguard_core_sg.id] + } + + # General egress + egress { + from_port = 0 + to_port = 0 + protocol = "-1" + cidr_blocks = ["0.0.0.0/0"] + } +} + +resource "aws_network_interface" "defguard_proxy_network_interface" { + subnet_id = module.vpc.public_subnets[0] + security_groups = [aws_security_group.defguard_proxy_sg.id] + + tags = { + Name = "defguard-proxy-network-interface" + } +} + + +########################################################################### +###################### Database network configuration ##################### +########################################################################### + +resource "aws_security_group" "defguard_db_sg" { + name = "defguard-db-sg" + description = "Access to the database" + vpc_id = module.vpc.vpc_id + + # Allows access to the database from the Defguard core instance + ingress { + from_port = local.db_port + to_port = local.db_port + protocol = "tcp" + security_groups = [aws_security_group.defguard_core_sg.id] + } + + tags = { + Name = "defguard-db-sg" + } +} + +########################################################################### +################################# Outputs ################################# +########################################################################### + +output "defguard_core_private_address" { + description = "The IP address of the Defguard core instance in the internal network" + value = aws_network_interface.defguard_core_network_interface.private_ip +} + +output "defguard_core_public_address" { + description = "The public IP address of the Defguard core instance" + value = aws_eip.defguard_core_endpoint.public_ip +} + +output "defguard_proxy_public_address" { + description = "The public IP address of the Defguard proxy instance" + value = aws_eip.defguard_proxy_endpoint.public_ip +} + +output "defguard_proxy_private_address" { + description = "The private IP address of the Defguard proxy instance" + value = aws_network_interface.defguard_proxy_network_interface.private_ip +} + +output "defguard_gateway_public_addresses" { + description = "The public IP addresses of the Defguard gateway instances" + value = [for gw in aws_eip.defguard_gateway_endpoint : gw.public_ip] +} + +output "defguard_gateway_private_addresses" { + description = "The private IP addresses of the Defguard gateway instances" + value = [for gw in aws_network_interface.defguard_gateway_network_interface : gw.private_ip] +} diff --git a/terraform/main.tf b/terraform/main.tf deleted file mode 100644 index 8469516..0000000 --- a/terraform/main.tf +++ /dev/null @@ -1,334 +0,0 @@ -locals { - region = "eu-north-1" - azs = ["eu-north-1a", "eu-north-1b"] -} - -terraform { - required_providers { - aws = { - source = "hashicorp/aws" - version = "~> 5.0" - } - } -} - -data "aws_ami_ids" "ubuntu" { - owners = ["099720109477"] - filter { - name = "name" - values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"] - } -} - -provider "aws" { - region = local.region - access_key = var.aws_access_key - secret_key = var.aws_secret_key -} - -resource "random_password" "gateway_secret" { - length = 64 - special = false -} - -module "defguard_core_db" { - source = "./modules/database" - subnet_ids = module.vpc.private_subnets - vpc_id = module.vpc.vpc_id - sg_ids = [aws_security_group.defguard_db_sg.id] - db_details = { - name = var.db_name - username = var.db_username - password = var.db_password - port = var.db_port - } - - allocated_storage = 20 -} - -module "defguard_core" { - source = "./modules/core" - core_url = var.core_url - proxy_address = module.defguard_proxy.proxy_private_address - proxy_grpc_port = var.proxy_grpc_port - proxy_url = var.proxy_url - grpc_port = var.core_grpc_port - gateway_secret = random_password.gateway_secret.result - network_interface_id = aws_network_interface.defguard_core_network_interface.id - http_port = var.core_http_port - cookie_insecure = var.core_cookie_insecure - vpn_networks = [for network in var.vpn_networks : { - id = network.id - name = network.name - address = network.address - port = network.port - endpoint = aws_eip.defguard_gateway_endpoint[network.id - 1].public_ip - }] - db_details = { - name = var.db_name - username = var.db_username - password = var.db_password - port = var.db_port - address = module.defguard_core_db.db_address - } - # instance_type = "t3.micro" - ami = data.aws_ami_ids.ubuntu.ids[0] - - # Version of the Defguard core package - package_version = "1.3.2-alpha2" - - # Supported values: "x86_64", "aarch64" - arch = "x86_64" -} - -module "defguard_proxy" { - source = "./modules/proxy" - grpc_port = var.proxy_grpc_port - http_port = var.proxy_http_port - proxy_url = var.proxy_url - network_interface_id = aws_network_interface.defguard_proxy_network_interface.id - # instance_type = "t3.micro" - ami = data.aws_ami_ids.ubuntu.ids[0] - - # Version of the Defguard proxy package - package_version = "1.2.0" - - # Supported values: "x86_64", "aarch64" - arch = "x86_64" -} - -module "defguard_gateway" { - count = length(var.vpn_networks) - source = "./modules/gateway" - gateway_secret = random_password.gateway_secret.result - network_id = var.vpn_networks[count.index].id - network_interface_id = aws_network_interface.defguard_gateway_network_interface[count.index].id - defguard_core_address = aws_network_interface.defguard_core_network_interface.private_ip - defguard_core_grpc_port = var.core_grpc_port - nat = var.vpn_networks[count.index].nat - # instance_type = "t3.micro" - ami = data.aws_ami_ids.ubuntu.ids[0] - - # Version of the Defguard gateway package - package_version = "1.3.0" - - # Supported values: "x86_64", "aarch64" - arch = "x86_64" -} - -module "vpc" { - source = "terraform-aws-modules/vpc/aws" - - name = "defguard" - cidr = "10.0.0.0/16" - - azs = local.azs - private_subnets = ["10.0.2.0/24", "10.0.3.0/24"] - public_subnets = ["10.0.1.0/24"] - - enable_dns_hostnames = true - - tags = { - Name = "defguard-vpc" - } -} - -# -# Core network configuration -# - -resource "aws_eip" "defguard_core_endpoint" { - domain = "vpc" -} - -resource "aws_eip_association" "defguard_core_endpoint_association" { - network_interface_id = aws_network_interface.defguard_core_network_interface.id - allocation_id = aws_eip.defguard_core_endpoint.id -} - -resource "aws_security_group" "defguard_core_sg" { - name = "defguard-core-sg" - description = "Core access" - vpc_id = module.vpc.vpc_id - - # SSH access - ingress { - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - # HTTP access to the Defguard core web UI - ingress { - from_port = var.core_http_port - to_port = var.core_http_port - protocol = "tcp" - # allow access from every eip of the Defguard gateways - cidr_blocks = [ - for eip in aws_eip.defguard_gateway_endpoint : "${eip.public_ip}/32" - ] - } - - # Internal communication with Defguard gateways - ingress { - from_port = var.core_grpc_port - to_port = var.core_grpc_port - protocol = "tcp" - security_groups = [ - for sg in aws_security_group.defguard_gateway_sg : sg.id - ] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } -} - -resource "aws_network_interface" "defguard_core_network_interface" { - subnet_id = module.vpc.public_subnets[0] - security_groups = [aws_security_group.defguard_core_sg.id] - - tags = { - Name = "defguard-core-network-interface" - } -} - -# -# Gateway network configuration -# - -resource "aws_eip" "defguard_gateway_endpoint" { - count = length(var.vpn_networks) - domain = "vpc" -} - -resource "aws_eip_association" "defguard_gateway_endpoint_association" { - count = length(var.vpn_networks) - network_interface_id = aws_network_interface.defguard_gateway_network_interface[count.index].id - allocation_id = aws_eip.defguard_gateway_endpoint[count.index].id -} - -resource "aws_security_group" "defguard_gateway_sg" { - count = length(var.vpn_networks) - name = "defguard-gateway-sg-${count.index}" - description = "Gateway access" - vpc_id = module.vpc.vpc_id - - # VPN traffic coming from connected clients - ingress { - from_port = var.vpn_networks[count.index].port - to_port = var.vpn_networks[count.index].port - protocol = "udp" - cidr_blocks = ["0.0.0.0/0"] - } - - # SSH access - ingress { - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } -} - -resource "aws_network_interface" "defguard_gateway_network_interface" { - count = length(var.vpn_networks) - subnet_id = module.vpc.public_subnets[0] - security_groups = [aws_security_group.defguard_gateway_sg[count.index].id] - - tags = { - Name = "defguard-gateway-network-interface-${count.index}" - } -} - -# -# Proxy network configuration -# - -resource "aws_eip" "defguard_proxy_endpoint" { - domain = "vpc" -} - -resource "aws_eip_association" "defguard_proxy_endpoint_association" { - network_interface_id = aws_network_interface.defguard_proxy_network_interface.id - allocation_id = aws_eip.defguard_proxy_endpoint.id -} - -resource "aws_security_group" "defguard_proxy_sg" { - name = "defguard-proxy-sg" - description = "Proxy access" - vpc_id = module.vpc.vpc_id - - # Internal communication with Defguard core - ingress { - from_port = var.proxy_grpc_port - to_port = var.proxy_grpc_port - protocol = "tcp" - security_groups = [aws_security_group.defguard_core_sg.id] - } - - # SSH access - ingress { - from_port = 22 - to_port = 22 - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - # HTTP access to the proxy service - ingress { - from_port = var.proxy_http_port - to_port = var.proxy_http_port - protocol = "tcp" - cidr_blocks = ["0.0.0.0/0"] - } - - egress { - from_port = 0 - to_port = 0 - protocol = "-1" - cidr_blocks = ["0.0.0.0/0"] - } -} - -resource "aws_network_interface" "defguard_proxy_network_interface" { - subnet_id = module.vpc.public_subnets[0] - security_groups = [aws_security_group.defguard_proxy_sg.id] - - tags = { - Name = "defguard-proxy-network-interface" - } -} - -# -# Database network configuration -# - -resource "aws_security_group" "defguard_db_sg" { - name = "defguard-db-sg" - description = "Access to the database" - vpc_id = module.vpc.vpc_id - - # Allow access from the Defguard core instance - ingress { - from_port = var.db_port - to_port = var.db_port - protocol = "tcp" - security_groups = [aws_security_group.defguard_core_sg.id] - } - - tags = { - Name = "defguard-db-sg" - } -} diff --git a/terraform/modules/database/main.tf b/terraform/modules/database/main.tf deleted file mode 100644 index dd9da33..0000000 --- a/terraform/modules/database/main.tf +++ /dev/null @@ -1,28 +0,0 @@ -resource "aws_db_instance" "defguard_core_db" { - engine = "postgres" - instance_class = "db.t3.micro" - username = var.db_details.username - password = var.db_details.password - db_name = var.db_details.name - port = var.db_details.port - skip_final_snapshot = true - allocated_storage = var.allocated_storage - db_subnet_group_name = aws_db_subnet_group.defguard.name - vpc_security_group_ids = var.sg_ids - parameter_group_name = aws_db_parameter_group.defguard_db_parameter_group.name -} - -resource "aws_db_parameter_group" "defguard_db_parameter_group" { - name = "defguard-db-parameter-group" - family = "postgres17" - - parameter { - name = "rds.force_ssl" - value = "0" - } -} - -resource "aws_db_subnet_group" "defguard" { - name = "defguard-db-subnet-group" - subnet_ids = var.subnet_ids -} diff --git a/terraform/modules/database/outputs.tf b/terraform/modules/database/outputs.tf deleted file mode 100644 index 5b1249f..0000000 --- a/terraform/modules/database/outputs.tf +++ /dev/null @@ -1,4 +0,0 @@ -output "db_address" { - value = aws_db_instance.defguard_core_db.address - sensitive = true -} diff --git a/terraform/modules/database/variables.tf b/terraform/modules/database/variables.tf deleted file mode 100644 index 3039e04..0000000 --- a/terraform/modules/database/variables.tf +++ /dev/null @@ -1,29 +0,0 @@ -variable "subnet_ids" { - type = list(string) - description = "List of private subnet IDs for the database instance" -} - -variable "vpc_id" { - type = string - description = "VPC ID where the database instance will be created" -} - -variable "allocated_storage" { - type = number - description = "Allocated storage for the database instance in GB" -} - -variable "db_details" { - description = "Details of the database connection" - type = object({ - name = string - username = string - password = string - port = number - }) -} - -variable "sg_ids" { - type = list(string) - description = "List of security group IDs to be associated with the database instance" -} diff --git a/terraform/outputs.tf b/terraform/outputs.tf deleted file mode 100644 index 20a44ea..0000000 --- a/terraform/outputs.tf +++ /dev/null @@ -1,29 +0,0 @@ -output "defguard_core_private_address" { - description = "The IP address of the Defguard core instance in the internal network" - value = aws_network_interface.defguard_core_network_interface.private_ip -} - -output "defguard_core_public_address" { - description = "The public IP address of the Defguard core instance" - value = aws_eip.defguard_core_endpoint.public_ip -} - -output "defguard_proxy_public_address" { - description = "The public IP address of the Defguard proxy instance" - value = aws_eip.defguard_proxy_endpoint.public_ip -} - -output "defguard_proxy_private_address" { - description = "The private IP address of the Defguard proxy instance" - value = aws_network_interface.defguard_proxy_network_interface.private_ip -} - -output "defguard_gateway_public_addresses" { - description = "The public IP addresses of the Defguard gateway instances" - value = [for gw in aws_eip.defguard_gateway_endpoint : gw.public_ip] -} - -output "defguard_gateway_private_addresses" { - description = "The private IP addresses of the Defguard gateway instances" - value = [for gw in aws_network_interface.defguard_gateway_network_interface : gw.private_ip] -} diff --git a/terraform/terraform.tfvars b/terraform/terraform.tfvars deleted file mode 100644 index ec826d6..0000000 --- a/terraform/terraform.tfvars +++ /dev/null @@ -1,38 +0,0 @@ -# -# Core configuration -# - -core_url = "https://defguard.example.com" -core_grpc_port = 50055 -core_http_port = 8000 -core_cookie_insecure = false -default_admin_password = "pass123" - -# -# Proxy configuration -# - -proxy_url = "https://proxy.example.com" -proxy_grpc_port = 50051 -proxy_http_port = 8000 - -# -# VPN configuration -# - -# vpn_networks = [{ -# id = 1 -# name = "vpn1" -# address = "10.10.10.1/24" -# port = 51820 -# nat = true -# }] - -# -# Database settings -# - -db_name = "defguard" -db_username = "defguard" -db_port = 5432 -db_password = "defguard" diff --git a/terraform/variables.tf b/terraform/variables.tf deleted file mode 100644 index 9894a1d..0000000 --- a/terraform/variables.tf +++ /dev/null @@ -1,90 +0,0 @@ -variable "aws_access_key" { - description = "AWS access key" - type = string -} - -variable "aws_secret_key" { - description = "AWS secret key" - type = string -} - -variable "core_url" { - description = "URL at which Defguard core web UI will be available" - type = string -} - -variable "core_grpc_port" { - description = "Port for gRPC communication with Defguard gateways" - type = number - default = 50055 -} - -variable "core_http_port" { - description = "HTTP server port (Web UI)" - type = number - default = 8000 -} - -variable "core_cookie_insecure" { - description = "Enable it if you want to use HTTP" - type = bool - default = false -} - -variable "proxy_url" { - description = "URL at which Defguard proxy (enrollment service) will be available" - type = string -} - -variable "proxy_grpc_port" { - description = "Port for gRPC communication with Defguard core" - type = number - default = 50051 -} - -variable "proxy_http_port" { - description = "HTTP server port" - type = number - default = 8000 -} - -variable "vpn_networks" { - description = "List of VPN networks to be created" - type = list(object({ - id = number - name = string - address = string - port = number - nat = bool - })) -} - -variable "db_name" { - description = "Name of the PostgreSQL database to create" - type = string - default = "defguard" -} - -variable "db_port" { - description = "Port for the PostgreSQL database" - type = number - default = 5432 -} - -variable "db_username" { - description = "Username for the PostgreSQL database" - type = string - default = "defguard" -} - -variable "db_password" { - description = "Password for the PostgreSQL database" - type = string -} - -variable "default_admin_password" { - description = "Default password for the admin user" - type = string - default = "pass123" -} - From 87b75d183e95a20d51b3e083e42661fe21cdddc3 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Thu, 5 Jun 2025 14:20:11 +0200 Subject: [PATCH 3/6] cleanup, log levels --- terraform/examples/basic/main.tf.example | 125 ++++++++++++----------- terraform/modules/core/main.tf | 1 + terraform/modules/core/setup.sh | 25 +++-- terraform/modules/core/variables.tf | 46 +++++---- terraform/modules/gateway/main.tf | 19 ++-- terraform/modules/gateway/setup.sh | 55 ++++++---- terraform/modules/gateway/variables.tf | 18 ++-- terraform/modules/proxy/main.tf | 13 +-- terraform/modules/proxy/outputs.tf | 2 +- terraform/modules/proxy/setup.sh | 25 +++-- terraform/modules/proxy/variables.tf | 10 +- 11 files changed, 196 insertions(+), 143 deletions(-) diff --git a/terraform/examples/basic/main.tf.example b/terraform/examples/basic/main.tf.example index baad7e3..99c1322 100644 --- a/terraform/examples/basic/main.tf.example +++ b/terraform/examples/basic/main.tf.example @@ -6,53 +6,53 @@ locals { ############################ Core configuration ########################### - # The URL for the Defguard core. This is the URL under which the Defguard core should be accessible. + # The URL for the Defguard Core. This is the URL under which the Defguard Core should be accessible. core_url = "https://defguard.example.com" - # The gRPC port for the Defguard core. This is the port that the core will use to communicate with Defguard gateways. + # The gRPC port for the Defguard Core. This is the port that the core will use to communicate with Defguard Gateways. core_grpc_port = 50055 - # The HTTP port for the Defguard core web UI. This is the port that the core will listen on for incoming HTTP requests. + # The HTTP port for the Defguard Core web UI. This is the port that the core will listen on for incoming HTTP requests. core_http_port = 8000 - # Whether to allow insecure cookies for the Defguard core web UI. Set to true if you - # are using HTTP to access the Defguard core web UI. + # Whether to allow insecure cookies for the Defguard Core web UI. Set to true if you + # are using HTTP to access the Defguard Core web UI. core_cookie_insecure = false - # The initial password for the "admin" user. Use it to login to the Defguard core web UI for the first time. + # The initial password for the "admin" user. Use it to login to the Defguard Core web UI for the first time. default_admin_password = "pass123" - # The deb package version of the Defguard core that will be installed on the instance. - # Must be a valid, released version of Defguard core. + # The deb package version of the Defguard Core that will be installed on the instance. + # Must be a valid, released version of Defguard Core. core_package_version = "1.3.2-alpha2" - # The architecture of the Defguard core server instance. + # The architecture of the Defguard Core server instance. # Supported values: "x86_64", "aarch64" core_arch = "x86_64" - # The instance type for the Defguard core server. + # The instance type for the Defguard Core server. core_instance_type = "t3.micro" ########################### Proxy configuration ########################### - # The URL for the Defguard proxy. This is the URL under which the Defguard proxy should be accessible. + # The URL for the Defguard Proxy. This is the URL under which the Defguard Proxy should be accessible. proxy_url = "https://proxy.example.com" - # The gRPC port for the Defguard proxy. This is the port that the proxy will use to communicate with the Defguard core. + # The gRPC port for the Defguard Proxy. This is the port that the proxy will use to communicate with the Defguard Core. proxy_grpc_port = 50051 - # The HTTP port for the Defguard proxy. This is the port that the proxy will listen on for incoming HTTP requests. + # The HTTP port for the Defguard Proxy. This is the port that the proxy will listen on for incoming HTTP requests. proxy_http_port = 8000 # The deb package version of the proxy that will be installed on the instance. - # Must be a valid, released version of Defguard proxy. + # Must be a valid, released version of Defguard Proxy. proxy_package_version = "1.2.0" - # The architecture of the Defguard proxy server instance. + # The architecture of the Defguard Proxy server instance. # Supported values: "x86_64", "aarch64" proxy_arch = "x86_64" - # The instance type for the Defguard proxy server. + # The instance type for the Defguard Proxy server. proxy_instance_type = "t3.micro" ###################### VPN and Gateway configuration ###################### @@ -76,28 +76,28 @@ locals { ] # The gateway deb package version that will be installed on the instance. - # Must be a valid, released version of Defguard gateway. + # Must be a valid, released version of Defguard Gateway. gateway_package_version = "1.3.0" - # The architecture of the Defguard gateway server instance. + # The architecture of the Defguard Gateway server instance. # Supported values: "x86_64", "aarch64" gateway_arch = "x86_64" - # The instance type for the Defguard gateway server. + # The instance type for the Defguard Gateway server. gateway_instance_type = "t3.micro" ########################## Database configuration ######################### - # The name of the database that will be created for the Defguard core. + # The name of the database that will be created for the Defguard Core. db_name = "defguard" - # The username for the database that will be created for the Defguard core. + # The username for the database that will be created for the Defguard Core. db_username = "defguard" # The port on which the database will listen for incoming connections. db_port = 5432 - # The password for the database user. This will be used by the Defguard core to connect to the database. + # The password for the database user. This will be used by the Defguard Core to connect to the database. db_password = "defguard" # The amount of storage allocated for the database in GB. The minimum amount for this example required by AWS is 20 GB. @@ -123,7 +123,7 @@ locals { # Note: 2 subnets are required for high availability of the database instance. vpc_private_subnets = ["10.0.2.0/24", "10.0.3.0/24"] - # The subnets for the VPC that will be used for the Defguard core, proxy, and gateways. + # The subnets for the VPC that will be used for the Defguard Core, proxy, and gateways. vpc_public_subnets = ["10.0.1.0/24"] # The availability zones for the VPC. This is used mainly for the database instance to ensure high availability. @@ -149,11 +149,13 @@ terraform { } } -data "aws_ami_ids" "ubuntu" { - owners = ["099720109477"] +data "aws_ami" "ubuntu" { + most_recent = true + owners = ["099720109477"] + filter { name = "name" - values = ["ubuntu/images/hvm-ssd/ubuntu-*-22.04-amd64-server-*"] + values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"] } } @@ -169,10 +171,13 @@ resource "random_password" "gateway_secret" { } module "defguard_core" { + # source = "../../modules/core" source = "github.com/DefGuard/deployment//terraform/modules/core?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" instance_type = local.core_instance_type package_version = local.core_package_version arch = local.core_arch + ami = data.aws_ami.ubuntu.id + core_url = local.core_url proxy_grpc_port = local.proxy_grpc_port proxy_url = local.proxy_url @@ -193,14 +198,14 @@ module "defguard_core" { port = local.db_port address = aws_db_instance.defguard_core_db.address } - - ami = data.aws_ami_ids.ubuntu.ids[0] proxy_address = module.defguard_proxy.proxy_private_address gateway_secret = random_password.gateway_secret.result network_interface_id = aws_network_interface.defguard_core_network_interface.id + # log_level = "info" } module "defguard_proxy" { + # source = "../../modules/proxy" source = "github.com/DefGuard/deployment//terraform/modules/proxy?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" instance_type = local.proxy_instance_type @@ -209,27 +214,31 @@ module "defguard_proxy" { grpc_port = local.proxy_grpc_port http_port = local.proxy_http_port proxy_url = local.proxy_url + # log_level = "info" - ami = data.aws_ami_ids.ubuntu.ids[0] + ami = data.aws_ami.ubuntu.id network_interface_id = aws_network_interface.defguard_proxy_network_interface.id } module "defguard_gateway" { - count = length(local.vpn_networks) + count = length(local.vpn_networks) + # source = "../../modules/gateway" source = "github.com/DefGuard/deployment//terraform/modules/gateway?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" - instance_type = local.gateway_instance_type - package_version = local.gateway_package_version - arch = local.gateway_arch - defguard_core_grpc_port = local.core_grpc_port - nat = local.vpn_networks[count.index].nat - network_id = local.vpn_networks[count.index].id + ami = data.aws_ami.ubuntu.id + instance_type = local.gateway_instance_type + package_version = local.gateway_package_version + arch = local.gateway_arch + + core_grpc_port = local.core_grpc_port + nat = local.vpn_networks[count.index].nat + network_id = local.vpn_networks[count.index].id + gateway_secret = random_password.gateway_secret.result + network_interface_id = aws_network_interface.defguard_gateway_network_interface[count.index].id + core_address = aws_network_interface.defguard_core_network_interface.private_ip + # log_level = "info" - ami = data.aws_ami_ids.ubuntu.ids[0] - gateway_secret = random_password.gateway_secret.result - network_interface_id = aws_network_interface.defguard_gateway_network_interface[count.index].id - defguard_core_address = aws_network_interface.defguard_core_network_interface.private_ip - depends_on = [module.defguard_core] + depends_on = [module.defguard_core] } module "vpc" { @@ -282,7 +291,7 @@ resource "aws_db_subnet_group" "defguard" { ######################## Core network configuration ####################### ########################################################################### -# Public IP address for the Defguard core instance +# Public IP address for the Defguard Core instance # Remove this if you want to use a private IP only # or you are running Defguard behind a reverse proxy. resource "aws_eip" "defguard_core_endpoint" { @@ -301,7 +310,7 @@ resource "aws_security_group" "defguard_core_sg" { ########################### General access rules ########################## - # (optional) SSH access to the Defguard core server instance + # (optional) SSH access to the Defguard Core server instance # ingress { # from_port = 22 # to_port = 22 @@ -309,7 +318,7 @@ resource "aws_security_group" "defguard_core_sg" { # cidr_blocks = ["0.0.0.0/0"] # } - # HTTP access to the Defguard core web UI from connected VPN clients + # HTTP access to the Defguard Core web UI from connected VPN clients # Remove this rule if you want to run core only behind a reverse proxy # Note that the core access should be limited to the VPN clients and internal networks only. ingress { @@ -331,7 +340,7 @@ resource "aws_security_group" "defguard_core_sg" { ########## Security group rules essential for Defguard operation ########## - # gRPC communication with Defguard gateways + # gRPC communication with Defguard Gateways ingress { from_port = local.core_grpc_port to_port = local.core_grpc_port @@ -363,7 +372,7 @@ resource "aws_network_interface" "defguard_core_network_interface" { ###################### Gateway network configuration ###################### ########################################################################### -# Public IP addresses for the Defguard gateway instances +# Public IP addresses for the Defguard Gateway instances # Gateways must be accessible externally to allow VPN clients to connect. resource "aws_eip" "defguard_gateway_endpoint" { @@ -385,7 +394,7 @@ resource "aws_security_group" "defguard_gateway_sg" { ########################### General access rules ########################## - # (optional) SSH access to the Defguard gateway server instance + # (optional) SSH access to the Defguard Gateway server instance # ingress { # from_port = 22 # to_port = 22 @@ -426,7 +435,7 @@ resource "aws_network_interface" "defguard_gateway_network_interface" { ####################### Proxy network configuration ####################### ########################################################################### -# Public IP address for the Defguard proxy instance +# Public IP address for the Defguard Proxy instance # Remove this if you want to run proxy behind a reverse proxy resource "aws_eip" "defguard_proxy_endpoint" { domain = "vpc" @@ -444,7 +453,7 @@ resource "aws_security_group" "defguard_proxy_sg" { ########################### General access rules ########################## - # (optional) SSH access to the Defguard proxy server instance + # # (optional) SSH access to the Defguard Proxy server instance # ingress { # from_port = 22 # to_port = 22 @@ -452,7 +461,7 @@ resource "aws_security_group" "defguard_proxy_sg" { # cidr_blocks = ["0.0.0.0/0"] # } - # HTTP access to the Defguard proxy web UI from anywhere + # HTTP access to the Defguard Proxy web UI from anywhere # Remove this rule if you want to run proxy behind a reverse proxy # Note that the proxy should be accessible externally to allow Defguard clients # to communicate through it and to allow the enrollment of new users. @@ -473,7 +482,7 @@ resource "aws_security_group" "defguard_proxy_sg" { ########## Security group rules essential for Defguard operation ########## - # Internal communication with Defguard core + # Internal communication with Defguard Core ingress { from_port = local.proxy_grpc_port to_port = local.proxy_grpc_port @@ -509,7 +518,7 @@ resource "aws_security_group" "defguard_db_sg" { description = "Access to the database" vpc_id = module.vpc.vpc_id - # Allows access to the database from the Defguard core instance + # Allows access to the database from the Defguard Core instance ingress { from_port = local.db_port to_port = local.db_port @@ -527,31 +536,31 @@ resource "aws_security_group" "defguard_db_sg" { ########################################################################### output "defguard_core_private_address" { - description = "The IP address of the Defguard core instance in the internal network" + description = "The IP address of the Defguard Core instance in the internal network" value = aws_network_interface.defguard_core_network_interface.private_ip } output "defguard_core_public_address" { - description = "The public IP address of the Defguard core instance" + description = "The public IP address of the Defguard Core instance" value = aws_eip.defguard_core_endpoint.public_ip } output "defguard_proxy_public_address" { - description = "The public IP address of the Defguard proxy instance" + description = "The public IP address of the Defguard Proxy instance" value = aws_eip.defguard_proxy_endpoint.public_ip } output "defguard_proxy_private_address" { - description = "The private IP address of the Defguard proxy instance" + description = "The private IP address of the Defguard Proxy instance" value = aws_network_interface.defguard_proxy_network_interface.private_ip } output "defguard_gateway_public_addresses" { - description = "The public IP addresses of the Defguard gateway instances" + description = "The public IP addresses of the Defguard Gateway instances" value = [for gw in aws_eip.defguard_gateway_endpoint : gw.public_ip] } output "defguard_gateway_private_addresses" { - description = "The private IP addresses of the Defguard gateway instances" + description = "The private IP addresses of the Defguard Gateway instances" value = [for gw in aws_network_interface.defguard_gateway_network_interface : gw.private_ip] } diff --git a/terraform/modules/core/main.tf b/terraform/modules/core/main.tf index 80f416b..8ac6545 100644 --- a/terraform/modules/core/main.tf +++ b/terraform/modules/core/main.tf @@ -20,6 +20,7 @@ resource "aws_instance" "defguard_core" { http_port = var.http_port default_admin_password = var.default_admin_password cookie_insecure = var.cookie_insecure + log_level = var.log_level }) user_data_replace_on_change = true diff --git a/terraform/modules/core/setup.sh b/terraform/modules/core/setup.sh index 4a3cafe..8496285 100755 --- a/terraform/modules/core/setup.sh +++ b/terraform/modules/core/setup.sh @@ -4,7 +4,7 @@ set -e LOG_FILE="/var/log/defguard.log" log() { - echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" } generate_secret_inner() { @@ -12,20 +12,21 @@ generate_secret_inner() { openssl rand -base64 $${length} | tr -d "=+/" | tr -d '\n' | cut -c1-$${length-1} } +( log "Updating apt repositories..." -sudo apt update | tee -a "$LOG_FILE" +apt update log "Installing curl..." -sudo apt install -y curl | tee -a "$LOG_FILE" +apt install -y curl log "Downloading defguard-core package..." -curl -fsSL -o /tmp/defguard-core.deb https://github.com/DefGuard/defguard/releases/download/v${package_version}/defguard-${package_version}-${arch}-unknown-linux-gnu.deb | tee -a "$LOG_FILE" +curl -fsSL -o /tmp/defguard-core.deb https://github.com/DefGuard/defguard/releases/download/v${package_version}/defguard-${package_version}-${arch}-unknown-linux-gnu.deb log "Installing defguard-core package..." -sudo dpkg -i /tmp/defguard-core.deb | tee -a "$LOG_FILE" +dpkg -i /tmp/defguard-core.deb -log "Writing core configuration to /etc/defguard/core.conf..." -sudo tee /etc/defguard/core.conf <&1 | tee -a "$LOG_FILE" diff --git a/terraform/modules/core/variables.tf b/terraform/modules/core/variables.tf index e1a60b3..580a18d 100644 --- a/terraform/modules/core/variables.tf +++ b/terraform/modules/core/variables.tf @@ -12,11 +12,11 @@ variable "instance_type" { variable "db_details" { description = "Details of the database connection" type = object({ - name = string - username = string - password = string - port = number - address = string + name = string + username = string + password = string + port = number + address = string }) } @@ -26,33 +26,33 @@ variable "core_url" { } variable "proxy_address" { - description = "The IP address of the Defguard proxy instance" + description = "The IP address of the Defguard Proxy instance" type = string } variable "proxy_grpc_port" { - description = "Port to be used to communicate with Defguard proxy" + description = "Port to be used to communicate with Defguard Proxy" type = string } variable "proxy_url" { - description = "The URL of the Defguard proxy instance where enrollment is performed" + description = "The URL of the Defguard Proxy instance where enrollment is performed" type = string } variable "grpc_port" { - description = "Port to be used to communicate with Defguard core" + description = "Port to be used to communicate with Defguard Core" type = number } variable "http_port" { - description = "Port to be used to access Defguard core via HTTP" + description = "Port to be used to access Defguard Core via HTTP" type = number default = 8000 } variable "gateway_secret" { - description = "Secret for the Defguard gateway" + description = "Secret for the Defguard Gateway" type = string } @@ -63,32 +63,38 @@ variable "network_interface_id" { variable "vpn_networks" { description = "List of VPN networks" - type = list(object({ - name = string - address = string - port = number + type = list(object({ + name = string + address = string + port = number endpoint = string - id = number + id = number })) } variable "package_version" { - description = "Version of the Defguard core package to be installed" + description = "Version of the Defguard Core package to be installed" type = string } variable "arch" { - description = "Architecture of the Defguard core package to be installed" + description = "Architecture of the Defguard Core package to be installed" type = string } variable "default_admin_password" { - description = "Default admin password for the Defguard core" + description = "Default admin password for the Defguard Core" type = string default = "pass123" } variable "cookie_insecure" { - description = "Whether to use insecure cookies for the Defguard core" + description = "Whether to use insecure cookies for the Defguard Core" type = bool } + +variable "log_level" { + description = "Log level for Defguard Core. Possible values: debug, info, warn, error" + type = string + default = "info" +} diff --git a/terraform/modules/gateway/main.tf b/terraform/modules/gateway/main.tf index a6931a2..db4c233 100644 --- a/terraform/modules/gateway/main.tf +++ b/terraform/modules/gateway/main.tf @@ -3,15 +3,16 @@ resource "aws_instance" "defguard_gateway" { instance_type = var.instance_type user_data = templatefile("${path.module}/setup.sh", { - gateway_port = var.gateway_port - gateway_secret = var.gateway_secret - network_id = var.network_id - defguard_core_address = var.defguard_core_address - defguard_core_grpc_port = var.defguard_core_grpc_port - package_version = var.package_version - nat = var.nat - gateway_name = "defguard-gateway-${var.network_id}" - arch = var.arch + gateway_port = var.gateway_port + gateway_secret = var.gateway_secret + network_id = var.network_id + core_address = var.core_address + core_grpc_port = var.core_grpc_port + package_version = var.package_version + nat = var.nat + gateway_name = "defguard-gateway-${var.network_id}" + arch = var.arch + log_level = var.log_level }) user_data_replace_on_change = true diff --git a/terraform/modules/gateway/setup.sh b/terraform/modules/gateway/setup.sh index f325ea1..21529e3 100644 --- a/terraform/modules/gateway/setup.sh +++ b/terraform/modules/gateway/setup.sh @@ -4,24 +4,31 @@ set -e LOG_FILE="/var/log/defguard.log" log() { - echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" } +LOG_FILE="/var/log/defguard.log" + +log() { + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" +} + +base64url_encode() { + echo -n "$1" | openssl base64 -e -A | tr '+/' '-_' | tr -d '=' +} + +( log "Updating apt repositories..." -sudo apt update | tee -a "$LOG_FILE" +apt update log "Installing curl..." -sudo apt install -y curl | tee -a "$LOG_FILE" +apt install -y curl log "Downloading defguard-gateway package..." -curl -fsSL -o /tmp/defguard-gateway.deb https://github.com/DefGuard/gateway/releases/download/v${package_version}/defguard-gateway_${package_version}_${arch}-unknown-linux-gnu.deb | tee -a "$LOG_FILE" +curl -fsSL -o /tmp/defguard-gateway.deb https://github.com/DefGuard/gateway/releases/download/v${package_version}/defguard-gateway_${package_version}_${arch}-unknown-linux-gnu.deb log "Installing defguard-gateway package..." -sudo dpkg -i /tmp/defguard-gateway.deb | tee -a "$LOG_FILE" - -base64url_encode() { - echo -n "$1" | openssl base64 -e -A | tr '+/' '-_' | tr -d '=' -} +dpkg -i /tmp/defguard-gateway.deb log "Generating gateway token..." NETWORK_ID="${network_id}" @@ -49,7 +56,7 @@ SIGNATURE=$(echo -n "$SIGNING_INPUT" | openssl dgst -sha256 -hmac "$SECRET" -bin GATEWAY_TOKEN="$${SIGNING_INPUT}.$${SIGNATURE}" log "Writing gateway configuration to /etc/defguard/gateway.toml..." -sudo tee /etc/defguard/gateway.toml <&1 | tee -a "$LOG_FILE" diff --git a/terraform/modules/gateway/variables.tf b/terraform/modules/gateway/variables.tf index f183351..2919148 100644 --- a/terraform/modules/gateway/variables.tf +++ b/terraform/modules/gateway/variables.tf @@ -16,7 +16,7 @@ variable "gateway_port" { } variable "gateway_secret" { - description = "Secret key for the Defguard gateway" + description = "Secret key for the Defguard Gateway" type = string } @@ -25,13 +25,13 @@ variable "network_id" { type = number } -variable "defguard_core_address" { +variable "core_address" { description = "Internal address of the Defguard instance" type = string } -variable "defguard_core_grpc_port" { - description = "Port to be used to communicate with Defguard core" +variable "core_grpc_port" { + description = "Port to be used to communicate with Defguard Core" type = number } @@ -41,12 +41,12 @@ variable "network_interface_id" { } variable "package_version" { - description = "Version of the Defguard gateway package to be installed" + description = "Version of the Defguard Gateway package to be installed" type = string } variable "arch" { - description = "Architecture of the Defguard gateway package to be installed" + description = "Architecture of the Defguard Gateway package to be installed" type = string } @@ -55,3 +55,9 @@ variable "nat" { type = bool default = true } + +variable "log_level" { + description = "Log level for Defguard Gateway. Possible values: debug, info, warn, error" + type = string + default = "info" +} diff --git a/terraform/modules/proxy/main.tf b/terraform/modules/proxy/main.tf index 7dc0fba..15b0cba 100644 --- a/terraform/modules/proxy/main.tf +++ b/terraform/modules/proxy/main.tf @@ -1,13 +1,14 @@ resource "aws_instance" "defguard_proxy" { ami = var.ami instance_type = var.instance_type - + user_data = templatefile("${path.module}/setup.sh", { - proxy_url = var.proxy_url - grpc_port = var.grpc_port - arch = var.arch + proxy_url = var.proxy_url + grpc_port = var.grpc_port + arch = var.arch package_version = var.package_version - http_port = var.http_port + http_port = var.http_port + log_level = var.log_level }) user_data_replace_on_change = true @@ -16,7 +17,7 @@ resource "aws_instance" "defguard_proxy" { device_index = 0 } - tags= { + tags = { Name = "defguard-proxy-instance" } } diff --git a/terraform/modules/proxy/outputs.tf b/terraform/modules/proxy/outputs.tf index c83fcfb..948469b 100644 --- a/terraform/modules/proxy/outputs.tf +++ b/terraform/modules/proxy/outputs.tf @@ -1,4 +1,4 @@ output "proxy_private_address" { - description = "The private IP address of the Defguard proxy instance" + description = "The private IP address of the Defguard Proxy instance" value = aws_instance.defguard_proxy.private_ip } diff --git a/terraform/modules/proxy/setup.sh b/terraform/modules/proxy/setup.sh index 0ce443c..b595ab6 100644 --- a/terraform/modules/proxy/setup.sh +++ b/terraform/modules/proxy/setup.sh @@ -4,29 +4,30 @@ set -e LOG_FILE="/var/log/defguard.log" log() { - echo "$(date '+%Y-%m-%d %H:%M:%S') $1" | tee -a "$LOG_FILE" + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" } +( log "Updating apt repositories..." -sudo apt update | tee -a "$LOG_FILE" +apt update log "Installing curl..." -sudo apt install -y curl | tee -a "$LOG_FILE" +apt install -y curl log "Downloading defguard-proxy package..." -curl -fsSL -o /tmp/defguard-proxy.deb https://github.com/DefGuard/proxy/releases/download/v${package_version}/defguard-proxy-${package_version}-${arch}-unknown-linux-gnu.deb | tee -a "$LOG_FILE" +curl -fsSL -o /tmp/defguard-proxy.deb https://github.com/DefGuard/proxy/releases/download/v${package_version}/defguard-proxy-${package_version}-${arch}-unknown-linux-gnu.deb log "Installing defguard-proxy package..." -sudo dpkg -i /tmp/defguard-proxy.deb | tee -a "$LOG_FILE" +dpkg -i /tmp/defguard-proxy.deb log "Writing proxy configuration to /etc/defguard/proxy.toml..." -sudo tee /etc/defguard/proxy.toml <&1 | tee -a "$LOG_FILE" + diff --git a/terraform/modules/proxy/variables.tf b/terraform/modules/proxy/variables.tf index 99de25c..d43f906 100644 --- a/terraform/modules/proxy/variables.tf +++ b/terraform/modules/proxy/variables.tf @@ -15,7 +15,7 @@ variable "proxy_url" { } variable "grpc_port" { - description = "Port to be used to communicate with Defguard core" + description = "Port to be used to communicate with Defguard Core" type = string } @@ -35,7 +35,13 @@ variable "package_version" { } variable "http_port" { - description = "Port to be used to access Defguard core via HTTP" + description = "Port to be used to access Defguard Proxy via HTTP" type = number default = 8080 } + +variable "log_level" { + description = "Log level for Defguard Proxy. Possible values: debug, info, warn, error" + type = string + default = "info" +} From b0cb433a10a03cdc15086b2c624b37a29993dc41 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Thu, 5 Jun 2025 16:00:27 +0200 Subject: [PATCH 4/6] Update main.tf.example --- terraform/examples/basic/main.tf.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terraform/examples/basic/main.tf.example b/terraform/examples/basic/main.tf.example index 99c1322..0224284 100644 --- a/terraform/examples/basic/main.tf.example +++ b/terraform/examples/basic/main.tf.example @@ -214,7 +214,7 @@ module "defguard_proxy" { grpc_port = local.proxy_grpc_port http_port = local.proxy_http_port proxy_url = local.proxy_url - # log_level = "info" + # log_level = "info" ami = data.aws_ami.ubuntu.id network_interface_id = aws_network_interface.defguard_proxy_network_interface.id From 40b741a175c617110643cde12df74e95019acc6c Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Thu, 5 Jun 2025 17:04:49 +0200 Subject: [PATCH 5/6] mention the trace level --- terraform/modules/core/variables.tf | 2 +- terraform/modules/gateway/variables.tf | 2 +- terraform/modules/proxy/variables.tf | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/terraform/modules/core/variables.tf b/terraform/modules/core/variables.tf index 580a18d..bf2d46d 100644 --- a/terraform/modules/core/variables.tf +++ b/terraform/modules/core/variables.tf @@ -94,7 +94,7 @@ variable "cookie_insecure" { } variable "log_level" { - description = "Log level for Defguard Core. Possible values: debug, info, warn, error" + description = "Log level for Defguard Core. Possible values: trace, debug, info, warn, error" type = string default = "info" } diff --git a/terraform/modules/gateway/variables.tf b/terraform/modules/gateway/variables.tf index 2919148..83c27df 100644 --- a/terraform/modules/gateway/variables.tf +++ b/terraform/modules/gateway/variables.tf @@ -57,7 +57,7 @@ variable "nat" { } variable "log_level" { - description = "Log level for Defguard Gateway. Possible values: debug, info, warn, error" + description = "Log level for Defguard Gateway. Possible values: trace, debug, info, warn, error" type = string default = "info" } diff --git a/terraform/modules/proxy/variables.tf b/terraform/modules/proxy/variables.tf index d43f906..21a7eeb 100644 --- a/terraform/modules/proxy/variables.tf +++ b/terraform/modules/proxy/variables.tf @@ -25,12 +25,12 @@ variable "network_interface_id" { } variable "arch" { - description = "Architecture of the Defguard proxy package to be installed" + description = "Architecture of the Defguard Proxy package to be installed" type = string } variable "package_version" { - description = "Version of the Defguard proxy package to be installed" + description = "Version of the Defguard Proxy package to be installed" type = string } @@ -41,7 +41,7 @@ variable "http_port" { } variable "log_level" { - description = "Log level for Defguard Proxy. Possible values: debug, info, warn, error" + description = "Log level for Defguard Proxy. Possible values: trace, debug, info, warn, error" type = string default = "info" } From 55e20c08f008e8797320a8adf030bd27046720b5 Mon Sep 17 00:00:00 2001 From: Aleksander <170264518+t-aleksander@users.noreply.github.com> Date: Fri, 6 Jun 2025 10:28:39 +0200 Subject: [PATCH 6/6] rename refs --- terraform/examples/basic/main.tf.example | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/terraform/examples/basic/main.tf.example b/terraform/examples/basic/main.tf.example index 0224284..36e34e9 100644 --- a/terraform/examples/basic/main.tf.example +++ b/terraform/examples/basic/main.tf.example @@ -172,7 +172,7 @@ resource "random_password" "gateway_secret" { module "defguard_core" { # source = "../../modules/core" - source = "github.com/DefGuard/deployment//terraform/modules/core?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" + source = "github.com/DefGuard/deployment//terraform/modules/core?ref=main" instance_type = local.core_instance_type package_version = local.core_package_version arch = local.core_arch @@ -206,7 +206,7 @@ module "defguard_core" { module "defguard_proxy" { # source = "../../modules/proxy" - source = "github.com/DefGuard/deployment//terraform/modules/proxy?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" + source = "github.com/DefGuard/deployment//terraform/modules/proxy?ref=main" instance_type = local.proxy_instance_type package_version = local.proxy_package_version @@ -223,7 +223,7 @@ module "defguard_proxy" { module "defguard_gateway" { count = length(local.vpn_networks) # source = "../../modules/gateway" - source = "github.com/DefGuard/deployment//terraform/modules/gateway?ref=697d1781b5ab0155ad8edd7cfa5ea21c8e746521" + source = "github.com/DefGuard/deployment//terraform/modules/gateway?ref=main" ami = data.aws_ami.ubuntu.id instance_type = local.gateway_instance_type @@ -453,7 +453,7 @@ resource "aws_security_group" "defguard_proxy_sg" { ########################### General access rules ########################## - # # (optional) SSH access to the Defguard Proxy server instance + # (optional) SSH access to the Defguard Proxy server instance # ingress { # from_port = 22 # to_port = 22