diff --git a/README.md b/README.md index 79d8785e..18181a8e 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,17 @@ Stop and start ec2, rds resources and autoscaling groups with lambda function. ## Features -* Aws lambda runtine Python 3.6 +* Aws lambda runtine Python 3.7 * ec2 instances scheduling +* spot instances scheduling * rds clusters scheduling * rds instances scheduling * autoscalings scheduling * Aws cloudWatch logs for lambda +### Caveats +You can't stop and start an [Amazon Spot instance](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/how-spot-instances-work.html) (only the Spot service can stop and start a Spot Instance), but you can reboot or terminate a Spot Instance. That why this module support only scheduler action `terminate` for spot instance. + ## Usage ```hcl module "stop_ec2_instance" { @@ -20,6 +24,8 @@ module "stop_ec2_instance" { name = "ec2_stop" cloudwatch_schedule_expression = "cron(0 00 ? * FRI *)" schedule_action = "stop" + autoscaling_schedule = "false" + spot_schedule = "terminate" ec2_schedule = "true" rds_schedule = "false" autoscaling_schedule = "false" @@ -32,9 +38,10 @@ module "stop_ec2_instance" { ## Examples -* [EC2 scheduler](https://github.com/diodonfrost/terraform-aws-lambda-scheduler-stop-start/tree/master/examples/ec2-schedule) - Create lamnda functions to stop ec2 with tag `tostop = true` on Friday at 23:00 Gmt and start them on Monday at 07:00 GMT -* [Rds aurora - mariadb scheduler](https://github.com/diodonfrost/terraform-aws-lambda-scheduler-stop-start/tree/master/examples/rds-schedule) - Create lamnda functions to stop rds mariadb and aurora cluster with tag `tostop = true` on Friday at 23:00 Gmt and start them on Monday at 07:00 GMT -* [Autoscaling scheduler](https://github.com/diodonfrost/terraform-aws-lambda-scheduler-stop-start/tree/master/examples/autoscaling-schedule) - Create lamnda functions to suspend autoscaling group with tag `tostop = true` and terminate its ec2 instances on Friday at 23:00 Gmt and start them on Monday at 07:00 GMT +* [Autoscaling scheduler](https://github.com/diodonfrost/terraform-aws-lambda-scheduler-stop-start/tree/master/examples/autoscaling-schedule) - Create lambda functions to suspend autoscaling group with tag `tostop = true` and terminate its ec2 instances on Friday at 23:00 Gmt and start them on Monday at 07:00 GMT +* [Spot scheduler](https://github.com/diodonfrost/terraform-aws-lambda-scheduler-stop-start/tree/master/examples/spot-schedule) - Create lambda functions to stop spot instance with tag `tostop = true` on Friday at 23:00 Gmt +* [EC2 scheduler](https://github.com/diodonfrost/terraform-aws-lambda-scheduler-stop-start/tree/master/examples/ec2-schedule) - Create lambda functions to stop ec2 with tag `tostop = true` on Friday at 23:00 Gmt and start them on Monday at 07:00 GMT +* [Rds aurora - mariadb scheduler](https://github.com/diodonfrost/terraform-aws-lambda-scheduler-stop-start/tree/master/examples/rds-schedule) - Create lambda functions to stop rds mariadb and aurora cluster with tag `tostop = true` on Friday at 23:00 Gmt and start them on Monday at 07:00 GMT * [test fixture](https://github.com/diodonfrost/terraform-aws-lambda-scheduler-stop-start/tree/master/examples/test_fixture) - Deploy environment for testing module @@ -47,9 +54,10 @@ module "stop_ec2_instance" { | cloudwatch_schedule_expression | The scheduling expression | string | `"cron(0 22 ? * MON-FRI *)"` | yes | | schedule_action | Define schedule action to apply on resources | string | `"stop"` | yes | | resources_tag | Set the tag use for identify resources to stop or start | map | { tostop = "true" } | yes | -| ec2_schedule | Enable scheduling on ec2 resources | string | `"false"` | no | -| rds_schedule | Enable scheduling on rds resources | string | `"false"` | no | | autoscaling_schedule | Enable scheduling on autoscaling resources | string | `"false"` | no | +| spot_schedule | Enable scheduling on spot instance resources | string | `"false"` | no | +| ec2_schedule | Enable scheduling on ec2 instance resources | string | `"false"` | no | +| rds_schedule | Enable scheduling on rds resources | string | `"false"` | no | ## Outputs diff --git a/examples/autoscaling-schedule/main.tf b/examples/autoscaling-schedule/main.tf index 61ec4223..ff045fc3 100644 --- a/examples/autoscaling-schedule/main.tf +++ b/examples/autoscaling-schedule/main.tf @@ -74,7 +74,7 @@ resource "aws_autoscaling_group" "not_scheduled" { ### Terraform modules ### module "autoscaling-stop-friday" { - source = "diodonfrost/lambda-scheduler-stop-start/aws" + source = "../../" name = "stop-autoscaling" cloudwatch_schedule_expression = "cron(0 23 ? * FRI *)" schedule_action = "stop" @@ -89,10 +89,11 @@ module "autoscaling-stop-friday" { } module "autoscaling-start-monday" { - source = "diodonfrost/lambda-scheduler-stop-start/aws" + source = "../../" name = "start-autoscaling" cloudwatch_schedule_expression = "cron(0 07 ? * MON *)" schedule_action = "start" + spot_schedule = "false" ec2_schedule = "false" rds_schedule = "false" autoscaling_schedule = "true" diff --git a/examples/ec2-schedule/main.tf b/examples/ec2-schedule/main.tf index d21c547c..31994089 100644 --- a/examples/ec2-schedule/main.tf +++ b/examples/ec2-schedule/main.tf @@ -22,7 +22,11 @@ resource "aws_instance" "scheduled" { instance_type = "t2.micro" tags = { - tostop = "true" + Name = "shceduled" + tostop = "true" + team = "flarf" + lint = "yes" + provider = "terraform" } } @@ -39,10 +43,11 @@ resource "aws_instance" "not_scheduled" { ### Terraform modules ### module "ec2-stop-friday" { - source = "diodonfrost/lambda-scheduler-stop-start/aws" + source = "../../" name = "stop-ec2" cloudwatch_schedule_expression = "cron(0 23 ? * FRI *)" schedule_action = "stop" + spot_schedule = "false" ec2_schedule = "true" rds_schedule = "false" autoscaling_schedule = "false" @@ -54,10 +59,11 @@ module "ec2-stop-friday" { } module "ec2-start-monday" { - source = "diodonfrost/lambda-scheduler-stop-start/aws" + source = "../../" name = "start-ec2" cloudwatch_schedule_expression = "cron(0 07 ? * MON *)" schedule_action = "start" + spot_schedule = "false" ec2_schedule = "true" rds_schedule = "false" autoscaling_schedule = "false" diff --git a/examples/rds-schedule/main.tf b/examples/rds-schedule/main.tf index de6d517e..b5ff3690 100644 --- a/examples/rds-schedule/main.tf +++ b/examples/rds-schedule/main.tf @@ -86,10 +86,11 @@ resource "aws_db_instance" "mysql_not_scheduled" { ### Terraform modules ### module "rds-stop-friday" { - source = "diodonfrost/lambda-scheduler-stop-start/aws" + source = "../../" name = "stop-rds" cloudwatch_schedule_expression = "cron(0 23 ? * FRI *)" schedule_action = "stop" + spot_schedule = "false" ec2_schedule = "false" rds_schedule = "true" autoscaling_schedule = "false" @@ -101,10 +102,11 @@ module "rds-stop-friday" { } module "rds-start-monday" { - source = "diodonfrost/lambda-scheduler-stop-start/aws" + source = "../../" name = "start-rds" cloudwatch_schedule_expression = "cron(0 07 ? * MON *)" schedule_action = "start" + spot_schedule = "false" ec2_schedule = "false" rds_schedule = "true" autoscaling_schedule = "false" diff --git a/examples/spot-schedule/main.tf b/examples/spot-schedule/main.tf new file mode 100644 index 00000000..b7095e09 --- /dev/null +++ b/examples/spot-schedule/main.tf @@ -0,0 +1,127 @@ +# Terraform spot instance with lambda scheduler + +data "aws_ami" "ubuntu" { + most_recent = true + + filter { + name = "name" + values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } + + owners = ["099720109477"] # Canonical +} + +# Create vpc use by asg +resource "aws_vpc" "main" { + cidr_block = "10.0.0.0/16" +} + +# Create subnet use bt asg +resource "aws_subnet" "main" { + vpc_id = "${aws_vpc.main.id}" + cidr_block = "10.0.1.0/24" +} + +# Run spot instances that will be scheduled +resource "aws_launch_template" "scheduled" { + name_prefix = "spot-scheduled" + image_id = "${data.aws_ami.ubuntu.id}" + instance_type = "t2.micro" +} + +resource "aws_autoscaling_group" "scheduled" { + desired_capacity = 3 + max_size = 3 + min_size = 3 + vpc_zone_identifier = ["${aws_subnet.main.id}"] + + mixed_instances_policy { + instances_distribution { + on_demand_percentage_above_base_capacity = "0" + } + + launch_template { + launch_template_specification { + launch_template_id = "${aws_launch_template.scheduled.id}" + } + + override { + instance_type = "t2.micro" + } + + override { + instance_type = "t2.nano" + } + } + } + + tag { + key = "tostop" + value = "true" + propagate_at_launch = true + } +} + +# Run spot instances that will be not scheduled +resource "aws_launch_template" "not_scheduled" { + name_prefix = "spot-not_scheduled" + image_id = "${data.aws_ami.ubuntu.id}" + instance_type = "t2.micro" +} + +resource "aws_autoscaling_group" "not_scheduled" { + desired_capacity = 2 + max_size = 2 + min_size = 2 + vpc_zone_identifier = ["${aws_subnet.main.id}"] + + mixed_instances_policy { + instances_distribution { + on_demand_percentage_above_base_capacity = "0" + } + + launch_template { + launch_template_specification { + launch_template_id = "${aws_launch_template.scheduled.id}" + } + + override { + instance_type = "t2.micro" + } + + override { + instance_type = "t2.nano" + } + } + } + + tag { + key = "tostop" + value = "false" + propagate_at_launch = true + } +} + + +### Terraform module ## + +module "spot-terminate-friday" { + source = "../../" + name = "terminate-spot" + cloudwatch_schedule_expression = "cron(0 23 ? * FRI *)" + schedule_action = "stop" + spot_schedule = "terminate" + ec2_schedule = "false" + rds_schedule = "false" + autoscaling_schedule = "false" + + resources_tag = { + key = "tostop" + value = "true" + } +} diff --git a/examples/spot-schedule/outputs.tf b/examples/spot-schedule/outputs.tf new file mode 100644 index 00000000..80bc09ce --- /dev/null +++ b/examples/spot-schedule/outputs.tf @@ -0,0 +1,9 @@ +# Terraform ex2-schedule outputs + +output "lambda_stop_name" { + value = "${module.spot-terminate-friday.scheduler_lambda_name}" +} + +output "lambda_stop_arn" { + value = "${module.spot-terminate-friday.scheduler_lambda_arn}" +} diff --git a/examples/test_fixture/main.tf b/examples/test_fixture/main.tf index cde86cff..a85946d1 100644 --- a/examples/test_fixture/main.tf +++ b/examples/test_fixture/main.tf @@ -5,9 +5,10 @@ module "aws-stop-friday" { name = "stop-aws" cloudwatch_schedule_expression = "cron(0 23 ? * FRI *)" schedule_action = "stop" + autoscaling_schedule = "true" + spot_schedule = "terminate" ec2_schedule = "true" rds_schedule = "true" - autoscaling_schedule = "true" resources_tag = { key = "tostop" @@ -20,9 +21,10 @@ module "aws-start-monday" { name = "start-aws" cloudwatch_schedule_expression = "cron(0 07 ? * MON *)" schedule_action = "start" + autoscaling_schedule = "true" + spot_schedule = "false" ec2_schedule = "true" rds_schedule = "true" - autoscaling_schedule = "true" resources_tag = { key = "tostop" diff --git a/main.tf b/main.tf index 7007480e..87985654 100644 --- a/main.tf +++ b/main.tf @@ -63,6 +63,27 @@ EOF } # Create custom policy for manage ec2 +resource "aws_iam_role_policy" "schedule_spot" { + name = "${var.name}-spot-custom-policy-scheduler" + role = "${aws_iam_role.scheduler_lambda.id}" + + policy = <