Lead Image © Kittipong Jirasukhanont, 123RF.com

Lead Image © Kittipong Jirasukhanont, 123RF.com

Explore automation-as-code with Ansible

Automated

Article from ADMIN 84/2024
By
The Ansible automation tool makes it really easy to implement IT scenarios as code. We use structured YAML code to roll out Ansible in the form of AWX.

The everything-as-code trend is popular in IT today. The complete hardware and software configuration is stored in text files, and an automation tool rolls everything out. Fortunately, arcane file formats (e.g., sendmail.cf) are pretty much a thing of the past; instead, you can expect easily readable formats such as YAML and perhaps JSON. The information in these files can usually be converted into one of the other formats without loss.

YAML is the preferred format of the Ansible automation tool, which is used here for as-code automation. Thanks to its modular structure, Ansible can control pretty much everything in the data center and the cloud, including rolling itself out from its command line. This scenario might sound strange, but in the automation-as-code example, it makes sense to roll out a complete AWX setup in this way on Kubernetes and configure the AWX server with all the required settings.

The code here can act as a skeleton, or a template if you prefer, for your own more extensive as-code scenarios, as well as for cases in which you roll out and configure other applications. Because a huge amount of code is involved, I can only describe fragments of it in detail here. The complete code is available on GitHub [1]. Incidentally, it works with both the free AWX and, with a few minor changes, the commercial Ansible automation controller implementation.

Two Approaches

The first approach to automating the AWX rollout involves setting up an empty AWX server, configuring it in the web user interface (UI), and then exporting the complete configuration as a JSON or YAML file. You can then upload the results to a new, empty AWX server. The approach is mainly used if you want to clone a setup or migrate to a new platform or a new release (e.g., Ansible Tower to Ansible controller).

However, this approach does not lend itself to as-code scenarios, because the YAML files you need to export can be fairly large and confusing. With AWX as code, you will be looking to create your AWX configuration directly in YAML, which you will then be able to roll out automatically, which is why the code used here needs to be simpler, more clear-cut, and readable for the admin.

The second approach uses a playbook that fetches the configuration data from a YAML document. You can format and expand the document to suit your own requirements, which makes the YAML document far simpler, at the price of no longer being compatible with the exported format. Of course, the as-code idea is to roll out the installation from the code and not go down the opposite route.

Code vs. Config

One basic rule when using Ansible is that you want to avoid assigning values to variables in your Ansible playbook, which would massively affect the playbook's flexibility. Therefore, variable declarations should always be kept separate from the actual Ansible code.

In this case, you will use two separate files: vars.yaml contains the complete configuration of the AWX server to be rolled out, and secrets.yaml stores the passwords and keys you need for your AWX service's credentials.

Once you have entered all the access credentials and passwords in readable form in the YAML file, you need to encrypt secrets.yaml with Ansible vault. When executing the code, and only then, you can unlock access with the --ask-vault-pass option.

Hierarchical Variables and Dictionaries

The configuration variables for the as-code scenario are grouped hierarchically:

scm:
   name:"Github"
   User: "user01"
   url: "https://www.github.com"

The playbook then accesses variables like {{ scm.url }}, which means you can easily see the sub-section to which a variable belongs. If you want to extend the code later, you can add sub-variables at any time.

The second entity in the variables area is the dictionary. With this unnumbered array, Ansible can execute a loop for each element:

user:
   kirk:
     firstname: "James T"
     rank: "Admiral"
   spock:
     rank: "Captain"
   uhura:
     firstname: "Nyota"
     rank: "lieutenant"

An Ansible task now uses,

"with_dictionary: "{{ user }}"

or, in line with the more modern (but not necessarily better) notation,

"loop: "{{ user | dict2items }}"

to iterate through a loop. In a loop task, Ansible then accesses parts of the dictionary with items, which is a hierarchical loop variable. In this example, the first execution of a task in the loop would give you the following variable content:

item.key = "kirk"
item.value.firstname = "James T"
item.value.rank = "Admiral"

When declaring a dictionary, you do not need to declare all of a variable's hierarchies, as in the case with the spock entry. That said, the playbook task must be able to cope with empty variables in this case. Ansible has a default function for this:

- ansible.builtin.debug:
msg: "firstname : {{ item.value.firstname |default('Mister') }}"

If the item.value.firstname variable is empty in this case, Ansible uses Mister instead. This approach is used later to configure the SSH ports of the inventory entries.

Armed with these simple tips for formatting YAML dictionaries and using loops to evaluate them in Ansible, you can now basically configure arbitrary hardware and software with Ansible. The AWX rollout in this example is just one of many options.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs



Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>
	</a>

<hr>		    
			</div>
		    		</div>

		<div class=