I’ve posted a module to interface with DNS Made Easy (hosted DNS service). It calls their v2 REST API using urllib2 (so that it should work without need for any further python dependencies).
Currently the module is properly idempotent and supports creating, updating, fetching, and deleting of records using conventional behavior (e.g. state=present|absent). It does not yet support manipulating domains, monitoring rules, and HTTPRED records.
Code is available here:
https://github.com/briceburg/ansible/blob/devel/library/net_infrastructure/dnsmadeeasy
I’ll submit a pull request in hopes of getting it included for the 1.3 release.
Many thanks,
~ Brice
Hi Brice,
After a quick test run, I had issues with this module.
msg: http://api.dnsmadeeasy.com/V2.0/dns/managed returned 403, with body: {error: [“API key not found”]}
FATAL: all hosts have already failed – aborting
I tried from a playbook and from command line, and both seem to be missing the account_key/apikey.
New to ansible, so trying to debug the actual call.
Any thoughts?
Eric
Eric,
No problem. Have you passed the account_key argument?
Show me an example of what you're trying to run and I can give you more info.
Hi Brice,
Perhaps I have misconfigured the playbook, but mine looks like this:
dns-test.yml
Eric,
A couple notes;
- You should use mydomain.com for domain, not node1.mydomain.com
a. If you are trying to get all the records for domain.com, just pass domain=mydomain.com (and result will be registered to response)
b. If you want to get the current value of node1.mydomain.com, pass domain=mydomain.com record_name=node1 (and result will be registered to response)
From the docs:
- If record_name is not specified; all records for the domain will be returned as “result” regardless of state argument.
- If record_value is not specified; no changes will be made and the record will be returned as “result” (e.g. can be used to fetch a record’s current id, type, and ttl)
- Make sure that you have an API enabled DNS Made Easy account (Business plan or above) and that you’re using the correct API key.
My thought is that their API is erring by passing node1.mydomain.com vs. mydomain.com.
~ Brice
Hi Brice,
Issue has been resolved. I had to change the endpoint for the API, as I found we were using a sandbox API, so should be http://api.sandbox.dnsmadeeasy.com.
Thanks for the great module and your help!
Eric
Eric,
Interesting! Glad you got it working. I was not aware of their sandbox API. Do you think adding sandbox=yes will be beneficial to other users of this module? Or perhaps allow explicitly setting the endpoint; e.g. endpoint="http://api.sandbox.dnsmadeeasy.com" ?
~ Brice
Hi Brice,
I wanted to mention a few things after using this the other day:
If you attempt to change a record that is setup for failover and monitored, it will go through, but then will revert back to the first ip1 in failover. I wasn’t aware of this, and was confused after the DNS updated, then reverted back. Essentially, DO NOT USE ON FAILOVER records. The process to change failover records is different, and requires utilizing the /monitor url. The variable changes to use ‘ip1’ and ‘ip2’ instead of ‘value’. Once this is changed, then it should it persist a record change using /dns/managed.
It looks pretty simple to change the domain root record, but I was wondering why it wasn’t implemented in the ansible module yet? I have been busy deconstructing and trying to add the changes in my own fork, but the lower level workings is harder to debug.
Eric
Eric,
Interesting. Admittedly I intended this module for “simple” use of basic record management, at least to begin with. I’m totally happy to expand it and test more features. Another missing feature is handling of HTTP Redirection records. Performance can also be greatly increased by caching the API returns for the duration of an ansible run. These are all possible and perhaps we can work together on implementing them?
I don’t have a failover setup with DNSMadeEasy yet; were you able to implement in your fork?
Thanks,
~ Brice
Hello Brice,
First of all thanks for the DME ansible module. I’m hoping to get it working and manage our domain entries with Ansible.
However I’m currently facing the following problem when trying to list my domain entries:
failed: [localhost] => {“failed”: true}
msg: The requested domain name is not accessible with this api_key; try using its ID if known.
FATAL: all hosts have already failed – aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/home/jacek/dns.retry
localhost : ok=1 changed=0 unreachable=0 failed=1
I was getting 403 initially but after regenerating api key and secret key I’ve been hitting above mentioned issue. I’ve tried providing my domain name with and without double quotes, tried using numerical ID of domain with and without double quotes as well. It doesn’t seem to make any difference.
Any hints on what could be wrong or how I could find out more about the problem?
I’ve tried sniffing with tshark but unfortunately the whole communication is passed via https.
Thanks in advance!
Jacek
Hey Jake,
I’ve been debugging the module to check this out. Providing you have a business account and keys are correct, I strongly suspect your issue relates to local time of the system making the API call. The dnsmadeeasy api is very strict re: local system time, as it hashes each call with a timestamp. If this is skewed too far from the current time of the [dnsmadeeasy] api server, the call will fail.
Use ntp and sync your machines to UTC time.
Unfortunately the output from the module does not include the response body. This would be a major help, and I’ll investigate a fix. Right now the module uses fetch_url
provided by ansible core – mainly to keep requirements and LOC to a minimum.
So here’s a quick punchlist to check if the module is failing;
- have a dnsmadeeasy business account (minimal requirement for api usage)
- origin server system time is synced to UTC (use ntp)
- using correct api keys
- the call works via dnsmeapi.pl (https://support.dnsmadeeasy.com/index.php?/Knowledgebase/List/Index/15/downloads)
Here’s a test playbook;
---
- name: "dnsmadeeasy"
hosts: localhost
vars:
dnsme_key: AAA-BBB-CCC-DDD-EEE
dnsme_secret: AAA-BBB-CCC-DDD-EEE
tasks:
- name: fetch dnsmadeeasy records for domain by ID
dnsmadeeasy:
account_key: "{{ dnsme_key }}"
account_secret: "{{ dnsme_secret }}"
domain: 000000
state: present
#baseurl: http://api.sandbox.dnsmadeeasy.com/V2.0/
register: response
- debug: msg=response
my inventory host_vars/localhost.yml defines a local connection for localhost;
---
ansible_connection: local
Hope this helps!
~ brice