In the vein of infrastructure as code OctoDNS provides a set of tools & patterns that make it easy to manage your DNS records across multiple providers. The resulting config can live in a repository and be deployed just like the rest of your code, maintaining a clear history and using your existing review & workflow.
The architecture is pluggable and the tooling is flexible to make it applicable to a wide variety of use-cases. Effort has been made to make adding new providers as easy as possible. In the simple case that involves writing of a single class
and a couple hundred lines of code, most of which is translating between the provider's schema and OctoDNS's. More on some of the ways we use it and how to go about extending it below and in the /docs directory.
It is similar to Netflix/denominator.
Running through the following commands will install the latest release of OctoDNS and set up a place for your config files to live.
$ mkdir dns
$ cd dns
$ virtualenv env
...
$ source env/bin/activate
$ pip install octodns
$ mkdir config
We start by creating a config file to tell OctoDNS about our providers and the zone(s) we want it to manage. Below we're setting up a YamlProvider
to source records from our config files and both a Route53Provider
and DynProvider
to serve as the targets for those records. You can have any number of zones set up and any number of sources of data and targets for records for each. You can also have multiple config files, that make use of separate accounts and each manage a distinct set of zones. A good example of this this might be ./config/staging.yaml
& ./config/production.yaml
. We'll focus on a config/production.yaml
.
---
providers:
config:
class: octodns.provider.yaml.YamlProvider
directory: ./config
dyn:
class: octodns.provider.dyn.DynProvider
customer: 1234
username: 'username'
password: env/DYN_PASSWORD
route53:
class: octodns.provider.route53.Route53Provider
access_key_id: env/AWS_ACCESS_KEY_ID
secret_access_key: env/AWS_SECRET_ACCESS_KEY
zones:
example.com.:
sources:
- config
targets:
- dyn
- route53
class
is a special key that tells OctoDNS what python class should be loaded. Any other keys will be passed as configuration values to that provider. In general any sensitive or frequently rotated values should come from environmental variables. When OctoDNS sees a value that starts with env/
it will look for that value in the process's environment and pass the result along.
Further information can be found in the docstring
of each source and provider class.
Now that we have something to tell OctoDNS about our providers & zones we need to tell it about or records. We'll keep it simple for now and just create a single A
record at the top-level of the domain.
config/example.com.yaml
---
'':
ttl: 60
type: A
values:
- 1.2.3.4
- 1.2.3.5
Further information can be found in Records Documentation.
We're ready to do a dry-run with our new setup to see what changes it would make. Since we're pretending here we'll act like there are no existing records for example.com.
in our accounts on either provider.
$ octodns-sync --config-file=./config/production.yaml
...
********************************************************************************
* example.com.
********************************************************************************
* route53 (Route53Provider)
* Create <ARecord A 60, example.com., [u'1.2.3.4', '1.2.3.5']>
* Summary: Creates=1, Updates=0, Deletes=0, Existing Records=0
* dyn (DynProvider)
* Create <ARecord A 60, example.com., [u'1.2.3.4', '1.2.3.5']>
* Summary: Creates=1, Updates=0, Deletes=0, Existing Records=0
********************************************************************************
...