Terraform GCE GNS3 Module
Terraform module which provisions a GNS3 remote server on a Ubuntu 18.04 Google Compute Instance, using Terraform and Packer. GNS3 is a network software emulator that simulates complex network configurations virtually. This module is based on GNS3's official instructions on how to set up a remote server, but automated and with additional features.
The basic GNS3 remote server setup involves:
-
Setting up OpenVPN to avoid exposing GNS3 to the internet
-
GNS3 running on the server reachable by connecting via OpenVPN
-
OpenVPN client profile available for download from a server endpoint for ease of sharing
Since this module is mainly geared towards development and training purposes, it does not focus on configuring a security hardened server, and instead, focuses on ease of setup and minimizing costs.
Why run a GNS3 remote server
-
Better performance with dedicated vCPUs for more complex workloads
-
Can collaborate on projects with others/share the instance between several users
-
No need to keep large image files, VM images, and VM software on your personal computer
Features
-
Automated deployment of GNS3 remote server on a Google Compute Instance along with firewall settings
-
Save images, appliances and project files to a persistent disk
-
Ability to shutdown server when not in use to minimize costs
-
Protect VPN profile endpoint via username and password authentication
Quickstart Requirements
-
Terraform version 0.13 or higher. Download Terraform here
-
Google Cloud Account and
gcloud
CLI installed. -
An OpenVPN client
Quickstart
-
Create a Google Cloud Project.
gcloud projects create <PROJECT_ID> gcloud config set project <PROJECT_ID>
-
Enable the Compute Engine API (may need to first enable billing for the project).
gcloud services enable compute.googleapis.com
-
Create a service account key for one of the service accounts in your project (can be the default or a dedicated service account for Terraform). Ensure that the service account has at least the following roles:
roles/compute.instanceAdmin.v1
,roles/compute.securityAdmin
.gcloud iam service-accounts keys create <KEY_OUTPUT_PATH> --iam-account <SERVICE_ACCOUNT_EMAIL> # To bind service account role gcloud projects add-iam-policy-binding <PROJECT_ID> --member=serviceAccount:<SERVICE_ACCOUNT_EMAIL> --role=<ROLE_NAME>
-
Create a
main.tf
file in your project directory with the following contents:provider "google" { version = "~> 3.0" credentials = file("path/to/service-account-key.json") project = "my_gcp_project" zone = "my_gcp_zone" } module "gns3_server" { source = "github.com/weiijiie/terraform-gce-gns3?ref=v0.1.0" # Selected machine type, the N2 high-CPU machine types are recommended, as # they support nested virtualization. Select number of virtual CPUs based # on your workload requirements machine_type = "n2-highcpu-8" # Disk size in GB for persistent disk. Adjust according to size requirements # of GNS3 image and project files gns3_disk_size = 20 # GNS requires that the server version matches the client version, thus I # publish the latest 4 versions of the GNS3 server as pre-built base images # for convenience. For long-term stability it is recommended to build your own # base images using the provided Packer files image_family = "gns3-server-v2-2-15" image_project = "civic-circuit-287709" # Project containing the image # Allow your IP to access the server allow_ingress_from_current_ip = true } output "openvpn_profile_endpoint" { description = "Endpoint to download the OpenVPN profile from." value = module.gns3_server.openvpn_profile_endpoint } output "gns3_server_ip" { description = "Private IP that the GNS3 server will listen for connections on. Set the remote server host to this value in the GNS3 client UI." value = module.gns3_server.gns3_server_ip } output "gns3_server_port" { description = "Port used to connect to the GNS3 server. Set the remote server port to this value in the GNS3 client UI." value = module.gns3_server.gns3_server_port }
-
Run
terraform apply
, inspect the generated plan, and confirm. -
Download the OpenVPN client profile from the endpoint specified (default port 8003) in the Terraform output. You may need to wait a short while for the server to be ready to accept connections. Use the profile to connect to the VPN via your OpenVPN client.
-
Open the GNS3 client and specify the host and port under Edit > Preferences > Server, based on the IP and port specified in the Terraform output (default IP 172.16.253.1, default port 3080). GNS should be able to connect to the remote server.
-
Done!
Resources Created
-
1x Google Compute Instance, the GNS3 server
-
1x Google Compute Disk of type "pd-standard"
-
1x Google Compute Firewall which allows SSH access and access to the OpenVPN client profile download endpoint and OpenVPN port
GNS3 Server base image
The base image that the Google Compute Instance is booted from is created using Packer, with the Packer files available in the packer/
directory. Since the GNS3 client can only connect to the server if they are running the same version, I publish the latest 4 released versions of the GNS3 server for convenience sake. The images are available in the project civic-circuit-287709
with the image family of gns3-server-v<MAJOR_NUMBER>-<MINOR_NUMBER>-<PATCH_NUMBER>
(dashes separating the numbers). However, it is recommended to build your own base images using Packer for stability and reliability.
To build the base images using Packer:
-
Download Packer version 1.6 or greater from here
-
Clone the repository using
git
-
cd into the
packer/
directory -
Ensure Packer can authenticate with Google Cloud services by following the instructions here.
-
Run the following command to build your GNS3 server image in your project (dots separating the version numbers):
packer build -var "gcp_project_id=<GCP_PROJECT_ID>" -var "gcp_zone=<GCP_ZONE>" -var "gns3_version=v<MAJOR_NUMBER>.<MINOR_NUMBER>.<PATCH_NUMBER>" gns3.json
Details
Costs
The costs of running the GNS3 server depends on the machine type of the Google Compute instance, but if using N2 high-CPU types with 4-8 vCPUs, the price is generally under $0.50 USD per hour (these types are recommended solely based on empirical observation, there may be better machine types more suited to running your workloads). In addition, the persistent disk used to store the GNS3 files may incur a small monthly cost, depending on how large the files are.
Shutting down the instance
To save costs, if the instance is not required to be running 24/7, the instance can be shut down and rebooted safely. To do so, set the enable_server
variable to be false
in the module body and run terraform apply
.
module "gns3_server" {
source = "github.com/weiijiie/terraform-gce-gns3"
# ... omitted for brevity
enable_server = false
}
Note that when Google Compute instances are rebooted, they may not keep the same public IP address. Hence, you will likely have to re-download the OpenVPN client profile and connect with the new profile.
Static IP
To avoid the problem of having to re-download/edit the OpenVPN client profile every time the instance reboots due to IP address changes, you can set the use_static_ip
variable to be true
in the module body and run terraform apply
.
module "gns3_server" {
source = "github.com/weiijiie/terraform-gce-gns3"
# ... omitted for brevity
use_static_ip = true
}
This will provision a Google Compute external IP address and attach it to your instance, allowing it to have a static public IP address. Note that your service account requires the role: roles/compute.publicIpAdmin
to provision a static IP address.
Persistent disk
The Terraform module configures the Google Compute Instance to automatically format and mount the attached persistent disk to the directory where GNS3 stores its files. Thus, your GNS3 files will persist even if the instance is destroyed and recreated.
Ingress
By default, the module only allows traffic from your current public IP to the server. If you want other parties to be able to share the server, allow other IPs access to the server by setting the allowed_ingress_cidr_blocks
Terraform variable.
module "gns3_server" {
source = "github.com/weiijiie/terraform-gce-gns3"
# ... omitted for brevity
allowed_ingress_cidr_blocks = ["0.0.0.0/0"] # to allow all IP addresses to access the instance
}
Protecting OpenVPN client profile endpoint
By default the OpenVPN client profile endpoint is not protected, and any IP address that the firewall allows through can download the OpenVPN client profile and connect to the VPN. Due its ephemeral nature and the lack of sensitive data on the server, this may not be a huge problem. However, if necessary, the OpenVPN client profile endpoint can be configured to have basic username/password HTTP authentication. To do so, add the following to the module body and re-run terraform apply
(note that the instance will have to be re-created).
module "gns3_server" {
source = "github.com/weiijiie/terraform-gce-gns3"
# ... omitted for brevity
allowed_ingress_cidr_blocks = ["0.0.0.0/0"] # to allow all IP addresses to access the instance
# can be used with the above to protect the endpoint
openvpn_profile_endpoint_creds = {
username = "my_username"
password = "my_password" # change to something secure
}
}
Terraform Requirements
Name | Version |
---|---|
terraform | >= 0.13.0 |
~> 3.0 | |
http | ~> 1.2.0 |
Terraform Providers
Name | Version |
---|---|
~> 3.0 | |
http | ~> 1.2.0 |
Inputs
Name | Description | Type | Default | Required |
---|---|---|---|---|
allow_ingress_from_current_ip | When enabled, the Google Compute Instance will allow inbound connections from your current IP address. Should consider disabling if your IP address is expected to not be stable. | bool |
true |
no |
allowed_ingress_cidr_blocks | Additional list of CIDR blocks that the Google Compute Instance will allow inbound connections from. Can be used to enable connections when ingress_from_current_ip_only is disabled. |
list(string) |
[] |
no |
enable_server | If true, sets the Google Compute Instance to a running state. Otherwise, stops the instance. | bool |
true |
no |
gns3_disk_size | Size (in GB) for the persistent disk used to store GNS3 files (images, appliances etc.) | number |
n/a | yes |
gns3_server_ip | Private IP that the GNS3 server will listen for connections on within the OpenVPN network. Should be in the 172.16.253.0/24 subnet. | string |
"172.16.253.1" |
no |
gns3_server_port | Port used to connect to the GNS3 server. | number |
3080 |
no |
image_family | Image family for a GNS3 server base image to be used for the Google Compute Instance. Exactly one of image_name or image_family must be specified. |
string |
null |
no |
image_name | Name of the GNS3 server base image to be used for the Google Compute Instance. Exactly one of image_name or image_family must be specified. |
string |
null |
no |
image_project | Project where the GNS3 server base image to be used belongs to. Required to use a public base image. | string |
null |
no |
machine_type | Machine type to use for the Google Compute Instance. | string |
n/a | yes |
min_cpu_platform | Minimum CPU platform to use for the Google Compute Instance. Your instance may need certain minimum CPU platforms to support nested virtualization, which is required for GNS3. Examples include "Intel Skylake" or "Intel Haswell". | string |
null |
no |
name | Name to use for resources created by Terraform. | string |
"gns3-server" |
no |
openvpn_access_port | Port used to access the OpenVPN access server. | number |
1194 |
no |
openvpn_profile_endpoint_creds | Credentials required for authentication to download the OpenVPN client profile from the server endpoint. Default uses no authentication. | object({ |
null |
no |
openvpn_profile_endpoint_port | Port used to download the OpenVPN client profile. | number |
8003 |
no |
use_static_ip | Whether to associate the Google Compute Instance with a static IP address. Will guarantee an instance with the same IP even after reboots. | bool |
false |
no |
vpc_network | Network to launch the Google resources in. | string |
"default" |
no |
Outputs
Name | Description |
---|---|
gns3_server_ip | Private IP that the GNS3 server will listen for connections on. Set the remote server host to this value in the GNS3 client UI. |
gns3_server_port | Port used to connect to the GNS3 server. Set the remote server port to this value in the GNS3 client UI. |
google_compute_instance_id | ID of the created Google Compute Instance. |
openvpn_profile_endpoint | Endpoint to download the OpenVPN profile from. |
public_ip | Public IP address of the created instance. |
License
MIT licensed. See LICENSE.md for full details.