Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions terraform/environments/aws/compute.tf
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ module "compute_lambda" {
enable_ri_exchange_schedule = var.enable_ri_exchange_schedule
ri_exchange_schedule = var.ri_exchange_schedule

# Commitment-ladder scheduling (default-off until GA)
enable_ladder_run_schedule = var.enable_ladder_run_schedule
ladder_run_schedule = var.ladder_run_schedule
enable_fire_scheduled_purchases_schedule = var.enable_fire_scheduled_purchases_schedule
fire_scheduled_purchases_schedule = var.fire_scheduled_purchases_schedule

# Additional environment variables
additional_env_vars = merge(
{
Expand Down Expand Up @@ -187,6 +193,12 @@ module "compute_fargate" {
enable_ri_exchange_schedule = var.enable_ri_exchange_schedule
ri_exchange_schedule = var.ri_exchange_schedule

# Commitment-ladder scheduling (default-off until GA)
enable_ladder_run_schedule = var.enable_ladder_run_schedule
ladder_run_schedule = var.ladder_run_schedule
enable_fire_scheduled_purchases_schedule = var.enable_fire_scheduled_purchases_schedule
fire_scheduled_purchases_schedule = var.fire_scheduled_purchases_schedule

# ECS Exec for debugging
enable_execute_command = var.fargate_enable_execute_command

Expand Down
24 changes: 24 additions & 0 deletions terraform/environments/aws/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,30 @@ variable "ri_exchange_schedule" {
default = "rate(6 hours)"
}

variable "enable_ladder_run_schedule" {
description = "Enable the scheduled commitment-ladder planning run. Default false until laddering is promoted to GA."
type = bool
default = false
}

variable "ladder_run_schedule" {
description = "EventBridge schedule for the commitment-ladder planning run (e.g. rate(1 day) or cron(0 2 * * ? *) for 02:00 UTC)."
type = string
default = "rate(1 day)"
}

variable "enable_fire_scheduled_purchases_schedule" {
description = "Enable the scheduled fire_scheduled_purchases sweep. Default false until auto-approve (L9) is promoted to GA."
type = bool
default = false
}

variable "fire_scheduled_purchases_schedule" {
description = "EventBridge schedule for the fire_scheduled_purchases sweep (default rate(15 minutes))."
type = string
default = "rate(15 minutes)"
}

# ==============================================
# Multi-Account Configuration
# ==============================================
Expand Down
224 changes: 224 additions & 0 deletions terraform/modules/compute/aws/fargate/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -975,3 +975,227 @@ resource "aws_iam_role_policy" "eventbridge_ri_exchange" {
]
})
}

# ==============================================
# Scheduled Commitment-Ladder Planning Run
# ==============================================
#
# The "ladder_run" scheduled action is registered by the ladder_run task
# (PR #1362). This rule is default-off (count-gated on
# var.enable_ladder_run_schedule). Enabling it before that task ships, or on
# an incomplete deploy, causes a loud dispatch error (unknown scheduled task
# action) rather than a silent no-op.

resource "aws_cloudwatch_event_rule" "ladder_run" {
count = var.enable_ladder_run_schedule ? 1 : 0

name = "${local.name_prefix}-ladder-run"
description = "Trigger commitment-ladder planning run (ladder_run task)"
schedule_expression = var.ladder_run_schedule

tags = local.common_tags
}

resource "aws_cloudwatch_event_target" "ladder_run" {
count = var.enable_ladder_run_schedule ? 1 : 0

rule = aws_cloudwatch_event_rule.ladder_run[0].name
target_id = "ecs-task"
arn = aws_ecs_cluster.main.arn
role_arn = aws_iam_role.eventbridge_ladder_run[0].arn

ecs_target {
task_count = 1
task_definition_arn = aws_ecs_task_definition.main.arn
launch_type = "FARGATE"
platform_version = "LATEST"

network_configuration {
subnets = var.private_subnet_ids
security_groups = [aws_security_group.ecs_tasks.id]
assign_public_ip = false
}
}

retry_policy {
maximum_retry_attempts = 0
maximum_event_age_in_seconds = 3600
}

input = jsonencode({
containerOverrides = [{
name = "app"
command = ["./cudly", "--task", "ladder_run"]
}]
})
}

resource "aws_iam_role" "eventbridge_ladder_run" {
count = var.enable_ladder_run_schedule ? 1 : 0

name = "${local.name_prefix}-eb-ladder-run"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "events.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})

tags = local.common_tags
}

resource "aws_iam_role_policy" "eventbridge_ladder_run" {
count = var.enable_ladder_run_schedule ? 1 : 0

name = "ecs-run-task"
role = aws_iam_role.eventbridge_ladder_run[0].id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ecs:RunTask"
]
Resource = aws_ecs_task_definition.main.arn
Condition = {
ArnEquals = {
"ecs:cluster" = aws_ecs_cluster.main.arn
}
}
},
{
Effect = "Allow"
Action = [
"iam:PassRole"
]
Resource = [
aws_iam_role.task_execution.arn,
aws_iam_role.task.arn
]
Condition = {
StringEquals = {
"iam:PassedToService" = "ecs-tasks.amazonaws.com"
}
}
}
]
Comment thread
coderabbitai[bot] marked this conversation as resolved.
})
}

# ==============================================
# Scheduled Fire-Scheduled-Purchases Sweep
# ==============================================

resource "aws_cloudwatch_event_rule" "fire_scheduled_purchases" {
count = var.enable_fire_scheduled_purchases_schedule ? 1 : 0

name = "${local.name_prefix}-fire-scheduled-purchases"
description = "Trigger fire_scheduled_purchases sweep (auto-approve delayed execution)"
schedule_expression = var.fire_scheduled_purchases_schedule

tags = local.common_tags
}

resource "aws_cloudwatch_event_target" "fire_scheduled_purchases" {
count = var.enable_fire_scheduled_purchases_schedule ? 1 : 0

rule = aws_cloudwatch_event_rule.fire_scheduled_purchases[0].name
target_id = "ecs-task"
arn = aws_ecs_cluster.main.arn
role_arn = aws_iam_role.eventbridge_fire_scheduled_purchases[0].arn

ecs_target {
task_count = 1
task_definition_arn = aws_ecs_task_definition.main.arn
launch_type = "FARGATE"
platform_version = "LATEST"

network_configuration {
subnets = var.private_subnet_ids
security_groups = [aws_security_group.ecs_tasks.id]
assign_public_ip = false
}
}

retry_policy {
maximum_retry_attempts = 0
maximum_event_age_in_seconds = 3600
}

input = jsonencode({
containerOverrides = [{
name = "app"
command = ["./cudly", "--task", "fire_scheduled_purchases"]
}]
})
}

resource "aws_iam_role" "eventbridge_fire_scheduled_purchases" {
count = var.enable_fire_scheduled_purchases_schedule ? 1 : 0

name = "${local.name_prefix}-eb-fire-sched-purchases"

assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "events.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})

tags = local.common_tags
}

resource "aws_iam_role_policy" "eventbridge_fire_scheduled_purchases" {
count = var.enable_fire_scheduled_purchases_schedule ? 1 : 0

name = "ecs-run-task"
role = aws_iam_role.eventbridge_fire_scheduled_purchases[0].id

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ecs:RunTask"
]
Resource = aws_ecs_task_definition.main.arn
Condition = {
ArnEquals = {
"ecs:cluster" = aws_ecs_cluster.main.arn
}
}
},
{
Effect = "Allow"
Action = [
"iam:PassRole"
]
Resource = [
aws_iam_role.task_execution.arn,
aws_iam_role.task.arn
]
Condition = {
StringEquals = {
"iam:PassedToService" = "ecs-tasks.amazonaws.com"
}
}
}
]
})
}
24 changes: 24 additions & 0 deletions terraform/modules/compute/aws/fargate/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,30 @@ variable "ri_exchange_schedule" {
default = "rate(6 hours)"
}

variable "enable_ladder_run_schedule" {
description = "Enable the scheduled commitment-ladder planning run. Default false until laddering is promoted to GA."
type = bool
default = false
}

variable "ladder_run_schedule" {
description = "EventBridge schedule for the commitment-ladder planning run (e.g. rate(1 day) or cron(0 2 * * ? *) for 02:00 UTC)."
type = string
default = "rate(1 day)"
}

variable "enable_fire_scheduled_purchases_schedule" {
description = "Enable the scheduled fire_scheduled_purchases sweep. Default false until auto-approve (L9) is promoted to GA."
type = bool
default = false
}

variable "fire_scheduled_purchases_schedule" {
description = "EventBridge schedule for the fire_scheduled_purchases sweep (default rate(15 minutes))."
type = string
default = "rate(15 minutes)"
}

variable "task_timeout" {
description = "Timeout in seconds for one-off scheduled tasks"
type = number
Expand Down
Loading
Loading