Conversation
erinecon
left a comment
There was a problem hiding this comment.
Thanks so much for writing this page! I think it provides a nice overview of the project and how all the charms work together :D
Most of my comments are nits, but my intention was to try to reduce ambiguity and make Vale happy.
| @@ -0,0 +1,39 @@ | |||
| # The DNS charms project | |||
|
|
|||
| The goal of the suite of DNS charms is to provide an easy-to-use and somewhat opinionated way to deploy DNS for your infrastructure using Juju. Since DNS can be used in many different ways and bind (the DNS server that we use as a workload for these charms) can be configured in many different ways, it is difficult to choose “one true way”. Since we intend to use them for our own infrastructure, we had some constraints that guided our decisions along the way. We still hope that the result is usable by a large majority of people who want a quick, production-ready solution that also scales to quite large deployments. | |||
There was a problem hiding this comment.
| The goal of the suite of DNS charms is to provide an easy-to-use and somewhat opinionated way to deploy DNS for your infrastructure using Juju. Since DNS can be used in many different ways and bind (the DNS server that we use as a workload for these charms) can be configured in many different ways, it is difficult to choose “one true way”. Since we intend to use them for our own infrastructure, we had some constraints that guided our decisions along the way. We still hope that the result is usable by a large majority of people who want a quick, production-ready solution that also scales to quite large deployments. | |
| The goal of the suite of DNS charms is to provide an easy-to-use and somewhat opinionated way to deploy DNS for your infrastructure using Juju. Since DNS can be used in many different ways and bind (the DNS server that we use as a workload for these charms) can be configured in many different ways, it is difficult to choose “one true way”. Since we intend to use DNS for our own infrastructure, we had some constraints that guided our decisions along the way. We still hope that the result is usable by a large majority of people who want a quick, production-ready solution that also scales to quite large deployments. |
"Them" was a bit confusing to me during my read-through, so I added a suggestion to try and clarify it. Feel free to update if I misunderstood
|
|
||
| ## `dns_record` interface | ||
|
|
||
| The first and simplest way to use these charms is by only deploying an authoritative DNS server (here `bind-operator`) and giving it a list of DNS records to be published. We want the operator to be able to give a list of DNS records as they usually would in a zone file. The format should therefore ideally be `host_label`, `TTL`, `record_class`, `record_type` and `record_data`. We can see that in that situation, someone is asking for those records to be published and someone is publishing them. The operator or charm asking for those records will be the requirer and the authoritative nameserver is the provider. |
There was a problem hiding this comment.
| The first and simplest way to use these charms is by only deploying an authoritative DNS server (here `bind-operator`) and giving it a list of DNS records to be published. We want the operator to be able to give a list of DNS records as they usually would in a zone file. The format should therefore ideally be `host_label`, `TTL`, `record_class`, `record_type` and `record_data`. We can see that in that situation, someone is asking for those records to be published and someone is publishing them. The operator or charm asking for those records will be the requirer and the authoritative nameserver is the provider. | |
| The first and simplest way to use these charms is by only deploying an authoritative DNS server (here `bind-operator`) and giving it a list of DNS records to be published. We want the operator to be able to give a list of DNS records as they usually would in a zone file. The format should therefore ideally be `host_label`, `TTL`, `record_class`, `record_type` and `record_data`. We can see that in this situation, someone is asking for those records to be published and someone is publishing them. The operator or charm asking for those records will be the requirer, and the authoritative name server is the provider. |
Some nits, and also a change to make Vale happy. But if "nameserver" is the appropriate spelling, then you'll need to add it to the repo's accept.txt file
|
|
||
| <img src="./record.png" alt="DNS record" width="480" /> | ||
|
|
||
| This realization led us to design the `dns_record` interface where the requirer basically sends a list of DNS records with a UUID for each (creating a DNS entry/request that way) and the provider can respond to those requests by stating the status of each request (using the UUID given by the requirer as an identification mechanism). |
There was a problem hiding this comment.
| This realization led us to design the `dns_record` interface where the requirer basically sends a list of DNS records with a UUID for each (creating a DNS entry/request that way) and the provider can respond to those requests by stating the status of each request (using the UUID given by the requirer as an identification mechanism). | |
| This realization led us to design the `dns_record` interface, where the requirer basically sends a list of DNS records with a UUID for each (creating a DNS entry/request that way), and the provider can respond to those requests by stating the status of each request (using the UUID given by the requirer as an identification mechanism). |
Nits, trying to add some pauses to the sentence since it's long. Maybe this is just a native English reader thing, but I find that the commas help me digest the sentence better.
|
|
||
| This realization led us to design the `dns_record` interface where the requirer basically sends a list of DNS records with a UUID for each (creating a DNS entry/request that way) and the provider can respond to those requests by stating the status of each request (using the UUID given by the requirer as an identification mechanism). | ||
|
|
||
| And this is exactly what we do when relating `bind-operator` to dns-integrator and configuring the latter with a list of DNS record requests: we are abstracting away the zone file to just a list of DNS records and `bind-operator` is doing the hard work of stitching together all the requests from all the requirers into a cohesive set of DNS zone files that can be consumed and published by bind. |
There was a problem hiding this comment.
| And this is exactly what we do when relating `bind-operator` to dns-integrator and configuring the latter with a list of DNS record requests: we are abstracting away the zone file to just a list of DNS records and `bind-operator` is doing the hard work of stitching together all the requests from all the requirers into a cohesive set of DNS zone files that can be consumed and published by bind. | |
| And this is exactly what we do when integrating `bind-operator` to `dns-integrator` and configuring the latter with a list of DNS record requests: we are abstracting away the zone file to just a list of DNS records, and `bind-operator` is doing the hard work of stitching together all the requests from all the requirers into a cohesive set of DNS zone files that can be consumed and published by bind. |
|
|
||
| ## Handling DNS record request merges | ||
|
|
||
| We just explained that all DNS record requests received by `bind-operator` through its `dns_record` relations are merged into one cohesive set of zone files for it to publish. This is very different from what traditional DNS servers do, and it is also opinionated in the way those files are created. |
There was a problem hiding this comment.
| We just explained that all DNS record requests received by `bind-operator` through its `dns_record` relations are merged into one cohesive set of zone files for it to publish. This is very different from what traditional DNS servers do, and it is also opinionated in the way those files are created. | |
| We just explained that all DNS record requests received by `bind-operator` through its `dns_record` relation are merged into one cohesive set of zone files for it to publish. This is very different from what traditional DNS servers do, and it is also opinionated in the way those files are created. |
Unless there are multiple dns_record relations that are set up?
|
|
||
| <img src="./merge.png" alt="Requests merging" width="680" /> | ||
|
|
||
| This conflict handling mechanism is one expression of our opinionated way to handle this DNS deployment since it doesn't really exist in the DNS world. We wanted to make sure that operators of different teams would not step on each other's shoes while deploying applications and relating them to `bind-operator`. If you want the usual round-robin response that a DNS server like bind should give when multiple records with different data are published, we are working on allowing conflicts on a per-record basis in the `dns_record` interface. |
There was a problem hiding this comment.
| This conflict handling mechanism is one expression of our opinionated way to handle this DNS deployment since it doesn't really exist in the DNS world. We wanted to make sure that operators of different teams would not step on each other's shoes while deploying applications and relating them to `bind-operator`. If you want the usual round-robin response that a DNS server like bind should give when multiple records with different data are published, we are working on allowing conflicts on a per-record basis in the `dns_record` interface. | |
| This conflict handling mechanism is one expression of our opinionated way to handle this DNS deployment since it doesn't really exist in the DNS world. We wanted to make sure that operators of different teams would not step on each other's shoes while deploying applications and integrating them to `bind-operator`. If you want the usual round-robin response that a DNS server like bind should give when multiple records with different data are published, we are working to allow conflicts on a record-by-record basis in the `dns_record` interface. |
Trying to make Vale happier, but if you prefer the "per-record" syntax, then I recommend wrapping the paragraph with ignore flags like
<!-- vale Canonical.025a-latinisms-with-english-equivalents = NO -->
Paragraph goes here
<!-- vale Canonical.025a-latinisms-with-english-equivalents = YES -->
|
|
||
| ## Adding a policy layer | ||
|
|
||
| Now that we understand that `bind-operator` is made to publish record requests from applications deployed by various teams, it raises the question of security: which application, or more specifically which records, will we allow to go through the publishing process? We wanted this approval operation to be doable by humans and software alike. We therefore designed the `dns-policy` charm. This operator is meant to sit between bind and the requirer application, working as a provider for the requirer and a requirer for bind. All the record requests are accumulated in a database on the workload, and an overlay Django application exposes a GUI and an API to approve and/or deny those requests. All requests are uniquely identified by their UUID (generated by the requirer) so that if a record was previously approved, its data may change without having to approve it again. We made that decision because we wanted to reduce toil when an application needs to regularly change its data. The idea is that if an application has the right to publish some data on a host label in a domain, then it will retain that right until it is revoked. |
There was a problem hiding this comment.
| Now that we understand that `bind-operator` is made to publish record requests from applications deployed by various teams, it raises the question of security: which application, or more specifically which records, will we allow to go through the publishing process? We wanted this approval operation to be doable by humans and software alike. We therefore designed the `dns-policy` charm. This operator is meant to sit between bind and the requirer application, working as a provider for the requirer and a requirer for bind. All the record requests are accumulated in a database on the workload, and an overlay Django application exposes a GUI and an API to approve and/or deny those requests. All requests are uniquely identified by their UUID (generated by the requirer) so that if a record was previously approved, its data may change without having to approve it again. We made that decision because we wanted to reduce toil when an application needs to regularly change its data. The idea is that if an application has the right to publish some data on a host label in a domain, then it will retain that right until it is revoked. | |
| Now that we understand that `bind-operator` is made to publish record requests from applications deployed by various teams, it raises the question of security: which application, or more specifically which records, will we allow to go through the publishing process? We wanted this approval operation to be doable by humans and software alike. We therefore designed the `dns-policy` charm. This operator is meant to sit between bind and the requirer application, working as both a provider for the requirer application and as a requirer for bind. All the record requests are accumulated in a database on the workload, and an overlay Django application exposes a GUI and an API to approve and/or deny those requests. All requests are uniquely identified by their UUID (generated by the requirer application) so that if a record was previously approved, its data may change without having to approve it again. We made that decision because we wanted to reduce toil when an application needs to regularly change its data. The idea is that if an application has the right to publish some data on a host label in a domain, then it will retain that right until it is revoked. |
Nits, the two usages of "requirer" were a bit difficult for me to disentangle. Please correct my suggestion if I misunderstood!
There was a problem hiding this comment.
I was a bit confused about how this diagram related to the text. What do the colors represent?
|
|
||
| ## A charm for each DNS server | ||
|
|
||
| With `bind-operator` and dns-integrator, we have the core functionality necessary for our DNS setup. But we still want to be able to mimic the classic “hidden primary” setup where the primary DNS server is not visible in the zones and these are served by a set of secondaries instead. This is where the `dns-secondary` charm comes into play. When `bind-operator` gets related to `dns-secondary`, it rewrites the configuration for the zone, removing references to its own units in favor of those of `dns-secondary` and then transfers its zones to `dns-secondary`. Now `dns-secondary` can serve them without leaking any IP address of the primary deployment. |
There was a problem hiding this comment.
| With `bind-operator` and dns-integrator, we have the core functionality necessary for our DNS setup. But we still want to be able to mimic the classic “hidden primary” setup where the primary DNS server is not visible in the zones and these are served by a set of secondaries instead. This is where the `dns-secondary` charm comes into play. When `bind-operator` gets related to `dns-secondary`, it rewrites the configuration for the zone, removing references to its own units in favor of those of `dns-secondary` and then transfers its zones to `dns-secondary`. Now `dns-secondary` can serve them without leaking any IP address of the primary deployment. | |
| With `bind-operator` and `dns-integrator`, we have the core functionality necessary for our DNS setup. But we still want to be able to mimic the classic “hidden primary” setup where the primary DNS server is not visible in the zones and these are served by a set of secondaries instead. This is where the `dns-secondary` charm comes into play. When `bind-operator` gets integrated to `dns-secondary`, it rewrites the configuration for the zone, removing references to its own units in favor of those of `dns-secondary` and then transfers its zones to `dns-secondary`. Now `dns-secondary` can serve the zones without leaking the IP address of the primary deployment. |
Nits, and trying to clarify what dns-secondary is serving
|
|
||
| With `bind-operator` and dns-integrator, we have the core functionality necessary for our DNS setup. But we still want to be able to mimic the classic “hidden primary” setup where the primary DNS server is not visible in the zones and these are served by a set of secondaries instead. This is where the `dns-secondary` charm comes into play. When `bind-operator` gets related to `dns-secondary`, it rewrites the configuration for the zone, removing references to its own units in favor of those of `dns-secondary` and then transfers its zones to `dns-secondary`. Now `dns-secondary` can serve them without leaking any IP address of the primary deployment. | ||
|
|
||
| We also want to be able to deploy DNS resolvers, and that's the role of the `dns-resolver` charm. Once related to `bind-operator` or `dns-secondary`, it will serve their zones without being involved in their definition. |
There was a problem hiding this comment.
| We also want to be able to deploy DNS resolvers, and that's the role of the `dns-resolver` charm. Once related to `bind-operator` or `dns-secondary`, it will serve their zones without being involved in their definition. | |
| We also want to be able to deploy DNS resolvers, and that's the role of the `dns-resolver` charm. Once integrated to `bind-operator` or `dns-secondary`, it will serve their zones without being involved in their definition. |
Overview
Add a project-overview.md documentation file. The goal is to explain the "why" and "how" of the whole DNS suite of this repository.
Checklist
docs/changelog.mdfile was updated