Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add time zone support for pool schedules #4063

Merged
merged 6 commits into from
Aug 16, 2024
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
5 changes: 3 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ The pool is introduced in combination with the ephemeral runners and is primaril
```hcl
pool_runner_owner = "my-org" # Org to which the runners are added
pool_config = [{
size = 20 # size of the pool
schedule_expression = "cron(* * * * ? *)" # cron expression to trigger the adjustment of the pool
size = 20 # size of the pool
schedule_expression = "cron(* * * * ? *)" # cron expression to trigger the adjustment of the pool
schedule_expression_timezone = "Australia/Sydney" # optional time zone (defaults to UTC)
}]
```

Expand Down
6 changes: 4 additions & 2 deletions examples/ephemeral/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,10 @@ module "runners" {
# # Example of simple pool usages
# pool_runner_owner = "philips-test-runners"
# pool_config = [{
# size = 3
# schedule_expression = "cron(* * * * ? *)"
# size = 3
# schedule_expression = "cron(0/3 14 * * ? *)" # every 3 minutes between 14:00 and 15:00
# schedule_expression_timezone = "Europe/Amsterdam"

# }]
#
#
Expand Down
7 changes: 4 additions & 3 deletions modules/multi-runner/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ variable "multi_runner_config" {
volume_size = 30
}])
pool_config = optional(list(object({
schedule_expression = string
size = number
schedule_expression = string
schedule_expression_timezone = optional(string)
size = number
})), [])
})

Expand Down Expand Up @@ -177,7 +178,7 @@ variable "multi_runner_config" {
idle_config: "List of time period that can be defined as cron expression to keep a minimum amount of runners active instead of scaling down to 0. By defining this list you can ensure that in time periods that match the cron expression within 5 seconds a runner is kept idle."
runner_log_files: "(optional) Replaces the module default cloudwatch log config. See https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Agent-Configuration-File-Details.html for details."
block_device_mappings: "The EC2 instance block device configuration. Takes the following keys: `device_name`, `delete_on_termination`, `volume_type`, `volume_size`, `encrypted`, `iops`, `throughput`, `kms_key_id`, `snapshot_id`."
pool_config: "The configuration for updating the pool. The `pool_size` to adjust to by the events triggered by the `schedule_expression`. For example you can configure a cron expression for week days to adjust the pool to 10 and another expression for the weekend to adjust the pool to 1."
pool_config: "The configuration for updating the pool. The `pool_size` to adjust to by the events triggered by the `schedule_expression`. For example you can configure a cron expression for week days to adjust the pool to 10 and another expression for the weekend to adjust the pool to 1. Use `schedule_expression_timezone` to override the schedule time zone (defaults to UTC)."
}
matcherConfig: {
labelMatchers: "The list of list of labels supported by the runner configuration. `[[self-hosted, linux, x64, example]]`"
Expand Down
99 changes: 69 additions & 30 deletions modules/runners/pool/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -118,36 +118,6 @@ data "aws_iam_policy_document" "lambda_assume_role_policy" {
}
}

# per config object one trigger is created to trigger the lambda.
resource "aws_cloudwatch_event_rule" "pool" {
count = length(var.config.pool)

name = "${var.config.prefix}-pool-${count.index}-rule"
schedule_expression = var.config.pool[count.index].schedule_expression
tags = var.config.tags
}

resource "aws_cloudwatch_event_target" "pool" {
count = length(var.config.pool)

input = jsonencode({
poolSize = var.config.pool[count.index].size
})

rule = aws_cloudwatch_event_rule.pool[count.index].name
arn = aws_lambda_function.pool.arn
}

resource "aws_lambda_permission" "pool" {
count = length(var.config.pool)

statement_id = "AllowExecutionFromCloudWatch-${count.index}"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.pool.function_name
principal = "events.amazonaws.com"
source_arn = aws_cloudwatch_event_rule.pool[count.index].arn
}

resource "aws_iam_role_policy_attachment" "ami_id_ssm_parameter_read" {
count = var.config.ami_id_ssm_parameter_name != null ? 1 : 0
role = aws_iam_role.pool.name
Expand Down Expand Up @@ -178,3 +148,72 @@ resource "aws_iam_role_policy" "pool_xray" {
policy = data.aws_iam_policy_document.lambda_xray[0].json
role = aws_iam_role.pool.name
}

resource "aws_scheduler_schedule_group" "pool" {
name_prefix = "${var.config.prefix}-pool"

tags = var.config.tags
}

data "aws_iam_policy_document" "scheduler_assume" {
statement {
sid = "ScheduleGroupAssumeRole"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["scheduler.amazonaws.com"]
}

condition {
test = "StringEquals"
variable = "aws:SourceArn"
values = [aws_scheduler_schedule_group.pool.arn]
}
}
}

data "aws_iam_policy_document" "scheduler" {
statement {
sid = "InvokePoolLambda"
actions = ["lambda:InvokeFunction"]
resources = [aws_lambda_function.pool.arn]
}
}

resource "aws_iam_role" "scheduler" {
name_prefix = "${var.config.prefix}-pool"

path = var.config.role_path
permissions_boundary = var.config.role_permissions_boundary

assume_role_policy = data.aws_iam_policy_document.scheduler_assume.json

inline_policy {
name = "terraform"
policy = data.aws_iam_policy_document.scheduler.json
}

tags = var.config.tags
}

resource "aws_scheduler_schedule" "pool" {
for_each = { for i, v in var.config.pool : i => v }

name_prefix = "${var.config.prefix}-pool-${each.key}-rule"
group_name = aws_scheduler_schedule_group.pool.name

flexible_time_window {
mode = "OFF"
}

schedule_expression = each.value.schedule_expression
schedule_expression_timezone = each.value.schedule_expression_timezone

target {
arn = aws_lambda_function.pool.arn
role_arn = aws_iam_role.scheduler.arn
input = jsonencode({
poolSize = each.value.size
})
}
}
5 changes: 3 additions & 2 deletions modules/runners/pool/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,9 @@ variable "config" {
instance_max_spot_price = string
prefix = string
pool = list(object({
schedule_expression = string
size = number
schedule_expression = string
schedule_expression_timezone = string
size = number
}))
role_permissions_boundary = string
kms_key_arn = string
Expand Down
7 changes: 4 additions & 3 deletions modules/runners/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -538,10 +538,11 @@ variable "pool_lambda_reserved_concurrent_executions" {
}

variable "pool_config" {
description = "The configuration for updating the pool. The `pool_size` to adjust to by the events triggered by the `schedule_expression`. For example you can configure a cron expression for week days to adjust the pool to 10 and another expression for the weekend to adjust the pool to 1."
description = "The configuration for updating the pool. The `pool_size` to adjust to by the events triggered by the `schedule_expression`. For example you can configure a cron expression for week days to adjust the pool to 10 and another expression for the weekend to adjust the pool to 1. Use `schedule_expression_timezone ` to override the schedule time zone (defaults to UTC)."
type = list(object({
schedule_expression = string
size = number
schedule_expression = string
schedule_expression_timezone = optional(string)
size = number
}))
default = []
}
Expand Down
7 changes: 4 additions & 3 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -686,10 +686,11 @@ variable "pool_lambda_reserved_concurrent_executions" {
}

variable "pool_config" {
description = "The configuration for updating the pool. The `pool_size` to adjust to by the events triggered by the `schedule_expression`. For example you can configure a cron expression for weekdays to adjust the pool to 10 and another expression for the weekend to adjust the pool to 1."
description = "The configuration for updating the pool. The `pool_size` to adjust to by the events triggered by the `schedule_expression`. For example you can configure a cron expression for weekdays to adjust the pool to 10 and another expression for the weekend to adjust the pool to 1. Use `schedule_expression_timezone` to override the schedule time zone (defaults to UTC)."
type = list(object({
schedule_expression = string
size = number
schedule_expression = string
schedule_expression_timezone = optional(string)
size = number
}))
default = []
}
Expand Down