/** * # ec2-instance-scheduler-sfn * * This module start or stop ec2 instances using step function. * Schedules are made with Event Scheduler */ resource "random_id" "rid" { byte_length = 3 } module "StepFunctionRole" { source = "../../../whk1-bea-sys-ss-dev-codecommit-sharedmodules/SecurityIdentityCompliance/iam-role-v2" role-name = "InstanceStartStopScheduler-StepFunction-${random_id.rid.dec}" description = "Step function role for starting or stopping ec2 instances" trusted-entity = "states.amazonaws.com" policies = { "InstanceStartStop0-${random_id.rid.dec}" = { description = "Allow starting or stopping of ec2 instances and logging" policy = jsonencode( { Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "ec2:StartInstances", "ec2:StopInstances", "ec2:DescribeInstances" ] Resource = "arn:aws:ec2:*:*:instance/*" }, { Effect = "Allow", Action = [ "logs:CreateLogDelivery", "logs:CreateLogStream", "logs:GetLogDelivery", "logs:UpdateLogDelivery", "logs:ListLogDeliveries", "logs:PutLogEvents", "logs:PutResourcePolicy", "logs:DescribeResourcePolicies", "logs:DescribeLogGroups" ] "Resource" : "*" } ] } ) } } } module "EventSchedulerRole" { source = "../../../whk1-bea-sys-ss-dev-codecommit-sharedmodules/SecurityIdentityCompliance/iam-role-v2" role-name = "InstanceStartStopScheduler-EventScheduler-${random_id.rid.dec}" description = "Event scheduler role for invoking step function" trusted-entity = "scheduler.amazonaws.com" policies = { ExecuteStepFunction = { description = "Allow execution of step function" policy = jsonencode( { Version = "2012-10-17" Statement = [{ Action = "states:StartExecution" Effect = "Allow" Resource = aws_sfn_state_machine.Ec2Scheduler.arn }] } ) } } } resource "aws_cloudwatch_log_group" "Ec2Scheduler" { name = "/aws/sfn/Ec2InstanceScheduler-${random_id.rid.dec}" retention_in_days = var.cloudwatchlog-retention kms_key_id = var.kms-key-id } resource "aws_sfn_state_machine" "Ec2Scheduler" { name = "Ec2InstanceScheduler-${random_id.rid.dec}" role_arn = module.StepFunctionRole.role-arn type = "STANDARD" logging_configuration { log_destination = "${aws_cloudwatch_log_group.Ec2Scheduler.arn}:*" include_execution_data = true level = "ALL" } definition = jsonencode({ "StartAt" : "DetermineAction", "States" : { "DetermineAction" : { "Type" : "Choice", "Choices" : [ { "Variable" : "$.action", "StringEquals" : "START", "Next" : "StartEC2Instances" }, { "Variable" : "$.action", "StringEquals" : "STOP", "Next" : "StopEC2Instances" } ], "Default" : "InvalidAction" }, "StartEC2Instances" : { "Type" : "Task", "Resource" : "arn:aws:states:::aws-sdk:ec2:startInstances", "Parameters" : { "InstanceIds.$" : "$.instanceIds" }, "End" : true }, "StopEC2Instances" : { "Type" : "Task", "Resource" : "arn:aws:states:::aws-sdk:ec2:stopInstances", "Parameters" : { "InstanceIds.$" : "$.instanceIds" }, "End" : true }, "InvalidAction" : { "Type" : "Fail", "Error" : "ActionError", "Cause" : "The action provided must be either START or STOP." } } }) } resource "aws_scheduler_schedule" "StartInstances" { name = "start-ec2-${random_id.rid.dec}" group_name = "default" description = "Start ec2 instances" flexible_time_window { mode = "OFF" } schedule_expression = var.instance-start-cron-expression schedule_expression_timezone = var.scheduler-timezone target { arn = aws_sfn_state_machine.Ec2Scheduler.arn role_arn = module.EventSchedulerRole.role-arn input = jsonencode({ action = "START" instanceIds = var.instance-ids }) retry_policy { maximum_retry_attempts = 0 } } } resource "aws_scheduler_schedule" "StopInstances" { name = "stop-ec2-${random_id.rid.dec}" group_name = "default" description = "Stop ec2 instances" flexible_time_window { mode = "OFF" } schedule_expression = var.instance-stop-cron-expression schedule_expression_timezone = var.scheduler-timezone target { arn = aws_sfn_state_machine.Ec2Scheduler.arn role_arn = module.EventSchedulerRole.role-arn input = jsonencode({ action = "STOP" instanceIds = var.instance-ids }) retry_policy { maximum_retry_attempts = 0 } } }