diff --git a/eventbridge-schedule-to-ec2-terraform/README.md b/eventbridge-schedule-to-ec2-terraform/README.md new file mode 100644 index 000000000..d12c5d850 --- /dev/null +++ b/eventbridge-schedule-to-ec2-terraform/README.md @@ -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 diff --git a/eventbridge-schedule-to-ec2-terraform/example-pattern.json b/eventbridge-schedule-to-ec2-terraform/example-pattern.json new file mode 100644 index 000000000..42412fa64 --- /dev/null +++ b/eventbridge-schedule-to-ec2-terraform/example-pattern.json @@ -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: terraform destroy." + ] + }, + "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" + } + ] + } + diff --git a/eventbridge-schedule-to-ec2-terraform/main.tf b/eventbridge-schedule-to-ec2-terraform/main.tf new file mode 100644 index 000000000..563edfd0a --- /dev/null +++ b/eventbridge-schedule-to-ec2-terraform/main.tf @@ -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" + } + }, + ] + }) +} diff --git a/eventbridge-schedule-to-ec2-terraform/variables.tf b/eventbridge-schedule-to-ec2-terraform/variables.tf new file mode 100644 index 000000000..832228321 --- /dev/null +++ b/eventbridge-schedule-to-ec2-terraform/variables.tf @@ -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" +}