Note:
This article utilizes an Ansible collection (configify.aapconfig) that's developed, published, and maintained by the Ansible community. Refer to the validated infra.aap_configuration Ansible collection supported by Red Hat.
In previous parts of this series, we looked at automating Red Hat Ansible Automation Platform configuration with CaC approach and discussed different kinds of migrations possible with configify.aapconfig collection. This article is about migrating configuration from version 2.4 to 2.5.
Follow this series:
Part 1: The first steps on the path of managing an existing Ansible Automation Platform instance as CaC, setting up Ansible Automation Platform accounts, collections, credentials, projects, and job templates required to run the automation, exporting configuration of some objects, handling secrets and special strings in the CaC, and managing configuration drift.
Part 2: Completing the transition: exporting all objects, formatting configurations for readability, verification, access restrictions, and Git management.
Part 3: Migrating configurations from AWX 24 to Ansible Automation Platform 2.5.
Part 4: Migrating smart inventories (deprecated in future Ansible Automation Platform releases) to constructed inventories.
Part 5: Migrating configurations from Ansible Automation Platform 2.4 to Ansible Automation Platform 2.5.
Preparation, export, and import
The approach and steps are very similar to what was discussed in Part 3 when we migrated configuration from AWX 25 to Ansible Automation Platform 2.5. We assume that the current task is to migrate configurations from an existing instance of Ansible Automation Platform 2.4 into a new 2.5 rather than performing an in-place upgrade. Thus the expectation is that you already have Ansible Automation Platform 2.5 deployed as a separate cluster. Specific deployment steps are available in the official Red Hat documentation and are outside of the scope of this article.
The use cases for such an approach opposed to in-place update include migration from physical or virtual servers to OCP, migration into Ansible Automation Platform in a cloud or simply a requirement to do a cleanup and migrate into a fresh environment and use configuration as code approach going forward.
The required preparation steps are the same as what was described in the previous parts. First, Ansible Automation Platform should be configured to use the configify.aapconfig collection and run playbooks from it. This includes tokens, credential types, credentials, projects and job templates.
If there is connectivity between old and new Ansible Automation Platform clusters the configuration can be done only in one of them. In this case the difference between import and export is in the credentials and the playbooks selected in the job template. For export, we will specify credentials for the source cluster and aap_audit_all.yml playbook. For import, new cluster credentials and aap_configure.yml playbook.
Otherwise the configuration needs to be done in each cluster separately.
As mentioned in Part 1 of the series, in case of Ansible Automation Platform 2.5 controller and hub hostname fields in credentials should be pointing to the gateway, because of unified authentication, while for version 2.4, the values are pointing to controller and hub directly.
Once preliminary configuration is completed, run configify.aapconfig.aap_audit_problematic_objects.yml playbook and spend time on fixing potential issues it finds and optionally a cleanup.
The export is done using configify.aapconfig.aap_audit_all.yml playbook specifying:
format_for_25: true
The switch makes sure that certain objects that have a different structure in Ansible Automation Platform 2.5 will be exported in the new format suitable for further import into Ansible Automation Platform 2.5. The next section describes these changes.
As discussed earlier, exported data needs to be formatted using Batch Replace script and reviewed for any potential issues as described in the "Formatting the output" section of Part 2. Make decisions regarding handling secrets and configurations related to external users and make adjustments to configurations if necessary.
Import configurations into the new cluster using configify.aapconfig.aap_configure.yml playbook with tags that limit the scope as required.
Changes in Ansible Automation Platform 2.5
Ansible Automation Platform 2.5 comes with a lot of changes and new features. The details can be found in the official release notes. For the purposes of configuration as code, we are interested in three areas: auditor users, read and gateway roles, authentication settings.
In earlier Ansible Automation Platform versions, whether a user is an administrator, auditor or a regular user was determined by the properties of user record, for example:
'superuser': False,
'auditor': True
Both of these fields set to False
would indicate a normal user.
In version 2.5, administrators are still defined by the superuser property while the auditor is defined by the Platform Auditor role.
In terms of configuration export formatted for version 2.5, in addition to a user object:
{'username': 'UserB_Auditor', 'first_name': userb, 'last_name': 'auditor', 'email': '',
'superuser': False, 'auditor': True, 'pass': '$encrypted$'},
The collection will also report a role:
{'user': 'UserB_Auditor', 'role': 'Platform Auditor',
'object_type': 'platform', 'object_name': 'Platform'}
Another area that is different in version 2.5 is roles. First, there are no explicit read roles anymore. The export for version 2.4 is removed from the export formatted for version 2.5:
{'team': 'Team B', 'role': 'JobTemplate Read',
'object_type': 'jobtemplate', 'object_name': 'Template B'},
{'team': 'Team C', 'role': 'Organization Read',
'object_type': 'organization', 'object_name': 'Org C'},
{'user': 'UserB', 'role': 'Project Read',
'object_type': 'project', 'object_name': 'Project B'},
{'user': 'UserB', 'role': 'Inventory Read',
'object_type': 'inventory', 'object_name': 'Inventory Constructed B'}
Second, Organization Member, Organization Admin, Platform Auditor roles are now considered gateway roles and in the export formatted for version 2.5 they will be in a separate variable:
gateway_objects_roles: [
{'user': 'UserC', 'role': 'Organization Admin',
'object_type': 'organization', 'object_name': 'Org C'},
{'user': 'UserB', 'role': 'Organization Member',
'object_type': 'organization', 'object_name': 'Org B'},
{'user': 'UserB_Auditor', 'role': 'Platform Auditor',
'object_type': 'platform', 'object_name': 'Platform'},
] # type: ignore
Finally, authentication settings, including organization and team mappings are separate configurations from settings and thus are exported as separate variables in 2.5 format. For example, LDAP configuration which before looked like a long dictionary with LDAP settings, organization and team mappings:
controller_settings_ldap: {
'AUTH_LDAP_ORGANIZATION_MAP': {
'Org B': {
'admins': [
'CN=orgbadm,OU=Users,DC=example,DC=com'
],
'remove_admins': true,
'remove_users': true,
'users': [
'CN=orgb,OU=Users,DC=example,DC=com'
]
},
'Org C': {
'admins': [],
'users': [
'CN=orgc,OU=Users,DC=example,DC=com',
'CN=orgc2,OU=Users,DC=example,DC=com'
]
}
},
'AUTH_LDAP_SERVER_URI': 'ldap://exampleb',
'AUTH_LDAP_TEAM_MAP': {
'Team B': {
'organization': 'Org B',
'remove': true,
'users': [
'CN=teamb,OU=Users,DC=example,DC=com'
]
},
'Team C': {
'organization': 'Org C',
'users': [
'CN=teamb,OU=Users,DC=example,DC=com',
'CN=teamb2,OU=Users,DC=example,DC=com'
]
}
}
} # type: ignore
After export in 2.5 format becomes two variables separate from settings:
controller_authentication: [
{
'configuration': {
'CONNECTION_OPTIONS': {},
'GROUP_TYPE': 'MemberDNGroupType',
'GROUP_TYPE_PARAMS': {
'member_attr': 'member',
'name_attr': 'cn'
},
'SERVER_URI': [
'ldap://exampleb'
],
'START_TLS': false,
'USER_ATTR_MAP': {
'email': 'mail',
'first_name': 'givenName',
'last_name': 'sn'
}
},
'enabled': true,
'name': 'Auth_LDAP',
'type': 'ansible_base.authentication.authenticator_plugins.ldap'
}
] # type: ignore
controller_authenticator_maps: [
{'name': 'Auth_LDAP_team_Team B_map', 'authenticator': 'Auth_LDAP', 'order': 0,
'map_type': 'team', 'role': 'Team Member', 'organization': 'Org B', 'team': 'Team B',
'revoke': True,
'triggers': {'groups': {'has_or': ['CN=teamb,OU=Users,DC=example,DC=com']}}},
{'name': 'Auth_LDAP_team_Team C_map', 'authenticator': 'Auth_LDAP', 'order': 0,
'map_type': 'team', 'role': 'Team Member', 'organization': 'Org C', 'team': 'Team C',
'revoke': False,
'triggers': {'groups': {'has_or': ['CN=teamb,OU=Users,DC=example,DC=com'
'CN=teamb2,OU=Users,DC=example,DC=com']}}},
{'name': 'Auth_LDAP_org_Org B_user_map', 'authenticator': 'Auth_LDAP', 'order': 0,
'map_type': 'organization', 'role': 'Organization Member', 'organization': 'Org B', 'team': '',
'revoke': True,
'triggers': {'groups': {'has_or': ['CN=orgb,OU=Users,DC=example,DC=com']}}},
{'name': 'Auth_LDAP_org_Org B_admin_map', 'authenticator': 'Auth_LDAP', 'order': 0,
'map_type': 'organization', 'role': 'Organization Admin', 'organization': 'Org B', 'team': '',
'revoke': True,
'triggers': {'groups': {'has_or': ['CN=orgbadm,OU=Users,DC=example,DC=com']}}},
{'name': 'Auth_LDAP_org_Org C_user_map', 'authenticator': 'Auth_LDAP', 'order': 0,
'map_type': 'organization', 'role': 'Organization Member', 'organization': 'Org C', 'team': '',
'revoke': False,
'triggers': {'groups': {'has_or': ['CN=orgc,OU=Users,DC=example,DC=com',
'CN=orgc2,OU=Users,DC=example,DC=com']}}}
] # type: ignore
The way these settings are being exported is determined by the format_for_25
switch.
Final thoughts
This article concludes the series about managing Ansible Automation Platform with configurations as code approach and performing different kinds of migration using configify.aapconfig collection. The collection is an open source project. Feel free to open a ticket if you run into an issue using it and contribute to the code.