-
Notifications
You must be signed in to change notification settings - Fork 928
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1487 from professional-ian/professional-ian-featu…
…re-eventbridge-schedule-to-ec2-terraform New serverless pattern - EventBridge Scheduler to EC2 using Terraform
- Loading branch information
Showing
4 changed files
with
279 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# EventBridge Scheduler to start and stop EC2 instances | ||
This pattern will create two EventBridge schedules that will start and stop a given array of instance-ids. You can control the start/stop time and timezone of you chosing. This example will start instances at 08:00 and stop them at 17:00 in the US/Eastern timezone. | ||
|
||
Learn more about this pattern at Serverless Land Patterns: https://serverlessland.com/patterns/eventbridge-schedule-to-ec2-terraform. | ||
|
||
Important: this application uses various AWS services and there are costs associated with these services after the Free Tier usage - please see the [AWS Pricing page](https://aws.amazon.com/pricing/) for details. You are responsible for any AWS costs incurred. No warranty is implied in this example. | ||
|
||
|
||
## Requirements | ||
|
||
* [Create an AWS account](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html) if you do not already have one and log in. The IAM user that you use must have sufficient permissions to make necessary AWS service calls and manage AWS resources. | ||
* [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) installed and configured | ||
* [Git Installed](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) | ||
* [Terraform](https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started) installed | ||
|
||
## Deployment Instructions | ||
|
||
1. Create a new directory, navigate to that directory in a terminal and clone the GitHub repository: | ||
``` | ||
git clone https://github.com/aws-samples/serverless-patterns | ||
``` | ||
1. Change directory to the pattern directory: | ||
``` | ||
cd eventbridge-schedule-to-ec2-terraform | ||
``` | ||
1. From the command line, initialize Terraform: | ||
``` | ||
terraform init | ||
``` | ||
1. From the commend line, apply the configuration in the main.tf file and follow the prompts: | ||
``` | ||
terraform apply | ||
``` | ||
|
||
|
||
## How it works | ||
|
||
An Amazon EventBridge Schedule is used to start and stop an EC2 instance. The Terraform stack creates a VPC, EC2 instance and EventBridge Scheduler that invokes the startInstance and stopInstance API on a schedule. | ||
|
||
## Testing | ||
|
||
1. After deployment, view the schedule created in the Amazon EventBridge console under Scheduler>Schedules. | ||
2. View the `ec2-start-schedule`. Navigate to the *Target* tab and note the `Payload` value which is in the format: `{"InstanceIds":["i-006c2e9f4e706bf48"]}` | ||
3. Navigate to the EC2 console and find the EC2 instance from the `Payload` value. Check the instance is powered on during 08:00 and 17:00 in the US/Eastern timezone. | ||
|
||
## Cleanup | ||
|
||
1. Delete all created resources and follow prompts: | ||
``` | ||
terraform destroy | ||
``` | ||
---- | ||
Copyright 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. | ||
|
||
SPDX-License-Identifier: MIT-0 |
54 changes: 54 additions & 0 deletions
54
eventbridge-schedule-to-ec2-terraform/example-pattern.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
{ | ||
"title": "EventBridge Scheduler to start and stop EC2 instances Monday to Friday", | ||
"description": "Simple pattern that starts and stops given EC2 instances based on time of day, timezone and days of week", | ||
"level": "300", | ||
"framework": "Terraform", | ||
"introBox": { | ||
"headline": "How it works", | ||
"text": ["Creates a schedule that turns on instances at 08:00 and turns them off at 17:00 Monday to Friday using the US/Eastern timezone."] | ||
}, | ||
"gitHub": { | ||
"template": { | ||
"repoURL": "https://github.com/aws-samples/serverless-patterns/tree/main/eventbridge-schedule-to-ec2-terrafrom", | ||
"templateURL": "serverless-patterns/eventbridge-schedule-to-ec2-terraform", | ||
"projectFolder": "eventbridge-schedule-to-ec2-terraform", | ||
"templateFile": "main.tf" | ||
} | ||
}, | ||
"resources": { | ||
"bullets": [ | ||
{ | ||
"text": "Introducing Amazon EventBridge Scheduler", | ||
"link": "https://aws.amazon.com/blogs/compute/introducing-amazon-eventbridge-scheduler/" | ||
}, | ||
{ | ||
"text": "Amazon EventBridge Scheduler Docs", | ||
"link": "https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html" | ||
} | ||
] | ||
}, | ||
"deploy": { | ||
"text": [ | ||
"terraform apply" | ||
] | ||
}, | ||
"testing": { | ||
"text": [ | ||
"See the Github repo for detailed testing instructions." | ||
] | ||
}, | ||
"cleanup": { | ||
"text": [ | ||
"Delete the stack: <code>terraform destroy</code>." | ||
] | ||
}, | ||
"authors": [ | ||
{ | ||
"name": "Ian Lodge", | ||
"image": "https://avatars.githubusercontent.com/u/135351711?v=4", | ||
"bio": "Ian is a Solutions Architect at Amazon Web Services based in the US.", | ||
"linkedin": "https://www.linkedin.com/in/ian-lodge" | ||
} | ||
] | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
terraform { | ||
required_providers { | ||
aws = { | ||
source = "hashicorp/aws" | ||
version = ">= 4.64.0" | ||
} | ||
} | ||
} | ||
|
||
provider "aws" { | ||
region = var.region | ||
} | ||
|
||
locals { | ||
project_name = "tf-test" | ||
} | ||
|
||
|
||
# This section creates VPC resources for the Amazon EC2 environment | ||
|
||
resource "aws_vpc" "vpc" { | ||
cidr_block = var.vpc_cidr | ||
} | ||
|
||
resource "aws_subnet" "subnet" { | ||
vpc_id = aws_vpc.vpc.id | ||
cidr_block = var.subnet_cidr | ||
tags = { | ||
Name = "private-subnet-1" | ||
} | ||
} | ||
|
||
# This section creates an Amazon EC2 instance using the latest Amazon Linux AMI | ||
|
||
data "aws_ami" "amazon-linux-2" { | ||
most_recent = true | ||
|
||
filter { | ||
name = "owner-alias" | ||
values = ["amazon"] | ||
} | ||
|
||
filter { | ||
name = "name" | ||
values = ["amzn2-ami-hvm*"] | ||
} | ||
} | ||
|
||
resource "aws_instance" "test-ec2" { | ||
ami = "${data.aws_ami.amazon-linux-2.id}" | ||
instance_type = "t3.micro" | ||
subnet_id = aws_subnet.subnet.id | ||
tags = { | ||
Name = "tf-test-ec2" | ||
} | ||
} | ||
|
||
# This section creates cron schedules using Amazon EventBridge Scheduler, as well as the required IAM roles to interact with EC2 | ||
|
||
resource "aws_scheduler_schedule" "ec2-start-schedule" { | ||
name = "ec2-start-schedule" | ||
|
||
flexible_time_window { | ||
mode = "OFF" | ||
} | ||
|
||
schedule_expression = "cron(0 8 ? * MON-FRI *)" # Scheduled startInstances at 8am EST Mon-Fri | ||
schedule_expression_timezone = "US/Eastern" # Default is UTC | ||
description = "Start instances event" | ||
|
||
target { | ||
arn = "arn:aws:scheduler:::aws-sdk:ec2:startInstances" | ||
role_arn = aws_iam_role.scheduler-ec2-role.arn | ||
|
||
input = jsonencode({ | ||
"InstanceIds": [ | ||
"${aws_instance.test-ec2.id}" | ||
] | ||
}) | ||
} | ||
} | ||
|
||
resource "aws_scheduler_schedule" "ec2-stop-schedule" { | ||
name = "ec2-stop-schedule" | ||
|
||
flexible_time_window { | ||
mode = "OFF" | ||
} | ||
|
||
schedule_expression = "cron(0 17 ? * MON-FRI *)" # Scheduled stopinstances at 5pm EST Mon-Fri | ||
schedule_expression_timezone = "US/Eastern" # Default is UTC | ||
description = "Stop instances event" | ||
|
||
target { | ||
arn = "arn:aws:scheduler:::aws-sdk:ec2:stopInstances" | ||
role_arn = aws_iam_role.scheduler-ec2-role.arn | ||
|
||
input = jsonencode({ | ||
"InstanceIds": [ | ||
"${aws_instance.test-ec2.id}" | ||
] | ||
}) | ||
} | ||
} | ||
|
||
resource "aws_iam_policy" "scheduler_ec2_policy" { | ||
name = "scheduler_ec2_policy" | ||
|
||
policy = jsonencode( | ||
{ | ||
"Version": "2012-10-17", | ||
"Statement": [ | ||
{ | ||
"Sid": "VisualEditor0", | ||
"Effect": "Allow", | ||
"Action": [ | ||
"ec2:StartInstances", | ||
"ec2:StopInstances" | ||
], | ||
"Resource": [ | ||
"${aws_instance.test-ec2.arn}:*", | ||
"${aws_instance.test-ec2.arn}" | ||
], | ||
} | ||
] | ||
} | ||
) | ||
} | ||
|
||
resource "aws_iam_role" "scheduler-ec2-role" { | ||
name = "scheduler-ec2-role" | ||
managed_policy_arns = [aws_iam_policy.scheduler_ec2_policy.arn] | ||
|
||
assume_role_policy = jsonencode({ | ||
Version = "2012-10-17" | ||
Statement = [ | ||
{ | ||
Action = "sts:AssumeRole" | ||
Effect = "Allow" | ||
Sid = "" | ||
Principal = { | ||
Service = "scheduler.amazonaws.com" | ||
} | ||
}, | ||
] | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
variable "region" { | ||
type=string | ||
description = "AWS Region where deploying resources" | ||
default = "us-east-1" | ||
} | ||
|
||
variable "aws_profile_name" { | ||
type=string | ||
description = "AWS CLI credentials profile name" | ||
default="default" | ||
} | ||
|
||
variable "vpc_cidr" { | ||
type=string | ||
description = "CIDR block for VPC" | ||
default = "10.0.0.0/16" | ||
} | ||
|
||
variable "subnet_cidr" { | ||
type=string | ||
description = "CIDR block for the subnet" | ||
default = "10.0.0.0/24" | ||
} |