This course will teach you what you need to know to deploy Terraform resources properly and efficiently whether you're a beginner or someone looking for some new tricks. We will start with the very basics and methodically build from there, learning new information, tricks, and skills along the way. Most lessons are less than 8 minutes long to help ensure a pace that doesn't put you to sleep.
This course will teach you what you need to know to deploy Terraform resources properly and efficiently whether you're a beginner or someone looking for some new tricks. We will start with the very basics and methodically build from there, learning new information, tricks, and skills along the way. Most lessons are less than 8 minutes long to help ensure a pace that doesn't put you to sleep.
In the brand new refreshed sections (July 2024+), you'll build out a Developer Platform that deploys GitHub repositories dynamically for developers. You'll do this using the latest and greatest Terraform skills and functions.
With a focus on using built-in tools to deploy and troubleshoot your deployments, you'll be the only one not having to Google every error you find or copy and paste from Stack Overflow.
You'll learn important Terraform tools to troubleshoot and build your infrastructure as you roll out a Node-RED IoT application using Docker, a Rancher K3s Kubernetes deployment on AWS, a Kubernetes deployment of pods, and even a full CICD deployment using Terraform Cloud.
We'll focus on writing efficient code with minimal repetition while utilizing many of Terraform's advanced features such as:
Import
Join
Min
Max
Local Resource
Variables
Splat
For Loops
Dynamic Blocks
Variable Validation
Path References
String Interpolation
Local and Remote Provisioners
and more.
The entire course was recorded using quality equipment for ease of listening, intelligent zooming and cursor highlighting to ensure maximum readability and the ability to follow along easily, and annotations where necessary to quickly see web links to visit, important topics, and follow along with the resources more easily.
All of the code in the refreshed sections is tested using Terraform version 1.9+
The refreshed sections will include the latest and greatest Terraform features and functionality. The Legacy sections all are still very useful, but may have a deprecation warning or two.
So what are you waiting for? Sign up today and Terraform Apply Yourself.
In this lesson, we're going to set up and configure Codespaces. You'll need a GitHub account before you continue. If you'd like to use your own system and VS Code, you'll need to configure a GitHub token that has access to modify repositories.
In codespaces, we're given a default set of permissions every time we log in. Unfortunately, these permissions will not let Terraform delete repositories we've created, so we will need to add that permission. We'll use the GitHub CLI and a quick script to do this. If you're on your machine, you will need the GitHub CLI installed before you proceed with the course.
unset GITHUB_TOKEN && gh auth login -h github.com -p https -s delete_repo -w
Terraform's primary purpose is to orchestrate resources for clouds and other major services, such as AWS, Git Hub, and even Domino's Pizza. Typically, you would use an API to manage these services without another tool. All Terraform does is interact with the API of these services. Any service with an API can be managed by Terraform. To do this, you must use a provider. A provider translates the API's Create, Read, Update, and Delete options into a standard Terraform can understand. In this section, we'll be interacting with Github and need the GitHub provider. Let's get that set up.
The first thing you'll need to do when you have Terraform code to run is initialize the directory. This will download the providers code needed, configure and lock the versions, and configure any state storage options you may have. we'll cover all of this over the next several lessons, but the most important thing to note is that Terraform init is required before you can use Terraform to deploy. Let's check it out.
Let's examine how Terraform manages versioning with the dependency lock file. This file is similar to package-lock.json in npm or the requirements.txt in Python but has a few more features.
One of the features that makes Terraform so powerful is its state. This state, which is the state of the resources you've deployed, sets it apart from other deployment tools, such as Ansible. This state is a file that needs to be stored somewhere. It defaults to local, but you can also store it in Terraform cloud, S3, an HTTP server, or many other potential places. These storage locations are known as "backends." In this lesson, we will configure the backend to store the state locally. This isn't how you would do things in production, but since we're still learning, we will keep it local so we have easy access to it. Let's get started.
Okay, now it's time to finally create an actual resource. We're going to create a github_repository in our GitHub account. We're not going to do much with it yet, but we'll at least see how Terraform creates resources.
Now that we have our very simple resource ready, it's time to finally create it in GitHub. To do this, we're going to follow the typical Terraform workflow of code, plan, and apply. We've already coded, so now let's plan and apply. After that, we'll do the fun part and destroy it, you know, just for kicks.
Now, let's deploy a second GitHub resource. We'll add a readme file to our GitHub repository. Now, a readme file was already deployed with the repo, but we want an explicit one to be created so that we have more control over it and its content.
State is one of the most powerful features of Terraform. It contains everything Terraform needs to manage your infrastructure. The state is created as soon as you run a Terraform apply, and it keeps it up to date any time you use the apply or refresh command. There are also other commands that allow you to manage objects in the state manually, but those are for a later lesson. Let's look at our state file and see what it contains.
As you know, modifying Terraform's state or viewing it manually is a big no-no. Unless a major incident requires it, you shouldn’t' do it. And when I say requires, I mean you've tried everything else. Let's take a look at a few commands that will allow you to access items in the state without opening the file manually.
Alright, it's time for you to get your hands dirty. In the Terraform Apply Yourself lesson, it's time to code some Terraform yourself. Go ahead and create a new github_repository_file resource, add the file to the repository, use the main branch, call the file index.html, set overwrite on create to true, and set the content to whatever you want. Hello, Terraform is fine. I know it's an HTML file, but don't bother with the full HTML syntax right now.
Since it's not 2004 anymore and everything's not run on five servers named after Star Wars planets, randomness and entropy play a huge part in naming things in the cloud and, by extension, terraform. Due to this, Hashicorp has created a provider that creates random numbers, strings, UUIDs, and more.
Terraform functions and other features can become a little confusing as your infrastructure grows. Luckily, Hashicorp has an extremely underrated feature called the terraform console to let you experiment with HCL and ensure you get the result you're looking for without having to constantly plan, apply, and verify over and over, trying to get things right. Let's look at how it can help us create a name for our repository that includes the decimal attribute from our random_id.
Most cloud infrastructure deployments you encounter will have a lot of resources. However, there will be many times when there will be similar, or even duplicate, resources throughout the codebase. To keep the deployment dry and not repeat code repeatedly, you can take a few routes. The route we will cover in this lesson is the Count Meta-Argument. With count, we can tell Terraform how many copies of a resource we want, and it handles the rest…well…most of it. Let's take a look.
Welcome back to another Terraform Apply Yourself challenge. For this, all you need to do is uncomment the repository files we commented before, add the count meta argument to match our other resources, and modify any necessary identifiers to allow them to properly deploy these files to each repository.
Now that we have multiple instances of each of our resources, it starts to get tough to keep track of what is what. When deploying terraform resources for a company, you're typically not going to expect your users to run terraform commands to find out information about those resources. To properly display information that other devs need to see or other automations need to consume, we can use outputs. Now, since we have miultiple instances of each resources, we'll also use another expression called a "splat expression" to help structure this output to display everything we need.
Let's step back a bit and take a look at the different data types supported by Terraform, or more specifically, Hashicorp Configuration Language. HCL is very similar to many programming languages in the types it supports and how it supports them. I won't dive into a comparison here, but we are going to take a quick look at the different types and some of their quirks.
In this lesson, we're going to hop back into the Terraform Console, I know I know, I promise we'll get back to coding some Terraform very soon. We're going to play around with for loops and refactor our outputs to give us something a little more interesting. Let's get started.
As you know, we strive to keep our code as repitition free and DRY as possible. If you look at our existing code, you can see we have repeated the count value several times. Now, what happens if we were to change the number of repositories from 2 to 3? That would be a mess if we missed one of these while changing them. With hundreds of resources, it could become very nasty. Let's create a variable that we only have to define once instead of chasing it through multiple resources.
So far, we've mentioned terraform.tfvars and the variable default as ways to define variables. Now, let's talk about the rest of them. While doing that, we're also going to look at how these variable definitions take precedence over the others. Terraform uses very explicit guidelines as to what variable definition is used when. Let's take a look.
In this lesson, we're going to see how to use Terraform's Variable Validation feature to ensure our variables are defined properly. Especially if other pesky developers have access to our code.
In this lesson, we'll use the contains() function to help validate our variable in a cleaner way.
In this lesson, we're going to see the power...and limitations...of Terraform's Conditional Expressions.
We've been applying and destroying infrastructure from Terraform for a good bit over this course, but what happens if something happens outside of terraform? Let's say, for security reasons, a specific repository has to be deleted. Let's take a look at that process and how to sync state and our code to that scenario.
Count, although simple, can lead to some pretty large issues when trying to make modifications to your deployments. Even though it can cause problems, you will probably still see it in plenty of terraform code over the course of your career. So it's good we covered it, but let's start moving towards a much better alternative, for_each. We'll start with some basic theory on how for_each works and why it is like it is, then we'll move into refactoring our deployment. So let's get started.
For this Terraform apply yourself lesson, go ahead and modify the repository files to also use the for_each functionality. To help DRY things up a bit, create a variable to hold the repository names. You can call it something simple like "repos." Then, use that to define the for_each meta argument for each resource. Alright, pause the video, knock that out, and I'll see you on the other side.
When using count, it was easy to set a max number of repositories per deployment since it was literally just a number. Now that we're using for_each, we have to correlate that to the number of items in the set or map. To set the maximum number of repositories, we can use the length function to check the number of items in the set and use that to set the limit in a validation block. Let's check it out.
In this lesson, we're going to use the local-exec provisioner to run local commands on our system.
In this terraform apply yourself lesson, you're going to add a little more functionality using local-exec provisioners.
As you remember, when the provisioner is run to clone the repositories, they're being cloned just after the repositories are created and before the files. So we end up with repo directories that don't have the files we need in them. Let's fix that. First, let's take a look at the depends_on meta-argument.
We have a pretty robust deployment here, but there's definitely still room for improvement.
One thing we can do, is modify some of these descriptions to be more appropriate to what is going to be added to each repository. we can also modify the index file to be more appropriate to the language used for each repository. To do this, we'll add more information to our repos variable and access that information using for_each. Let's take a look.
Alright, so we've built a pretty cool deployment here. It deploys however many repos you may need,
has a descriptive readme specifying the language each repo is for, and creates a placeholder file with the extension for each language. Let's now walk through how a dev may use this deployment in their workflow and push some content to our file.
Let's see how to prevent a resource from changing based on a diff in one of its attributes.
Let's put the R in CRUD and read some data from the GitHub API using a Data Source.
In this lesson, we'll add security to your AWS Account. Please note, we will utilize the security measures recommended by AWS, but if you are using a corporate or enterprise account, be sure to consult your security advisors first to ensure compliance.
In this lesson, we're going to expand the disk space on our Cloud9 instance to ensure we have enough room to store our resources.
In this lesson, we're going to configure our AWS Security Group rules to allow access to our instance from our workstations. This will allow us to see the applications we deploy in our browser. Please note, if you are in a corporate account or using a corporate account, please verify with your security team that this is ok!
In this lesson, we install Terraform. Please note that I will be using Apt since it is compatible with the Ubuntu distribution we are using. If you are using another distribution, you can find installation instructions here:
In this lesson, I'm going to cover the basics of Terraform, some of the terminology you're going to see, and some differences between it and other utilities such as Cloudformation and Ansible. Now, this is the first and only lesson that is mostly a Powerpoint slideshow, so please bear with me. If you are pretty comfortable with what Terraform is, idempotence, declarative vs. imperative programming, etc., then you can probably skip this and head straight to the fun stuff!
We will configure our Docker Provider in this lesson to get our deployment setup!
In this lesson, we'll dive a little deeper into what happens when Terraform Init is run.
In this lesson, we're going to discuss one of the most important changes to Terraform 0.14. *Note* You may notice some lessons after this do not match this syntax as the changes weren't breaking changes, I didn't want to delay the entire course to modify a few lines.
In this lesson, we'll finally deploy an actual resource!
We'll cover a little more about the Terraform Apply command here.
In this lesson, we'll see how to reference another resource to provide information required to deploy.
In this lesson, we'll finally take a look at an early version of our deployment!
Time to take a little bit of a deeper look into the state.
Being able to access and see metadata about our infrastructure is crucial to a successful Terraform Deployment.
Utilizing Random strings, IDs, and more is tantamount to ensuring a DRY and idempotent deployment.
Using the Count parameter in Terraform is crucial to scaling resources and maintaining a DRY configuration.
Using the Splat Expression allows you to access all resources deployed using the count parameter.
Using For Expressions can provide a more granular approach that the Splat Expression sometimes does not allow.
The Taint command can become very useful when you need to reload a resource to apply a new configuration or otherwise reload it.
In this lesson, we break our state...on purpose! This will help illustrate the issues you may encounter during multi-engineer Terraform deployments.
In this lesson, we'll learn how to overcome a corrupted state by importing the extraneous resources.
Sometimes, you don't need to import extra resources, you just need them removed. With the refresh and state rm commands, this can be done easily and relatively safely.
We finally learn about variables here!
We investigate a relatively new feature for Terraform called Custom Validation to validate our variables.
In this lesson, we move our Variables and Outputs to external files in order to clean up our deployment.
Not all variables can be committed to source control! That's why we need the tfvars files!
In this lesson, we'll take a look at how many organizations manage their variables using multiple .tfvars files. We'll then take a quick look at what happens when multiple variable definitions are presented to the deployment.
In this lesson, we work with a feature only available in Terraform 0.14. If you don't have it, you will need to upgrade your terraform installation. This feature will allow us to hide our sensitive variable definitions from the CLI in order to keep the terminal clean of any sensitive information.
We now get to add the volume required to use our node-red deployment! After this lesson, you'll be able to reload your containers and maintain the information stored in node-red.
In this lesson, we'll cover another way to centralize our functions and data source: Local Values.
We'll cover Min and Max functions and the Expansion Expression (also known as the "spread operator" in other languages) in order to correct our variable validations.
In this lesson, we'll make our script more resilient to directory changes by referencing the local path instead of hardcoding our path. We'll also introduce a very useful feature called String Interpolation.
In this lesson, we're going to utilize maps and the lookup function to enable us to deploy different versions of our infrastructure based on whether we set var.env to be "dev" or "prod".
In this lesson, we continue our refactor to be able to specify different port ranges for different environments using the lookup function.
Terraform Workspaces are incredibly important when deploying multiple environments, such as dev and prod. By utilizing workspaces, you can add another element of control to your deployments without introducing extra complexity.
Now that we're using workspaces, it's imperative that we know how to reference them and utilize them in our scripts. This will make things a lot easier and more efficient!
Although the lookup function is very useful, it really is more clutter than we need. By referencing our maps using keys, we can clean up a lot of the clutter and make our scripts more efficient. But, lookups still has a purpose, and it has to do with setting defaults.
OpenCourser helps millions of learners each year. People visit us to learn workspace skills, ace their exams, and nurture their curiosity.
Our extensive catalog contains over 50,000 courses and twice as many books. Browse by search, by topic, or even by career interests. We'll match you to the right resources quickly.
Find this site helpful? Tell a friend about us.
We're supported by our community of learners. When you purchase or subscribe to courses and programs or purchase books, we may earn a commission from our partners.
Your purchases help us maintain our catalog and keep our servers humming without ads.
Thank you for supporting OpenCourser.