NEW: ec2 instance scheduler
This commit is contained in:
parent
076bc5013c
commit
2ac422441b
16
modules/compute/ec2-instance-scheduler/Ec2Scheduler.py
Normal file
16
modules/compute/ec2-instance-scheduler/Ec2Scheduler.py
Normal file
@ -0,0 +1,16 @@
|
||||
import boto3
|
||||
import os
|
||||
import json
|
||||
|
||||
# reference: https://aws.amazon.com/premiumsupport/knowledge-center/start-stop-lambda-eventbridge/
|
||||
|
||||
ec2 = boto3.client('ec2', region_name=os.environ['region_name'])
|
||||
|
||||
def lambda_handler(event, context):
|
||||
if (event['action'] == 'start'):
|
||||
resp = ec2.start_instances(InstanceIds=json.loads(os.environ['instances']))
|
||||
elif (event['action'] == 'stop'):
|
||||
resp = ec2.stop_instances(InstanceIds=json.loads(os.environ['instances']))
|
||||
else:
|
||||
resp = "Event action not provided"
|
||||
return resp
|
52
modules/compute/ec2-instance-scheduler/README.md
Normal file
52
modules/compute/ec2-instance-scheduler/README.md
Normal file
@ -0,0 +1,52 @@
|
||||
<!-- This readme file is generated with terraform-docs -->
|
||||
## Requirements
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| terraform | >= 1.3.0 |
|
||||
| aws | >= 5.0 |
|
||||
|
||||
## Providers
|
||||
|
||||
| Name | Version |
|
||||
|------|---------|
|
||||
| archive | n/a |
|
||||
| aws | >= 5.0 |
|
||||
| random | n/a |
|
||||
|
||||
## Modules
|
||||
|
||||
No modules.
|
||||
|
||||
## Resources
|
||||
|
||||
| Name | Type |
|
||||
|------|------|
|
||||
| [aws_iam_role.eventscheduler](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
|
||||
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
|
||||
| [aws_iam_role_policy.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy) | resource |
|
||||
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
|
||||
| [aws_lambda_function.ec2-start-stop](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
|
||||
| [aws_lambda_permission.lambda_permission](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
|
||||
| [aws_scheduler_schedule.start](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/scheduler_schedule) | resource |
|
||||
| [aws_scheduler_schedule.stop](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/scheduler_schedule) | resource |
|
||||
| [random_id.this](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/id) | resource |
|
||||
| [archive_file.lambda-package](https://registry.terraform.io/providers/hashicorp/archive/latest/docs/data-sources/file) | data source |
|
||||
| [aws_caller_identity.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
|
||||
|
||||
## Inputs
|
||||
|
||||
| Name | Description | Type | Default | Required |
|
||||
|------|-------------|------|---------|:--------:|
|
||||
| description | A description of instances to be started/stopped on schedule | `string` | n/a | yes |
|
||||
| instance-ids | Instances to be automatically started/stopped on schedule | `list(string)` | n/a | yes |
|
||||
| instance-start-cron-expression | Cron expression for instance start schedule | `string` | n/a | yes |
|
||||
| instance-stop-cron-expression | Cron expression for instance stop schedule | `string` | n/a | yes |
|
||||
|
||||
## Outputs
|
||||
|
||||
No outputs.
|
||||
|
||||
---
|
||||
## Authorship
|
||||
This module was developed by UPDATE_THIS.
|
171
modules/compute/ec2-instance-scheduler/main.tf
Normal file
171
modules/compute/ec2-instance-scheduler/main.tf
Normal file
@ -0,0 +1,171 @@
|
||||
data "aws_caller_identity" "this" {}
|
||||
|
||||
resource "random_id" "this" {
|
||||
byte_length = 4
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "eventscheduler" {
|
||||
name = "EventSchedulerRole-${random_id.this.dec}"
|
||||
assume_role_policy = jsonencode(
|
||||
{
|
||||
"Version" : "2012-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Effect" : "Allow",
|
||||
"Principal" : {
|
||||
"Service" : "scheduler.amazonaws.com"
|
||||
},
|
||||
"Action" : "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy_attachment" "this" {
|
||||
policy_arn = "arn:aws:iam::aws:policy/AmazonEventBridgeSchedulerFullAccess"
|
||||
role = aws_iam_role.eventscheduler.name
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "this" {
|
||||
name = "lambda-startstop-ec2-${var.description}"
|
||||
|
||||
assume_role_policy = jsonencode(
|
||||
{
|
||||
"Version" : "2012-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Effect" : "Allow",
|
||||
"Principal" : {
|
||||
"Service" : "lambda.amazonaws.com"
|
||||
},
|
||||
"Action" : "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "this" {
|
||||
policy = jsonencode(
|
||||
{
|
||||
"Version" : "2012-10-17",
|
||||
"Statement" : [
|
||||
{
|
||||
"Sid" : "AllowCreationOfCloudwatchLogGroup",
|
||||
"Effect" : "Allow",
|
||||
"Action" : "logs:CreateLogGroup",
|
||||
"Resource" : "arn:aws:logs:ap-east-1:${data.aws_caller_identity.this.account_id}:*"
|
||||
},
|
||||
{
|
||||
"Sid" : "AllowWritingToCloudwatchLogGroup",
|
||||
"Effect" : "Allow",
|
||||
"Action" : [
|
||||
"logs:CreateLogStream",
|
||||
"logs:PutLogEvents"
|
||||
],
|
||||
"Resource" : [
|
||||
"arn:aws:logs:ap-east-1:${data.aws_caller_identity.this.account_id}:log-group:/aws/lambda/*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Sid" : "AllowStartingStoppingOfEc2Instance",
|
||||
"Action" : [
|
||||
"ec2:StopInstances",
|
||||
"ec2:StartInstances",
|
||||
"kms:CreateGrant"
|
||||
],
|
||||
"Effect" : "Allow",
|
||||
"Resource" : "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
role = aws_iam_role.this.id
|
||||
name = "LambdaExecutionPolicy"
|
||||
}
|
||||
|
||||
resource "aws_scheduler_schedule" "start" {
|
||||
name = "scheduled-start-of-${var.description}-instances"
|
||||
description = "Starts ${var.description} ec2 instance"
|
||||
flexible_time_window {
|
||||
mode = "OFF"
|
||||
}
|
||||
|
||||
schedule_expression = var.instance-start-cron-expression
|
||||
|
||||
target {
|
||||
arn = aws_lambda_function.ec2-start-stop.arn
|
||||
role_arn = aws_iam_role.eventscheduler.arn
|
||||
input = jsonencode({ "action" : "start" })
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_scheduler_schedule" "stop" {
|
||||
name = "scheduled-stop-of-${var.description}-instances"
|
||||
description = "Stops ${var.description} ec2 instance"
|
||||
flexible_time_window {
|
||||
mode = "OFF"
|
||||
}
|
||||
|
||||
schedule_expression = var.instance-stop-cron-expression
|
||||
|
||||
target {
|
||||
arn = aws_lambda_function.ec2-start-stop.arn
|
||||
role_arn = aws_iam_role.eventscheduler.arn
|
||||
input = jsonencode({ "action" : "stop" })
|
||||
}
|
||||
}
|
||||
#
|
||||
#resource "aws_cloudwatch_event_rule" "start" {
|
||||
# name = "scheduled-start-of-${var.description}-instances"
|
||||
# description = "Starts automation ec2 instance"
|
||||
# schedule_expression = var.instance-start-cron-expression
|
||||
#}
|
||||
#
|
||||
#resource "aws_cloudwatch_event_rule" "stop" {
|
||||
# name = "scheduled-stop-of-${var.description}-instances"
|
||||
# description = "Stops automation ec2 instance"
|
||||
# schedule_expression = var.instance-stop-cron-expression
|
||||
#}
|
||||
#
|
||||
#resource "aws_cloudwatch_event_target" "start" {
|
||||
# rule = aws_cloudwatch_event_rule.start.name
|
||||
# arn = aws_lambda_function.ec2-start-stop.arn
|
||||
# input = "{\"action\": \"start\"}"
|
||||
#}
|
||||
#
|
||||
#resource "aws_cloudwatch_event_target" "stop" {
|
||||
# rule = aws_cloudwatch_event_rule.stop.name
|
||||
# arn = aws_lambda_function.ec2-start-stop.arn
|
||||
# input = "{\"action\": \"stop\"}"
|
||||
#}
|
||||
|
||||
# Lambda function for instance scheduler
|
||||
data "archive_file" "lambda-package" {
|
||||
type = "zip"
|
||||
source_file = "${path.module}/Ec2Scheduler.py"
|
||||
output_path = "lambda-package.zip"
|
||||
}
|
||||
|
||||
resource "aws_lambda_function" "ec2-start-stop" {
|
||||
function_name = "${var.description}-ec2-start-stop"
|
||||
filename = data.archive_file.lambda-package.output_path
|
||||
source_code_hash = data.archive_file.lambda-package.output_base64sha256
|
||||
handler = "Ec2Scheduler.lambda_handler"
|
||||
runtime = "python3.12"
|
||||
role = aws_iam_role.this.arn
|
||||
timeout = 30
|
||||
environment {
|
||||
variables = {
|
||||
instances = jsonencode(var.instance-ids)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_lambda_permission" "lambda_permission" {
|
||||
statement_id = "AllowCloudWatchToInvokeLambda"
|
||||
action = "lambda:InvokeFunction"
|
||||
function_name = aws_lambda_function.ec2-start-stop.function_name
|
||||
principal = "events.amazonaws.com"
|
||||
}
|
19
modules/compute/ec2-instance-scheduler/variables.tf
Normal file
19
modules/compute/ec2-instance-scheduler/variables.tf
Normal file
@ -0,0 +1,19 @@
|
||||
variable instance-start-cron-expression {
|
||||
type = string
|
||||
description = "Cron expression for instance start schedule"
|
||||
}
|
||||
|
||||
variable instance-stop-cron-expression {
|
||||
type = string
|
||||
description = "Cron expression for instance stop schedule"
|
||||
}
|
||||
|
||||
variable instance-ids {
|
||||
type = list(string)
|
||||
description = "Instances to be automatically started/stopped on schedule"
|
||||
}
|
||||
|
||||
variable description {
|
||||
type = string
|
||||
description = "A description of instances to be started/stopped on schedule"
|
||||
}
|
13
modules/compute/ec2-instance-scheduler/versions.tf
Normal file
13
modules/compute/ec2-instance-scheduler/versions.tf
Normal file
@ -0,0 +1,13 @@
|
||||
terraform {
|
||||
required_version = ">= 1.3.0"
|
||||
required_providers {
|
||||
aws = {
|
||||
source = "hashicorp/aws"
|
||||
version = ">= 5.0"
|
||||
}
|
||||
|
||||
archive = {
|
||||
source = "hashicorp/archive"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user