Turning Ansible Playbooks into Self-Service Workflows with Cloudify
When I speak with customers, one of the most common goals that they describe is making their existing automation available to their internal developers and customers in a self-service way. Most organizations invested countless hours in developing scripts and playbooks for performing common “Day 2” operations, such as patching servers or triggering backup jobs. Empowering internal customers to execute and consume these workflows without the involvement of a DevOps or internal IT team is an excellent way to reduce lead time and boost overall satisfaction with an organization’s IT systems.
If you have tried Cloudify or viewed any of our demos, please link to our video page, then you are familiar with how Cloudify can unify your existing tools into self-service, certified environments that your customers can deploy. However, Cloudify is much more than just a deployment tool. Cloudify is capable of managing the entire lifecycle of an environment, from Day 1 provisioning, through Day 2 operations and into final decommissioning.
In this article, I’ll show you how you can turn an Ansible playbook for patching a server into an Ansible self-service workflow. Custom workflows can then be easily exposed to your developers via the UI, API, or CLI for quick consumption using the method that is best for them.
Day 1 – Deploying the Environment
The environment used in this article consists of an EC2 instance running Nginx. The Cloudify Terraform plugin deploys all of the infrastructure resources, including networking and the EC2 instance, into AWS. Nginx is then installed and configured using Cloudify’s Ansible plugin.
The environment blueprint and supporting resources are available on the Cloudify Community GitHub. You can deploy the environment via the Cloudify UI or via the CLI in a single command:
cfy blueprint upload -b Ansible-Custom-Workflow https://github.com/cloudify-community/ansible-custom-workflow/archive/refs/heads/master.zip
Day 2 – An Update Workflow
Many organizations have existing playbooks that can be turned into Cloudify workflows. For example, the Ansible playbook below performs full patching on a server:
---
- hosts: all
become: yes
tasks:
- name: Apply full patches
package:
name: "*"
state: latest
Making this playbook available as a custom workflow involves two simple steps:
- Adding the playbook as a custom interface operation on a node in the environment
- Exposing this operation via a custom workflow
Interface operations map logical tasks, such as updating a server, to operations that can be executed by Cloudify, such as running an Ansible playbook. Interfaces are defined on nodes in the blueprint topology, and they execute individual tasks that are relevant to the node. For example, an interface operation for a Terraform module might run Terraform apply.
Workflows represent more complex automation, and they can be composed of multiple interface operations. Workflows are defined within plugins or at a blueprint level. Continuing with Terraform as an example, a workflow for Terraform may consist of running Terraform linting operations before running Terraform apply. Each step in the workflow can be an interface operation, and the workflow executes them in order.
In this article, I define the custom_actions.patch_server interface to run the Ansible playbook. The operation is defined on the Terraform module that represents the EC2 instance:
vm:
type: cloudify.nodes.terraform.Module
...
interfaces:
...
custom_actions:
patch_server:
implementation: ansible.cloudify_ansible.tasks.run
inputs:
playbook_path: playbooks/patch_server.yaml
sources: { get_attribute: [ SELF, sources ] }
...
This operation can be executed natively from Cloudify using the “Execute operation” workflow. However, that would require the user to enter the name of the operation each time they want to run it. To make this easier, I expose it as a custom workflow using Cloudify’s custom workflow plugin:
workflows:
PatchServer:
mapping: cloudify_custom_workflow.cloudify_custom_workflow.tasks.customwf
parameters:
nodes_to_runon:
default:
- vm
operations_to_execute:
default:
- custom_actions.patch_server
Day 2 – Running the Workflow
Once the workflow has been defined in the blueprint, it can be easily run via the UI, CLI, or API. The UI exposes the workflow under the Execute workflow > Cloudify custom workflow menu on the page for a deployment:
Similarly, the CLI allows the user to trigger the workflow via a single command by specifying the deployment ID and workflow name. The CLI also streams logs to the console, making it easy to follow the progress of the workflow and troubleshoot any issues with the Ansible playbook:
$ cfy execution start -d ef794537-a71a-4f90-877f-5f4d50e67234 PatchServer
Executing workflow `PatchServer` on deployment `ef794537-a71a-4f90-877f-5f4d50e67234` [timeout=900 seconds]
2022-08-10 15:34:21.109 CFY <ef794537-a71a-4f90-877f-5f4d50e67234> Starting 'PatchServer' workflow execution
2022-08-10 15:34:21.138 LOG <ef794537-a71a-4f90-877f-5f4d50e67234> INFO: Starting Custom Workflow
2022-08-10 15:34:21.163 LOG <ef794537-a71a-4f90-877f-5f4d50e67234> INFO: Nodes not in Json trying directly
2022-08-10 15:34:21.189 LOG <ef794537-a71a-4f90-877f-5f4d50e67234> INFO: operations not in Json trying directly
2022-08-10 15:34:21.213 LOG <ef794537-a71a-4f90-877f-5f4d50e67234> INFO: Nodes ['vm'] on Operations ['custom_actions.patch_server']
2022-08-10 15:34:21.336 CFY <ef794537-a71a-4f90-877f-5f4d50e67234> [vm_rrdueq] Starting to custom_actions.patch_server on instance vm_rrdueq of node vm
2022-08-10 15:34:21.361 CFY <ef794537-a71a-4f90-877f-5f4d50e67234> [vm_rrdueq] Sending task 'cloudify_ansible.tasks.run'
2022-08-10 15:34:23.011 LOG <ef794537-a71a-4f90-877f-5f4d50e67234> [vm_rrdueq.patch_server] INFO: Process created, PID: 16957
...
Triggering the workflow orchestrates a run of the Ansible playbook against the VM. The UI or CLI will reflect the completed workflow once the playbook is done running, and the server will be fully patched:
[root@ip-10-10-4-129 centos]# yum update
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: download.cf.centos.org
* epel: d2lzkl7pfhq30w.cloudfront.net
* extras: download.cf.centos.org
* updates: download.cf.centos.org
No packages marked for update
Wrapping Up
Undertaking a project to enable developer self-service often focuses on orchestrating the “Day 1” deployment activities for provisioning a new environment. However, continuously updating and maintaining the environment are equally important aspects of a developer’s daily workflow. Cloudify has the ability to orchestrate the full environment lifecycle by taking the tools that you are already using, such as Ansible, and exposing them in a self-service way to your internal customers. In this article, you saw how a simple Ansible playbook can be exposed to a user in an easy, self-service manner.
Interested in learning more about Cloudify? Sign up for our free trial or contact us to book a demo.
You be interested in reading:
Tanzu grid with Kubernetes explained