top of page

Terraform-Day-3

### Hands-on Lab: Using Provisioners in Terraform


Provisioners in Terraform allow you to execute scripts or commands on resources after they are created. This lab focuses on launching an EC2 instance using Terraform and automating the installation of the Apache HTTP server using provisioners.


### Scenario

You need to launch an EC2 instance and automatically install Apache HTTP server. Provisioners will:

- Use `remote-exec` to SSH into the instance and install Apache.

- Use `file` to upload a custom configuration file.


### Prerequisites

- Terraform installed.

- AWS CLI installed and configured.

- An AWS account with IAM permissions to create EC2 instances.

- An SSH key pair created in AWS.


#### Step 1: Set Up the Project Directory

1. Create a new directory for your Terraform project:

   mkdir terraform-provisioners-lab

   cd terraform-provisioners-lab

2. Create the following Terraform files:

- `main.tf`: Defines EC2 resources and provisioners.

- `variables.tf`: Contains variables for instance type and AMI ID.

- `outputs.tf`: Outputs EC2 instance details.


#### Step 2: Define the EC2 Instance Resource with Provisioners


`main.tf`:


provider "aws" {

  region = "us-west-2"

}



resource "aws_instance" "example" {

  ami           = "ami-0abcdef1234567890" # Replace with a valid AMI ID

  instance_type = "t2.micro"

  key_name      = "my-key-pair"           # Replace with your key pair name

  tags = {

    Name = "Terraform-EC2-Instance"

  }



  # File provisioner to upload index.html

  provisioner "file" {

    source      = "index.html"

    destination = "/tmp/index.html"

  }



  # Remote-exec provisioner to install Apache

  provisioner "remote-exec" {

    inline = [

      "sudo yum update -y",

      "sudo yum install httpd -y",

      "sudo systemctl start httpd",

      "sudo systemctl enable httpd",

      "sudo cp /tmp/index.html /var/www/html"

    ]



    connection {

      type        = "ssh"

      user        = "ec2-user"  # Default user for Amazon Linux

      private_key = file("~/.ssh/my-key-pair.pem") # Replace with your private key

      host        = aws_instance.example.public_ip

    }

  }

}

#### Step 3: Create the HTML File


Create a simple HTML file named `index.html` with the following content:


<!DOCTYPE html>

<html lang="en">

<head>

  <meta charset="UTF-8">

  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <title>Terraform Provisioners Example</title>

</head>

<body>

  <h1>Apache HTTP Server Provisioned by Terraform!</h1>

</body>

</html>


#### Step 4: Initialize Terraform

Run the following command to initialize the Terraform project:


terraform init

#### Step 5: Apply the Configuration

1. Run the following command:

 terraform apply

2. Confirm with `yes`. Terraform will create the EC2 instance, upload the HTML file, and install Apache.


Expected Output:


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

Outputs:

instance_id = i-xxxxxxxxxxxxxxxxx

public_ip = 203.0.113.0


#### Step 6: Access the EC2 Instance

1. Open your browser and navigate to:

http://<public-ip-of-ec2>

2. You should see the message:

Apache HTTP Server Provisioned by Terraform!

#### Step 7: Validate the Provisioners

- Ensure Apache HTTP server is running.

- Verify the uploaded HTML file is served correctly.



#### Step 8: Destroy Resources

To clean up resources, run:


terraform destroy

Confirm with `yes` to delete the EC2 instance.


### Conclusion

In this lab, we:

1. Created an EC2 instance using Terraform.

2. Used the `file` provisioner to upload a file to the instance.

3. Used the `remote-exec` provisioner to install Apache HTTP server and configure it.

4. Verified the setup by accessing the EC2 instance's public IP.

5. Cleaned up resources with `terraform destroy`.


Provisioners in Terraform enable efficient automation for post-provisioning tasks, ensuring consistent and reliable infrastructure configuration.


 

# Hands-on Lab: Creating EC2 Instance with VPC, Subnet, Internet Gateway, Route Table, and Security Group


In this lab, we will walk through the process of creating an EC2 instance within a custom VPC in AWS using Terraform. The resources we will create include:


- VPC: A custom Virtual Private Cloud to host the EC2 instance.

- Subnet: A subnet within the VPC for the EC2 instance.

- Internet Gateway (IGW): To allow internet access to the EC2 instance.

- Route Table: To define the route for traffic within the VPC.

- Route Table Association: To associate the route table with the subnet.

- Security Group: To define firewall rules for the EC2 instance.



## Prerequisites

1. Terraform installed.

2. AWS CLI installed and configured.

3. AWS account with appropriate IAM roles and policies to create VPC, EC2 instances, and related resources.


### Step 1: Set Up the Terraform Project Directory

Create a directory for the project:

mkdir terraform-ec2-vpc-lab

cd terraform-ec2-vpc-lab

### Step 2: Define the Terraform Configuration Files

Create the following Terraform configuration files:

1. `main.tf`: Contains all the resource definitions.

2. `variables.tf`: Defines input variables such as instance type, region, etc.

3. `outputs.tf`: Specifies outputs like EC2 instance IP and VPC ID.


### Step 3: Create the VPC, Subnet, and Other Resources in `main.tf`


`main.tf`:


provider "aws" {

  region = "us-west-2"

}


# Create VPC

resource "aws_vpc" "main" {

  cidr_block           = "10.0.0.0/16"

  enable_dns_support   = true

  enable_dns_hostnames = true

  tags = {

    Name = "terraform-vpc"

  }

}



# Create Subnet

resource "aws_subnet" "subnet_1" {

  vpc_id            = aws_vpc.main.id

  cidr_block        = "10.0.1.0/24"

  availability_zone = "us-west-2a"

  tags = {

    Name = "terraform-subnet"

  }

}



# Create Internet Gateway (IGW)

resource "aws_internet_gateway" "gw" {

  vpc_id = aws_vpc.main.id

  tags = {

    Name = "terraform-igw"

  }

}



# Create Route Table

resource "aws_route_table" "route_table" {

  vpc_id = aws_vpc.main.id



  route {

    cidr_block = "0.0.0.0/0"

    gateway_id = aws_internet_gateway.gw.id

  }



  tags = {

    Name = "terraform-route-table"

  }

}



# Associate Route Table with Subnet

resource "aws_route_table_association" "assoc" {

  subnet_id      = aws_subnet.subnet_1.id

  route_table_id = aws_route_table.route_table.id

}



# Create Security Group

resource "aws_security_group" "sec_group" {

  name        = "terraform-sec-group"

  description = "Allow inbound SSH and HTTP"

  vpc_id      = aws_vpc.main.id



  ingress {

    from_port   = 22

    to_port     = 22

    protocol    = "tcp"

    cidr_blocks = ["0.0.0.0/0"]

  }



  ingress {

    from_port   = 80

    to_port     = 80

    protocol    = "tcp"

    cidr_blocks = ["0.0.0.0/0"]

  }



  egress {

    from_port   = 0

    to_port     = 0

    protocol    = "-1"

    cidr_blocks = ["0.0.0.0/0"]

  }

}



# Create EC2 Instance

resource "aws_instance" "web" {

  ami                         = "ami-0abcdef1234567890"  # Replace with your AMI ID

  instance_type               = "t2.micro"

  subnet_id                   = aws_subnet.subnet_1.id

  security_groups             = [aws_security_group.sec_group.name]

  associate_public_ip_address = true



  tags = {

    Name = "terraform-ec2-instance"

  }



  # User data to install Apache HTTP Server

  user_data = <<-EOF

              #!/bin/

              yum update -y

              yum install -y httpd

              systemctl start httpd

              systemctl enable httpd

              echo "Hello from Terraform EC2 instance" > /var/www/html/index.html

              EOF

}

### Step 4: Define Variables in `variables.tf`


`variables.tf`:


variable "instance_type" {

  description = "EC2 instance type"

  default     = "t2.micro"

}



variable "ami" {

  description = "AMI ID"

  default     = "ami-0abcdef1234567890"  # Replace with a valid AMI ID

}



variable "region" {

  description = "AWS Region"

  default     = "us-west-2"

}

### Step 5: Define Outputs in `outputs.tf`


`outputs.tf`:


output "instance_public_ip" {

  description = "The public IP of the EC2 instance"

  value       = aws_instance.web.public_ip

}



output "vpc_id" {

  description = "The VPC ID"

  value       = aws_vpc.main.id

}


### Step 6: Initialize Terraform


Run the following command to initialize Terraform and download necessary provider plugins:


terraform init

### Step 7: Apply the Terraform Configuration


To create the resources, run:


terraform apply

Terraform will display an execution plan and ask for confirmation. Type `yes` to proceed.


### Step 8: Verify the EC2 Instance


After successful execution, Terraform will output the public IP address of the EC2 instance. Open the browser and navigate to:

http://<instance_public_ip>

You should see:


Hello from Terraform EC2 instance



### Step 9: Clean Up Resources


To avoid unnecessary charges, clean up the resources by running:


terraform destroy


Type `yes` when prompted.



## Conclusion


In this lab, we:

1. Created a custom VPC with a subnet, internet gateway, route table, and security group.

2. Launched an EC2 instance and installed Apache HTTP Server using a user data script.

3. Verified the web server by accessing the EC2 instance’s public IP.

4. Cleaned up resources with `terraform destroy`.

bottom of page