Every Deployment on ECS using AWS Codepipeline creates a new version of task definition - amazon-ecs

Every time a deployment happens, Codepipeline creates a new version of the task definition. How do I avoid it?
I want to specifically use a particular version.

Related

Is there a way we can deploy all the cloudformation templates from a gitlab repository using gitlab pipeline in aws in a single stack?

I'm looking for an option to pick all the templates from the repository without hardcode the yml template files and in future if new templates are added, the pipeline should automatically pick all of them and do the deploy and create a single stack in aws environment, without making any modification to gitlab-ci.yml/pipeline file.
I tried using deploy CLI command, it deploy all the templates but then it goes for update and start deleting one by one and only the last template resource will be available after the pipeline execution is complete.
Let me know if there is an option to do this?

Cloudformation - ECS service. How to manage pipeline-deployed image updates without stack conflicts

I'm attempting to write a CloudFormation template to fully to define all resources required for an ECS service, including...
CodeCommit repository for the nodejs code
CodePipeline to manage builds
ECR Repository
ECS Task Definition
ECS Service
ALB Target Group
ALB Listener Rule
I've managed to get all of this working. The stack builds fine. However I'm not sure how to correctly handle updates.
The Container in the Task Defition in the template required an image to be defined. However the actual application image won't exist until after the code is first built by the pipeline.
I had an idea that I might be able to work around this issue, by defining some kind of placeholder image "amazon/amazon-ecs-sample" for example, just to allow the stack to build. This image would be replaced by CodeBuild when the pipeline first runs.
This part also works fine.
The issues occur when I attempt to update the task definition, for example adding environment variables, in the CloudFormation template. When I re-run the stack, it replaces my application image in the container definition, with the original placeholder image from the template.
This is logical enough, as CloudFormation obviously assumes the image in the template is the correct one to use.
I'm just trying to figure out the best way to handle this.
Essentially I'd like to find some way to tell CloudFormation to just use whatever image is defined in the most recent revision of the task definition when creating new revisions, rather than replacing it with the original template property.
Is what I'm trying to do actually possible with pure CloudFormation, or will I need to use a custom resource or something similar?
Ideally I'd like to keep extra stack dependencies to a minimum.
One possibility I had thought of, would be to use a fixed tag for the container definition image, which won't actually exist when the cloudformation stack first builds, but which will exist after the first code-pipeline build.
For example
image: [my_ecr_base_uri]/[my_app_name]:latest
I can then have my pipeline push a new revision with this tag. However, I prefer to define task defition revisions with specific verion tags, like so ...
image: [my_ecr_base_uri]/[my_app_name]:v1.0.1-[git-sha]
... as this makes it very easy to see exactly what version of the application is currently running, and to revert revisions easily if needed.
Your problem is that you're putting too many things into this CloudFormation template. Your template could include the CodeCommit repository and the CodePipeline. But the other things should be outputs from your pipeline. Remember: Your pipeline will have a build and a deploy stage. The build stage can "build" another cloudformation template that is executed in the deploy stage. During this deploy stage, your pipeline will construct the ECS services, tasks, ALB etc...

Updating ECS task definition image using Codeship

I'm trying to determine the best way to generate a new or update an existing AWS ECS task definition JSON file using Codeship's codeship/aws-deployment image.
I don't want to rely on the implicit :latest tag within my task definition and wish to use the custom image tag generated in a previous step which pushes to AWS ECR.
Is a custom bash or python script to pull the current task definition, increment the version and replace the image string the only way to accomplish this or is there an existing CLI tool I'm glossing over?

Create new task definition and remove old task definitions for an ECS service

If I create a new task definition for ECS, is there a way to delete all existing task definitions for a service and add the new definition, or do I have to create a brand new service?
The problem I am having, I am stuck in a long development loop where I update a container, create a new task definition revision and find myself having to create a brand new service, load balancer, target group, etc, for this new task definition. Is there a way, perhaps to tell the existing service to use the latest revision of the task definition instead of having to do all the above?
Yes by using the 'latest' tag on your uploaded docker image.
Then make sure your task definition uses the 'latest' tag for its container image.
After updating the docker image going forward, you'll need to simply 'cycle' the service. In the AWS Console, you can update the service and simply check the 'Force New Deployment' checkbox in the wizard and change nothing else. AWS will then stop existing tasks and start new ones which will use the current version of the docker image. For non-web tasks this is usually pretty quick. Web tasks take a little longer to 'drain'. In any case, you won't need to create new task definitions this way or update the service except to redeploy.
Force new deployment is also available through all of the CLI and API tools as well.
When a new version of the task definition is created, then open the service and click Edit, then select the new version from the drop-down box, then check the Force Deployment and click the Update button. Note that the new task will be in the pending state as not enough resource; if that is the case then select the currently running task and Stop it.

serverless deploy: Stop watching after CloudFormation has the update

I'm using Bitbucket Pipelines to do CD for a Serverless app. I want to use as few "build minutes" as possible for each deployment. The lifecycle of the serverless deploy command, when using AWS as the backing, seems to be:
Push the package to CloudFormation. (~60 seconds)
Sit around watching the logs from CloudFormation until the deployment finishes. (~20-30 minutes)
Because of the huge time difference, I don't want to do step two. So my question is simple: how do I deploy a serverless app such that it only does step one and returns success or failure based on whether or now CloudFormation successfully accepted the new package?
I've looked at the docs for serverless deploy and I can't see any options to enable that. Also, there seem to be AWS specific options in the serverless deploy command already, so maybe this is an option that the serverless team will consider if there is no other way to do this.
N.B. As for, "how will you know if CloudFormation fails?", for that, I would rather set up notifications to come from CloudFormation directly. The build can just have the responsibility of pushing to CloudFormation.
I don't think you can do it with serverless deploy. You can try serverless package command that will store the package in .serverless folder or you can specify the path using --package. Package will create a CloudFormation template file e.g. cloudformation-template-update-stack.json. You can then call Create Stack API action to create the stack. It will return the stack ID without waiting for all the resources to be created.