Setting up networking between resources in different folders
In Yandex Cloud, network resources, such as cloud network and subnets, are usually created in a single resource cloud folder that is not linked to resources in other cloud folders. When deploying resources in Yandex Cloud, it is often necessary to ensure networking between resources residing in different folders. One of the ways to do that is using the Multi-folder VPC
method that extends the scope of an individual VPC network to multiple rather than one folder.
Depending on the selected Yandex Cloud management interface, a network's scope is extended to other folders by:
- Moving subnets to other cloud folders using the
management console (UI)
orYC CLI
. - Creating subnets in target folders using
YC CLI
. - Creating subnets in target folders using
Terraform
.
After that, you can connect VMs, Managed Service for Kubernetes clusters, database hosts, load balancers, load testing agents, and other resources residing in these folders, to the subnets hosted in target folders. As a result, your network will ensure connectivity between resources in different folders.
This guide provides an example of how to create an infrastructure consisting of three VM instances, each residing in a different folder. These instances are connected via a shared internal network. Network connectivity between cloud resources hosted in different folders is established by creating a cloud network in one of these folders and then extending its scope to other folders. This way, a single-folder network is extended to multiple folders, which allows connecting required resources to extended subnets
residing in these folders.
Warning
You can only move subnets between folders within a single cloud.
For example, the development environment includes the CI/CD module whose components are hosted in the net-folder
. This module should enable networking between the dev, stage, and prod components residing in their folders.
This solution pattern is shown below.
This will set up networking between VMs from different environments (folders) connected to different subnets in one network. Furthermore, all VMs will be able to communicate with one another both by IPs and their FQDNs (over DNS).
Steps to follow
Depending on the selected management interface, steps to create Multi-folder VPC
may differ.
To create a test infrastructure and enable networking between resources:
- Prepare your cloud.
- Create folders without a VPC network.
- Create a VPC cloud network with subnets.
- Move the subnets.
- Create VM instances.
- Check the networking.
If you no longer need the resources you created, delete them.
Prepare your cloud
Sign up for Yandex Cloud and create a billing account:
- Go to the management console
and log in to Yandex Cloud or create an account if you do not have one yet. - On the Yandex Cloud Billing
page, make sure you have a billing account linked and it has theACTIVE
orTRIAL_ACTIVE
status. If you do not have a billing account, create one.
If you have an active billing account, you can go to the cloud page
Learn more about clouds and folders.
Required paid resources
The infrastructure support costs include:
- Fee for continuously running VMs (see Yandex Compute Cloud pricing).
- Fee for using public IP addresses and outgoing traffic (see Yandex Virtual Private Cloud pricing).
Set up access rights
Set up access rights for the folder:
- To create networks and manage subnets, assign the
vpc.admin
or thevpc.privateAdmin
,vpc.publicAdmin
, andvpc.securityGroups.admin
service roles to the service account or user. - To create and manage VMs in the folder, assign the
vpc.user
andcompute.admin
service roles.
For granular network access, use security groups.
Create folders without a VPC network
-
Created the
net-folder
,dev-folder
, andprod-folder
folders:Management consoleCLITerraformAPI- In the management console
, select a cloud and click Create folder. - Enter the folder name:
net-folder
. - Disable Create a default network to create your network and subnets manually.
- Click Create.
Similarly, create two more folders without the VPC network, and name them
dev-folder
andprod-folder
.If you do not have the Yandex Cloud command line interface yet, install and initialize it.
Note
To create resources using the CLI, get authenticated using the service account that has the
admin
role for the cloud.-
View the description of the create folder command:
yc resource-manager folder create --help
-
Created the
net-folder
,dev-folder
, andprod-folder
cloud folders:yc resource-manager folder create --name net-folder yc resource-manager folder create --name dev-folder yc resource-manager folder create --name prod-folder
-
If you don't have Terraform, install it and configure the Yandex Cloud provider.
-
Specify the Yandex Cloud Terraform provider configuration:
# ================================== # Terraform & Provider Configuration # ================================== terraform { required_providers { yandex = { source = "yandex-cloud/yandex" version = "~> 0.92.0" } } }
-
Describe the input variables:
variable "cloud_id" { description = "YC cloud-id. Taken from environment variable." }
-
Describe the targets (cloud folders):
# ======== # Folders # ======== resource "yandex_resourcemanager_folder" "net_folder" { cloud_id = var.cloud_id name = "net-folder" } resource "yandex_resourcemanager_folder" "dev_folder" { cloud_id = var.cloud_id name = "dev-folder" } resource "yandex_resourcemanager_folder" "prod_folder" { cloud_id = var.cloud_id name = "prod-folder" }
-
Create the required infrastructure:
-
Run the following commands:
export TF_VAR_cloud_id=$(yc config get cloud-id) export YC_TOKEN=$(yc iam create-token) terraform apply
-
Confirm updating the resources and wait for the operation to complete.
-
Use the create REST API method for the Folder resource or the FolderService/Create gRPC API call.
- In the management console
Create a VPC cloud network with subnets
In net-folder
, create a network named shared-net
with three subnets that have the following settings:
Subnet name | Prefix | Availability zone | Target folder |
---|---|---|---|
subnet-a |
10.1.11.0/24 |
ru-central1-a |
net-folder |
subnet-b |
10.1.12.0/24 |
ru-central1-b |
dev-folder |
subnet-d |
10.1.13.0/24 |
ru-central1-d |
prod-folder |
-
Create a cloud network:
Management consoleCLITerraformAPI- In the management console
, go tonet-folder
. - In the list of services, select Virtual Private Cloud.
- Click Create network.
- Enter the network name:
shared-net
. - Disable Create subnets to create subnets manually.
- Click Create network.
-
See the description of the CLI command for creating a cloud network:
yc vpc network create --help
-
Create the
shared-net
cloud network innet-folder
.yc vpc network create --folder-name net-folder --name shared-net
-
Describe the target (cloud network):
# ============= # VPC Resources # ============= resource "yandex_vpc_network" "shared_net" { folder_id = yandex_resourcemanager_folder.net_folder.id name = "shared-net" }
-
Run the following commands:
export TF_VAR_cloud_id=$(yc config get cloud-id) export YC_TOKEN=$(yc iam create-token) terraform apply
-
Confirm updating the resources.
-
Wait for the operation to complete.
Use the create REST API method for the Network resource or the NetworkService/Create gRPC API call.
- In the management console
-
Create a subnet named
subnet-a
in theru-central1-a
availability zone:Management consoleCLITerraformAPI- In the management console
, go tonet-folder
. - In the list of services, select Virtual Private Cloud.
- Click the
shared-net
name. - Click Create subnet.
- Enter the subnet name:
subnet-a
. - Select the
ru-central1-a
availability zone from the drop-down list. - Enter the subnet CIDR:
10.1.11.0
as IP address and24
as subnet mask. For more information about subnet IP address ranges, see Cloud networks and subnets. - Click Create subnet.
Similarly, create
subnet-b
andsubnet-d
in theru-central1-b
andru-central1-d
availability zones in net-folder.-
See the description of the CLI command for creating a subnet:
yc vpc subnet create --help
-
Create subnets in the target folders:
yc vpc subnet create --folder-name net-folder --name subnet-a \ --network-name shared-net --zone ru-central1-a --range 10.1.11.0/24 yc vpc subnet create --folder-name dev-folder --name subnet-b \ --network-name shared-net --zone ru-central1-b --range 10.1.12.0/24 yc vpc subnet create --folder-name prod-folder --name subnet-d \ --network-name shared-net --zone ru-central1-d --range 10.1.13.0/24
-
Check the state of the created subnets:
yc vpc subnet list --folder-name net-folder yc vpc subnet list --folder-name dev-folder yc vpc subnet list --folder-name prod-folder
-
Describe the targets (cloud subnets):
resource "yandex_vpc_subnet" "subnet_a" { folder_id = yandex_resourcemanager_folder.net_folder.id name = "subnet-a" description = "NET folder subnet" v4_cidr_blocks = ["10.1.11.0/24"] zone = "ru-central1-a" network_id = yandex_vpc_network.shared_net.id } resource "yandex_vpc_subnet" "subnet_b" { folder_id = yandex_resourcemanager_folder.dev_folder.id name = "subnet-b" description = "DEV folder subnet" v4_cidr_blocks = ["10.1.12.0/24"] zone = "ru-central1-b" network_id = yandex_vpc_network.shared_net.id } resource "yandex_vpc_subnet" "subnet_d" { folder_id = yandex_resourcemanager_folder.prod_folder.id name = "subnet-d" description = "PROD folder subnet" v4_cidr_blocks = ["10.1.13.0/24"] zone = "ru-central1-d" network_id = yandex_vpc_network.shared_net.id }
-
Run the following commands:
export TF_VAR_cloud_id=$(yc config get cloud-id) export YC_TOKEN=$(yc iam create-token) terraform apply
-
Confirm updating the resources and wait for the operation to complete.
Use the create REST API method for the Subnet resource or the SubnetService/Create gRPC API call.
- In the management console
Move the subnets
Move the subnet-b
subnet to dev-folder
:
- In the management console
, go tonet-folder
. - In the list of services, select Virtual Private Cloud.
- Click the
shared-net
name. - In the
subnet-b
row, click and select Move. - In the drop-down list, select
dev-folder
. - Click Move.
-
View a description of the CLI move subnet command:
yc vpc subnet move --help
-
Move the subnet:
yc vpc subnet move subnet-b \ --destination-folder-name dev-folder
Use the move REST API method for the Subnet resource or the SubnetService/Move gRPC API call.
Similarly, move subnet-d
to prod-folder
:
Create VMs
Create VMs with the following parameters:
VM name | Folder | Availability zone | Subnet |
---|---|---|---|
net-vm |
net-folder |
ru-central1-a |
subnet-a |
dev-vm |
dev-folder |
ru-central1-b |
subnet-b |
prod-vm |
prod-folder |
ru-central1-d |
subnet-d |
Create a Linux VM named net-vm
in net-folder
:
- In the management console
, selectnet-folder
. - In the list of services, select Compute Cloud.
- Click Create virtual machine.
- Under General information:
- Enter the name:
net-vm
. - Select the
ru-central1-a
availability zone.
- Enter the name:
- Under Boot disk image, select Ubuntu 22.04 LTS.
- Under Network settings, select
subnet-a
. - Under Access, specify the data for access to the VM:
- In the Login field, enter the
ycuser
username. - In the SSH key field, paste the contents of the public key file. You need to create a key pair for the SSH connection on your own.
- In the Login field, enter the
- Leave all other settings unchanged and click Create VM.
Similarly, create VMs named dev-vm
and prod-vm
in the respective folders.
Note
A public and a private IP addresses are assigned to the VM when you create it. Write them down, as you will need them to access the VM and test networking with other VMs.
-
Describe a template for VM metadata in a separate
vm-init.tpl
file:#cloud-config datasource: Ec2: strict_id: false ssh_pwauth: yes users: - name: "${USER_NAME}" sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash ssh-authorized-keys: - "${USER_SSH_KEY}"
-
Generate a metadata file to deploy the VM:
export USER_NAME=ycuser export USER_SSH_KEY=$(cat ~/.ssh/id_rsa.pub) envsubst < vm-init.tpl > vm-config.txt
-
Create VMs:
yc compute instance create --name=net-vm --hostname=net-vm \ --zone=ru-central1-a \ --platform=standard-v3 \ --cores=2 --memory=4G --core-fraction=100 \ --create-boot-disk image-folder-id=standard-images,image-family=ubuntu-2204-lts \ --network-interface subnet-name=subnet-a,ipv4-address=auto,nat-ip-version=ipv4 \ --metadata-from-file user-data=vm-config.txt yc compute instance create --name=dev-vm --hostname=dev-vm \ --zone=ru-central1-b \ --platform=standard-v3 \ --cores=2 --memory=4G --core-fraction=100 \ --create-boot-disk image-folder-id=standard-images,image-family=ubuntu-2204-lts \ --network-interface subnet-name=default-ru-central1-b,ipv4-address=auto,nat-ip-version=ipv4 \ --metadata-from-file user-data=vm-config.txt yc compute instance create --name=prod-vm --hostname=prod-vm \ --zone=ru-central1-d \ --platform=standard-v3 \ --cores=2 --memory=4G --core-fraction=100 \ --create-boot-disk image-folder-id=standard-images,image-family=ubuntu-2204-lts \ --network-interface subnet-name=default-ru-central1-d,ipv4-address=auto,nat-ip-version=ipv4 \ --metadata-from-file user-data=vm-config.txt
-
Save the VM public IPs to use them later:
NET_VM_IP=$(yc compute instance get net-vm --format=json | jq -r '.network_interfaces[0].primary_v4_address.one_to_one_nat.address') DEV_VM_IP=$(yc compute instance get dev-vm --format=json | jq -r '.network_interfaces[0].primary_v4_address.one_to_one_nat.address') PROD_VM_IP=$(yc compute instance get prod-vm --format=json | jq -r '.network_interfaces[0].primary_v4_address.one_to_one_nat.address')
-
Describe the input variables:
variable "user_name" { description = "VM User Name" default = "ycuser" } variable "user_ssh_key_path" { description = "User's SSH public key file" default = "~/.ssh/id_rsa.pub" }
-
Describe a template for VM metadata in a separate
vm-init.tpl
file:#cloud-config datasource: Ec2: strict_id: false ssh_pwauth: yes users: - name: "${USER_NAME}" sudo: ALL=(ALL) NOPASSWD:ALL shell: /bin/bash ssh-authorized-keys: - "${USER_SSH_KEY}"
-
Describe the targets (VMs):
# ================= # Compute Resources # ================= data "yandex_compute_image" "vm_image" { family = "ubuntu-2204-lts" } resource "yandex_compute_disk" "boot-disk-1" { name = "boot-disk-1" type = "network-hdd" zone = "ru-central1-a" size = "20" image_id = yandex_compute_image.vm_image.id } resource "yandex_compute_disk" "boot-disk-2" { name = "boot-disk-2" type = "network-hdd" zone = "ru-central1-b" size = "20" image_id = yandex_compute_image.vm_image.id } resource "yandex_compute_disk" "boot-disk-3" { name = "boot-disk-3" type = "network-hdd" zone = "ru-central1-d" size = "20" image_id = yandex_compute_image.vm_image.id } resource "yandex_compute_instance" "net_vm" { folder_id = yandex_resourcemanager_folder.net_folder.id name = "net-vm" hostname = "net-vm" platform_id = "standard-v3" zone = "ru-central1-a" resources { cores = 2 memory = 4 } boot_disk { disk_id = yandex_compute_disk.boot-disk-1.id } network_interface { subnet_id = yandex_vpc_subnet.subnet_a.id nat = true } metadata = { user-data = templatefile("vm-init.tpl", { USER_NAME = var.user_name USER_SSH_KEY = file(var.user_ssh_key_path) }) } } resource "yandex_compute_instance" "dev_vm" { folder_id = yandex_resourcemanager_folder.dev_folder.id name = "dev-vm" hostname = "dev-vm" platform_id = "standard-v3" zone = "ru-central1-b" resources { cores = 2 memory = 4 } boot_disk { disk_id = yandex_compute_disk.boot-disk-2.id } network_interface { subnet_id = yandex_vpc_subnet.subnet_b.id nat = true } metadata = { user-data = templatefile("vm-init.tpl", { USER_NAME = var.user_name USER_SSH_KEY = file(var.user_ssh_key_path) }) } } resource "yandex_compute_instance" "prod_vm" { folder_id = yandex_resourcemanager_folder.prod_folder.id name = "prod-vm" hostname = "prod-vm" platform_id = "standard-v3" zone = "ru-central1-d" resources { cores = 2 memory = 4 } boot_disk { disk_id = yandex_compute_disk.boot-disk-3.id } network_interface { subnet_id = yandex_vpc_subnet.subnet_d.id nat = true } metadata = { user-data = templatefile("vm-init.tpl", { USER_NAME = var.user_name USER_SSH_KEY = file(var.user_ssh_key_path) }) } } # ======= # Outputs # ======= output "NET-vm" { value = yandex_compute_instance.network_vm.network_interface.0.nat_ip_address } output "DEV-vm" { value = yandex_compute_instance.dev_vm.network_interface.0.nat_ip_address } output "PROD-vm" { value = yandex_compute_instance.prod_vm.network_interface.0.nat_ip_address }
-
Run the following commands:
export TF_VAR_cloud_id=$(yc config get cloud-id) export YC_TOKEN=$(yc iam create-token) terraform apply
-
Confirm updating the resources and wait for the operation to complete.
To create a VM, use the create REST API method for the Compute Instance resource or the InstanceService/Create gRPC API call.
Check network connectivity across the resources
-
Connect to the
net-vm
VM over SSH:ssh ycuser@<net-vm_public_IP_address>
-
Check the IP connectivity to
dev-vm
inside the VPC:ping -c3 <net-vm_internal_IP_address>
Result:
PING 10.127.20.4 (10.127.20.4) 56(84) bytes of data. 64 bytes from 10.127.20.4: icmp_seq=1 ttl=61 time=7.45 ms 64 bytes from 10.127.20.4: icmp_seq=2 ttl=61 time=5.61 ms 64 bytes from 10.127.20.4: icmp_seq=3 ttl=61 time=5.65 ms --- 10.127.20.4 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 5.613/6.235/7.446/0.855 ms
-
Similarly, check the IP connectivity to
prod-vm
inside the VPC. -
Connect to
dev-vm
over SSH and check the IP connectivity tonet-vm
andprod-vm
through the ping command. -
Connect to
prod-vm
over SSH and check the IP connectivity tonet-vm
anddev-vm
through the ping command.
How to delete the resources you created
To stop paying for the resources you created, delete net-vm
, dev-vm
, and prod-vm
.