Project architecture¶
DNS operators are a family of charms used to integrate a fully functional DNS solution in Juju. The core charm is the bind-operator, which acts as a primary DNS server. The underlying workload uses Bind, packaged as a snap with other tooling to help administer it from the charm perspective.
The following diagram shows how these charms are intended to be used with other charms:
C4Context
title DNS charms story
UpdateLayoutConfig($c4ShapeInRow="2", $c4BoundaryInRow="2")
Container_Boundary(is-model, "IS model") {
Component(tls-policy, "TLS policy")
Component(dns-policy, "DNS policy")
Rel(dns-policy, bind, "dns_record")
UpdateRelStyle(dns-policy, bind, $textColor="green", $lineColor="green", $offsetX="10", $offsetY="20")
Component(lego, "Lego")
Component(bind, "Bind charm")
Component(httpreq, "HTTP Request Lego Provider")
Rel(httpreq, bind, "dns_record")
Rel(lego, httpreq, "API")
Rel(tls-policy, lego, "tls-certificates")
UpdateRelStyle(httpreq, bind, $textColor="green", $lineColor="green", $offsetX="0")
UpdateRelStyle(lego, httpreq, $textColor="purple", $lineColor="purple", $offsetY="10", $offsetX="10")
UpdateRelStyle(tls-policy, lego, $textColor="red", $lineColor="red", $offsetX="10")
}
Container_Boundary(app-model, "App model") {
Component(app-1, "Application 1")
Component(ingress, "Ingress")
Component(app-2, "Application 2")
Rel(app-1, ingress, "ingress")
Rel(app-2, ingress, "ingress")
UpdateRelStyle(app-1, ingress, $textColor="blue", $lineColor="blue", $offsetX="10")
UpdateRelStyle(app-2, ingress, $textColor="blue", $lineColor="blue", $offsetX="10")
}
Rel(ingress, dns-policy, "dns_record")
Rel(ingress, tls-policy, "tls-certificates")
UpdateRelStyle(ingress, dns-policy, $textColor="green", $lineColor="green", $offsetX="30", $offsetY="-10")
UpdateRelStyle(ingress, tls-policy, $textColor="red", $lineColor="red", $offsetX="-120", $offsetY="-10")
Person(operator, "Operator")
Rel(operator, dns-policy, "approve/denies requests")
Rel(operator, tls-policy, "approve/denies requests")
UpdateRelStyle(operator, dns-policy, $offsetY="-40", $offsetX="-60")
UpdateRelStyle(operator, tls-policy, $offsetY="-200", $offsetX="-155")
The bind-operator is usually deployed with dns-policy to enable human and/or automated approval of incoming DNS record requests. The workload of dns-policy is a Django application packaged as a snap with additional tooling. Since the workloads of both bind-operator and dns-policy are snaps, they can work on the same machine. It was therefore decided to make dns-policy a subordinate charm.
The following diagram shows the interactions between bind-operator, dns-policy, and external components of a typical deployment of the DNS charms:
C4Container
title DNS charms components
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="2")
Rel(operator, charmed-dns-policy, "API", "approve/denies requests")
Component(postgresql, "Postgresql")
Person(operator, "Operator")
Component(empty1, "")
Component(empty2, "")
Component(empty3, "")
UpdateElementStyle(empty1, $bgColor="#0000", $borderColor="#0000")
UpdateElementStyle(empty2, $bgColor="#0000", $borderColor="#0000")
UpdateElementStyle(empty3, $bgColor="#0000", $borderColor="#0000")
Component(dns-integrator, "DNS integrator")
Rel(dns-integrator, dns-policy, "dns_record")
UpdateRelStyle(dns-integrator, dns-policy, $textColor="green", $lineColor="green")
Rel(charmed-dns-policy, postgresql, "database")
UpdateRelStyle(charmed-dns-policy, postgresql, $textColor="blue", $lineColor="blue", $offsetX="10")
Container_Boundary(machine-1, "Machine 1") {
Component(charmed-dns-policy, "DNS policy snap")
Component(empty6, "")
UpdateElementStyle(empty6, $bgColor="#0000", $borderColor="#0000")
Component(charmed-bind, "Bind snap")
Component(empty0, "")
UpdateElementStyle(empty0, $bgColor="#0000", $borderColor="#0000")
Component(empty5, "")
UpdateElementStyle(empty5, $bgColor="#0000", $borderColor="#0000")
Component(empty7, "")
UpdateElementStyle(empty7, $bgColor="#0000", $borderColor="#0000")
Component(dns-policy, "DNS policy charm")
Component(empty8, "")
UpdateElementStyle(empty8, $bgColor="#0000", $borderColor="#0000")
Component(bind, "Bind charm")
Rel(dns-policy, bind, "dns_record")
UpdateRelStyle(dns-policy, bind, $textColor="green", $lineColor="green", $offsetY="10")
Rel(bind, charmed-bind, "API", "Update DNS records")
Rel(dns-policy, charmed-dns-policy, "API", "Update DNS requests")
UpdateRelStyle(bind, charmed-bind, $offsetX="10")
UpdateRelStyle(dns-policy, charmed-dns-policy, $offsetX="10")
}
After having deployed and integrated all the DNS charms in one model, you should see the following output with juju status --relations:
user@host:~$ juju status --relations
Model Controller Cloud/Region Version SLA Timestamp
machine lxd localhost/localhost 3.6.5 unsupported 13:14:27-04:00
App Version Status Scale Charm Channel Rev Exposed Message
bind active 3 bind latest/edge 77 no active
dns-integrator-operator active 1 dns-integrator-operator 0 no
dns-policy active 3 dns-policy latest/edge 1 no
postgresql 14.15 active 1 postgresql 14/stable 553 no
Unit Workload Agent Machine Public address Ports Message
bind/0* active idle 0 10.227.61.237 53/tcp 53/udp active
dns-policy/0* active idle 10.227.61.237 8080/tcp
bind/1 active idle 3 10.227.61.162 53/tcp 53/udp
dns-policy/1 active idle 10.227.61.162 8080/tcp
bind/2 active idle 4 10.227.61.3 53/tcp 53/udp
dns-policy/2 active idle 10.227.61.3 8080/tcp
dns-integrator-operator/0* active idle 1 10.227.61.161
postgresql/0* active idle 2 10.227.61.146 5432/tcp Primary
Machine State Address Inst id Base AZ Message
0 started 10.227.61.237 juju-cd7a0a-0 ubuntu@22.04 Running
1 started 10.227.61.161 juju-cd7a0a-1 ubuntu@22.04 Running
2 started 10.227.61.146 juju-cd7a0a-2 ubuntu@22.04 Running
3 started 10.227.61.162 juju-cd7a0a-3 ubuntu@22.04 Running
4 started 10.227.61.3 juju-cd7a0a-4 ubuntu@22.04 Running
Integration provider Requirer Interface Type Message
bind:bind-peers bind:bind-peers bind-instance peer
bind:dns-record dns-policy:dns-record-requirer dns_record subordinate
dns-policy:dns-record-provider dns-integrator-operator:dns-record dns_record regular
postgresql:database dns-policy:database postgresql_client regular
postgresql:database-peers postgresql:database-peers postgresql_peers peer
postgresql:restart postgresql:restart rolling_op peer
postgresql:upgrade postgresql:upgrade upgrade peer
You can here observe that the DNS policy charm is a subordinate one: It will be deployed on the same machine as the Bind charm as soon as it is integrated to it.