Using the new Gandi provider
Table of contents
Manage your Gandi DNS records via Terraform with open source tools and free commercial products. Also, setup your repository for better documentation writing with Vale.
🔗 view the source code
The new Gandi Terraform provider dropped on the 30th of September, 2022. I can’t remember where I read the news from but this is pretty good news for me. Now I can start managing my DNS records using Terraform. I’d done this at 18F back in my time there and now that my DNS registrar has a Terraform provider I’m aware of, I decided to give it a shot.
➡️ Checkout the Gandi Terraform provider on the Terraform Registry.
I’ve used Gandi for a long time as my personal choice in DNS providers. And if you happen to use Gandi as your domain registrar, then this should help you dive right in. And if you’re not that’s okay too. You might learn something from this, but I can’t promise anything.
➡️ Learn more about Gandi.
➡️ The blog post on marco.org about domain registrars that introduced me to Gandi
Get the TF into version control (Link to this header)
The first major steps for me here was to get started and create a repository for the code. I use sourcehut for my open source development now. I’ve made the switch about a year ago. I love it. If you haven’t checked out sourcehut yet, I recommend it.
➡️ Checkout sourcehut.
I went ahead and started a repository from scratch with the intentions of writing Terraform code. The initial scaffolding here covers a license, documentation, tooling around documentation, and the bare Terraform that’s required to exist to get started using the provider. It won’t do anything, but it’s the foundation you need.
➡️ Here’s the commits so far
The documentation is important (Link to this header)
Documentation is everywhere. It’s important to get it right. Things like spelling, repetition, and sentence structure don’t come easy to me. I like to have the computer suggest things based on rules I find or can even write myself. I like to use Vale to make sure that what I write makes sense to the reader.
➡️ Checkout the Vale command-line tool.
You could tie
vale into your CI/CD process using the same steps to have it run
in your editor. Choose what you’d like but the best part for me is that it
covers a lot of edge cases in my writing such as spelling mistakes, using
passive voice, and generally trying to “write good”. That last one is an open
source package for Vale which is easy enough to install.
I keep a basic
vale.ini file in my home directory just to make sure I have the
my editor’s linting running without crashing.
But to actually use Vale in a better way, you’ll probably want something like this using the built-ins.
Note that this one uses the
write-good package that I manually installed into
.vale/styles directory in the repository. Also note that the Vocab
and the Styles are different directories to Vale. That’s why line 8 above is a
comment. I don’t have custom styles but I do have custom spellings.
Get the TF state off my laptop (Link to this header)
It’s important to securely store the Terraform state file even if it’s on your machine. I like to get the TF state off of my machine, but I do this at work where someone else is paying for the secure storage. While it’s convenient that Terraform uses local state storage by default I consider it an anti-pattern. But like I mentioned, cloud storage costs money. HashiCorp provides a free tier to their Terraform Cloud
You can still plan and work with your variables locally, but you can store your state file in your private account for free. There’s more information about what you can do below.
➡️ Checkout the official documentation on Terraform Cloud Free Organizations
The following code is a breakdown of the least amount of work I did before getting started with the Terraform CLI and logging into my new Terraform Cloud account.
➡️ Here's the code or click the non-highlighted part of this sentence to see it without leaving the page.
Make sure you login to Terraform using the CLI after creating your Terraform
Cloud account. I’ve shortened the CLI to
tf with an alias. Once you’ve logged
in, you can start using Terraform the way you expect to with a backend
configuration such as AWS S3, but if you opt-in to remote execution you get a
nice little web URL to track your plans and applies in the Terraform Cloud UI.
➡️ Learn more about Backend configuration for Terraform
Once you’ve logged into Terraform Cloud locally, the following Terraform will let you use it as your backend configuration. Learn more about it in the official docs above.
➡️ Sign up for Terraform Cloud
It doesn’t just have to be the state (Link to this header)
While I choose to keep my secret variables and have my plans and applies execute locally, Terraform Cloud does off some benefits if you use the more mainstream version control systems. They don’t support integrating with sourcehut, so I will be sticking to using my local machine to run things, but I do still appreciate having some secure storage for my state files behind a username and password.
But it’s nice that you can store environmental variables and sensitive
variables you’d expect to put in a
terraform.tfvars file. They also support a
UI and remote execution for your Terraform commands. Not all commands, but most
of the important ones. And if you do have a supported SCM system, then you have
trigger builds whenever you push code to your repository.
It’s DNS (Link to this header)
As mentioned earlier, this is all about DNS. Specifically, it’s about updating DNS records. I love this pattern of using Terraform to manage them as most DNS records are not considered sensitive information. But it’s too common to keep these sort of records behind closed doors of an authenticated web UI. That means you will have to log in just to verify your DNS settings. It also means that you would need to share a screenshot or have someone log into your account to manage your DNS records. I like that you could just have people take a look at some code to verify that your DNS records are setup properly. There’s a better way. And that way is configuring your DNS records via infrastructure as code.
Security around DNS (Link to this header)
Are DNS records secure? I asked myself that a lot and found out that they
aren’t most of the time. It’s possible that some things like an IP address or a
URI is not public, but there is no real sensitive information. But consider the
value of a
TXT record. Those may look sensitive considering that sometimes
you need to generate these to prove trust somewhere on the internet. But, these
records are also tied to your domain as well and are accessible via
You’re welcome to do what you want with that
google-site-verification value up
there. But if it’s not coming from my domain, then it’s useless to you. As usual
though, my threat model is not the same as yours. Always make sure you assess
one for yourself and your situation.
Writing the Terraform (Link to this header)
Now the Terraform code for the using provider specifically is in my DNS repository. But, I’m going to include an example using the default DNS resources you’ll need to import your Gandi LiveDNS records. You will probably want to import those into your Terraform state rather than creating them. But the Gandi provider will not delete or override LiveDNS domains from your infrastructure. Some providers I’ve used do this.
Importing the infrastructure (Link to this header)
This part of the documentation for the provider is a little sparse. I’m working on figuring out how to contribute back to the provider repository to include some better examples but it easy to figure out from reading the source code as long as you’re comfortable with Go.
➡️ The Terraform import command
When importing infrastructure via the Terraform CLI, you need to target the import with both an address and an identity. The address part is easy to understand. It’s the part of the code you write to create a resource.
This translates to the following command to import this into your Terraform state file.
As I said, the code for this is pretty straight forward to read.
➡️ This is the line where the ID gets set to the name that’s passed in.
If you have more questions on this, you can get some answers from the official documentation soon. For now, go explore the codebase to see what the definitions for the other IDs are.
Running the plans and applies with safety (Link to this header)
With this provider in particular, it’s great that DNS records get updated in place. As usual, Terraform will update or control parts of the infrastructure that it knows about leaving the rest of the infrastructure alone.
Known issues around the Gandi API and the Terraform provider include setting
a long value for
TXT records. The solution seems to include escaped quotes in
your DNS record values to prevent the Gandi API from splitting up the values.
➡️ Remember to include escaped quotes in your TXT records to avoid running into this bug.
I had minimal issues with the provider and I’m excited to manage more of my Gandi infrastructure with Terraform going forward. Thanks for making it this far and reading this. I hope it helps you understand more how to leverage Terraform to manage your DNS records with Gandi.