Skip to content

Collections for the EDA Applications#

Note

Beta version. Collections content may change.

Nokia EDA is an extensible infrastructure automation framework. Its extensibility is powered by the EDA Applications that can be developed by anyone, installed anytime, and used by everyone.

Applications extend EDA's functionality by adding new abstracted resources, dashboards, workflows, alarms. Given that the EDA Applications are pluggable and can be added/removed at any time, we offer Ansible Collections per each application to match the extensibility of the API layer. An Ansible user would install the collections for the apps they plan to use via Ansible and use the relevant module plugins provided by the collections.

Nokia provides Ansible collections for the applications available in Nokia's EDA built in apps catalog that EDA users get by default when they install the platform. For custom, user-provided applications, we will offer the instrumentation to generate the Ansible modules based on the application's OpenAPI specification in the future.

Installation#

Installation instructions provided in the main readme and are universal for all collections.

Collection structure#

Each application collection contains module plugins that are designed to manage the lifecycle of the resources offered by the application. In a nutshell, the app collection provides the modules for the following tasks:

  1. list metadata information about the available API versions and the resources the given application provides
  2. create, update, query, and delete the resources offered by the application
  3. list the revision history of a given resource and fetch the info about the deleted instances of the resource

We will explain the typical modules you will see in each collection based on the Siteinfo collection and the modules it provides.

Module Name Example Description
appgroup nokia.eda_siteinfo_v1alpha1.appgroup lists available API versions the given API group provides
resourcelist nokia.eda_siteinfo_v1alpha1.resourcelist lists the resources the given application provides
<resource-name> nokia.eda_siteinfo_v1alpha1.banner create, update, query, and delete the resources offered by the application
<resource-name>list nokia.eda_siteinfo_v1alpha1.bannerlist fetch all instance of a given resource type from all or a given namespace
<resource-name>_deleted nokia.eda_siteinfo_v1alpha1.banner_deleted list deleted instances of a given resource
<resource-name>_revisions nokia.eda_siteinfo_v1alpha1.banner_revisions list revision history of a given resource

Metadata information#

Each application collection provides two modules to extract the metadata about the supported api versions and resources offered by the application:

  • nokia.eda_<app-name>_<app-api-version>.appgroup: lists available API versions the given API group provides
  • nokia.eda_<app-name>_<app-api-version>.resourcelist: lists the API resources the given API group/version provides

API group, App name and API version

EDA adheres to the Kubernetes Resource Model when defining its own resources, the groups they belong to, and the version of the API. This warrants some familiarity with the terms being used in the documentation.

In the FQCN like nokia.eda_siteinfo_v1alpha1 you have:

  • siteinfo.eda.nokia.com - the API group. For Nokia-provided apps, the API Group is a combination of the app name and eda.nokia.com string that, when combined, provides a DNS-like name.
  • v1alpha1 - the API version in that group

API versions#

In future EDA will support multiple API versions of the same app to interact with the resources offered by the application. This is especially useful during the transition period where a new API has been announced, but the old API is still in use and allows users to transition gradually.

To lay the foundation for this, an appgroup module cab used to list the available API versions for the application. For example, to see what API versions of the Siteinfo application group are available:

- name: Get Banner appgroup
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Get Banner app group
      nokia.eda_siteinfo_v1alpha1.appgroup:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response

The output shows that the Siteinfo application provides only one group/version - siteinfo.eda.nokia.com/v1alpha1:

response:
  changed: false
  failed: false
  result:
    apiVersion: v1
    kind: ApiGroup
    name: siteinfo.eda.nokia.com
    preferredVersion:
      groupVersion: siteinfo.eda.nokia.com/v1alpha1
      version: v1alpha1
    versions:
      - groupVersion: siteinfo.eda.nokia.com/v1alpha1
        version: v1alpha1
  status: 200

Available resources#

To list the available resources that an application provides, you would use the resourcelist module from the collection.

- name: Get Siteinfo resource list
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Get Siteinfo resource list
      nokia.eda_siteinfo_v1alpha1.resourcelist:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: false
  failed: false
  result:
    apiVersion: v1
    groupVersion: siteinfo.eda.nokia.com/v1alpha1
    kind: ApiResourceList
    resources:
      - kind: Banner
        name: banners
        namespaced: true
        readOnly: false
        singularName: banner
        uiCategory: Site Profiles
  status: 200

As per the output, the Siteinfo application identified by the group/version siteinfo.eda.nokia.com/v1alpha1 provides a single resource - Banner that is namespaced and can be found in the UI under the Site Profiles category.

Resources and CRUD operations#

Most often you will find yourself using app collections to perform Create/Read/Update/Delete (CRUD) operations on the resources provided by the application. Like creating an interface, getting the configured fabrics, removing a banner and so on.

Transaction API vs CRUD operations

Creating, Updating and Deleting resources via the modules provided by each application collection is done by using the REST API endpoint that each application exposes for their resources. This results in every create/update/delete action to become a transaction with an individual change of a resource.

While using the individual modules from the collection to manage resources is not wrong, you miss on features that the Transaction API brings such as combining multiple resources in an atomic transaction, running the dry-run and collecting the diffs.

Learn how to use Transaction module from the Core collection to fully leverage Nokia EDA powers.

For each resource in the application group, the collection provides the following modules:

  • <resource-name>, e.g. banner: to manage the lifecycle of a singular resource. Supports create, update, query (read), and delete operations
  • <resource-name>list, e.g. bannerlist: to fetch a several instances of the resource in a namespace or across all namespaces. Supports only query/read operation.

For example, if you take a look at the Siteinfo application and the modules it provides, you will see the following entries in the table:

  • nokia.eda_siteinfo_v1alpha1.banner
  • nokia.eda_siteinfo_v1alpha1.bannerlist

These modules allow you to perform CRUD operations on the resource, Banner in this case. Let us cover these operations in detail in the next section.

Create#

To create a resource, use the nokia.eda_<app-name>_<app-api-version>.<resource-name> module. In case of the Siteinfo application, you would use the nokia.eda_siteinfo_v1alpha1.banner module to create an abstracted Banner.

The argument specification for every application module is the same and follows the pattern depicted below:

- name: Create a resource
  nokia.eda_<app-name>_<app-api-version>.<resource-name>:
    base_url: "{{ eda_api_url }}"
    auth_token: "Bearer {{ eda_access_token }}"
    resource:
      metadata:
        name:
        namespace:
        # other optional resource metadata
      spec:
        # resource spec
    state: present

As you can see, the module argument specification simply embeds the resource body with its metadata and spec fields1 under the .resource block. A user can simply copy the YAML from the EDA UI and paste it in the playbook, or craft the payload manually based on the OpenAPI spec or Resource Browser of a given resource.

The state: present in the module argspec instructs the module to ensure the resource is created or updated to match the desired state defined in the playbook.

- name: Create a Banner
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Create a banner
      nokia.eda_siteinfo_v1alpha1.banner:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        resource:
          metadata:
            labels:
              some-label: ansible-demo
            namespace: eda
            name: demo-banner
          spec:
            loginBanner: "This is a demo banner provisioned by Ansible"
            nodeSelector:
              - eda.nokia.com/role=leaf
              - eda.nokia.com/role=spine
        state: present
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: true
  failed: false
  result: {}
  status: 201

When creating a resource you can omit the apiVersion and Kind under the resource block, as this information is automatically populated by the module.

Read#

Single resource#

To read (aka query/get) the particular resource in a namespace you need to provide the name and namespace in the module specification along with the state: query argument.

- name: Get a banner
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Get a banner
      nokia.eda_siteinfo_v1alpha1.banner:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        namespace: eda
        name: demo-banner
        state: query
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: false
  failed: false
  result:
    apiVersion: siteinfo.eda.nokia.com/v1alpha1
    kind: Banner
    metadata:
      labels:
        some-label: ansible-demo
      name: demo-banner
      namespace: eda
    spec:
      loginBanner: This is a demo banner provisioned by Ansible
      nodeSelector:
        - eda.nokia.com/role=leaf
        - eda.nokia.com/role=spine
    status:
      nodes:
        - leaf2
        - leaf1
        - spine1
  status: 200
All in a namespace#

To get all resources of the same kind from a namespace, use the ***list as in bannerlist module and provide the namespace argument:

- name: Get banners
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Get banners
      nokia.eda_siteinfo_v1alpha1.bannerlist:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        namespace: eda
        state: query
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: false
  failed: false
  result:
    apiVersion: siteinfo.eda.nokia.com/v1alpha1
    items:
      - apiVersion: siteinfo.eda.nokia.com/v1alpha1
        kind: Banner
        metadata:
          labels:
            some-label: ansible-demo
          name: demo-banner
          namespace: eda
        spec:
          loginBanner: This is a demo banner provisioned by Ansible
          nodeSelector:
            - eda.nokia.com/role=leaf
            - eda.nokia.com/role=spine
        status:
          nodes:
            - leaf2
            - leaf1
            - spine1
    kind: BannerList
  status: 200
All in a cluster#

To get all Banner resources from all namespaces, use the bannerlist module without providing a namespace:

- name: List banners in all namespaces
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: List banners in all namespaces
      nokia.eda_siteinfo_v1alpha1.bannerlist:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        state: query
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: false
  failed: false
  result:
    apiVersion: siteinfo.eda.nokia.com/v1alpha1
    items:
      - apiVersion: siteinfo.eda.nokia.com/v1alpha1
        kind: Banner
        metadata:
          labels:
            some-label: ansible-demo
          name: demo-banner
          namespace: eda
        spec:
          loginBanner: This is a demo banner provisioned by Ansible
          nodeSelector:
            - eda.nokia.com/role=leaf
            - eda.nokia.com/role=spine
        status:
          nodes:
            - leaf2
            - leaf1
            - spine1
    kind: BannerList
  status: 200
By label#

To get resources with a specific label, use the ***list module and provide the label-selector argument with a label-selector string value in it. If you add namespace you will get the resources with the label from a namespace, and without the namespace you will get the resources from all namespaces.

- name: List banners in all namespaces
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: List banners with a label
      nokia.eda_siteinfo_v1alpha1.bannerlist:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        label-selector: "some-label=ansible-demo"
        state: query
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: false
  failed: false
  result:
    apiVersion: siteinfo.eda.nokia.com/v1alpha1
    items:
      - apiVersion: siteinfo.eda.nokia.com/v1alpha1
        kind: Banner
        metadata:
          labels:
            some-label: ansible-demo
          name: demo-banner
          namespace: eda
        spec:
          loginBanner: This is a demo banner provisioned by Ansible
          nodeSelector:
            - eda.nokia.com/role=leaf
            - eda.nokia.com/role=spine
        status:
          nodes:
            - leaf2
            - leaf1
            - spine1
    kind: BannerList
  status: 200

Update#

The update workflow reuses the module argument specification of the create operation with the same state: present argument. The module's logic checks if the resource by this name (and in the same namespace, if applicable) already exists and if its metadata and spec match the provided ones. If they do not match, the existing resource is replaced with the new one.

For instance, if we start with the Banner resource created as in the create section above and we were to update the nodeSelector field to remove spine nodes, we would use the following playbook:

- name: Update a Banner
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Update a banner
      nokia.eda_siteinfo_v1alpha1.banner:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        resource:
          metadata:
            labels:
              some-label: ansible-demo
            namespace: eda
            name: demo-banner
          spec:
            loginBanner: "This is a CHANGED demo banner provisioned by Ansible"
            nodeSelector:
              - eda.nokia.com/role=leaf
        state: present
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: true
  failed: false
  result:
    apiVersion: siteinfo.eda.nokia.com/v1alpha1
    kind: Banner
    metadata:
      labels:
        some-label: ansible-demo
      name: demo-banner
      namespace: eda
    spec:
      loginBanner: This is a CHANGED demo banner provisioned by Ansible
      nodeSelector:
        - eda.nokia.com/role=leaf
  status: 200

The update response includes the full resource representation of the updated banner (minus the status field). If we would run the get-banner playbook, we would see that our changes (the login banner message and the selected nodes) are all respected:

ansible-playbook apps/siteinfo_v1alpha1/docs/examples/get-banner.yaml

PLAY [Get a banner] *********************************************************************************************

TASK [Fetch EDA access token] ***********************************************************************************
[WARNING]: Platform linux on host localhost is using the discovered Python interpreter at /home/roman/nokia-
eda/ansible/.venv/bin/python3.12, but future installation of another Python interpreter could change the meaning
of that path. See https://docs.ansible.com/ansible-core/2.17/reference_appendices/interpreter_discovery.html for
more information.
ok: [localhost]

TASK [Get a banner] *********************************************************************************************
ok: [localhost]

TASK [print response] *******************************************************************************************
ok: [localhost] => 
    response:
        changed: false
        failed: false
        result:
            apiVersion: siteinfo.eda.nokia.com/v1alpha1
            kind: Banner
            metadata:
                labels:
                    some-label: ansible-demo
                name: demo-banner
                namespace: eda
            spec:
                loginBanner: This is a CHANGED demo banner provisioned by Ansible
                nodeSelector:
                - eda.nokia.com/role=leaf
            status:
                nodes:
                - leaf1
                - leaf2
        status: 200

Revisions#

Thanks to the Git used by EDA as its resource database, every modifications to the resources are tracked, can be listed and reverted if needed. The history of changes to the resources can be fetched using the _revisions module.

If you have been following the examples in this section and modified the banner resource, running the revisions module will show you the history of changes made to it.

- name: Get a banner revision history
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Get a banner revision history
      nokia.eda_siteinfo_v1alpha1.banners_revisions:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        namespace: eda
        name: demo-banner
        state: query
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: false
  failed: false
  result:
    - author: admin
      changeType: MODIFIED
      commitTime: "2025-08-25T13:21:21+00:00"
      hash: 05655f0e61890d972537622f3278eef811125609
      message: REST
      transactionId: 76
    - author: admin
      changeType: ADDED
      commitTime: "2025-08-25T09:27:28+00:00"
      hash: b7dd27e1e56fd157d0a9703dfe8047cb803434e1
      message: REST
      transactionId: 75
  status: 200

The revision history shows the changes made to the demo-banner resource in the eda namespace. First it was created in transaction 75 and then modified in transaction 76.

Delete#

To delete a resource, use the resource module with the namespace and name arguments provided and state: absent set:

- name: Delete a Banner
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Delete a banner
      nokia.eda_siteinfo_v1alpha1.banner:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        namespace: eda
        name: demo-banner
        state: absent
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: true
  failed: false
  result:
    apiVersion: v1
    details:
      group: siteinfo.eda.nokia.com
      kind: Banner
      name: demo-banner
    kind: Status
    string: Success
  status: 200

Delete history#

Similar to the revision history of the existing resource, the deletion history of all instances of the resource can be tracked using the _deleted module. This module lists the deleted instances of a given resource type along with the transaction ID when it was deleted.

- name: Get a banner revision history
  hosts: all
  gather_facts: false
  tasks:
    - name: Fetch EDA access token
      nokia.eda_utils_v1.get_token:
        base_url: "{{ eda_api_url }}"
        client_secret: "{{ client_secret }}"
        username: admin
        password: "{{ eda_password }}"
      register: token

    - name: Get a banner revision history
      nokia.eda_siteinfo_v1alpha1.banner_deleted:
        base_url: "{{ eda_api_url }}"
        auth_token: "Bearer {{ token.result.access_token }}"
        namespace: eda
        state: query
      register: response

    - name: print response
      ansible.builtin.debug:
        var: response
response:
  changed: false
  failed: false
  result:
    - commitTime: "2025-08-25T15:01:52.466829+00:00"
      hash: 10ce977ce091bbedabb33eeec5121242392d5a02
      name: demo-banner
      namespace: eda
      transactionId: 77
  status: 200

The response shows that an instance of the Banner resource with the name demo-banner was deleted in transaction 77.


  1. There is no need to provide apiVersion and kind fields in the argspec of a module, as these are implied by the module.