aws-actions/amazon-ecs-render-task-definition

Dynamic task modification

neugeeug opened this issue ยท 12 comments

In our use case, we need to modify some of our task definition parameters and use values that are known just during deployment. For example,
We need to provide to our component env variable VERSION:

{
   "environment": [
        {
          "name": "VERSION",
          "value": "7.0.1476"
        }
      ],
}

Some general mechanism for replacing placeholders with wanted value would be really helpful. For example we could define

{
    "environment": [
        {
          "name": "VERSION",
          "value": "#VERSION#"
        }
      ],
}

And pass there the correct value:

    - name: Render Amazon ECS task definition
      id: render-task-definition
      uses: aws-actions/amazon-ecs-render-task-definition@v1
      with:
        task-definition: abc
        container-name: abc
        image: abc
        replacement_pattern: #VERSION#
        replacement_value: ${{steps.version.outputs.prop}}

The action would replace the replacement_pattern (regexp) with replacement_value.
Would be possible to add this or similar functionality ?

@neugeeug thanks for bringing up this topic. This would be a very useful feature, I was just looking for something similar right now!

@neugeeug thanks for bringing up this topic. This would be a very useful feature, I was just looking for something similar right now!

Thank you for the comment @faraquet.
I took a look to the code. Despite the fact that I am not a JS ninja, the change seems to be quite simple in the shape I proposed above. I am waiting for a green light from the owners side and can prepare the PR just when I get it :)

@neugeeug thanks very much for the suggestion and PR! We've seen similar requests re: interpolating stage/env specific-values into a task definition before, but so far haven't landed on a choice re: implementation.

The linked approach (merging a task def 'fragment') strikes me as more extensible b/c you can apply a whole set of changes at once vs. a specific value. I understand the use cases may be somewhat different (to merge a JSON 'fragment' you need to have or add the JSON in a file, where for a single value creating a JSON string is more overhead), but I could be missing something. What do you think about a more general "merge" capability?

@allisaurus thank you for the comment. I took a look to the linked approach and I agree, the more general solution might be good, but in my simple scenario will not solve the problem. I need to replace one value in the task definition and I know the new value only when the workflow is being executed (it is calculated during the build process). As you wrote, I would probably have to generate a JSON file first during the build process in order to be able to use it later in the proposed way. My idea was to keep it simple. I also see the constraints that @clareliguori mentioned regarding the input data types. There is not possible to define a kind of input map where you could define several different placeholders and values, but as a workaround you could use piping and call several time the same action. Each will replace another placeholder... I know it is not very elegant but seems to be simple.

I would like to mention that we are able to accept any solution that solves the problem in ASAP mode because a deadline is approaching. Would be really pity to eliminate the Github Actions because of lack of this functionality. Thank you again for your help. I hope we are able to find a right solution together.

@neugeeug Re: getting quickly unblocked, would it be possible for you to use a basic envsubst action in addition to this one in your workflow? There are a few available, but taking a look at an example I think you could do something like the following:

...

 - name: Render Amazon ECS task definition
      id: render-task-definition
      uses: aws-actions/amazon-ecs-render-task-definition@v1
      with:
        task-definition: abc
        container-name: abc
        image: abc

 - name: Render version env var
        uses: nowactions/envsubst@v1
        with:
          input: ${{ steps.render-task-definition.outputs.task-definition }}
          output: ./task-def-final.json
        env:
          VERSION: ${{ steps.version.outputs.prop }}

- name: Deploy to Amazon ECS service
      uses: aws-actions/amazon-ecs-deploy-task-definition@v1
      with:
        task-definition: ./task-def-final.json
        service: my-service
        cluster: my-cluster

...

@neugeeug are you still experiencing this issue?

@pkandasamy91 thank you for asking. I had to to switch for a while to another areas, and I have not had a time to test the solution proposed by @allisaurus. Fortunately I am going to switch back to the issue this week. I will let you know soon.

@neugeeug No worries, please let us know if the proposed solution does not work for you.

I've finally found a time to test the proposed solution and it seems that I am able to achieve the goal defined above in a simpler way, even without the render-task-definition action. It was not possible to use the action you proposed in a simple way because it is a Docker based action, and it is not so easy to pass the rendered task definition to the docker container (a copy action would be needed in order to transfer the file to place where Docker can see it)

/entrypoint.sh: line 3: can't open /home/runner/work/_temp/task-definition--2985-91iQ5SbzGlIT-.json: no such file

Anyway it inspired me a bit and the final solution looks like below:

- name: Replace version in ECS task definition
  run: |
    export VERSION=${{steps.version.outputs.prop}} && envsubst < "task-definition-template.json" > "task-definition-result.json"

- name: Deploy to Amazon ECS
  timeout-minutes: 15
  uses: aws-actions/amazon-ecs-deploy-task-definition@v1
  with:
    task-definition: ./task-definition-result.json
    service: my-service
    cluster: my-cluster

Thanks for help all of you @allisaurus @pkandasamy91

Thanks for the additional info @neugeeug ! Very glad you got unblocked.
Since you no longer need it, and given our conversation above, can we close #54 ?

can we close #54 ?

I did it already.
Thanks.

Closing in favour of #20