Introduction to Advanced Terraform
This is the first article in a series that will introduce some fairly advanced terraform concepts quite quickly
Updated April, 2024
Introduction
This is the first article in a series that will introduce some fairly advanced terraform concepts quite quickly. That doesn't mean it is not for beginners, terraform is good like that, you can take some complex code, see how it starts out, manipulate it, output the manipulated code (so you understand what it's doing) and then use it. This is the approach I will take in this series. I found it hard to find examples like this, there are a wealth of beginner tutorials that start slowly and build up, but there didn't seem to be much for those wanting to jump in at the deep end, so I thought I'd jot some notes down.
No-Module (child module that is)
The articles in this series are opinionated, meaning that I'm going to demonstrate a way to do things so that we can keep moving quickly. You don't have to do it this way, in Terraform there are many ways to do things. Writing this way just means I don't have to cover every eventuality, while hopefully giving you a good base to start deploying enterprise level infrastructure.
I will not be using child modules, that is not the aim of this series. If you source a module that is maintained by someone else, then you can't easily manipulate the code, you are beholden to the maintainer who may introduce some feature that breaks your code, and you are reliant on them to update it when new features are released. Sure you can pin to a child-module version, but this just encourages code to stagnate.
You can maintain your own child-modules, this works well when kept updated, but you may find that extra layer of abstraction adds complexity that you don't need. What I want to show you is how to write code that is as dynamic as using child-modules, but without the extra layer of abstraction.
What is Terraform?
Terraform is a powerful Infrastructure as Code (IaC) tool, allowing us to define, provision, and manage infrastructure through declarative configuration files. While incredibly effective, Terraform code can sometimes become complex and difficult to understand, especially for newcomers or those less familiar with its syntax.
In the articles in this collection, I'll demonstrate:
- Setting your code up for multi-region infrastructure from the off:
- Setting up your credentials so that Terraform can access your account.
- Defining and using multi-region aliased providers.
- An example of how to deploy a multi-region infrastructure.
- Terraform data structures, including objects, maps, lists and sets:
- Will mostly focus on Objects and Tuples
- Terraform Workspaces and Environments
- User friendly Terraform:
- A technique for writing Terraform code that will allow other users to easily understand and interact with your infrastructure.
- Flattening data in Terraform, a deep-dive into flattening and combining data structures:
- Keeping your local's definitions clean and easy to use/read.
- Why you might flatten data and 2 detailed examples of how to do it.
- Handling remote state
- Wrapping it all up
Articles in this collection
Terraform setup, providers and Multi-Region Deployments
Terraform data structures, Objects, Maps, Lists, Sets and Tuples
Terraform workspaces and Environments
Terraform Cloud and Remote State
Initial Setup
Install Terraform CLI
I'm going to assume you have Terraform installed, if you don't then you can find the installation instructions here. Most Linux distributions are covered in the installation instructions but if you're on Linux Mint, or another variant of Ubuntu like me, then just follow the Ubuntu apt-get method but swap the release command as follows:
# This is the command shown in the installation guide which works for Ubuntu
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
# For Ubuntu variants, swap it for this one that gets the codename from the upstream-release file instead of the `lsb_release` command
ubuntu_codename=$(grep DISTRIB_CODENAME /etc/upstream-release/lsb-release | cut -d'=' -f2)
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $ubuntu_codename main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
AWS Account
If you want to run a plan yourself using the code you find here, then it would also help that you have an AWS account to run it against. I'm going to use AWS in this series because that's the most popular Terraform provider by quite a long way, but there are plenty of other providers, including the other big cloud compute providers, Azure, Google Cloud, Alibaba Cloud etc. You can manage your GitHub organization with Terraform, deploy new repositories and manage permissions, you could manage your web hosting provider to deploy new sites, a DNS provider to manage your domains, or even your home network to manage your router. The possibilities are, well, there's a lot, at the time of writing there are over 4000 providers in the Terraform registry, sure some will be duplicates (there are multiple providers for some database engines for example) but that's still a lot of choice.
AWS Nuke
I have plenty of experience with AWS, and the first thing I do to any new AWS account is to run AWS Nuke, but this should be done with a good amount of CAUTION. If you have a new account, and there is nothing in there that you need, then feel free to check out my article on AWS Nuke.
Summary
In this article I hope I've given you an idea of what to expect from this series, some good pointers on how to get started, and a little bit of a warning about AWS Nuke. I hope you enjoy the series, and if you have any questions, feel free to reach out to me via Email