0% found this document useful (0 votes)
4 views

Lab_Final_terraform

Uploaded by

d
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Lab_Final_terraform

Uploaded by

d
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Lab: Deploying Modular Infrastructure with Terraform

Lab Overview

In this lab, we will:

1. Deploy an EC2 instance inside a VPC using a module.


2. Create a Lambda function to dynamically stop the EC2 instance.
3. Set up CloudWatch alarms and EventBridge rules to trigger the Lambda
function.
4. Organize the infrastructure into modules for better reusability.
5. Use dynamic scripting to pass instance details to the Lambda function.
6. Debug the setup and verify proper functioning.

Learning Objectives

1. Understand how to structure Terraform projects using modules.


2. Learn how to integrate Lambda, EventBridge, and CloudWatch alarms into
an AWS architecture.
3. Explore debugging techniques for Terraform and AWS Lambda.

Directory Structure

Before starting, organize your files as shown:


Your code is here...
-
terraform-lab/
├── main.tf # Core orchestration for modules
├── variables.tf # Global input variables
├── outputs.tf # Outputs from all modules
├── provider.tf # AWS provider configuration
├── modules/
│ ├── ec2/
│ │ ├── main.tf # EC2 resources
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ ├── lambda/
│ │ ├── main.tf # Lambda resources
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ ├── scripts/
│ │ │ └── shutdown_instance.py # Python script for Lambda
│ ├── cloudwatch/
│ │ ├── main.tf # CloudWatch and EventBridge resources
│ │ ├── variables.tf
│ │ ├── outputs.tf

Step-by-Step Lab Instructions

1. Configure the Provider

In provider.tf, define the AWS provider:


Your code is here...
-
provider "aws" {
region = var.region
}

variable "region" {
default = "ap-southeast-2"
}
2. Define Global Variables

In variables.tf, declare reusable variables:


Your code is here...
-
variable "ec2_instance_name" {
description = "Name of the EC2 instance"
default = "example-ec2-instance"
}

variable "instance_type" {
description = "Type of the EC2 instance"
default = "t2.micro"
}

variable "lambda_function_name" {
description = "Name of the Lambda function"
default = "shutdown-ec2-instance"
}

3. Create the EC2 Module


modules/ec2/main.tf

Your code is here...


-
resource "aws_instance" "instance" {
ami = "ami-0d6560f3176dc9ec0"
instance_type = var.instance_type

tags = {
Name = var.instance_name
}
}

output "instance_id" {
value = aws_instance.instance.id
}

output "public_ip" {
value = aws_instance.instance.public_ip
}

modules/ec2/variables.tf

Your code is here...


-
variable "instance_name" {
description = "Name of the EC2 instance"
}

variable "instance_type" {
description = "Type of the EC2 instance"
}

4. Create the Lambda Module


modules/lambda/main.tf

Your code is here...


-
resource "aws_lambda_function" "shutdown_lambda" {
function_name = var.lambda_function_name
runtime = "python3.9"
handler = "shutdown_instance.lambda_handler"
role = aws_iam_role.lambda_role.arn
filename = "${path.module}/scripts/shutdown_instance.zip"

environment {
variables = {
INSTANCE_ID = var.instance_id
}
}
}

resource "aws_iam_role" "lambda_role" {


name = "lambda-ec2-shutdown-role"

assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "lambda.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
}

resource "aws_iam_role_policy_attachment" "lambda_policy_attachment" {


role = aws_iam_role.lambda_role.name
policy_arn = aws_iam_policy.ec2_shutdown_policy.arn
}
resource "aws_iam_policy" "ec2_shutdown_policy" {
name = "ec2-shutdown-policy"
description = "Allows Lambda to stop EC2 instances"
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Action = [
"ec2:StopInstances",
"ec2:DescribeInstances"
],
Resource = "*"
}
]
})
}

modules/lambda/variables.tf

Your code is here...


-
variable "lambda_function_name" {
description = "Name of the Lambda function"
}

variable "instance_id" {
description = "ID of the EC2 instance to shut down"
}

modules/lambda/scripts/shutdown_instance.py

python
-
import boto3
import os

def lambda_handler(event, context):


ec2_client = boto3.client('ec2')
instance_id = os.environ['INSTANCE_ID']

try:
response =
ec2_client.stop_instances(InstanceIds=[instance_id])
return {
"statusCode": 200,
"body": f"Shutting down instance {instance_id}"
}
except Exception as e:
return {
"statusCode": 500,
"body": f"Error: {str(e)}"
}

Compress the script into shutdown_instance.zip:


Your code is here...
-
zip shutdown_instance.zip shutdown_instance.py

5. Create the CloudWatch Module


modules/cloudwatch/main.tf

Your code is here...


-
resource "aws_cloudwatch_event_rule" "delayed_trigger" {
name = "shutdown-ec2-after-5-minutes"
description = "Trigger Lambda function to shut down EC2
after 5 minutes"
schedule_expression = "rate(5 minutes)"
}

resource "aws_cloudwatch_event_target" "lambda_target" {


rule = aws_cloudwatch_event_rule.delayed_trigger.name
target_id = "shutdown-ec2-target"
arn = var.lambda_arn
}

resource "aws_lambda_permission" "allow_cloudwatch" {


statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = var.lambda_function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.delayed_trigger.arn
}

modules/cloudwatch/variables.tf

Your code is here...


-
variable "lambda_function_name" {
description = "Name of the Lambda function"
}

variable "lambda_arn" {
description = "ARN of the Lambda function"
}
6. Main Orchestration
main.tf

Your code is here...


-
module "ec2" {
source = "./modules/ec2"
instance_name = var.ec2_instance_name
instance_type = var.instance_type
}

module "lambda" {
source = "./modules/lambda"
lambda_function_name = var.lambda_function_name
instance_id = module.ec2.instance_id
}

module "cloudwatch" {
source = "./modules/cloudwatch"
lambda_function_name = var.lambda_function_name
lambda_arn = module.lambda.shutdown_lambda_arn
}

7. Debugging Tips

1. Check Terraform Logs:


o Use TF_LOG=DEBUG terraform apply to view detailed logs.
2. Lambda Logs:
o Check CloudWatch Logs for Lambda function execution details.
3. Test CloudWatch Events:
o Manually trigger the EventBridge rule and verify Lambda execution.

8. Deploy the Lab

1. Initialize Terraform:
Your code is here...
-
terraform init
2. Plan the Deployment:
Your code is here...
-
terraform plan

3. Apply the Deployment:


Your code is here...
-
terraform apply

You might also like