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
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.
3º Task - Create EC2 instance + Install Nginx + Create and attach Elastic IP address to it
Requirements:
AMI:
ami-06178cf087598769c
, use variable namedami
Region:
eu-west-2,
use variable namedregion
Instance Type:
m5.large
, use variable namedinstance_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 calledpublic_dns
to a file/root/citadel_public_dns.txt
on the iac-serverInstall 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 calledinstall-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
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! 😊