terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "5.82.2"
}
}
}
provider "aws" {
region = "ap-southeast-2"
}
# Create an EC2 instance
resource "aws_instance" "example_ec2" {
ami = "ami-0d6560f3176dc9ec0" # Replace with a valid AMI for your region
instance_type = "t2.micro"
tags = {
Name = "example-ec2-instance"
}
}
# Create IAM Role for Lambda
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"
}
]
})
}
# Attach EC2 Shutdown Permissions to Lambda Role
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 = "*"
}
]
})
}
resource "aws_iam_role_policy_attachment" "lambda_attach_policy" {
role = aws_iam_role.lambda_role.name
policy_arn = aws_iam_policy.ec2_shutdown_policy.arn
}
# Lambda Function to Shut Down EC2 Instance
resource "aws_lambda_function" "shutdown_lambda" {
function_name = "shutdown-ec2-instance"
runtime = "python3.9"
handler = "lambda_function.lambda_handler"
role = aws_iam_role.lambda_role.arn
filename = "lambda_function.zip"
environment {
variables = {
INSTANCE_ID = aws_instance.example_ec2.id
}
}
}
# CloudWatch Event Rule to Trigger Lambda after 5 Minutes
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)" # Trigger Lambda every 5 minutes
}
# CloudWatch Event Target to Link Rule and Lambda
resource "aws_cloudwatch_event_target" "lambda_target" {
rule = aws_cloudwatch_event_rule.delayed_trigger.name
target_id = "shutdown-ec2-target"
arn = aws_lambda_function.shutdown_lambda.arn
}
# Allow CloudWatch to Invoke Lambda
resource "aws_lambda_permission" "allow_cloudwatch" {
statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.shutdown_lambda.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.delayed_trigger.arn
}
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)}"
}
Save it as as lambda_function.py and zip it