Terraform module which creates Client VPN Endpoint resources on AWS.
These type of resources are supported:
- ACM Certificate
- EC2 Client VPN Endpoint
- EC2 Client VPN Network association
- CloudWatch Log Group
- CloudWatch Log Stream
Terraform 0.12 and newer.
Name | Version |
---|---|
terraform | >= 0.12 |
aws | >= 2.49 |
bash |
- Client certificate revocation list
- Self Service VPN Portal
This project is using terraform to deploy infrastructure, you can download it here: https://learn.hashicorp.com/tutorials/terraform/install-cli
$ cd ./tf
$ terraform init
$ terraform plan
$ terraform apply
You may need to add execution permission :
chmod u+x .terraform/modules/client_vpn/scripts/*
$ terraform destroy
- AWS VPN Client download link : https://aws.amazon.com/vpn/client-vpn-download/
- You can find the generated Client VPN configuration into your terraform folder.
- Each user have a login/password to authenticate.
module "client_vpn" {
source = "github.com/trackit/terraform-aws-client-vpn?ref=v0.2.0"
region = "us-east-1"
env = "production"
cert_issuer = "mycompany.internal"
cert_server_name = "mycompany"
aws_tenant_name = "aws"
clients = ["client"]
subnet_id = "subnet-12345678"
client_cidr_block = "10.250.0.0/16"
target_cidr_block = "10.0.0.0/16"
vpn_name = "My VPN Endpoint"
client_auth = "federated-authentication"
saml_provider_arn = "arn:12345678"
}
- You can find the generated Client VPN configuration into your terraform folder.
- Be carefull no user/password needed. Only the configuration file so do not lost it.
module "client_vpn" {
source = "github.com/trackit/terraform-aws-client-vpn?ref=v0.2.0"
region = "us-east-1"
env = "production"
cert_issuer = "mycompany.internal"
cert_server_name = "mycompany"
aws_tenant_name = "aws"
clients = ["client"]
subnet_id = "subnet-12345678"
client_cidr_block = "10.250.0.0/16"
target_cidr_block = "10.0.0.0/16"
vpn_name = "My VPN Endpoint"
client_auth = "certificate-authentication"
}
Name | Description | Type | Default |
---|---|---|---|
region | Region to work on. | string | |
env | The environment (e.g. prod, dev, stage) | string | "prod" |
clients | A list of client certificate name | list(string) | ["client"] |
cert_issuer | Common Name for CA Certificate | list(string) | "CA" |
cert_server_name | Name for the Server Certificate | string | "Server" |
aws_tenant_name | Name for the AWS Tenant | string | "AWS" |
key_save_folder | Where to store keys (relative to pki folder) | string | "clientvpn_keys" |
subnet_id | The subnet ID to which we need to associate the VPN Client Connection. | string | |
target_cidr_block | The CIDR block to wich the client will have access to. Might be VPC CIDR's block for example. | string | |
dns_servers | Information about the DNS servers to be used for DNS resolution. A Client VPN endpoint can have up to two DNS servers. | list(string) | null |
vpn_name | The name of the VPN Client Connection. | string | "VPN" |
cloudwatch_enabled | Indicates whether connection logging is enabled. | bool | true |
cloudwatch_log_group | The name of the cloudwatch log group. | string | vpn_endpoint_cloudwatch_log_group |
cloudwatch_log_stream | The name of the cloudwatch log stream. | string | vpn_endpoint_cloudwatch_log_stream |
aws_cli_profile_name | The name of the aws cli profile used in scripts | string | default |
client_auth | the type of client authentication to be used : certificate-authentication / directory-service-authentication / federated-authentication | string | certificate-authentication |
active_directory_id | The ID of the Active Directory to be used for authentication if type is directory-service-authentication | string | null |
root_certificate_chain_arn | The ARN of the client certificate. The certificate must be signed by a certificate authority (CA) and it must be provisioned in AWS Certificate Manager (ACM). Only necessary when type is set to certificate-authentication. | string | null |
saml_provider_arn | The ARN of the IAM SAML identity provider if type is federated-authentication | string | null |
Name | Description |
---|---|
kms_sops_arn | |
decrypt_command | Output of the decrypt script |
encrypt_command | Output of the encrypt script |
server_certificate_arn | The ARN of the generated Server Certificate |
env | Environment variable |
pki_folder_name | Generated certificate folder |
client_vpn_endpoint_id | The ID of the Client VPN endpoint. |
client_vpn_endpoint_arn | The ARN of the Client VPN endpoint. |
client_vpn_endpoint_dns_name | The DNS name to be used by clients when establishing their VPN session. |
client_vpn_endpoint_status | The current state of the Client VPN endpoint. |
- Clone the latest easy-rsa repo.
- Generate the CA and Server certificates and keys.
- Copy the files to the defined KEY_SAVE_FOLDER.
- the Server certificate is uploaded into AWS ACM.
- Using the previous created PKI, generate a client certificate / key pair.
- Then move it to the KEY_SAVE_FOLDER.
resource "aws_ec2_client_vpn_endpoint" "client_vpn" {
depends_on = [aws_acm_certificate.server_cert]
description = var.vpn_name
server_certificate_arn = aws_acm_certificate.server_cert.arn
client_cidr_block = var.client_cidr_block
split_tunnel = true
dns_servers = var.dns_servers
lifecycle {
ignore_changes = [server_certificate_arn, authentication_options]
}
authentication_options {
type = var.client_auth
active_directory_id = var.active_directory_id
root_certificate_chain_arn = var.root_certificate_chain_arn
saml_provider_arn = var.saml_provider_arn
}
connection_log_options {
enabled = var.cloudwatch_enabled
cloudwatch_log_group = aws_cloudwatch_log_group.client_vpn.name
cloudwatch_log_stream = aws_cloudwatch_log_stream.client_vpn.name
}
provisioner "local-exec" {
environment = merge(local.provisioner_base_env, {
"CLIENT_VPN_ID" = self.id
})
command = "${path.module}/scripts/authorize_client.sh"
}
tags = {
Name = var.vpn_name
}
}
- With aws-cli allow traffic to TARGET_CIDR from CLIENT_VPN_ID
- With aws-cli export the ovpn configuration file.
- Add the client certificate to end of it.
- Add the opvn configuration to AWS VPN Client.
- Start the VPN.