amazon-ecs-deploy-task-definition icon indicating copy to clipboard operation
amazon-ecs-deploy-task-definition copied to clipboard

run one-off task (e.g. migrations)

Open cainlevy opened this issue 5 years ago • 12 comments

I'm using the render & deploy actions provided by github.com/aws-actions. The only thing missing is an option to run a one-off task after registering the new task definition and before deploying it. This would be useful for executing database migration scripts that the new service version requires.

cainlevy avatar Apr 13 '20 15:04 cainlevy

I think I'm interested in the same functionality. I'd like to deploy a task and just run it on an ECS Cluster without defining a service. After the task runs, it shuts itself down. I don't need it to run indefinitely. Is this possible?

mrsuau627 avatar Apr 29 '20 20:04 mrsuau627

@cainlevy Not sure if you already figured this out...I ended up creating a github workflow that doesn't use this action at all. Instead, I install the Amazon.ECS.Tools cli and use that (which is what Visual Studio uses).

Example:

name: Deploy to dev environment
on:
  push:
    branches:
      - develop
jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 3.1.101
    - name: Install dependencies
      run: dotnet restore {your project name here}
    - name: Install AWS command line tools
      run: dotnet tool install -g Amazon.ECS.Tools
    - name: Deploy to AWS
      run:  dotnet ecs deploy-task 
        --region us-east-2 
        --aws-access-key-id ${{ secrets.AWS_ACCESS_KEY_ID }} 
        --aws-secret-key ${{ secrets.AWS_SECRET_ACCESS_KEY }} 
        --container-environment-variables 'ASPNETCORE_ENVIRONMENT=Production;DB_SERVER=${{ secrets.DB_SERVER }};DB_PORT=${{ secrets.DB_PORT }};DB=${{ secrets.DB }};DB_PASSWORD=${{ secrets.DB_PASSWORD }};'

I had to play with the various options of the ecs deploy-task command which are available by typing dotnet ecs help deploy-task in the cli

mrsuau627 avatar May 01 '20 03:05 mrsuau627

I'm looking for the same functionality on Fargate type task for migration. I also want to wait until a one-off task is finished.

jaedung avatar Aug 04 '20 04:08 jaedung

This is what i use for migrations and test on ecs fargate. https://github.com/noelzubin/aws-ecs-run-task

noelzubin avatar Nov 29 '21 16:11 noelzubin

Recently created this: https://github.com/muya/amazon-ecs-run-task, which allows:

  • setting of launch type OR capacity provider strategy (so you can use FARGATE, FARGATE_SPOT, EC2 or whatever)
  • setting of appropriate network configuration (subnets, security groups, public IP)
  • waiting until a task is finished

It builds upon several other implementations to bring the functionality together. More details in this blog post.

muya avatar Sep 28 '22 04:09 muya

any news on this? will it be supported on this action?

bmbferreira avatar Feb 26 '23 23:02 bmbferreira

I need this feature as well, use case is: run Prisma migrations before running new tasks

RomainSF avatar Mar 13 '23 23:03 RomainSF

While this is not a thing, this is how I've done:

release:
    runs-on: ubuntu-latest
    needs:
      - build-application
      - build-migrations
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Configure AWS CLI
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-region: us-west-2
          role-to-assume: ${{ secrets.aws_role_arn }}
      - name: Run database migrations
        run: |
          aws ecs run-task --task-definition ${{ secrets.AWS_ECS_DB_MIGRATIONS_TASK_NAME}} --cluster ${{ secrets.AWS_ECS_CLUSTER_NAME }} --launch-type="FARGATE" --network-configuration '${{ secrets.ECS_TASK_RUN_NETWORK_CONFIG }}'
      - name: Wait for migrations run to finish
        run: aws ecs wait tasks-stopped --cluster ${{ secrets.AWS_ECS_CLUSTER_NAME }} --tasks $(aws ecs list-tasks --cluster ${{ secrets.AWS_ECS_CLUSTER_NAME }} --family ${{  secrets.AWS_ECS_DB_MIGRATIONS_TASK_NAME}} --query 'taskArns' --output text)
      - name: Download application task definition
        run: |
          aws ecs describe-task-definition --task-definition ${{ secrets.AWS_ECS_SERVICE_NAME }} \
          --query taskDefinition > task-definition.json
      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ secrets.AWS_ECS_CONTAINER_NAME }}
          image: ${{ needs.build-application.outputs.image }}
      - name: Deploy Amazon ECS task definition
        uses: aws-actions/amazon-ecs-deploy-task-definition@v1
        with:
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          service: ${{ secrets.AWS_ECS_SERVICE_NAME }}
          cluster: ${{ secrets.AWS_ECS_CLUSTER_NAME }}
          wait-for-service-stability: true

francardoso93 avatar Jul 03 '23 13:07 francardoso93

This has been sitting in the feature request path for over 3 years!

Kinda expected this feature to just exist... I'll have to look at one of the work arounds

jeropaul avatar Jul 19 '23 03:07 jeropaul

Here is my simple work around. In the task-definition.json, define one more container to be used for migration. Use this container as a dependency of the app-container to ensure that migration must be done before deploying.

// task-definition.json
{
"containerDefinitions": [
    {
      "name": "app-container",
      "image": "{my-image}:latest",
      "essential": true,
      "dependsOn":[
        {
          "containerName":"migration",
          "condition":"SUCCESS"
        }
      ]
    },
    {
      "name":"migration",
      "image":"{my-image}:latest",
      "essential":false, 
      "command":[
         "npm",
         "run",
         "migrate"
      ]
   }
  ]
}

And in the GitHub workflow, fill the latest image into both containers and deploy it.

- name: Render Amazon ECS task definition for app
  id: task-def-app
  uses: aws-actions/amazon-ecs-render-task-definition@v1
  with:
    task-definition: ${{ env.TASK_DEFINITION }}
    container-name: app-container
    image: ${{ steps.build-image.outputs.image }}

- name: Render Amazon ECS task definition for migration
  id: task-def-migration
  uses: aws-actions/amazon-ecs-render-task-definition@v1
  with:
    task-definition: ${{ steps.task-def-app.outputs.task-definition }}
    container-name: migration
    image: ${{ steps.build-image.outputs.image }}

- name: Deploy Amazon ECS task definition
  uses: aws-actions/amazon-ecs-deploy-task-definition@v1
  with:
    task-definition: ${{ steps.task-def-migration.outputs.task-definition }}
    service: ${{ env.ECS_SERVICE }}
    cluster: ${{ env.ECS_CLUSTER }}
    wait-for-service-stability: true

DucNguyenVan avatar Jul 21 '23 03:07 DucNguyenVan

Any update other workaround on this? Specifically looking to run a step after registering the new task definition and before deploying it.

keithslater avatar Sep 08 '23 20:09 keithslater

@DucNguyenVan unfortunately this only works if you have migrations that are under 3 hours.

If you ever have a long migration, AWS will clean up the service because it is still considered pending and re run the process. This would be controllable by ECS_ENGINE_TASK_CLEANUP_WAIT_DURATION, however this did not seem alterable for FARGATE.

A separate one-off task is required in these cases.

JGSweets avatar Dec 26 '23 16:12 JGSweets