GCE VyOS module

VyOS is a router open source operating system, based on the previous vyatta virtual router implementation. VyOS runs both on bare-metal devices as well as on all major cloud providers, including Google Cloud Platform.

Motivation

At the time of writing, there is no easy-to-go way to get VyOS running on GCP, except the Google Marketplace deploy. While the current version of VyOS available on GCP marketplace is paid (even if it is an open-source project) it is not updated and does not come with Google Compute agent nor Google Ops Agent installed. This module aims at enabling IaC projects to take advantage of VyOS instances with ease, following a more IaC-oriented approach.

Features

This module achieves the following major objectives:

  • Provides a way for deploying a VyOS Equuleus 1.3 GCE Image on GCP
  • Enables the VyOS instance to update its configuration using Cloud Storage and Pub/Sub notifications
  • Enables users connecting via IAP/GCLOUD ssh to administer the VyOS instance with the built-in command line

Why not simply using cloud-init?

Cloud-init is a great feature that allows initial configuration and bootstrapping of cloud images. VyOS has developed a couple of modules that allow fetching and changing the configuration of the router at boot time, via metadata gathering, specifically using the user-data key.

However, that approach has some major limitations:

  • It works by issuing configuration commands (i.e. imperative) while the rest of the module works with declarative approach.
  • It is limited to the maximum size of the metadata
  • It requires a reboot to be reapplied (most likely a startup script)

This module uses a GCS file to hold the configuration state, fetched via pubsub event by a python daemon running on the VyOS instance. However, the module still allows the developer to pass the user-data content, in case that is preferred.

Image Prerequisites

This Terraform module requires a custom GCE Image to be built or imported into the GCP project where the VyOS router will reside. You can either build and customize that image yourself (but chances are you landed on this page because you don't want to do so), or you can simply import the GCE image (vyos-equuleus-gce-image.tar.gz) built on this repository, available here.

To get the image ready by using the one built on this repository, simply download the .ta.gz tarball and update it into a GCS bucket. Then, create a new GCE image starting from the uploaded file. More info about this process can be found on the official GCP documentation.

Building VyOS GCE Image by your own

The GCE image is built via the build scripts provided by the VyOS team and enriched with the necessary configurations and scripts needed to run on the GCP environment. At the time of writing, the GCE image on this repository is built as follows:

  1. Build the VyOS Equuleus 1.3 ISO, using the official build-script;
  2. Build the base VyOS Equuleus 1.3 GCE Image, using the official build-script;
  3. Configure and patch the image to run correctly on GCE:
    • Install the GCE Linux Guest Agent
    • Install the GCE Linux Ops Agent (which includes metrics and logging features) against Stackdriver
    • Configure the file VyOS boot config to use a single instance with DHCP
    • Map the metadata.google.internal host to 169.256.169.256
  4. Install the Configuration Reloader service to automatically fetch the configuration from GCS
  5. Install the Login Helper service to handle SSH users login via VyOS

Note: this module won't take care of enabling the necessary APIs. It is developer's responsibility to enable them in the root module.

Please note that covering the build phase of the image is out of the scope of this document.

That being said, if you plan to build the VyOS image by yourself, please inject the repository contents of vyos-gce-image/chroot-patches/opt/gce_helper and vyos-gce-image/chroot-patches/etc/systemd/system respectively to /opt/gce_helper and /etc/systemd/system (on the target image). Also, make sure to override the default vyos config.boot.default file with the one provided in this repository. Eventually, make sure to install the GCE agent and the ops agent. You can see how this is done in this repository by lookig at the 99-gce-agent.chroot shell script.

Limitations

So far, the VyOS image has been tested only on n2 or n1 instance families. Other instance families might not be supported.

The VyOS image is equipped with the host-agent which might require access to Google APIs. Make sure the Subnet you attach the VyOS instance to has the Private Google Access (PGA) activated.

Organizational policies prerequisites

Some organizational policies might require an exception for this module to work. For instance, the constraints/storage.uniformBucketLevelAccess constraint should not apply to the bucket where the configuration is held, as the current version of the module works with ACLs on single objects. If you plan to use VyOS instance with a public IP assigned, you should make sure that the policy constraints/compute.vmExternalIpAccess does allow that.

Moreover, at the time of writing, the provided GCE VyOS image does not comply with shielded image requirements nor supports OS-LOGIN. Therefore constraints/compute.requireShieldedVm and constraints/compute.requireOsLogin org policies should allow an exception for the VyOS intance.

Lastly, the current version of the module assigns the "ip_forwardign" capability to the vyos instance, as it would be generally useful when using natting and firewalling capabilities of VyOS. Therefore, you should make sure the constraints/compute.vmCanIpForward organizational policy allows the VyOS instance to use the ip_forward functionality.

Usage

Refer to the example folder for some quick examples on how to use this module.

Module reference

Providers

Name Version
google n/a

Resources

Name Type
google_compute_firewall.allow_ssh_iap resource
google_compute_instance.vyos resource
google_project_iam_member.sa_log_writer resource
google_project_iam_member.sa_metric_writer resource
google_project_service.project_services resource
google_pubsub_subscription.vyos_instance_subscription resource
google_pubsub_subscription_iam_policy.instance_subscriber resource
google_pubsub_topic.configuration_update_topic resource
google_pubsub_topic_iam_member.pubsub_notification_event resource
google_service_account.vyos_compute_sa resource
google_storage_bucket.conf_file_bucket resource
google_storage_bucket_iam_member.instance_sa_bucket_permissions resource
google_storage_bucket_object.conf_file_object resource
google_storage_notification.configuration_update resource
google_compute_image.vyos data source
google_iam_policy.subscription_subscriber data source
google_storage_project_service_account.gcs_account data source

Inputs

Name Description Type Default Required
configuration_bucket_name Bucket name where to store VyOs instance configuration file any null no
configuration_bucket_path GCS object path where to store VyOs instance configuration file any null no
enable_serial_port_connection When true, allows the connection via the serial port bool false no
gcp_region Default GCP region where to spawn resources any n/a yes
instance_name Name to assign to the VyOs instance string "vyos" no
instance_tags Tags to assign to the vyos instance list
[
"vyos"
]
no
instance_tier Machine tier for the VyOs instance string "e2-small" no
instance_vyos_image_name Instance image name any n/a yes
instance_vyos_image_project_id The project id where the vyos image is stored. Override this parameter if the image
specified as instance_vyos_image_name is located into another GCP project.
When null, the project_id value is used instead.
any null no
instance_zone GCP Zone where to spawn the VyOs instance any n/a yes
networks_configuration Instance networking configuration.
map(object({
assign_external_ip=bool,
static_external_ip=string,
create_iap_ssh_firewall_rule=bool,
network_project_id=string,
network=string,
subnetwork=string,
network_ip=string,
}))
n/a yes
project_id Google project id where to spawn the VyOs instance any n/a yes
user_data_content Holds the content of the user-data metadata to be used as configuration script at instance boot. string "" no
vyos_configuration_content Contents of the VyOs configuration to apply to the target instance any n/a yes

Licensing notes

This module is provided as is, with absolutely no warranty.

Quoting the original documentation, we read:

VyOS is now free as in speech, but not as in beer. 
This means that while VyOS is still an open source project, 
the release ISOs are no longer free and can only be obtained 
via subscription, or by contributing to the community.