- Docker logs tail: Troubleshoot Docker containers with real-time logging - Wed, Sep 13 2023
- dsregcmd: Troubleshoot and manage Azure Active Directory (Microsoft Entra ID) joined devices - Thu, Aug 31 2023
- Ten sed command examples - Wed, Aug 23 2023
First, download the Terraform binary for your desktop OS. Once the binary is downloaded, add it to your PATH to run Terraform commands from any directory.
Test your installation by running terraform at your command line to see a list of available commands.
Terraform basics
Terraform uses configuration files (often with the extension .tf) to manage infrastructure. You'll specify what resources you want to create or manage in these Terraform configuration files.
The core Terraform commands are init, plan, and apply.
The terraform init command initializes your working directory, including loading the AWS provider and other provider plugins from Terraform.
Running the terraform plan command displays which changes Terraform will make to your infrastructure without actually applying these changes. This is a safety measure to ensure you're confident with the changes. You can think of it as similar to the "what if" flag in PowerShell.
Finally, the terraform apply command prompts Terraform to go ahead and make the proposed changes. Once it runs successfully, you should see a "creation complete" message.
Defining the AWS provider
We need a few pieces of information to plug into our Terraform Provider and ec2.tf files:
- AWS region
- AWS access key
- AWS secret key
- AMI image ID
- Subnet ID
Once you have this information, you are ready to define a provider block. Terraform uses these providers to interact with different systems and technologies. The corresponding filename is provider.tf. You can use anything you want for the filename in this example. Terraform will read the files and understand which information to pull from which files.
The AWS provider block will include details such as the AWS region in which to create resources, your access key, and your secret access key:
provider "aws" { region = "us-east-1" ##Enter your region here access_key = "your_access_key" secret_key = "your_secret_key" }
The "us-east-1" region is the default value in this example. You can replace it with the AWS region of your choice. Just replace "your_access_key" and "your_secret_access_key" with your actual AWS access key and secret access key.
Defining the AWS resource
Now, let's create an AWS resource. In this case, we'll create an EC2 instance, a virtual server in the AWS cloud, along with the required VPC and subnet resources. We are using the filename ec2.tf. Again, you can name the file name anything. Here's a simple resource block for an EC2 instance. We are doing the following:
- Creating a new VPC with a defined CIDR block range of 10.0.0.0/16
- Creating a new subnet within the new VPC of 10.0.1.0/24
- Defining the AMI ID and instance type, and connecting the EC2 instance to our newly created subnet
- Naming the instance using the "tags" block.resource
resource "aws_vpc" "testvpc" { cidr_block = "10.0.0.0/16" tags = { Name = "testvpc" } } resource "aws_subnet" "testsubnet" { vpc_id = aws_vpc.testvpc.id cidr_block = "10.0.1.0/24" tags = { Name = "testsubnet" } } resource "aws_instance" "testec2" { ami = "ami-06ca3ca175f37dd66" # replace with your AMI ID instance_type = "t2.micro" subnet_id = aws_subnet.testsubnet.id tags = { Name = "testec2" } }
The parameters ami and instance_type are essential. The ami is the ID of the Amazon Machine Image (AMI) that you want to use for your EC2 instance. The instance_type parameter specifies the size of the instance, and the subnet ID specifies the specific subnet you want to use for your EC2 instance. You can find the AMI ID in the AMI catalog of the AWS Console for EC2. Note that the AMI IDs will differ in different regions.
Take a look at the official documentation from Amazon on finding a Linux AMI image.
Initializing, planning, and applying the Terraform code
You will want to focus on the command line in the directory where your Terraform files exist. This is how Terraform finds the configuration files.
The first step is to run the Terraform init command.terraform init. As mentioned above, it downloads Terraform's required provider plugins to interact with cloud providers, services, and APIs. In our case, the command downloads the provider plugin for AWS.
Now that we have initialized the provider and have the AWS resource defined, we can run terraform plan and apply processes to proof our code for any issues and then apply the configuration.
terraform plan
Next, we run the terraform apply command. It will ask you to confirm the operation. Type yes, and the apply operation will begin.
After the apply operation finishes, you will see the apply complete message with the number of resources added.
Now you should be able to navigate to the AWS Console and see the newly created EC2 instance.
You can also see the new VPC and subnets that have been created.
And the AWS VPC also appears now in the AWS Console.
Destroying the instance
You can easily destroy the instance you created with the terraform destroy command. Terraform creates a state file that maintains a record of all resources and their configurations.
terraform destroy
When you run terraform destroy, it will simply read the resources from the state file and destroy those resources.
Like the apply operation, you must confirm the destroy operation.
Using variables and outputs
In this basic example, we have shown how to place configuration directly inside the Terraform HCL files. However, you can define input and output variables. Input variables let you customize aspects of your infrastructure without modifying the Terraform configuration files themselves. For instance, we could place our AWS key and secret key, the AMI machine image ID, and subnet cidrs in variables and set them outside of the configuration files.
While you don't have to do this, it is generally best practice to split out variables and the values of those variables into separate files. variables.tf declares the variables, and terraform.tfvars assigns the values to those variables. It helps to split out your variables from potentially sensitive information being checked into code repositories.
For example, look at the code above. We could create a variables.tf file that looks like the following:
variable "region" {} variable "access_key" {} variable "secret_key" {} variable "aws_vpc_cidr" {} variable "aws_subnet_cidr" {} variable "aws_ami" {}
The terraform.tfvars file would contain the actual values of the variables, such as the following:
region = "us-east-1" access_key = "your access key" secret_key = "your secret key" aws_vpc_cidr = "10.0.0.0/16" aws_subnet_cidr = "10.0.1.0/24" aws_ami = "ami-06ca3ca175f37dd66"
We would then update provider.tf with the following:
provider "aws" { region = var.region access_key = var.access_key secret_key = var.secret_key }
The ec2.tf file would also take advantage of the variables using the following:
Subscribe to 4sysops newsletter!
resource "aws_vpc" "testvpc" { cidr_block = var.aws_vpc_cidr tags = { Name = "testvpc" } } resource "aws_subnet" "testsubnet" { vpc_id = aws_vpc.testvpc.id cidr_block = var.aws_subnet_cidr tags = { Name = "testsubnet" } } resource "aws_instance" "testec2" { ami = var.aws_ami instance_type = "t2.micro" subnet_id = aws_subnet.testsubnet.id tags = { Name = "testec2" } }
Wrapping up
In this AWS Terraform provider example, we covered a lot of ground, including setting up your AWS account, installing Terraform, running basic Terraform commands, and creating and destroying AWS resources. We also looked at the components of Terraform configuration files and learned how to create an EC2 instance. This is just scratching the surface of what Terraform can do and the types of infrastructure it can build. The great thing with Terraform is that you can apply the concepts and processes to other cloud and on-premises environments.
Brandon,
Thanks for a great explanation!
This was just what I was looking for as I study AWS.
As I was making my own notes, I think I found a typo that is easily fixed.
Near the end, you show how to update the “provider.tf with variables:
“We would then update provider.tf with the following:”
after the screen shot, you state:
“The provider.tf file would also take advantage of the variables using the following:”
I think it should be
“The ec2.tf file would also take advantage of the variables using the following:”
Thanks again for a clear and helpful explanation as I begin to learn Terraform!!!
Brad
Brad,
Thank you for the comment! Good catch, yes this should be the ec2.tf file would take advantage of the variables. Also, good luck on your AWS studies!
Brandon