Tag Archives: Customisation

Creating RR Records in Route53 with Ansible

So if you are like me and using Ansible to deploy all of your infrastructure, you probably run into more than your fair share of issues. Often Ansible modules take a list or a string, but output fancy structured data. One particular case of this is if you are using the route53 module and creating RR records in DNS. Here is what the route53 module accepts as a value:

- value
        The new value when creating a DNS record.  Multiple comma-
        spaced values are allowed.  When deleting a record all values
        for the record must be specified or Route53 will not delete
        it. [Default: None]

So here you can see that it takes a string (the source code indicates it also accepts lists) listing the ip addresses to point to. If you are deploying in a cloud however you probably need to pull the IP addresses from the inventory, which is stored as complex structured data. Extracting a list of IP addresses out of this is an extremely difficult task. To do this we will need to make heavy use of the features Ansible provides us through its Jinja2 variable expressions.

The first thing that we need is a list of all the variables for the machines in a particular group. Ansible doesn’t provide this, but it does provide two similar variables. First, it provides a variable names ‘group’ which gives the names of all the members of a particular group. Secondly it provides the ‘hostvars’ variable which gives you all of the variables in a dictionary with keys as the hostname and the variables as the values. As there is no builtin that does what we want we are going to need a custom filter plugin.

To install this plugin place it in a directory then add that directory to the end of your filter_plugins configuration option. For example if you placed the file in the plugins/filter directory your filter_plugins line might look like this:

filter_plugins     = /usr/share/ansible_plugins/filter_plugins:plugins/filter

This plugin will take a dictionary and a list, lookup all the keys within the list and return their values in a new list in the same order as the keys were in. So we can use this to get all the variables for the machines we are interested in. For example to get the variables for the hosts in the webservers group we can now do this:

{{ hostvars|fetchlistfromdict(groups.webservers) }}

Now that we have the right variables we simply need to filter it down to just the attribute we need. Jinja2 provides the map filter for this purpose. Map takes a list and can either pick out a particular attribute, or run another filter on all the items in the list. So to get the IP addresses we would do this:

{{ hostvars|fetchlistfromdict(groups.webservers)|map(attribute='ansible_default_ipv4.address') }}

If you try to print this out in a debug line you might notice that you don’t get a list in response and Ansible instead gives you a string with the following:

 <generator object do_map at 0x2d7f640>

To work around this issue you need to explicitly convert it to a list. This is fairly simple with the list filter. Adding that onto this example looks like this:

{{ hostvars|fetchlistfromdict(groups.webservers)|map(attribute='ansible_default_ipv4.address')|list }}

You now have a list of all the IP addresses ready to pass into a template, a role, or in this case into the route53 module. Finally we put this all together to create that round robin record we wanted at the start.

route53:
  command: create
  zone: example.com
  record: rr.example.com
  type: A
  value: "{{ hostvars|fetchlistfromdict(groups.webservers)|map(attribute='ansible_default_ipv4.address')|list }}"

Resources

Firefox Personas

Does anybody reading this remember Hotbar for IE 5 and 6? Remember how it came with dozens and dozens of adware and spyware apps. For anyone who doesn’t remember this was back when Bonzi Buddy spoke to us to distract you from the fact he was tracking everything you did online. When anybody who was somebody had a Geocities pages and was ‘programming’ in HTML. When marquees scrolled past and all Javascript did was make flashy pictures follow your cursor around. Yes that’s right I’m talking about the Web 1.0 days.

Firefox Persona LogoPersonas for Firefox does essentially what Hotbar did for IE, except it doesn’t pollute your PC with all sorts of nefarious software. This comparison isn’t quite fair though. Personas has drawn on the experiences of Web 2.0 to provide a simpler immersive themed atmosphere.

A Persona is an extremely simple way to theme your browser. There are five parts that make up a Firefox Persona. The header image is shown behind the menu bar, the navigation toolbar, the bookmarks toolbar and any other toolbars you have up the top. You set it as a 3000x200pixel image. The footer (a 3000x100px image) is shown behind the status bar and if show the search bar. You also set a text colour and an accent colour for any text that will be shown in front of your backgrounds. Finally you set a name for your theme as you upload it to Mozilla.

The best thing Personas has over themes is that you don’t have to restart Firefox in order to apply them. This leads to some especially neat features, for example while browsing for a new persona for your browser when you mouse over a persona it gets applied as a preview. This means effectively when you are looking for themes you get to see exactly what they’ll looks like before you pick them. You can get Personas from Mozilla labs, or at its dedicated website. Also see Mozilla’s blog post about Personas.

Random Thought: The Linux kernel must have a bad heart, every time it panics it dies.