OpenShift 3.4 Standalone Registry (Atomic Registry)

I realized today that the current OpenShift 3.4 documentation around installing the standalone registry is missing an important parameter. Here is the link to the bug openshift_master_default_subdomain missing . Its a small error but has some impact as the route registry-console-default.yourdomain will not be exposed externally.

Remember the standalone OpenShift registry is a full OpenShift installation thus it will need a DNS wildcard entry pointing to it for the subdomain defined in openshift_master_default_subdomain.

I used the following ansible hosts file to install the registry

If you followed the redhat documentation around requirements you should be good to go. You can know run the

Once the install is done you can check with oc get routes if your route was created correctly

You can know browse to and you should see the following UI (if you did not configure any users yet you will not be able to login!)

If you chose htpasswd_auth create a user with htpasswd /etc/origin/master/htpasswd admin and login. Once logged in you will see the atomic registry.

Then you can create a project and upload an image and you should see something like this

Posted in OpenShift | Tagged , , , , | Leave a comment

Deny container image execution via CloudForms 4.2 / OpenShift 3.4

I’ve been waiting for this feature since quite a while and its finally here and working. CloudForms 4.2 and OpenShift 3.4 have the ability combined of scanning docker images and define if the images are compliant or not. If the image is not compliant CloudForms annotates the image in OpenShift with true and if OpenShift is configured correctly it will deny execution the next time someone tries to run the container image.

Having this feature is really awesome as you can prevent someone from building a vulnerable image and deploying it multiple times. Also CloudForms can either have a policy set on the provider which auto scans newly discovered pods/images, schedule image registry scans or your check images on demand.

So here are the steps to get this working (a detailed description on what an image policy is can be found here:

1. First  login to the OpenShift Master and edit /etc/origin/master/master-config.yaml Add the following lines above apiLevels

2. Restart the OpenShift masters so that the policy will take effect.

3. Deploy a vulnerable image in OpenShift. In my case I named it testme.

4. Go to CloudForms and run a Smart State Analysis. Login to CloudForms and go to Compute -> Containers -> Container Images and choose the image you’ve just deployed via OpenShift.

5. Click on the image.  Then on the top left press “Perform Smart StateAnalysis”

6. If your admin in OpenShift you can go to the management-infra project and see that a new pod manageiq-img-scan is started (oc get pods). The image will pull your testme image down and check it for vulnerabilities. Once scanned (remember we did not add any policies yet) you will see the following:

7. Go to policy -> manage policy and check the box for OpenScap Profile Once checked go back to the policies and run “Check Compliance of last known configuration.

8. As I used a image which has known vulnerabilities the compliance status will show Non-Compliant.
What happens in the background as well is that CloudForms tells OpenShift to annotate the image with true

9. Go to your image id and copy your sha

10. Now in OpenShift check if the annotation exist. You can either check in the UI in OpenShift under image -> annotations or on the command line

11. Lets see if the policy catches and build a new container based of the above. As you can see below OpenShift denies running the above image!

12. If you want to remove the restriction your can use

Happy OpenShifting

Posted in Cloud, OpenShift | Tagged , , , , | Leave a comment

Red Hat Cloud Suite In A Box

Today I finally finished my Ikea Helmer rack project. The goal of the project was to have enough resources to build a full Red Hat Cloud Suite lab. I am in IT now since 1996 and learned  that the only way to stay on top of the game is by playing with the technology. I have to say it took quite a lot of dremeling to cut the Ikea Helmer rack into shape so that I could fit motherboards, fans, disks and power supplies etc. The cool thing about the Helmer rack is that it fits a mini itx mother board perfectly and if you add switches on the bottom you have a self contained rack. With two fans blowing air in and one fan blowing air out you also achieve a good air flow.

Here is a list of the components used in my lab:
2 x APC Smart UPS 1500W
9 x Antec Earthwatts 380
27 x Gelid FN-PX08-20 silent 8 PWN 80mm
3 x SuperMicro X10SDV-6C+-TLN4F-O for Red Hat Virtualization Hyper-converged with 64 GB RAM which will host
Satellite 6, Ansible Tower, CloudForms and OpenShift
6 x SuperMicro X10SDV-4C-TLN4F-O for Red Hat OpenStack (3 controller 2 compute 1 ceph) or (3 controller 3 Compute hyper converged)
1 x Asustor 608t (NFS and ISCSI storage)
4 x Juniper ex2200-c (fanless) (virtual chassis)
1 x Netgear XS708E-200nes
15 x SSD in different sizes
1 x Raspberry PI as a DNS and pxe server for the main deployment

In the next few weeks I will start building out the RHCS components and write blog posts on how to deploy the different products via Red Hat Management Suite automatically.

Posted in ansible, Cloud, CloudForms, Linux, OpenShift, Openstack, Uncategorized | Tagged , , , , | Leave a comment

Red Hat Summit 2017 S102320: Button Push Deployments With Integrated Red Hat Open Management

My 2017 redhat summit talk “Button Push Deployments With Integrated Red Hat Open Management” got accepted. I have the big honor of sharing the talk not just with my last years co presenter Michael Dahlgren but also with Red Hat EMEA’S configuration management extraordinaire Maxim Burgerhout.

As we combine our talks you can expect an awesome mixture of different demos and showcases around Red Hat Open Management.

Posted in CloudForms, Linux, OpenShift, Puppet | Tagged | Leave a comment

CloudForms AWS IAM policies

To enable Cloudforms to connect to the AWS provider you need to following policies:

  • AmazonEC2FullAccess
  • AWSConfigUserAccess
  • IAMReadOnlyAccess
  • IAMUserSSHKeys
  • AWSCloudFormationReadOnlyAccess

As well as two custom policies



Posted in Uncategorized | 1 Comment

Deploy and build containers on Red Hat OpenShift Container Platform 3.4 via CloudForms 4.2 self service

I had multiple requests if CloudForms is able to provision containers via self service to the Red Hat OpenShift container platform. I liked the idea as you can not expect from every developer in your company to know how to create templates or build configs. I will walk you through, step by step how this can be achieved with CloudForms and it’s native integration into Ansible Tower.

Step 1 Create a new project in Ansible Tower and add as the giturl this will download the role / playbook which I wrote to prove the above case.


Step 2 I assume that you already have an inventory added to your tower instance. Let’s create the Job Template so we can launch containers / pod in OpenShift. Add the following values to the job template


Step 3 For extra_vars add the following
projectname: test
template: nodejs-example
apphostname: mynodejsapp
templatename: phptemplate
createtemplate: false
quickapp: false
sti: false
scaleme: false
autoscale: false
username: laurent
pass: redhat
contextdir: .
number_of_instances: 1
ocport: 8443

Do not forget to check to box Prompt on launch and save tho job template

Step 4 Login to CloudForms and go to the tab configuration management -> Ansible Job Templates. You should see the following. Generate a catalog item from the octools template and name it ose_sti.

Step 5 Then go to Automate -> Customization -> Service Dialogs and click on the ose_sti catalog item. For this example we can delete some of the fields as they are not needed for source to image. Make sure your catalog item has the same fields as I am showing in the picture below.


Step 6 Set the STI value to true as I am filtering for it in the ansible playbook. This field is read only.

Step 7 For autoscale create a radio button with the values true or false. If you set it to true it will automatically create a horizontal pod autoscaler based on cpu load.

Step 8 The Limit for the job needs to be read only as well. I choose it to be the master as the master has the oc tools installed.

Step 9 For my OpenShift installation I am using basic auth. For this demo to work you need create a user in OpenShift matching the user loggedin in CloudForms.

Login to your openshift master and add a user to the htpasswd file

$ sudo htpasswd /etc/origin/htpasswd username

Remember the password.

Step 10 Go back to CloudForms. For the username field I’ve created a new method based on Kevin Moreys CloudForms Dropdown list in CloudForms_Essentials -> Integration -> RedHat -> CloudForms -> Dynamic dialog -> get_loggedin_user


dialog_hash = {}

users = $evm.vmdb(:user).all

users.each do |u|
if == $evm.root[‘user’].id
dialog_hash[u.userid] = “#{u.userid}”

$evm.object[“values”] = dialog_hash
$evm.log(:info, “$evm.object[‘values’]: #{$evm.object[‘values’].inspect}”)

Step 11 Wire the field to be a dynamic dropdown and add the following values.

Step 12 The password field needs to be protected and match the one you’ve create with htpasswd on OpenShift. In reality you would have connected your CloudForms appliance and OpenShift to LDAP and grabbed the encrypted password from CloudForms instead of entering it.

Step 13 For the email address I used another method in the CloudForms essentials domain as I want to send an email to the developer once his application is deployed. Create new method called get_loggedin_user_email


dialog_hash = {}

users = $evm.vmdb(:user).all

users.each do |u|
if == $evm.root[‘user’].id
dialog_hash[] = “#{}” if

$evm.object[“values”] = dialog_hash
$evm.log(:info, “$evm.object[‘values’]: #{$evm.object[‘values’].inspect}”)


The field email address should look like this


Step 14 To be able to send a user a customized email message I copied the ConfigurationManagement->AnsibleTower->Service->Provisioning->Email->ServiceProvision_Complete instance and its method ServiceProvision_Complete and renamed the method to ServiceProvision_Complete_OSE. Your instance should look like this.

Step 15 Create the email method ServiceProvision_Complete_OSE and add the following content

# Description: Email the user once provisioning is done.

# Setup variables from dialog
user_name = $evm.root[‘dialog_param_username’]
user_mail = $evm.root[‘dialog_user_mail’]
apphostname = $evm.root[‘dialog_param_apphostname’]
giturl = $evm.root[‘dialog_param_git_url’]
projectname = $evm.root[‘dialog_param_projectname’]

# Set up Static variables
from = $evm.object[‘from_email_address’]

#form the messsage
subject = “Container Provisioning Request Complete”

body = “Hello #{user_name}”
body += ”

Your Application #{apphostname} is up and running.”
body += ”

We used the following git_url to build the app #{giturl}”
body += ”

You can reach your app at http://#{apphostname}-#{projectname}
body += ”

Go back to work!
body += ”

Please be aware that you get billed for this application”
body += ”

Thank you,”
body += ”

The Cloud Team”

# Send email
$evm.log(“info”, “Sending email to from subject: “)
$evm.execute(:send_email, user_mail, from, subject, body)

Step 16 Wire up your email field and we are done with configuring the catalog item

Step 17 Create a new StateMachine named default_ose for Email Owner add


This will send off the email once you deployed the container

Step 18 Login to your cloudforms self service portal https:///self_service and click on the ose_sti tile which will lead you to the catalog item.

Fill out the fields in the catalog item, add it to the shopping cart and order it.

You can know check the Ansible Tower and see that your job got kicked off

Step 19 After a few seconds you will see that OpenShift starts up the pods with your container in it.

Step 20 If your pod started successfully you should see this

Step 21 Go back to CloudForms and verify that you also see the newly created pod.

and its services


Step 22 In the meantime you also should have received an email saying that the container provisioning was complete.

Posted in ansible, CloudForms, OpenShift | Tagged , , | Leave a comment

Register hosts to Satellite6 via CloudForms and Ansible Tower part 3

In the first two parts of the blog series you’ve learned how you can create an inventory synchronizing Ansible Tower with CloudForms, create a Job Template in Ansible Tower and auto generate a service catalog item in CloudForms from the Job Template under the configuration management tab. You’ve also learned how you can create a new catalog and add the catalog item to it. Part 3 in the blog series is going to show you how you can create a custom button under the VM instances tab.

Step 1 Click on Automate

Step 2 Select VM and Instances
Configuration -> Add new button Group
and add the following values
click add on the bottom right

Step 3 Scroll to your new button group and select it.
Go to Configuration Add new Button tab
and enter the following values

Once done press add on the bottom right and your done.

Step 4 I will now show you where you can find the button. Go to Compute
Virtual Machines

Step 5 Select any of your VM instances

Step 6 In the menu bar you will see your button group AnsibleTowerJob and your button registersat6
Press the registersat6 button which will load the sat6register service dialog.

In part 2 we create a service dialog which can be ordered from the self service ui. There is one big difference between both dialogs. If you submit the dialog from a button, the Limit (‘hostname’) of the select host is automatically passed as a variable to the CloudForms automate engine. Therefore the limit can be left empty while ordering from a button. This is not the case when ordering from a self service dialog.

Posted in ansible, CloudForms, Puppet | Tagged , , , | Leave a comment

Register hosts to Satellite6 via CloudForms and Ansible Tower part 4

This post will walk you through how to customize the service dialog which we created in the previous post so that we pull the following values via api calls from Satellite6:
– Activation Keys
– Organization
– Location
– Hostgroups

The end goal will look like this
Step 1 First you will need to pull my automation model which contains the functions to connect to satellite6 and get the necessary information.

Step 1 Download the automate model for satellite6 from the managiq depot so you get access to the api calls to Red Hat Satellite 6 for the dynamic drop downs.
Here also a direct link to the download

Follow the instructions in the to upload the automate domain into CloudForms.

Step 2 As the domain will be imported as disabled
We will have to go and enable it.
Click on Configuration -> Edit this Domain
and check the box Enabled
Save the Domain name

Step 3
You should now see the following

Step 4 Edit the Schema to fit your configuration. Select DynamicDropDowns -> and the Schema tab.

Click on Configuration -> Edit selected Schema

Step 5 Edit the following fields
username: your admin user
password: your admin password
sat6url: https://yoursat6fqdn/api
katellourl: https://yoursat6fqdn/katello/api

Click the save button

Step 6 You are now ready to start pointing your service dialog fields to the automate methods. Go to Automate
Service Dialogs

Select your service catalog item which we created in the previous blog posts.

Step 7 Click the Configuration -> Edit this Dialog
We want to re arrange the order of the fields a little bit. Click the Extra_Vars value on the left
Drag and drop the fields on the right so they will look like mine.

Do not hit save yet!

Step 8
Select the org field
We will switch the Type of the filed from Text Box to Drop Down List. Check the Dynamic box which will give you the ability to select the Entry point for that field ( /Integration/RedHat/Satellite6/DynamicDropDowns/List_Organizations )

We also want the Show Refresh Button box checked and the values loaded on init. As the organization defines the activation keys we want to Auto Refresh other fields when modified as well.

Step 9 Select activationkey and change the values to the following

Step 10 Select location and change the fields to match the picture

Step 11 Select hostgroup and change the values to reflect the picture below.

Step 12 We will update the updatehost filed from a text field to radio buttons.

Now you can hit the save button.

Step 13 Congratulations. Your done. when you go know to your service dialog or custom button you will see the following

Posted in ansible, CloudForms | Tagged , , | Leave a comment

Register hosts to Satellite6 via CloudForms and Ansible Tower part 2

This post will show you how to add Ansible Tower as a provider in CloudForms, discover and create a catalog item out of a job template we’ve created and order the catalog item via self service portal.

If you followed part 1 you now have a fully functional Ansible Tower which we can add as a provider to Red Hat CloudForms.

Step 1 Login to CloudForms

Step 2 Go to Configuration -> Configuration Management

Step 3 Click on Configuration and add a new provider

Step 4 Fill in the following values (of course it needs to match your environment)
Now validate your credentials
and hit add

Step 5 After Adding the provider you will see that CloudForms will discover the created job template from Ansible Tower

Step 6 Click on the sat6register job template
Then click configuration -> Create Service Dialog from this Job Template

In my case I did name the template reghosts_to_sat6
Click the save button on the bottom right

Step 7 Now its time to look at the actual service dialog which got created from the Ansible Job Template
Got to Automate -> Customization -> Service Dialogs and click on your service dialog. You will see a dialog which pretty much looks like this
If you want to be able to edit the fields you have to uncheck the readonly box for each field. Per default they are set readonly!

Step 8 Believe it or not but this is a fully functional service dialog which can be added to a catalog in CloudForms. Part 4 of the series which I will release next week will show you how you can make some of these fields dynamic.

Step 9 Create a catalog. Go to Services -> Catalogs -> Catalogs and click on Configuration -> Create new catalog
Name the catalog however you like and add it

Step 10 Lets add the service dialog to the ansible catalog. Click on Services -> Catalogs -> Catalog items -> ansible -> Configuration -> Create new catalog item
As a catalog item type choose AnsibleTower
Add the following values to the catalog item and click add

Step 11 Lets add some color to the catalog item and add an ansible logo. Click on the newly created catalog item and upload the ansible logo.

Step 12 login to the self service ui, you will find that under https://cloudformsfqdn/self_service
Once logged in click on Service Catalog and you will see your ansible catalog item

Step 13 Click on the ansible catalog item and fill out the values. The limit is the host or hosts separated by “:” which you would like to register to Satellite6. The limit cannot be left empty and the host must exist in the Ansible Tower inventory unless you chose the tower inventory to update on launch of a job.
If you have entered all the correct values you can go ahead, add the item to the shopping cart
You can now click on the shopping cart on the top right and order the item

As this item was launched as a service you can follow the work flow under Services->Requests. Once the statemachine steps gets to launch_job you will see the job popping up in the Ansible Tower Console.


After few second, the job is executed and registers the host with the Red Hat Satellite 6 server. The completion of the job can be validated in CloudForms under Services -> Requests or in the Satellite 6 UI.

The next part (part 3) of the blog series which I will release next week will show you how you can add that dialog as a button under vm instances.

Posted in ansible, CloudForms, Puppet | Tagged , , , | Leave a comment

Register hosts to Satellite6 via CloudForms and Ansible Tower part 1

CloudForms is the single pane of glass for virtual machines, cloud instances, and baremetal servers provisioned via Satellite 6. Since we added support for Ansible Tower we can do a lot of magic as we can now call Ansible Tower via CloudForms. What does that mean for operations and orchestration?

Let’s say we have the following use case:

We have a host or multiple hosts which need to be registered to Red Hat Satellite 6 and update to the latest errata. We also want to be able to choose if puppet should be used as a configuration management tool or if the host will be managed by Ansible Tower.

CloudForms gives you endless possibilities on how you could achieve this registration. The blog series will walk you through the steps on how to build the above use case through the out of the box integration with Ansible Tower by Red Hat and Red Hat Satellite 6.

Part 1 Will walk you through how to enable the inventory synchronization between CloudForms and Ansible Tower and how to create the sat6register job which will be executed from CloudForms.
Part 2 Will walk you through how to auto generate a service dialog in CloudForms from an Ansible Tower Job and expose it as a self service catalog item which can be ordered via self service portal.
Part 3 Will walk you through the creation of a custom button sat6register under the VM section which enable you to register a host from the administration ui.
Part 4 Will walk you through the customization of the service dialog to make it dynamic and grab information via api from Red Hat Satellite 6.

Step 1 Login to Ansible Tower with an admin user

Step 2 Click on the project tab on the top left
Step 3 Then click +ADD

Step 4 Fill in the following information
NAME: Can be arbitrary
DESCRIPTION: I like to see the giturl of the project there so
ORGANIZATION: In my case default
Step 5 Once done hit save
and go back to the project tab
where you will see the following

Step 6 Create machine credentials for the hosts you would like to access via ssh. Click on settings

Fill in the information for your host. In my case I did use username password. In your case it could be an ssh-key. The vault password is used to decrypt the admin_pass password for the Red Hat Satellite 6 connection. You can learn how to set the initial vault password it here:
click +ADD

Step 7 Create the credential to connect to your Red Hat CloudForms appliance. We will need those when we setup the inventory sync between Ansible Tower and Red Hat CloudForms. Repeat Step 6 (You won’t need a vault password here). As a type choose CloudForms
and hit +ADD
Step 8 Now we are ready to go and create an inventory for the hosts which are in CloudForms. We need this as ansible is going to ask us about the inventory if we create the job template. Click on the inventory tab
and click the +ADD button.
Fill in the following values
and hit save. You will get redirected to the groups page. Here is where you could add group variables for the CloudForms inventory.

Click the ADD Group button and
fill in the following values
and hit save

Step 9 Now Sync the inventory on the bottom left corner of the page
You will get redirected to the following page. Once the sync is finished you should see a screen similar to this if you have hosts within CloudForms.

Step 10 We are finally ready to create the job in Ansible Tower. Click on the Job Template tab
click +ADD
and enter the following values for the job template

Step 11. Add the following values to the EXTRA VARIABLE field
sat6_ip: $HOST_IP_ADDR
sat6_fqdn: $HOST_FQDN
admin_user: admin
org: redhat
loc: nyc
hostgroup: false
activationkey: ak-Reg_To_Library_soe_no_puppet

Make sure you create a password in the /roles/sat6register/group_vars/all/vault file as it will be looked up by /roles/sat6register/group_vars/all/vars file containing admin_pass: “{{ vault_admin_pass}}”.
You also find instructions on how to do this here:

Make sure that the box Prompt on launch is checked. This is very important as if you don’t do this right you will NOT be able to override any extra_vars from CloudForms when executing the job template.
. We are now done with the Ansible Tower setup. Let’s go to part 2 which will explain howto setup CloudForms to execute this Job Template.

Posted in ansible, CloudForms, Puppet | Tagged , , | Leave a comment