Terra Week Challenge Day 3
Create a Terraform configuration file to define a resource of AWS EC2 instance, Azure storage account, Google Compute Engine, etc. (anyone)
# Define provider for AWS
provider "aws" {
region = "us-west-2"
}
# Define resource for EC2 instance
resource "aws_instance" "example" {
ami = "<Your EC2 Instance AMI>"
instance_type = "t2.micro"
key_name = "my-key"
tags = {
Name = "example-instance"
}
}
The configuration starts with defining the provider block for AWS. This block specifies the AWS region to be used for resource provisioning.
The
resource
block is used to define the EC2 instance resource. Theaws_instance
resource type is used to create an EC2 instance.Inside the
aws_instance
block, you specify the required attributes for the instance. In this example:ami
specifies the ID of the Amazon Machine Image (AMI) to be used for the instance.instance_type
specifies the EC2 instance type.key_name
specifies the name of the key pair used for SSH access to the instance.tags
allow you to add metadata tags to the resource, in this case, a name tag.
That's a basic example of AWS EC2 instances. Similarly, you can define resources for other cloud providers like Azure and Google Cloud Platform using their respective Terraform providers and resource blocks.
Check state files before running terraform plan and apply commands and Use validate command to validate your tf file for errors and provide the Output generated by each command
State File :
It's crucial to confirm that the Terraform state files are in a proper and consistent state before executing the plan and apply commands. The resources that Terraform manages are recorded in the state files along with their present condition.
To check the state files, you can use the
terraform state
command. Here are some common state-related commands:terraform state list: #Lists all resources tracked in the Terraform state. terraform state show: #Displays detailed information about a specific resource in the state.
To validate the Terraform configuration file for errors, you can use the terraform validate
command. This command checks the syntax and validates the configuration file against any provider requirements or constraint
Understanding Output Generated by Command:
terraform validate
command:
Running terraform validate
validates the syntax and configuration file for errors. If there are any syntax errors or invalid configurations, it will display an error message. If the file is valid, it will return no output
Output (valid file):
Success! The configuration is valid.
Output (invalid file):
Error: Invalid character
on main.tf line 5, in resource "aws_instance" "example":
5: key_name = my-key
terraform state list
command:
Running terraform state list
lists all the resources tracked in the Terraform state file.
Output:
aws_instance.example
terraform state show
command:
Running terraform state show <resource>
displays detailed information about a specific resource in the Terraform state. Replace <resource>
with the resource name.
Output:
# aws_instance.example:
resource "aws_instance" "example" {
ami = "ami-0c94855ba95c71c99"
instance_type = "t2.micro"
key_name = "my-key"
tags = {
Name = "example-instance"
}
}
terraform plan
command: Terraform plan displays the modifications that Terraform will apply to your infrastructure in its output. Terraform intends to create an example AWS EC2 instance in this example.
terraform apply
command: Your infrastructure's resources will be created, updated, or destroyed as a result.
terraform destroy
command: The terraform destroy command obliterates all of the resources in your infrastructure. This is helpful for testing the disaster recovery procedure or cleaning up outdated infrastructure.
Add a provisioner to the configuration file to configure the resource after it is created and use Terraform commands to apply for changes and destroy to remove resources
Here's an example of adding a provisioner to the aws_instance
resource:
resource "aws_instance" "example" {
ami = "ami-0c94855ba95c71c99"
instance_type = "t2.micro"
key_name = "my-key"
tags = {
Name = "example-instance"
}
provisioner "local-exec" {
command = "echo Instance created: ${self.public_ip}"
}
}
In the above example, the provisioner block uses the local-exec
provisioner type and executes the echo Instance created: ${self.public_ip}
shell command. The ${self.public_ip}
interpolates the public IP address of the created instance into the command.
Once you have added the provisioner block, you can use the following Terraform commands to apply changes or destroy resources:
terraform init
: Initializes the Terraform working directory (only required once in a new project).terraform plan
: Shows the execution plan for the changes without actually applying them.terraform apply
: Applies the changes and creates/updates resources.terraform destroy
: Destroys the resources created by Terraform.
Remember to navigate to the directory containing your Terraform configuration file before running these commands.
Note: The local-exec
provisioner is just one example. Terraform provides other provisioner types like remote-exec
, chef
, ansible
, etc., depending on your requirements and the available provisioners for the specific resource type.
What is a provisioner block:
You can use provisioners to model specific actions on the local machine or on a remote machine to prepare servers or other infrastructure objects for service.
You can add a provisioner
block inside the resource
block of a compute instance.
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo The server's IP address is ${self.private_ip}"
}
}
The local-exec
provisioner requires no other configuration, but most other provisioners must connect to the remote system using SSH or WinRM
The self
Object
Expressions in provisioner
blocks cannot refer to their parent resource by name. Instead, they can use the special self-
object.
Creation - Time Provisioners
By default, provisioners run when the resource they are defined within is created. Creation-time provisioners are only run during creation, not during updating or any other lifecycle. They are meant as a means to perform bootstrapping of a system.
Destroy-Time Provisioners
If when = destroy
is specified, the provisioner will run when the resource it is defined within is destroyed.
Example :
Here's an example using the null_resource
resource type. The null_resource
is a resource type that doesn't create or manage any infrastructure but can be used as a placeholder for running provisioners.
resource "null_resource" "example" {
# Provisioner to run during resource creation
provisioner "local-exec" {
command = "echo Resource created at: $(date)"
}
# Provisioner to run during resource destruction
provisioner "local-exec" {
when = "destroy"
command = "echo Resource destroyed at: $(date)"
}
}
During resource creation, the local-exec
provisioner is used to execute the command echo Resource created at: $(date)
, which will print the current date and time when the resource is created.
During resource destruction, the second local-exec
provisioner is triggered by specifying when = "destroy"
. It will execute the command echo Resource destroyed at: $(date)
, which will print the current date and time when the resource is destroyed.
Add lifecycle management configurations to the configuration file to control the creation, modification, and deletion of the resource and use Terraform commands to apply the changes
Lifecycle Block
lifecycle
is a nested block that can appear within a resource block. The lifecycle
block and its contents are meta-arguments, available for all resource
blocks regardless of type. The arguments available within a lifecycle
block are create_before_destroy
, prevent_destroy
, ignore_changes
, and replace_triggered_by
.
resource "aws_instance" "example" {
ami = "<Your EC2 Instance AMI Here>"
instance_type = "t2.micro"
key_name = "my-key"
tags = {
Name = "example-instance"
}
lifecycle {
create_before_destroy = true
ignore_changes = ["tags"]
prevent_destroy = false
}
}
In the above example, the lifecycle
block is added to the aws_instance
resource and includes three configuration options:
create_before_destroy
: When set totrue
, Terraform will create a new resource before destroying the existing one, ensuring continuous availability during replacement. If not specified, the default value isfalse
.ignore_changes
: This option specifies a list of resource attributes that Terraform should ignore when determining whether changes have occurred.prevent_destroy
: If set totrue
, Terraform will prevent the resource from being destroyed. This can be useful in scenarios where you want to protect specific resources from accidental deletion. If not specified, the default value isfalse
.
After adding the lifecycle management configurations to your Terraform configuration file, you can use the following Terraform commands to apply the changes:
terraform init
: Initializes the Terraform working directory (only required once in a new project).terraform plan
: Shows the execution plan for the changes without actually applying them.terraform apply
: Applies the changes and creates/updates resources.
Thank You! I appreciate your time and effort invested for reading this blog. A feedback is always welcomed and appreciated!