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

IPS-1284: Predictive scaling for ECS in forecast mode #357

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
6 changes: 3 additions & 3 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
rev: v5.0.0
hooks:
- id: check-json
- id: end-of-file-fixer
Expand All @@ -10,13 +10,13 @@ repos:
- id: detect-private-key

- repo: https://github.com/awslabs/cfn-python-lint
rev: v1.15.2 # The version of cfn-lint to use
rev: v1.22.3 # The version of cfn-lint to use
hooks:
- id: cfn-python-lint
files: .template\.yaml$

- repo: https://github.com/bridgecrewio/checkov.git
rev: "3.2.256"
rev: "3.2.350"
hooks:
- id: checkov
verbose: true
Expand Down
31 changes: 21 additions & 10 deletions .secrets.baseline
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
{
"name": "GitHubTokenDetector"
},
{
"name": "GitLabTokenDetector"
},
{
"name": "HexHighEntropyString",
"limit": 3.0
Expand All @@ -36,6 +39,9 @@
{
"name": "IbmCosHmacDetector"
},
{
"name": "IPPublicDetector"
},
{
"name": "JwtTokenDetector"
},
Expand All @@ -49,9 +55,15 @@
{
"name": "NpmDetector"
},
{
"name": "OpenAIDetector"
},
{
"name": "PrivateKeyDetector"
},
{
"name": "PypiTokenDetector"
},
{
"name": "SendGridDetector"
},
Expand All @@ -67,6 +79,9 @@
{
"name": "StripeDetector"
},
{
"name": "TelegramBotTokenDetector"
},
{
"name": "TwilioKeyDetector"
}
Expand All @@ -75,10 +90,6 @@
{
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
},
{
"path": "detect_secrets.filters.common.is_baseline_file",
"filename": ".secrets.baseline"
},
{
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
"min_level": 2
Expand Down Expand Up @@ -281,37 +292,37 @@
"filename": "deploy/template.yaml",
"hashed_secret": "b811ac90fe7fab03f6144a17aaebc38dcf3e007b",
"is_verified": false,
"line_number": 72
"line_number": 69
},
{
"type": "Secret Keyword",
"filename": "deploy/template.yaml",
"hashed_secret": "690de9fd42add772818ae392cb68a4f81d1511e3",
"is_verified": false,
"line_number": 109
"line_number": 114
},
{
"type": "Secret Keyword",
"filename": "deploy/template.yaml",
"hashed_secret": "b63bf00edb07af6ffba7f7ceb7ed573a913271f7",
"is_verified": false,
"line_number": 636
"line_number": 643
},
{
"type": "Secret Keyword",
"filename": "deploy/template.yaml",
"hashed_secret": "42af5cf9fcf4f09147c032a0fb4877f5cf626bbc",
"is_verified": false,
"line_number": 637
"line_number": 644
},
{
"type": "Secret Keyword",
"filename": "deploy/template.yaml",
"hashed_secret": "7584a31168b8e8f62d9b84b7b95d239b99fad815",
"is_verified": false,
"line_number": 639
"line_number": 646
}
]
},
"generated_at": "2025-01-07T17:50:34Z"
"generated_at": "2025-01-17T13:13:51Z"
}
48 changes: 33 additions & 15 deletions deploy/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ Conditions:
- !Equals [!Ref Environment, integration]
- !Equals [!Ref Environment, production]
IsProduction: !Equals [!Ref Environment, production]
IsPerformance: !Or
- !Equals [!Ref Environment, build]
- !Equals [!Ref Environment, production]
DeployAlarms: !Or
- Condition: IsNotDevelopment
- !Equals [!Ref DeployAlarmsInDev, true]
Expand All @@ -76,6 +73,8 @@ Mappings:
uaEnabled: "true"
languageToggleDisabled: "false"
authSourceEnabled: "true"
minECSCount: 1
maxECSCount: 4
build:
logLevel: "info"
dynatraceSecretArn: arn:aws:secretsmanager:eu-west-2:216552277552:secret:DynatraceNonProductionVariables
Expand All @@ -85,6 +84,8 @@ Mappings:
uaEnabled: "true"
languageToggleDisabled: "false"
authSourceEnabled: "true"
minECSCount: 6
maxECSCount: 60
staging:
logLevel: "warn"
dynatraceSecretArn: arn:aws:secretsmanager:eu-west-2:216552277552:secret:DynatraceNonProductionVariables
Expand All @@ -95,6 +96,8 @@ Mappings:
uaEnabled: "true"
languageToggleDisabled: "false"
authSourceEnabled: "true"
minECSCount: 2
maxECSCount: 4
integration:
logLevel: "warn"
dynatraceSecretArn: arn:aws:secretsmanager:eu-west-2:216552277552:secret:DynatraceNonProductionVariables
Expand All @@ -104,6 +107,8 @@ Mappings:
uaEnabled: "true"
languageToggleDisabled: "false"
authSourceEnabled: "false"
minECSCount: 2
maxECSCount: 4
production:
logLevel: "warn"
dynatraceSecretArn: arn:aws:secretsmanager:eu-west-2:216552277552:secret:DynatraceProductionVariables
Expand All @@ -113,6 +118,8 @@ Mappings:
uaEnabled: "true"
languageToggleDisabled: "false"
authSourceEnabled: "false"
minECSCount: 6
maxECSCount: 60

# see https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-access-logs.html
ElasticLoadBalancerAccountIds:
Expand Down Expand Up @@ -810,22 +817,36 @@ Resources:

# ECS Autoscaling
ECSAutoScalingTarget:
Condition: IsPerformance
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MinCapacity: 6
MaxCapacity: 60
ResourceId: !Join
- "/"
- - "service"
- !Ref DrivingPermitFrontEcsCluster
- !GetAtt DrivingPermitFrontEcsService.Name
MaxCapacity:
!FindInMap [EnvironmentConfiguration, !Ref Environment, maxECSCount]
MinCapacity:
!FindInMap [EnvironmentConfiguration, !Ref Environment, minECSCount]
ResourceId: !Sub service/${DrivingPermitFrontEcsCluster}/${DrivingPermitFrontEcsService.Name}
RoleARN: !Sub "arn:aws:iam::${AWS::AccountId}:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService"
ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs

ECSPredictiveScalingPolicy:
DependsOn: ECSAutoScalingTarget
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: ECSPredictiveScalingPolicy
PolicyType: PredictiveScaling
ResourceId: !Sub service/${DrivingPermitFrontEcsCluster}/${DrivingPermitFrontEcsService.Name}
ScalableDimension: ecs:service:DesiredCount
ServiceNamespace: ecs
PredictiveScalingPolicyConfiguration:
MaxCapacityBreachBehavior: HonorMaxCapacity
MetricSpecifications:
- PredefinedMetricPairSpecification:
PredefinedMetricType: ECSServiceCPUUtilization
TargetValue: 60
Mode: ForecastOnly
SchedulingBufferTime: 600

EcsStepScaleOutPolicy:
Condition: IsPerformance
DependsOn: ECSAutoScalingTarget
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
Expand Down Expand Up @@ -867,7 +888,6 @@ Resources:
# on Fargate, so leave the upper bound open

EcsStepScaleInPolicy:
Condition: IsPerformance
DependsOn: ECSAutoScalingTarget
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
Expand Down Expand Up @@ -898,7 +918,6 @@ Resources:
# with <20% utilisation

EcsStepScaleOutAlarm:
Condition: IsPerformance
DependsOn: ECSAutoScalingTarget
Type: AWS::CloudWatch::Alarm
Properties:
Expand All @@ -922,7 +941,6 @@ Resources:
Threshold: "60"

EcsStepScaleInAlarm:
Condition: IsPerformance
DependsOn: ECSAutoScalingTarget
Type: AWS::CloudWatch::Alarm
Properties:
Expand Down
Loading