# Orchestrating Connectware with Ansible

This guide shows you how to use Ansible to set up and manage a local Connectware instance. You will learn how to deploy Connectware, install services, and manage the instance lifecycle using infrastructure as code.

## Prerequisites

Before starting, ensure you have the following installed on your system:

* **Ansible** (latest version)
* **Docker**
* **Docker Compose**
* **A valid Connectware license key**

This guide assumes you are familiar with:

* **Connectware** and its service concept
* **Docker fundamentals**
* **Ansible basics** ([ansible.com - Getting started with Ansible](https://docs.ansible.com/ansible/latest/getting_started/index.html))

## What is the Connectware Ansible Collection?

Ansible is an open-source infrastructure automation tool that enables infrastructure as code. Cybus provides a specialized Ansible Collection with custom modules designed to manage every aspect of Connectware deployments.

The collection provides the following modules to help you manage Connectware resources:

| Module     | Purpose                       |
| ---------- | ----------------------------- |
| `instance` | Manages Connectware instances |
| `service`  | Manages Connectware services  |
| `role`     | Manages Connectware roles     |
| `user`     | Manages Connectware users     |
| `agent`    | Manages agent instances       |

## 1. Installing the Ansible Collection

* Install the Connectware Ansible Collection from Ansible Galaxy:

```bash
ansible-galaxy collection install cybus.connectware
```

### Verifying the Installation

```bash
ansible-galaxy collection list
```

### Updating an Existing Installation

```bash
ansible-galaxy collection install cybus.connectware --force
```

## 2. Creating Your First Playbook

### Setting Up the Project

1. Create a new project directory:

{% code lineNumbers="true" %}

```bash
mkdir connectware-ansible-demo
cd connectware-ansible-demo
```

{% endcode %}

2. Create a playbook file named `playbook.yaml`:

{% code lineNumbers="true" %}

```yaml
---
- name: Connectware Deployment
  hosts: localhost

  tasks:
    - name: Deploy Connectware instance
      cybus.connectware.instance:
        license: 'YOUR_LICENSE_KEY_HERE'
        install_path: ./
```

{% endcode %}

**Important:** Replace `YOUR_LICENSE_KEY_HERE` with your actual Connectware license key.

### Understanding the Playbook Structure

* **Play**: "Connectware Deployment" runs on `localhost`
* **Task**: "Deploy Connectware instance" uses the `cybus.connectware.instance` module
* **Parameters**:
  * `license`: Your Connectware license (required)
  * `install_path`: Directory for deployment files (current directory)

### Exploring Module Options

* View all available parameters for the instance module:

{% code lineNumbers="true" %}

```bash
ansible-doc cybus.connectware.instance
```

{% endcode %}

## 3. Deploying Connectware

Running this playbook will install and start Connectware on your local system, making it accessible via `https://localhost`.

* Execute the following playbook to deploy Connectware:

{% code lineNumbers="true" %}

```bash
ansible-playbook playbook.yaml
```

{% endcode %}

**Expected Output**

After running the playbook, you should see output like this:

{% code lineNumbers="true" %}

```bash
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [Connectware Deployment] ***************************************************************************

TASK [Gathering Facts] ***************************************************************************
ok: [localhost]

TASK [Deploy Connectware] ***************************************************************************
changed: [localhost]

PLAY RECAP ***************************************************************************
localhost: ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

{% endcode %}

Notice that the state of the `Deploy Connectware` task is marked as `changed`. This indicates that Connectware is now running and is reachable at `https://localhost`.

In addition to the log output, you should now find two new files next to `playbook.yaml`. One is the Docker Compose file managing the Connectware containers, and the other contains additional configuration.

**Result**

* Connectware is now running and accessible at: `https://localhost`
* Two new files were created:
  * `docker-compose.yml`: Container orchestration file
  * A configuration file with additional settings

### Verifying Idempotency

* Run the playbook again to verify that no changes occur:

{% code lineNumbers="true" %}

```bash
ansible-playbook playbook.yaml
```

{% endcode %}

Notice the task shows `ok` instead of `changed`, confirming the desired state is maintained.

## 4. Deploying Services

The Connectware Ansible Collection provides flexible options for deploying services. You can deploy services one at a time (synchronous) or multiple services in parallel (asynchronous) depending on your needs.

### Creating a Service Definition

* Create a file named `example-service.yml` with a basic service configuration:

{% code lineNumbers="true" %}

```yaml
---
description: Example service demonstrating MQTT connection

metadata:
  name: example_service

resources:
  mqttConnection:
    type: Cybus::Connection
    properties:
      protocol: Mqtt
      connection:
        host: !ref Cybus::MqttHost
        port: !ref Cybus::MqttPort
        scheme: mqtt
        username: !ref Cybus::MqttUser
        password: !ref Cybus::MqttPassword
```

{% endcode %}

This service creates a connection to the internal Connectware MQTT broker.

### Sequential Deployment

For deploying individual services or when you need to wait for each deployment to complete before proceeding, use the standard `cybus.connectware.service` module.

* Add a service installation task to your `playbook.yaml`:

{% code lineNumbers="true" %}

```yaml
---
- name: Connectware Deployment
  hosts: localhost

  tasks:
    - name: Deploy Connectware instance
      cybus.connectware.instance:
        license: 'YOUR_LICENSE_KEY_HERE'
        install_path: ./

    - name: Install example service
      cybus.connectware.service:
        id: example_service
        commissioning_file: ./example-service.yml
```

{% endcode %}

**Key Parameters:**

* `id`: Unique identifier for the service (required)
* `commissioning_file`: Path to the service definition file (required)

**Deploying:**

```bash
ansible-playbook playbook.yaml
```

The output should show the service installation as `changed`. Verify the service is installed by visiting the Connectware UI at: `https://localhost/admin/#/services`.

Learn more about the service module:

```bash
ansible-doc cybus.connectware.service
```

### Asynchronous Deployment

For large-scale deployments where you need to install multiple services simultaneously, use the `cybus.connectware.service_async` module with Ansible's async capabilities. This significantly speeds up rollouts by deploying services in parallel.

**Example: Deploying Multiple Services in Parallel**

```yaml
---
- name: Connectware Deployment
  hosts: localhost

  tasks:
    - name: Deploy Connectware instance
      cybus.connectware.instance:
        license: 'YOUR_LICENSE_KEY_HERE'
        install_path: ./

    # Start multiple service deployments in parallel
    - name: Deploy services in parallel
      cybus.connectware.service_async:
        id: 'service_{{ item }}'
        commissioning_file_b64: "{{ lookup('file', './example-service.yml') | b64encode }}"
      loop: '{{ range(1, 11) | list }}'
      async: 300
      poll: 0
      register: service_jobs

    # Wait for all deployments to finish
    - name: Wait for service deployments to complete
      async_status:
        jid: '{{ item.ansible_job_id }}'
      loop: '{{ service_jobs.results }}'
      register: async_results
      until: async_results.finished
      retries: 30
      delay: 10
```

**Key Parameters:**

* `id`: Unique identifier for each service (required).
* `commissioning_file_b64`: Base64-encoded service definition (required for async).
* `async`: Maximum time (in seconds) allowed for the task.
* `poll: 0`: Tells Ansible not to wait and to start the next task immediately.

**How It Works:**

1. The first task starts all service deployments in parallel without waiting.
2. The `async_status` task checks the status of each deployment.
3. The `until` condition ensures the playbook waits for completion.
4. Idempotency is maintained: services are only deployed or updated when necessary.

Learn more about the async service module:

```bash
ansible-doc cybus.connectware.service_async
```

## 5. Managing Instance Lifecycle

### Stopping Connectware

* To stop the Connectware instance, add a task with the `stopped` state:

{% code lineNumbers="true" %}

```yaml
- name: Stop Connectware instance
  cybus.connectware.instance:
    state: stopped
    license: 'YOUR_LICENSE_KEY_HERE'
    install_path: ./
```

{% endcode %}

After running this playbook, Connectware will be stopped and no longer accessible.

### Available States

The instance module supports different states:

* `started` (default): Ensures Connectware is running
* `stopped`: Ensures Connectware is stopped
* `absent`: Removes the Connectware installation


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.cybus.io/2-1-2/guides/ansible/orchestrating-connectware-with-ansible.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
