diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cb86cbc --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +private-variables.tf +.terraform +.terraform.lock.hcl diff --git a/README.md b/README.md index 3413319..6de22f0 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,62 @@ Terraform module which creates OpenVPN on AWS -## This module is creating the following resources: +# Important steps for permissions and startvpn.sh + +*IMPORTANT: you will need to have the permissions locked down tight in on startvpn.sh for this to be secure. +Make the file owned by root and group root:* + + sudo chown root:root startvpn.sh + +Now set the SetUID bit, make it executable for all and writable only by root: + + sudo chmod 4755 startvpn.sh + sudo chmod +s startvpn.sh + + +edit the sudoers file to conatin this line, which will allow these vpn autologin files to be copied to /etc without a password. + +``` +deadlineuser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa /home/deadlineuser/openvpn_config/ca.crt /etc/openvpn/. +deadlineuser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa /home/deadlineuser/openvpn_config/client.crt /etc/openvpn/. +deadlineuser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa /home/deadlineuser/openvpn_config/client.key /etc/openvpn/. +deadlineuser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa /home/deadlineuser/openvpn_config/openvpn.conf /etc/openvpn/. +deadlineuser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa /home/deadlineuser/openvpn_config/ta.key /etc/openvpn/. +deadlineuser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa /home/deadlineuser/openvpn_config/yourserver.txt /etc/openvpn/. + +/home/deadlineuser ALL=(ALL:ALL) NOPASSWD:/bin/systemctl daemon-reload +/home/deadlineuser ALL=(ALL:ALL) NOPASSWD:/usr/sbin/service openvpn restart +``` + +instead, you may want to allow a group of users to be able to do this. + +Edit: THIS DIDN'T ACTUALLY WORK BECAUSE WE CANT USE RELATIVE PATHS IN SUDOERS. +the right way to do it if needed would be to have a non home dir path temp location, with appropraite permissions to read and write by the group on within that path. + +``` +%deadlineanduser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa ~/openvpn_config/ca.crt /etc/openvpn/. +%deadlineanduser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa ~/openvpn_config/client.crt /etc/openvpn/. +%deadlineanduser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa ~/openvpn_config/client.key /etc/openvpn/. +%deadlineanduser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa ~/openvpn_config/openvpn.conf /etc/openvpn/. +%deadlineanduser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa ~/openvpn_config/ta.key /etc/openvpn/. +%deadlineanduser ALL=(ALL:ALL) NOPASSWD:/bin/cp -rfa ~/openvpn_config/yourserver.txt /etc/openvpn/. + +%deadlineanduser ALL=(ALL:ALL) NOPASSWD:/bin/systemctl daemon-reload +%deadlineanduser ALL=(ALL:ALL) NOPASSWD:/usr/sbin/service openvpn restart +``` + +Keep in mind if this script will allow any input or editing of files, this will also be done as root. some more references on related subjects: +https://bbs.archlinux.org/viewtopic.php?id=126126 +https://askubuntu.com/questions/229800/how-to-auto-start-openvpn-client-on-ubuntu-cli +https://serverfault.com/questions/480909/how-can-i-run-openvpn-as-daemon-sending-a-config-file + +startvpn.sh is currently how open vpn configuration is handled locally. the files retrieved from remote access server +are needed for auto login to work. + +It would be better to replace this with an Ansible playbook instead. + + +## the tf_aws_openvpn module is creating the following resources: 1. Two Route53 Records a. vpn-web.domain.com @@ -45,7 +100,7 @@ module "openvpn" { vpc_cidr = "${var.vpc_cidr}" public_subnet_ids = "${var.public_subnet_ids}" # EC2 Inputs - key_name = "${var.key_name}" + key_name = "${var.aws_key_name}" private_key = "${var.private_key}" ami = "${var.ami}" instance_type = "${var.instance_type}" @@ -61,9 +116,69 @@ module "openvpn" { } ``` +## Important Notes for Routing: + +You can check /var/log/syslog to confirm vpn connection. +check autoload is set to all or openvpn in /etc/default +ensure startvpn.sh is in ~/openvpn_config. openvpn.conf auto login files are constructed here and placed in /etc/openvpn before execution. + +read more here to learn about setting up routes +https://openvpn.net/vpn-server-resources/site-to-site-routing-explained-in-detail/ +https://askubuntu.com/questions/612840/adding-route-on-client-using-openvpn + +You will need ip forwarding on client and server if routing both sides. +https://community.openvpn.net/openvpn/wiki/265-how-do-i-enable-ip-forwarding + +**These are the manual steps required to get both private subnets to connect, and we'd love to figure out the equivalent commands drop in when I'm provisioning the access server to automate them, but for now these are manual steps.** + +- Should VPN clients have access to private subnets +(non-public networks on the server side)? +Yes, enable routing + +- Specify the private subnets to which all clients should be given access (one per line): +10.0.101.0/24 +10.0.1.0/24 +(these subnets are in aws, the open vpn access server resides in the 10.0.101.0/24 subnet) + +- Allow access from these private subnets to all VPN client IP addresses and subnets : on + +- in user permissions / user +configure vpn gateway: +yes + +- Allow client to act as VPN gateway (enter the cidr block for your onsite network) +for these client-side subnets: +192.168.92.0/24 + +At this point, your client side vpn client should be able to ping any private ip, and if you ssh into one of those ips, it whould be able to ping your client side ip with its private ip address. + +If not you will have to trouble shoot before you can continue further because this functionality is required. + +if you intend to provide access to other systems on your local network, promiscuous mode must enabled on host ethernet adapters. for example, if openvpn client is in ubuntu vm, and we are running the vm with bridged ethernet in a linux host, then enabling promiscuous mode, and setting up a static route is needed in the host. +https://askubuntu.com/questions/430355/configure-a-network-interface-into-promiscuous-mode +for example, if you use a rhel host run this in the host to provide static route to the adaptor inside the vm (should be on the same subnet) +``` +sudo ip route add 10.0.0.0/16 via [ip adress of the bridged ethernet adaptor in the vm] +``` +check routes with: +``` +sudo route -n +ifconfig eth1 up +ifconfig eth1 promisc +``` + +In the ubuntu vm where where terraform is running, ip forwarding must be on. You must be using a bridged adaptor. +http://www.networkinghowtos.com/howto/enable-ip-forwarding-on-ubuntu-13-04/ + +``` +sudo sysctl net.ipv4.ip_forward=1 +``` + + ## Authors Created and maintained by [Quentin Rousseau](https://github.com/kwent) (contact@quent.in). +Autostart and Routing Abilities in this fork by Andrew Graham (https://github.com/queglay/) (queglay@gmail.com) ## License diff --git a/gitignore b/gitignore new file mode 100644 index 0000000..d61e3c1 --- /dev/null +++ b/gitignore @@ -0,0 +1,2 @@ +# plan files are temporary +**/tfplan \ No newline at end of file diff --git a/main.tf b/main.tf index baeac9e..fba0eaa 100644 --- a/main.tf +++ b/main.tf @@ -2,139 +2,237 @@ # This module creates all resources necessary for OpenVPN in AWS #---------------------------------------------------------------- -resource "aws_security_group" "openvpn" { - name = "${var.name}" - vpc_id = "${var.vpc_id}" - description = "OpenVPN security group" +# You should define this variable as your remote static ip adress to limit vpn exposure to the public internet - tags { - Name = "${var.name}" +variable "source_dest_check" { + default = true +} + +resource "null_resource" "gateway_dependency" { + triggers = { + igw_id = var.igw_id } +} - ingress { - protocol = -1 - from_port = 0 - to_port = 0 - cidr_blocks = ["${var.vpc_cidr}"] +resource "null_resource" "bastion_dependency" { + triggers = { + bastion_dependency = var.bastion_dependency + } +} +resource "aws_instance" "openvpn" { + count = var.create_vpn ? 1 : 0 + depends_on = [null_resource.gateway_dependency, null_resource.bastion_dependency] + ami = var.ami + # ami = local.ami + # needs VPNServerRole_${var.conflictkey} + # iam_instance_profile = "VPNServerProfile_${var.conflictkey}" + # iam_instance_profile = data.terraform_remote_state.openvpn_profile.instance_profile_name + iam_instance_profile = var.iam_instance_profile_name + instance_type = var.instance_type + key_name = var.aws_key_name + subnet_id = var.public_subnet_id + source_dest_check = var.source_dest_check + + vpc_security_group_ids = var.security_group_attachments + + root_block_device { + delete_on_termination = true } - # For OpenVPN Client Web Server & Admin Web UI + tags = merge(tomap({ "Name" : var.name }), var.common_tags, local.extra_tags) - ingress { - protocol = "tcp" - from_port = 22 - to_port = 22 - cidr_blocks = ["0.0.0.0/0"] - } - ingress { - protocol = "tcp" - from_port = 443 - to_port = 443 - cidr_blocks = ["0.0.0.0/0"] + # `admin_user` and `admin_pw` need to be passed in to the appliance through `user_data`, see docs --> + # https://docs.openvpn.net/how-to-tutorialsguides/virtual-platforms/amazon-ec2-appliance-ami-quick-start-guide/ + # Python is required for Ansible to function. + # user_data = < 0 ? aws_instance.openvpn[0].private_ip : null + _eip_public_ip = length(aws_eip.openvpnip) > 0 ? aws_eip.openvpnip[0].public_ip : null + _instance_public_ip = length(aws_instance.openvpn) > 0 ? aws_instance.openvpn[0].public_ip : null + public_ip = var.use_eip ? local._eip_public_ip : local._instance_public_ip + id = length(aws_instance.openvpn) > 0 ? aws_instance.openvpn[0].id : null + network_interface_id = length(aws_instance.openvpn) > 0 ? aws_instance.openvpn[0].primary_network_interface_id : null + vpn_address = var.route_public_domain_name ? "vpn.${var.public_domain_name}" : local.public_ip +} - tags { - Name = "${var.name}" +resource "aws_route53_record" "openvpn_record" { + count = var.route_public_domain_name && var.create_vpn ? 1 : 0 + zone_id = try(var.route_zone_id, null) + name = try("vpn.${var.public_domain_name}", null) + type = "A" + ttl = 300 + records = [local.public_ip] +} +resource "null_resource" "firehawk_init_dependency" { # ensure that the firehawk gateway has finished being prrovisioned because the next process may interupt its network connection + triggers = { + firehawk_init_dependency = var.firehawk_init_dependency } +} - # `admin_user` and `admin_pw` need to be passed in to the appliance through `user_data`, see docs --> - # https://docs.openvpn.net/how-to-tutorialsguides/virtual-platforms/amazon-ec2-appliance-ami-quick-start-guide/ - user_data = < >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 + +# These variables are passed in via Terraform template interpolation +/opt/consul/bin/run-consul --client --cluster-tag-key "${consul_cluster_tag_key}" --cluster-tag-value "${consul_cluster_tag_value}" + +# Log the given message. All logs are written to stderr with a timestamp. +function log { + local -r message="$1" + local -r timestamp=$(date +"%Y-%m-%d %H:%M:%S") + >&2 echo -e "$timestamp $message" +} + +# A retry function that attempts to run a command a number of times and returns the output +function retry { + local -r cmd="$1" + local -r description="$2" + + for i in $(seq 1 30); do + log "$description" + + # The boolean operations with the exit status are there to temporarily circumvent the "set -e" at the + # beginning of this script which exits the script immediatelly for error status while not losing the exit status code + output=$(eval "$cmd") && exit_status=0 || exit_status=$? + errors=$(echo "$output") | grep '^{' | jq -r .errors + + log "$output" + + if [[ $exit_status -eq 0 && -z "$errors" ]]; then + echo "$output" + return + fi + log "$description failed. Will sleep for 10 seconds and try again." + sleep 10 + done; + + log "$description failed after 30 attempts." + exit $exit_status +} + +export AWS_DEFAULT_REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/\(.*\)[a-z]/\1/') +public_ip=$(curl http://169.254.169.254/latest/meta-data/public-ipv4); echo "Public IP: $public_ip" +private_ip=$(curl http://169.254.169.254/latest/meta-data/local-ipv4); echo "Private IP: $private_ip" + +export VAULT_ADDR=https://vault.service.consul:8200 + +### Vault Auth IAM Method CLI +retry \ + "vault login --no-print -method=aws header_value=vault.service.consul role=${example_role_name}" \ + "Waiting for Vault login" + + +log "Request Vault sign's the SSH host key and becomes a known host for other machines." +# Allow access from clients signed by the CA. +trusted_ca="/etc/ssh/trusted-user-ca-keys.pem" +# Aquire the public CA cert to approve an authority +vault read -field=public_key ssh-client-signer/config/ca | tee $trusted_ca +if test ! -f "$trusted_ca"; then + log "Missing $trusted_ca" + exit 1 +fi +### Sign SSH host key +if test ! -f "/etc/ssh/ssh_host_rsa_key.pub"; then + log "Missing public host key /etc/ssh/ssh_host_rsa_key.pub" + exit 1 +fi +# Sign this host's public key +vault write -format=json ssh-host-signer/sign/hostrole \ + cert_type=host \ + public_key=@/etc/ssh/ssh_host_rsa_key.pub +# Aquire the cert +vault write -field=signed_key ssh-host-signer/sign/hostrole \ + cert_type=host \ + public_key=@/etc/ssh/ssh_host_rsa_key.pub | tee /etc/ssh/ssh_host_rsa_key-cert.pub +if test ! -f "/etc/ssh/ssh_host_rsa_key-cert.pub"; then + log "Failed to aquire /etc/ssh/ssh_host_rsa_key-cert.pub" + exit 1 +fi +chmod 0640 /etc/ssh/ssh_host_rsa_key-cert.pub +# Private key and cert are both required for ssh to another host. Multiple entries for host key may exist. +grep -q "^HostKey /etc/ssh/ssh_host_rsa_key" /etc/ssh/sshd_config || echo 'HostKey /etc/ssh/ssh_host_rsa_key' | tee --append /etc/ssh/sshd_config +# Configure host cert to be recognised as a known host. +grep -q "^HostCertificate" /etc/ssh/sshd_config || echo 'HostCertificate' | tee --append /etc/ssh/sshd_config +sed -i 's@HostCertificate.*@HostCertificate /etc/ssh/ssh_host_rsa_key-cert.pub@g' /etc/ssh/sshd_config + +# Configure VPN Gateway +client_network=${client_network} +client_netmask_bits=${client_netmask_bits} +combined_vpcs_cidr=${combined_vpcs_cidr} +aws_internal_domain=${aws_internal_domain} +onsite_private_subnet_cidr=${onsite_private_subnet_cidr} + +ls -la /usr/local/openvpn_as/scripts/ + +# see https://evanhoffman.com/2014/07/22/openvpn-cli-cheat-sheet/ + +# # this may need to be in the image +# /usr/local/openvpn_as/scripts/sacli Init +/usr/local/openvpn_as/scripts/sacli -k vpn.daemon.0.client.network -v $client_network ConfigPut +/usr/local/openvpn_as/scripts/sacli -k vpn.daemon.0.client.netmask_bits -v $client_netmask_bits ConfigPut +/usr/local/openvpn_as/scripts/sacli --key 'vpn.server.tls_auth' --value 'true' ConfigPut +/usr/local/openvpn_as/scripts/sacli --key vpn.server.routing.gateway_access --value 'true' ConfigPut +/usr/local/openvpn_as/scripts/sacli --key vpn.server.routing.private_network.2 --value "$client_network/$client_netmask_bits" ConfigPut +/usr/local/openvpn_as/scripts/sacli --key vpn.server.routing.private_network.0 --value "$combined_vpcs_cidr" ConfigPut +/usr/local/openvpn_as/scripts/sacli --key vpn.server.routing.private_access --value 'route' ConfigPut +/usr/local/openvpn_as/scripts/sacli --key 'vpn.client.routing.reroute_dns' --value 'true' ConfigPut +/usr/local/openvpn_as/scripts/sacli --key 'vpn.server.dhcp_option.domain' --value "$aws_internal_domain" ConfigPut +/usr/local/openvpn_as/scripts/sacli --key 'vpn.server.routing.allow_private_nets_to_clients' --value 'true' ConfigPut + +# ensure listen on interfaces at default. restore ip since the old one during ami build is now invalid. +/usr/local/openvpn_as/scripts/sacli --key "vpn.daemon.0.server.ip_address" --value "all" ConfigPut +/usr/local/openvpn_as/scripts/sacli --key "vpn.daemon.0.listen.ip_address" --value "all" ConfigPut +/usr/local/openvpn_as/scripts/sacli --key "vpn.server.daemon.udp.port" --value "1194" ConfigPut +/usr/local/openvpn_as/scripts/sacli --key "vpn.server.daemon.tcp.port" --value "443" ConfigPut +/usr/local/openvpn_as/scripts/sacli --key "host.name" --value "$public_ip" ConfigPut + +/usr/local/openvpn_as/scripts/sacli start + +cd /usr/local/openvpn_as/scripts/ +/usr/local/openvpn_as/scripts/sacli --user $openvpn_user --key 'prop_autologin' --value 'true' UserPropPut +/usr/local/openvpn_as/scripts/sacli --user $openvpn_user --key 'c2s_route.0' --value "$onsite_private_subnet_cidr" UserPropPut +/usr/local/openvpn_as/scripts/sacli --user $openvpn_user AutoGenerateOnBehalfOf +mkdir -p /usr/local/openvpn_as/scripts/seperate +/usr/local/openvpn_as/scripts/sacli -o ./seperate --cn "${openvpn_user}_AUTOLOGIN" get1 +chown $openvpn_user seperate/* +/usr/local/openvpn_as/scripts/sacli start +ls -la seperate + +# show entire config +/usr/local/openvpn_as/scripts/sacli ConfigQuery + +### Store Generated keys and password with vault +echo "Storing keys with vault..." +set +x + vault kv put -address="$VAULT_ADDR" -format=json $resourcetier/network/openvpn_admin_pw value="$admin_pw" + vault kv put -address="$VAULT_ADDR" -format=json $resourcetier/network/openvpn_user_pw value="$openvpn_user_pw" + +log "Revoking vault token..." +vault token revoke -self + +set -o history +echo "Done." diff --git a/user-data-register-consul-service.sh b/user-data-register-consul-service.sh new file mode 100644 index 0000000..1baf1e5 --- /dev/null +++ b/user-data-register-consul-service.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -e +exec > >(tee -a /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 + +# Register the service with consul. not that it may not be necesary to set the hostname in the beggining of this user data script, especially if we create a cluster in the future. +echo "...Registering service with consul" +service_name="${consul_service}" +consul services register -name=$service_name +sleep 5 +consul catalog services +dig $service_name.service.consul +result=$(dig +short $service_name.service.consul) && exit_status=0 || exit_status=$? +if [[ ! $exit_status -eq 0 ]]; then echo "No DNS entry found for $service_name.service.consul"; exit 1; fi diff --git a/user-data-vault-store-file.sh b/user-data-vault-store-file.sh new file mode 100644 index 0000000..9c9f69c --- /dev/null +++ b/user-data-vault-store-file.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +set -e +exec > >(tee -a /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1 + +# User Vars: Set by terraform template +resourcetier="${resourcetier}" +example_role_name="${example_role_name}" + +# Script vars (implicit) +export VAULT_ADDR="https://vault.service.consul:8200" +client_cert_file_path="${client_cert_file_path}" +client_cert_vault_path="${client_cert_vault_path}" + +# Functions +function log { + local -r message="$1" + local -r timestamp=$(date +"%Y-%m-%d %H:%M:%S") + >&2 echo -e "$timestamp $message" +} +function has_yum { + [[ -n "$(command -v yum)" ]] +} +function has_apt_get { + [[ -n "$(command -v apt-get)" ]] +} +# A retry function that attempts to run a command a number of times and returns the output +function retry { + local -r cmd="$1" + local -r description="$2" + attempts=5 + + for i in $(seq 1 $attempts); do + log "$description" + + # The boolean operations with the exit status are there to temporarily circumvent the "set -e" at the + # beginning of this script which exits the script immediatelly for error status while not losing the exit status code + output=$(eval "$cmd") && exit_status=0 || exit_status=$? + errors=$(echo "$output") | grep '^{' | jq -r .errors + + log "$output" + + if [[ $exit_status -eq 0 && -z "$errors" ]]; then + echo "$output" + return + fi + log "$description failed. Will sleep for 10 seconds and try again." + sleep 10 + done; + + log "$description failed after $attempts attempts." + exit $exit_status +} +function store_file { + local -r file_path="$1" + if [[ -z "$2" ]]; then + local target="$resourcetier/vpn/client_cert_files/$file_path" + else + local target="$2" + fi + if sudo test -f "$file_path"; then + vault kv put -address="$VAULT_ADDR" "$target/file" value="$(sudo cat $file_path | base64 -w 0)" + if [[ "$OSTYPE" == "darwin"* ]]; then # Acquire file permissions. + octal_permissions=$(sudo stat -f %A $file_path | rev | sed -E 's/^([[:digit:]]{4})([^[:space:]]+)/\1/' | rev ) # clip to 4 zeroes + else + octal_permissions=$(sudo stat --format '%a' $file_path | rev | sed -E 's/^([[:digit:]]{4})([^[:space:]]+)/\1/' | rev) # clip to 4 zeroes + fi + octal_permissions=$( python3 -c "print( \"$octal_permissions\".zfill(4) )" ) # pad to 4 zeroes + file_uid="$(sudo stat --format '%u' $file_path)" + file_gid="$(sudo stat --format '%g' $file_path)" + blob="{ \ + \"permissions\":\"$octal_permissions\", \ + \"owner\":\"$(sudo id -un -- $file_uid)\", \ + \"uid\":\"$file_uid\", \ + \"gid\":\"$file_gid\", \ + \"format\":\"base64\" \ + }" + jq_parse=$( echo "$blob" | jq -c -r '.' ) + vault kv put -address="$VAULT_ADDR" -format=json "$target/permissions" value="$jq_parse" + else + print "Error: file not found: $file_path" + exit 1 + fi +} + +### Vault Auth IAM Method CLI +retry \ + "vault login --no-print -method=aws header_value=vault.service.consul role=${example_role_name}" \ + "Waiting for Vault login" +# Store generated certs in vault +echo "...Store certificate." +store_file "$client_cert_file_path" "$client_cert_vault_path" +echo "Revoking vault token..." +vault token revoke -self diff --git a/variables.tf b/variables.tf index abec526..0d074b1 100644 --- a/variables.tf +++ b/variables.tf @@ -1,22 +1,198 @@ +variable "resourcetier" { + description = "The resource tier speicifies a unique name for a resource based on the environment. eg: dev, green, blue, main." + type = string +} + +variable "security_group_attachments" { + description = "The Security Group ID to attach to this instance" + type = list( string ) +} + +variable "pipelineid" { + description = "The pipelineid variable can be used to uniquely specify and identify resource names for a given deployment. The pipeline ID could be set to a job ID in CI software for example. The default of 0 is fine if no more than one concurrent deployment run will occur." + type = string + default = "0" +} + +variable "conflictkey" { + description = "The conflictkey is a unique name for each deployement usuallly consisting of the resourcetier and the pipeid." + type = string +} +variable "example_role_name" { + description = "The name of the vault role. (Note: This is not the AWS role name.)" + type = string + default = "example-role" +} +variable "consul_cluster_name" { + description = "What to name the Consul server cluster and all of its associated resources" + type = string + # default = "consul-example" +} + +variable "consul_cluster_tag_key" { + description = "The tag the Consul EC2 Instances will look for to automatically discover each other and form a cluster." + type = string + default = "consul-servers" +} variable "name" { default = "openvpn" + type = string } -variable "vpc_id" {} -variable "vpc_cidr" {} +variable "create_vpn" {} -variable "public_subnet_ids" { - type = "list" +variable "vpc_id" { } -variable "cert_arn" {} -variable "key_name" {} -variable "private_key" {} +variable "vpc_cidr" { +} + +variable "remote_vpn_ip_cidr" { + default = "0.0.0.0/0" +} + +variable "public_subnet_id" { + default = null +} + +# variable "cert_arn" { +# } + +variable "aws_key_name" { +} + +variable "use_bastion" { + description = "If enabled, will open ssh ports to a bastion host for provisioning. This shouldn't be required if provisioning via private subnet." + type = bool + default = false +} + +variable "bastion_ip" { + description = "The IP address of the bastion for access" + type = string + default = "none" +} + +# variable "private_key" { +# } + +# variable "aws_private_key_path" { +# } + +variable "instance_type" { +} + +variable "openvpn_user" { +} + +# variable "openvpn_user_pw" { +# description = "The user password used to login to Open VPN Access Server." +# type = string +# validation { +# condition = ( +# length(var.openvpn_user_pw) >= 8 +# ) +# error_message = "The openvpn_user_pw configured in vault must be at least 8 characters in length." +# } +# } + +variable "openvpn_admin_user" { + description = "The admin user name used to configure OpenVPN Access Server" + default = "openvpnas" +} + +# variable "openvpn_admin_pw" { +# description = "The admin password used to login to Open VPN Access Server." +# type = string +# validation { +# condition = ( +# length(var.openvpn_admin_pw) >= 8 +# ) +# error_message = "The openvpn_admin_pw configured in vault must be at least 8 characters in length." +# } +# } + +variable "use_eip" { + description = "Allows the provisioning of an elsatice IP" + type = bool + default = false +} + +variable "vpn_cidr" { + description = "The CIDR range that the vpn will assign using DHCP. These are virtual addresses for routing traffic." + type = string +} + +variable "onsite_private_subnet_cidr" { + description = "The subnet CIDR Range of your onsite private subnet. This is also the subnet where your VPN client resides in. eg: 192.168.1.0/24" + type = string +} + +variable "public_domain_name" { + description = "(Optional) The public domain if required for DNS names of hosts eg: vpn.example.com" + type = string + default = null +} + +variable "route_zone_id" { +} + +variable "sleep" { + default = false +} + +variable "igw_id" { +} + +variable "private_subnets" { + default = [] +} + +variable "public_subnets" { + default = [] +} + +variable "bastion_dependency" { + default = "None" +} + +variable "firehawk_init_dependency" { + default = "None" +} + +variable "private_route_table_ids" {} +variable "public_route_table_ids" {} variable "ami" {} -variable "instance_type" {} -variable "openvpn_user" {} -variable "openvpn_admin_user" {} -variable "openvpn_admin_pw" {} -variable "vpn_cidr" {} -variable "domain_name" {} -variable "route_zone_id" {} + +variable "iam_instance_profile_name" { + description = "The name of the instance profile to attach to the VPN" + type = string +} + +variable "common_tags" { + description = "Common tags for all resources in a deployment run." + type = map(string) +} + +variable "combined_vpcs_cidr" { + description = "Terraform will automatically configure multiple VPCs and subnets within this CIDR range for any resourcetier ( dev / green / blue / main )." + type = string +} + +variable "route_public_domain_name" { +} + +variable "sqs_remote_in_vpn" { + description = "The SQS queue URL for a remote client to observe messages to establish connection with the VPN Server." + type = string +} + +variable "host1" { + description = "The user@publichost string to connect to the bastion host to aquire vpn credentials from Vault." + type = string +} + +variable "host2" { + description = "The user@privatehost string to connect to the vault client to aquire vpn credentials from Vault." + type = string +} \ No newline at end of file diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..bd97f68 --- /dev/null +++ b/versions.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.6.0" + } + null = { + source = "hashicorp/null" + version = "~> 3.0" + } + } + required_version = ">= 0.13" +}