Chapter 11. Creating a customized instance Cloud users can specify additional data to use when they launch an instance, such as a shell script that the instance runs on boot. The cloud user can use the following methods to pass data to instances: User data Use to include instructions in the instance launch command for cloud-init to execute. Instance metadata A list of key-value pairs that you can specify when you create or update an instance. You can access the additional data passed to the instance by using a config drive or the metadata service. Config drive You can attach a config drive to an instance when it boots. The config drive is presented to the instance as a read-only drive. The instance can mount this drive and read files from it. You can use the config drive as a source for cloud-init information. Config drives are useful when combined with cloud-init for server bootstrapping, and when you want to pass large files to your instances. For example, you can configure cloud-init to automatically mount the config drive and run the setup scripts during the initial instance boot. Config drives are created with the volume label of config-2 , and attached to the instance when it boots. The contents of any additional files passed to the config drive are added to the user_data file in the openstack/{version}/ directory of the config drive. cloud-init retrieves the user data from this file. Metadata service Provides a REST API to retrieve data specific to an instance. Instances access this service at 169.254.169.254 or at fe80::a9fe:a9fe . cloud-init can use both a config drive and the metadata service to consume the additional data for customizing an instance. The cloud-init package supports several data input formats. Shell scripts and the cloud-config format are the most common input formats: Shell scripts: The data declaration begins with #! or Content-Type: text/x-shellscript . Shell scripts are invoked last in the boot process. cloud-config format: The data declaration begins with #cloud-config or Content-Type: text/cloud-config . cloud-config files must be valid YAML to be parsed and executed by cloud-init . Note cloud-init has a maximum user data size of 16384 bytes for data passed to an instance. You cannot change the size limit, therefore use gzip compression when you need to exceed the size limit. Vendor-specific data The RHOSP administrator can also pass data to instances when they are being created. This data may not be visible to you as the cloud user, for example, a cryptographic token that registers the instance with Active Directory. The RHOSP administrator uses the vendordata feature to pass data to instances. Vendordata configuration is read only, and is located in one of the following files: /openstack/{version}/vendor_data.json /openstack/{version}/vendor_data2.json You can view these files using the metadata service or from the config drive on your instance. To access the files by using the metadata service, make a GET request to either http://169.254.169.254/openstack/{version}/vendor_data.json or http://169.254.169.254/openstack/{version}/vendor_data2.json . Note To execute openstack client commands on the cloud, you must specify the name of the cloud detailed in your clouds.yaml file. You can specify the name of the cloud by using one of the following methods: Use the --os-cloud option with each command, for example: Use this option if you access more than one cloud. Create an environment variable for the cloud name in your bashrc file: 11.1. Customizing an instance by using user data You can use user data to include instructions in the instance launch command. cloud-init executes these commands to customize the instance as the last step in the boot process. Prerequisites The administrator has created a project for you and they have provided you with a clouds.yaml file for you to access the cloud. You have installed the python-openstackclient package. Procedure Create a file with instructions for cloud-init . For example, create a bash script that installs and enables a web server on the instance: Launch an instance with the --user-data option to pass the bash script: When the instance state is active, attach a floating IP address: Log in to the instance with SSH: Check that the customization was successfully performed. For example, to check that the web server has been installed and enabled, enter the following command: Review the /var/log/cloud-init.log file for relevant messages, such as whether or not the cloud-init executed: 11.2. Customizing an instance by using metadata You can use instance metadata to specify the properties of an instance in the instance launch command. Prerequisites The administrator has created a project for you and they have provided you with a clouds.yaml file for you to access the cloud. You have installed the python-openstackclient package. Procedure Launch an instance with the --property <key=value> option. For example, to mark the instance as a webserver, set the following property: Optional: Add an additional property to the instance after it is created, for example: 11.3. Customizing an instance by using a config drive You can create a config drive for an instance that is attached during the instance boot process. You can pass content to the config drive that the config drive makes available to the instance. Prerequisites The administrator has created a project for you and they have provided you with a clouds.yaml file for you to access the cloud. You have installed the python-openstackclient package. Procedure Enable the config drive, and specify a file that contains content that you want to make available in the config drive. For example, the following command creates a new instance named config-drive-instance and attaches a config drive that contains the contents of the file my-user-data.txt : This command creates the config drive with the volume label of config-2 , which is attached to the instance when it boots, and adds the contents of my-user-data.txt to the user_data file in the openstack/{version}/ directory of the config drive. Log in to the instance. Mount the config drive: If the instance OS uses udev : If the instance OS does not use udev , you need to first identify the block device that corresponds to the config drive:

Commands:
openstack flavor list --os-cloud <cloud_name>
`export OS_CLOUD=<cloud_name>`
vim /home/scripts/install_httpd #!/bin/bash -y install httpd python-psycopg2 systemctl enable httpd --now
openstack server create --image rhel8 --flavor default --nic net-id=web-server-network --security-group default --key-name web-server-keypair --user-data /home/scripts/install_httpd --wait web-server-instance
openstack floating ip create web-server-network openstack server add floating ip web-server-instance 172.25.250.123
ssh -i ~/.ssh/web-server-keypair cloud-user@172.25.250.123
curl http://localhost | grep Test <title>Test Page for the Apache HTTP Server on Red Hat Enterprise Linux</title> <h1>Red Hat Enterprise Linux <strong>Test Page</strong></h1>
sudo less /var/log/cloud-init.log ...output omitted ...util.py[DEBUG]: Cloud-init v. 0.7.9 finished at Sat, 23 Jun 2018 02:26:02 +0000. Datasource DataSourceOpenStack [net,ver=2]. Up 21.25 seconds
openstack server create --image rhel8 --flavor default --property role=webservers --wait web-server-instance
openstack server set --property region=emea --wait web-server-instance
openstack server create --flavor m1.tiny --config-drive true --user-data ./my-user-data.txt --image cirros config-drive-instance
mkdir -p /mnt/config mount /dev/disk/by-label/config-2 /mnt/config
blkid -t LABEL="config-2" -odevice /dev/vdb mkdir -p /mnt/config mount /dev/vdb /mnt/config