Azure Credentials for Ansible

So, you need Ansible to connect to Azure. Congrats, Ansible is awesome for managing Azure resources. The Ansible team has already put together a scenario on how to integrate Ansible with Azure over at https://docs.ansible.com/ansible/latest/scenario_guides/guide_azure.html

The section ‘Authenticating with Azure‘ sounds like the right place, but you can’t use your AD username / password from Ansible because you turned on 2FA – You turned it on RIGHT? So the option left to you is to create a Service Principal (SP).

Note: having 2FA on your account is what you should be doing, so don’t turn it off.

It’s quite simple to create a credential for Ansible to use when connecting to Azure. Simply, fire up the Cloud Shell (awesome feature BTW Microsoft) and create a Service Principal (SP).

But Hang On, what is a Service Principal? The Ansible guide refers you to the Azure documentation over at https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal which you will read, and if you’re like me, you’ll wonder what you actually just read. Have no fear. As I mentioned above you can use a simple Azure CLI command (via the Cloud Shell you just started) and create the Service Principal. Think of the Service Principal as a credential an application (in this case Ansible) can use to access the Azure service(s).

geoff@Azure:~$ az ad sp create-for-rbac --name svc-ansible-azure  # (optional if not specified one will be generated)  --password 'ALovelyComplexPasswor@'
Changing "svc-ansible-azure" to a valid URI of "http://svc-ansible-azure", which is the required format used for service principal names
Creating a role assignment under the scope of "/subscriptions/88888888-4444-4444-4444-cccccccccccc"
  Retrying role assignment creation: 1/36
  Retrying role assignment creation: 2/36
{
  "appId": "appid888-4444-4444-4444-cccccccccccc",
  "displayName": "svc-ansible-azure",
  "name": "http://svc-ansible-azure",
  "password": "password-4444-4444-4444-cccccccccccc",
  "tenant": "tenant88-4444-4444-4444-cccccccccccc"
}
geoff@Azure:~$

If you want to see what that command just did in the Azure portal, head over to the Azure Active Directory -> App registrations blade.

and then you can see the Service Principal you just created.

So what do you do with the new credential.

The Ansible Azure scenario guide has a section on what to do, however, it’s a bit too vague for me.

Using Environment Variables

To pass service principal credentials via the environment, define the following variables:

  • AZURE_CLIENT_ID
  • AZURE_SECRET
  • AZURE_SUBSCRIPTION_ID
  • AZURE_TENANT

Azure has given me :

“appId”: “appid888-4444-4444-4444-cccccccccccc”,
“displayName”: “svc-ansible-azure”,
“name”: “http://svc-ansible-azure”,
“password”: “password-4444-4444-4444-cccccccccccc”,
“tenant”: “tenant88-4444-4444-4444-cccccccccccc”

For your sanity,
AZURE_CLIENT_ID ==> appId
AZURE_SECRET ==> password
AZURE_TENANT ==> tenant

The remaining item, AZURE_SUBSCRIPTION_ID is exactly that, you can also get from the Cloud Shell as follows

geoff@Azure:~$ az account list
[
  {
    "cloudName": "AzureCloud",
    "id": "subscrip-4444-4444-4444-cccccccccccc
    "isDefault": true,
.
.
.

In this case AZURE_SUBSCRIPTION_ID ==> id , whichever id in your account that is valid for your use case.

If you want to add these credentials into Ansible Tower, simply create a Credential of type Microsoft Azure Resource Manager and use the values you’ve deduced above. Ansible Tower will automatically translate them into Environment Variables for your Tower template execution.

Enjoy Ansible and Azure!

Ansible, more than just SSH

I often see the statement Ansible manages clients using SSH or WinRM. While this is a true statement, it is also incomplete.

Ansible currently has 26 connection types which you can find at https://docs.ansible.com/ansible/latest/plugins/connection.html

For me personally, some of the other interesting connection types are :

  • netconf
  • network_cli

    netconf and network_cli are commonly used to perform network device automation.
  • psrp

    psrp is similar to WinRM however it has the added benefit of being used via a proxy which is very useful when you have to consider bastian hosts.
  • vmware_tools

    vmware_tools is a relatively new addition to the ansible family and allows you to execute commands, transfer files to vSphere based systems without using the VM network.

Most Ansible developers will have also used connection type local in many of their playbooks, probably without realizing that it was a different connection type.

Ansible is also extensible. If you need to connect to something weird and wacky (but of great importance to you) then you can develop your own modules and connection plugin (or other sorts of plugins) – see https://docs.ansible.com/ansible/latest/plugins/plugins.html

Ansible versatility doesn’t end there though and many newcomers to ansible don’t realise that you can also manage multiple clouds, container platforms and virtualisation platforms – it’s the Swiss Army knife of IT automation.

Adding a custom credential type in Ansible Tower for ServiceNOW

It’s been one of those weeks and I needed to get some more experience with the ansible ServiceNOW modules, specifically within Ansible Tower. It looked pretty simple and in fact it really was quite simple.

Ansible Tower neatly stores credentials within it – or externally if that fills you with joy. There isn’t a ServiceNow credential type in Ansible Tower. Undeterred, I thought I would use machine credentials, but tower has an annoying behavior of only allowing 1 instance of each credential type attached to a tower template and I am already using machine credentials in my template.

Fortunately on the left hand side of the tower ui there’s an entry labelled credential types

When creating the credential type you need to supply two (2) pieces of information. The first piece is called the Input configuration – or what the fields look like on the web ui when you create a credential of this type and secondly, the Injector configuration which details what do do with thew credentials.

In my case, the new credential type is called SNOW and i’m providing the instance name, username and password as part of the structure for this credential – via the Input configuration and then I detail that I want to store this data in environment variables that will be accessible from my playbook when run in tower.

Input configuration

fields:
  - id: instance
    type: string
    label: Instance
  - id: username
    type: string
    label: Username
  - id: password
    type: string
    label: Password
    secret: true
required:
  - instance
  - username
  - password

Injector configuration

env:
  SN_INSTANCE: '{{instance}}'
  SN_PASSWORD: '{{password}}'
  SN_USERNAME: '{{username}}'

The way you use them in your playbook is quite simple. The following is a snippet of playbook showing that.


   - name: Create an incident
     snow_record:
       username: '{{ lookup("env", "SN_USERNAME") }}'
       password: '{{ lookup("env", "SN_PASSWORD") }}'
       instance: '{{ lookup("env", "SN_INSTANCE") }}'
       state: present
       data:
         short_description: "This is a test incident opened by Ansible"
         severity: 3
         priority: 2
     register: new_incident

ESXi 6+ PXE Boot from Centos 8 – Nope?

I was rebuilding some Lab ESXi physical hosts, but also thought i’d upgrade my ‘builder’ system to Centos 8. My builder system uses a bunch of Ansible playbooks to create the necessary DHCP, TFTP etc configuration to support PXE booting multiple OS types – including ESXi 6.5/6.7.

I started with test builds of Centos 7/8 using my now Centos 8 build server and it was all fine.

However….. when I tried to build ESXi 6.5+ the TFTP delivered the ESXi mboot.c32 file to the host (via syslinux 6.04 which is new to Centos 8) but it couldn’t be loaded. After several hours of frustration I tried downgrading to the syslinux 3.86 version mentioned in https://www.vmware.com/techpapers/2015/installing-vmware-esxi-6.0-using-pxe-10508.html . Sadly you can’t install that version on Centos 8 without considerable grief.

I was able to install syslinux 4.05 on Centos 8 and lo and behold the build process works. Clearly something in syslinux 6 doesn’t like PXE booting ESXi. I’m not sure what yet, but hopefully this blog post at least gives people a workaround to a frustrating problem.

Centos 8 – where did Lynx go ?

It’s always fun when you build a system at a new OS level and things have moved around. But having Lynx disappear made me a #sadpanda.

Fortunately, it wasn’t far away – it’s been moved to the PowerTools repository which you can enable with a quick:

dnf config-manager --set-enabled PowerTools

Then you can install my favourite little text based web browser again.

Navigation