Write a Vultr Marketplace provisioning script that runs during customer deployment and reads application variables through the Vultr Metadata API endpoint.
Provisioning scripts run during a customer's deployment to configure the application. When a customer deploys your application, it is often useful to generate random passwords and provide them to both the application and the customer. The Marketplace provides this function through application variables, and your script retrieves their values through the Vultr Metadata API.
This guide explains how to write a provisioning script that reads application variables through the Metadata API.
Variable names are used in multiple places:
The per-instance cloud-init script is an appropriate place to use these variables because it only runs once when the instance is first deployed. For example, create two variables on the Variables tab:
demo_password: A password for a user named demo.web_password: A password for a web server's basic authentication.You can discover their values in your startup script through the Vultr Metadata API. 169.254.169.254 is a link-local address. RFC 3927 reserves the 169.254.0.0/16 range for link-local addressing, reachable only from within the instance itself and not routable over the internet, so the Metadata API only responds to requests the instance makes about itself. The API endpoint is formed from the variable name in the format http://169.254.169.254/v1/internal/app-{variable_name}. For example, retrieve a variable named demo_password from this endpoint:
http://169.254.169.254/v1/internal/app-demo_passwordWhen making requests, you must pass METADATA-TOKEN: vultr in the request header.
Retrieve demo_password.
# curl -H "METADATA-TOKEN: vultr" http://169.254.169.254/v1/internal/app-demo_password
Retrieve web_password.
# curl -H "METADATA-TOKEN: vultr" http://169.254.169.254/v1/internal/app-web_password
The following example creates a demo user and reports the web password.
Create a /var/lib/cloud/scripts/per-instance/provision.sh cloud-init script.
# nano /var/lib/cloud/scripts/per-instance/provision.sh
Paste the following:
#!/bin/bash
## Runs once-and-only-once at first boot per instance.
echo $(date -u) ": System provisioned." >> /var/log/per-instance.log
## Capture Marketplace Password Variables
DEMO_PASSWORD=$(curl -H "METADATA-TOKEN: vultr" http://169.254.169.254/v1/internal/app-demo_password)
WEB_PASSWORD=$(curl -H "METADATA-TOKEN: vultr" http://169.254.169.254/v1/internal/app-web_password)
## Create user
adduser demo --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password
## Set Password
echo demo:$DEMO_PASSWORD | chpasswd
## Report the Web Password
echo "The Web password is: $WEB_PASSWORD" > /root/web-password.txt
Save and close the file. This example creates a user account named demo with the unique password generated by the Marketplace variable demo_password. It also writes a file to /root/web-password.txt with the value of web_password.
Make the script executable.
# chmod +x /var/lib/cloud/scripts/per-instance/provision.sh
In a real application, you might pass the values to a database or set HTTP Authentication on your web server.
Add the following to your /var/lib/cloud/scripts/per-instance/provision.sh script to create a database user with a Marketplace Password Variable.
## Capture the Marketplace Password Variable.
DB_PASS=$(curl -H "METADATA-TOKEN: vultr" http://169.254.169.254/v1/internal/app-db_pass)
## Create an example database.
mysql -u root -e "CREATE DATABASE example_db;"
## Create an example user with the Marketplace Password Variable $DB_PASS as its password.
mysql -u root -e "CREATE USER 'example_user'@'localhost' IDENTIFIED BY '$DB_PASS';"
## Grant the user privileges on the example database.
mysql -u root -e "GRANT ALL ON example_db.* TO 'example_user'@'localhost' WITH GRANT OPTION;"
Assuming you declared a variable named db_pass on the Edit App Variables screen, this script creates an example database user with a random password. The password is available to you in the Metadata API, and it is shown to the customer on the application instructions page.
Disable SSH while your provisioning scripts run, then re-enable SSH when finished, particularly if they require a long time to complete. A user who logs in through SSH while your provisioning script is running could cause unexpected side effects. We recommend disabling the SSH service entirely while your script runs. If this is not possible, block access with the OS firewall. The final step in the provisioning script should enable SSH if your application allows SSH access for customers.