diff options
| author | Yuriy Andamasov <yuriy@vyos.io> | 2026-05-02 17:25:47 +0300 |
|---|---|---|
| committer | Yuriy Andamasov <yuriy@vyos.io> | 2026-05-06 16:18:03 +0300 |
| commit | fa54a080fac977157454beb0853daf0ac0e6af66 (patch) | |
| tree | 82b112cde06437b80515450d63eb793bee198ec6 /docs/automation/terraform | |
| parent | 746195618941d8be8ed132f4b0be539763ec352d (diff) | |
| download | vyos-documentation-fa54a080fac977157454beb0853daf0ac0e6af66.tar.gz vyos-documentation-fa54a080fac977157454beb0853daf0ac0e6af66.zip | |
feat(swap): import .md files and webp transition from myst/current
Selective import from origin/myst/current (cf9c9b34):
- Add/update 255 .md files (full MyST conversion plus webp ref updates)
- Delete 175 PNG/JPG from docs/_static/images (webp twins already present)
- Delete 5 autotest topology.png (webp twins already present)
Preserved on swap (untouched):
- All .rst files (incremental swap pattern)
- conf.py, _ext/, _include/*.txt, .gitignore
- 115 canary md-*.md files
- 7 superpowers/specs/*.md design docs
- Logos vyos-logo.png / vyos-logo-icon.png (referenced by conf.py)
🤖 Generated by [robots](https://vyos.io)
Diffstat (limited to 'docs/automation/terraform')
| -rw-r--r-- | docs/automation/terraform/index.md | 29 | ||||
| -rw-r--r-- | docs/automation/terraform/terraformAWS.md | 551 | ||||
| -rw-r--r-- | docs/automation/terraform/terraformAZ.md | 500 | ||||
| -rw-r--r-- | docs/automation/terraform/terraformGoogle.md | 703 | ||||
| -rw-r--r-- | docs/automation/terraform/terraformvSphere.md | 389 | ||||
| -rw-r--r-- | docs/automation/terraform/terraformvyos.md | 44 |
6 files changed, 2216 insertions, 0 deletions
diff --git a/docs/automation/terraform/index.md b/docs/automation/terraform/index.md new file mode 100644 index 00000000..dc787db1 --- /dev/null +++ b/docs/automation/terraform/index.md @@ -0,0 +1,29 @@ +--- +lastproofread: '2026-03-23' +--- + +# VyOS Terraform + +VyOS supports development infrastructure via Terraform and provisioning +via Ansible. +Terraform allows you to automate the deployment of instances on a number of +cloud and virtual platforms. This section shows how to deploy VyOS on +multiple platforms: AWS, Microsoft Azure, Google Cloud Platform (GCP), +and VMware vSphere. +For more information, see the +official documentation for [Terraform] and [Ansible]. + +```{toctree} +:caption: Guides +:maxdepth: 1 + +terraformvyos +terraformAWS +terraformAZ +terraformGoogle +terraformvSphere +``` + +[ansible]: https://docs.ansible.com +[install]: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli +[terraform]: https://developer.hashicorp.com/terraform/intro diff --git a/docs/automation/terraform/terraformAWS.md b/docs/automation/terraform/terraformAWS.md new file mode 100644 index 00000000..b0c06bb1 --- /dev/null +++ b/docs/automation/terraform/terraformAWS.md @@ -0,0 +1,551 @@ +--- +lastproofread: '2026-03-16' +--- + +(terraformaws)= + +# Deploy VyOS on AWS with Terraform and Ansible + +You can use Terraform to quickly deploy VyOS-based infrastructure +on AWS and remove infrastructure when it's no longer needed. +Additionally, you can use Ansible for provisioning. + +```{eval-rst} +.. image:: /_static/images/aws.webp + :width: 50% + :align: center + :alt: Network Topology Diagram +``` + +On this page you'll learn how to: +- Create the necessary files for Terraform and Ansible. +- Use Terraform to create a single instance on AWS and use Ansible for + provisioning. + +## Prepare to deploy VyOS with Terraform on AWS + +To create a single instance and install your configuration using +Terraform, Ansible, and AWS, follow these steps: + +### AWS + +1. Create an account with AWS and get your `access_key` and `secret_key`. +2. Create a key [pair] and download your `.pem` key. + +```{eval-rst} +.. image:: /_static/images/keypairs.webp + :width: 50% + :align: center + :alt: Network Topology Diagram +``` + +3. Create a security [group] for the new VyOS instance and open all traffic. + +```{eval-rst} +.. image:: /_static/images/sg.webp + :width: 50% + :align: center + :alt: Network Topology Diagram +``` + +```{eval-rst} +.. image:: /_static/images/traffic.webp + :width: 50% + :align: center + :alt: Network Topology Diagram +``` + + +### Terraform + +```{eval-rst} +1. Create an UNIX or Windows instance. + +2. Download and install + `Terraform <https://developer.hashicorp.com/terraform/install>`__. + +3. Create a folder, for example ``/root/awsterraform``: + + .. code-block:: none + + mkdir /root/awsterraform + +.. stop_vyoslinter + +4. Copy all files into your Terraform project + (``vyos.tf``, ``var.tf``, ``terraform.tfvars``, ``version.tf``). + See `Structure of files in Terraform for AWS <#structure-of-files-in-terraform-for-aws>`__ for more details. + +.. start_vyoslinter + +5. Run the following commands: + +.. code-block:: none + + cd /<your folder> + terraform init +``` + +### Ansible + +```{eval-rst} +1. Create a UNIX instance whenever you need. + +2. Download and install Ansible + +3. Create a folder, for example ``/root/aws/``. + +.. stop_vyoslinter + +4. Copy all files into your Ansible project + (``ansible.cfg``, ``instance.yml``, + ``mykey.pem``, and ``all``). + See `Structure of files in Ansible for AWS <#structure-of-files-in-ansible-for-aws>`__ for more details. + You can obtain ``mykey.pem`` by creating a key `pair <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html>`__ in AWS and + downloading your ``.pem`` key. +``` + +### Deploy with Terraform + +Run the following commands on your Terraform instance: + +```none +cd /<your folder> +terraform plan +terraform apply +yes +``` + +## Create an AWS instance and check its configuration + +```none +root@localhost:~/awsterraform# terraform apply + +Terraform used the selected providers to generate the following execution plan. +Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # aws_instance.myVyOSec2 will be created + + resource "aws_instance" "myVyOSec2" { + + ami = "ami-************62c2d" + + arn = (known after apply) + + associate_public_ip_address = (known after apply) + + availability_zone = (known after apply) + + cpu_core_count = (known after apply) + + cpu_threads_per_core = (known after apply) + + disable_api_stop = (known after apply) + + disable_api_termination = (known after apply) + + ebs_optimized = (known after apply) + + get_password_data = false + + host_id = (known after apply) + + host_resource_group_arn = (known after apply) + + iam_instance_profile = (known after apply) + + id = (known after apply) + + instance_initiated_shutdown_behavior = (known after apply) + + instance_lifecycle = (known after apply) + + instance_state = (known after apply) + + instance_type = "t2.micro" + + ipv6_address_count = (known after apply) + + ipv6_addresses = (known after apply) + + key_name = "awsterraform" + + monitoring = (known after apply) + + outpost_arn = (known after apply) + + password_data = (known after apply) + + placement_group = (known after apply) + + placement_partition_number = (known after apply) + + primary_network_interface_id = (known after apply) + + private_dns = (known after apply) + + private_ip = (known after apply) + + public_dns = (known after apply) + + public_ip = (known after apply) + + secondary_private_ips = (known after apply) + + security_groups = [ + + "awsterraformsg", + ] + + source_dest_check = true + + spot_instance_request_id = (known after apply) + + subnet_id = (known after apply) + + tags = { + + "name" = "VyOS System" + } + + tags_all = { + + "name" = "VyOS System" + } + + tenancy = (known after apply) + + user_data = (known after apply) + + user_data_base64 = (known after apply) + + user_data_replace_on_change = false + + vpc_security_group_ids = (known after apply) + } + + # local_file.ip will be created + + resource "local_file" "ip" { + + content = (known after apply) + + content_base64sha256 = (known after apply) + + content_base64sha512 = (known after apply) + + content_md5 = (known after apply) + + content_sha1 = (known after apply) + + content_sha256 = (known after apply) + + content_sha512 = (known after apply) + + directory_permission = "0777" + + file_permission = "0777" + + filename = "ip.txt" + + id = (known after apply) + } + + # null_resource.SSHconnection1 will be created + + resource "null_resource" "SSHconnection1" { + + id = (known after apply) + } + + # null_resource.SSHconnection2 will be created + + resource "null_resource" "SSHconnection2" { + + id = (known after apply) + } + +Plan: 4 to add, 0 to change, 0 to destroy. + +Changes to Outputs: + + my_IP = (known after apply) + +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. + + Enter a value: yes + +aws_instance.myVyOSec2: Creating... +aws_instance.myVyOSec2: Still creating... [10s elapsed] +aws_instance.myVyOSec2: Still creating... [20s elapsed] +aws_instance.myVyOSec2: Still creating... [30s elapsed] +aws_instance.myVyOSec2: Still creating... [40s elapsed] +aws_instance.myVyOSec2: Creation complete after 44s [id=i-09edfca15aac2fe0a] +null_resource.SSHconnection1: Creating... +null_resource.SSHconnection2: Creating... +null_resource.SSHconnection1: Provisioning with 'file'... +null_resource.SSHconnection2: Provisioning with 'remote-exec'... +null_resource.SSHconnection2 (remote-exec): Connecting to remote host via SSH... +null_resource.SSHconnection2 (remote-exec): Host: 10.217.80.104 +null_resource.SSHconnection2 (remote-exec): User: root +null_resource.SSHconnection2 (remote-exec): Password: true +null_resource.SSHconnection2 (remote-exec): Private key: false +null_resource.SSHconnection2 (remote-exec): Certificate: false +null_resource.SSHconnection2 (remote-exec): SSH Agent: false +null_resource.SSHconnection2 (remote-exec): Checking Host Key: false +null_resource.SSHconnection2 (remote-exec): Target Platform: unix +local_file.ip: Creating... +local_file.ip: Creation complete after 0s [id=e8e91f2e24579cd28b92e2d152c0c24c3bf4b52c] +null_resource.SSHconnection2 (remote-exec): Connected! +null_resource.SSHconnection1: Creation complete after 0s [id=7070868940858935600] + +null_resource.SSHconnection2 (remote-exec): PLAY [integration of terraform and ansible] ************************************ + +null_resource.SSHconnection2 (remote-exec): TASK [Wait 300 seconds, but only start checking after 60 seconds] ************** +null_resource.SSHconnection2: Still creating... [10s elapsed] +null_resource.SSHconnection2: Still creating... [20s elapsed] +null_resource.SSHconnection2: Still creating... [30s elapsed] +null_resource.SSHconnection2: Still creating... [40s elapsed] +null_resource.SSHconnection2: Still creating... [50s elapsed] +null_resource.SSHconnection2: Still creating... [1m0s elapsed] +null_resource.SSHconnection2 (remote-exec): ok: [54.xxx.xxx.xxx] + +null_resource.SSHconnection2 (remote-exec): TASK [Configure general settings for the vyos hosts group] ********************* +null_resource.SSHconnection2: Still creating... [1m10s elapsed] +null_resource.SSHconnection2 (remote-exec): changed: [54.xxx.xxx.xxx] + +null_resource.SSHconnection2 (remote-exec): PLAY RECAP ********************************************************************* +null_resource.SSHconnection2 (remote-exec): 54.xxx.xxx.xxx : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +null_resource.SSHconnection2: Creation complete after 1m16s [id=4902256962410024771] + +Apply complete! Resources: 4 added, 0 changed, 0 destroyed. + +Outputs: + +my_IP = "54.xxx.xxx.xxx" +``` + +After running all the commands, your VyOS instance is deployed on +AWS with your specified configuration. +To delete the instance, type the following command: + +```none +terraform destroy +``` + +## Troubleshooting + +1. If Ansible doesn't connect via SSH to your AWS instance, verify that + your SSH key is in the path `/root/aws/`. You might need to + increase the timeout in `instance.yml` from 300 seconds to 500 + seconds or more, depending on your location. Make sure that the + security group allows access to the instance. +2. If Terraform doesn't connect via SSH to your Ansible instance, + verify the correct login and password in the `VyOS.tf` file. + +```{eval-rst} + .. code-block:: none + + connection { + type = "ssh" + user = "root" # open root access using login and password on your Ansible + password = var.password # check password in the file terraform.tfvars isn't empty + host = var.host # check the correct IP address of your Ansible host + } +``` + +Make sure Ansible can ping from Terraform. + +## Structure of files in Terraform for AWS + +```none +. +├── vyos.tf # The main script +├── var.tf # The file of all variables in "vyos.tf" +├── versions.tf # File for the changing version of Terraform. +└── terraform.tfvars # The value of all variables (passwords, login, ip adresses and so on) +``` + +## File contents of Terraform for AWS + +`vyos.tf` + +```none +############################################################################## +# Build a VyOS VM from the Marketplace. +# Find the necessary AMI image_ in AWS. +# +# The vyos.tf script uses default values (you can change them as +# needed) +# AWS Region = "us-east-1" +# AMI = "standard AMI of VyOS from AWS Marketplace" +# Size of VM = "t2.micro" +# AWS Region = "us-east-1" +# After deploying the AWS instance and getting an IP address, the IP address is copied into the file +#"ip.txt" and copied to the Ansible node for provisioning. +############################################################################## + +provider "aws" { + access_key = var.access + secret_key = var.secret + region = var.region +} + +variable "region" { + default = "us-east-1" + description = "AWS Region" +} + +variable "ami" { + default = "ami-**************3b3" # ami image please enter your details + description = "Amazon Machine Image ID for VyOS" +} + +variable "type" { + default = "t2.micro" + description = "Size of VM" +} + +# my resource for VyOS + +resource "aws_instance" "myVyOSec2" { + ami = var.ami + key_name = "awsterraform" # Please enter your details from 1.2 of Preparation steps for deploying VyOS on AWS + security_groups = ["awsterraformsg"] # Please enter your details from 1.3 of Preparation steps for deploying VyOS on AWS + instance_type = var.type + tags = { + name = "VyOS System" + } +} + +############################################################################## +# Specific variable (to getting type "terraform plan"): +# aws_instance.myVyOSec2.public_ip - the information about public IP address +# of our instance, needs for provisioning and SSH connection from Ansible +############################################################################## + +output "my_IP"{ +value = aws_instance.myVyOSec2.public_ip +} + +############################################################################## +# The IP address of the AWS instance is copied to the ip.txt file +# on the local Terraform system. The ip.txt file contains the public +# IP address in the format: xxx.xxx.xxx.xxx +############################################################################## + +resource "local_file" "ip" { + content = aws_instance.myVyOSec2.public_ip + filename = "ip.txt" +} + +#connecting to the Ansible control node using SSH connection + +############################################################################## +# The "SSHconnection1" and "SSHconnection2" steps retrieve ip.txt +# from the Terraform node and run the Ansible playbook remotely. +############################################################################## + +resource "null_resource" "SSHconnection1" { +depends_on = [aws_instance.myVyOSec2] +connection { + type = "ssh" + user = "root" + password = var.password + host = var.host +} + +# Copy the ip.txt file to the Ansible control node from the local +# system + provisioner "file" { + source = "ip.txt" + destination = "/root/aws/ip.txt" # The folder of your Ansible project + } +} + +resource "null_resource" "SSHconnection2" { +depends_on = [aws_instance.myVyOSec2] +connection { + type = "ssh" + user = "root" + password = var.password + host = var.host +} +# Run Ansible playbook on remote Linux OS +provisioner "remote-exec" { + inline = [ + "cd /root/aws/", + "ansible-playbook instance.yml" # more detailed in "File contents of Ansible for AWS" +] +} +} +``` + +`var.tf` + +```none +variable "password" { + description = "pass for Ansible" + type = string + sensitive = true +} +variable "host"{ + description = "The IP of my Ansible" + type = string +} +variable "access" { + description = "my access_key for AWS" + type = string + sensitive = true +} +variable "secret" { + description = "my secret_key for AWS" + type = string + sensitive = true +} +``` + +`versions.tf` + +```none + terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 5.0" + } + } +} +``` + +`terraform.tfvars` + +```none +password = "" # password for Ansible SSH +host = "" # IP of my Ansible +access = "" # access_key for AWS +secret = "" # secret_key for AWS +``` + +## Structure of files in Ansible for AWS + +```none +. +├── group_vars + └── all +├── ansible.cfg +├── mykey.pem +└── instance.yml +``` + +## File contents of Ansible for AWS + +`ansible.cfg` + +```none +[defaults] +inventory = /root/aws/ip.txt +host_key_checking= False +private_key_file = /root/aws/awsterraform.pem # check the name +remote_user=vyos +``` + +`mykey.pem` + +```none +Copy your key.pem from AWS +``` + +`instance.yml` + +```none +############################################################################## +# About tasks: +# "Wait 300 seconds, but only start checking after 60 seconds" - +# attempts SSH connection every 60 seconds until 300 seconds +# "Configure general settings for the VyOS hosts group" - +# provisions the AWS VyOS node +# Add all necessary VyOS commands under the "lines:" block +############################################################################## + +- name: integration of terraform and ansible + hosts: all + gather_facts: 'no' + + tasks: + + - name: "Wait 300 seconds, but only start checking after 60 seconds" + wait_for_connection: + delay: 60 + timeout: 300 + + - name: "Configure general settings for the VyOS hosts group" + vyos_config: + lines: + - set system name-server xxx.xxx.xxx.xxx + save: + true +``` + +`group_vars/all` + +```none +ansible_connection: ansible.netcommon.network_cli +ansible_network_os: vyos.vyos.vyos +ansible_user: vyos +``` + + +## Source files on GitHub + +All files related to deploying VyOS on AWS with Terraform and Ansible +can be found in the [vyos-automation] repository. + +[group]: https://docs.aws.amazon.com/cli/latest/userguide/cli-services-ec2-sg.html +[image]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html +[install]: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli +[link]: https://developer.hashicorp.com/terraform/intro +[pair]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/create-key-pairs.html +[vyos-automation]: <https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/AWS_terraform_ansible_single_vyos_instance-main> diff --git a/docs/automation/terraform/terraformAZ.md b/docs/automation/terraform/terraformAZ.md new file mode 100644 index 00000000..05856824 --- /dev/null +++ b/docs/automation/terraform/terraformAZ.md @@ -0,0 +1,500 @@ +--- +lastproofread: '2026-03-19' +--- + +(terraformaz)= + +# Deploy VyOS on Microsoft Azure with Terraform and Ansible + +You can use Terraform to quickly deploy VyOS-based infrastructure +on Microsoft Azure (hereafter referred to as *Azure*) and remove +infrastructure when it's no longer needed. +Additionally, you can use Ansible for provisioning. + +On this page you'll learn how to: + +- Create the necessary files for Terraform and Ansible. +- Use Terraform to create a single instance on Azure and use Ansible for + provisioning. + +## Prepare to deploy VyOS with Terraform on Azure + +To create a single instance and install your configuration using +Terraform, Ansible, and Azure, follow these steps: + +### Azure + +- Create an [Azure account](https://azure.microsoft.com/). + +### Terraform + +```{eval-rst} +1. Create an UNIX or Windows instance. + +2. Download and install + `Terraform <https://developer.hashicorp.com/terraform/install>`__. + +3. Create the folder for example ``/root/azvyos/``. + +.. code-block:: none + + mkdir /root/azvyos + +.. stop_vyoslinter + +4. Copy all files into your Terraform project "/root/azvyos" + (``vyos.tf``, ``var.tf``, ``terraform.tfvars``). For more details, see + `Structure of files in Terraform for Azure <#structure-of-files-in-terraform-for-azure>`_. + +.. start_vyoslinter + +5. Log in to Azure using the command: + + .. code-block:: none + + az login + +6. Run the following commands to initialize Terraform: + + .. code-block:: none + + cd /<your folder> + terraform init +``` + + +### Ansible + +1. Create an UNIX instance either locally or in the cloud. + +2. Download and install Ansible + +3. Create a folder, for example `/root/az/`. + +4. Copy all files into your Ansible project `/root/az/` (`ansible.cfg`, + `instance.yml`, `all`). For more details, see + [Structure of files in Ansible for Azure](#structure-of-files-in-ansible-for-azure) + +### Deploy with Terraform + +Run the following commands on your Terraform instance: + +```none +cd /<your folder> +terraform plan +terraform apply +yes +``` + +After executing all the commands, your VyOS instance is deployed to +Azure with your configuration. +If you need to delete the instance, run the following command: + +```none +terraform destroy +``` + + +## Structure of files in Terraform for Azure + +```none +. +├── vyos.tf # The main script +├── var.tf # File for the Terraform version. +└── terraform.tfvars # Values for all variables (passwords, + # login, IP addresses, etc.) +``` + + +## File contents of Terraform for Azure + +`vyos.tf` + +```none +############################################################################## +# HashiCorp Guide to Using Terraform on Azure +# This Terraform configuration will create the following: +# Resource group with a virtual network and subnet +# A VyOS server without SSH key (only login+password) +############################################################################## + +# Choose a provider + +provider "azurerm" { + features {} +} + +# Create a resource group. In Azure, every resource belongs to a +# resource group. + +resource "azurerm_resource_group" "azure_vyos" { + name = "${var.resource_group}" + location = "${var.location}" +} + +# The next resource is a Virtual Network. + +resource "azurerm_virtual_network" "vnet" { + name = "${var.virtual_network_name}" + location = "${var.location}" + address_space = ["${var.address_space}"] + resource_group_name = "${var.resource_group}" +} + +# Build a subnet to run your VMs. + +resource "azurerm_subnet" "subnet" { + name = "${var.prefix}subnet" + virtual_network_name = "${azurerm_virtual_network.vnet.name}" + resource_group_name = "${var.resource_group}" + address_prefixes = ["${var.subnet_prefix}"] +} + +############################################################################## +# Build a VyOS VM from the Marketplace. +# To find the necessary image, use the command: +# +# az vm image list --offer vyos --all +# +# Now that you have a network, you can deploy a VyOS server. +# An Azure Virtual Machine has several components. In this example, +# you build a security group, a network interface, a public IP +# address, a storage account, and finally the VM itself. Terraform +# handles all the dependencies automatically, and each resource is +# named with user-defined variables. +############################################################################## + + +# Security group to allow inbound access on port 22 (SSH) + +resource "azurerm_network_security_group" "vyos-sg" { + name = "${var.prefix}-sg" + location = "${var.location}" + resource_group_name = "${var.resource_group}" + + security_rule { + name = "SSH" + priority = 100 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "${var.source_network}" + destination_address_prefix = "*" + } +} + +# A network interface. + +resource "azurerm_network_interface" "vyos-nic" { + name = "${var.prefix}vyos-nic" + location = "${var.location}" + resource_group_name = "${var.resource_group}" + + ip_configuration { + name = "${var.prefix}ipconfig" + subnet_id = "${azurerm_subnet.subnet.id}" + private_ip_address_allocation = "Dynamic" + public_ip_address_id = "${azurerm_public_ip.vyos-pip.id}" + } +} + +# Add a public IP address. + +resource "azurerm_public_ip" "vyos-pip" { + name = "${var.prefix}-ip" + location = "${var.location}" + resource_group_name = "${var.resource_group}" + allocation_method = "Dynamic" +} + +# Build a virtual machine. This is a standard VyOS instance from +# Marketplace. + +resource "azurerm_virtual_machine" "vyos" { + name = "${var.hostname}-vyos" + location = "${var.location}" + resource_group_name = "${var.resource_group}" + vm_size = "${var.vm_size}" + + network_interface_ids = ["${azurerm_network_interface.vyos-nic.id}"] + delete_os_disk_on_termination = "true" + +# To find information about the plan, use the command: +# az vm image list --offer vyos --all + + plan { + publisher = "sentriumsl" + name = "vyos-1-3" + product = "vyos-1-2-lts-on-azure" + } + + storage_image_reference { + publisher = "${var.image_publisher}" + offer = "${var.image_offer}" + sku = "${var.image_sku}" + version = "${var.image_version}" + } + + storage_os_disk { + name = "${var.hostname}-osdisk" + managed_disk_type = "Standard_LRS" + caching = "ReadWrite" + create_option = "FromImage" + } + + os_profile { + computer_name = "${var.hostname}" + admin_username = "${var.admin_username}" + admin_password = "${var.admin_password}" + } + + os_profile_linux_config { + disable_password_authentication = false + } +} + +data "azurerm_public_ip" "example" { + depends_on = ["azurerm_virtual_machine.vyos"] + name = "vyos-ip" + resource_group_name = "${var.resource_group}" +} +output "public_ip_address" { + value = data.azurerm_public_ip.example.ip_address +} + +# IP of AZ instance copied to a file ip.txt in the local system. + +resource "local_file" "ip" { + content = data.azurerm_public_ip.example.ip_address + filename = "ip.txt" +} + +# Connect to the Ansible control node via SSH + +resource "null_resource" "nullremote1" { +depends_on = ["azurerm_virtual_machine.vyos"] +connection { + type = "ssh" + user = "root" + password = var.password + host = var.host +} + +# Copy the ip.txt file to the Ansible control node from the local +# system + + provisioner "file" { + source = "ip.txt" + destination = "/root/az/ip.txt" + } +} + +resource "null_resource" "nullremote2" { +depends_on = ["azurerm_virtual_machine.vyos"] +connection { + type = "ssh" + user = "root" + password = var.password + host = var.host +} + +# Run the Ansible playbook on the remote Linux OS + +provisioner "remote-exec" { + + inline = [ + "cd /root/az/", + "ansible-playbook instance.yml" +] +} +} +``` + +`var.tf` + +```none +############################################################################## +# Variables File +# +# Default values for all variables used in Terraform code. +############################################################################## + +variable "resource_group" { + description = "The name of your Azure Resource Group." + default = "my_resource_group" +} + +variable "prefix" { + description = "This prefix will be included in the name of some resources." + default = "vyos" +} + +variable "hostname" { + description = "Virtual machine hostname. Used for local hostname, DNS, and storage-related names." + default = "vyos_terraform" +} + +variable "location" { + description = "The region where the virtual network is created." + default = "centralus" +} + +variable "virtual_network_name" { + description = "The name for your virtual network." + default = "vnet" +} + +variable "address_space" { + description = "The address space that is used by the virtual network. You can supply more than one address space. Changing this forces a new resource to be created." + default = "10.0.0.0/16" +} + +variable "subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.0.10.0/24" +} + +variable "storage_account_tier" { + description = "Defines the storage tier. Valid options are Standard and Premium." + default = "Standard" +} + +variable "storage_replication_type" { + description = "Defines the replication type to use for this storage account. Valid options include LRS, GRS etc." + default = "LRS" +} + +# The most cost-effective size + +variable "vm_size" { + description = "Specifies the size of the virtual machine." + default = "Standard_B1s" +} + +variable "image_publisher" { + description = "Name of the publisher of the image (az vm image list)" + default = "sentriumsl" +} + +variable "image_offer" { + description = "Name of the offer (az vm image list)" + default = "vyos-1-2-lts-on-azure" +} + +variable "image_sku" { + description = "Image SKU to apply (az vm image list)" + default = "vyos-1-3" +} + +variable "image_version" { + description = "Version of the image to apply (az vm image list)" + default = "1.3.3" +} + +variable "admin_username" { + description = "Administrator user name" + default = "vyos" +} + +variable "admin_password" { + description = "Administrator password" + default = "Vyos0!" +} + +variable "source_network" { + description = "Allow access from this network prefix. Defaults to '*'." + default = "*" +} + +variable "password" { + description = "pass for Ansible" + type = string + sensitive = true +} +variable "host"{ + description = "IP of my Ansible" +} +``` + +`terraform.tfvars` + +```none +password = "" # password for Ansible SSH +host = "" # IP of my Ansible +``` + + +## Structure of files in Ansible for Azure + +```none +. +├── group_vars + └── all +├── ansible.cfg +└── instance.yml +``` + + +## File contents of Ansible for Azure + +`ansible.cfg` + +```none +[defaults] +inventory = /root/az/ip.txt +host_key_checking= False +remote_user=vyos +``` + +`instance.yml` + +```none +############################################################################## +# About tasks: +# "Wait 300 seconds, but only start checking after 60 seconds" - Tries +# to make SSH connection every 60 seconds until 300 seconds. +# "Configure general settings for the VyOS hosts group" - Provision +# the Azure VyOS node. +# Add all necessary commands for VyOS under the block "lines:" +############################################################################## + + +- name: integration of terraform and ansible + hosts: all + gather_facts: 'no' + + tasks: + + - name: "Wait 300 seconds, but only start checking after 60 seconds" + wait_for_connection: + delay: 60 + timeout: 300 + + - name: "Configure general settings for the VyOS hosts group" + vyos_config: + lines: + - set system name-server xxx.xxx.xxx.xxx + save: + true +``` + +`group_vars/all` + +```none +ansible_connection: ansible.netcommon.network_cli +ansible_network_os: vyos.vyos.vyos + +# user and password gets from terraform variables "admin_username" and "admin_password" in the file /root/azvyos/var.tf +ansible_user: vyos +ansible_ssh_pass: Vyos0! +``` + + +## Source files on GitHub + +All files related to deploying VyOS on Azure with Terraform and Ansible +can be found in the [vyos-automation] repository. + +[vyos-automation]: <https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/Azure_terraform_ansible_single_vyos_instance-main> diff --git a/docs/automation/terraform/terraformGoogle.md b/docs/automation/terraform/terraformGoogle.md new file mode 100644 index 00000000..7236b045 --- /dev/null +++ b/docs/automation/terraform/terraformGoogle.md @@ -0,0 +1,703 @@ +--- +lastproofread: '2026-03-23' +--- + +(terraformgoogle)= + +# Deploy VyOS on Google Cloud with Terraform and Ansible + +Using Terraform, you can quickly deploy VyOS-based infrastructure on +Google Cloud Platform (GCP) and remove the +infrastructure when it's no longer needed. +Additionally, you can use Ansible for provisioning. + +On this page you'll learn how to: + +- Create the necessary files for Terraform and Ansible. +- Use Terraform to create a single instance on GCP and use Ansible for + provisioning. + +## Prepare to deploy VyOS with Terraform on GCP + +To create a single instance and install your configuration using +Terraform, Ansible, and GCP, follow these steps: + +### GCP + +1. Create an account with GCP and a new project. + +```{image} /_static/images/project.webp +:align: center +:alt: Network Topology Diagram +:width: 50% +``` + +2. Create a service account and download your key (a JSON file). + +```{image} /_static/images/service.webp +:align: center +:alt: Network Topology Diagram +:width: 50% +``` + +```{image} /_static/images/key.webp +:align: center +:alt: Network Topology Diagram +:width: 50% +``` + +The .JSON file downloads automatically after you create it and looks +like the following: + +```{image} /_static/images/json.webp +:align: center +:alt: Network Topology Diagram +:width: 50% +``` + +### Terraform + +1. Create an UNIX or Windows instance. + +2. Download and install + [Terraform](https://developer.hashicorp.com/terraform/install). + +3. Create the folder. For example, `/root/google`. + +```none +mkdir /root/google +``` + +4. Copy all files into your Terraform project `/root/google` + (`vyos.tf`, `var.tf`, `terraform.tfvars`, `mykey.json`). + For more details, + see [Structure of files Terraform for Google Cloud](#structure-of-files-in-terraform-for-google-cloud) + +<!-- --> + +5. Run the following commands: + +```none +cd /<your folder> +terraform init +``` + +### Ansible + +1. Create an UNIX instance either locally or in the cloud. + +2. Download and install Ansible + +3. Create the folder for example /root/google/ + +4. Copy all files into your Ansible project `/root/google/` + (`ansible.cfg`, `instance.yml`, `mykey.json`, and `all`). For more + details, see [Structure of files in Ansible for Google Cloud](#structure-of-files-in-ansible-for-google-cloud) + +You obtain `mykey.json` when you create a service account in GCP +and download the key (a JSON file). + +### Deploy with Terraform + +Run the following commands on your Terraform instance: + +```none +cd /<your folder> +terraform plan +terraform apply +yes +``` + +## Create a GCP instance and check its configuration + +```none +# terraform apply + +Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols: + + create + +Terraform will perform the following actions: + + # google_compute_firewall.tcp_22[0] will be created + + resource "google_compute_firewall" "tcp_22" { + + creation_timestamp = (known after apply) + + destination_ranges = (known after apply) + + direction = (known after apply) + + enable_logging = (known after apply) + + id = (known after apply) + + name = "vyos-tcp-22" + + network = "default" + + priority = 1000 + + project = "vyosproject" + + self_link = (known after apply) + + source_ranges = [ + + "0.0.0.0/0", + ] + + target_tags = [ + + "vyos-deployment", + ] + + + allow { + + ports = [ + + "22", + ] + + protocol = "tcp" + } + } + + # google_compute_firewall.udp_500_4500[0] will be created + + resource "google_compute_firewall" "udp_500_4500" { + + creation_timestamp = (known after apply) + + destination_ranges = (known after apply) + + direction = (known after apply) + + enable_logging = (known after apply) + + id = (known after apply) + + name = "vyos-udp-500-4500" + + network = "default" + + priority = 1000 + + project = "vyosproject" + + self_link = (known after apply) + + source_ranges = [ + + "0.0.0.0/0", + ] + + target_tags = [ + + "vyos-deployment", + ] + + + allow { + + ports = [ + + "500", + + "4500", + ] + + protocol = "udp" + } + } + + # google_compute_instance.default will be created + + resource "google_compute_instance" "default" { + + can_ip_forward = true + + cpu_platform = (known after apply) + + current_status = (known after apply) + + deletion_protection = false + + effective_labels = (known after apply) + + guest_accelerator = (known after apply) + + id = (known after apply) + + instance_id = (known after apply) + + label_fingerprint = (known after apply) + + machine_type = "n2-highcpu-4" + + metadata = { + + "enable-oslogin" = "FALSE" + + "serial-port-enable" = "TRUE" + + "user-data" = "" + } + + metadata_fingerprint = (known after apply) + + min_cpu_platform = (known after apply) + + name = "vyos" + + project = "vyosproject" + + self_link = (known after apply) + + tags_fingerprint = (known after apply) + + terraform_labels = (known after apply) + + zone = "us-west1-a" + + + boot_disk { + + auto_delete = true + + device_name = (known after apply) + + disk_encryption_key_sha256 = (known after apply) + + kms_key_self_link = (known after apply) + + mode = "READ_WRITE" + + source = (known after apply) + + + initialize_params { + + image = "projects/sentrium-public/global/images/vyos-1-3-5-20231222143039" + + labels = (known after apply) + + provisioned_iops = (known after apply) + + provisioned_throughput = (known after apply) + + size = (known after apply) + + type = (known after apply) + } + } + + + network_interface { + + internal_ipv6_prefix_length = (known after apply) + + ipv6_access_type = (known after apply) + + ipv6_address = (known after apply) + + name = (known after apply) + + network = "default" + + network_ip = (known after apply) + + nic_type = "GVNIC" + + stack_type = (known after apply) + + subnetwork = "default" + + subnetwork_project = (known after apply) + + + access_config { + + nat_ip = (known after apply) + + network_tier = (known after apply) + } + } + } + + # local_file.ip will be created + + resource "local_file" "ip" { + + content = (known after apply) + + content_base64sha256 = (known after apply) + + content_base64sha512 = (known after apply) + + content_md5 = (known after apply) + + content_sha1 = (known after apply) + + content_sha256 = (known after apply) + + content_sha512 = (known after apply) + + directory_permission = "0777" + + file_permission = "0777" + + filename = "ip.txt" + + id = (known after apply) + } + + # null_resource.SSHconnection1 will be created + + resource "null_resource" "SSHconnection1" { + + id = (known after apply) + } + + # null_resource.SSHconnection2 will be created + + resource "null_resource" "SSHconnection2" { + + id = (known after apply) + } + +Plan: 6 to add, 0 to change, 0 to destroy. + +Changes to Outputs: + + public_ip_address = (known after apply) +╷ +│ Warning: Quoted references are deprecated +│ +│ on vyos.tf line 126, in resource "null_resource" "SSHconnection1": +│ 126: depends_on = ["google_compute_instance.default"] +│ +│ In this context, references are expected literally rather than in quotes. Terraform 0.11 and earlier required quotes, but quoted references are now deprecated and will be removed in a +│ future version of Terraform. Remove the quotes surrounding this reference to silence this warning. +│ +│ (and one more similar warning elsewhere) +╵ + +Do you want to perform these actions? + Terraform will perform the actions described above. + Only 'yes' will be accepted to approve. + + Enter a value: yes + +google_compute_firewall.udp_500_4500[0]: Creating... +google_compute_firewall.tcp_22[0]: Creating... +google_compute_instance.default: Creating... +google_compute_firewall.udp_500_4500[0]: Still creating... [10s elapsed] +google_compute_firewall.tcp_22[0]: Still creating... [10s elapsed] +google_compute_instance.default: Still creating... [10s elapsed] +google_compute_firewall.tcp_22[0]: Creation complete after 16s [id=projects/vyosproject/global/firewalls/vyos-tcp-22] +google_compute_firewall.udp_500_4500[0]: Creation complete after 16s [id=projects/vyosproject/global/firewalls/vyos-udp-500-4500] +google_compute_instance.default: Creation complete after 20s [id=projects/vyosproject/zones/us-west1-a/instances/vyos] +null_resource.SSHconnection1: Creating... +null_resource.SSHconnection2: Creating... +null_resource.SSHconnection1: Provisioning with 'file'... +null_resource.SSHconnection2: Provisioning with 'remote-exec'... +null_resource.SSHconnection2 (remote-exec): Connecting to remote host via SSH... +null_resource.SSHconnection2 (remote-exec): Host: 10.***.***.104 +null_resource.SSHconnection2 (remote-exec): User: root +null_resource.SSHconnection2 (remote-exec): Password: true +null_resource.SSHconnection2 (remote-exec): Private key: false +null_resource.SSHconnection2 (remote-exec): Certificate: false +null_resource.SSHconnection2 (remote-exec): SSH Agent: false +null_resource.SSHconnection2 (remote-exec): Checking Host Key: false +null_resource.SSHconnection2 (remote-exec): Target Platform: unix +local_file.ip: Creating... +local_file.ip: Creation complete after 0s [id=7d568c3b994a018c942a3cdb952ccbf3c729d0ca] +null_resource.SSHconnection2 (remote-exec): Connected! +null_resource.SSHconnection1: Creation complete after 4s [id=5175298735911137161] + +null_resource.SSHconnection2 (remote-exec): PLAY [integration of terraform and ansible] ************************************ + +null_resource.SSHconnection2 (remote-exec): TASK [Wait 300 seconds, but only start checking after 60 seconds] ************** +null_resource.SSHconnection2: Still creating... [10s elapsed] +null_resource.SSHconnection2: Still creating... [20s elapsed] +null_resource.SSHconnection2: Still creating... [30s elapsed] +null_resource.SSHconnection2: Still creating... [40s elapsed] +null_resource.SSHconnection2: Still creating... [50s elapsed] +null_resource.SSHconnection2: Still creating... [1m0s elapsed] +null_resource.SSHconnection2: Still creating... [1m10s elapsed] +null_resource.SSHconnection2 (remote-exec): ok: [104.***.***.158] + +null_resource.SSHconnection2 (remote-exec): TASK [Configure general settings for the vyos hosts group] ********************* +null_resource.SSHconnection2: Still creating... [1m20s elapsed] +null_resource.SSHconnection2 (remote-exec): changed: [104.***.***.158] + +null_resource.SSHconnection2 (remote-exec): PLAY RECAP ********************************************************************* +null_resource.SSHconnection2 (remote-exec): 104.***.***.158 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 + +null_resource.SSHconnection2: Creation complete after 1m22s [id=3355727070503709742] + +Apply complete! Resources: 6 added, 0 changed, 0 destroyed. + +Outputs: + +public_ip_address = "104.***.***.158" +``` + +After running all the commands, your VyOS instance is deployed on +GCP with your specified configuration. +To delete the instance, type the following command: + +```none +terraform destroy +``` + +## Troubleshooting + +- Increase the timeout value in `instance.yml` from 300 seconds to + 500 seconds or more (depends on your location). Ensure that the + security group allows access to the instance. +- If Terraform doesn't connect via SSH to your Ansible instance: + Check the correct login and password in the `VyOS.tf` file. + +```none +connection { + type = "ssh" + user = "root" # open root access using login and password on your Ansible + password = var.password # check password in the file terraform.tfvars isn't empty + host = var.host # check the correct IP address of your Ansible host +} +``` + +Verify that Ansible can ping from Terraform. + +## Structure of files in Terraform for Google Cloud + +```none +. +├── vyos.tf # The main script +├── ***.JSON # The credential file from GCP +├── var.tf # The file of all variables in "vyos.tf" +└── terraform.tfvars # The value of all variables (passwords, login, IP addresses and so on) +``` + +## File contents of Terraform for Google Cloud + +`vyos.tf` + +```none +############################################################################## +# Build a VyOS VM from the Marketplace +# +# After deploying the GCP instance and getting an IP address, the IP address is copied into the file +#"ip.txt" and copied to the Ansible node for provisioning. +############################################################################## + +terraform { + required_providers { + google = { + source = "hashicorp/google" + } + } +} + +provider "google" { + project = var.project_id + request_timeout = "60s" + credentials = file(var.gcp_auth_file) +} + +locals { + network_interfaces = [for i, n in var.networks : { + network = n, + subnetwork = length(var.sub_networks) > i ? element(var.sub_networks, i) : null + external_ip = length(var.external_ips) > i ? element(var.external_ips, i) : "NONE" + } + ] +} + +resource "google_compute_instance" "default" { + name = var.goog_cm_deployment_name + machine_type = var.machine_type + zone = var.zone + + metadata = { + enable-oslogin = "FALSE" + serial-port-enable = "TRUE" + user-data = var.vyos_user_data + } + boot_disk { + initialize_params { + image = var.image + } + } + + can_ip_forward = true + + dynamic "network_interface" { + for_each = local.network_interfaces + content { + network = network_interface.value.network + subnetwork = network_interface.value.subnetwork + nic_type = "GVNIC" + dynamic "access_config" { + for_each = network_interface.value.external_ip == "NONE" ? [] : [1] + content { + nat_ip = network_interface.value.external_ip == "EPHEMERAL" ? null : network_interface.value.external_ip + } + } + } + } +} + +resource "google_compute_firewall" "tcp_22" { + count = var.enable_tcp_22 ? 1 : 0 + + name = "${var.goog_cm_deployment_name}-tcp-22" + network = element(var.networks, 0) + + allow { + ports = ["22"] + protocol = "tcp" + } + + source_ranges = ["0.0.0.0/0"] + + target_tags = ["${var.goog_cm_deployment_name}-deployment"] +} + +resource "google_compute_firewall" "udp_500_4500" { + count = var.enable_udp_500_4500 ? 1 : 0 + + name = "${var.goog_cm_deployment_name}-udp-500-4500" + network = element(var.networks, 0) + +allow { + ports = ["500", "4500"] + protocol = "udp" +} + +source_ranges = ["0.0.0.0/0"] + + target_tags = ["${var.goog_cm_deployment_name}-deployment"] +} + +output "public_ip_address" { + value = google_compute_instance.default.network_interface[0].access_config[0].nat_ip +} + +############################################################################## +# +# IP of google instance copied to a file ip.txt in local system Terraform +# ip.txt looks like: +# cat ./ip.txt +# ххх.ххх.ххх.ххх +############################################################################## + +resource "local_file" "ip" { + content = google_compute_instance.default.network_interface[0].access_config[0].nat_ip + filename = "ip.txt" +} + +#connecting to the Ansible control node using SSH connection + +############################################################################## +# Steps "SSHconnection1" and "SSHconnection2" need to get file ip.txt from the terraform node and start remotely the playbook of Ansible. +############################################################################## + +resource "null_resource" "SSHconnection1" { +depends_on = ["google_compute_instance.default"] +connection { + type = "ssh" + user = "root" + password = var.password + host = var.host +} + +#copying the ip.txt file to the Ansible control node from local system + + provisioner "file" { + source = "ip.txt" + destination = "/root/google/ip.txt" # The folder of your Ansible project + } +} + +resource "null_resource" "SSHconnection2" { +depends_on = ["google_compute_instance.default"] +connection { + type = "ssh" + user = "root" + password = var.password + host = var.host +} + +#command to run Ansible playbook on remote Linux OS + +provisioner "remote-exec" { + inline = [ + "cd /root/google/", + "ansible-playbook instance.yml" # more detailed in "File contents of Ansible for Google Cloud" +] +} +} +``` + +`var.tf` + +```none +variable "image" { + type = string + default = "projects/sentrium-public/global/images/vyos-1-3-5-20231222143039" +} + +variable "project_id" { + type = string +} + +variable "zone" { + type = string +} + +############################################################################## +# You can choose a lower cost machine type than n2-highcpu-4 +############################################################################## + +variable "machine_type" { + type = string + default = "n2-highcpu-4" +} + +variable "networks" { + description = "The network name to attach the VM instance." + type = list(string) + default = ["default"] +} + +variable "sub_networks" { + description = "The sub network name to attach the VM instance." + type = list(string) + default = ["default"] +} + +variable "external_ips" { + description = "The external IPs assigned to the VM for public access." + type = list(string) + default = ["EPHEMERAL"] +} + +variable "enable_tcp_22" { + description = "Allow SSH traffic from the Internet" + type = bool + default = true +} + +variable "enable_udp_500_4500" { + description = "Allow IKE/IPSec traffic from the Internet" + type = bool + default = true +} + +variable "vyos_user_data" { + type = string + default = "" +} + +// Marketplace requires this variable name to be declared +variable "goog_cm_deployment_name" { + description = "VyOS Universal Router Deployment" + type = string + default = "vyos" +} + +# GCP authentication file +variable "gcp_auth_file" { + type = string + description = "GCP authentication file" +} + +variable "password" { + description = "pass for Ansible" + type = string + sensitive = true +} +variable "host"{ + description = "The IP of my Ansible" + type = string +} +``` + +`terraform.tfvars` + +```none +############################################################################## +# Must be filled in +############################################################################## + +zone = "us-west1-a" +gcp_auth_file = "/root/***/***.json" # path of your .json file +project_id = "" # the google project +password = "" # password for Ansible SSH +host = "" # IP of my Ansible +``` + +## Structure of files in Ansible for Google Cloud + +```none +. +├── group_vars + └── all +├── ansible.cfg +└── instance.yml +``` + +## File contents of Ansible for Google Cloud + +`ansible.cfg` + +```none +[defaults] +inventory = /root/google/ip.txt +host_key_checking= False +remote_user=vyos +``` + +`instance.yml` + +```none +############################################################################## +# About tasks: +# "Wait 300 seconds, but only start checking after 60 seconds" - try to make ssh connection every 60 seconds until 300 seconds +# "Configure general settings for the VyOS hosts group" - make provisioning into Google Cloud VyOS node +# Add all necessary VyOS commands under the "lines:" block +############################################################################## + + +- name: integration of terraform and ansible + hosts: all + gather_facts: 'no' + + tasks: + + - name: "Wait 300 seconds, but only start checking after 60 seconds" + wait_for_connection: + delay: 60 + timeout: 300 + + - name: "Configure general settings for the VyOS hosts group" + vyos_config: + lines: + - set system name-server xxx.xxx.xxx.xxx + save: + true +``` + +`group_vars/all` + +```none +ansible_connection: ansible.netcommon.network_cli +ansible_network_os: vyos.vyos.vyos +ansible_user: vyos +ansible_ssh_pass: vyos +``` + + +## Source files on GitHub + +All files related to deploying VyOS on Google Cloud Platform with +Terraform and Ansible can be found in the [vyos-automation] repository. + +[vyos-automation]: <https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/Google_terraform_ansible_single_vyos_instance-main> diff --git a/docs/automation/terraform/terraformvSphere.md b/docs/automation/terraform/terraformvSphere.md new file mode 100644 index 00000000..8bbb91e9 --- /dev/null +++ b/docs/automation/terraform/terraformvSphere.md @@ -0,0 +1,389 @@ +--- +lastproofread: '2026-03-23' +--- + +(terraformvSphere)= + +# Deploy VyOS on VMware vSphere with Terraform and Ansible + +You can use Terraform to quickly deploy VyOS-based infrastructure +on VMware vSphere (hereafter referred to as *vSphere*) and remove +infrastructure when it's no longer needed. +Additionally, you can use Ansible for provisioning. + +On this page you'll learn how to: + +- Create the necessary files for Terraform and Ansible. +- Use Terraform to create a single instance on vSphere and use Ansible for + provisioning. + +## Prepare to deploy VyOS with Terraform on vSphere + +To create a single instance and install your configuration using +Terraform, Ansible, and vSphere, follow these steps: + +### vSphere + +- Add all necessary data to the `terraform.tfvars` + [file](<https://github.com/vyos/vyos-automation/blob/main/TerraformCloud/Vsphere_terraform_ansible_single_vyos_instance-main/terraform.tfvars>) + and create resources. + +### Terraform + +- Create an UNIX or Windows instance. +- Download and install + [Terraform](https://developer.hashicorp.com/terraform/install). +- Create the folder for example `/root/vsphereterraform`. + +```none +mkdir /root/vsphereterraform +``` + +- Copy all files into your Terraform project `/root/vsphereterraform` + (`vyos.tf`, `var.tf`, `terraform.tfvars`, `version.tf`). + For more details, + see [Structure of files in Terraform for vSphere](#structure-of-files-in-terraform-for-vsphere) +- Run the following commands: + +```none +cd /<your folder> +terraform init +``` + + +### Ansible + +- Create an UNIX instance either locally or in the cloud. +- Download and install Ansible. +- Create the folder. For example, `/root/vsphereterraform/`. +- Copy all files into your Ansible project `/root/vsphereterraform/` + (`ansible.cfg`, `instance.yml`, `all`). For more details, see + [Structure of files in Ansible for vSphere](#structure-of-files-in-ansible-for-vsphere) + +### Deploy with Terraform + +Run the following commands on your Terraform instance: + +```none +cd /<your folder> +terraform plan +terraform apply +yes +``` + +After executing these commands, your VyOS instance is deployed to +vSphere with your configuration. +If you need to delete the instance, run the following command: + +```none +terraform destroy +``` + +## Structure of files in Terraform for vSphere + +```none +. +├── vyos.tf # The main script. +├── versions.tf # File for Terraform version. +├── var.tf # File for Terraform version. +└── terraform.tfvars # Values for all variables (passwords, + # login, IP addresses, etc.). +``` + +## File contents of Terraform for vSphere + +`vyos.tf` + +```none +provider "vsphere" { + user = var.vsphere_user + password = var.vsphere_password + vsphere_server = var.vsphere_server + allow_unverified_ssl = true +} + +data "vsphere_datacenter" "datacenter" { + name = var.datacenter +} + +data "vsphere_datastore" "datastore" { + name = var.datastore + datacenter_id = data.vsphere_datacenter.datacenter.id +} + +data "vsphere_compute_cluster" "cluster" { + name = var.cluster + datacenter_id = data.vsphere_datacenter.datacenter.id +} + +data "vsphere_resource_pool" "default" { + name = format("%s%s", data.vsphere_compute_cluster.cluster.name, "/Resources/terraform") # set as you need + datacenter_id = data.vsphere_datacenter.datacenter.id +} + +data "vsphere_host" "host" { + name = var.host + datacenter_id = data.vsphere_datacenter.datacenter.id +} + +data "vsphere_network" "network" { + name = var.network_name + datacenter_id = data.vsphere_datacenter.datacenter.id +} + +# Deployment of VM from Remote OVF +resource "vsphere_virtual_machine" "vmFromRemoteOvf" { + name = var.remotename + datacenter_id = data.vsphere_datacenter.datacenter.id + datastore_id = data.vsphere_datastore.datastore.id + host_system_id = data.vsphere_host.host.id + resource_pool_id = data.vsphere_resource_pool.default.id + network_interface { + network_id = data.vsphere_network.network.id + } + wait_for_guest_net_timeout = 2 + wait_for_guest_ip_timeout = 2 + + ovf_deploy { + allow_unverified_ssl_cert = true + remote_ovf_url = var.url_ova + disk_provisioning = "thin" + ip_protocol = "IPv4" + ip_allocation_policy = "dhcpPolicy" + ovf_network_map = { + "Network 1" = data.vsphere_network.network.id + "Network 2" = data.vsphere_network.network.id + } + } + vapp { + properties = { + "password" = "12345678", + "local-hostname" = "terraform_vyos" + } + } +} + +output "ip" { + description = "default ip address of the deployed VM" + value = vsphere_virtual_machine.vmFromRemoteOvf.default_ip_address +} + +# IP of vSphere instance copied to a file ip.txt in local system + +resource "local_file" "ip" { + content = vsphere_virtual_machine.vmFromRemoteOvf.default_ip_address + filename = "ip.txt" +} + +#Connecting to the Ansible control node using SSH connection + +resource "null_resource" "nullremote1" { +depends_on = ["vsphere_virtual_machine.vmFromRemoteOvf"] +connection { + type = "ssh" + user = "root" + password = var.ansiblepassword + host = var.ansiblehost + +} + +# Copying the ip.txt file to the Ansible control node from local system + + provisioner "file" { + source = "ip.txt" + destination = "/root/vsphere/ip.txt" + } +} + +resource "null_resource" "nullremote2" { +depends_on = ["vsphere_virtual_machine.vmFromRemoteOvf"] +connection { + type = "ssh" + user = "root" + password = var.ansiblepassword + host = var.ansiblehost +} + +# Command to run ansible playbook on remote Linux OS + +provisioner "remote-exec" { + + inline = [ + "cd /root/vsphere/", + "ansible-playbook instance.yml" +] +} +} +``` + +`versions.tf` + +```none +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +terraform { + required_providers { + vsphere = { + source = "hashicorp/vsphere" + version = "2.4.0" + } + } +} +``` + +`var.tf` + +```none +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +variable "vsphere_server" { + description = "vSphere server" + type = string +} + +variable "vsphere_user" { + description = "vSphere username" + type = string +} + +variable "vsphere_password" { + description = "vSphere password" + type = string + sensitive = true +} + +variable "datacenter" { + description = "vSphere data center" + type = string +} + +variable "cluster" { + description = "vSphere cluster" + type = string +} + +variable "datastore" { + description = "vSphere datastore" + type = string +} + +variable "network_name" { + description = "vSphere network name" + type = string +} + +variable "host" { + description = "Name of your host" + type = string +} + +variable "remotename" { + description = "The name of your VM" + type = string +} + +variable "url_ova" { + description = "The URL to the .OVA file or cloud storage" + type = string +} + +variable "ansiblepassword" { + description = "Ansible password" + type = string +} + +variable "ansiblehost" { + description = "Ansible host name or IP" + type = string +} +``` + +`terraform.tfvars` + +```none +vsphere_user = "" +vsphere_password = "" +vsphere_server = "" +datacenter = "" +datastore = "" +cluster = "" +network_name = "" +host = "" +url_ova = "" +ansiblepassword = "" +ansiblehost = "" +remotename = "" +``` + +## Structure of files in Ansible for vSphere + +```none +. +├── group_vars + └── all +├── ansible.cfg +└── instance.yml +``` + +## File contents of Ansible for vSphere + +`ansible.cfg` + +```none +[defaults] +inventory = /root/vsphere/ip.txt +host_key_checking= False +remote_user=vyos +``` + +`instance.yml` + +```none +############################################################################## +# About tasks: +# "Wait 300 seconds, but only start checking after 60 seconds" - try to make ssh connection every 60 seconds until 300 seconds +# "Configure general settings for the VyOS hosts group" - make provisioning into vSphere VyOS node +# You have to add all necessary cammans of VyOS under the block "lines:" +############################################################################## + + +- name: integration of terraform and ansible + hosts: all + gather_facts: 'no' + + tasks: + + - name: "Wait 300 seconds, but only start checking after 60 seconds" + wait_for_connection: + delay: 60 + timeout: 300 + - name: "Configure general settings for the VyOS hosts group" + vyos_config: + lines: + - set system name-server 192.0.2.1 + - set system name-server 192.0.2.1 + save: + true +``` + +`group_vars/all` + +```none +ansible_connection: ansible.netcommon.network_cli +ansible_network_os: vyos.vyos.vyos + +# user and password gets from terraform variables "admin_username" and "admin_password" +ansible_user: vyos +# get from vyos.tf "vapp" +ansible_ssh_pass: 12345678 +``` + + +## Source files on GitHub + +All files related to deploying VyOS on vSphere with Terraform and Ansible +can be found in the [vyos-automation] repository. + +[vyos-automation]: <https://github.com/vyos/vyos-automation/tree/main/TerraformCloud/Vsphere_terraform_ansible_single_vyos_instance-main> diff --git a/docs/automation/terraform/terraformvyos.md b/docs/automation/terraform/terraformvyos.md new file mode 100644 index 00000000..bfe1b6d1 --- /dev/null +++ b/docs/automation/terraform/terraformvyos.md @@ -0,0 +1,44 @@ +--- +lastproofread: '2024-03-03' +--- + +(terraformvyos)= + +# Terraform for VyOS + +VyOS supports development infrastructure via Terraform and +provisioning via Ansible. Terraform allows you to automate the +process of deploying instances on many cloud and virtual +platforms. In this article, we will look at using Terraform to +deploy VyOS on platforms - AWS, Azure, and vSphere. For more +details about Terraform please have a look at [link]. + +You will need to [install] Terraform before proceeding. + +Structure of files in the standard Terraform project: + +```none +. +├── main.tf # The main script +├── version.tf # File for the changing version of Terraform. +├── variables.tf # The file of all variables in "main.tf" +└── terraform.tfvars # The value of all variables (passwords, login, IP addresses and so on) +``` + +General commands that we will use for running Terraform scripts + +```none +cd /<your folder> # go to the Terraform project +terraform init # install all add-ons and providers (AWS, Azure, and so on) +terraform plan # show what is changing +terraform apply # run script +yes # apply running +``` + +% stop_vyoslinter + +% start_vyoslinter + +[install]: https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli +[link]: https://developer.hashicorp.com/terraform/intro + |
