Skip to content

Maintain long-running Fargate ECS tasks within your Serverless project

Notifications You must be signed in to change notification settings

eddmann/serverless-fargate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

60 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚀 Serverless Fargate

Adds the ability to maintain long-running Fargate ECS tasks within your Serverless project.

Overview

Not all behaviour can be broken down and modelled within Lambda's execution duration constraints. Sometimes you need the ability to exceed this duration, but wish to remain in a Serverless environment.

This plugin adds the ability to declare Fargate-backed ECS tasks which are provisioned during a Serverless deployment. Taking advantage of Serverless Frameworks ability to build/push images to ECR, you are able to declare both long-running and Lambda-based behaviour side-by-side.

At a high-level the plugin provides the following functionality:

  • Allows you to declare service-based (continuous) and scheduled tasks.
  • Uses the ECR image support provided within Serverless Framework to help build tasks.
  • Maintains an IAM role which honours all managed policies and statements that have been declared within the provider configuration.
  • Provides escape-hatches to supply custom configuration such as role ARNs/tags etc.
  • Handles both Fargate and Fargate Spot execution environments.

Example

Below is an example configuration which highlights all possible available options.

provider:
  # (required) similar to Lambda-containers, images defined within the provider are available to tasks.
  ecr:
    images:
      my-task:
        path: ./
        file: Dockerfile

  # (optional) role statements present within the provider are added to the task role.
  iamRoleStatements:
    - Effect: Allow
      Action: 'sqs:*'
      Resource: '*'

  # (optional) managed polices present within the provider are added to the task role.
  iamManagedPolicies:
    - arn:aws:iam::123456:policy/my-managed-provider-policy

  # (optional) environment variables present within the provider are added to all tasks.
  environment:
    name: value

  vpc:
    # (required) default security groups which are added to tasks that do not contain any overrides.
    securityGroupIds:
      - sg-12345

    # (required) default subnets which are added to tasks that do not contain any overrides.
    # all tasks MUST be assigned subnets as Fargate operates within `awsvpc` mode.
    subnetIds:
      - subnet-1234

  # (optional) tags present within the provider are added to task resources.
  tags:
    name: value

fargate:
  # (optional) name used for the provisoned cluster; an auto-generated name by CloudFormation is used if not supplied.
  clusterName: my-cluster-name

  # (optional) enable CloudWatch Container Insights for the provisoned cluster; if specified this overrides the account-level setting.
  containerInsights: true

  # (optional) default memory you wish to allocate to each task (if not supplied at the task level) - defaults to 0.5GB.
  # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size
  memory: '0.5GB'

  # (optional) default CPU you wish to allocate to each task (if not supplied at the task level) - defaults to 256 (.25 vCPU).
  # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size
  cpu: 256

  # (optional) default CPU architecture you wish to use for each task (if not supplied at the task level)
  # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#runtime-platform
  architecture: X86_64

  # (optional) environment variables which are added to all tasks.
  environment:
    name: value

  # (optional) name used for the provisoned log group.
  logGroupName: my-cluster-log-group

  # (optional) the number of days to retain the log events in the provisoned log group.
  logRetentionInDays: 365

  # (optional) default execution role ARN you wish to use for the task.
  executionRoleArn: arn:aws:iam::123456:role/my-custom-execution-role

  # (optional) default task role ARN you wish to use for the task.
  taskRoleArn: arn:aws:iam::123456:role/my-custom-task-role

  # (optional) additional role statements you wish to add to the task role, you would place statements here instead of at
  # the provider level if you only wished them to target Fargate tasks.
  iamRoleStatements:
    - Effect: Allow
      Action: 'resource:*'
      Resource: '*'

  # (optional) additional managed policies you wish to add to the task role, you would place policies here instead of at
  # the provider level if you only wished them to target Fargate tasks.
  iamManagedPolicies:
    - arn:aws:iam::123456:policy/my-managed-task-policy

  vpc:
    # (optional) default security groups which are added to tasks that do not contain any overrides; these override any provider-level configuration.
    securityGroupIds:
      - sg-12345

    # (required) default subnets which are added to tasks that do not contain any overrides; these override any provider-level configuration.
    # all tasks MUST be assigned subnets as Fargate operates within `awsvpc` mode.
    subnetIds:
      - subnet-1234

    # (optional) default flag to assign a public IP to each task, this requires the supplied subnets to be public (internet) facing.
    assignPublicIp: false

  # (optional) additional tags you wish to apply to only Fargate task resources.
  tags:
    name: value

  # (optional) additional CloudFormation resource properties you wish to include for all compiled tasks.
  # This provides a means of including properties present in the CloudFormation resource that are not exposed via the plugin DSL.
  cloudFormationResource:
    # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html
    task:
      EphemeralStorage: 5
    # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html
    container:
      StopTimeout: 5
    # container definitions you wish to run alongside the primary container
    # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html
    additionalContainers:
      - Name: 'additional-container-name'
        Image: 'additional-container-image'
    # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html
    service:
      EnableECSManagedTags: 'true'

  tasks:
    my-task:
      # (optional) unique name for the given task, defaults to the task key name.
      name: my-task-name

      # (required) the task image you wish to run, references images built within the `ecr` section.
      image: my-task

      # (optional) execution role ARN you wish to use for the given task.
      executionRoleArn: arn:aws:iam::123456:role/my-custom-execution-role

      # (optional) task role ARN you wish to use for the given task.
      taskRoleArn: arn:aws:iam::123456:role/my-custom-task-role

      vpc:
        # (optional) security groups you wish to apply to the given tasks; these override any provider/fargate-level configuration.
        securityGroupIds:
          - sg-12345

        # (required) subnets you wish to apply to the given tasks; these override any provider/fargate-level configuration.
        # all tasks MUST be assigned subnets as Fargate operates within `awsvpc` mode.
        subnetIds:
          - subnet-1234

        # (optional) flag to assign a public IP to the given task, this requires the supplied subnets to be public (internet) facing.
        assignPublicIp: false

      # (optional) the overridden command you wish to execute within the task container.
      command:
        - my-command

      # (optional) the overridden entrypoint you wish to execute within the task container.
      entryPoint:
        - my-entrypoint

      # (optional) memory you wish to allocate to the given task, defaults to the globally supplied memory value.
      # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size
      memory: '0.5GB'

      # (optional) CPU you wish to allocate to the given task, defaults to the globally supplied CPU value.
      # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size
      cpu: 256

      # (optional) CPU architecture you wish to use for the given task, defaults to the globally supplied CPU architecture.
      # https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#runtime-platform
      architecture: ARM64

      # (optional) environment variables which are added to the given task, these are combined with
      # the globally supplied environment variables.
      environment:
        name: value

      # (optional) additional tags you wish to apply to the given task, these are combined with
      # the provider and globally supplied tags.
      tags:
        name: value

      # (optional) ensure that the creation of task-related resources occur after listed resources.
      dependsOn: ['MyExampleResource']

      # (optional) by default a task is deemed to be a service with a desired count of one,
      # this results in a single long-running process which is a typical use-case of the plugin.
      # however, if you wish to alter this you can include the following configuration options.
      service:
        # (optional) the desired amount of running tasks for the given service.
        desiredCount: 1

        # (optional) used during deployment to determine how many tasks can be provisioned for the transition phase.
        maximumPercent: 200

        # (optional) used during deployment to determine how many tasks are required to remain active for the transition phase.
        minimumHealthyPercent: 100

        # (optional) flag to determine if you wish to provision the task using Fargate Spot.
        # note: at this time there is no fallback measures in-place to ensure that the task will be provisioned using
        # on-demand Fargate if the spot instance can not be acquired.
        spot: false

      # (optional) schedule expression used to configure the task to be executed at a desired time, as opposed to being a service.
      # https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/ScheduledEvents.html
      schedule: 'rate(1 minute)'

      # (optional) additional CloudFormation resource properties you wish to include for this compiled task.
      # This provides a means of including properties present in the CloudFormation resource that are not exposed via the plugin DSL.
      cloudFormationResource:
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html
        task:
          EphemeralStorage: 5
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html
        container:
          StopTimeout: 5
        # container definitions you wish to run alongside the primary container
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html
        additionalContainers:
          - Name: 'additional-container-name'
            Image: 'additional-container-image'
        # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html
        service:
          EnableECSManagedTags: 'true'

Inspired by https://github.com/svdgraaf/serverless-fargate-tasks