Getting Started with Terraform Part - 1
Terraform is an open-source Infrastructure as code software that helps you to create/update/delete Infrastructure.
You will be learning how to create Infrastructure using Terraform and some of its key features. We will be using AWS as our cloud provider and assuming you are already familiar with it.
This article towards beginners and expects no previous experience of Terraform. By the end of this book, you will be able to use Terraform to create Infrastructure.
Prerequisites
- An account with AWS cloud
- Experience in working with AWS cloud
Installation
- We will be using Terraform CLI to create infrastructure.
- If you are having multiple projects which require different versions, you can use tfswitch
- We will be using VSCode as our code editor with Terraform extension or This
- We will be using AWS as our cloud provider for creating Infrastructure using Terraform. You can create an AWS free tier account. Click here for more information.
- Configure AWS Account using its CLI.
- Installation -https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
- Configuring AWS - https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-methods
- Test configuration - To test your AWS configuration run the following command and it should return your account id.
aws sts get-caller-identity
Output as follows
{
"UserId": "XXXXXXXXX",
"Account": "XXXXXXX",
"Arn": "arn:aws:iam::XXXXXX:user/XXXXXXX"
}
More on Terraform
Language
Terraform uses HCL configuration language and every Terraform file ends with a .tf
extension.
State
when you create infrastructure using Terraform, it creates a file terraform.tfstate
. Terraform tracks changes made in code with state file. either it creates or destroys Infrastructure based on changes that were made.
Create S3 Bucket Using Terraform
Now let’s see how to create an S3 bucket using Terraform
let’s create a folder with the name terraform-S3
and add following content in main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "3.72.0"
}
}
}
# Configure the AWS Provider
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "bucket" {
bucket = "terraform-remote-state-test-bucket-example"
tags = {
Environment = "Development"
}
}
now let’s break down the code
Terraform Block
Terraform supports multiple providers (AWS, Azure, GCP …) These providers are an abstraction of API to create infrastructure. for more information check here. We will be using AWS providers to create our infrastructure.
terraform {
required_providers {
AWS = {
source = "hashicorp/aws"
version = "3.72.0"
}
}
}
Provider Block
This block helps us to configure AWS Keys, regions, etc… when you are not defining keys explicitly, it will be reading default credentials from path ~/.aws/credentials
.
# Configure the AWS Provider
provider "aws" {
region = "us-east-1"
}
Resource Block
This defines one or more resources to create Infrastructure for a given provider. This is probably the most used Terraform feature. Terraform has tons of AWS prebuilt resources which can be found here.
resource "aws_s3_bucket" "bucket" {
bucket = "terraform-remote-state-test-bucket-example"
tags = {
Environment = "Development"
}
}
Commands
Init
Init: The following command will initialize Terraform project by Installing listed providers like AWS and its resources. It also creates a few of the folders like .terraform
and .terraform.lock.hcl
. For more information check here.
terraform init
The output should be as follow
Initializing the backend...
Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
- Installing hashicorp/aws v3.72.0...
- Installed hashicorp/aws v3.72.0 (signed by HashiCorp)
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
Plan
Plan: The following command will give you the list of resources that will be created/updated/destroyed if you apply your configuration.
terraform plan
The output should be as follow
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_s3_bucket.b will be created
+ resource "aws_s3_bucket" "b" {
+ acceleration_status = (known after apply)
+ acl = "private"
+ arn = (known after apply)
+ bucket = "terraform-remote-state-test-bucket-example"
+ bucket_domain_name = (known after apply)
+ bucket_regional_domain_name = (known after apply)
+ force_destroy = false
+ hosted_zone_id = (known after apply)
+ id = (known after apply)
+ region = (known after apply)
+ request_payer = (known after apply)
+ tags = {
+ "Environment" = "Development"
}
+ tags_all = {
+ "Environment" = "Development"
}
+ website_domain = (known after apply)
+ website_endpoint = (known after apply)
+ versioning {
+ enabled = (known after apply)
+ mfa_delete = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform
apply" now.
Apply
Apply: Following command will create infrastructure as configured and planned in earlier steps.
terraform apply
When you run the above command, it will plan and ask for confirmation.
terraform-S3 git:(master) ✗ terraform apply
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# aws_s3_bucket.b will be created
+ resource "aws_s3_bucket" "b" {
+ acceleration_status = (known after apply)
+ acl = "private"
+ arn = (known after apply)
+ bucket = "terraform-remote-state-test-bucket-example"
+ bucket_domain_name = (known after apply)
+ bucket_regional_domain_name = (known after apply)
+ force_destroy = false
+ hosted_zone_id = (known after apply)
+ id = (known after apply)
+ region = (known after apply)
+ request_payer = (known after apply)
+ tags = {
+ "Environment" = "Development"
}
+ tags_all = {
+ "Environment" = "Development"
}
+ website_domain = (known after apply)
+ website_endpoint = (known after apply)
+ versioning {
+ enabled = (known after apply)
+ mfa_delete = (known after apply)
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value:
Now enter yes
to create Bucket and output should be as follow
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_s3_bucket.b: Creating...
aws_s3_bucket.b: Still creating... [10s elapsed]
aws_s3_bucket.b: Still creating... [20s elapsed]
aws_s3_bucket.b: Creation complete after 23s [id=terraform-remote-state-test-bucket-example]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Lets goto AWS console to confirm if S3 bucket has been created
Destroy: Once we confirm with S3 bucket on console, run the following command to destroy it.
terraform destroy
The Output should be as follows
terraform-S3 git:(master) ✗ terraform destroy
aws_s3_bucket.b: Refreshing state... [id=terraform-remote-state-test-bucket-example]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# aws_s3_bucket.b will be destroyed
- resource "aws_s3_bucket" "b" {
- acl = "private" -> null
- arn = "arn:aws:s3:::terraform-remote-state-test-bucket-example" -> null
- bucket = "terraform-remote-state-test-bucket-example" -> null
- bucket_domain_name = "terraform-remote-state-test-bucket-example.s3.amazonaws.com" -> null
- bucket_regional_domain_name = "terraform-remote-state-test-bucket-example.s3.amazonaws.com" -> null
- force_destroy = false -> null
- hosted_zone_id = "Z3AQBSTGFYJSTF" -> null
- id = "terraform-remote-state-test-bucket-example" -> null
- region = "us-east-1" -> null
- request_payer = "BucketOwner" -> null
- tags = {
- "Environment" = "Development"
} -> null
- tags_all = {
- "Environment" = "Development"
} -> null
- versioning {
- enabled = false -> null
- mfa_delete = false -> null
}
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value:
Now enter yes
to destroy Bucket and output should be as follows
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
aws_s3_bucket.b: Destroying... [id=terraform-remote-state-test-bucket-example]
aws_s3_bucket.b: Destruction complete after 2s
Destroy complete! Resources: 1 destroyed.
Go to the AWS console to confirm if the S3 bucket has been deleted or you can run the following command to verify the same.
aws s3 ls