summaryrefslogtreecommitdiff
path: root/docs/automation/terraform
diff options
context:
space:
mode:
authorYuriy Andamasov <yuriy@vyos.io>2026-05-02 17:25:47 +0300
committerYuriy Andamasov <yuriy@vyos.io>2026-05-06 16:18:03 +0300
commitfa54a080fac977157454beb0853daf0ac0e6af66 (patch)
tree82b112cde06437b80515450d63eb793bee198ec6 /docs/automation/terraform
parent746195618941d8be8ed132f4b0be539763ec352d (diff)
downloadvyos-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.md29
-rw-r--r--docs/automation/terraform/terraformAWS.md551
-rw-r--r--docs/automation/terraform/terraformAZ.md500
-rw-r--r--docs/automation/terraform/terraformGoogle.md703
-rw-r--r--docs/automation/terraform/terraformvSphere.md389
-rw-r--r--docs/automation/terraform/terraformvyos.md44
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
+