How to schedule ECS Services in AWS easily (start/stop)
Tags: aws, cloud, ecs, python
Published: 2021-07-28 13:52:58

> This is my solution which is highly based on a great AWS employee (Alfredo J).

Most likely if you are reading this article, you might know this is not something possible to do without a workaround in AWS. You might think of using a scheduled task or complex solutions but after a while, Alfredo from Mexico supported me to bring this solution to all of you.

First, create a **Policy** using the **JSON option** with the following config.

```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"logs:*"
			],
			"Resource": "arn:aws:logs:*:*:*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"ecs:DescribeServices",
				"ecs:UpdateService"
			],
			"Resource": [
				"*"
			]
		}
	]
}
```

It can be called **servicesscheduler**.

After the policy is created, you need to create an **IAM role** using the new **policy (servicesscheduler)**. It can be called **ECSScheduler**.

Next, you need to create a **Lambda** function that runs using the new **IAM role ECSScheduler**. After the function is created, add this Python (3.8) script:

```python
import json
import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

client = boto3.client('ecs')

def lambda_handler(event, context):
	cluster = event["cluster"]
	service_names = event["service_names"]
	service_desired_count = int(event["service_desired_count"])

	for service_name in service_names.split(","):
		response = client.update_service(
			cluster=cluster,
			service=service_name,
			desiredCount=service_desired_count
			)

		logger.info("Updated {0} service in {1} cluster with desire count set to {2} tasks".format(service_name, cluster, service_desired_count))
		
	return {
		'statusCode': 200,
		'new_desired_count': service_desired_count
	}

The script expects the following variables in a JSON format:

{
  "cluster": "clusterName",
  "service_names": "service1,service2",
  "service_desired_count": "0"
}
```

Where:

 - `cluster` is the name of the cluster you want to modify.
 - `service_names` is an array for the collection of services.
 - `service_desired_count` is the number of desired services. 0 is to stop the service/s, any other number is to start the service/s.

After everything is created you need to create some rules in Amazon EventBridge (formerly, CloudWatch Events). Here, you define the event you want to trigger based on the schedule that you expect. This is an example:

[![aws example][1]][1]

If something fails, you need to double-check that the created IAM role has the required policies like `ecs:UpdateService`. You can check this from the logs.

Can there be any variations using **tags** to make it more efficient? Yes, it's possible. I wrote a different version in my [blog](https://supernovaic.blogspot.com/2021/07/how-to-schedule-ecs-services-in-aws.html) focused on this alternative approach.

### Follow me on:

|  Personal  |  LinkedIn  |YouTube|Instagram|Cyber Prophets|Sharing Your Stories|
|:----------|:----------|:------------:|:------------:|:------------:|:------------:|
|[![Personal](https://raw.githubusercontent.com/FANMixco/federiconavarrete/master/img/favicons/favicon.png)](https://federiconavarrete.com)|[![LinkedIn](https://i.stack.imgur.com/idQWu.png)](https://www.linkedin.com/in/federiconavarrete)|[![YouTube](https://i.stack.imgur.com/CFPMR.png)](https://youtube.com/c/FedericoNavarrete)|[![Instagram](https://i.stack.imgur.com/PIfqY.png)](https://www.instagram.com/federico_the_consultant)|[![RedCircle Podcast](https://i.stack.imgur.com/4XICF.png)](https://redcircle.com/shows/cyber-prophets)|[![RedCircle Podcast](https://i.stack.imgur.com/4XICF.png)](https://redcircle.com/shows/sharing-your-stories)|

[![sponsor me](https://raw.githubusercontent.com/FANMixco/Xamarin-SearchBar/master/bmc-rezr5vpd.gif)](https://www.buymeacoffee.com/fanmixco)

  [1]: https://i.stack.imgur.com/6TBYG.png