Infrastructure as code makes our lives easy by allowing us to deploy our servers by describing the configurations for our infrastructure as code.
When you're setting up your servers you go through a 3-step process i.e
Provision your servers: You create your EC2 instances, S3 buckets etc...
Configure your servers: You install docker or some other software that will help you during the application setup.
Application setup: You setup your app in production or test mode.
All the above steps are time consuming processes hence we can automate each of the above step by:
- Provisioning our infrastructure using tools like terraform or cloud formation.
- Managing Configurations using ansible or puppet
- Finally containerizing your application to make sure it runs the same everywhere with docker or vagrant
In this post we'll learn about basics of provisioning tool called terraform.
Terraform is an infrastructure provisioning tool similar to AWS's cloud formation or the serverless framework which allow you to manage resources via code.
Install Terraform
You can setup terraform by downloading a binary file and adding it to your system PATH from here.
Basic Concepts
Terraform has its own language called HCL
(Hashicorp configuration language) through which you have describe your infrastructure.
you define all your configs in files that have a .tf
extension.
Terraform supports various cloud providers like AWS, GCP and much more in order to manage infrastructure on these platforms terraform has plugins.
plugins are of 3-types:
-
Official
- These are plugins created and maintained by Hashicorp eg: AWS, Azure, GCP and etc.... -
Verified
- These are plugins created and maintained by Hashicorp's partners like Linode, Digital Ocean and etc.... -
Community
- These are plugins built and maintained by the community.
you can learn more about plugins from here
Basic commands
Once you define your config you can create your resources using 3 basic commands in a sequence:
terraform init
: This command looks at your config and downloads all the plugins that's required to create and manage your resources.terraform plan
: Before actually creating your resources, you can review the changes that will be made to your infrastructure using this command.terraform apply
: finally running the apply command will create your resources
Creating your first resource with terraform
The first resource we'll be creating will be a file.
So, first create a file with a .tf
extension and add the code down below.
In terraform everything is defined as a block and the above image we are using something called a resource
block the resource block takes 2 arguments first is the resource type
and second is a logical name for your resource.
In the resource type argument the keyword before the _
indicates the provider we are using in this case it's an official provider from hashicorp called local and the keyword after the _
indicates the resource provided by the provider.
another example can be aws_s3_bucket
where aws
is the provider and s3_bucket
symbolizes the S3 feature provided by aws.
Each block expects you to enter a few key value pairs to function,
Here the resource block's key value pair will change depending on the provider and resources being used.
In the above image the local_file
provider expects us to pass the filename
key which will create a file in the provided path and the content key specifies what content will be added to the newly created file.
No if you run terraform init
, plan
, apply
you'll see a new file created with the name pet.txt
with the content hello pets
Using variables
Terraform allows us to define variables and use them in our config file.
you can learn about the variable types supported by terraform here
you can create a variable by starting the block with the variable
keyword,
Each keyword block expects you to enter a default value and if required you can enter a variable type.
if you do not enter a default value terraform will require you to enter a default value when you run the apply command.
you can also set a default value by passing the value while running the apply command using the -var
flag or you can initialize your variables using a .tfvar
file.
You can also export the value for variables as an environment variable.
you can use the variable in your config like this var.test
here's a more complex variable for your reference
let's access the name of the dog and print it in the console.
You can print values from terraform using the output
block and the output block expects you to provide it a value to print.
now when you run the terraform apply
command you will see the output in your console.
Resource Dependency
There are times where we might want to supply the output of one resource as an input to another resource or we might want a resource B to be created after the creation of resource A we can achieve this with resource dependency.
There are 2 types implicit
and explicit
Implicit Resource Dependency
We can use the output of one resource to be the input of another by referencing the resource using the resource type
followed by the resource's logical name
and one of the property that's being returned by the resource.
here in our case, we are using the random provider and resource pet that returns and id.
Now run apply the changes and see what happens.
Explicit Resource Dependency
using references will make your resource implicitly dependent but if you want to explicitly make a resource dependent, we can use the depends_on
key in the resource
block like in the image below
Now if you have a look at the console the resource time
is created first following the petz
resource.
Terraform Lifecycle
Generally, in terraform most of the time when you make a change the resource block the resource is completely destroyed and recreated.
For example, say that you change the name of the file the file will first be deleted then a new copy will be created but there are times where you might want the old file to be deleted only when the new one is up and running you can achieve that using the lifecycle block.
there are 3 types create_before_destroy
, prevent_destroy
and ignore_changes
create_before_destroy
: when set to true will first create the new resource and then delete the old one.
resource "azurerm_resource_group" "example" {
# ...
lifecycle {
create_before_destroy = true
}
}
prevent_destroy
: when set to true will cause Terraform to reject with an error any plan that would destroy the infrastructure.
ignore_changes
: Accepts a list of attributes it should ignore when changed.
resource "aws_instance" "example" {
lifecycle {
ignore_changes = [
tags,
]
}
}
These are the basic concepts of terraform which will help you provision and manage your resources.
If you are looking for resources on how to use terraform with cloud providers stay tuned will soon publish how to setup your linode and digital ocean instances using terraform.
Also checkout Getting Started With Terraform on AWS.
Thanks for the read.
Top comments (0)