Configure resources with Ansible

This is an advanced lab, so we don’t really want you to use the web UI for everything. To fully embrace automation and adopt the infrastructure as code (IaC) and Configuration as Code (CaC) methodology, we want to use Ansible to configure our automation platform.

Since the automation platform is exposing all of its functionality via REST API, we can automate everything. Instead of using the API directly, it is highly recommended to use the Ansible Collections to setup, configure and maintain your Red Hat Ansible Automation Platform using Ansible.

Before we jump into the details, let’s have a quick overview of the currently available collections and how they rely on each other.

  • ansible.controller This Ansible collection allows for easy interaction with an Red Hat Ansible Automation Platform server via Ansible playbooks.

  • ansible.eda This collection contains event source plugins, event filters and example rulebooks to be used with ansible-rulebook.

  • ansible.hub This Ansible collection allows for easy interaction with an Ansible Automation Hub server via Ansible playbooks.

  • ansible.platform This collection contains modules that can be used to automate the creation of resources on Ansible Automation Platform.

The Scenario

For the next chapters we need a number of resources configured in AAP:

  • Static Inventory with two hosts

  • Credentials

  • Two Projects

  • Two Job Templates

This would involve a lot of error prone clicking in the web UI, so you’ll use the pro way: a playbook was prepared upfront to save time, but you will still learn how to use Ansible to configure the Automation Execution part of AAP.

Authentication

The Ansible modules we use in the playbook need to talk to AAP and require authentication, of course. There are a number of ways to accomplish this, you could e.g. set the URL/user name/password as environment variables.

In this lab we use a little trick to save time and make it less error prone. We set the credentials and other values directly in the .ansible-navigator.yml file in your home directory, so ansible-navigator will pick them up with every run. Have a look for yourself in your terminal on the bastion host:

cat ~/.ansible-navigator.yml

The result should look like this:

---
ansible-navigator:
  execution-environment:
    image: "https://aap.MYGUID.sandboxMYSANDBOX.opentlc.com/ee-supported-rhel8:latest"
    enabled: true
    container-engine: podman
    pull:
      policy: missing
    volume-mounts:
       - {dest: /etc/ansible/, src: /etc/ansible/}
    environment-variables:
      pass:
        - GUID
      set:
        CONTROLLER_HOST: "https://aap.MYGUID.sandboxMYSANDBOX.opentlc.com"
        CONTROLLER_USERNAME: "MYUSER"
        CONTROLLER_PASSWORD: "MYPASSWORD"
        CONTROLLER_VERIFY_SSL: "True"

The environment variables prefixed with CONTROLLER_ are the connection and credential parameters.

For your convenience we added the authentication credentials for automation controller to the configuration, so you don’t have to manually log in. In most real world scenarios you probably don’t want to do this and will not store your password in a clear text configuration file.
For performance and security reasons, it is recommended "in real life" to generate and use a token for your automation. Check the ansible-navigator documentation for details on how to do this.

Create the Playbook

Now, let’s get the Playbook. In your VS Code terminal (or SSH session) run:

git clone https://bastion.MYGUID.sandboxMYSANDBOX.opentlc.com:488/MYUSER/playbooks-adv-controller.git
cd playbooks-adv-controller
cat configure-controller.yml

Use cat or the VS Code editor to have a good look at what the configure-controller.yml Playbook is supposed to do.

Since we are calling the REST API of automation controller, the Ansible playbook is running against localhost, but the modules will connect to the URL provided by the CONTROLLER_HOST environment variable set for you in ~/.ansible-navigator.yml.

Tasks:

  • Create an inventory: An inventory is created.

  • Add hosts to inventory: Hosts are added to the inventory.

  • Machine Credentials: Machine credentials are created.

    SSH keys have already been created and distributed in your lab environment and sudo has been setup on the managed hosts to allow password-less login. When you SSH into a host as a regular user from the bastion node you will become user ec2-user on the host you logged in.
  • Create Projects: different projects are created based on public Git repos which we have synced to your environment (check how we define the scm variable if you’re interested in the details).

  • Create Web Infra and Dev Templates: and finally two job templates are created based on the previously added elements (the trinity inventory, credential and project).

Run the Playbook

After you have inspected the Playbook finally run it:

ansible-navigator run configure-controller.yml

While in ansible-navigator press a line number e.g. to get more information about a play or tasks. This works only for less then 10 lines, if you want to inspect a line number with 2 digits or more, you need to prefix it with :. To leave, press Esc multiple times to get up again in the views and eventually out of Navigator.

Do not leave the Navigator TUI (Text User Interface) before the job is finished! Check the colored text box in the bottom-right corner, it must go from Running to Successful.

After the successful run, log into your Ansible Automation Platform web UI, using the user MYUSER and the usual password MYPASSWORD. Open Automation Execution and make sure that you see the configured objects and a job "Source Control Update" successfully executed which cloned the git repository.

If you run this Ansible Playbook multiple times, you will notice the ansible.controller.credential module is not idempotent! Since automation controller stores the SSH key encrypted, the Ansible Module is unable to verify it has already been set and didn’t change. This is what we want and expect from a secure system, but it also means Ansible has no means to verify it and hence overrides the SSH key or password every time the Ansible Playbook is executed. This can be overridden with the update_secrets parameter. Also note that the credential_type value is simply the type’s name.