Using Terraform IAC to Deploy your free VPN server on AWS
Heavily motivated by Chuck’s video on setting up a free VPN server on AWS.
As a Terraform enthusiast, I naturally asked myself, what if we can automate all the steps and not have to click around in setting up the server? I then decided to translate all the steps in setting up the server into IAC, Infrastructure As Code using Terraform. With this, we can achieve; one command spins up and tears down of the whole setup, the ability to select a region location interactively for our VPN server, maintainability of our infrastructure through code plus all the benefits of IAC. View the full code on Github here.
Set-Up
- Install Terraform.
- Make sure to have a working AWS account and AWS CLI installed. You can follow here to correctly set up your AWS CLI credentials.
- Be eligible to spin up a free tier instance on AWS.
Writing Terraform Config
- Create a folder for the project, let’s say we name it OpenVPN. In the folder create a file also, name it main.tf, you can name it anything but it must end with .tf.
- You need to locate the AMI id for the OpenVPN community instance images. I have collected the image ids for three regions, us-east-1, eu-central-1, and ap-northeast-1 so we can spin up VPN servers in the US, Europe, and Asia as we want.
- Create a variables.tf file which will hold all our config variables. These variables are defined with default values but you have the option to specify your values when running the config. Our variables file will look like below;
- With the
server_region
variable, we will be able to specify a region we want to launch our VPN server. It defaults to EU central, ‘eu-central-1’ server_username
helps us define what our admin username for OpenVPN will be. Uses a default of ‘openvpn’server_password
defines what will be the admin password for OpenVPN. Default is ‘password’- In our main.tf, we will define the following;
- We first have to tell Terraform we require a provider, which is AWS.
- Then in setting up our AWS provider we select a region. This is read from our previous variables file as
var.server_region
.
- Next, We declare our result output. This will be the response we get after running our Terraform configuration.
locals
will help us define a mapping of AWS regions to AMI image IDs. I have fetched the image IDs here and assigned them correctly.
- We then declare our instance resource. Select the correct AMI id by using the local mapping here then pass in the region. We use a
t2.micro
for free tier eligibility. We assign a security group to the security group resource which will be defined next. Setup auser_data
which will help us automate all our initial OpenVPN server setup to accept defaults, according to their documentation. We only need to assign a username and password for our admin user. Our Terraform script is here enabled to supply the username and password through variables which we can pass in at the run time.
- Lastly, we define a security group for our VPN server. This is the exact kind of security group set up the OpenVPN marketplace setups up for you when you choose to spin their OpenVPN Access Server. I have only translated this to Terraform resource config. We essentially allow special ports for connection to the server using SSH, HTTPS, and other TCP connections required by OpenVPN.
Running the Server
- In the project directory, from your terminal, you have to run
terraform init
. This setup a project for terraform to work it. It installs also all recognized providers in our case AWS. - Then we run
terraform plan
to see what terraform plans to do. You should get a detailed output of AWS resources to be provisioned, an instance, and a security group. The latter part of your output should look like
Plan: 2 to add, 0 to change, 0 to destroy.Changes to Outputs:+ access_vpn_url = (known after apply)
This means we will have two new resources added and get the correct URL output after applying our changes.
- Next, we want to go live and apply our changes. Run
terraform apply -var server_region="eu-central-1" -var server_username="myuser" -var server_password="password"
. Confirm with a yes. You then get an output likeaccess_vpn_url = https://12.123.123.123:943/admin.
Visit this URL and login with the username and password supplied in the apply command. Continue your VPN setup from there. And we are done!
Conclusion
With this script in hand, we can spin up and tear down our free private VPN server at will. If you want to destroy the whole setup just run terraform destroy
from the project root directory, confirm with a yes. Then, the instance and the security group will be terminated automatically. Let me know what you think and how this worked for you or if you come up with a better solution. Happy Terraforming!