Step-by-Step Solution for KodeKloud's Terraform Challenge 3

Step-by-Step Solution for KodeKloud's Terraform Challenge 3

KodeKloud is the #1 DevOps course provider and helps students learn trending technologies they need to thrive in their career. They also have this Terraform Challenges series that consists of a set of challenges that will assist you in mastering provisioning and managing infrastructure using Terraform.

In this challenge we will implement a simple EC2 instance with some preinstalled packages.

Architecture diagram

1º Task - Check AWS Provider

Amazon Web Services (AWS) provider have been configured already to interact with the many resources supported by AWS.

Solution:

You're probably asking yourself: why is just checking the provider relevant?

Because we need to know the exact namespace and version it's using, so we can look at the right documentation page and avoid using deprecated fields/keys.

provider.tf

terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "4.15.0"
    }
  }
}

provider "aws" {
  region                      = var.region
  skip_credentials_validation = true
  skip_requesting_account_id  = true

...

Namespace hashicorp, provider aws and version 4.15.0

Here´s the provider´s documentation that we´re going to make use during the challenge: https://registry.terraform.io/providers/hashicorp/aws/4.15.0/docs

Also note that the provider.tf relies on a variable named region that is not defined yet.

Let's create the variable region. For that, we´re going to create a file named variables.tf to concentrate all variables there, following Terraform best practices:

variables.tf

variable "region" {
  default = "eu-west-2"
}

We are using eu-west-2 as default because the EC2 is requested to be created on it (we will see it later)

Don't forget to run terraform init to install the provider's plugin

install cd rom GIF

2º Task - Create a SSH Key-Pair

Create a terraform key-pair citadel-key with key_name citadel.

Upload the public key ec2-connect-key.pub to the resource. You may use the file function to read the the public key at /root/terraform-challenges/project-citadel/.ssh

Solution:

Making use of the documentation related to this resource:

main.tf

resource "aws_key_pair" "citadel-key" {
  key_name   = "citadel"
  public_key = file("/root/terraform-challenges/project-citadel/.ssh/ec2-connect-key.pub") 
}

...

As requested, we're using the file function to read the public key. If you want to know more about this function, here's the documentation: https://developer.hashicorp.com/terraform/language/functions/file

Run the command terraform plan to review the execution plan, and then terraform apply to create it.

Fox Tv GIF by BH90210

3º Task - Create EC2 instance + Install Nginx + Create and attach Elastic IP address to it

Requirements:

  • AMI: ami-06178cf087598769c, use variable named ami

  • Region: eu-west-2, use variable named region

  • Instance Type: m5.large, use variable named instance_type

  • Elastic IP address attached to the EC2 instance

  • Create a local-exec provisioner for the eip resource and use it to print the attribute called public_dns to a file /root/citadel_public_dns.txt on the iac-server

  • Install nginx on citadel instance, make use of the user_data argument.
    Using the file function or by making use of the heredoc syntax, use the script called install-nginx.sh as the value for the user_data argument.

Solution:

First, let's create the variables needed:

variables.tf

variable "ami" {
  default = "ami-06178cf087598769c"
}

variable "region" {
  default = "eu-west-2"
}

variable "instance_type" {
  default = "m5.large"
}

To create an EC2 resource, let's make use of the documentation: https://registry.terraform.io/providers/hashicorp/aws/4.15.0/docs/resources/instance

main.tf

resource "aws_instance" "citadel" {
  ami = var.ami
  instance_type = var.instance_type
  user_data = file("install-nginx.sh")
  key_name = aws_key_pair.citadel-key.id
}

...

Note that in the field key_name, we are using attribute reference to refer to the aws_key_pair resource we´ve just created.

Also note that we're making use of the user_data argument as requested to run a script that installs Nginx.

Great, but it's missing the Elastic IP. Let's make use of its documentation to create it and attach it to the EC2 resource: https://registry.terraform.io/providers/hashicorp/aws/4.15.0/docs/resources/eip

main.tf

resource "aws_eip" "eip" {
  vpc      = true
  instance = aws_instance.citadel.id
  provisioner "local-exec" {
    command = "echo ${self.public_dns} > /root/citadel_public_dns.txt"
  }
}

...

As requested, we're using provisioner to print the attribute called public_dns to a file /root/citadel_public_dns.txt on the iac-server. Here´s the provisioners doc if want to know more: https://developer.hashicorp.com/terraform/language/resources/provisioners/syntax

Well, I think we're ready to go. Let's create it by running terraform apply

nixCraft - We may giggle, but I know a few who left their EC2 instances  running after the project was done. When your AWS account or API keys are  compromised, it can

Conclusion

At the end, click on the “Check” button, and you should see the architecture diagram highlighted in green like this:

If you found this helpful, a like and share would mean a lot! Consider following for more insightful DevOps content!

Happy learning! 😊

The Late Show gif. Ryan Gosling is leaving an interview and he walks towards the cameras, getting so close that he's out of focus. He frowns before raising his hand at us and waving, saying, "Bye!"