Kodekloud Terraform Challenge 3 solution | Implement a simple AWS EC2 instance with some preinstalled packages

Ticker

6/recent/ticker-posts

Kodekloud Terraform Challenge 3 solution | Implement a simple AWS EC2 instance with some preinstalled packages

Question : Welcome to the terraform challenge series.

In this challenge we will implement a simple EC2 instance with some preinstalled packages. Utilize /root/terraform-challenges/project-citadel directory to store your Terraform configuration files.


Inspect the requirements in detail by clicking on the icons of the interactive architecture diagram on the right and complete the tasks. Once done click on the Check button to validate your work.



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



  • 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:  

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


1. Enter the project directory

iac-server $ pwd

/root

iac-server $ cd /root/terraform-challenges/project-citadel

iac-server $ ls

install-nginx.sh  main.tf  provider.tf

iac-server $



2. use the script called install-nginx.sh as the value for the user_data argument.
check existing provider & main terraform files

iac-server $ cat install-nginx.sh

#!/bin/bash

sudo yum update -y

sudo yum install nginx -y

sudo systemctl start nginx

iac-server $

iac-server $ cat main.tf

iac-server $

iac-server $ cat 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

 

endpoints {

    ec2            = "http://aws:4566"

    apigateway     = "http://aws:4566"

    cloudformation = "http://aws:4566"

    cloudwatch     = "http://aws:4566"

    dynamodb       = "http://aws:4566"

    es             = "http://aws:4566"

    firehose       = "http://aws:4566"

    iam            = "http://aws:4566"

    kinesis        = "http://aws:4566"

    lambda         = "http://aws:4566"

    route53        = "http://aws:4566"

    redshift       = "http://aws:4566"

    s3             = "http://aws:4566"

    secretsmanager = "http://aws:4566"

    ses            = "http://aws:4566"

    sns            = "http://aws:4566"

    sqs            = "http://aws:4566"

    ssm            = "http://aws:4566"

    stepfunctions  = "http://aws:4566"

    sts            = "http://aws:4566"

  }

}

iac-server $



3. Create terraform resources 

citadel , ec2_elastic_ip , ssh-key-citadel , variables

Created  TF files with all the parameters, Kindly clone repo or you can copy from GitLab 

git clone https://gitlab.com/nb-tech-support/devops.git

 Refer Below Video for more clarity )


iac-server $ cat ssh-key-citadel.tf

resource "aws_key_pair" "citadel-key" {

  key_name   = "citadel"

  public_key = file("/root/terraform-challenges/project-citadel/.ssh/ec2-connect-key.pub")

}

 

iac-server $ cat citadel.tf

resource "aws_instance" "citadel" {

  ami           = var.ami

  instance_type = var.instance_type

  key_name      = aws_key_pair.citadel-key.key_name

  user_data     = file("/root/terraform-challenges/project-citadel/install-nginx.sh")

}

iac-server $ cat ec2_elastic_ip.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"

  }

}

iac-server $



4. Run  terraform  init & terraform plan to check for any error before to apply.

iac-server $ terraform init

 

Initializing the backend...

 

Initializing provider plugins...

- Finding hashicorp/aws versions matching "4.15.0"...

- Installing hashicorp/aws v4.15.0...

- Installed hashicorp/aws v4.15.0 (self-signed, key ID 34365D9472D7468F)

 

Partner and community providers are signed by their developers.

If you'd like to know more about provider signing, you can read about it here:

https://www.terraform.io/docs/plugins/signing.html

 

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.

iac-server $ terraform plan

Refreshing Terraform state in-memory prior to plan...

The refreshed state will be used to calculate this plan, but will not be

persisted to local or remote state storage.


------------------------------------------------------------------------

 

An execution plan has been generated and is shown below.

Resource actions are indicated with the following symbols:

  + create

 

Terraform will perform the following actions:

 

  # aws_eip.eip will be created

  + resource "aws_eip" "eip" {

      + allocation_id        = (known after apply)

      + association_id       = (known after apply)

      + carrier_ip           = (known after apply)

      + customer_owned_ip    = (known after apply)

      + domain               = (known after apply)

      + id                   = (known after apply)

      + instance             = (known after apply)

      + network_border_group = (known after apply)

      + network_interface    = (known after apply)

      + private_dns          = (known after apply)

      + private_ip           = (known after apply)

      + public_dns           = (known after apply)

      + public_ip            = (known after apply)

      + public_ipv4_pool     = (known after apply)

      + tags_all             = (known after apply)

      + vpc                  = true

    }

 

  # aws_instance.citadel will be created

  + resource "aws_instance" "citadel" {

      + ami                                  = "ami-06178cf087598769c"

      + 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)

      + disable_api_termination              = (known after apply)

      + ebs_optimized                        = (known after apply)

      + get_password_data                    = false

      + host_id                              = (known after apply)

      + id                                   = (known after apply)

      + instance_initiated_shutdown_behavior = (known after apply)

      + instance_state                       = (known after apply)

      + instance_type                        = "m5.large"

      + ipv6_address_count                   = (known after apply)

      + ipv6_addresses                       = (known after apply)

      + key_name                             = "citadel"

      + monitoring                           = (known after apply)

      + outpost_arn                          = (known after apply)

      + password_data                        = (known after apply)

      + placement_group                      = (known after apply)

      + placement_partition_number           = (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)

      + source_dest_check                    = true

      + subnet_id                            = (known after apply)

      + tags_all                             = (known after apply)

      + tenancy                              = (known after apply)

      + user_data                            = "1751b4ee8cedb2fb6bfa764f0587ac7c4e76c779"

      + user_data_base64                     = (known after apply)

      + user_data_replace_on_change          = false

      + vpc_security_group_ids               = (known after apply)

 

      + capacity_reservation_specification {

          + capacity_reservation_preference = (known after apply)

 

          + capacity_reservation_target {

              + capacity_reservation_id                 = (known after apply)

              + capacity_reservation_resource_group_arn = (known after apply)

            }

        }

 

      + ebs_block_device {

          + delete_on_termination = (known after apply)

          + device_name           = (known after apply)

          + encrypted             = (known after apply)

          + iops                  = (known after apply)

          + kms_key_id            = (known after apply)

          + snapshot_id           = (known after apply)

          + tags                  = (known after apply)

          + throughput            = (known after apply)

          + volume_id             = (known after apply)

          + volume_size           = (known after apply)

          + volume_type           = (known after apply)

        }

 

      + enclave_options {

          + enabled = (known after apply)

        }

 

      + ephemeral_block_device {

          + device_name  = (known after apply)

          + no_device    = (known after apply)

          + virtual_name = (known after apply)

        }

 

      + maintenance_options {

          + auto_recovery = (known after apply)

        }

 

      + metadata_options {

          + http_endpoint               = (known after apply)

          + http_put_response_hop_limit = (known after apply)

          + http_tokens                 = (known after apply)

          + instance_metadata_tags      = (known after apply)

        }

 

      + network_interface {

          + delete_on_termination = (known after apply)

          + device_index          = (known after apply)

          + network_card_index    = (known after apply)

          + network_interface_id  = (known after apply)

        }

 

      + root_block_device {

          + delete_on_termination = (known after apply)

          + device_name           = (known after apply)

          + encrypted             = (known after apply)

          + iops                  = (known after apply)

          + kms_key_id            = (known after apply)

          + tags                  = (known after apply)

          + throughput            = (known after apply)

          + volume_id             = (known after apply)

          + volume_size           = (known after apply)

          + volume_type           = (known after apply)

        }

    }

 

  # aws_key_pair.citadel-key will be created

  + resource "aws_key_pair" "citadel-key" {

      + arn             = (known after apply)

      + fingerprint     = (known after apply)

      + id              = (known after apply)

      + key_name        = "citadel"

      + key_name_prefix = (known after apply)

      + key_pair_id     = (known after apply)

      + public_key      = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDi/ANd86SvCBNjCrJ86NWdVqIuh9TSuL2tgqZC58MbggMXdpxf27RM+ov6i6/vX2vIVfHgkOkAkpVV1d8jcux4vjQc3BThGvufycRoqyQMFuNUwz8iENW3+/bMUe7Vm1TqLjc0cj6QdtC9BiwsOJuRrXyLtAeoTYZk3KDfViP7g+TkROlM3Q3pNhtziuLdX97XzMrcKbhrZMs6B3ZY2gq1ucfRUIiZAsVuip9z/wLkeIGz3D+I33NF9s6TdBed7P4aS/EXhL2Lar6UUo8sUvySSrasWggAQv+Db3OjwbRTfrg36AyudYzsJUTLwIjn1ji9QxhExcC7GQv/4oyOgQBH root@iac-server"

      + tags_all        = (known after apply)

    }

 

Plan: 3 to add, 0 to change, 0 to destroy.

 

------------------------------------------------------------------------

 

Note: You didn't specify an "-out" parameter to save this plan, so Terraform

can't guarantee that exactly these actions will be performed if

"terraform apply" is subsequently run.

 iac-server $



Happy Learning!!!!


Apart from this if you need more clarity,  I have made a  tutorial video on this , please go through and share your comments. Like and share the knowledge





























Post a Comment

0 Comments

Latest Posts

KodeKloud Kubernetes Security CKS  Lab Challenge 4 |  Audit-policy | Install & configure falco utility | Inspect the API server audit logs and identify the user