text: Ansible Playbook Bundle Development Guide
  Developing with Ansible Playbook Bundle (APB)
  Abstract
  Chapter 1. Introduction
  1.1. About This Guide
  This guide outlines the design concepts and workflow of Ansible Playbook Bundles (APBs), shows how to install and use the
  apb CLI tooling, and provides a tutorial and reference material on writing your own APBs.
  1.2. Design Overview.
  Specification of an APB is intended to be lightweight, consisting of several named playbooks and a metadata file to capture information such as parameters to pass into the application.
  1.3. Workflow
  The APB workflow is broken up into the following steps:
  Preparation
  - APB initialization
  - APB spec file
  - Actions (provision, deprovision, bind, unbind)
  - Build
  - Deploy
  1.3.1. Preparation
  You must prepare your APB’s directory structure and spec file before you can build and deploy it. The Getting Started topic provides a step by step tutorial on creating your first APB, while the following sections briefly cover this workflow.
  1.3.1.1. APB Initialization
  The
  apb init command creates the required skeleton directory structure and a few required files (for example, the apb.yml spec file) for the APB.
  The following shows an example directory structure of an APB:
  Directory Structure
  1.3.1.2. APB Spec File
  1.3.1.3. Actions
  The following are the actions for an APB. At a minimum, an APB must implement the provision and deprovision actions:
  - provision.yml
  - Playbook called to handle installing application to the cluster.
  - deprovision.yml
  - Playbook called to handle uninstalling.
  - bind.yml
  - Playbook to grant access to another service to use this service, such as generating credentials.
  - unbind.yml
  - Playbook to revoke access to this service.
  - test.yml
  - .
  1.3.2. Build.
  Figure 1.1. APB Build
  1.3.3. Deploy OpenShift Container Platform resources, perhaps through calling
  oc create commands or leveraging Ansible modules. The end result is that the APB runs Ansible to talk to OpenShift Container Platform to orchestrate the provisioning of the intended application.
  The following diagrams illustrate this deployment flow in two phases: a user discovering a list of available APBs and then requesting their chosen APB be provisioned to their project:
  Figure 1.2. Listing Available APBs
  An OpenShift Container Platform user is interested in provisioning a service into their project, so they interact with the service catalog by accessing the OpenShift Container Platform UI (web console or CLI) to discover any APBs that are already available.
  The service catalog requests a list of APBs from the OAB to show the user.
  The OAB searches all configured container registries (the cluster’s OpenShift Container Registry or any other remote registry) for any APBs (images with a specific label, for example
  LABEL=apb-1.0).
  The OAB returns the discovered list to the service catalog, to be viewed by the user in the OpenShift Container Platform UI.
  Figure 1.3. Deploying a Chosen APB
  The user now chooses an APB from the discovered list provided by the service catalog.
  The service catalog communicates with the OAB that the user has requested use of the chosen APB.
  The OAB initiates the image pull from the appropriate container image registry.
  After the image is pulled, the OAB defers the logic for orchestrating the application to the APB. The service is deployed by running the APB container with a few parameters. To do so, the following command is issued against the OpenShift Container Platform cluster in a temporary namespace:
  $ oc run $IMAGE $METHOD $VARS ansible-playbook ${METHOD}.yaml ${VARS}
  To break this command down further:
  - The
  oc runcommand runs the APB image.
  - In the short-lived container that is created as a result, Ansible is launched using the
  ansible-playbookcommand, which runs the appropriate playbook (for example, provision.yaml) to execute the requested action. This creates OpenShift Container Platform resources in the user’s project.
  - The container exits at the end of the run, and the temporary namespace is removed.
  As a result, the user views via the OpenShift Container Platform UI that their requested service has been successfully provisioned in their project.
  Chapter 2. CLI Tooling
  2.1. Overview
  The
  apb CLI tool helps Ansible Playbook Bundle (APB) authors create, build, and publish their APBs to container registries. It enforces best practices and takes care of the details so they should be easy to deploy.
  2.2. Installing the Tool
  2.2.1. Prerequisites
  2.2.1.1. Docker Daemon
  The
  docker daemon must be correctly installed and running on the system.
  2.2.1.2. Access Permissions):
  This is effectively cluster root and should only be used in a development setting.
  $ -
  2.2.2. Installing via RPM
  The APB CLI tool is provided by the apb package, which is available from the
  rhel-7-server-ose-3.11-rpms channel:
  $ sudo yum install apb
  2.2.3. Verifying the Installation
  2.3. Typical Workflows
  2.3.1. Local Registry>
  2.3.2. Remote Registry
  2.4. APB Creation Commands
  2.4.1.
  init
  Description
  Initializes a directory structure for a new APB. Also creates example files for the new APB with sensible defaults.
  Usage
  $ apb init [OPTIONS] NAME
  Arguments
  NAME: Name of the APB and directory to be created.
  Options
  Async bind and unbind is an experimental feature and is not supported or enabled by default.
  Examples
  2.4.2.
  prepare
  Description.
  Usage
  $ apb prepare [OPTIONS]
  Options
  Examples
  Writes the label for the spec field in the Dockerfile:
  $ apb prepare
  Writes the label for the spec field in Dockerfile-custom:
  $ apb prepare --dockerfile Dockerfile-custom
  2.4.3.
  build
  Description
  Builds the image for the APB.
  Similar to running
  apb prepare and
  docker build with a tag.
  Usage
  $ apb build [OPTIONS]
  Options
  Examples
  2.4.4.
  push
  Description.
  Usage
  $ apb push [OPTIONS]
  Options
  Examples
  Push to the OAB development endpoint:
  $ apb push
  Push to the local OpenShift Container Registry:
  $ apb push
  Push to the local OpenShift Container Registry under namespace
  myproject:
  $ apb push --namespace myproject
  2.4.5.
  test
  Description
  Runs the APB unit tests.
  Usage
  $ apb test [OPTIONS]
  Options
  Examples
  Run the tests:
  $ apb test
  Run the tests but use a specific tag on the built image:
  $ apb test --tag docker.io/my-org/my-new-apb
  2.5. Broker Utility Commands
  2.5.1.
  list
  Description
  Lists all the APBs the broker has loaded.
  Usage
  $ apb list [OPTIONS]
  Options
  Examples
  Basic list of APBs including name, ID, and description:
  $ apb list
  List verbose, easily readable specs:
  $ apb list -v
  List all the JSON output:
  $ apb list -v -o json
  2.5.2.
  bootstrap
  Description
  Requests the OAB to reload all APBs from the registries.
  Usage
  $ apb bootstrap [OPTIONS]
  Options
  Examples
  Basic reload of APBs:
  $ apb bootstrap
  2.5.3.
  remove
  Description
  Removes one (or all) APBs from the OAB.
  Usage
  $ apb remove [OPTIONS]
  Options
  Examples
  Remove an APB using an ID:
  $ apb remove --id ca91b61da8476984f18fc13883ae2fdb
  If you need an ID of an APB, use:
  $ apb list ID NAME DESCRIPTION ca91b61da8476984f18fc13883ae2fdb dh-etherpad-apb Note taking web application
  Remove all APBs:
  $ apb remove --all
  2.5.4.
  relist
  Description
  Forces service catalog to relist the provided services to match the broker.
  Usage
  $ apb relist [OPTIONS]
  Options
  Examples
  $ apb relist
  2.6. Other Commands
  2.6.1.
  Description
  Displays a help message.
  Usage
  $ apb help
  Examples
  $ apb help
  $ apb -h
  Chapter 3. Writing APBs
  3.1. Writing APBs: Getting Started
  3.1.1. Overview.
  For the remainder of this tutorial, substitute your own information for items marked in brackets; for example,
  <host>:<port> might need to be replaced with
  172.17.0.1.nip.io:8443.
  3.1.2. Before You Begincommand and check for a valid response.
  - If you are developing against an OpenShift Container Platform cluster that exists on a remote host or you do not have access to the docker daemon, see Working with Remote Clusters for alternative steps when using the
  apb pushand
  apb runcommands described in this guide.
  3.1.3. Creating Your First APB
  In this tutorial, you will create an APB for a containerized hello world application. You will work through a basic APB that will mirror the APB hello-world-apb.
  Your first task is to initialize the APB using the
  apbCLI.
  apb.yml
  version: 1.0 name: my-test-apb description: This is a sample application generated by apb init bindable: False async: optional metadata: displayName: my-test plans: - name: default description: This default plan deploys my-test-apb free: True metadata: {} parameters: []
  Dockerfiledirective to use the image from the Red Hat Container Catalog. The first line should now read:
  FROM openshift3/apb-base
  Update
  com.redhat.apb.specin the
  LABELinstruction with a base64 encoded version of apb.yml. To do this, run
  apb prepare:
  $ cd my-test-apb $ apb prepare
  This updates the Dockerfile as follows:
  Dockerfilecommand OpenShift Container Platform web console will now display the new APB named my-test-apb in the service catalog under the All and Other tabs.
  3.1.4. Adding Actions OpenShift Container Platform cluster via the
  ocCLI. This will ensure the
  apbtool can interact with OpenShift Container Platform and the OAB:
  # oc login <cluster_host>:<port> -u <user_name> -p <password>
  Log in to the OpenShift Container Platform web console and verify your APB listed in the catalog:
  Figure 3.1. OpenShift Container Platform Web Console
  Create a project named getting-started where you will deploy OpenShift Container Platform resources. You can create it using the web console or CLI:
  $ oc new-project getting-started
  3.1.4.1. Provision.
  playbooks/provision.yml
  - OpenShift Container Platform:
  Figure 3.2. Provisioning my-test
  3.1.4.1.1. Creating a Deploying Configuration:Note
  Normally, you would replace the
  image:value with your own application image.
  - OpenShift Container Platform.
  To clean up before moving on and allow you to provision again, you can delete the getting-started project and recreate it or create a new one.
  3.1.4.1.2. Creating a Servicesection will allow the my-test service to include the correct pods. The
  portswill take the target port from the pods (8080) and expose them as a single port for the service (80). Notice the application was running on 8080 but has now been made available on the default HTTP port of 80.
  The
  namefield.
  To clean up before moving on and allow you to provision again, you can delete the getting-started project and recreate it or create a new one.
  3.1.4.1.3. Creating a Route
  You can expose external access to your application through a reliable named route:is the name of the target service. The
  spec_port_target_portrefers.
  3.1.4.2. Deprovision:
  playbooks/deprovision.yml
  -.
  3.1.4.2.1. Bind.
  3.1.4.2.1.1. Preparation
  For a good starting point, create the necessary files for provision and deprovisioning PostgreSQL.
  A more in-depth example can be found at the PostgreSQL example APB.
  Initialize the APB using the
  --bindableoption:
  $ credentialstask.
  3.1.4.2.1.2. Executing From the UI:
  - Now, if you have not already done so, navigate to the project. You can see both your hello-world application and your PostgreSQL database. If you did not select to create a binding at provision time, you can also do so here with the Create binding link.
  After you the binding has been created, you must add the secret created by the binding into the application. First, navigate to the secrets on the Resources → Secrets page:
  Add the secret as environment variables:
  After this addition, you can return to the Overview page. The my-test application may still be redeploying from the configuration change. If so, wait until you can click on the route to view the application:
  After clicking the route, you will see the hello-world application has detected and connected to the my-pg database:
  3.1.4.2.2. Test
  Test actions are intended to check that an APB passes a basic sanity check before publishing to the service catalog. They are not meant to test a live service. OpenShift Container Platform provides the ability to test a live service using liveness and readiness probes, which you can add when provisioning.
  The actual implementation of your test is left to you as the APB author. The following sections provide guidance and best practices.
  3.1.4.2.2.1. Writing a Test Action
  To create a test action for your APB:
  - Include a playbooks/test.yml file.
  - Include defaults for the test in the playbooks/vars/ directory.
  my-apb/ ├── ... ├── playbooks/ ├── test.yml └── vars/ └── test_defaults.yml
  To orchestrate the testing of an APB, you should use the include_vars and include_role modules in your test.yml file:
  test.yml
  - name: test media wiki abp hosts: localhost gather_facts: false connection: local roles: - role: ansible.kubernetes-modules 1 install_python_requirements: no post_tasks: - name: Load default variables for testing 2 include_vars: test_defaults.yaml - name: create project for namespace openshift_v1_project: name: '{{ namespace }}' - name: Run the provision role. 3 include_role: name: provision-mediawiki-apb - name: Run the verify role. 4 include_role: name: verify-mediawiki-apb
  - 1
  - Load the Ansible Kubernetes modules.
  - 2
  - Include the default values needed for provision from the test role.
  - 3
  - Include the provision role to run.
  - 4
  - Include the verify role to run. See Writing a Verify Role.
  3.1.4.2.2.2. Writing a Verify Role
  A verify role allows you to determine if the provision has failed or succeeded. The verify_<name> role should be in the roles/ directory. This should be a normal Ansible role.
  my-apb/ ├── ... └── roles/ ├── ... └── verify_<name> ├── defaults └── defaults.yml └── tasks └── main.yml
  An example task in the main.yml file could look like:
  - name: url check for media wiki uri: url: "http://{{ route.route.spec.host }}" return_content: yes register: webpage failed_when: webpage.status != 200
  3.1.4.2.2.3. Saving Test Results
  The asb_save_test_result module can also be used in the verify role, allowing the APB to save test results so that the
  apb test command can return them. The APB pod will stay alive for the tool to retrieve the test results.
  For example, adding asb_save_test_result usage to the previous main.yml example:
  - name: url check for media wiki uri: url: "http://{{ route.route.spec.host }}" return_content: yes register: webpage - name: Save failure for the web page asb_save_test_result: fail: true msg: "Could not reach route and retrieve a 200 status code. Recieved status - {{ webpage.status }}" when: webpage.status != 200 - fail: msg: "Could not reach route and retrieve a 200 status code. Recieved status - {{ webpage.status }}" when: webpage.status != 200 - name: Save test pass asb_save_test_result: fail: false when: webpage.status == 200
  3.1.4.2.2.4. Running a Test Action
  After you have defined your test action, you can use the CLI tooling to run the test:
  $ apb test
  The test action will:
  - build the image,
  - start up a pod as if it was being run by the service broker, and
  - retrieve the test results if any were saved.
  The status of pod after execution has finished will determine the status of the test. If the pod is in an error state, then something failed and the command reports that the test was unsuccessful.
  3.2. Writing APBs: Reference
  3.2.1..
  3.2.2. Directory Structure
  3.2.3.
  3.2.3.1. Top-level Structure
  3.2.3.2. Metadata
  3.2.3.3. Plans
  Plans are declared as a list. This section explains what each field in a plan describes.
  3.2.3.4. Plan Metadata
  3.2.3.5. Parameters
  Each item in the
  parameters section can have several fields. The
  name field is required. The order of the parameters will be displayed in sequential order in the form in the OpenShift Container Platform.
  3.2.3.6. APB Spec Versioning
  The APB spec uses semantic versioning with the format of
  x.y where
  x is a major release and
  y is a minor release.
  The current spec version is
  1.0.
  3.2.3.6.1. Major Version
  The APB spec will increment the major version whenever an API breaking change is introduced to the spec. Some examples include:
  - Introduction or deletion of a required field.
  - Changing the YAML format.
  - New features.
  3.2.3.6.2. Minor Version
  The APB spec will increment the minor version whenever a non-breaking change is introduced to the spec. Some examples include:
  - Introduction or deletion of an optional field.
  - Spelling change.
  - Introduction of new options to an existing field.
  3.2.4.
  3.2.5.
  3.2.6. Working With Common Resources
  This section describes a list of common OpenShift Container Platform resources that are created when developing APBs. See the Ansible Kubernetes Module for a full list of available resource modules.
  3.2.6.1. Service
  The following is a sample Ansible task to create a service named hello-world. The
  namespace variable in an APB will be provided by the OAB when launched from the web console.
  Provision
  - name: create hello-world service k8s_v1_service: name: hello-world namespace: '{{ namespace }}' labels: app: hello-world service: hello-world selector: app: hello-world service: hello-world ports: - name: web port: 8080 target_port: 8080
  Deprovision
  - k8s_v1_service: name: hello-world namespace: '{{ namespace }}' state: absent
  3.2.6.2. Deployment Configuration
  The following is a sample Ansible task to create a deployment configuration for the image docker.io/ansibleplaybookbundle/hello-world which maps to service hello-world.
  Provision
  -
  Deprovision
  - openshift_v1_deployment_config: name: hello-world namespace: '{{ namespace }}' state: absent
  3.2.6.3. Route
  The following is an example of creating a route named hello-world which maps to the service hello-world.
  Provision
  - name: create hello-world route openshift_v1_route: name: hello-world namespace: '{{ namespace }}' spec_port_target_port: web labels: app: hello-world service: hello-world to_name: hello-world
  Deprovision
  - openshift_v1_route: name: hello-world namespace: '{{ namespace }}' state: absent
  3.2.6.4. Persistent Volume
  The following is an example of creating a persistent volume claim (PVC) resource and deployment configuration that uses it.
  Provision
  #
  Deprovision
  - openshift_v1_deployment_config: name: hello-world-db namespace: '{{ namespace }}' state: absent - k8s_v1_persistent_volume_claim: name: hello-world-db namespace: '{{ namespace }}' state: absent
  3.2.7.
  3.2.8. Working with Remote Clusters
  When developing APBs, there are a few factors which could prevent the developer from using the full development lifecycle that the
  apb tooling offers. Primarily, these factors are:
  - Developing against an OpenShift Container Platform cluster that exists on a remote host.
  - Developing APBs on a machine that does not have access to the docker daemon.
  If a developer meets any of these criteria, use the following workflow to publish images to the internal OpenShift Container Platform registry so that the broker can bootstrap the image (the process of loading APB specs into the broker). The following sections show how to do these steps with the
  apb tooling and without.
  3.2.8.1. Pushing APBs
  To use the
  apb push command when working with a remote OpenShift Container Platform OpenShift Container Platform registry with your built APB image.
  This is normally handled by the
  apb pushcommand. In order to build your image without using the
  dockerCLI, you can take advantage of the S2I functionality of OpenShift Container Platform. openshift-ansible-service-broker NAME HOST/PORT PATH SERVICES PORT TERMINATION WILDCARD asb-1338 asb-1338-openshift }Note
  The
  oc whoami -tcommand should return a token and the authenticated user must have permissions as described in Access Permissions..
  3.2.8.2. OpenShift Container Platform
  3.2.9. Working With the Restricted SCC
  When building an OpenShift Container Platform OpenShift Container Platform
  3.2.10.
  3.2.11..
  See Kubernetes documentation for more details on pod termination.