Monday, April 23, 2018

Using Azure Service Principal login with Ansible

The problem

When using the Azure REST API from Ansible using the uri module you need to ensure you are authenticated towards Azure. The easiest way to do that is to set a Bearer token based on a Service Principal user on Azure. 

This is the official Azure REST API documentation: https://docs.microsoft.com/en-us/rest/api/azure/

This is how you can create a service principal:

When you have created an Azure service principal you will have 4 necessary pieces of information:

  • Tenant id (the protected resource)
  • Client id (username)
  • Client secret (password)
  • Subscription id (you already had that from your user profile)
Make sure to save those values to an Ansible Vault. In my example I have called them:

  • vault_az_tenant_id
  • vault_az_client_id
  • vault_az_client_secret
  • vault_az_subscription_id

The solution

Create a playbook.yml with the following information:

---
- hosts: localhost
  vars:
    az_tenant_id: "{{ vault_az_tenant_id }}"
    az_client_id: "{{ vault_az_client_id }}"
    az_client_secret: "{{ vault_az_client_secret }}"
    az_subscription_id: "{{ vault_az_subscription_id }}"
    az_token_url: "https://login.microsoftonline.com/{{ az_tenant_id }}/oauth2/token"
    az_token_body: >
        resource=https://management.core.windows.net/
        &client_id={{ az_client_id }}
        &grant_type=client_credentials
        &client_secret={{ az_client_secret }}

  tasks:
    - name: Login to Azure
      uri:
        url: "{{ az_token_url }}"
        method: POST
        body: "{{ az_token_body }}"
        headers:
          Content-Type: "application/x-www-form-urlencoded"
        status_code: 200
      register: login

    - name: Setting Bearer token as fact
      set_fact:
        az_bearer: "{{ login.json.access_token }}"
 

That is how easy it is to authenticate with Azure from the Ansible uri module. Thanks to Vivek to helping out with the az_token_body.

Now every time you us the Ansible uri module in the same playbook, you just need to add the Bearer token to the request header, like this:

- uri:
        url: "{{ whatever-azure-url }}"
        method: POST
        headers:
          Authorization: "Bearer {{ az_bearer }}"

Wednesday, August 16, 2017

False positive: ansible-lint reports [ANSIBLE0002] Trailing whitespace when there are none

The problem

When running ansible-lint on a Ansible role, it reported [ANSIBLE0002] Trailing whitespace on every line in one of my task files, like shown in the example below:


(vansible23)[audun@hostname my-role]$ ansible-lint .
[ANSIBLE0002] Trailing whitespace
/home/audun/git/my-role/tasks/main.yml:1
---

[ANSIBLE0002] Trailing whitespace
/home/audun/git/my-role/tasks/main.yml:2


[ANSIBLE0002] Trailing whitespace
/home/audun/git/my-role/tasks/main.yml:3
- debug: msg="Hello World"



The investigation

I had a suspicion there might be hidden characters in the file, but before running it through a HEX editor, I tried to check it with the Linux file command:


(vansible23)[audun@hostname my-role]$ file /home/audun/git/my-role/tasks/main.yml
/home/audun/git/my-role/tasks/main.yml: ASCII text, with CRLF line terminators



As shown above, it turned out that the file had CRLF line terminators on every line, indicating that this file had been created on Windows. That was luckily easy to fix.


The solution

The dos2unix command was used to change the file to Unix format:


(vansible23)[audun@hostname my-role]$ dos2unix /home/audun/git/my-role/tasks/main.yml
dos2unix: converting file /home/audun/git/my-role/tasks/main.yml to Unix format ...



Afterwards ansible-lint reported no issues:


(vansible23)[audun@hostname my-role]$ ansible-lint .

Wednesday, March 15, 2017

Using atom-beautify package to beautify a Markdown file results in: Error: Cannot find module '../lib/language-code-rewrites'

The problem

I was using Atom Editor 1.14.4 with atom-beautify 0.29.17 package. When I tried to beautify a README.md file created with ansible-galaxy init <rolename> I got the following exception:

File 0Project 0No IssuesREADME.md9:77
LFUTF-8GitHub Markdowngit+
Cannot find module '../lib/language-code-rewrites'
Cannot find module '../lib/language-code-rewrites'
Hide Stack Trace
Error: Cannot find module '../lib/language-code-rewrites'
    at Module._resolveFilename (module.js:455:15)
    at Module._resolveFilename (/usr/share/atom/resources/electron.asar/common/reset-search-paths.js:35:12)
    at Function.Module._resolveFilename (/usr/share/atom/resources/app.asar/src/module-cache.js:383:52)
    at Function.Module._load (module.js:403:25)
    at Module.require (module.js:483:17)
    at require (/usr/share/atom/resources/app.asar/src/native-compile-cache.js:50:27)
    at Object.<anonymous> (/home/ane058/.atom/packages/atom-beautify/node_modules/tidy-markdown/lib/converters.js:12:23)
    at Module._compile (/usr/share/atom/resources/app.asar/src/native-compile-cache.js:109:30)
    at Object.value [as .js] (/usr/share/atom/resources/app.asar/src/compile-cache.js:216:21)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (/usr/share/atom/resources/app.asar/src/native-compile-cache.js:50:27)
    at Object.<anonymous> (/home/ane058/.atom/packages/atom-beautify/node_modules/tidy-markdown/lib/index.js:16:14)
    at Module._compile (/usr/share/atom/resources/app.asar/src/native-compile-cache.js:109:30)
    at Object.value [as .js] (/usr/share/atom/resources/app.asar/src/compile-cache.js:216:21)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.require (module.js:483:17)
    at require (/usr/share/atom/resources/app.asar/src/native-compile-cache.js:50:27)
    at /home/ane058/.atom/packages/atom-beautify/src/beautifiers/tidy-markdown.coffee:13:22
    at Promise._execute (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/debuggability.js:300:9)
    at Promise._resolveFromExecutor (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:483:18)
    at new Promise (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:79:10)
    at TidyMarkdown.module.exports.TidyMarkdown.beautify (/home/ane058/.atom/packages/atom-beautify/src/beautifiers/tidy-markdown.coffee:12:16)
    at /home/ane058/.atom/packages/atom-beautify/src/beautifiers/index.coffee:318:24
    at Promise._execute (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/debuggability.js:300:9)
    at Promise._resolveFromExecutor (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:483:18)
    at new Promise (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:79:10)
    at /home/ane058/.atom/packages/atom-beautify/src/beautifiers/index.coffee:240:18
    at tryCatcher (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:693:18)
    at Promise._fulfill (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:638:18)
    at PromiseArray._resolve (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise_array.js:126:19)
    at PromiseArray._promiseFulfilled (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise_array.js:144:14)
    at Promise._settlePromise (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:574:26)
    at Promise._settlePromise0 (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:693:18)
    at Promise._fulfill (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:638:18)
    at Promise._resolveCallback (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:432:57)
    at Promise._settlePromiseFromHandler (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:524:17)
    at Promise._settlePromise (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:693:18)
    at Promise._fulfill (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:638:18)
    at Promise._resolveCallback (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:432:57)
    at Promise._settlePromiseFromHandler (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:524:17)
    at Promise._settlePromise (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:693:18)
    at Promise._fulfill (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:638:18)
    at Promise._resolveCallback (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:432:57)
    at ReductionPromiseArray._resolve (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/reduce.js:61:19)
    at Promise.completed [as _fulfillmentHandler0] (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/reduce.js:122:15)
    at Promise._settlePromise (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:566:21)
    at Promise._settlePromise0 (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/promise.js:693:18)
    at Async._drainQueue (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/async.js:133:16)
    at Async._drainQueues (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/async.js:143:10)
    at Async.drainQueues (/home/ane058/.atom/packages/atom-beautify/node_modules/bluebird/js/release/async.js:17:14)

I logged it as an issue at https://github.com/Glavin001/atom-beautify/issues/1549, but after a few days of tinkering I finally found the likely root cause, and working solution.

The investigation

The exception suggest there is an issue with the tidy-markdown dependency, and it turned out that tidy-markdown 2.0.5 npm package had been released a few days earlier at https://www.npmjs.com/package/tidy-markdown 

ls ~/.atom/.apm/tidy-markdown/
showed that atom-beautify had pulled down the tidy-markdown 2.0.5 package.

The solution

cd ~/.atom/packages/atom-beautify
npm install tidy-markdown@2.0.4


Saturday, January 21, 2017

Released my second role to Ansible Galaxy today

The ansible-role-tint2 is an Ansible role for installing the tint2 panel for Linux. Currently the role supports the following platforms (in alphabetic order):


  • Arch Linux
  • Debian sid
  • Debian stretch
  • Fedora 24
  • Fedora 25 
  • Ubuntu 16.04
  • Ubuntu 16.10

The Ansible role can be found here: https://github.com/avnes/ansible-role-tint2
It has been released under the liberal MIT license.

While this Ansible role and this blog post of somewhat similar to my previous Ansible role, I used a much more flexible and portable test framework based on mulecule.

Saturday, January 14, 2017

Released my first role to Ansible Galaxy today

The ansible-role-conky is an Ansible role for installing the conky monitoring overlay tool. Currently the role supports the following platforms (in alphabetic order):


  • Arch Linux
  • Debian sid
  • Debian stretch
  • Fedora 24
  • Fedora 25 
  • Ubuntu 16.04
  • Ubuntu 16.10

The Ansible role can be found here: https://galaxy.ansible.com/avnes/ansible-role-conky/
It has been released under the liberal MIT license.

Wednesday, November 23, 2016

Customize Fedora 25 in a few minutes using Ansible

Instead of spending a few hours after installing Fedora 25 on adding the software you want and tweaking the options you prefer, why not use Ansible to get you up and running in minutes?

I assume you have already downloaded Fedora 25 Workstation from the official site at https://getfedora.org/, and that you have installed it, and that your personal user is allowed to run sudo (hint: being a member of the wheel group).


After logon to Fedora 25, download my Ansible playbook sample from https://github.com/avnes/blogsamples/blob/master/fedora.yml 

The rest of this article assumes you saved the file to ~/fedora.yml

Open ~/fedora.yml in a text editor (for instance vi or Gedit) and have look at what software it is installing, and what software it removes. Change it if you like.

When you are ready to play, run the following commands as your personal user:
sudo dnf install -y ansible
ansible-playbook ~/fedora.yml --connection=local --ask-become-pass

When promoted for a password, type in your personal password, and the playbook will then be executed with sudo rights. Both the sudo command and the ansible.playbook command will prompt you for your personal password.

Afterwards you should see a similar output as below, though changed would be higher than 0. In my case of is 0 because I have already run the playbook a few times already, so no changes.




Wednesday, November 9, 2016

How to install Vagrant with Oracle® VM VirtualBox and libvirt support on Antergos Linux

Installation

I recently needed to install Vagrant with support for Oracle® VM VirtualBox and libvirt for my dixie project at GitHub. Some of the virtualbox dependencies was found in this excellent post over at forum.antergos.com. Then I wrapped it into a script, and the here is the part of the script that installs and configures it:

if [ $(uname -r | grep ARCH | wc -l) -gt 0 ]; then
  sudo pacman -S --needed --noconfirm vagrant
  sudo pacman -S --needed --noconfirm libvirt
  sudo pacman -S --needed --noconfirm linux-headers
  sudo pacman -S --needed --noconfirm virtualbox virtualbox-guest-iso
  sudo pacman -S --needed --noconfirm vde2 net-tools virtualbox-ext-vnc virtualbox-host-modules-arch
  sudo pacman -S --needed --noconfirm ansible rsync
  sudo su -c "modprobe vboxdrv" || echo "Reboot your computer and try again"
  if [ ! -f "/etc/modules-load.d/virtualbox.conf" ]; then
    sudo touch /etc/modules-load.d/virtualbox.conf
  fi

  if [ $(grep vboxdrv /etc/modules-load.d/virtualbox.conf | wc -l) -eq 0 ]; then
    sudo su -c 'echo "vboxdrv" >> /etc/modules-load.d/virtualbox.conf'
  fi

  if [ $(grep vboxnetadp /etc/modules-load.d/virtualbox.conf | wc -l) -eq 0 ]; then
    sudo su -c 'echo "vboxnetadp" >> /etc/modules-load.d/virtualbox.conf'
  fi
  if [ $(grep vboxnetflt /etc/modules-load.d/virtualbox.conf | wc -l) -eq 0 ]; then
    sudo su -c 'echo "vboxnetflt" >> /etc/modules-load.d/virtualbox.conf'
  fi
  if [ $(grep vboxpci /etc/modules-load.d/virtualbox.conf | wc -l) -eq 0 ]; then
    sudo su -c 'echo "vboxpci" >> /etc/modules-load.d/virtualbox.conf'
  fi
fi