Skip to content

Commit a00fcdb

Browse files
authored
Merge pull request #21 from byu-oit/rc-4.0.0
feat!: Release 4.0.0 scheduler support, and better existing_ecs_cluster support
2 parents 4458b14 + b4b94a3 commit a00fcdb

File tree

12 files changed

+547
-189
lines changed

12 files changed

+547
-189
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ jobs:
2222

2323
- name: Terraform Format
2424
working-directory: "./"
25-
run: terraform fmt -check -recursive
25+
run: terraform fmt -check -recursive -diff
2626

2727
plan:
2828
name: Terraform Plan
2929
runs-on: ubuntu-latest
3030
strategy:
3131
matrix:
32-
terraform: [ '1.3.x' ]
32+
terraform: [ '1.3.x', '1.4.x', '1.5.x' ]
3333
fail-fast: false
3434
permissions:
3535
contents: read

README.md

Lines changed: 112 additions & 59 deletions
Large diffs are not rendered by default.

docs/adr-template.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# [short title of solved problem and solution]
2+
3+
* Status: [proposed | rejected | accepted | deprecated | … | superseded by [ADR-0005](0005-example.md)] <!-- optional -->
4+
* Deciders: [list everyone involved in the decision] <!-- optional -->
5+
* Date: [YYYY-MM-DD when the decision was last updated] <!-- optional -->
6+
7+
Technical Story: [description | ticket/issue URL] <!-- optional -->
8+
9+
## Context and Problem Statement
10+
11+
[Describe the context and problem statement, e.g., in free form using two to three sentences. You may want to articulate the problem in form of a question.]
12+
13+
## Decision Drivers <!-- optional -->
14+
15+
* [driver 1, e.g., a force, facing concern, …]
16+
* [driver 2, e.g., a force, facing concern, …]
17+
*<!-- numbers of drivers can vary -->
18+
19+
## Considered Options
20+
21+
* [option 1]
22+
* [option 2]
23+
* [option 3]
24+
*<!-- numbers of options can vary -->
25+
26+
## Decision Outcome
27+
28+
Chosen option: "[option 1]", because [justification. e.g., only option, which meets k.o. criterion decision driver | which resolves force force | … | comes out best (see below)].
29+
30+
### Positive Consequences <!-- optional -->
31+
32+
* [e.g., improvement of quality attribute satisfaction, follow-up decisions required, …]
33+
*
34+
35+
### Negative Consequences <!-- optional -->
36+
37+
* [e.g., compromising quality attribute, follow-up decisions required, …]
38+
*
39+
40+
## Pros and Cons of the Options <!-- optional -->
41+
42+
### [option 1]
43+
44+
[example | description | pointer to more information | …] <!-- optional -->
45+
46+
* Good, because [argument a]
47+
* Good, because [argument b]
48+
* Bad, because [argument c]
49+
*<!-- numbers of pros and cons can vary -->
50+
51+
### [option 2]
52+
53+
[example | description | pointer to more information | …] <!-- optional -->
54+
55+
* Good, because [argument a]
56+
* Good, because [argument b]
57+
* Bad, because [argument c]
58+
*<!-- numbers of pros and cons can vary -->
59+
60+
### [option 3]
61+
62+
[example | description | pointer to more information | …] <!-- optional -->
63+
64+
* Good, because [argument a]
65+
* Good, because [argument b]
66+
* Bad, because [argument c]
67+
*<!-- numbers of pros and cons can vary -->
68+
69+
## Links <!-- optional -->
70+
71+
* [Link type] [Link to ADR] <!-- example: Refined by [ADR-0005](0005-example.md) -->
72+
*<!-- numbers of links can vary -->

docs/adr/000-use-scheduler.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Use EventBridge Scheduler to Trigger Scheduled Fargate Tasks
2+
3+
* Status: accepted
4+
* Deciders:
5+
* Jamie Visker
6+
* Josh Gubler
7+
* Scott Hutchings
8+
* Spencer Visker
9+
* Date: 2023-09-26
10+
11+
## Context and Problem Statement
12+
13+
We used CloudWatch Event Rules and Targets to trigger scheduled Fargate tasks.
14+
AWS has a newer service called [EventBridge Scheduler](https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduler.html).
15+
Do we start using the Scheduler to take advantage of those newer features?
16+
17+
## Decision Drivers <!-- optional -->
18+
19+
* Would be nice if our tasks could support time zone scheduled jobs
20+
* Needs to be easy to use
21+
22+
## Considered Options
23+
24+
* Keep using Event Rules and Targets
25+
* Use EventBridge Scheduler (keep event trigger functionality)
26+
* Use EventBridge Scheduler (move event trigger functionality to new module)
27+
* Use EventBridge Scheduler and refactor fargate modules
28+
29+
## Decision Outcome
30+
31+
Chosen option: "Use EventBridge Scheduler (keep event trigger functionality)", because it'll give us the best of both worlds with using the new Scheduler and still supporting events.
32+
33+
### Positive Consequences <!-- optional -->
34+
35+
* We were able to implement in such a way that a fargate task can be both scheduled and triggered by an event with the same module.
36+
37+
### Negative Consequences <!-- optional -->
38+
39+
* Using the Scheduler removes the fargate task from the "Scheduled tasks" portion of the ECS cluster on the AWS console.
40+
41+
## Pros and Cons of the Options <!-- optional -->
42+
43+
### Keep using Event Rules and Targets
44+
45+
* Good, because there'll be no change to our module
46+
* Good, because it still works
47+
* Bad, because we can't take advantage of the EventBridge Scheduler features (time zone, start-end dates, retries etc.)
48+
49+
### Use EventBridge Scheduler (keep event trigger functionality)
50+
51+
* Good, because we can take advantage of the EventBridge Scheduler features (time zone, start-end dates, retries etc.)
52+
* Good, because we can still support tasks triggered by tasks
53+
* Bad, because the module will be more complex (it will include resources for both EventBridge Scheduler, and CloudWatch Rules and Targets)
54+
* Bad, because using the Scheduler removes the task from the list of "Scheduled Tasks" in the ECS cluster
55+
56+
### Use EventBridge Scheduler (move event trigger functionality to new module)
57+
58+
* Good, because we can take advantage of the EventBridge Scheduler features (time zone, start-end dates, retries etc.)
59+
* Good, because this module will be simplified
60+
* Bad, because in order to support tasks triggered by tasks we'll need to create a new module (with lots of copy/paste terraform configuration)
61+
* Bad, because using the Scheduler removes the task from the list of "Scheduled Tasks" in the ECS cluster
62+
63+
### Use EventBridge Scheduler and refactor fargate modules
64+
65+
We can refactor the fargate-api, and scheduled-fargate modules into smaller pieces that work together in order to reduce duplicate terraform code.
66+
Maybe something like:
67+
* `fargate-definition` module that sets up the fargate task definition, ECS cluster, SGs, related IAM roles etc.
68+
* `fargate-service` module that takes task definition and cluster inputs from 'fargate-defintion' module, and creates an ECS service with ALB, CodeDeploy, related IAM roles etc.
69+
* `fargate-scheduled` module that takes task definition and cluster inputs from 'fargate-defintion' module, and creates Scheduler that runs the task on the schedule, related IAM roles etc.
70+
* `fargate-event` module that takes task definition and cluster inputs from 'fargate-defintion' module, and creates CloudWatch Event to trigger task, Rule(s), Target(s), and related IAM roles etc.
71+
72+
* Good, because we can reduce duplicate terraform
73+
* Good, because our modules can be smaller and simpler, thus easier to maintain
74+
* Bad, because it completely breaks our exising terraform module contract, so upgrades will be more difficult
75+
* Bad, because it makes our apps a little more complex having to use interconnected modules instead of just one. It borders on not needing modules in the first place if our apps have to know how everything integrates.
76+
* Bad, because using the Scheduler removes the task from the list of "Scheduled Tasks" in the ECS cluster
77+
78+
## Links <!-- optional -->
79+
80+
* [EventBridge Scheduler](https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduler.html)

docs/migration-to-v4.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Migration to v4
2+
V4 has a significant amount of breaking changes from v3 and earlier:
3+
4+
* How we use an existing ECS cluster allowing the creating of a cluster alongside using it as an existing cluster in the same terraform configuration.
5+
* This module now uses the [EventBridge Scheduler](https://docs.aws.amazon.com/eventbridge/latest/userguide/scheduler.html) instead of CloudWatch EventBridge Rules.
6+
7+
## For scheduled tasks
8+
1. Change `schedule_expression` variable to be inside the `expression` block
9+
2. Remove `event_role_arn`
10+
3. Change `ecs_cluster` output to `new_ecs_cluster` output if you're using it
11+
> **Note:** that the `new_ecs_cluster` will only be populated if you let the module create the cluster, if you provide your own existing cluster this output will be `null`
12+
13+
```diff
14+
module "scheduled_fargate" {
15+
- source = "github.com/byu-oit/terraform-aws-scheduled-fargate?ref=v3.0.1"
16+
source = "github.com/byu-oit/terraform-aws-scheduled-fargate?ref=v4.0.0"
17+
app_name = "test-scheduled-fargate-dev"
18+
- schedule_expression = "rate(5 minutes)"
19+
+ schedule = {
20+
+ expression = "rate(5 minutes)"
21+
+ }
22+
primary_container_definition = {
23+
# ...
24+
}
25+
- event_role_arn = module.acs.power_builder_role.arn
26+
vpc_id = module.acs.vpc.id
27+
private_subnet_ids = module.acs.private_subnet_ids
28+
role_permissions_boundary_arn = module.acs.role_permissions_boundary.arn
29+
}
30+
```
31+
32+
## For event triggered tasks
33+
1. Change the `event_pattern` variable to be inside the `event` block
34+
2. Remove `event_role_arn`
35+
3. Change `ecs_cluster` output to `new_ecs_cluster` output if you're using it
36+
> **Note:** that the `new_ecs_cluster` will only be populated if you let the module create the cluster, if you provide your own existing cluster this output will be `null`
37+
38+
```diff
39+
module "scheduled_fargate" {
40+
- source = "github.com/byu-oit/terraform-aws-scheduled-fargate?ref=v3.0.1"
41+
+ source = "github.com/byu-oit/terraform-aws-scheduled-fargate?ref=v4.0.0"
42+
app_name = "event-triggered-fargate-example-dev"
43+
- event_pattern = <<EOF
44+
+ event = {
45+
+ pattern = <<EOF
46+
{
47+
"source": ["aws.s3"],
48+
"detail-type": ["Object Created"],
49+
"detail": {
50+
"bucket": {
51+
"name": ["${aws_s3_bucket.test_bucket.bucket}"]
52+
}
53+
}
54+
}
55+
EOF
56+
+ }
57+
primary_container_definition = {
58+
# ...
59+
}
60+
- event_role_arn = module.acs.power_builder_role.arn
61+
vpc_id = module.acs.vpc.id
62+
private_subnet_ids = module.acs.private_subnet_ids
63+
role_permissions_boundary_arn = module.acs.role_permissions_boundary.arn
64+
}
65+
```
66+
67+
View the release notes for more detailed changes

examples/ci/ci.tf

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ terraform {
44
required_providers {
55
aws = {
66
source = "hashicorp/aws"
7-
version = "~> 3.69"
7+
version = "~> 4.0"
88
}
99
}
1010
}
@@ -14,19 +14,20 @@ provider "aws" {
1414
}
1515

1616
module "acs" {
17-
source = "github.com/byu-oit/terraform-aws-acs-info?ref=v3.5.0"
17+
source = "github.com/byu-oit/terraform-aws-acs-info?ref=v4.0.0"
1818
}
1919

2020
module "scheduled_fargate" {
21-
source = "../../"
22-
23-
app_name = "test-scheduled-fargate-dev"
24-
schedule_expression = "rate(5 minutes)"
21+
# source = "github.com/byu-oit/terraform-aws-scheduled-fargate?ref=v4.0.0"
22+
source = "../../"
23+
app_name = "test-scheduled-fargate-dev"
24+
schedule = {
25+
expression = "rate(5 minutes)"
26+
}
2527
primary_container_definition = {
2628
name = "test"
2729
image = "hello-world"
2830
}
29-
event_role_arn = module.acs.power_builder_role.arn
3031
vpc_id = module.acs.vpc.id
3132
private_subnet_ids = module.acs.private_subnet_ids
3233
role_permissions_boundary_arn = module.acs.role_permissions_boundary.arn
@@ -36,9 +37,8 @@ module "scheduled_fargate" {
3637
}
3738
}
3839

39-
40-
output "scheduled_fargate_ecs_cluster" {
41-
value = module.scheduled_fargate.ecs_cluster
40+
output "scheduled_fargate_new_ecs_cluster" {
41+
value = module.scheduled_fargate.new_ecs_cluster
4242
}
4343

4444
output "scheduled_fargate_security_group" {
@@ -49,12 +49,8 @@ output "scheduled_task_definition" {
4949
value = module.scheduled_fargate.task_definition
5050
}
5151

52-
output "scheduled_event_rule" {
53-
value = module.scheduled_fargate.event_rule
54-
}
55-
56-
output "scheduled_event_target" {
57-
value = module.scheduled_fargate.event_target
52+
output "schedule" {
53+
value = module.scheduled_fargate.schedule
5854
sensitive = true
5955
}
6056

@@ -71,3 +67,8 @@ output "task_role" {
7167
value = module.scheduled_fargate.task_role
7268
sensitive = true
7369
}
70+
71+
output "run_task_cli_command" {
72+
value = module.scheduled_fargate.run_task_cli_command
73+
sensitive = true
74+
}

examples/complex/complex-example.tf

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ terraform {
44
required_providers {
55
aws = {
66
source = "hashicorp/aws"
7-
version = "~> 3.69"
7+
version = "~> 4.0"
88
}
99
}
1010
}
1111

12+
provider "aws" {
13+
region = "us-west-2"
14+
}
15+
16+
1217
module "acs" {
13-
source = "github.com/byu-oit/terraform-aws-acs-info?ref=v3.5.0"
18+
source = "github.com/byu-oit/terraform-aws-acs-info?ref=v4.0.0"
1419
}
1520

1621
variable "env" {
@@ -31,6 +36,9 @@ locals {
3136
}
3237
}
3338

39+
resource "aws_ecs_cluster" "existing" {
40+
name = "test-existing-cluster"
41+
}
3442
resource "aws_ecr_repository" "repo" {
3543
name = "test-existing-ecr"
3644
}
@@ -39,12 +47,26 @@ output "repo_url" {
3947
value = aws_ecr_repository.repo.repository_url
4048
}
4149

50+
resource "aws_scheduler_schedule_group" "group" {
51+
name = "test"
52+
}
53+
4254
// Scheduled fargate
4355
module "scheduled_fargate" {
44-
source = "github.com/byu-oit/terraform-aws-scheduled-fargate?ref=v3.0.1"
45-
app_name = local.name
46-
ecs_cluster_name = aws_ecr_repository.repo.name
47-
schedule_expression = "rate(5 minutes)"
56+
# source = "github.com/byu-oit/terraform-aws-scheduled-fargate?ref=v4.0.0"
57+
source = "../../"
58+
app_name = local.name
59+
existing_ecs_cluster = {
60+
arn = aws_ecs_cluster.existing.arn
61+
}
62+
schedule = {
63+
expression = "rate(5 minutes)"
64+
timezone = "UTC"
65+
start_date = "2023-10-01T00:00:00.000Z"
66+
end_date = "2023-10-02T00:00:00.000Z"
67+
}
68+
69+
log_group_name = aws_scheduler_schedule_group.group.name
4870
primary_container_definition = {
4971
name = "test-dynamo"
5072
image = "${aws_ecr_repository.repo.repository_url}:${var.image_tag}"
@@ -61,7 +83,6 @@ module "scheduled_fargate" {
6183
]
6284
}
6385
task_policies = [aws_iam_policy.my_dynamo_policy.arn]
64-
event_role_arn = module.acs.power_builder_role.arn
6586
vpc_id = module.acs.vpc.id
6687
private_subnet_ids = module.acs.private_subnet_ids
6788
role_permissions_boundary_arn = module.acs.role_permissions_boundary.arn
@@ -127,7 +148,7 @@ resource "aws_security_group" "efs_sg" {
127148
}
128149

129150
resource "aws_efs_mount_target" "efs_target" {
130-
for_each = toset(module.acs.private_subnet_ids)
151+
for_each = nonsensitive(toset(module.acs.private_subnet_ids))
131152

132153
file_system_id = aws_efs_file_system.my_efs.id
133154
subnet_id = each.key

0 commit comments

Comments
 (0)