How to change an Ansible namespace with FQCN migration tool
Tags: ansible
Published: 2023-11-23 17:00:00

Packaging [Ansible Playbooks](https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html) within a collection is the best way to distribute reusable [automation](https://developers.redhat.com/topics/automation) content. To avoid naming conflicts, developers organize collections inside namespaces. Sometimes situations arise where you need to migrate a collection from one namespace to another, such as a personal or community collection graduating to a more well known or certified namespace.

Altering the namespace can be a tedious task. However, the Fully Qualified Collection Name (FQCN) migration tool simplifies this process by utilizing the fqcn_migration command. Employing a straightforward configuration file transforms an entire collection from one namespace to another. This article introduces the tool and demonstrates how to use it.

## Case story

Let’s assume we have a collection called useful_stuff living in a community namespace. It has proven valuable to the Ansible community for several years, so there was a decision to move its content from the `community` namespace to the `ansible` namespace. The migration also presents the opportunity to rename the collection, as its current one was deemed not applicable in the destination namespace.

The content of useful_stuff adheres to the best practices and conventions associated with Ansible collections, which means that all the roles it contains are prefixed by the collection name (`useful_stuff_role_name`) and all variables inside the role are also prefixed with the role name (`useful_stuff_varname`).

On top of the runnable Ansible content, the name of the collection and its namespace appears in other files, such as the `galaxy.yml` metadata file as well as within the included documentation resource. Also, as a result of the namespace change, a few URLs will need to be updated.

## Using FQCN migration to alter the collection content

To ease the migration from community.useful_stuff to `ansible.helpful_things`, we are going to use the FQCN migration tool. First, we’ll need to install it. The tool is packaged as a collection and requires to be available on the system that we will utilize to perform the migration:

```
$ ansible-galaxy collection install community.fqcn_migration
```
Once the collection is installed on the system, use the included playbook from within the collection and set several variables properly. Let’s create a playbook called `playbook.yml` with the following content:


```
---
- ansible.builtin.import_playbook: community.fqcn_migration.fqcn_migration
  vars:
    upstream_name: useful_stuff
    downstream_name: helpful_things
    upstream_namespace: 'community'
    downstream_namespace: 'ansible'
    project_git_url: https://github.com/ansible-collections/useful_stuff.git
    project_git_version: main
    galaxy:
      documentation:  https://docs.ansible.com/ansible/latest/collections/ansible/helpfull_things/index.html
      homepage: https://docs.ansible.com/ansible/latest/collections/ansible/helpfull_things/index.html
```
This playbook can then be run like any other one:

```
$ ansible-playbook playbook.yml
```
The playbook will first perform a Git clone of the project’s repository of the collection to migrate and alter its content to match the new naming convention required. All that remains is to use git diff to review the modifications, test that the collection still works as expected, and then commit the changes back to the existing repository (or import the resulting content into another repository).

Note that because fqcn_migration is a development tool, the provided playbook is designed to target the local instance (Ansible controller) rather than on a target (remote) system. As a result, no inventory file is required.

## Generating a downstream collection

As demonstrated, `fqcn_migration` is already quite helpful for migrating collections from one namespace to another. However, the tool was also developed to support creating downstream collections. Before explaining how to use the tool for such a purpose, let’s briefly clarify what we mean by downstream content. This is a topic that is somewhat specific for providing commercial support over an open source solution.

Most Red Hat Ansible Automation Platform users are familiar with the Red Hat Enterprise Linux distribution, as a supported and certified version based on the community project Fedora. The same logic applies with JBoss Enterprise Platform being the supported and certified version of the community supported Java/JEE application WildFly. In this context, the community project is often referred to as upstream, while the code base of the Red Hat products is the downstream. Naturally, downstream source derives from the upstream. But, for many reasons, it is frequently transformed (to add files specific content related to the certified product) and then resides in its separate source code repository. Fixes and enhancements in the upstream project are selected afterward and back-ported to the downstream.

The Ansible Middleware collections are a set of collections designed to help manage Red Hat Runtimes solutions ([RH JBoss EAP](https://www.redhat.com/en/technologies/jboss-middleware/application-platform), [RH SSO](https://access.redhat.com/products/red-hat-single-sign-on/), [RH JBoss Web Server](https://www.redhat.com/en/technologies/jboss-middleware/web-server), [RH Data Gri](https://www.redhat.com/en/technologies/jboss-middleware/data-grid)d, [RH AMQ](https://www.redhat.com/en/technologies/jboss-middleware/amq) and [RH AMQ Streams](https://www.redhat.com/en/resources/amq-streams-datasheet)). Therefore, the upstream collections target the community project (upstream) of each of those projects and each has a downstream version targeting the products provided by Red Hat.

However, functionally, those collections are the same. The only technical difference is the naming convention and the supportability options. Consequently, to generate the downstream collection of one of those collections, for release purposes, fqcn_migration is also used. Naturally, the transformation performed on the collection is a bit more extensive, as there are extra requirements for documentation along with those that become Ansible certified content published on Ansible automation hub.

All of these considerations are handled within the fqcn_migration logic so that no manual change is required during a release of the downstream collection. For example, the following is the transformation rule used to convert the `middleware_automation.wildfly` collection into the `redhat.eap` collection: [see this configuration file](https://github.com/ansible-middleware/janus/blob/main/playbooks/eap.yml).

This configuration of fqcn_migration is richer than the previous one. We leverage some advanced features that allow us to add or replace content to the collection. Based on a simple placeholder, this capacity allows the user to change the documentation of the downstream collection, so that it matches the documentation requirements of Ansible certified content.

Once we have generated the downstream collection, we can validate that the result is functional simply by running its transformed molecule test suite:

```
$ cd downstream/eap/
$ molecule test
…
```

## Summary

In summary, altering a namespace requires a lot of changes because Ansible collections live inside namespaces, and it is best to use it in variables and role names. However, thanks to the fqcn_migration tool, we can easily migrate a collection’s content from one namespace to another, but also transform its roles and playbooks to generate a fully functional downstream version of the Ansible extension.