Skip to content

Commit 65e805c

Browse files
Add a new template to configure regionally highly-available private loadbalancer. Change hybrid_dns template to update default DHCP options with custom DNS servers (#439)
* Update default DHCP options to use the custom DNS servers * New example to demonstrate regionally HA setup of private loadbalancers * Update image in Readme * Minor change for better organization * Minor changes for better organization * Fixed review comments. * Moved regional_private_lb to solutions/
1 parent 66f1065 commit 65e805c

File tree

18 files changed

+1051
-5
lines changed

18 files changed

+1051
-5
lines changed

docs/examples/networking/hybrid_dns/dns.tf

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ resource "oci_core_virtual_network" "CoreVCN" {
7575
cidr_block = "${var.vcn_cidr}"
7676
compartment_id = "${var.compartment_ocid}"
7777
display_name = "mgmt-vcn"
78+
dns_label = "mgmtvcn"
7879
}
7980

8081
resource "oci_core_internet_gateway" "MgmtIG" {
@@ -172,6 +173,7 @@ resource "oci_core_subnet" "MgmtSubnet" {
172173
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD1 - 1],"name")}"
173174
cidr_block = "${var.mgmt_subnet_cidr1}"
174175
display_name = "MgmtSubnet"
176+
dns_label = "mgmtsubnet"
175177
compartment_id = "${var.compartment_ocid}"
176178
vcn_id = "${oci_core_virtual_network.CoreVCN.id}"
177179
route_table_id = "${oci_core_route_table.MgmtRouteTable.id}"
@@ -183,6 +185,7 @@ resource "oci_core_subnet" "MgmtSubnet2" {
183185
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD2 - 1],"name")}"
184186
cidr_block = "${var.mgmt_subnet_cidr2}"
185187
display_name = "MgmtSubnet2"
188+
dns_label = "mgmtsubnet2"
186189
compartment_id = "${var.compartment_ocid}"
187190
vcn_id = "${oci_core_virtual_network.CoreVCN.id}"
188191
route_table_id = "${oci_core_route_table.MgmtRouteTable.id}"
@@ -246,12 +249,23 @@ data "oci_core_vnic" "DnsVMVnic2" {
246249
vnic_id = "${lookup(data.oci_core_vnic_attachments.DnsVMVnics2.vnic_attachments[0],"vnic_id")}"
247250
}
248251

249-
output "DefaultDHCPOptions" {
250-
value = ["${oci_core_virtual_network.CoreVCN.default_dhcp_options_id}"]
251-
}
252+
# Update the default DHCP options to use custom DNS servers
253+
resource "oci_core_default_dhcp_options" "default-dhcp-options" {
254+
manage_default_resource_id = "${oci_core_virtual_network.CoreVCN.default_dhcp_options_id}"
252255

253-
output "VcnId" {
254-
value = ["${oci_core_virtual_network.CoreVCN.id}"]
256+
// required
257+
options {
258+
type = "DomainNameServer"
259+
server_type = "CustomDnsServer"
260+
custom_dns_servers = [ "${data.oci_core_vnic.DnsVMVnic.private_ip_address}",
261+
"${data.oci_core_vnic.DnsVMVnic2.private_ip_address}" ]
262+
}
263+
264+
// optional
265+
options {
266+
type = "SearchDomain"
267+
search_domain_names = [ "${oci_core_virtual_network.CoreVCN.dns_label}.oraclevcn.com" ]
268+
}
255269
}
256270

257271
output "DnsServer1" {
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# ___ ____ _ ____ _ _____
2+
# / _ \| _ \ / \ / ___| | | ____|
3+
# | | | | |_) | / _ \| | | | | _|
4+
# | |_| | _ < / ___ | |___| |___| |___
5+
# \___/|_| \_/_/ \_\____|_____|_____|
6+
***
7+
This example configures a regionally highly-available private load balancer using custom DNS servers.
8+
9+
It creates a VCN with the required subnets and other components, and it creates two private load balancers in two availability domains with the same set of backend instances.
10+
11+
It then creates two VMs (in the same ADs but different subnets) and configures them to perform DNS forwarding. It creates a custom domain and adds a round-robin DNS entry which resolves to the two private load balancer IP addresses. It also updates the default DHCP options of the VCN to use the DNS VMs as the custom DNS resolvers. With this setup, all instances in subnets that uses the default DHCP options (or the custom DNS servers explicitly) will be able to use the FQDN as the endpoint (instead of any one private load balancer's IP address).
12+
13+
It configures [monit](https://mmonit.com/monit/) (an open-source utility to monitor unix systems) on the DNS VMs to check the availability of the private load balancer's listener endpoint. In case the endpoint becomes unavailable, the monitoring service updates the DNS records to remove the private load balancer's IP.
14+
15+
In case of an AD-level failure or when a private load balancer is down, 'monit' will detect that endpoint is down and remove it from round-robin DNS entries. When clients query for the FQDN, it resolves to the IP address of the other private load balancer which is available.
16+
17+
![Architecture diagram](images/regional_ha_private_lb.png)
18+
19+
20+
### Using this example
21+
* Update env-vars with the required information. Most examples use the same set of environment variables so you only need to do this once.
22+
* Source env-vars
23+
* `$ . env-vars`
24+
25+
Once the environment is built, the DNS VMs will be able to query the DNS hostnames within the VCN. You can run 'nslookup <fqdn-of-the-app>' from any instance in the VCN (that uses default DHCP options) to verify this.
26+
27+
### Files in the configuration
28+
29+
#### `env-vars`
30+
Is used to export the environmental variables used in the configuration. These are usually authentication related, be sure to exclude this file from your version control system. It's typical to keep this file outside of the configuration.
31+
32+
Before you plan, apply, or destroy the configuration source the file -
33+
`$ . env-vars`
34+
35+
### `provider.tf`
36+
Defines the provider configuration
37+
38+
#### `variables.tf`
39+
Defines the variables
40+
41+
#### `network.tf`
42+
Defines the network resources - VCN, subnets and other related resources
43+
44+
### `lb_private.tf`
45+
Defines the private load balancer configuration
46+
47+
### `lb_backends.tf`
48+
Defines the backend VMs to be included into the load balancer backendsets
49+
50+
### `dns_instances.tf`
51+
Defines the DNS VMs and the configuration to be performned on these instances
52+
53+
### `outputs.tf`
54+
Shows the IP addresses of the DNS VMs and the private load balancers
55+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Gets a list of Availability Domains
2+
data "oci_identity_availability_domains" "ADs" {
3+
compartment_id = "${var.tenancy_ocid}"
4+
}
5+
6+
# Gets a list of vNIC attachments of the instance
7+
data "oci_core_vnic_attachments" "Instance1Vnics" {
8+
compartment_id = "${var.compartment_ocid}"
9+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD1 - 1],"name")}"
10+
instance_id = "${oci_core_instance.instance1.id}"
11+
}
12+
13+
# Gets the OCID of the first (default) vNIC
14+
data "oci_core_vnic" "Instance1Vnic" {
15+
vnic_id = "${lookup(data.oci_core_vnic_attachments.Instance1Vnics.vnic_attachments[0],"vnic_id")}"
16+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
;
2+
; Named file for custom entries in ha.oraclevcn.com
3+
;
4+
$TTL 5S
5+
@ IN SOA ha.oraclevcn.com. root.ha.oraclevcn.com. (
6+
2018012810 ; Serial
7+
604800 ; Refresh
8+
86400 ; Retry
9+
2419200 ; Expire
10+
604800 ) ; Negative Cache TTL
11+
;
12+
NS ha.oraclevcn.com.
13+
A ${dns_server_ip}
14+
15+
;; Round robin entry for the private loadbalancer
16+
${app} IN A ${lb_ip1}
17+
${app} IN A ${lb_ip2}
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
2+
# Launch and configure DNS VMs
3+
4+
resource "oci_core_instance" "DnsVM1" {
5+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD1 - 1],"name")}"
6+
compartment_id = "${var.compartment_ocid}"
7+
display_name = "DnsVM1"
8+
image = "${var.InstanceImageOCID[var.region]}"
9+
shape = "${var.InstanceShape}"
10+
create_vnic_details {
11+
subnet_id = "${oci_core_subnet.MgmtSubnet1.id}"
12+
}
13+
metadata {
14+
ssh_authorized_keys = "${var.ssh_public_key}"
15+
}
16+
timeouts {
17+
create = "10m"
18+
}
19+
}
20+
21+
resource "oci_core_instance" "DnsVM2" {
22+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD2 - 1],"name")}"
23+
compartment_id = "${var.compartment_ocid}"
24+
display_name = "DnsVM2"
25+
image = "${var.InstanceImageOCID[var.region]}"
26+
shape = "${var.InstanceShape}"
27+
create_vnic_details {
28+
subnet_id = "${oci_core_subnet.MgmtSubnet2.id}"
29+
}
30+
metadata {
31+
ssh_authorized_keys = "${var.ssh_public_key}"
32+
}
33+
timeouts {
34+
create = "10m"
35+
}
36+
}
37+
38+
# Gets a list of VNIC attachments on the DNS instance
39+
data "oci_core_vnic_attachments" "DnsVM1Vnics" {
40+
compartment_id = "${var.compartment_ocid}"
41+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD1 - 1],"name")}"
42+
instance_id = "${oci_core_instance.DnsVM1.id}"
43+
}
44+
45+
data "oci_core_vnic_attachments" "DnsVM2Vnics" {
46+
compartment_id = "${var.compartment_ocid}"
47+
availability_domain = "${lookup(data.oci_identity_availability_domains.ADs.availability_domains[var.AD2 - 1],"name")}"
48+
instance_id = "${oci_core_instance.DnsVM2.id}"
49+
}
50+
51+
# Gets the OCID of the first (default) vNIC
52+
data "oci_core_vnic" "DnsVMVnic" {
53+
vnic_id = "${lookup(data.oci_core_vnic_attachments.DnsVM1Vnics.vnic_attachments[0],"vnic_id")}"
54+
}
55+
56+
data "oci_core_vnic" "DnsVMVnic2" {
57+
vnic_id = "${lookup(data.oci_core_vnic_attachments.DnsVM2Vnics.vnic_attachments[0],"vnic_id")}"
58+
}
59+
60+
# Update the default DHCP options to use custom DNS servers
61+
resource "oci_core_default_dhcp_options" "default-dhcp-options" {
62+
manage_default_resource_id = "${oci_core_virtual_network.MgmtVcn.default_dhcp_options_id}"
63+
64+
options {
65+
type = "DomainNameServer"
66+
server_type = "CustomDnsServer"
67+
custom_dns_servers = [ "${data.oci_core_vnic.DnsVMVnic.private_ip_address}",
68+
"${data.oci_core_vnic.DnsVMVnic2.private_ip_address}" ]
69+
}
70+
71+
options {
72+
type = "SearchDomain"
73+
search_domain_names = [ "${oci_core_virtual_network.MgmtVcn.dns_label}.oraclevcn.com" ]
74+
}
75+
}
76+
77+
data "template_file" "generate_named_conf" {
78+
template = "${file("named.conf.tpl")}"
79+
80+
vars {
81+
vcn_cidr = "${var.vcn_cidr}"
82+
zone = "${var.ha_app_domain}"
83+
onprem_cidr = "${var.onprem_cidr}"
84+
onprem_domain = "${var.onprem_domain}"
85+
onprem_dns_server1 = "${var.onprem_dns_server1}"
86+
onprem_dns_server2 = "${var.onprem_dns_server2}"
87+
}
88+
}
89+
90+
data "template_file" "generate_db_zone_vm1" {
91+
template = "${file("db.zone.tmpl")}"
92+
93+
vars {
94+
dns_server_ip = "${data.oci_core_vnic.DnsVMVnic.private_ip_address}"
95+
app = "${var.ha_app_name}"
96+
lb_ip1 = "${oci_load_balancer.lb1.ip_addresses[0]}"
97+
lb_ip2 = "${oci_load_balancer.lb2.ip_addresses[0]}"
98+
}
99+
}
100+
101+
data "template_file" "generate_db_zone_vm2" {
102+
template = "${file("db.zone.tmpl")}"
103+
104+
vars {
105+
dns_server_ip = "${data.oci_core_vnic.DnsVMVnic2.private_ip_address}"
106+
app = "${var.ha_app_name}"
107+
lb_ip1 = "${oci_load_balancer.lb1.ip_addresses[0]}"
108+
lb_ip2 = "${oci_load_balancer.lb2.ip_addresses[0]}"
109+
}
110+
}
111+
112+
data "template_file" "generate_monitrc" {
113+
template = "${file("monitrc.tmpl")}"
114+
115+
vars {
116+
lb_ip1 = "${oci_load_balancer.lb1.ip_addresses[0]}"
117+
lb_ip2 = "${oci_load_balancer.lb2.ip_addresses[0]}"
118+
lb_port = "${var.ha_app_port}"
119+
lb_protocol = "${var.ha_app_protocol}"
120+
app = "${var.ha_app_name}"
121+
zone_file = "/etc/named/db.${var.ha_app_domain}"
122+
}
123+
}
124+
125+
resource "null_resource" "configure-bind-vm1" {
126+
connection {
127+
type = "ssh"
128+
user = "opc"
129+
private_key = "${var.ssh_private_key}"
130+
host = "${data.oci_core_vnic.DnsVMVnic.public_ip_address}"
131+
timeout = "30m"
132+
}
133+
134+
provisioner "file" {
135+
content = "${data.template_file.generate_named_conf.rendered}"
136+
destination = "~/named.conf"
137+
}
138+
139+
provisioner "file" {
140+
content = "${data.template_file.generate_db_zone_vm1.rendered}"
141+
destination = "~/db.${var.ha_app_domain}"
142+
}
143+
144+
provisioner "file" {
145+
content = "${data.template_file.generate_monitrc.rendered}"
146+
destination = "~/monitrc"
147+
}
148+
149+
provisioner "file" {
150+
source = "dnsops"
151+
destination = "~/dnsops"
152+
}
153+
154+
provisioner "remote-exec" {
155+
inline = [
156+
"sudo yum update -y",
157+
158+
"sudo yum install bind -y",
159+
"sudo cp ~/named.conf /etc/named.conf",
160+
"sudo cp ~/db.${var.ha_app_domain} /etc/named/db.${var.ha_app_domain}",
161+
"sudo systemctl enable named",
162+
"sudo systemctl restart named",
163+
164+
"sudo firewall-offline-cmd --add-port=53/udp",
165+
"sudo firewall-offline-cmd --add-port=53/tcp",
166+
"sudo /bin/systemctl restart firewalld",
167+
168+
"sudo yum install monit -y",
169+
"sudo cp ~/monitrc /etc/monitrc",
170+
"sudo chmod +x ~/dnsops/*",
171+
"sudo systemctl enable monit",
172+
"sudo systemctl restart monit"
173+
]
174+
}
175+
}
176+
177+
resource "null_resource" "configure-bind-vm2" {
178+
connection {
179+
type = "ssh"
180+
user = "opc"
181+
private_key = "${var.ssh_private_key}"
182+
host = "${data.oci_core_vnic.DnsVMVnic2.public_ip_address}"
183+
timeout = "30m"
184+
}
185+
186+
provisioner "file" {
187+
content = "${data.template_file.generate_named_conf.rendered}"
188+
destination = "~/named.conf"
189+
}
190+
191+
provisioner "file" {
192+
content = "${data.template_file.generate_db_zone_vm2.rendered}"
193+
destination = "~/db.${var.ha_app_domain}"
194+
}
195+
196+
provisioner "file" {
197+
content = "${data.template_file.generate_monitrc.rendered}"
198+
destination = "~/monitrc"
199+
}
200+
201+
provisioner "file" {
202+
source = "dnsops"
203+
destination = "~/dnsops"
204+
}
205+
206+
provisioner "remote-exec" {
207+
inline = [
208+
"sudo yum update -y",
209+
210+
"sudo yum install bind -y",
211+
"sudo cp ~/named.conf /etc/named.conf",
212+
"sudo cp ~/db.${var.ha_app_domain} /etc/named/db.${var.ha_app_domain}",
213+
"sudo systemctl enable named",
214+
"sudo systemctl restart named",
215+
216+
"sudo firewall-offline-cmd --add-port=53/udp",
217+
"sudo firewall-offline-cmd --add-port=53/tcp",
218+
"sudo /bin/systemctl restart firewalld",
219+
220+
"sudo yum install monit -y",
221+
"sudo cp ~/monitrc /etc/monitrc",
222+
"sudo chmod +x ~/dnsops/*",
223+
"sudo systemctl enable monit",
224+
"sudo systemctl restart monit"
225+
]
226+
}
227+
}
228+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
3+
zonefile=$1
4+
ip=$2
5+
name=$3
6+
7+
if [ $(grep ^$name $zonefile | grep -qs $ip ; echo $?) != 0 ]
8+
then
9+
echo "$name IN A $ip" >> $zonefile
10+
fi
11+
12+
systemctl reload named

0 commit comments

Comments
 (0)