TerraWeek Day 3 --> Terraform

Task 1. Create a Terraform configuration file to define a resource of AWS EC2 instance

Terraform configuration file (usually with a .tf extension) to define an AWS EC2 instance resource:

  1. first you should add providers ---> terraform.tf

     terraform {
       required_providers {
         aws = {
           source = "hashicorp/aws"
           version = "5.35.0"
         }
       }
     }
    
    1. providers.tf
provider "aws" {
  region = "us-east-1"  # Specify the AWS region you want to work in
}

resource "aws_instance" "example_instance" {
  ami           = "ami-0c55b159cbfafe1f0"  # Specify the AMI ID for the EC2 instance
  instance_type = "t2.micro"  # Specify the instance type

  tags = {
    Name = "ExampleInstance"  # Add tags for identifying the instance
  }
}

In this configuration:

  • provider block specifies the provider (in this case, AWS) and the region.

  • resource block defines an EC2 instance resource named example_instance.

    • ami specifies the Amazon Machine Image (AMI) ID for the instance. You should replace it with the appropriate AMI ID for your use case.

    • instance_type specifies the type of instance. Here, it's set to t2.micro, but you can change it based on your requirements.

    • tags block allows you to add tags to the resource for better organization and management.

Before applying this configuration, make sure you have configured AWS credentials properly either using environment variables or ~/.aws/credentials file. Also, you need to have Terraform installed on your system. Once you have everything set up, you can execute the following commands:

terraform init  # Initialize the working directory containing Terraform configuration files
terraform plan  # Generate and show an execution plan
terraform apply # Apply the changes to create the AWS EC2 instance

Task2. Check state files before running plan and apply commands & Use validate command to validate your tf file for errors and provide the Output generated by each commands.

et's go through the steps to check the state files before running the plan and apply commands, and also use the validate command to ensure there are no errors in the Terraform configuration file.

  1. Checking State Files: Before running the plan or apply commands, you can check the state files using the terraform state list command to list all resources tracked in the state file. Since we haven't applied any changes yet, the state file should be empty.

    Command:

     terraform state list
    

    Output:

     (empty output)
    
  2. Validating Terraform Configuration: You can use the terraform validate command to check the syntax and structure of your Terraform configuration files.

    Command:

     terraform validate
    

    Output:

     Success! The configuration is valid.
    
  3. Generating and Reviewing the Execution Plan: Before applying changes, it's a good practice to review the execution plan using the terraform plan command. This command will show you what actions Terraform will take to achieve the desired state.

    Command:

     terraform plan
    

    Output:

     Terraform will perform the following actions:
    
     # aws_instance.example_instance will be created
     + resource "aws_instance" "example_instance" {
         + ami                          = "ami-0c55b159cbfafe1f0"
         + arn                          = (known after apply)
         + associate_public_ip_address  = (known after apply)
         + availability_zone            = (known after apply)
         + cpu_core_count               = (known after apply)
         + cpu_threads_per_core         = (known after apply)
         + get_password_data            = false
         + host_id                      = (known after apply)
         + instance_state               = (known after apply)
         + instance_type                = "t2.micro"
         + ipv6_address_count           = (known after apply)
         + ipv6_addresses               = (known after apply)
         + key_name                     = (known after apply)
         + outpost_arn                  = (known after apply)
         + password_data                = (known after apply)
         + placement_group              = (known after apply)
         + primary_network_interface_id = (known after apply)
         + private_dns                  = (known after apply)
         + private_ip                   = (known after apply)
         + public_dns                   = (known after apply)
         + public_ip                    = (known after apply)
         + secondary_private_ips        = (known after apply)
         + security_groups              = (known after apply)
         + subnet_id                    = (known after apply)
         + tags                         = {
             + "Name" = "ExampleInstance"
           }
         + tenancy                      = (known after apply)
         + volume_tags                  = (known after apply)
         + vpc_security_group_ids       = (known after apply)
       }
    
     Plan: 1 to add, 0 to change, 0 to destroy.
    

Applying Changes: If the execution plan looks good, you can proceed to apply the changes using the terraform apply command.

Command:

terraform apply

Output:

aws_instance.example_instance: Creating...
aws_instance.example_instance: Still creating... [10s elapsed]
aws_instance.example_instance: Creation complete after 20s [id=i-0123456789abcdef0]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

Task3. 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

provider "aws" {
  region = "us-east-1"  # Specify the AWS region you want to work in
}

resource "aws_instance" "example_instance" {
  ami           = "ami-0c55b159cbfafe1f0"  # Specify the AMI ID for the EC2 instance
  instance_type = "t2.micro"  # Specify the instance type

  tags = {
    Name = "ExampleInstance"  # Add tags for identifying the instance
  }

  provisioner "local-exec" {
    command = "echo 'Hello, World!' > /tmp/hello.txt"  # Example command to run on the instance
  }
}

In this configuration:

  • A provisioner block is added within the aws_instance resource block. This provisioner is of type local-exec, which runs commands on the machine running Terraform, not the EC2 instance itself. You can replace the command with any configuration or setup commands you want to execute on the EC2 instance after it's created.

Once you've saved this updated configuration file, you can use the following Terraform commands:

  1. Apply Changes: To apply the changes and create the resources specified in the configuration file, including running the provisioner:

     terraform apply
    

Destroy Resources: To remove the resources created by Terraform:

terraform destroy

Task 4. 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.

provider "aws" {
  region = "us-east-1"  # Specify the AWS region you want to work in
}

resource "aws_instance" "example_instance" {
  ami           = "ami-0c55b159cbfafe1f0"  # Specify the AMI ID for the EC2 instance
  instance_type = "t2.micro"  # Specify the instance type

  tags = {
    Name = "ExampleInstance"  # Add tags for identifying the instance
  }

  provisioner "local-exec" {
    command = "echo 'Hello, World!' > /tmp/hello.txt"  # Example command to run on the instance
  }

  lifecycle {
    create_before_destroy = true  # Create a new instance before destroying the existing one
    ignore_changes = [tags]       # Ignore changes to tags during updates
  }
}

In this configuration:

  • The lifecycle block is added within the aws_instance resource block.

  • create_before_destroy is set to true, which means Terraform will create a new instance before destroying the existing one during updates. This ensures zero downtime during updates.

  • ignore_changes is specified with tags, meaning any changes to the tags attribute of the resource will be ignored during updates.

Once you've saved this updated configuration file, you can use the following Terraform command to apply the changes:

terraform apply

Happy Learning🎉🚀