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