Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dynamic records in Azure DNS #706

Merged
merged 8 commits into from May 18, 2021
Merged

Conversation

viranch
Copy link
Collaborator

@viranch viranch commented May 11, 2021

Adds support for dynamic records in Azure DNS by using Azure Traffic Managers (ATMs).

An ATM can be one of 'Geographic', 'Priority' or 'Weighted' (among others). So a single ATM can only do one of geo-fencing, failover and weighted round-robin. All types support TCP, HTTP and HTTPS health-checks with customizable host, port and path.

To achieve the full functionality of dynamic records, multiple ATMs need to be created (one for each pool, each rule and failover chains) and nested together. This PR implements dynamic records by creating 3 layers of nested ATMs: DNS record -> Geographic -> Priority -> Weighted. Each pool gets a Weighted ATM, which are nested within another Priority ATM for failovers corresponding to each rule, which are further nested inside a top-level Geographic ATM which does geo-fencing. The top-level ATM then gets aliased to a record inside the DNS zone (this is not an ALIAS record, it's a Azure-specific "nesting" which is called 'alias' on the portal).

Here's my attempt at a graphical representation:

www:
  ttl: 60
  type: CNAME
  value: default.com.
  dynamic:
    pools:
      one:
        fallback: two
        values:
        - value: one1.com.
          weight: 11
        - value: one2.com.
          weight: 12
      two:
        values:
        - value: two.com.
    rules:
    - geos:
      - EU
      pool: one
    - pool: two

becomes:

www.site.com
  -> www-site-com (Geographical ATM)
     Europe -> rule-one--www-site-com (Priority ATM)
               Priority 1 -> pool-one--www-site-com (Weighted ATM)
                             Weight 11 -> one1.com
                             Weight 12 -> one2.com
               Priority 2 -> two.com
               Priority 3 -> default.com
     WORLD  -> rule-two--www-site-com (Priority ATM)
               Priority 1 -> two.com
               Priority 2 -> default.com

Each ATM gets the heathcheck config as defined in octodns. This works fairly well in my testing.

Now some caveats:

  • Nested ATMs actually result in foo.trafficmanager.net CNAMEs to send DNS clients to each other. This introduces extra CNAME hops in DNS resolution of user's dynamic records, and poses all risks associated with single-DNS due to *.trafficmanager.net CNAMEs. The above example will result in this CNAME chain for Europe:
$ dig +short +noshort www.site.com
www.site.com.                               60  IN  CNAME   www-site-com.trafficmanager.net.
www-site-com.trafficmanager.net.            60  IN  CNAME   rule-one--www-site-com.trafficmanager.net.
rule-one--www-site-com.trafficmanager.net.  60  IN  CNAME   pool-one--www-site-com.trafficmanager.net.
pool-one--www-site-com.trafficmanager.net.  60  IN  CNAME   one1.com.
  • Because of above, it is impossible to alias A/AAAA records to ATMs that have other nested ATMs. As a result, Azure DNS cannot fully support A/AAAA dynamic records.
  • ATMs cannot have health checking disabled on any of its member endpoints. As a result, the default answer will also be health-checked. If all answers in the pools are unhealthy along with the default one, Azure DNS may not hand out the default answer.

I believe this is still somewhat functional if someone wanted to pursue dynamic records on Azure DNS.

@viranch viranch force-pushed the azuredns-dynamic branch 3 times, most recently from baf6321 to d619025 Compare May 12, 2021 05:32
If single-value pools have a weight defined, it will be lost by this
optimization. Next time octodns-sync is run, it will show an update for
setting the weight on remote. To overcome this, this commit includes a
change to Record object that ignores the weight in single-value pools.
@viranch
Copy link
Collaborator Author

viranch commented May 12, 2021

alright done with force pushes (sorry!) and more commits, this is ready for review.

@ross
Copy link
Contributor

ross commented May 14, 2021

I originally looked at Azure dynamic support and bailed b/c they didn't support transparently having www.foo.com. backed by a Traffic Manager setup when the TM used geo rules. Looked like you skirted that by using a CNAME and making the trafficmanager.net. hop visible? I wasn't super keen on that setup since it was SO different from how everthing else would work and I didn't want to mix NS1/Dyn/Route53 records where it'd be direct and Azure where there'd be an extra hop/CNAME.

That was more of a specific product decision at the time (didn't want it visible for github.com etc.) and Azure lost out in the selection as a result. I really wish they'd address that, but I'm not opposed having support that does it (I just wouldn't use it for "big" things.) 😁

alright done with force pushes (sorry!) and more commits, this is ready for review.

Cool. Will aim to dig into this today.

@viranch
Copy link
Collaborator Author

viranch commented May 14, 2021

using a CNAME and making the trafficmanager.net. hop visible

I am not CNAMEing to the traffic manager, I am using 'Nested' endpoint to select the target traffic manager from a dropdown. This makes the CNAME hop visible, no way around it. Azure might rollout a feature to hide that CNAME hop at some point.

mix NS1/Dyn/Route53 records where it'd be direct and Azure where there'd be an extra hop/CNAME

Agreed, it's not a uniform behavior across providers and you'd be better off without the extra CNAME hop.

@ross
Copy link
Contributor

ross commented May 14, 2021

using a CNAME and making the trafficmanager.net. hop visible

I am not CNAMEing to the traffic manager, I am using 'Nested' endpoint to select the target traffic manager from a dropdown. This makes the CNAME hop visible, no way around it. Azure might rollout a feature to hide that CNAME hop at some point.

Oh that would have been a blocker if I'd known/realized it back when I evaled things. At the time I couldn't point it at a Geo TM so I stopped there. Amazingly I could point it at something else that was supported and then go in and change the TM to be a Geo and it seemed to work, but I wasn't actually going to try hijinks like that with a real/production setup.

Copy link
Contributor

@ross ross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a first pass through and added a few comments/questions. Will look more deeply 🔜

README.md Outdated Show resolved Hide resolved
octodns/provider/azuredns.py Show resolved Hide resolved
octodns/provider/azuredns.py Show resolved Hide resolved
@ross ross mentioned this pull request May 16, 2021
Copy link
Contributor

@ross ross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think things are good here if it's working for you and you're happy with it. I don't really have an Azure setup to test this with currently so sort of going to take your word for it 😁

Couple more questions inline I'll let you review/ack. Once that's done we can :shipit:

octodns/record/__init__.py Outdated Show resolved Hide resolved
octodns/provider/azuredns.py Show resolved Hide resolved
@ross ross merged commit a79e2f3 into octodns:master May 18, 2021
@viranch viranch deleted the azuredns-dynamic branch May 18, 2021 03:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants