Terraform is an open-source infrastructure as code software tool that provides a consistent CLI workflow to manage hundreds of cloud services. Terraform codifies cloud APIs into declarative configuration files.
While we could deploy all of our resources using the cloud providers user interfaces or CLIs, it is much better practice to use Terraform. So that we can define all of our infrastructure as code and be sure that the deployed resources matches our desired configuration. Furthermore, while doing this, you will be able to keep state file about the deployment. But it may contain sensitive information, which means you need to keep it safely. Because of this, it’s better not to store it locally, in this case AWS we will keep this state file in S3 Bucket. With this way we can protect it with our IAM Roles & IAM Users.
Firstly, we need an S3 Bucket to store the state file;
aws s3api create-bucket --bucket hoketech-terraform --region eu-central-1
Then, we can move forward with configure a remote backend;
terraform {
backend "s3" {
bucket = "hoketech-terraform"
key = "path/to/my/key"
region = "eu-central-1"
}
}
First step for writing terraform file is going to be add a block to define associated provider within our code. Also by adding the version, we can pin the version number and the reason is if the AWS updates its provider in the background, we don’t necessarily want to pull newer version because it could have breaking changes in the API.
provider "aws" {
version = "~> 3.0"
region = "eu-central-1"
}
At this point we’re ready to run the initialize the working directory, and store state file to AWS S3;
Anytime you add a new module or change the providers within your terraform configuration, you need to rerun the this command.
terraform init
Then we can move forward with defining an EC2 Instance;
resource "aws_instance" "web" {
ami = "ami-08c148bb835696b45"
instance_type = "t2.micro"
tags = {
Name = "hello-world"
}
}
Now, you can check what will be deployed with this terraform file with terraform plan command. Then continue with deploying;
terraform apply
What is Data Block?
The difference between resource and data blocks within a terraform file is while a resource block is going to be some resource that we’re creating, a data block is just a reference to an already existing resource.
For example;
data "aws_ami" "amazonlinux2" {
most_recent = true
filter {
name = "name"
values = ["amzn2-ami-hvm-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["amazon"]
}
resource "aws_instance" "second-ec2" {
ami = data.aws_ami.amazonlinux2.id
instance_type = "t2.micro"
tags = {
Name = "hello-world-2"
}
}
This way, you’ll get the latest Amazon Linux 2 AMI.