How to run OpenVPN from Terraform Code
by Mateusz Ślaski, Sales Support Engineer, CloudFerro
The following article covers the subject of creating an OpenVPN instance allowing secure access to the OpenStack network through a VPN tunnel.
We will build step-by-step code containing templates for:
- network for our environment
- necessary security group with rules
- virtual machine instance with automatically configured VPN
- dedicated Object Storage for VPN configuration persistence
Instructions and the way of executing are defined in a way that allows you to learn, by the way, some Terraform and OpenStack functions such as:
- splitting TF code into multiple files
- using TF Workspaces
- using TF templates
- launching instances configured with Cloud-Init as TF and OpenStack "user-data"
Prerequisites / Preparation
Before you start, please read the documents:
- "Generating and Authorizing Terraform using a Keycloak User on CREODIAS" https://creodias.docs.cloudferro.com/en/latest/openstackdev/Generating-and-authorizing-Terraform-using-Keycloak-user-on-Creodias.html
- "How to Generate or Use Application Credentials via CLI on CREODIAS": https://creodias.docs.cloudferro.com/en/latest/cloud/How-to-generate-or-use-Application-Credentials-via-CLI-on-Creodias.html We will use them to authenticate the Terraform OpenStack provider.
- Additionally, you may review:
- Official Terraform documentation: https://developer.hashicorp.com/terraform
- Terraform OpenStack Provider documentation: https://registry.terraform.io/providers/terraform-provider-openstack/openstack/latest/docs
You may also, if necessary, refresh some details about the manual management of: projects, key-pairs, networks, and security groups:
- https://creodias.docs.cloudferro.com/en/latest/networking/Generating-a-SSH-keypair-in-Linux-on-Creodias.html
- https://creodias.docs.cloudferro.com/en/latest/cloud/How-to-create-key-pair-in-OpenStack-Dashboard-on-Creodias.html
- https://creodias.docs.cloudferro.com/en/latest/networking/How-to-Import-SSH-Public-Key-to-OpenStack-Horizon-on-Creodias.html
- https://creodias.docs.cloudferro.com/en/latest/cloud/How-to-use-Security-Groups-in-Horizon-on-Creodias.html
- https://creodias.docs.cloudferro.com/en/latest/networking/How-to-create-a-network-with-router-in-Horizon-Dashboard-on-Creodias.html
Step 1 - Select or create project
You may use the default project in your tenant (usually named "cloud_aaaaa_bb") or create a new one by following the document mentioned below.
Step 2 - Install Terraform
There are various ways to install Terraform, some of which are described in the documentation mentioned in the "Preparation" chapter.
If you are using Ubuntu 22.04 LTS or newer and you do not need the latest Terraform release (for the Terraform OpenStack provider, it is not necessary), the easiest way is to use Snap.
First, install Snap
sudo apt install snapd
Then install Terraform
Step 3 - Allowing access to project from Terraform
Now create Application Credentials.
Please follow the mentioned document: "How to Generate or Use Application Credentials via CLI on CREODIAS": https://creodias.docs.cloudferro.com/en/latest/cloud/How-to-generate-or-use-Application-Credentials-via-CLI-on-Creodias.html
When you have them ready, save them in a secure location (i.e., password manager) and fill in the variables in the "my_first_vpn.tfvars" file.
Step 4 - Prepare configuration files
As Terraform operates on the entire directory and automatically merges all "*.tf" files into one codebase, we may split our Terraform code into a few files to manage the code more easily.
- main.tf
- variables.tf
- resources.tf
Additionally, we need two other files:
- open_vpn_user_data.yaml
- my_first_vpn.tfvars
File 1 - main.tf
In this file, we keep the main definitions for Terraform and the OpenStack provider.
File 2 - variables.tf
In this file, we will keep variable definitions.
File 3 - resources.tf
This is the most significant file where definitions of all entities and resources are stored.
File 4 - vpn_user_data.yaml
This is a template of user-data that would be injected into our VPN instance. This file contains configuration and package installation directives and a script responsible for VPN configuration.
File 5 - my_first_vpn.tfvars
In this file we will provide values of Terraform variables
- os_user_name - Enter your username used to authenticate in CREODIAS here.
- tenant_project_name - Name of the project selected or created in step 1.
- os_application_credential_id
- os_application_credential_secret
- region - CloudFerro Cloud region name. Allowed values are: WAW3-1, WAW3-2, FRA1-2, WAW4-1.
- env_id - Name that will prefix all resources created in OpenStack.
- vpn_keypair - Keypair available in OpenStack. You will use it to log in via SSH to the VPN machine to get the Client configuration file.
- network - Network class for our environment. Any of 10.a.b.c or 192.168.b.c.
- netmask - Network mask. Allowed values: /24, /16.
- vpn_flavor - VM flavor for our VPN.
- vpn_version - It may be any string. If this value doesn't change, then recreating the VPN instance will download the backup configuration from the object archive, and users may still connect with the VPN client config file. However, if you change this variable and reapply Terraform on your environment, the VPN configuration will be recreated, and a new VPN client configuration file has to be delivered to users.
Some of the included data, such as credentials, are sensitive. So if you save this in a Git repository, it is strongly recommended to add the file pattern "*.tfvars" to ".gitignore".
You may also add to this file the variable "external_network" however.
Do not forget to fill or update variable values in the content below.
Files listed above except "my_first_vpn.tfvars" will be available in the CloudFerro GitHub repository.
Step 5 - Activate Terraform workspace
A very useful Terraform functionality is workspaces. Using workspaces, you may manage multiple environments with the same code.
Create and enter a directory for our project by executing commands:
To initialize Terraform, execute:
Then, check workspaces:
terraform workspace list
As an output of the command above, you should see output like this:
As we want to use a dedicated workspace for our environment, we must create it. To do this, please execute the command:
Terraform will create a new workspace and switch to it.
Step 6 - Validate configuration
To ensure the prepared configuration is valid, do two things.
First, execute the command:
terraform validate
Then execute Terraform plan:
You should get as an output a list of messages describing resources that would be created.
Step 7 - Provisioning of resources
To provision all resources, execute the command:
As with the plan command, you should get as an output a list of messages describing resources that would be created, but now finished with a question if you want to apply changes.
You must answer with the full word "yes".
You will see a sequence of messages about the status of provisioning.
Please remember that when the above sequence successfully finishes, the VPN is still not ready!
A script configuring the VPN is still running on the VPN server.
The process of automatically signing certificates with the easy-rsa package may take several minutes.
We recommend waiting about 5 minutes.
Step 8 - Obtaining VPN Client Configuration File
First, you have to find the public IP address of the created VPN server.
You may check it in the OpenStack Horizon GUI or use the OpenStack CLI command `openstack server list`. But if Terraform is at hand, then use it and execute: terraform state show openstack_networking_floatingip_v2.vpn_public_ip
In the command output, look for the row with "address".
Test the connection to the VPN server by executing the command:
You will be asked to confirm the server fingerprint. Type "yes".
When you successfully get a connection, check if the VPN was automatically configured.
Execute the command:
You should see two files:
- client-ENV_ID.ovpn - Contains client configuration with all necessary keys and certificates.
- server_ready.txt - Contains the date and time when the configuration script finished its work.
Logout by typing:
And copy the configuration file to your computer by executing:
Step 9 - Configure OpenVPN Client to Test Connection
Create an Ubuntu instance in another project, or in another region.
Associate an FIP to it.
Log in with SSH.
And install OpenVPN:
sudo apt install openvpn
Exit this instance and copy the client configuration file by executing:
Log in to this instance again and execute:
You should see a sequence of log messages finished with "Initialization Sequence Completed". If you connect to this machine with another terminal and execute:
You should see 3 network interfaces:
- lo
- eth0
- tun0
Return to terminal where test session of OpenVPN was started. Stop it by pressing "Ctr+C".
To make VPN connection persistent execute:
That is all. From this moment, you may access any resources within the created network via the VPN tunnel.
Some remarks and possible improvements:
- Obtained client file may be used also on Windows computers. To connect them. Download community OpenVPN client from https://openvpn.net/community-downloads/ and import this file.
- Proposed configuration allow to connect separate computers to single VPN server. If you need bridge connection network to network, then please check OpenVPN documentation to tune this solution.
- All client computers connected use the same certificates and keys to connect. If you need user based access end client identification than also please tune it to your needs.