trying to runjavascript code from aws lambda to list or kill ecs task

758 views Asked by At

I have been trying hard to run the following code from aws lambda but I am not seeing any error neither I am seeing any ECS task getting killed.

Roles are all good.

Is it possible to connect to ECS from lambda?

  // NOTE: Set Lambda timeout to at least 60 seconds
const AWS = require('aws-sdk');

AWS.config.region = 'us-east-1';

const ecs = new AWS.ECS({ apiVersion: '2014-11-13' });
const sns = new AWS.SNS({ apiVersion: '2016-11-15' });

// ARN of the SNS topic to get generate exceptions
// *** UPDATE FOR YOUR REGION, ACCOUNT, AND SNS TOPIC ***
const TOPIC_INFORMATION_ARN = 'arn:aws:sns:[REGION]:[ACCOUNT NUMBER]:[SNS TOPIC]';  //replaced by sns

// *** MODIFY SETTINGS HERE FOR YOUR FARGATE CLUSTERS
const FARGATE_CLUSTERS = [
    {
        cluster: "ecs-dev",
        period: 15,  // 4 times an hour
        enabled: false
    },
    {
        cluster: "ecs-stage",
        period: 30,  // 2 times an hour
        enabled: false
    },
    {
        cluster: "ecs-prod",
        period: 60,  // 1 time an hour
        enabled: false
    }];

// Called every 15 minutes using CRON, so minute value should be 00, 15, 30, 45
async function main(event) {
    try {

        // For each ECS cluster listed above...
        for (var i = 0; i < FARGATE_CLUSTERS.length; i++) {

            // Only kill a task if cluster is enabled
            if (FARGATE_CLUSTERS[i].enabled) {

                let date = new Date(event.time);
                let minutes = date.getMinutes();                

                // Only kill a task if schedule matches the current time
                if ((minutes % FARGATE_CLUSTERS[i].period) == 0) {
                   
                    // Get the list of currently running Fargate tasks in the cluster.
                    var res = await ecs.listTasks({
                        cluster: FARGATE_CLUSTERS[i].cluster,
                        desiredStatus: 'RUNNING',
                        launchType: 'FARGATE'
                    }).promise();

                    // Select one of the tasks at random for termination.
                    var index = Math.floor(Math.random() * res.taskArns.length);
                    var doomedTask = res.taskArns[index];

                    // Kill the selected task.
                    await ecs.stopTask({
                        cluster: FARGATE_CLUSTERS[i].cluster,
                        task: doomedTask,
                        reason: 'CHAOS MONKEY'
                    }).promise();
                }
            }
        }
    } catch (err) {
        console.log(err.stack);
        await sns.publish({
            Message: err.stack,
            Subject: 'Chaos Monkey Fargate',
            TopicArn: TOPIC_INFORMATION_ARN
        }).promise();
    }
};

exports.handler = async (event) => {
    await main(event);
};

Trying to connect to Fargate ECS Cluster and execute lambda to list and kill running ECS Task on certain time interval.

How can I run the javascript in debug mode?

What could be the issue here?

1

There are 1 answers

0
Asri Badlah On

I think you would like to schedule start / stop ECS tasks, you can do this you need the following:

1- Create a lambda function, to start or stop by update the ECS service DesiredCount (DesiredCount=0 to stop, DesiredCount>0 to start).

2- Create scheduled CloudWatch Events, to start the ECS tasks (set DesiredCount to number of tasks you like).

3- Create scheduled CloudWatch Events, to stop the ECS tasks (set DesiredCount to 0 ).

This lambda code by python, check if the cluster Env tag is Dev to change DesiredCount value based on cloudwatch event (start or stop)

import boto3 
import json
  ecs_client = boto3.client('ecs')
  client_scale = boto3.client('application-autoscaling')
def lambda_handler(event, context):
  response_clusters = ecs_client.list_clusters()
  clusters_list = response_clusters['clusterArns']
  for cluster in clusters_list:
    cluster_info = ecs_client.describe_clusters(clusters=[cluster,],include=['TAGS'])
    print(cluster)
    for cluster_item_info in cluster_info['clusters']:
      ISDev = False
      IsService = False
      for tag in cluster_item_info['tags']:
         if tag['key'] == 'Env' and tag['value'] =='Dev':
            ISDev = True
         if tag['key'] == 'Type' and tag['value'] =='Service':
            IsService = True
         if ISDev and IsService:
           print(cluster_item_info['clusterName'])
           response_services =
           ecs_client.list_services(cluster=cluster_item_info['clusterName'])
           services_list = response_services['serviceArns']
           for service in services_list:
              service_info = 
                                                                                               
              ecs_client.describe_services(cluster=cluster_item_info['clusterName'],
              services= [service,],)
              for item in service_info ['services']:
                 print(item['serviceName'])
                 print(item['desiredCount'])
                 resource = 
                 'service/'+cluster_item_info['clusterName']+'/'+item['serviceName']
                 scale_info = client_scale.describe_scalable_targets
                 (ServiceNamespace='ecs',ResourceIds=[resource,])
                 for scale_item_info in scale_info['ScalableTargets']:
                    print(scale_item_info['MinCapacity'])
                    print(scale_item_info['MaxCapacity'])
                    print(event['Action'])
                    if event['Action'] == 'stop':
                       desiredCount_number = 0
                    else:
                       desiredCount_number = scale_item_info['MinCapacity']
                    response_ecs_update = ecs_client.update_service(
                    cluster=cluster_item_info['clusterName'],
                    service=item['serviceName'],
                    desiredCount=desiredCount_number
                    )