Cloud-init script examples for Cloudforms

Example #1 (tested on Openstack) – Simple script to register a VM to Satellite 6 and IdM. Also allow root login without key and setting password to “password123”

#cloud-config
# vim:syntax=yaml
debug: True
ssh_pwauth: True
disable_root: false
chpasswd:
  list: |
    root: password123
  expire: false
runcmd:
- sed -i'.orig' -e's/without-password/yes/' /etc/ssh/sshd_config
- service sshd restart
- yum -y localinstall http://satellite6.home.marcoberube.com/pub/katello-ca-consumer-latest.noarch.rpm >> /root/cloudinit.log
- subscription-manager register --org MarcoBerube --activationkey rhel7-basic >> /root/cloudinit.log
- yum -y install ipa-client >> /root/cloudinit.log
- ipa-client-install --enable-dns-updates --mkhomedir -p admin -w password123 --unattended >> /root/cloudinit.log
- yum -y install katello-agent >> /root/cloudinit.log
- yum -y update && yum clean all >> /root/cloudinit.log
- systemctl enable goferd.service >> /root/cloudinit.log
- yum -y install puppet >> /root/cloudinit.log
- echo server=satellite6.yourdomain.com >> /etc/puppet/puppet.conf
- systemctl enable puppet >> /root/cloudinit.log
- systemctl restart puppet >> /root/cloudinit.log
- reboot

Example #2 (tested on AWS) – This example shows how to pass arguments from Cloudforms to your cloud-init script dynamically.

#cloud-config
# MiqProvisionAmazon_Web.yaml
# CloudForms - Cloud-Init Script for Apache Installation on EC2
# For troubleshooting check: /var/lib/cloud/instance/user-data.txt & /var/log/boot.log

<%   # Set Global Variables   
    role                = evm[:role]   
    role                ||= evm[:ws_values][:role] rescue 'web'   
    instance_name       = evm[:vm_target_name]   
    key_pair            = evm[:keypair]   
    key_pair            ||= evm[:ws_values][:keypair] rescue nil %>

bootcmd:
  ## Turn off SELinux
  - setenforce 0

ssh_authorized_keys:
    <% if key_pair.nil? %>
  - echo "WARN --: Using default key pari"
    <% else %>
  - <%=key_pair%>
    <% end %>

runcmd:
  ## Setup motd and root authorized keys
  - echo Welcome to Red Hat CloudForms <%=role.titlecase%> Instance <%=instance_name%> > /etc/motd

  ## Turn off firewall
  - echo "CloudForms - Turning off firewall"
  - chkconfig iptables off  
  - service iptables stop

  ## Install Apache
  - echo "CloudForms - Installing apache"
  - yum -y install httpd wget
  - service httpd start
  - chkconfig httpd on

  ## Modify default apache homepage
  - echo "CloudForms - Modifyig default apache homepage"
  - sed -i 's/Red Hat Enterprise Linux.  Welcome to Red Hat CloudForms <%=role.titlecase%> Instance <%=instance_name%>/' /var/www/error/noindex.html

Changing VMWare adapter type based on Template OS

Here is how you can customize your network adapter type in VMWare based on what OS is getting provisioned. In this example, Windows templates requires VMXNET3 adapters while Linux VMs requires E1000 adapter.

# Get provisioning object
prov = $evm.root["miq_provision"]
vm_template = prov.vm_template

# Changing Adapter type based on Template OS
if vm_template.operating_system[:product_name].downcase.include?('windows')
   $evm.log("info", "WINDOWS DETECTED: SETTING UP NETWORK INTERFACE TO VMXNET3")
   prov.set_network_adapter(0, { :network => "VM Network", :devicetype => "VirtualVmxnet3", :is_dvs => false})
else
   $evm.log("info", "SETTING UP NETWORK INTERFACE TO E1000")
   prov.set_network_adapter(0, { :network => "VM Network", :devicetype => "VirtualE1000", :is_dvs => false})
end

Cloudforms 3.1 Enhancements

Cloudforms 3.1 has just been released.   Here are a few enhancements:

  • REST API Integration:  Cloudforms Management Engine now offers a REST API that supports Service Management and Insight capabilities
  • Openstack Enhanced Integration:  Ability to gather information from Glance, Cinder and Neutron services.
  • Support for Microsoft SCVMM:  Tech preview!  Full support coming soon.

For more information, download the release form here.

 

Killing provisioning object

Sometimes during the course of using Cloudforms Automation Engine a task could get stuck in an undesired state. Use the steps to kill an errant:

SSH into the Cloudforms Worker running the task.

Navigate to:
/var/www/miq/vmdb/

Execute this command:
script/rails r tools/kill_provision.rb <task number>

Determine the task number either via Services->Requests page under “Request ID” or in /var/www/miq/vmdb/automation.log

It will appear in the automation log as <miq_provision_”task number”> or <service_template_provision_task_”task number”>.

Allow VMs not provisioned by Cloudforms to retire

By default CloudForms does not allow for deleting of VMs not provisioned by it. There is however an override that you can apply by creating a tag category called “lifecycle” and a tag called “retire_full” and then apply it to the VM. Otherwise you can modify the /Factory/VM/DeleteFromVC and remove the check in there. I believe /Factory/VM/delete_from_vmdb has this same check in there. Below is a snippet:

# Get vm from root object 
vm = $evm.root['vm']
category = "lifecycle" 
tag = "retire_full"

miq_guid = /\w*MIQ\sGUID/i
if vm.v_annotation =~ miq_guid 
   vm_was_provisioned = true 
else
   vm_was_provisioned = false end

if vm && (vm_was_provisioned || vm.miq_provision || vm.tagged_with?(category,tag)) 
    ems = vm.ext_management_system 
    log(:info, "Deleting VM:<#{vm.name}> from EMS:<#{ems ? ems.name : nil}>")   
    vm.remove_from_disk 
end

Set VLAN based on environment tag

Replace your current “if set_vlan” code from your existing PreProvision method to set your VLAN based on the environment tag.

* This code assume that your service dialog as a dropdown named “tag_0_environment”.

tags = prov.get_tags
log(:info, "Provision Tags:<#{tags.inspect}>")

if set_vlan

  default_vlan = "Private"
  #default_dvs = "portgroup1"

  case tags[:environment].to_s
  when 'private'
    prov.set_vlan("Private")
    #prov.set_dvs(default_dvs)
    log(:info, "ENVIRONMENT tag = private; setting vlan to Private")
  when 'public'
    prov.set_vlan("Public")
    #prov.set_dvs(default_dvs)
    log(:info, "ENVIRONMENT tag = public; setting vlan to Public")
  else
    prov.set_vlan("Private")
    #prov.set_dvs(default_dvs)
    log(:info, "No ENVIRONMENT tag set, setting default: #{default_vlan}")
  end

end