Increasing business demands are driving the need for automation to support rapid, yet stable and reliable deployments of applications and supporting infrastructure.  Kubernetes and cloud-native tools have quickly emerged as the enabling technologies essential for organizations to build the scalable open hybrid cloud solutions of tomorrow. This is why Red Hat has developed the Red Hat OpenShift Container Platform (OCP) to enable enterprises to meet these emerging business and technical challenges. Red Hat OpenShift brings together Kubernetes and other cloud-native technologies into a single, consistent platform that has been fine-tuned and enhanced for the enterprise. 

There are many similarities to how Red Hat OpenShift and Red Hat Ansible Automation Platform approach their individual problem domains that make a natural fit when we bring the two together to help make hard things easier through automation and orchestration.

We’ve released the Ansible Content Collection for Red Hat OpenShift (redhat.openshift) to enable the automation and management of Red Hat OpenShift clusters. This is the latest edition to the certified content available to subscribers of Red Hat Ansible Automation Platform in the Ansible Automation Hub.

In this blog post, we will go over what you’ll find in redhat.openshift and how it works together with the Ansible Content Collection for Kubernetes.

Built on Kubernetes

Kubernetes is at the heart of the Red Hat OpenShift Container Platform. The effort that resulted in the creation of this collection began with developing a stable and supported release of Kubernetes automation content from upstream sources that Red Hat is known for. We started by looking at what was in community.kubernetes and elsewhere. In doing so, we recognized that community.kubernetes contained content and functionality for two distinct user groups with different needs — those working with Kubernetes and those working with Red Hat OpenShift. While those working with Red Hat OpenShift were able to effectively use the Kubernetes content, they also needed more to take full advantage of what that platform provided on top of Kubernetes. 

So we made the decision to split out Red Hat OpenShift-specific content and functionality into its own collection. It will take some release cycles to completely perform this transition, but it has begun with the release of this collection and the kubernetes.core collection we covered in a recent blog post.

Here is what we moved under the redhat.openshift collection:

  • the openshift inventory plugin
  • the oc connection plugin (from community.general)
  • the k8s_auth module (renamed to openshift_auth)
  • all associated module utilities and docs

The idea here is when it comes to Red Hat OpenShift automation development, you will utilize both the kubernetes.core and redhat.openshift collections together rather than two entirely separate and mostly redundant collections. When it comes to native Kubernetes and Helm 3 automation, you’ll utilize what’s in kubernetes.core and when you need the enhancements that Red Hat OpenShift provides, you’ll use what’s in redhat.openshift.

While the migrated Red Hat OpenShift-specific content still remains in kubernetes.core for now, all development and maintenance has been moved to the upstream project community.okd that the redhat.openshift is cut from. It is planned to deprecate the Red Hat OpenShift-specific content in the Kubernetes Collection in the near future.

The k8s Module: What’s in a Name?

We also extracted Red Hat OpenShift-specific logic in the underlying k8s  module code for resources like Projects and DeploymentConfigs not found in the base Kubernetes distribution. 

This particular aspect of our work required some extra thought and planning. The initial proposal was to create a separate module called “oc”, but that was deemed too misleading in that this module is not the functional equivalent of the oc command line tool. Another proposal was floated to call this module “openshift”, but after more consideration, we thought the name would be an unnecessary burden on automation developers. The “openshift” module would do everything the k8s module does with the same interface, but with the added special handling for Red Hat OpenShift-specific resources. So developers would need to switch between, or even search and replace, the k8s  and openshift module names in their plays depending on what system they were automating. Not ideal, and potentially annoying.

A more elegant solution was proposed: call the redhat.openshift module “k8s” like its counterpart. Ansible Automation Platform had introduced namespaces as part of its support of Ansible Content Collections in version 2.9 of the base engine. With this we could have a k8s module in both collections. This gave developers more flexibility and less burden in switching between the two implementations by using fully-qualified namespaces or the collections keyword in a play. We thought this was a more elegant and Ansible-native way of handling the overlap, while still providing developers the control they need with minimal overhead.

New Modules

A lot of work in getting this initial release out was migrating, organizing and setting up the project, but that wasn’t the only thing. With existing Red Hat OpenShift content split out from the kubernetes.core collection, we started to turn our attention towards creating a more complete and comprehensive collection of automation tools for Red Hat OpenShift. We also recognized doing that would need to happen over multiple releases so our initial focus was on making the most common Red Hat OpenShift automation tasks easier. 

As mentioned, we needed to add some additional logic in this collection’s k8s module on top of the one in kubernetes.core. The idea here was to make this logic transparent to the end user to work as they expect from any native Kubernetes resources such as Projects and ProjectRequest resources. 

Another such case are DeploymentConfig resources in Red Hat OpenShift and how their close relationship to ImageStreams is managed by the platform. This is an inconsequential thing—that is, until you hit it and it becomes a big deal. 

The scenario we addressed is where an ImageStream resource updated the image field of the DeploymentConfig, which made it so that when you went to “idempotently” update that DeploymentConfig, you would overwrite the value of the image set by the ImageStream. The Red Hat OpenShift controller would then immediately set the image field back to the ImageStream reference, and Ansible Automation Platform and Red Hat OpenShift would wrestle back and forth like that in perpetuity. Not good. 

What is good is that users of the redhat.openshift.k8s module don’t have to worry about this. We added logic that intentionally avoids updating the image field when it is being managed by an ImageStream, preventing the loop from ever starting.

Let’s look at some example scenarios of the other new modules in this collection and how you might use them. Here, we’re using the fully qualified namespace of the Certified Content Collection available to Ansible Automation Platform subscribers in Automation Hub. If you are working with the community supported upstream project release, use community.okd instead. 

Scenario: Process an OpenShift Template

A template describes a set of objects that can be parameterized and processed to produce a list of objects for creation by Red Hat OpenShift. Template resources themselves can be managed declaratively through the k8s module, but rendering and application of the template is an imperative action we wanted to address so we developed the openshift_process module. This module is analogous to oc process command.

Templates can be provided inline, from a file, or specified by name and namespace in the cluster and can optionally be applied to the cluster. In this first example, we process a template that already exists in the cluster and capture the result for further operations:

- name: Process a template in the cluster
  redhat.openshift.openshift_process:
    name: nginx-example
    namespace: openshift
    parameters:
      NAMESPACE: openshift
      NAME: test123
    state: rendered
  register: result

- name: Create the rendered resources using apply
  redhat.openshift.k8s:
    namespace: default
    definition: '{{ item }}'
    wait: yes
    apply: yes
  loop: '{{ result.resources }}'

We added an option to give automation developers the flexibility and convenience to work how they needed to work. Here, we read the template and parameters from the local file system and, as an added convenience, the module can apply a rendered template to the cluster in one task:

- name: Process a local template and create the resources
  redhat.openshift.openshift_process:
    src: files/example-template.yaml
    parameter_file: files/example.env
    namespace_target: default
    state: present

Scenario: Expose a Service as an OpenShift Route

We developed the openshift_route module to look up a Service and create a new Route based on it. This is analogous to oc expose and oc create route commands for creating Routes, but does not support creating Services. Exposing Services is also a baseline Kubernetes function, so that support is eventually better suited for the kubernetes.core collection

In this example, we create a deployment and service before using the openshift_route module to expose the service externally.

- name: Create Service for the hello-world deployment
  redhat.openshift.k8s:
    definition:
      apiVersion: v1
      kind: Service
      metadata:
        name: hello-kubernetes
        namespace: default
      spec:
        ...

- name: Expose the insecure hello-kubernetes service externally
  redhat.openshift.openshift_route:
    service: hello-kubernetes
    namespace: default
    insecure_policy: allow
  register: route

Going Forward (Next Steps)

Combining this collection with kubernetes.core, Ansible users can better manage applications on Kubernetes clusters and on existing IT and with faster iterations and easier maintenance. Ansible lets you connect the different technologies that are ultimately needed to be successful in your efforts with cloud-native technologies that Red Hat OpenShift delivers. 

We’ve delivered a solid start to what can be achieved when you combine Ansible Automation Platform with the OpenShift Container Platform. We’re always looking to improve to help users like you get things done in more simplified, faster ways. 

Try out the redhat.openshift collection and let us know what you’d like to see added next.

If you want to dive deeper into the topic of Ansible and Kubernetes, you can also check out these resources: