End-to_End CI/CD Deployment to Kubernetes¶
Setup and Host Your Own Free VPN Server on AWS Using Terraform and OpenVPN¶
In this mini-project, I will demonstrate how to setup and self-host a VPN server on AWS using terraform and OpenVPN Access Server.
Watch the Video - How To Create a Free Self-Hosted VPN Server on AWS using Terraform and OpenVPN
How to Create a Free Self-Hosted VPN Server on AWS using Terraform and OpenVPN
Introduction¶
Setting up a self-hosted VPN server can be a cost-effective and secure solution for personal or organizational needs. This documentation provides a step-by-step guide on using a Terraform configuration script to deploy an OpenVPN Access server on AWS.
With this guide, you'll learn how to configure the script, customize it for your requirements, and launch a fully functional VPN server in less than 5-minutes and ensures your internet traffic remains private and encrypted without been locked in a vpn subscription plan.
This VPN server is also "disposable", meaning, you can create and delete it anytime after use with just one command
Pre-requisites¶
- AWS account (free tier account will work )
- Terraform installed on local machine (How to Install Terraform )
- OpenVPN Connect Client software installed on local machine (download from here)
- Your AWS access key ID and secret access key (learn how to get your AWS access keys here )
- AWS CLI installed and configured with your AWS access key ID and Secret access keys (learn more about AWS CLI here )
-
The OpenVPN-Terraform Setup Script (click the button below)
Install Gitleaks*¶
Workflow¶
- Run Terraform to setup Jenkins
- Confiure Jenkins
- install plugins: Go to
Dashboard > Manage Jenkins > Manage Plugins
and install the following plugins:- SonarQube Scanner
- docker
- docker pipeline
- docker build step
- cloudbees docker build and publish
- kubernetes
- kubernetes CLI
- Email Extension Template
- Prometheus Metrics
- OWASP Dependency Check Plugin
- install plugins: Go to
Configure Plugins¶
SonarQube¶
-
Server Name: sonar (Or use a suitable name)
-
Server URL:
<sonar_server_ip:9000>
Tip
Since our SonarQube server is running as a docker container on port 9000
on the same machine as the Jenkins server, use http://<server_ip_address>:9000
as the Server URL
Prometheus¶
- No further configuration needed
- By default, the Prometheus metrics will be scrapped from
http://<jenkins_server_ip:8080>/prometheus
Docker Hub Credentials¶
- Configure Docker Credentials to enable pushing docker images to Docker Hub
Jenkins Email Notifications¶
Goto Dashboard > Manage Jenkins > System
and configure both the "Extended E-mail Notification" and the "E-mail Notification" sections as below:
- SMTP Server Name: smtp.gmail.com
- SMTP Port: 465
- Username:
user_email_id@gmail.com
- Password:
app_password
- Use SSL: checked
- System Admin e-mail address:
<Admin_Name> <user_email_id@gmail.com>
- Default Content Type:
HTML
- Test email delivery
Note
- The settings above apply to Gmail address configuration. Confirm SMTP settings from your email service provider.
- Copy
App password
from your gmail account security settings and use that as the password in the above configuration.
What this Terraform Configuration Script Does¶
This terraform configuration creates a fully functional, free and ready-to-use self-hosted OpenVPN Server in any chosen AWS region. The script perfomes the following operations:
- Creates a Ubuntu 22.04 EC2 instance and configures a fully functional OpenVPN Access Server on it
- Configures the server as a type t2-micro instance so that it can run within the AWS Free-tier plan (Learn more about the AWS free-tier plan here)
- Sets up and configures the VPN server with an IP address in the speicified AWS region.
- Generates an AWS keypair file for optional SSH connection to the EC2 instance, downloads the file and saves it in the terraform working directory on your local machine. The chosen AWS region is appended to the name of the keypair file.
- Generates an OpenVPN User Profile file (*.ovpn) that will be used to authenticate and establish an encrypted VPN connection from your local machine to the VPN server. The OpenPVN User Profile file is also donwloaded and saved to the terraform working directory on your local machine.
- One command tear down that destroys and cleans up the whole infrastructure along with the locally created files (the keypair file and the *.ovpn user profile file)
Jenkins Pipeline Script¶
Copy the script below and paste into the job pipeline section:
Jenkins Pipeline script for the Jenkins job
The Jenkins CI/CD pipeline is below:
The Jenkins Pipeline Script
Jenkins Pipeline Script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
|
- Lines 6-9 filters the name of the ami "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
- Lines 11-14 filters the virtualization type of the ami
- Line 16 filters the AWS account ID of the ami publisher - Canonical
This ami.tf
is used to find the latest Ubuntu 22.04 AMI (Amazon Machine Image) from the AWS ami Catalog.
-
It creates a data source named "ubuntu" that searches for AMIs with these criteria:
-
Uses most_recent = true to get the latest version
-
Filters for Ubuntu 22.04 (Jammy Jellyfish) images using the name pattern
-
Ensures it's using HVM (Hardware Virtual Machine) virtualization
-
Only looks for images owned by Canonical (Ubuntu's publisher) using their AWS account ID (099720109477)
-
This prevents hardcoding a specific AMI ID into the script, which could become outdated. The AMI ID is then referenced elsewhere in the Terraform code using data.aws_ami.ubuntu.id
The OpenVPN_ec2.tf
file
OpenVPN_ec2.tf
Jenkins Plugins to install¶
- sonar
- SonarQube Scanner
- docker
- docker pipeline
- docker build step
- cloudbees docker build and publish
- kubernetes
- kubernetes CLI
- Email Notifications
- Extended Email Notifications
- Prometheus Metrics
Jenkins Email Configuration¶
- SMTP Server Name: smtp.gmail.com
- Username: user_email_id@gmail.com
- Password: app_password
- Use SSL: checked
- SMTP Port: 465
Setting the script options¶
The script allows you to set some options based on your use case. These are the available options you can set:
- project_name - This is used for labelling purposes only. It is appended to the resource tags
- OpenVPN_instance_type - This has been set to
t2-micro
so the setup remains within the AWS free-tier plan. You can change this to any suitable instance type but a t2-micro will server in most situations - openvpn_user - This is the username used to create the
*.ovpn
profile file on the VPN server. The profile name is displayed when you connect through the OpenVPN client. It is currently set to append the selected AWS region so you can easily know which region you are connected to. - selected_region - this option is set at runtime and it is required for the script to run. Here you select the AWS region where you want your server to be hosted. The region you select will determine where your VPN traffic is routed through. For example, if you select
ca-central-1
, your VPN traffic will be routed through the AWS Canada Central IP address and as such your public IP address will read "Quebec, Montreal, Canada"
Public IP address showing Canada
The list of acceptable AWS regions are shown here
¶
AWS IAM Policies required for EKS Cluster Creation¶
- AmazonEC2FullAccess
- AmazonEKS_CNI_Policy
- AmazonEKSClusterPolicy
- AmazonEKSWorkerNodePolicy
- AmazonPCIFullAccess
- AWSCloudFormationFullAccess
- IAMFullAccess
- IAMUserChangePolicy
Install and setup Prometheus Stack on EKS using Helm¶
Install Helm¶
Check Helm version¶
Add Helm repo¶
(Optionally) Search Available Hem Charts
create namespace¶
Install Prometheus Stack into monitoring namespace¶
Check running status of pods to verify deployment¶
OR
List all svc in the monitoring namespace¶
Display Grafana URL (optional)¶
Display Prometheus URL (optional)¶
Change Grafana Service Type from ClusterIP to LoadBalancer to expose for external access¶
Change Prometheus Service Type from ClusterIP to LoadBalancer to expose for external access¶
Display LoadBalancer URL for Grafana and Prometheus. Wait for the EXTERNAL-IP field to be populated, then open that IP in your browser (Grafana on port 80, Prometheus on port 9090)¶
Get Grafana password by running:¶
- Username is
admin
Install & Configure Node-Exporter on linux¶
To Scrape metrics from a standalone Linux server running node_exporter using a Prometheus instance running inside EKS¶
β Prerequisites:¶
- Prometheus is installed via Helm chart (likely the kube-prometheus-stack).
- node_exporter is running and accessible on the Linux server (default port: 9100).
- The Linux server's IP address is publicly accessible or reachable from within the EKS cluster (e.g., via VPC Peering, VPN, or internal networking).
- Security Groups and firewall rules allow traffic from EKS nodes to port
9100
on the standalone server.
π Steps to Add Standalone Server to Prometheus Scrape Targets:¶
- Create Additional Scrape Config via Secret
- Create a file named
additional-scrape-configs.yaml
with the following content:
Replace <server-ip>
with the IP address or DNS name of your standalone Linux server.
- Now create a Kubernetes secret:
-
Edit Prometheus Custom Resource
-
First get the prometheus resource name
- Then edit the prometheus custom resource
Under spec
add:
So the result should look like this:
- Apply and Verify
Prometheus will reload its config automatically by deafult. Wait a minute, then:
- Go to the Prometheus UI (
/targets
page). - Look for the job
node-exporter-standalone
. - Ensure itβs marked as UP.
To Uninstall Prometheus-Stack and delete namespace¶
¶
Question
Why do you call EKS Distro a Kubernetes distribution?
Answer
EKS Distro is a distro of the same open source Kubernetes and dependencies
deployed by Amazon EKS. We include binaries and containers of open source
Kubernetes, etcd
, networking, and storage plugins, all of which are tested
for compatibility. We provide extended support for Kubernetes versions after
community support expires by updating builds of previous versions with the
latest critical security patches. You can securely access EKS Distro releases
from GitHub or within AWS via Amazon S3 and ECR for a common source of
releases and updates.
Is this a fork of Kubernetes-1?¶
Question
Why do you call EKS Distro a Kubernetes distribution?
Answer
EKS Distro is a distro of the same open source Kubernetes and dependencies
deployed by Amazon EKS. We include binaries and containers of open source
Kubernetes, etcd
, networking, and storage plugins, all of which are tested
for compatibility. We provide extended support for Kubernetes versions after
community support expires by updating builds of previous versions with the
latest critical security patches. You can securely access EKS Distro releases
from GitHub or within AWS via Amazon S3 and ECR for a common source of
releases and updates.
Is this a fork of Kubernetes-2?¶
Question
Why do you call EKS Distro a Kubernetes distribution?
Answer
EKS Distro is a distro of the same open source Kubernetes and dependencies
deployed by Amazon EKS. We include binaries and containers of open source
Kubernetes, etcd
, networking, and storage plugins, all of which are tested
for compatibility. We provide extended support for Kubernetes versions after
community support expires by updating builds of previous versions with the
latest critical security patches. You can securely access EKS Distro releases
from GitHub or within AWS via Amazon S3 and ECR for a common source of
releases and updates.
Is this a fork of Kubernetes?¶
Question
Why do you call EKS Distro a Kubernetes distribution?¶
Answer
EKS Distro is a distro of the same open source Kubernetes and dependencies
deployed by Amazon EKS. We include binaries and containers of open source
Kubernetes, etcd
, networking, and storage plugins, all of which are tested
for compatibility. We provide extended support for Kubernetes versions after
community support expires by updating builds of previous versions with the
latest critical security patches. You can securely access EKS Distro releases
from GitHub or within AWS via Amazon S3 and ECR for a common source of
releases and updates.
## Question-Main
Why do you call EKS Distro a Kubernetes distribution-1?¶
Question
Why do you call EKS Distro a Kubernetes distribution-2?¶
Answer
EKS Distro is a distro of the same open source Kubernetes and dependencies
deployed by Amazon EKS. We include binaries and containers of open source
Kubernetes, etcd
, networking, and storage plugins, all of which are tested
for compatibility. We provide extended support for Kubernetes versions after
community support expires by updating builds of previous versions with the
latest critical security patches. You can securely access EKS Distro releases
from GitHub or within AWS via Amazon S3 and ECR for a common source of
releases and updates.
¶
Running the script¶
Follow the "Quick Start Guide" below to provision and configure your OpenVPN server and to connect to your new VPN network.
Quick Start Guide¶
Click here for a quick start guide on setting up the OpenVPN Access Server
Clone the Repository¶
Create a folder on your local machine and clone the repository in the folder
Initialize the terraform configuration¶
From within the cloned directory, initialize the terraform configuration
Terraform Initialiaztion Command
Apply the Terraform Configuration¶
- When prompted, enter an AWS region from the list below and press enter. (e.g.
us-west-2
) - This will be the AWS region where the VPN server and all resources will be hosted.
Terraform apply command
List of accepted AWS regions¶
- us-east-1 = N. Virginia
- us-east-2 = Ohio
- us-west-1 = N. California
- us-west-2 = Oregon
- af-south-1 = Cape Town
- ap-east-1 = Hong Kong
- ap-south-1 = Mumbai
- ap-southeast-1 = Singapore
- ap-southeast-2 = Sydney
- ap-southeast-3 = Jakarta
- ap-northeast-1 = Tokyo
- ap-northeast-2 = Seoul
- ap-northeast-3 = Osaka
- ca-central-1 = Canada Central
- eu-central-1 = Frankfurt
- eu-west-1 = Ireland
- eu-west-2 = London
- eu-west-3 = Paris
- eu-north-1 = Stockholm
- eu-south-1 = Milan
- eu-south-2 = Zurich
- me-south-1 = Bahrain
- me-central-1 = UAE
- sa-east-1 = SΓ£o Paulo
Outputs¶
At the end of the terraform apply command, the script outputs the following details on the screen:
- The Public IP address of the VPN Server
- The instance-ID
- The name of the keypair created
- The path where the private key file was saved on your local machine
- SSH connection string that you can use to the VPN server
- The OpenVPN profile file that you will use to ssh into the VPN server
- Further steps to launch your VPN connection
Terraform Output Screen
Showing the OpenVPN server on the AWS EC2 Console
AWS Console Showing the OpenVPN Server details
Connect to your VPN¶
- Download and install OpenVPN Connect client on your local machine
- Import the
*.ovpn
file into the OpenVPN cient appllication - Connect to your VPN network
OpenVPN Client Connected to the VPN
Testing your VPN Connection¶
One very simple way to check if you are actually connected to your new VPN network is to open your browser and check your public IP address. You can use websites like whatsmyip.com or simply search "what is my ip address" on Google to check your public IP address.
Public IP address showing Canada
When you are connected to your VPN server, your internet traffic will be routed through your VPN server and as such, only your VPN server IP address will be seen publicly, your local ISP assigned ip address will be hidden from the internet.
Cleanup¶
To delete the server and cleanup all resources that were created.
-
First disconnect the OpenVPN Connect Client
-
Then enter the command below to delete all locally created files and also delete the server and all other resources from your AWS account.
- This will terminate the EC2 instance and delete all resources created and also delete the files that were locally created in the terraform working directory i.e. the *.ovpn user profile and the keypair file that was created earlier
Terraform Destroy Command
Use Cases¶
This self-hosted OpenVPN solution offers flexibility, control, and enhanced security compared to commercial VPN services. Here are some possible use cases:
1. Secure Remote Access
- Corporate Network Access: Allow employees to securely connect to on-premises resources or internal systems.
- Remote Development: Enable developers to work on private servers or cloud environments without exposing them to the public internet.
2. Privacy and Anonymity
- Encrypt Internet Traffic: Protect personal or organizational internet traffic, especially when using public Wi-Fi.
- Location Masking: Access the internet as if from a specific location to bypass geolocation restrictions.
3. Secure Inter-Office Communication
- Branch Office Connectivity: Connect multiple office locations securely over a shared network.
- IoT Devices: Secure communication for IoT devices spread across different sites.
4. Personal Use
- Ad-Free Browsing: Avoid invasive tracking and ads by routing traffic through your onw self-hosted VPN server.
- Bypass ISP Throttling: Prevent internet service providers from throttling bandwidth for specific services.
5. Development and Testing
- Environment Testing: Simulate network environments for application development and QA testing.
- Access Restricted APIs: Connect securely to APIs or other restricted services during development.
6. Secure Cloud Resources
- Private Cloud Access: Connect securely to AWS resources without exposing them to the public internet.
- DevOps Pipelines: Ensure secure deployment pipelines that require private network connectivity.
7. Enhanced Security
- Multi-Layered Security: Combine a self-hosted VPN with firewalls or IDS/IPS systems to add another layer of protection.
- Self-Controlled Data: Prevent third-party logging or tracking of your internet activity.
8. Education and Research
- Bypass Censorship: Enable access to academic resources or restricted sites in regions with strict censorship.
- Research Anonymity: Conduct secure and private research online.
9. Cost Efficiency
- Avoiding Commercial VPN Costs: Reduce long-term expenses for secure connections, especially for teams or organizations.
- No User Limits: Create a solution tailored to your usage, avoiding per-user or bandwidth fees common with commercial VPNs.
10. Gaming and Media
- LAN Gaming: Create a virtual local area network for multiplayer gaming.
- Bypass Regional Blocks: Access region-restricted content like streaming services.
By usign this solution to host your own VPN, you gain complete control over configuration, logs, and data flow, making it an excellent choice for your specific use case.
Conclusion¶
Setting up a self-hosted VPN server using this Terraform configuration script is a straightforward and efficient way to enhance your network security and maintain control over your data. By following this documentation, you can deploy a robust OpenVPN server on AWS, customize it to your needs, and ensure private and secure internet access. This guide aims to empower you with the knowledge and tools to manage your own VPN server effectively. For any troubleshooting or further customization, explore the Terraform and OpenVPN documentation for advanced insights and solutions.