The course is part of this learning path
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can help with multi-cloud by having one workflow for all clouds. The infrastructure Terraform manages can be hosted on public clouds like Amazon Web Services, Microsoft Azure, and Google Cloud Platform, or on-prem in private clouds such as VMWare vSphere, OpenStack, or CloudStack. Terraform treats infrastructure as code (IaC) so you never have to worry about you infrastructure drifting away from its desired configuration. If you like what you are hearing about Terraform then this course is for you!
In this course, we’ll learn Terraform from the ground up. While building a strong foundation for you to solve real-world challenges with Terraform, you'll learn about its core concepts including HashiCorp Configuration Language, providers, resources, and state. The course concludes with a demo to illustrate how Terraform can be used to manage a practical infrastructure for deploying development and production versions of a two-tier application in Google's Cloud using Cloud SQL, Google Kubernetes Engine (GKE), and Kubernetes. The Terraform configuration files used in the course are all available in the course's GitHub repository.
This course is for anyone that is interested in managing infrastructure in public, private, or hybrid clouds. Some roles that fit into that category are:
- DevOps Engineers
- IT Professionals
- Cloud Engineers
After completing this course, you will be able to:
- Describe what Terraform is
- Write Terraform configuration files
- Understand how Terraform integrates infrastructure sources
- Manage multiple infrastructure environments with Terraform
This is an intermediate level course that assumes:
- You have priors experience with a scripting or programming language.
|Lesson||What you'll learn|
|Introduction||What will be covered in this course|
|What is Terraform?||Take a high-level look at what Terraform is and when to use it|
|Terraform Configuration||Understand the ins and outs of HashiCorp Configuration Language (HCL)|
|Providers||Discover how Terraform integrates various infrastructure sources|
|Resources||See how to configure parameters that are common to all resources|
|State||Learn how Terraform state connects your configuration with the real world|
|Two-Tier App Demo||See how to deploy a two-tier app in multiple environments with Terraform|
|Summary||Review the course and see what's next|
If you have thoughts or suggestions for this course, please contact Cloud Academy at firstname.lastname@example.org.
Providers must be configured to manage any infrastructure in Terraform. We’ll go more detail about providers and demonstrate setting up the Google Cloud provider in a demo in this Lesson.
We’ll begin by covering the provider architecture in Terraform.
Then we’ll consider special provider configuration keys for constraining provider versions and working with aliases to use multiple instances of the same provider.
Lastly, we’ll demonstrate configuring the Google Cloud Platform provider as an example of configuring a cloud platform provider.
Let’s start by reviewing the definition. A provider is
n. the logical abstraction of an upstream API -- https://www.terraform.io
The provider wraps the create, read, update and delete API calls needed to manage resources. It’s easy to tell what provider a resource uses because the type of a resource always begins with the name of its provider. For example, google_compute_instance uses the google provider.
Your configurations can use as many providers as you need. Terraform doesn’t ship with any built-in providers. Instead it uses a plugin architecture to download the provider plugins required by your configuration.
Each required plugin corresponds to a provider block in your configuration. If you try to run plan or apply without having Terraform download the plugins you will get a nasty error message telling you to initialize the plugins.
You initialize Terraform by running the init command. Terraform will parse your configuration and download the providers specified. The plugins are downloaded to a plugins directory inside of the hidden .terraform directory by default. As an aside, the init command follows the same process for any modules your configuration specifies as well.
Although there are over one hundred public Terraform providers available,
If there isn’t a plugin available for what you need, perhaps for an internal private cloud implementation or internal tool you want to integrate, you are able to write your own provider plugins.
Custom providers are written in Golang.
HasiCorp provides guides on writing custom providers and a link to them is at the end of this lessons transcript.
Writing custom providers is an advanced topic and that’s all that needs to be said about custom providers for this course.
Providers are released on their own schedule and have their own versions separate from Terraform.
Within a provider block, you can omit a version and have the latest version downloaded automatically. However, this can become problematic. For example, if the same configuration is applied on separate machines before and after a new provider version is released, potentially resulting in different behaviors. To avoid these issues, it is a best practice to constrain the provider version in your configurations.
The string you assign to the version key constrains the version of the provider Terraform will use.
You can set a specific version for Terraform to use, such as version 1.12.1, or you can specify a range.
When you specify a range, you can use the less than, less than or equal to, greater than, or greater than or equal to operators. If you specify a lower and an upper bound, you separate the constraints using a comma, as shown in the example constraining the version to be any 1.2 version or higher but less than version 1.12.
You also use the tilde arrow or pessimistic operator as a short hand for certain ranges. The version number you specify acts as a lower bound of the version and the upper bound is set as the second last version digit specified. In the example the version 1.7 is specified so the lower bound would be 1.7.0. The second last version digit is the major version of 1, so the allowed versions must all be major version one. The range of allowed versions is equivalent to greater than or equal to 1.7.0 and less than version 2.0.0.
You can also use the same version constraints for modules and for Terraform itself if you add a terraform block to your configuration.
If you have previously downloaded provider plugins satisfying the version constraints, running the init command again won’t result in newer versions being downloaded, even if there are newer versions satisfying the constraints. To upgrade to the latest provider plugin versions that satisfy your version constraints, you use the upgrade option of the init command.
You can declare multiple blocks for the same provider in your configuration. One scenario where you may want or need to do this is when you have resources with the same cloud provider but in multiple regions. You can configure one provider for each region to accommodate this scenario.
To identify multiple instances of a single provider, you must add an alias. The alias is used by resources to indicate which instance of the provider to use.
One default provider is allowed. The default instance doesn’t specify an alias and is used by default when resources don’t specify a specific provider.
To refer to a specific instance inside of a resource block, you add a provider key. The value of the provider is a string beginning with the provider type followed by dot and the assigned alias.
For example, to use the Google provider with the alias of west, a resource sets its provider to google dot west. That’s all for the slides in this lesson. I’ll switch over to my mac to demo how to configure a provider in Terraform
I’m here at the Terraform Providers page where you can see a list of all the providers that are tested or maintained by HashiCorp. There are also community-maintained providers that are listed on a separate page. If you don’t find a provider you want on the main provider page, be sure to check the community page. I’ll go back to the main provider page because we’ll be using the google cloud provider. I’ll select Google Cloud from the list and we’re taken to the Google Cloud provider page.
All resource providers will have a page similar to this. The data sources and resources provided by the provided are listed on the left sidebar. In the provider documentation, there’s an example of how to use it to get started quickly, and a more detailed reference below. Most providers will need credentials and may have several ways of specifying the credentials. In the example it shows how to use interpolation to read a JSON file containing GCP account credentials. If you are running terraform from a Google Compute Engine instance, the provider can use a service account associated with the instance so that you can omit the credentials from the configuration. Both of these methods avoid storing actual keys or passwords in the configuration file. That makes it safer to check the configuration into version control. I’ll demo using an environment variable to set the credentials. This also doesn’t leave any credential information in the configuration. There are a few different choices for the environment variable to set. I’ll use GOOGLE_CREDENTIALS which is the highest precedence. The other provider configuration keys are also optional and can be set in the configuration or with environment variables.
I’ve prepared a main.tf configuration file here in Visual Studio Code. It only declares the google cloud provider. The project and region are hard-coded. You can use variable interpolations inside of provider blocks if you wanted to make the configuration more generic. The only exceptions to using interpolations in a provider block is for the version and the alias which must be hard-coded.
I haven’t initialized the working directory so if I try to run a plan, Terraform will tell me I need to initialize. Let’s run init to initialize and download the google provider plugin. Now if I tried to create any resources it would still fail because I haven’t set any credentials. I’ll need to set up a service account with GCP to get credentials Terraform can use.
Back in my browser I’m logged into the console of GCP. I’ve already created the cloud-academy-terraform project. I need credentials to obtain API access to the project. I’ll search for credentials in the search bar and select credentials in the API & Services section. Then I’ll select create credentials and create a service account key.
I’ll make a new service account called terraform-admin and will give it owner access on the project for demonstration purposes. Click create the service and the key file will be downloaded automatically. GCP warns us to store the credentials securely. I’ll destroy the account after finishing the course so I won’t take any additional steps to guard the file in my Downloads directory.
Switching back to the console, I can now set the GOOGLE_CREDENTIALS environment variable in the bash shell like so. Now terraform has the google plugin and API access through the credentials set via an environment variable.
This lesson started by covering the plugin architecture that Terraform uses. You specify the providers you need in your configuration and Terraform downloads the appropriate plugin.
The options available for constraining provider plugin versions were then described.
Provider aliases were then explained for situations where you need multiple instances of the same provider.
We finished with a demo of how to configure the Google Cloud provider. Other cloud providers generally follow a similar pattern.
In the next lesson we’ll discuss the specifics of configuring resources. When you’re ready, continue on to learn more about resource configuration.
Custom providers: https://www.terraform.io/guides/writing-custom-terraform-providers.html
About the Author
Logan has been involved in software development and research since 2007 and has been in the cloud since 2012. He is an AWS Certified DevOps Engineer - Professional, AWS Certified Solutions Architect - Professional, Microsoft Certified Azure Solutions Architect Expert, MCSE: Cloud Platform and Infrastructure, Google Cloud Certified Associate Cloud Engineer, Certified Kubernetes Administrator (CKA), Certified Kubernetes Application Developer (CKAD), Linux Foundation Certified System Administrator (LFCS), and Certified OpenStack Administrator (COA). He earned his Ph.D. studying design automation and enjoys all things tech.