Assigning a domain name to a VM with a web server
In this tutorial, you will assign your own domain name to a VM with a web server. You can use any domain name registrar to register your domain name.
To create a VM, this tutorial uses a public LAMP image with a pre-installed Apache HTTP server
To assign a domain name to a VM with a web server in Cloud DNS:
- Prepare your cloud.
- Create a VM with a web server.
- Create a public DNS zone.
- Delegate your domain to Cloud DNS.
- Create a type A resource record.
- Test the website.
If you no longer need the resources you created, delete them.
You can also assign a domain name to a VM with a web server via Terraform using a ready-made configuration file.
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 support cost includes:
- Fee for using a public IP address (see Yandex Virtual Private Cloud pricing).
- Fee for VM computing resources and disks (see Yandex Compute Cloud pricing).
- Fee for using a public DNS zone and public DNS requests (see Yandex Cloud DNS pricing).
Create a cloud network and subnet
- In the management console
, select your folder. - In the list of services, select Virtual Private Cloud.
- At the top right, click Create network.
- In the Name field, specify
webserver-network
. - In the Advanced field, disable the Create subnets option.
- Click Create network.
- In the left-hand panel, select
Subnets. - At the top right, click Create.
- In the Name field, specify
webserver-subnet-ru-central1-b
. - In the Zone field, select the
ru-central1-b
availability zone. - In the Network field, select the cloud network named
webserver-network
. - In the CIDR field, specify
192.168.1.0/24
. - Click Create subnet.
If you do not have the Yandex Cloud command line interface yet, install and initialize it.
The folder specified in the CLI profile is used by default. You can specify a different folder using the --folder-name
or --folder-id
parameter.
-
Create the
webserver-network
cloud network.yc vpc network create webserver-network
Result:
id: enp1gg8kr3pv******** folder_id: b1gt6g8ht345******** created_at: "2023-12-20T20:08:11Z" name: webserver-network default_security_group_id: enppne4l2eg5********
For more information about the
yc vpc network create
command, see the CLI reference. -
Create a subnet in the
ru-central1-b
availability zone:yc vpc subnet create webserver-subnet-ru-central1-b \ --zone ru-central1-b \ --network-name webserver-network \ --range 192.168.1.0/24
Result:
id: e2li9tcgi7ii******** folder_id: b1gt6g8ht345******** created_at: "2023-12-20T20:11:16Z" name: webserver-subnet-ru-central1-b network_id: enp1gg8kr3pv******** zone_id: ru-central1-b v4_cidr_blocks: - 192.168.1.0/24
For more information about the
yc vpc subnet create
command, see the CLI reference.
See How to create an infrastructure using Terraform for details.
-
To create a cloud network, use the create REST API method for the Network resource or the NetworkService/Create gRPC API call.
-
To create a subnet, use the create REST API method for the Subnet resource or the SubnetService/Create gRPC API call.
Create a security group
Create a security group that allows inbound TCP traffic on ports 22
, 80
, and 443
as well as any outbound traffic.
-
In the management console
, select your folder. -
In the list of services, select Virtual Private Cloud.
-
In the left-hand panel, select
Security groups. -
Click Create security group.
-
In the Name field, enter the name:
webserver-sg
. -
In the Network field, select the
webserver-network
network you created earlier. -
Under Rules, create the following traffic management rules:
Traffic
directionDescription Port range Protocol Source /
Destination nameCIDR blocks Incoming http
80
TCP
CIDR
0.0.0.0/0
Incoming https
443
TCP
CIDR
0.0.0.0/0
Incoming ssh
22
TCP
CIDR
0.0.0.0/0
Outgoing any
All
Any
CIDR
0.0.0.0/0
-
Click Save.
Run this command:
yc vpc security-group create \
--name webserver-sg \
--rule "description=http,direction=ingress,port=80,protocol=tcp,v4-cidrs=[0.0.0.0/0]" \
--rule "description=https,direction=ingress,port=443,protocol=tcp,v4-cidrs=[0.0.0.0/0]" \
--rule "description=ssh,direction=ingress,port=22,protocol=tcp,v4-cidrs=[0.0.0.0/0]" \
--rule "description=any,direction=egress,port=any,protocol=any,v4-cidrs=[0.0.0.0/0]" \
--network-name webserver-network
Result:
id: enp4htsnl1sa********
folder_id: b1gt6g8ht345********
created_at: "2023-12-23T19:07:03Z"
name: webserver-sg
network_id: enp37qpnksl2********
status: ACTIVE
rules:
- id: enpdu0t8san9********
description: http
direction: INGRESS
ports:
from_port: "80"
to_port: "80"
protocol_name: TCP
protocol_number: "6"
cidr_blocks:
v4_cidr_blocks:
- 0.0.0.0/0
- id: enpr7oirpff5********
description: https
direction: INGRESS
ports:
from_port: "443"
to_port: "443"
protocol_name: TCP
protocol_number: "6"
cidr_blocks:
v4_cidr_blocks:
- 0.0.0.0/0
- id: enp0bgk6dkdd********
description: ssh
direction: INGRESS
ports:
from_port: "22"
to_port: "22"
protocol_name: TCP
protocol_number: "6"
cidr_blocks:
v4_cidr_blocks:
- 0.0.0.0/0
- id: enpspns0tfml********
description: any
direction: EGRESS
protocol_name: ANY
protocol_number: "-1"
cidr_blocks:
v4_cidr_blocks:
- 0.0.0.0/0
For more information about the yc vpc security-group create
command, see the CLI reference.
Save the security group ID (id
) as you will need it to create a VM.
See How to create an infrastructure using Terraform for details.
To create a security group, use the create REST API method for the SecurityGroup resource or the SecurityGroupService/Create gRPC API call.
Create a VM with a web server
Before you start, prepare a key pair (public and private keys) to access your VM over SSH.
-
In the management console
, select the folder to create your VM in. -
In the list of services, select Compute Cloud.
-
In the left-hand panel, select
Virtual machines. -
Click Create virtual machine.
-
Under Boot disk image:
- Go to the Marketplace tab.
- Click Show all Marketplace products.
- In the list of public images, select LAMP and click Use.
-
Under Location, select the
ru-central1-b
availability zone. -
Under Network settings:
- In the Subnet field, select the
webserver-subnet-ru-central1-b
subnet you created earlier. - In the Public IP field, select
Auto
. - In the Security groups field, select the
webserver-sg
security group you created earlier.
- In the Subnet field, select the
-
Under Access, specify the information required to access the VM:
- In the Login field, enter the
yc-user
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 yourself. To learn how, see Connecting to a VM via SSH.
- In the Login field, enter the
-
Under General information, specify the VM name:
mywebserver
. -
Click Create VM.
Run the command specifying the security group ID you saved at the previous step:
yc compute instance create \
--name mywebserver \
--zone ru-central1-b \
--network-interface subnet-name=webserver-subnet-ru-central1-b,nat-ip-version=ipv4,security-group-ids=<security_group_ID> \
--create-boot-disk image-folder-id=standard-images,image-id=fd8jtn9i7e9ha5q25niu \
--ssh-key <SSH_key>
Where --ssh-key
is the path to the public SSH key file and its name, e.g., ~/.ssh/id_ed25519.pub
.
Result:
done (32s)
id: fhmaq4shfrcm********
folder_id: b1gt6g8ht345********
created_at: "2023-12-23T05:36:34Z"
name: mywebserver
zone_id: ru-central1-b
platform_id: standard-v2
resources:
memory: "2147483648"
cores: "2"
core_fraction: "100"
status: RUNNING
metadata_options:
gce_http_endpoint: ENABLED
aws_v1_http_endpoint: ENABLED
gce_http_token: ENABLED
aws_v1_http_token: DISABLED
boot_disk:
mode: READ_WRITE
device_name: fhmprher1d0q********
auto_delete: true
disk_id: fhmprher1d0q********
network_interfaces:
- index: "0"
mac_address: d0:0d:ad:13:91:7e
subnet_id: e9bk1m87r4m4********
primary_v4_address:
address: 192.168.1.11
one_to_one_nat:
address: 158.160.***.***
ip_version: IPV4
security_group_ids:
- enpa5j0mrgm4********
gpu_settings: {}
fqdn: fhmaq4shfrcm********.auto.internal
scheduling_policy: {}
network_settings:
type: STANDARD
placement_policy: {}
For more information about the yc compute instance create
command, see the CLI reference.
See How to create an infrastructure using Terraform for details.
To create a VM, use the create REST API method for the Instance resource or the InstanceService/Create gRPC API call.
This will create the mywebserver
VM in your folder. To connect to the VM over SSH, use the yc-user
username and the VM’s public IP address. If you plan to use the created web server over a long period of time, make this VM's public IP address static.
Create a public DNS zone
-
In the management console
, select your folder. -
Select Cloud DNS.
-
Click Create zone.
-
Specify the DNS zone settings consistent with your domain:
- Zone: Domain zone. The zone name must end with a period. For example, the
example.com.
zone name corresponds to theexample.com
domain. You cannot create public top-level domain (TLD) zones. To create a domain zone with non-Latin characters, use the Punycode encoding. - Type:
Public
. - Name: Zone name.
- Zone: Domain zone. The zone name must end with a period. For example, the
-
Click Create.
Run this command:
yc dns zone create \
--name <zone_name> \
--zone <domain_zone> \
--public-visibility
Where:
--name
: DNS zone name.--zone
: Domain zone. The zone name must end with a period. For example, theexample.com.
zone name corresponds to theexample.com
domain. You cannot create public top-level domain (TLD) zones. To create a domain zone with non-Latin characters, use the Punycode encoding.
Result:
id: dns39gihj0ef********
folder_id: b1gt6g8ht345********
created_at: "2023-12-21T16:43:37.883Z"
name: my-domain-zone
zone: example.com.
public_visibility: {}
For more information about the yc dns zone create
command, see the CLI reference.
See How to create an infrastructure using Terraform for details.
To create a public DNS zone, use the create REST API method for the DnsZone resource or the DnsZoneService/Create gRPC API call.
Delegate your domain to Cloud DNS
To delegate a domain to Cloud DNS, in your account on your domain registrar's website, specify the DNS server addresses in the domain settings:
ns1.yandexcloud.net
ns2.yandexcloud.net
Delegation does not take effect immediately. It usually takes up to 24 hours (86,400 seconds) for internet service providers to update records. This depends on the TTL value which specifies how long domain records are cached.
You can check the domain delegation using Whoisdig
utility:
dig +short NS example.com
Result:
ns2.yandexcloud.net.
ns1.yandexcloud.net.
Create a type A resource record
In your DNS zone, create a type A resource record that points to the web server's public IP address:
-
In the management console
, select your folder. -
Select Cloud DNS.
-
Select the previously created DNS zone.
-
Click Create record.
-
Set the record parameters:
-
In the Name field, select
Matches zone name (@)
. -
In the Type field, select
A
as the record type. -
Under Data, specify the web server's public IP address.
You can find the VM IP address in the Network section on the VM page in the management console
or using this CLI command:yc compute instance get <VM_name>
.
-
-
Click Create.
Run this command:
yc dns zone add-records \
--name <zone_name> \
--record "<domain_name> 600 A <VM_IP_address>"
Where:
--name
: Name of the public DNS zone you created earler.--record
: Parameters of the new resource record:-
<domain_name>
: Domain name that must end with a period. For example, for theexample.com
domain, the correct value isexample.com.
. -
<VM_IP_address>
: Public IP address of the web server.You can find the VM IP address in the Network section on the VM page in the management console
or using this CLI command:yc compute instance get <VM_name>
.
-
Result:
+--------+--------------+------+---------------+-----+
| ACTION | NAME | TYPE | DATA | TTL |
+--------+--------------+------+---------------+-----+
| + | example.com. | A | 51.250.**.*** | 600 |
+--------+--------------+------+---------------+-----+
For more information about the yc dns zone add-records
command, see the CLI reference.
See How to create an infrastructure using Terraform for details.
To create a resource record in a DNS zone, use the updateRecordSets REST API method for the DnsZone resource or the DnsZoneService/UpdateRecordSets gRPC API call.
Test the website
The website on your web server is now accessible by its domain name. To test the site, enter its IP address or domain name in your browser:
http://<VM_public_IP_address>
http://example.com
How to delete the resources you created
Some resources are not free of charge. To avoid paying for them, delete the resources you no longer need:
- In Compute Cloud, delete the VM you created.
- In Cloud DNS, delete the domain zone you created.
- In Virtual Private Cloud, delete the security group first, then delete the subnet; finally, delete the network.
How to create an infrastructure using Terraform
Terraform
For more information about the provider resources, see the documentation on the Terraform
If you change the configuration files, Terraform automatically detects which part of your configuration is already deployed, and what should be added or removed.
To create an infrastructure for assigning a domain name to a VM with a web server in Cloud DNS using Terraform:
-
Install Terraform, get the authentication credentials, and specify the source for installing the Yandex Cloud provider (see Configure a provider, step 1).
-
Prepare a file with the infrastructure description:
Ready-made archiveCreating files manually- Create a folder for the file with the infrastructure description.
- Download the archive
(2 KB). - Unpack the archive to the directory. As a result, it should contain the
bind-domain-to-vm.tf
configuration file and thebind-domain-to-vm.auto.tfvars
user data file.
-
Create a folder for the file with the infrastructure description.
-
In the directory, create a configuration file named
bind-domain-to-vm.tf
:bind-domain-to-vm.tf
# Declaring variables for custom parameters variable "folder_id" { type = string } variable "domain_name" { type = string } variable "ssh_key_path" { type = string } # Adding other variables locals { network_name = "webserver-network" subnet_name = "webserver-subnet-ru-central1-b" sg_name = "webserver-sg" vm_name = "mywebserver" domain_zone_name = "my-domain-zone" } # Setting the provider terraform { required_providers { yandex = { source = "yandex-cloud/yandex" version = ">= 0.47.0" } } } provider "yandex" { folder_id = var.folder_id } # Creating a cloud network resource "yandex_vpc_network" "webserver-network" { name = local.network_name } # Creating a subnet resource "yandex_vpc_subnet" "webserver-subnet-b" { name = local.subnet_name zone = "ru-central1-b" network_id = "${yandex_vpc_network.webserver-network.id}" v4_cidr_blocks = ["192.168.1.0/24"] } # Creating a security group resource "yandex_vpc_security_group" "webserver-sg" { name = local.sg_name network_id = "${yandex_vpc_network.webserver-network.id}" ingress { protocol = "TCP" description = "http" v4_cidr_blocks = ["0.0.0.0/0"] port = 80 } ingress { protocol = "TCP" description = "https" v4_cidr_blocks = ["0.0.0.0/0"] port = 443 } ingress { protocol = "TCP" description = "ssh" v4_cidr_blocks = ["0.0.0.0/0"] port = 22 } egress { protocol = "ANY" description = "any" v4_cidr_blocks = ["0.0.0.0/0"] from_port = 0 to_port = 65535 } } # Creating a VM instance resource "yandex_compute_instance" "mywebserver" { name = local.vm_name platform_id = "standard-v2" zone = "ru-central1-b" resources { cores = "2" memory = "2" } boot_disk { initialize_params { image_id = "fd8jtn9i7e9ha5q25niu" } } network_interface { subnet_id = "${yandex_vpc_subnet.webserver-subnet-b.id}" nat = true security_group_ids = ["${yandex_vpc_security_group.webserver-sg.id}"] } metadata = { user-data = "#cloud-config\nusers:\n - name: yc-user\n groups: sudo\n shell: /bin/bash\n sudo: 'ALL=(ALL) NOPASSWD:ALL'\n ssh-authorized-keys:\n - ${file("${var.ssh_key_path}")}" } } # Creating a DNS zone resource "yandex_dns_zone" "my-domain-zone" { name = local.domain_zone_name zone = "${var.domain_name}." public = true } # Creating a type А resource record resource "yandex_dns_recordset" "rsА1" { zone_id = yandex_dns_zone.my-domain-zone.id name = "${yandex_dns_zone.my-domain-zone.zone}" type = "A" ttl = 600 data = ["${yandex_compute_instance.mywebserver.network_interface.0.nat_ip_address}"] }
-
In the directory, create a user data file named
bind-domain-to-vm.auto.tfvars
:bind-domain-to-vm.auto.tfvars
folder_id = "<folder_ID>" ssh_key_path = "<path_to_SSH_key>" domain_name = "<domain_name>"
For more information about the parameters of resources used in Terraform, see the provider documentation:
-
In the
bind-domain-to-vm.auto.tfvars
file, set the following user-defined parameters:folder_id
: Folder ID.ssh_key_path
: Path to the file with a public SSH key to authenticate the user on the VM, e.g.,~/.ssh/id_ed25519.pub
. For more information, see Creating an SSH key pair.domain_name
: Your domain name, e.g.,example.com
.
-
Create resources:
-
In the terminal, change to the folder where you edited the configuration file.
-
Make sure the configuration file is correct using the command:
terraform validate
If the configuration is correct, the following message is returned:
Success! The configuration is valid.
-
Run the command:
terraform plan
The terminal will display a list of resources with parameters. No changes are made at this step. If the configuration contains errors, Terraform will point them out.
-
Apply the configuration changes:
terraform apply
-
Confirm the changes: type
yes
in the terminal and press Enter.
-