# MongoDB 3.6: Here to SRV you with easier replica set connections

If you have logged into MongoDB Atlas
recently - and you should, the entry-level tier is free! - you may have
noticed a strange new syntax on 3.6 connection strings.

## MongoDB Seed Lists

What is this `mongodb+srv` syntax?

Well, in MongoDB 3.6 we introduced the concept of a seed
list
that is specified using DNS records, specifically
SRV and
TXT records. You will recall
from using replica sets with MongoDB that the client must specify at
least one replica set member (and may specify several of them) when
connecting. This allows a client to connect to a replica set even if one
of the nodes that the client specifies is unavailable.

You can see an example of this URL on a 3.4 cluster connection string:

Note that without the SRV record configuration we must list several
nodes (in the case of Atlas we always include all the cluster members,
though this is not required). We also have to specify the `ssl` and
`replicaSet` options.

With the 3.4 or earlier driver, we have to specify all the options on
the command line using the MongoDB URI
syntax.

The use of SRV records eliminates the requirement for every client to
pass in a complete set of state information for the cluster. Instead, a
single SRV record identifies all the nodes associated with the cluster
(and their port numbers) and an associated TXT record defines the
options for the URI.

## Reading SRV and TXT Records

We can see how this works in practice on a MongoDB Atlas cluster with a
simple Python script.

``` python
import srvlookup #pip install srvlookup
import sys 
import dns.resolver #pip install dnspython 

host = None 

if len(sys.argv) > 1 : 
   host = sys.argv1] 

if host : 
   services = srvlookup.lookup("mongodb", domain=host) 
   for i in services:
      print("%s:%i" % (i.hostname, i.port)) 
   for txtrecord in dns.resolver.query(host, 'TXT'): 
      print("%s: %s" % ( host, txtrecord))

else: 
  print("No host specified") 
```

We can run this script using the node specified in the 3.6 connection
string as a parameter.

![The node is specified in the connection string

``` sh
$ python mongodb_srv_records.py
freeclusterjd-ffp4c.mongodb.net
freeclusterjd-shard-00-00-ffp4c.mongodb.net:27017
freeclusterjd-shard-00-01-ffp4c.mongodb.net:27017
freeclusterjd-shard-00-02-ffp4c.mongodb.net:27017
freeclusterjd-ffp4c.mongodb.net: "authSource=admin&replicaSet=FreeClusterJD-shard-0" 
$ 
```

You can also do this lookup with nslookup:

``` sh
JD10Gen-old:~ jdrumgoole$ nslookup
> set type=SRV > \_mongodb._tcp.rs.joedrumgoole.com
Server: 10.65.141.1
Address: 10.65.141.1#53

Non-authoritative answer:
\_mongodb._tcp.rs.joedrumgoole.com  service = 0 0 27022 rs1.joedrumgoole.com.
\_mongodb._tcp.rs.joedrumgoole.com  service = 0 0 27022 rs2.joedrumgoole.com.
\_mongodb._tcp.rs.joedrumgoole.com  service = 0 0 27022 rs3.joedrumgoole.com.

Authoritative answers can be found from:
> set type=TXT
> rs.joedrumgoole.com
Server: 10.65.141.1
Address: 10.65.141.1#53

Non-authoritative answer:
rs.joedrumgoole.com     text = "authSource=admin&replicaSet=srvdemo"
```

You can see how this could be used to construct a 3.4 style connection
string by comparing it with the 3.4 connection string above.

As you can see, the complexity of the cluster and its configuration
parameters are stored in the DNS server and hidden from the end user. If
a node's IP address or name changes or we want to change the replica set
name, this can all now be done completely transparently from the
client's perspective. We can also add and remove nodes from a cluster
without impacting clients.

So now whenever you see `mongodb+srv` you know you are expecting a SRV
and TXT record to deliver the client connection string.

## Creating SRV and TXT records

Of course, SRV and TXT records are not just for Atlas. You can also
create your own SRV and TXT records for your self-hosted MongoDB
clusters. All you need for this is edit access to your DNS server so you
can add SRV and TXT records. In the examples that follow we are using
the AWS Route 53 DNS service.

I have set up a demo replica set on AWS with a three-node setup. They
are

``` sh
rs1.joedrumgoole.com 
rs2.joedrumgoole.com 
rs3.joedrumgoole.com
```

Each has a mongod process running on port 27022. I have set up a
security group that allows access to my local laptop and the nodes
themselves so they can see each other.

I also set up the DNS names for the above nodes in AWS Route 53.

We can start the mongod processes by running the following command on
each node.

``` sh
$ sudo /usr/local/m/versions/3.6.3/bin/mongod --auth --port 27022 --replSet srvdemo --bind_ip 0.0.0.0 --keyFile mdb_keyfile"
```

Now we need to set up the SRV and TXT records for this cluster.

The SRV record points to the server or servers that will comprise the
members of the replica set. The TXT record defines the options for the
replica set, specifically the database that will be used for
authorization and the name of the replica set. It is important to note
that the **mongodb+srv** format URI implicitly adds "ssl=true". In our
case SSL is not used for the demo so we have to append "&ssl=false" to
the client connector. Note that the SRV record is specifically designed
to look up the **mongodb** service referenced at the start of the URL.

The settings in AWS Route 53 are:

Which leads to the following entry in the zone file for Route 53.

Now we can add the TXT record. By convention, we use the same name as
the SRV record (`rs.joedrumgoole.com`) so that MongoDB knows where to
find the TXT record.

We can do this on AWS Route 53 as follows:

This will create the following TXT record.

Now we can access this service as :

``` sh
mongodb+srv://rs.joedrumgoole.com/test
```

This will retrieve a complete URL and connection string which can then
be used to contact the service.

The whole process is outlined below:

Once your records are set up, you can easily change port numbers without
impacting clients and also add and remove cluster members.

SRV records are another way in which MongoDB is making life easier for
database developers everywhere.

You should also check out full documentation on SRV and TXT records in
MongoDB
3.6.

You can sign up for a free MongoDB Atlas tier
which is suitable for single user use.

Find out how to use your favorite programming language with MongoDB via
our MongoDB drivers.

Please visit MongoDB University for
free online training in all aspects of MongoDB.

Follow Joe Drumgoole on twitter for
more news about MongoDB.