My attempts to figure out OpenStack are happily producing more headaches for me. This is still on tha Matika release.
I have temporarily suspended my attempts to get migration between compute nodes working as I have been sidetracked by heat templates and stacks. Although in testing for this post I discovered some instances were being deployed on the second compute node, identified by everything starting on the second compute node complaining it cannot contact the metadata service so the vxlan setup may not be correct even tho instances can be started there, but without networking; so disabled that compute node while I play with templates. But that will be another post; this is on using a template to create a stack.
Template issues in general
The major unexpected issues in using heat templates I have encountered already are…
- users even with admin authority to an openstack project are not permitted to create stacks with the “openstack stack create” command for the projects, it errors with ‘not heat_stack_owner’
- the only workaround is to create a new user for the project the stack is being created for with a role of ‘heat_stack_owner’; and of course creating a new ssh key-pair for the user as a ssh key is needed to access servers created by the stack and as the stack is created by the new user that user has no access to any other keys
- once the stack is created it seems other members of the project can manage the stack, at least other members with admin roles can delete the stack after it is created anyway
So the issue is that it seems that the use of ‘stacks’ is by design intended to be used by users seperate from the day-to-day management of instances; or basically admin users cannot create stacks and a user can have only one role so in a test environment where I am the only user I need a minimum of two userids just to do admin functions. It is just inconvenient for a single user system, but I guess in the real world there may be a need to prevent admin users from creating stacks; but personally I think the admin role should be renamed from ‘admin’ if it is not a god role to avoid confusion.
YAML syntax is a bit of a pain as well, took me about an hour to get rid of unexpected start/end block errors in my test template for ‘openstack stack create’ playtime, the solution was… I was missing a SPACE character before a parameter; indentation onto exact columns is a requirement, don’t miss out those leading spaces.
Fedora supplied cloud image (Fedora-Cloud-Base-24-1.2.x86_64)
The only other major issue encountered was not with OpenStack itself but with the Fedora supplied cloud image (Fedora-Cloud-Base-24-1.2.x86_64) for use with OpenStack. The issue there being that the F24 cloud image is shipped with python3 and the cloud-init scripts that handle user provided data to an image try to use python, so all fail to run complaining that the ‘python’ command is not found.
The fix for that is to create a symbolic link for python pointing to the phyton3 symbolic link, in a new image. Which painfully is to fire up an instance using the Fedora supplied F24 cloud image, login to it, and as root “cd /usr/bin;ln -s python3 python”; then shutdown the instance, snapshot it, use the “glance image-download” command to retrieve the snapshot as a qcow2 disk image, virt-sysprep that new qcow2 file, and use glance to install that new qcow2 file as a new image with a name meaningfull to you; and use that new image to launch future instances that require user data to be passed to them. However as while doing that you can also install additional packages to the image to make it more useful to you is not really a wasted effort.
It also does not have the “wc_notify” command so is presumably missing some heat packages in the cloud image; but that is not causing me any issues as long as I ensure I do not use that command in any of the user_data scripts.
My example template
This template is for my customised environment, all the parameters can be overidden at stack creation time. The reason the some parameters differ from the supplied users and flavours in a new openstack install are
- as noted earlier in the post, a new user with heat_owner role was required to be created with a new keypair, so the key pair used is mark_heatstack_owner_keypair as that is a key created for that user, and the only key the user has access to
- it uses my OpenStack network configuration, the project is my personal project so the private network is tenant-mark-10-0-3-0 with subnet tenant-mark-10-0-3-0-subnet1; and the external network available to this project is ext-net-192-flat
- as noted earlier in the post the Fedora supplied F24 cloud image cannot process user_data passed to cloud-init, so the image used in my example is F24-CloudBase-24-1.2.x86_64-python which is a copy of the F24 image with the only change from the origional being the python link has been created so cloud-init can find python and process the user_data
- the instance types are my customised ones, override with your own, the cloud base virtual disk needs 3Gb minimum, and has no swap partition so needs 256Mb memory minimum or 128Mb memory and a swap filesystem used in the flavor
This template example creates two instances and customises them as follows to make them usable. The idea is all access to instances in the stack are via the public ip-address on server1; in the real world there would probably be a proxy service on server1 providing passthru to other instances in the stack if the instances were to be running for more than a few days… but cloud instances are supposed to be throw up and tear down, not long running.
- server1 is assigned a floating ip-address as well as a private ip-address, server2 only has a private ip-address; so access to the instances in the stack is via ssh key to server1
- the root password is set for both servers (this is for troubleshooting from the console, you would not normally do that)
- server2 has the sshd_config altered to allow login using a password instead of the default of only allowing login via ssh keys; this is to avoid having to scp/sftp to ssh keys to server1 to be able to login to server2 from server1
- server2 has a password set for the fedora user, that can then be used when logging on from server1
- from the dashboard stack overview page after the stack is created the outputs are ip-addreses assigned and passwords used
Filename is test_two_servers.yaml and the command to create the stack is therefore “openstack stack create –template test_two_servers.yaml mark_test_stack01”, running it with environment settings for a user with a heat_owner role. And the contents of the yaml file are below.
heat_template_version: 2016-04-08
description: >
Test of stack deploy that sets root password,
using my private network and a floating ip assigned.
parameters:
key_name:
type: string
label: Key Name
description: Name of key-pair to be used for compute instance
default: mark_heatstack_owner_keypair
image_id:
type: string
label: Image ID
description: Image to be used for compute instance
default: F24-CloudBase-24-1.2.x86_64-python
instance_type:
type: string
label: Instance Type
description: Type of instance (flavor) to be used
default: marks.tiny
constraints:
- allowed_values: [ marks.tiny, marks.small, m1.tiny ]
description: Value must be one of marks.tiny, marks.small or m1.tiny.
root_password:
type: string
label: Root User Password
description: Password to be used for root user
hidden: true
default: letmein
constraints:
- length: { min: 6, max: 8 }
description: Password length must be between 6 and 8 characters.
- allowed_pattern: "[a-zA-Z0-9]+"
description: Password must consist of characters and numbers only.
user_password:
type: string
label: Fedora Cloud User Password
description: Password to be used for fedora user on servers with only private ips
hidden: true
default: password
constraints:
- length: { min: 6, max: 8 }
description: Password length must be between 6 and 8 characters.
- allowed_pattern: "[a-zA-Z0-9]+"
description: Password must consist of characters and numbers only.
net:
description: name of network used to launch instance.
type: string
default: tenant-mark-10-0-3-0
subnet:
description: name of subnet within network used to launch instance.
type: string
default: tenant-mark-10-0-3-0-subnet1
public_network:
description: name of the public network to associate floating ip from.
type: string
default: ext-net-192-flat
resources:
my_server1:
type: OS::Nova::Server
properties:
name: mark-server1
key_name: { get_param: key_name }
image: { get_param: image_id }
flavor: { get_param: instance_type }
networks:
- network: { get_param: net }
user_data:
str_replace:
template: |
#!/bin/bash
echo "Customising system image..."
# For troubleshooting use a known password for console login
echo "$ROOTPSWD" | passwd root --stdin
echo "...end of install"
# wc_notify not in F24 cloud image base
# wc_notify --data-binary '{"status": "SUCCESS"}'
exit 0
# ... done
params:
$ROOTPSWD: { get_param: root_password }
floating_ip:
type: OS::Neutron::FloatingIP
properties:
floating_network: {get_param: public_network}
association:
type: OS::Neutron::FloatingIPAssociation
properties:
floatingip_id: { get_resource: floating_ip }
port_id: {get_attr: [my_server1, addresses, {get_param: net}, 0, port]}
my_server2:
type: OS::Nova::Server
properties:
name: mark-server2
key_name: { get_param: key_name }
image: { get_param: image_id }
flavor: { get_param: instance_type }
networks:
- network: { get_param: net }
user_data:
str_replace:
template: |
#!/bin/bash
echo "Customising system image..."
# For troubleshooting use a known password for console login
echo "$ROOTPSWD" | passwd root --stdin
# Servers with only private ips can allow password logins
# (or all the ssh keys would have to be copied to all servers
# in the private network that might want to logon to this server).
cd /etc/ssh
cat sshd_config | sed -e 's/PasswordAuthentication no/PasswordAuthentication yes/' > sshd_config.new
datenow=`date +"%Y%m%d"`
mv sshd_config sshd_config.${datenow}
mv sshd_config.new sshd_config
chmod 644 sshd_config
service sshd restart
# But we leave "PermitRootLogin no" so set the Fedora cloud
# user password here as that is the user they ssh keys would
# normally be used to login to, so we can use that
echo "$USERPSWD" | passwd fedora --stdin
#
echo "...end of install"
exit 0
# ... done
params:
$ROOTPSWD: { get_param: root_password }
$USERPSWD: { get_param: user_password }
outputs:
instance_private_ip_server1:
description: Private IP address of server1
value: { get_attr: [my_server1, networks, {get_param: net}, 0] }
instance_public_ip_server1:
description: Public IP address of server1
value: { get_attr: [my_server1, networks, {get_param: net}, 1] }
instance_private_ip_server2:
description: Private IP address of server2
value: { get_attr: [my_server2, networks, {get_param: net}, 0] }
instance_keypair:
description: SSH Key-Pair to be used to access the instances
value: { get_param: key_name }
instance_rootpw:
description: Root password for both servers at instance creation
value: { get_param: root_password }
instance_userpw:
description: User fedora password for servers with only private ips
value: { get_param: user_password }
top tip: for testing use the –dry-run option (ie:openstack stack create –dry-run –template test_two_servers.yaml mark_test_stack01) and that will (if the template passes validation) produce a detailed list of all settings available should you want to tweak it further.