Automated OpenStack instance configuration with cloud-init and metadata service

Cloud Creator

User Data Script

A Bash script is another common way to inject user data into an instance. The file must be a valid Bash script, so it must begin with a #!/bin/bash line. For example, Listing 5 shows an instance configuration input file run on boot that installs two RPM packages, enables the Apache HTTP service, and creates the index.html file in the server's root directory.

Listing 5

user_data.sh

#!/bin/bash
# install additional packages
sudo yum install -y httpd vim
# enable httpd service
sudo systemctl enable httpd
sudo systemctl start httpd
# create file in http document root
sudo echo "<p>hello world</p>" > /var/www/html/index.html

The command to launch an instance with a user data Bash script would look like Listing 6.

Listing 6

Launching Instance with Bash Script

root@controller ~(keystone_gjuszczak)]# openstack server create --flavor m2.tiny --image CentOS_7_cloud_init --nic net-id=int_net --key-name cloud --security-group default --user-data user_data.sh CentOS_7_CI_UD

Image Metadata Properties

Worth mentioning is that images also can contain metadata properties that determine the purpose and nature of a particular image. OpenStack offers a variety of image properties that can be set for the image to define its purpose (e.g., CPU pinning, compute CPU architecture, or Cinder volume type required by the image).

Figure 1 shows the image properties configuration screen with the hypervisor_type parameter set to kvm, which means that launching an instance from this particular image requires a KVM-based compute node. Otherwise, the instance won't boot. Booting the instance on compute nodes other than KVM (e.g., LXC- or XEN-based nodes) results in an error.

Figure 1: Defining the image metadata properties.

You can also set an image property from the command line with the --property <key>=<type> parameter. For example,

[root@controller ~(keystone_admin)]# openstack image set --property hypervisor_type= kvm cirros-0.4.0

sets the hypervisor_type parameter to kvm.

Passing Metadata with a Config Drive

You can force OpenStack to write instance metadata to a special drive called a configuration drive, or simply config drive, that is attached to the instance during the boot process.

Thanks to the cloud-init script, a config drive is automatically mounted on the instance's OS, and its files can be read easily, as if they were coming from the metadata service. With a config drive, you can pass different user data formats, as well as ordinary files, to the instance. The main requirement for using a config drive is passing the --config-drive true parameter in the openstack server create command. You can also configure the compute node always to use a config drive by setting the following parameter in /etc/nova/nova.conf:

force_config_drive = true

The example command in Listing 7 enables a config drive and passes a previously created user data script and two files to the instance on boot. The first --file replaces the original /etc/hosts with a file with new content, and the second --file copies content to the /tmp directory on the instance:

Listing 7

Using a Config Drive

[root@controller ~(keystone_gjuszczak)]# openstack server create --config-drive true --flavor m2.tiny --image CentOS_7_cloud_init --nic net-id=int_net --key-name cloud --security-group default --user-data user_data.sh --file /etc/hosts=/root/hosts --file /tmp/example_file.txt=/root/example_file.txt CentOS_7_CI_CD

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs



Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>
	</a>

<hr>		    
			</div>
		    		</div>

		<div class=