Ansible Plugin

The Ansible plugin enables you to configure Cloudify resources with Ansible and provides an agentless method for executing operations on hosts.

Playbook Run Operation

Similar to the Script Plugin and the Fabric Plugin, there is no one node type associated with the Ansible plugin. Instead, you modify existing node types to perform one or more of their lifecycle operations using the Ansible plugin and any additional inputs that you provide.

Operations

In addition, you can provide additional key-word args parameters to the AnsiblePlaybookFromFile class, such as options_config.

NOTE there is a special handling for “ANSIBLE_FACT_PATH” environment variable that you can pass to ansible_env_vars property, where you could add custom .fact files -which could be executable that Ansible expect JSON on stdout. If you include files that are not executable and simply contain raw JSON then Ansible will just read them and use the data inside - when gather facts is triggered they will be part of runtime_properties.facts.ansible_local.{fact_file_name}

For example you could do something like this inside your playbook:

- hosts: all
  connection: local
  tasks:
    - name: "Set fact: output dictionary"
      set_fact:
        output_dict:
          just_a_test: "my value from ansible gathered fact !!"
    - name: "Creates facts directory if it doesn't exist"
      file:
        path: "{{ lookup('ansible.builtin.env', 'ANSIBLE_FACT_PATH') }}"
        state: directory
    - name: "Insert custom fact file"
      copy:
        content: "{{ output_dict | to_nice_json }}"
        dest: "{{ lookup('ansible.builtin.env', 'ANSIBLE_FACT_PATH') }}/custom.fact"
        mode: 0644

Inventory Sources

** There are also two methods for generating the sources parameter automatically, see using compute nodes and Relationships.

For all inventory sources, we require these parameters:

In addition, we handle these parameters if provided (and highly recommend them):

For more information on the sources format in YAML, see Ansible Inventory YAML.

Using Compute Nodes

If your operation is mapped on the lifecycle operation of a node template derived from cloudify.nodes.Compute, we will attempt to generate the sources parameter from the node properties.

Example Compute Node

Provision some component on a VM.

  compute_and_component:
    type: cloudify.nodes.Compute
    properties:
      ip: { get_input: ip }
      agent_config:
        install_method: none
        key: { get_input: private_key_path }
        user: { get_input: username }
    interfaces:
      cloudify.interfaces.lifecycle:
        start:
          implementation: ansible.cloudify_ansible.tasks.run
          inputs:
            site_yaml_path: resources/component/site.yaml

Using Relationships

Use the cloudify.ansible.relationships.connected_to_host relationship defined in the plugin to populate the sources parameter, if the target node is derived from cloudify.nodes.Compute.

Example Relationship Usage

  component:
    type: cloudify.nodes.Root
    interfaces:
      cloudify.interfaces.lifecycle:
        start:
          implementation: ansible.cloudify_ansible.tasks.run
          inputs:
            site_yaml_path: resources/component/site.yaml
            sources: { get_attribute: [ SELF, sources ] }
    relationships:
      - type: cloudify.ansible.relationships.connected_to_host
        target: compute

  compute:
    type: cloudify.nodes.Compute
    properties:
      ip: { get_input: ip }
      agent_config:
        install_method: none
        key: { get_input: private_key_path }
        user: { get_input: username }

More Examples

Basic usage with no special node or relationship type behavior.

  my_node:
    type: cloudify.nodes.Root
    interfaces:
      cloudify.interfaces.lifecycle:
        create:
          implementation: ansible.cloudify_ansible.tasks.run
          inputs:
            site_yaml_path: resources/my_ansible_playbook/site.yaml
            sources:
              webservers:
                hosts:
                  web:
                    ansible_host: { get_input: ip }
                    ansible_user: { get_input: username }
                    ansible_ssh_private_key_file: { get_input: private_key_path }
                    ansible_become: true
                    ansible_ssh_common_args: '-o StrictHostKeyChecking=no'

Passing run_data at runtime:

  component:
    type: cloudify.nodes.Root
    interfaces:
      cloudify.interfaces.lifecycle:
        create:
          implementation: ansible.cloudify_ansible.tasks.run
          inputs:
            site_yaml_path: resources/my_ansible_playbook/site.yaml
            sources:
              foo_group:
                hosts:
                  foo_host:
                    ansible_host: { get_input: ip }
                    ansible_user: { get_input: username }
                    ansible_ssh_private_key_file: { get_input: private_key_path }
                    ansible_become: true
                    ansible_ssh_common_args: '-o StrictHostKeyChecking=no'
            run_data:
              foo: bar

Node Types

cloudify.nodes.ansible.Executor

Execute playbook lifecycle as stand-alone node template.

cloudify.nodes.ansible.Playbook

Stores Ansible inputs in runtime properties.

Example on how to use the reload workflow :

  hello-world:
    type: cloudify.nodes.ansible.Playbook
    properties:
      playbook_source_path: {get_input: playbook_source_path}
      playbook_path: {get_input: playbook_path}
      # save_playbook: true
    relationships:
      - type: cloudify.ansible.relationships.run_on_host
        target: vm
        source_interfaces:
          cloudify.interfaces.relationship_lifecycle:
            establish:
              inputs:
                sources:
                  vms:
                    hosts:
                      vm:
                        ansible_host: { get_attribute: [ vm, ip ] }
                        ansible_user: { get_input: agent_user }
                        ansible_ssh_private_key_file: { get_secret: agent_key_private }
                        ansible_become: True
                        ansible_ssh_common_args: -o StrictHostKeyChecking=no

we can trigger reload workflow like this, providing a new path to playbook :

cfy executions start reload_ansible_playbook -d {deployment_id} -p '{"playbook_source_path": "https://github.com/cloudify-community/blueprint-examples/releases/download/latest/hello-world-example.zip","playbook_path":"apache2/playbook.yaml","node_ids": ["hello-world"]}'