Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Customizing an OpenShift Ansible Playbook Bundle

May 23, 2018
Alessandro Arrichiello
Related topics:
ContainersLinuxKubernetes
Related products:
Streams for Apache KafkaRed Hat OpenShiftRed Hat OpenShift Container PlatformRed Hat Enterprise Linux

Share:

    Today I want to talk about Ansible Service Broker and Ansible Playbook Bundle. These components are relatively new in the Red Hat OpenShift ecosystem, but they are now fully supported features available in the Service Catalog component of OpenShift 3.9.

    Before getting deep into the technology, I want to give you some basic information (quoted below from the product documentation) about all the components and their features:

    • Ansible Service Broker is an implementation of the Open Service Broker API that manages applications defined in Ansible Playbook Bundles.
    • Ansible Playbook Bundles (APB) are a method of defining applications via a collection of Ansible Playbooks built into a container with an Ansible runtime with the playbooks corresponding to a type of request specified in the Open Service Broker API specification.
    • Playbooks are Ansible’s configuration, deployment, and orchestration language. They can describe a policy you want your remote systems to enforce, or a set of steps in a general IT process.

    So the ASB (Ansible Service Broker) is the man-in-the-middle between the APB (Ansible Playbook Bundle) and a third-party user that would like to consume the service offered through the Ansible Playbook on OpenShift.

    Linking up these two components, OpenShift Service Catalog is able to offer—through OpenShift Web Portal and its API—access to these pieces of deployment/configuration to OpenShift users. This enables an entire world of possibilities from an OpenShift perspective:

    • Easily define, distribute, and provision microservice(s), such as RocketChat and PostgreSQL, via Ansible Playbooks packaged in Ansible Playbook Bundles.
    • Easily bind microservice(s) provisioned through Ansible Playbook Bundles, for example, as shown in this video: Using the Service Catalog to Bind a PostgreSQL APB to a Python Web App.

    Getting deeper into the technology, we'll see how to use the following steps to create a MariaDB APB that will set up MariaDB on an external remote host:

    1. Get started with the technology by creating your first APB.
    2. Customize your first APB and let it configure an external remote host (through SSH).
    3. Build and push your first APB.
    4. Understand the ASB and APB operations under the hood.
    5. Troubleshoot an APB.

    Are you ready? Let's get started!

    Please note: You need to have a fully configured and functional OpenShift 3.9 cluster before continuing. Minishift and the CDK, at the moment, do not offer Service Catalog and Ansible Service Broker enabled. Please check the project documentation.

     

    Getting Started with an APB

    Starting from OpenShift 3.9, you'll not need any additional configuration or deployment to get Ansible Service Broker and the Service Catalog working. They will be set up by the OpenShift installer at first installation/update.

    So, the first thing you need to do is to let the Ansible Service Broker search in the OpenShift default registry for container images. To achieve this, edit the configmap used by the Ansible Service Broker and edit the whitelist:

    $ oc edit configmap broker-config -n openshift-ansible-service-broker

    In the configmap, add a whitelist rule for the OpenShift registry similar to the one already set up for the Docker Hub registry:

    - type: local_openshift
    name: localregistry
    namespaces:
    - openshift
    white_list:
    - ".*-apb$"

    With this rule in place, the Ansible Service Broker will search in the local OpenShift registry for container images  ending with the string -apb.

    After that we need we need to rollout a new version of the Ansible Service Broker:

    $ oc rollout latest dc/asb -n openshift-ansible-service-broker

    You're now ready to initialize your first APB. First, you need the apb binary. On a Red Hat Enterprise Linux (with OpenShift repos enabled), you just need to run this command:

    $ yum install -y apb

    Then you can initialize your first APB by running this command:

    $ apb init mariadb-deployment-apb

    The command will set up an initial directory tree (shown below), which is ready to be customized depending on your needs:

    $ ls -la mariadb-deployment-apb/
    total 12
    drwxrwxr-x. 4 ocpadmin ocpadmin 85   May 18 14:08 .
    drwx------. 9 ocpadmin ocpadmin 255  May 18 14:33 ..
    -rw-rw-r--. 1 ocpadmin ocpadmin 1082 May 18 13:57 apb.yml
    -rw-rw-r--. 1 ocpadmin ocpadmin 1731 May 18 14:34 Dockerfile
    -rw-rw-r--. 1 ocpadmin ocpadmin 769  May 16 12:16 Makefile
    drwxrwxr-x. 2 ocpadmin ocpadmin 50   May 18 14:33 playbooks
    drwxrwxr-x. 6 ocpadmin ocpadmin 145  May 16 12:30 roles

    As you can see, the command creates a description file called apb.yml for metadata and parameters that need to be requested from users of the playbook bundle. The metadata will be used for displaying the item in the ServiceCatalog, while the parameters will be used to prompt users of the bundle to supply necessary configuration details. We'll take a look and customize it in the next section.

    Then it creates a Dockerfile for building up the final container and a Makefile, of course, that defines the method for building and pushing the container up to the OpenShift internal registry.

    Finally, you'll find the two key directories containing—guess what?— Ansible "playbooks" and "roles." These directories contain pre-built playbooks for provisioning and de-provisioning and a skeleton for a custom role you may want to build.

    But let's take a look to the playbook it made:

    $ cat playbooks/provision.yml 
    - name: mariadb-test-apb playbook to provision the application
      hosts: localhost
      gather_facts: false
      connection: local
      roles:
      - role: ansible.kubernetes-modules
        install_python_requirements: no
      - role: ansibleplaybookbundle.asb-modules
      - role: provision-mariadb-test-apb

    As you can see, the playbook is really simple. It runs against localhost (connection: local), and it will execute two pre-defined roles: ansible.kubernetes-modules and ansibleplaybookbundle.asb-modules. These two roles will set up the basic actions for letting your container communicate with the current OpenShift platform and its underlying Kubernetes layer.

    Finally, the playbook will execute a custom role, provision-mariadb-test-apb. This role is basically empty; you should fill it with your code!

     

    Customizing Your First APB for Connecting to a Remote Host

    As mentioned in the introduction, you will not use the standard behavior for your APB. Instead, you'll make it connect to an external host for installing and configuring MariaDB.

    First, you need to edit the apb.yml file to add some metadata and variables that you'll use later in the playbooks:

    $ cat apb.yml 
    version: 1.0
    name: mariadb-deployment-apb
    description: This is a sample application generated by apb init
    bindable: False
    async: optional
    metadata:
      displayName: MariaDB on vm (APB)
    plans:
      - name: default
        description: This default plan deploys mariadb-deployment-apb
        free: True
        metadata: {}
        parameters:
          - name: dbname 
            title: Database name to create on just created mariadb
            type: string
            default: myappdb
            required: true
          - name: rootpassword
             title: Database root password to set
             type: string
             default: P4ssw0rd!
             required: true
             display_type: password
          - name: target_host
             title: Target Host for provisioning
             type: string
             default: 172.16.0.7
             required: true
          - name: remoteuser
             title: SSH Remote User
             type: string
             default: user
             required: true
          - name: sshprivkey
             title: SSH Private key for connecting to the remote machine
             type: string
             required: true
             display_type: textarea

    As you can see, you set up five parameters that the user will be asked to provide through the OpenShift interface:

    1. The database name
    2. The root password for the database
    3. The target host to connect to
    4. The remote user to use during SSH connection
    5. The SSH private key to use during SSH connection

    As you may suppose, you'll not write from scratch a role for installing and configuring MariaDB on your remote system. There are tons of roles available on the Ansible Galaxy network!

    For this example, I chose these two (you'll need a role for configuring the firewall, too):

    1. MariaDB Ansible role
    2. Firewall Ansible role

    Download them and place them under roles directory.

    After that, you need to edit the provision.yml playbook. For connecting to an external host, you need to add the host to the inventory, dynamically.

    $ cat playbooks/provision.yml
    - name: mariadb-deployment-apb playbook to provision the application
      hosts: localhost
      gather_facts: false
      connection: local
      roles:
      - role: ansible.kubernetes-modules
        install_python_requirements: no
      - role: ansibleplaybookbundle.asb-modules
      - role: provision-mariadb-deployment-apb
        playbook_debug: false
      tasks:
        - name: Adding the remote host to the inventory
          add_host:
            name: "{{ target_host }}"
            groups: target_group
          changed_when: false
        - name: Adding ssh private key
          shell: "mkdir -p /opt/apb/.ssh && chmod 700 /opt/apb/.ssh && echo -e \"{{ sshprivkey }}\" > /opt/apb/.ssh/id_rsa && chmod 600 /opt/apb/.ssh/id_rsa"
    
    - name: Provision mariadb
      hosts: target_group
      remote_user: "{{ remoteuser }}"
      become: true
      vars:
      firewall_allowed_tcp_ports:
      - "22"
      - "3306"
      mariadb_bind_address: "0.0.0.0"
      mariadb_root_password: "{{ rootpassword }}"
      mariadb_databases:
      - name: "{{ dbname }}"
      roles:
      - role: ansible-role-firewall
      - role: ansible-role-mariadb

    Inspecting the playbook, you'll see that first you add the host (from the variable) to the inventory, and then you set up the SSH private key for connecting to the remote host. To accomplish this, I use a single shell command instead of taking the command apart using all the available Ansible modules.

    Then in the second playbook, you connect to the remote host to configure the firewall and MariaDB.

    So, you'll also need to edit the deprovision.yml playbook:

    $ cat playbooks/deprovision.yml 
    - name: mariadb-deployment-apb playbook to deprovision the application
      hosts: localhost
      gather_facts: false
      connection: local
      roles:
      - role: ansible.kubernetes-modules
        install_python_requirements: no
      - role: ansibleplaybookbundle.asb-modules
      - role: deprovision-mariadb-deployment-apb
        playbook_debug: false
      tasks:
      - name: Adding the remote host to the inventory
        add_host:
          name: "{{ target_host }}"
          groups: target_group
        changed_when: false
      - name: Adding ssh private key
        shell: "mkdir -p /opt/apb/.ssh && chmod 700 /opt/apb/.ssh && echo -e \"{{ sshprivkey }}\" > /opt/apb/.ssh/id_rsa && chmod 600 /opt/apb/.ssh/id_rsa"
    
    - name: Remove mariadb packages
      remote_user: "{{ remoteuser }}"
      become: yes
      hosts: target_group
      tasks:
      - name: Remove the package from the host
        package:
          name: mariadb
          state: absent

    The deprovisioning is just to remove the mariadb package and nothing else.

    Finally, for connecting smoothly to your remote host without SSH prompting us to add  the host to the known list, you can make a little addition to the Dockerfile to disable host_key_checking:

    $ cat ../mariadb-test-apb/Dockerfile 
    FROM ansibleplaybookbundle/apb-base
    
    LABEL "com.redhat.apb.spec"=\
    
    COPY playbooks /opt/apb/actions
    COPY roles /opt/ansible/roles
    RUN echo "host_key_checking = False" >> /opt/apb/ansible.cfg
    RUN chmod -R g=u /opt/{ansible,apb}
    USER apb

     

    Building and Pushing Your First APB

    First, you need to prepare the APB for the push to the registry:

    $ apb prepare
    Finished writing dockerfile.

    This command adds a signature to the Dockerfile so you can double-checking the build later.

    After that, you can build the APB. Remember you need to be root (or have proper rights for accessing the Docker daemon):

    $ sudo apb build
    Finished writing dockerfile.
    Building APB using tag: [mariadb-deployment-apb]
    Successfully built APB image: mariadb-deployment-apb

    You can double-check the build by checking the list of docker images:

    $ sudo docker images|grep mariadb
    mariadb-deployment-apb latest b4d6a95a79b7 2 days ago 604 MB

    And finally, you can push the APB into the registry. But before proceeding, you should be logged in to OpenShift as an admin user with a valid token. The user system:admin doesn't have a token by default, so create an additional user and give it the cluster-admin" role.

    $ sudo oc whoami
    ocpadmin
    $ sudo apb push
    Didn't find OpenShift Ansible Broker route in namespace: ansible-service-broker. Trying openshift-ansible-service-broker
    version: 1.0
    name: mariadb-deployment-apb
    description: This is a sample application generated by apb init
    bindable: False
    async: optional
    metadata:
     displayName: MariaDB on vm (APB)
    plans:
     - name: default
     description: This default plan deploys mariadb-deployment-apb
     free: True
     metadata: {}
     parameters:
     - name: dbname 
       title: Database name to create on just created mariadb
       type: string
       default: myappdb
       required: true
     - name: rootpassword
       title: Database root password to set
       type: string
       default: R3dh4t1!
       required: true
       display_type: password
     - name: target_host
       title: Target Host for provisioning
       type: string
       default: 172.16.0.7
       required: true
     - name: remoteuser
       title: SSH Remote User
       type: string
       default: user
       required: true
     - name: sshprivkey
       title: SSH Private key for connecting to the remote machine
       type: string
       required: true
       display_type: textarea
    
    
    Found registry IP at: 172.30.3.246:5000
    Finished writing dockerfile.
    Building APB using tag: [172.30.3.246:5000/openshift/mariadb-deployment-apb]
    Successfully built APB image: 172.30.3.246:5000/openshift/mariadb-deployment-apb
    Found image: docker-registry.default.svc:5000/openshift/mariadb-deployment-apb
    Warning: Tagged image registry prefix doesn't match. Deleting anyway. Given: 172.30.3.246:5000; Found: docker-registry.default.svc:5000
    Successfully deleted sha256:0bd78762bbf717333f1e017e3578bcd55a70877810fc7f859d04455e80df0a94
    Pushing the image, this could take a minute...
    Successfully pushed image: 172.30.3.246:5000/openshift/mariadb-deployment-apb
    Contacting the ansible-service-broker at: https://asb-1338-openshift-ansible-service-broker.140.11.34.16.nip.io/ansible-service-broker/v2/bootstrap
    Successfully bootstrapped Ansible Service Broker
    Successfully relisted the Service Catalog

    You did it! You successfully loaded an APB into the OpenShift registry and Ansible Service Broker.

    The next time you log in to OpenShift, you should find the APB in the Service Catalog:

    And moving forward, in the Configuration section, you'll see the required variables you configured earlier:

     

    Understanding the ASB and APB Operations Under the Hood

    Requesting the element from the Service Catalog by clicking Create in the previous screen, will start a very special action inside the running OpenShift cluster:

    $ oc get serviceinstance -n test
    NAME AGE
    localregistry-mariadb-deployment-apb-bd4cb 27s
    $ oc get pods --all-namespaces|grep apb
    localregistry-mariadb-deployment-apb-prov-6pntf apb-f34a346d-3b25-46a5-95c2-54d480ae6701 1/1 Running 0 28s

    As you can see, an element of type ServiceInstance was created and linked to this, a new pod was scheduled: our Ansible playbook is just running in this container.

    Looking through the logs, you can monitor the running activities:

    $ oc logs -n localregistry-mariadb-deployment-apb-prov-6pntf apb-f34a346d-3b25-46a5-95c2-54d480ae6701 -f
    
    PLAY [mariadb-deployment-apb playbook to provision the application] ************
    
    TASK [ansible.kubernetes-modules : Install latest openshift client] ************
    skipping: [localhost]
    
    TASK [ansibleplaybookbundle.asb-modules : debug] *******************************
    skipping: [localhost]
    
    TASK [Adding the remote host to the inventory] *********************************
    ok: [localhost]
    
    TASK [Adding ssh private key] **************************************************
     [WARNING]: Consider using the file module with state=directory rather than
    running mkdir. If you need to use command because file is insufficient you can
    add warn=False to this command task or set command_warnings=False in
    ansible.cfg to get rid of this message.
    changed: [localhost]
    
    PLAY [Provision mariadb] *******************************************************
    
    TASK [Gathering Facts] *********************************************************
    ok: [10.1.0.11]
    
    TASK [ansible-role-firewall : Ensure iptables is present.] *********************
    ok: [10.1.0.11]
    
    TASK [ansible-role-firewall : Flush iptables the first time playbook runs.] ****
    ok: [10.1.0.11]
    
    TASK [ansible-role-firewall : Copy firewall script into place.] ****************
    ok: [10.1.0.11]
    
    TASK [ansible-role-firewall : Copy firewall init script into place.] ***********
    skipping: [10.1.0.11]
    
    TASK [ansible-role-firewall : Copy firewall systemd unit file into place (for systemd systems).] ***
    ok: [10.1.0.11]
    
    TASK [ansible-role-firewall : Configure the firewall service.] *****************
    ok: [10.1.0.11]
    ...

     

    Troubleshooting an APB

    What happens if your tests go wrong and the Ansible pod fails and produces an error?

    Of course you can look through all the APB pods (as shown before) and run the usual oc debug PODNAME command for creating a brand-new pod for troubleshooting.

    If you experience some issue deleting a failed ServiceInstance, you can edit the element to remove the Kubernetes finalizer, as shown below:

    $ oc get serviceinstance -n test -o yaml
    apiVersion: v1
    items:
    - apiVersion: servicecatalog.k8s.io/v1beta1
      kind: ServiceInstance
      metadata:
        creationTimestamp: 2018-05-20T21:14:23Z
        finalizers:
        - kubernetes-incubator/service-catalog
        generateName: localregistry-mariadb-deployment-apb-
        generation: 1
        name: localregistry-mariadb-deployment-apb-bd4cb
        namespace: test
    ...

    Sometimes, some nodes can get a different version of your APB in the Docker cache, so you might experience different behaviors if you did multiple builds and pushes. You can manually log in to the various OpenShift nodes and then clean up the outdated Docker images (you may want use Ansible from bastion host for doing that).

    That's all!

    Feel free to ask if you have any questions!

     

    About Alessandro

    Alessandro Arrichiello is a Solution Architect for Red Hat Inc. He has a passion for GNU/Linux systems, which began at age 14 and continues today. He works with tools for automating enterprise IT: configuration management and continuous integration through virtual platforms. He’s now working on a distributed cloud environment involving PaaS (OpenShift), IaaS (OpenStack) and processes management (CloudForms), container building, instance creation, HA services management, and workflow builds.

    Last updated: March 24, 2023

    Recent Posts

    • GuideLLM: Evaluate LLM deployments for real-world inference

    • Unleashing multimodal magic with RamaLama

    • Integrate Red Hat AI Inference Server & LangChain in agentic workflows

    • Streamline multi-cloud operations with Ansible and ServiceNow

    • Automate dynamic application security testing with RapiDAST

    Red Hat Developers logo LinkedIn YouTube Twitter Facebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dashboard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue