Provision a MariaDB RDS Database Instance with CloudFormation in AWS

I’m now 5 posts into this series (and 5 months in), and I’m finally ready to start talking about provisioning my workload, i.e. WordPress. I’ve laid out a rough outline for this, and it’s clearly too much for a single blog post, so I’m going to split it into 3 posts, which I’ll try to publish in the next 3 weeks or so (rather than 3 months, as I’ve been pacing myself until now). After all, I’ve spent twice as much time (in terms of months, not man hours) writing this series as I spent building and launching my blog on AWS. So the next three posts will be:

  1. Provision a MariaDB RDS Database Instance with CloudFormation in AWS (this post)
  2. And Finally, a WordPress Cluster using CloudFormation in AWS
  3. How’s About we add a Scaling Policy, eh?

This post and the last one will be relatively brief, but the middle post will be substantial enough to justify splitting it up. So let’s get started.

When we’re done with this post, the state of our infrastructure will look like:

Current state of VPC with MariaDB

I’ve draw a path from the MariaDB cluster to the NAT, which may seem a little strange. But it may actually use the NAT for patching, and it could even reach out to the Internet via a stored procedure or something like that. I don’t really expect either of those things to happen, but the NAT is available to the whole private subnet so I drew the line. I’m guessing Amazon can update the server without having to reach out to the Internet, I’m pretty sure WordPress doesn’t have any stored procedures that call out to the Internet, and I’m quite certain I’m not going to write one.

The MariaDB Resources

The first resource we’ll define in our template will be a dedicated security group for MariaDB. We’ve already done a couple of security groups, and there’s nothing special about this one. It looks like:

The security group just allows inbound port 3306, which is the standard port for MariaDB. It only allows connections from the range of addresses defined for the VPC. Technically, maybe it should only allow connections from the private subnet, unless you need to use tools like MySQL Workbench, which you can use by setting up SSH tunneling through the Bastion Host. If you can live with phpMyAdmin, you can install that later on the same servers running WordPress and lock it down to just the subnet.

The next, fairly trivial, resource is a database subnet group, which just as the name implies, is just a list of subnet ids to which MariaDB can be deployed. Conveniently, we ask for a list of subnets as a parameter, so we just pass that in. Note that to do a multiple availability zone deployment of MariaDB (or any other RDS instance type), you need at least two subnets.

Pretty sure you can specify more than two, but at any given time RDS will only be using two of them, because multiple availability zones in this case means one master and one synchronous standby replica, in two different availability zones. Your clients access MariaDB through a CNAME DNS record which points to the master, and if Amazon determines the master has failed it points the CNAME at the replica. Otherwise, you can’t directly address the replica.

This setup addresses High Availability, not horizontal scalability, which is why in the picture, for the database cluster, I only show up/down arrows because this RDS can only scale vertically. For horizontal scaling, you need to look at read replicas, a completely separate topic, and something I’m not using in this setup.

Anyway, here is the database subnet group:

And finally, there is the database instance resource, which looks like:

A surprisingly simple declaration for such a powerful construct. We pass in a database name, admin user name, and password, all of which were gathered as parameters. We also set a database instance class (more or less the VM instance size), the amount of storage we want allocated (minimum of 5G), and a Boolean to indicate if we want multiple availability zones or not.

Keep in mind that a multiple-AZ deployment costs twice as much as a single instance. Makes sense, twice the fun, twice the cost. And Amazon promises to make a reasonable effort to maintain 99.95% uptime over any monthly billing cycle for multi-AZ RDS deployments. Don’t know if there’s an SLA for single-AZ deployments, but I haven’t seen it. For what it’s worth, over the last 4 months, and according to uptime testing from Pingdom, I’ve maintained 99.99% uptime. And of course, I hard-coded the database engine to MariaDB.

Deploying the MariaDB Instance

To deploy, just upload the template in the zip file below to CloudFormation and fill in the parameters. Here’s what I entered for the parameters:

The MariaDB Parameters

First note that all of the parameters I’ve marked with a red asterisk are not actually used at this time. They’ll come into play in my next post where we’ll add the WordPress instances and load balancer to the template. I’ve gone ahead and filled them in correctly so for my next deployment I can just skip parameters.

The DBUser and DBPassword parameters are for the database administrator. The DBName is the name of the database to which WordPress will be deployed. I’ve set the DBClass to db.t3.micro; this is the equivalent to Instance Type for the VMs and I’ve selected the smallest t3 size I could. I’ve also entered 5 for the DBAllocated storage which is 5 GB, the smallest hard drive you can allocate. I’ve also entered true for MultiAZ (but choose false if you want to save a little money), and selected the VPC I deployed in the first post in this series, and the two private subnets from that VPC. Click create stack and smoke em’ if you’ve got em’, because this is a pretty slow deployment (took about 15 minutes for me).

Testing the MariaDB Instance

First we’re going to need to SSH into our Bastion host. Next we need to install the MariaDB package:

Now run the client like so (the command is mysql, but it’s actually the MariaDB client as evidenced by the first line of output):

The user name and password are whatever you entered into the parameters when you deployed the stack. The host name is the CNAME for your RDS instance, which you can get from RDS in the console, or the Outputs tab of your stack in the CloudFormation console. If you are able to connect, and you can run show databases, and your database is listed (mine is wordpressdb), then you’re in business.

Sum Up

And finally, we’re ready to install some WordPress. No, really this time. I’ll do that in my next post. – the CloudFormation template.

Leave a Comment