Adding AutoScaling to Amazon ECS with AWS CDK - Building Modern PHP/Yii2 Application using AWS  
Tags: aws, php, yii2
Published: 2020-03-19 13:14:18

In this section, I will show how to add autoscaling in the code that we have written in [previous post](https://dev.to/petrabarus/deploying-yii2-application-to-amazon-ecs-and-aws-fargate-using-aws-cdk-building-modern-php-yii2-application-using-aws-41kh).

Why do we need to use autoscaling? The reason is so that we can serve visitors to our site with optimal cost. Here is how it goes. The image below is the pattern of visitors to common e-commerce site like Amazon.com. Usually the visitor count peaks at day and goes down at night.

![Visitor Pattern](https://blog.petrabarus.net/wp-content/uploads/2020/01/Screen-Shot-2020-01-29-at-7.50.37-AM-1024x315.png)

(Picture Credit: [Scaling Up to Your First 10 Millions presentation](https://www.youtube.com/watch?v=kKjm4ehYiMs))

In order to serve the visitors without any problem, we have to provision servers just enough for the peak performance.

![Visitor Pattern](https://blog.petrabarus.net/wp-content/uploads/2020/01/Screen-Shot-2020-01-29-at-7.51.23-AM-1024x319.png)

With AWS AutoScaling, we can automatically turn off unused server capacility when the traffic goes down. Since we only pay the amount of servers that we turn on, we then can save a lot money.

![Autoscaling](https://blog.petrabarus.net/wp-content/uploads/2020/01/Screen-Shot-2020-01-29-at-10.51.27-AM-1024x349.png)

So, coming back to our code in previous post, we use `ApplicationLoadBalancedFargateService` construct to create a site using Amazon ECS with AWS Fargate. This construct hides a lot of resources and process in the below layer.

```php
const fargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
    cluster: ecsCluster,
    taskImageOptions: {
       image: ecs.ContainerImage.fromAsset('.')
    },
});
```

From the code above, we can configure the autoscaling with just a few line of code.

```php
const fargateService = new ecsPatterns.ApplicationLoadBalancedFargateService(this, 'Service', {
    cluster: ecsCluster,
    taskImageOptions: {
        image: ecs.ContainerImage.fromAsset('.')
    },
});

const autoScalingGroup = fargateService.service.autoScaleTaskCount({
    minCapacity: 2,
    maxCapacity: 10
});
```

It can be seen from the code above that we take the `AutoScalingGroup` object by calling `autoScaleTaskCount` method and assign the object with minimum capacity of 2 and maximum capacity of 10. This means that in the peak time, the Fargate task will scale out up to 10 tasks. It will scale in to 2 task in off-peak time just in case one of the task go under failure.

## Scaling By Schedule

We can configure the scaling by time schedule, means the capacity will go up or down based on the schedule that we set.

Untuk fitur penjadwalan ini kita harus mengimpor dependensi @aws-cdk/aws-applicationautoscaling di package.json. Eksekusi npm install untuk menginstall dependensi tersebut.

To enable the autoscaling, we need to install the CDK dependency `@aws-cdk/aws-applicationautoscaling` to our NPM package by executing the following command.

```
npm update
npm install @aws-cdk/aws-applicationautoscaling
```

Then in the `app.ts` we import the library.

```typescript
import appAutoscaling = require("@aws-cdk/aws-applicationautoscaling");
```

We just need to call `scaleOnSchedule` method on the `autoScalingGroup` object. Usually the schedule done by adding task near the noon and removing task at night.

```typescript
const autoScalingGroup = fargateService.service.autoScaleTaskCount({
    minCapacity: 2,
    maxCapacity: 10
});
autoScalingGroup.scaleOnSchedule('ScaleUpInMorning', {
    schedule: appAutoscaling.Schedule.cron({hour: '03', minute: '30'}),
    minCapacity: 10,
});
autoScalingGroup.scaleOnSchedule('ScaleDownInEvening', {
    schedule: appAutoscaling.Schedule.cron({hour: '10', minute: '00'}),
    maxCapacity: 5,
});
```

We schedule the task addition with minimum 10 task at 3.30 UTC time (it's 10.30 Jakarta time, almost noon). The task removal is scheduled at 10.00 UTC time with maximum 5 tasks (17.00 Jakarta time, afternoon).

To apply the change, execute the following command.

```
cdk deploy
```

![Scheduled Fargate Task](https://blog.petrabarus.net/wp-content/uploads/2020/02/Screen-Shot-2020-02-02-at-2.39.32-PM-1024x237.png)

## Scaling By CPU Usage

In addition to configure autoscaling by schedule, we can also configure by other metrics such as CPU utilization. We can assume that the more visitors to our site, the more CPU usage will become.

The following code shows autoscaling will keep CPU utilization below 50%.

```typescript
autoScalingGroup.scaleOnCpuUtilization('CpuScaling', {
    targetUtilizationPercent: 50,
    scaleInCooldown: cdk.Duration.seconds(60),
    scaleOutCooldown: cdk.Duration.seconds(60),
});
```
When the CPU utilization is below 50%, ECS will scale in to reduce the number of tasks, and when it reaches above 50%, it will add more task. The parameter `scaleInCoolDown` and `scaleOutCoolDown` is the length of time to wait before scale out and scale in process.

---

That is just a bit overview about auto scaling and how to add auto scaling capabilities to our existing PHP Yii2 application that we built before. Don't forget to execute `cdk destroy` to avoid additional cost if you are still exploring.

Please do drop comments if you have any questions or ideas for next post.

## References

You can learn more about the autoscaling here

- [AWS CDK API: aws-applicationautoscaling module](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-applicationautoscaling-readme.html)
- [AWS Auto Scaling](https://docs.aws.amazon.com/autoscaling/index.html)