Creating a VM with a custom configuration script
You can create a VM with a preset software configuration by using the user-data
key in the VM metadata.
The cloud-inituser-data
key. Cloud-init supports different metadata transmission formats, e.g., cloud-config
Creating a VM with a custom configuration script
Warning
In the user-data
configuration, you must always set the user login and SSH key, even if you have already specified them under Access in the management console.
To create a VM with a custom configuration script:
-
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.
-
Set the required VM parameters.
-
Expand the Metadata section and specify:
- Key:
user-data
. - Value:
cloud-config
configuration in YAML format. See configuration examples foruser-data
under Examples.
- Key:
-
Click Create VM.
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.
Run this command:
yc compute instance create \
--name my-sample-instance \
--zone ru-central1-a \
--network-interface subnet-name=<subnet_name>,nat-ip-version=ipv4,security-group-ids=<security_group_ID> \
--create-boot-disk image-folder-id=standard-images,image-family=ubuntu-2204-lts \
--metadata-from-file user-data="<path_to_configuration_file>"
Where:
-
subnet-name
: Name of the subnet in the availability zone specified in the--zone
parameter. -
security-group-ids
: Security group ID. -
--metadata-from-file
:user-data
key and its value, i.e., path to thecloud-config
configuration file in YAML format, e.g.,--metadata-from-file user-data="/home/user/metadata.yaml"
.See configuration examples for
user-data
under Examples.
If you don't have Terraform, install it and configure the Yandex Cloud provider.
Add the VM configuration script to the metadata
section of the yandex_compute_instance
resource in the Terraform configuration file:
resource "yandex_compute_instance" "vm-1" {
name = "my-sample-instance"
...
metadata = {
user-data = "${file("<path_to_configuration_file>")}"
}
...
}
Where:
-
user-data
: Path to thecloud-config
configuration file in YAML format, e.g.,user-data = "${file("/home/user/metadata.yaml")}"
.See configuration examples for
user-data
under Examples.
Create a VM using the create REST API method for the Instance resource and provide the object with the cloud-config
YAML configuration under metadata
in the request body. For a multiline configuration, use \n
as a separator. See the examples below.
{
"folderId": "b1gvmob95yys********",
"name": "my-sample-instance",
"zoneId": "ru-central1-a",
"platformId": "standard-v3",
...
"metadata": {
"user-data": "#cloud-config\ndatasource:\n Ec2:\n strict_id: false\nssh_pwauth: yes\nusers:\n- name: <username>\n sudo: 'ALL=(ALL) NOPASSWD:ALL'\n shell: /bin/bash\n ssh_authorized_keys:\n - <public_SSH_key>\nwrite_files:\n - path: '/usr/local/etc/startup.sh'\n permissions: '755'\n content: |\n #!/bin/bash\n apt-get update\n apt-get install -y nginx\n service nginx start\n sed -i -- 's/nginx/Yandex Cloud - ${HOSTNAME}/' /var/www/html/index.nginx-debian.html\n defer: true\nruncmd:\n - ['/usr/local/etc/startup.sh']"
},
...
}
See configuration examples for user-data
under Examples.
For more information on how to create a VM, see Creating a VM from a public Linux image.
To make sure the configuration scripts run successfully, get the serial port output of your VM.
Examples
To install and run an Nginxuser-data
key:
#cloud-config
datasource:
Ec2:
strict_id: false
ssh_pwauth: no
users:
- name: <username>
sudo: 'ALL=(ALL) NOPASSWD:ALL'
shell: /bin/bash
ssh_authorized_keys:
- <public_SSH_key>
write_files:
- path: "/usr/local/etc/startup.sh"
permissions: "755"
content: |
#!/bin/bash
apt-get update
apt-get install -y nginx
service nginx start
sed -i -- "s/nginx/Yandex Cloud - ${HOSTNAME}/" /var/www/html/index.nginx-debian.html
defer: true
runcmd:
- ["/usr/local/etc/startup.sh"]
Where:
<username>
: User login to use when connecting to the VM via SSH.<Public_SSH_key>
: Contents of the public key file. You need to create a key pair for the SSH connection yourself.
To install Dockeruser-data
key:
#cloud-config
datasource:
Ec2:
strict_id: false
ssh_pwauth: no
users:
- name: <username>
sudo: "ALL=(ALL) NOPASSWD:ALL"
shell: /bin/bash
ssh_authorized_keys:
- <public_SSH_key>
write_files:
- path: "/usr/local/etc/docker-start.sh"
permissions: "755"
content: |
#!/bin/bash
# Docker
echo "Installing Docker"
sudo apt update -y && sudo apt install docker.io -y
echo "Grant user access to Docker"
sudo usermod -aG docker ${USER}
newgrp docker
defer: true
- path: "/usr/local/etc/docker-main.sh"
permissions: "755"
content: |
#!/bin/bash
# Docker run container
docker pull hello-world:latest
docker run hello-world
defer: true
runcmd:
- [su, <username>, -c, "/usr/local/etc/docker-start.sh"]
- [su, <username>, -c, "/usr/local/etc/docker-main.sh"]
Where:
<username>
: User login to use when connecting to the VM via SSH.<Public_SSH_key>
: Contents of the public key file. You need to create a key pair for the SSH connection yourself.
To install the Yandex Cloud CLI on the new VM, specify the following value for the user-data
key:
#cloud-config
datasource:
Ec2:
strict_id: false
ssh_pwauth: no
users:
- name: <username>
sudo: 'ALL=(ALL) NOPASSWD:ALL'
shell: /bin/bash
ssh_authorized_keys:
- <public_SSH_key>
write_files:
- path: "/usr/local/etc/yc-install.sh"
permissions: "755"
content: |
#!/bin/bash
# YC CLI
echo "Installing Yandex Cloud CLI"
curl \
--silent \
--show-error \
--location \
https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
VM_ID=$(curl --silent http://169.254.169.254/latest/meta-data/instance-id)
# Save YC params
echo "Saving YC params to the ~/.bashrc"
cat << EOF >> $HOME/.bashrc
defer: true
runcmd:
- [su, <username>, -c, "/usr/local/etc/yc-install.sh"]
Where:
<username>
: User login to use when connecting to the VM via SSH.<Public_SSH_key>
: Contents of the public key file. You need to create a key pair for the SSH connection yourself.
To install Terraformuser-data
key:
#cloud-config
datasource:
Ec2:
strict_id: false
ssh_pwauth: no
users:
- name: <username>
sudo: 'ALL=(ALL) NOPASSWD:ALL'
shell: /bin/bash
ssh_authorized_keys:
- <public_SSH_key>
write_files:
- path: "/usr/local/etc/tf-install.sh"
permissions: "755"
content: |
#!/bin/bash
# Install Global Ubuntu things
sudo apt-get update
echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
sudo apt-get install -y unzip python3-pip
# Install Terraform
echo "Installing Terraform"
sudo curl \
--silent \
--show-error \
--location \
https://hashicorp-releases.yandexcloud.net/terraform/1.8.5/terraform_1.8.5_linux_amd64.zip \
--output /usr/local/etc/terraform.zip
sudo unzip /usr/local/etc/terraform.zip -d /usr/local/etc/
sudo install -o root -g root -m 0755 /usr/local/etc/terraform /usr/local/bin/terraform
sudo rm -rf /usr/local/etc/terraform /usr/local/etc/terraform.zip /usr/local/etc/LICENSE.txt
defer: true
runcmd:
- [su, <username>, -c, "/usr/local/etc/tf-install.sh"]
Where:
<username>
: User login to use when connecting to the VM via SSH.<Public_SSH_key>
: Contents of the public key file. You need to create a key pair for the SSH connection yourself.
To install kubectluser-data
key:
#cloud-config
datasource:
Ec2:
strict_id: false
ssh_pwauth: no
users:
- name: <username>
sudo: 'ALL=(ALL) NOPASSWD:ALL'
shell: /bin/bash
ssh_authorized_keys:
- <public_SSH_key>
write_files:
- path: "/usr/local/etc/kubectl-install.sh"
permissions: "755"
content: |
#!/bin/bash
# Install kubectl
echo "Installing kubectl"
sudo curl \
--silent \
--show-error \
--location \
https://dl.k8s.io/release/v1.3.0/bin/linux/amd64/kubectl \
--output /usr/local/etc/kubectl
sudo install -o root -g root -m 0755 /usr/local/etc/kubectl /usr/local/bin/kubectl
sudo rm -rf /usr/local/etc/kubectl
defer: true
runcmd:
- [su, <username>, -c, "/usr/local/etc/kubectl-install.sh"]
Where:
<username>
: User login to use when connecting to the VM via SSH.<Public_SSH_key>
: Contents of the public key file. You need to create a key pair for the SSH connection yourself.
To install Helmuser-data
key:
#cloud-config
datasource:
Ec2:
strict_id: false
ssh_pwauth: no
users:
- name: <username>
sudo: 'ALL=(ALL) NOPASSWD:ALL'
shell: /bin/bash
ssh_authorized_keys:
- <public_SSH_key>
write_files:
- path: "/usr/local/etc/helm-install.sh"
permissions: "755"
content: |
#!/bin/bash
# Install Helm
echo "Installing Helm"
sudo curl \
--silent \
--show-error \
--location \
https://get.helm.sh/helm-v3.15.2-linux-amd64.tar.gz \
--output /usr/local/etc/helm-v3.15.2-linux-amd64.tar.gz
sudo tar xf /usr/local/etc/helm-v3.15.2-linux-amd64.tar.gz -C /usr/local/etc/
sudo install -o root -g root -m 0755 /usr/local/etc/linux-amd64/helm /usr/local/bin/helm
sudo rm -rf /usr/local/etc/helm-v3.15.2-linux-amd64.tar.gz /usr/local/etc/linux-amd64
defer: true
runcmd:
- [su, <username>, -c, "/usr/local/etc/helm-install.sh"]
Where:
<username>
: User login to use when connecting to the VM via SSH.<Public_SSH_key>
: Contents of the public key file. You need to create a key pair for the SSH connection yourself.
See also
Other configuration examples for the user-data
key: