Code Monkey home page Code Monkey logo

awslabs / ecs-refarch-continuous-deployment Goto Github PK

View Code? Open in Web Editor NEW
849.0 89.0 1.0K 1.8 MB

ECS Reference Architecture for creating a flexible and scalable deployment pipeline to Amazon ECS using AWS CodePipeline

Home Page: https://aws.amazon.com/blogs/compute/continuous-deployment-to-amazon-ecs-using-aws-codepipeline-aws-codebuild-amazon-ecr-and-aws-cloudformation/

License: Apache License 2.0

Shell 100.00%
aws ec2 fargate ecs docker continuous-deployment devops

ecs-refarch-continuous-deployment's Introduction

ECS Reference Architecture:Β Continuous Deployment

The ECS Continuous Deployment reference architecture demonstrates how to achieve continuous deployment of an application to Amazon Elastic Container Service (Amazon ECS) using AWS CodePipeline and AWS CodeBuild. With continuous deployment, software revisions are deployed to a production environment automatically without explicit approval from a developer, making the entire software release process automated.

Launching this AWS CloudFormation stack provisions a continuous deployment process that uses AWS CodePipeline to monitor a GitHub repository for new commits and AWS CodeBuild to create a new Docker container image and to push it into Amazon Elastic Container Registry (Amazon ECR).

When creating this stack, you can opt to deploy the service onto AWS Fargate or Amazon EC2. AWS Fargate allows you to run containers without managing clusters or services. If you choose Amazon EC2, an Auto Scaling group of t2.micro instances will be created to host your service.

Running the example

1. Fork the GitHub repository

Fork the Amazon ECS sample app GitHub repository into your GitHub account.

From your terminal application, execute the following command (make sure to replace <your_github_username> with your actual GitHub username):

git clone https://github.com/<your_github_username>/ecs-demo-php-simple-app

This creates a directory named ecs-demo-php-simple-app in your current directory, which contains the code for the Amazon ECS sample app.

2. Create the CloudFormation stack

Deploy Region Name Region Launch Types
πŸš€ US East (N. Virginia) us-east-1 Fargate, EC2
πŸš€ US East (Ohio) us-east-2 EC2
πŸš€ US West (N. California) us-west-1 EC2
πŸš€ US West (Oregon) us-west-2 EC2
πŸš€ EU (Ireland) eu-west-1 EC2
πŸš€ EU (London) eu-west-2 EC2
πŸš€ EU (Frankfurt) eu-central-1 EC2
πŸš€ Asia Pacific (Singapore) ap-southeast-1 EC2
πŸš€ Asia Pacific (Sydney) ap-southeast-2 EC2
πŸš€ Asia Pacific (Tokyo) ap-northeast-1 EC2
πŸš€ Asia Pacific (Seoul) ap-northeast-2 EC2
πŸš€ Canada (Central) ca-central-1 EC2

This reference architecture can only be deployed to Regions which have all necessary services available. See the Region Table for information about service availability.

The CloudFormation template requires the following parameters:

  • Cluster Configuration

    • Launch Type: Deploy the service using either AWS Fargate or Amazon EC2. Selecting EC2 will create an Auto Scaling group of t2.micro instances for your cluster. See the documentation to learn more about launch types.
  • GitHub Configuration

    • Repo: The repo name of the sample service.
    • Branch: The branch of the repo to deploy continuously.
    • User: Your username on GitHub.
    • Personal Access Token: Token for the user specified above. (https://github.com/settings/tokens)

The CloudFormation stack provides the following output:

  • ServiceUrl: The sample service that is being continuously deployed.
  • PipelineUrl: The continuous deployment pipeline in the AWS Management Console.

Testing the example

After the CloudFormation stack is created, the latest commit to the GitHub repository is run through the pipeline and deployed to ECS. Open the PipelineUrl to watch the first revision run through the CodePipeline pipeline. After the deploy step turns green, open the URL from ServiceUrl which loads a page similar to this:

ECS sample app

To test continuous deployment, make a change to src/index.php in the ecs-demo-php-simple-app repository and push it to GitHub. CodePipeline detects the change, builds the new application, and deploys it to your cluster automatically. After the pipeline finishes deploying the revision, reload the page to see the changes made.

Cleaning up the example resources

To remove all resources created by this example, do the following:

  1. Delete the main CloudFormation stack which deletes the substacks and resources.

  2. Manually delete resources which may contain content:

    • S3 Bucket: ArtifactBucket
    • ECR Repository: Repository

CloudFormation template resources

The following sections explains all of the resources created by the CloudFormation template provided with this example.

Resources that compose the deployment pipeline include the CodeBuild project, the CodePipeline pipeline, an S3 bucket for deployment artifacts, and all necessary IAM roles used by those services.

An ECS task definition, service, IAM role, and ECR repository for the sample application. This template is used by the CodePipeline pipeline to deploy the sample service continuously.

An ECS cluster optionally backed by an Auto Scaling group of EC2 instances running the Amazon ECS-optimized AMI for the EC2 launch type.

An Application Load Balancer to be used for traffic to the sample application.

A VPC with two public subnets on two separate Availability Zones, an internet gateway, and a route table with a default route to the public internet.

License

This reference architecture sample is licensed under Apache 2.0.

ecs-refarch-continuous-deployment's People

Contributors

clorichel avatar jpignata avatar rnzsgh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ecs-refarch-continuous-deployment's Issues

coupling of service.yaml on the continuous-deployment.yaml

Since the service.yaml is defined in the ecs-refarch-continuous-deployment.yaml, whenever we have changes on that file like adding a new subnet, it will update the service back to using the initial image: "amazon/amazon-ecs-sample". Which might be undesirable.

Assuming my understanding is correct, any ideas how to mitigate that? Or how to go around it?

Updating a child stack directly can cause root stack to get stuck in UPDATE_ROLLBACK_FAILED

It is very unadvisable to modify a child stack directly as this can cause the stack to get stuck in state which is hard to recover from.

If an update is being made to stack as a whole while a change is being made to a child stack and one fails, it can find it hard to roll back successfully. What tends to happen is a resource reports a status of being stable however another part of stack thinks its failed.

Generally when this happens a user is unable to fix it and it gets referred to the CloudFormation team which can take 12+ hours to resolve.

Whenever I've spoken to the CF team they advice updating child stacks directly is not a good thing to do.

In my opinion structuring your stacks in a way similar to that described in this example is a bad idea.

Deploy ECS FileName syntax

Just a question with regards to the images.json syntax.
I'm struggling to find any documentation with regards to it.

Configuration:
                ClusterName: !Ref Cluster
                ServiceName: !Ref Service
                FileName: images.json

Basing on this, I assume that valid keys are name and imageUri. Is that it, or are there others?
If you don't mind, can you share a link on any documentation?

printf '[{"name":"simple-app","imageUri":"%s"}]' "$IMAGE_URI" > images.json

Great templates, really helpful btw..

IAM doc

It would be helpful if you documented which policies you need for the IAM role which you attach to this stack. I ended up using the AdministratorAccess policy to just get this stack deployed and running. Maybe that's necessary but it's not clear in the ReadMe.
Thanks!

Also, totally possible this is user error on my part.

Failed deploying on Tokyo region

Failed deploying on Tokyo region due to the following error while creating VPC with cloudformation.

10:36:24 UTC+0900 CREATE_FAILED AWS::EC2::Subnet Subnet2 Value (ap-northeast-1b) for parameter availabilityZone is invalid. Subnets can currently only be created in the following availability zones: ap-northeast-1a, ap-northeast-1c.

FYI, Its stack id is arn:aws:cloudformation:ap-northeast-1:073730675998:stack/Sample-ECS-ContinuousDeployment-VPC-YMS9BWIDVHQG/ff016890-3e8e-11e7-9079-50fa13f1d0ad

Thanks

ECS Cluster Role not longer authorized to run cfn scripts

Ok, I don't know what happened, but I am planning a service based on this reference infrastructure and as of yesterday it worked like a charm.
But today the Initialization via CloudFormation stopped working at all. The Autoscaling Instances that make up the ECS Cluster seem not longer be authorized to send signals to CloudFormation. So instead of adding itself to the cluster they remain in the "default" cluster and the stack creation fails/times out. The managed role

AmazonEC2ContainerServiceforEC2Role

seem no longer be able to perform the necessary actions.
Dont know how to quickly fix that, just wanted to leave it here. The system log of the instances look like this

AccessDenied: User: arn:aws:sts::$AccountId:assumed-role/ecs-cluster-ECSRole-1U3Z9R13GFRX6/$InstanceId is not authorized to perform: cloudformation:DescribeStackResource on resource: arn:aws:cloudformation:eu-west-1:$AccountID:stack/ecs-cluster/*
AccessDenied: User: arn:aws:sts::$AccountId:assumed-role/ecs-cluster-ECSRole-1U3Z9R13GFRX6/$InstanceId is not authorized to perform: cloudformation:SignalResource on resource: arn:aws:cloudformation:eu-west-1:$AccountID:stack/ecs-cluster/*

Ok, just fyi I fixed it for now by adding an explicit access policy to cloudformation to the ECSRole with this configuration. Thats probably not following the "minimal permissions" policy but it works for now. I read the docs like that cfn-init and co would have automatic access to their respective stacks.

cloudformationAccessRole:
Type: AWS::IAM::Policy
Properties:
PolicyName: !Sub "${AWS::StackName}-cfn"
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "cloudformation:DescribeStackResource"
- "cloudformation:SignalResource"
Resource:
- "*"
Roles:
- !Ref ECSRole

Is it possible to use this architecture to deploy to ECS in another account?

I would like to use a similar architecture to deploy my application to ECS in another account, that way I would have the source (in my case, CodeCommit) and CodeBuild project in one account and the deployment on an ECS in another account. I found something similar in this article, but it uses CloudFormation to deploy to Lambda and since things can vary greatly from service to service, I decided to ask your opinions. Is it can be done with CodePipeline integration with ECS? If not, CloudFormation should work, right?
Thanks in advance for the help!

Service Template for ASP.NET Core 2.1 Container

I have a containerized ASP.NET Core 2.1 Web API with the following Dockerfile:

FROM microsoft/dotnet:2.1-sdk-alpine AS build

# Set working directory within container
WORKDIR /app

# Copy files
COPY ./src .

# Restore dependencies
RUN dotnet restore

# Build app
RUN dotnet publish -c Release -o dist

# Build runtime image
FROM microsoft/dotnet:2.1-aspnetcore-runtime-alpine AS runtime
COPY --from=build /app/dist .
ENTRYPOINT ["dotnet", "demo-netcore-api.dll"]

I need to update the TaskDefinition of service.yaml, but I need an example of the ContainerDefinitions section. Would you be able to tell me where I could find one?

Thanks.

Circular Dependency on ECR artifact

This is such a powerful architectural pattern, @jpignata - especially with Fargate.

I just wanted to make you aware of a circular dependency issue. I couldn't figure out an elegant workaround. Since you are creating a brand new ECR repository that will have zero artifacts until you do a successful build, the ECS service will never complete creation because the task can't move from PENDING to RUNNING state until it can pull the artifact from ECR. And, the Pipeline can't create yet because it needs an ECS service to deploy to.

The workaround I am currently using is to launch the CloudFormation template, then while the ECS Service is attempting to launch, doing a manual "docker build/tag/push" to the newly created ECR repository. Once there is an artifact to pull, the ECS service goes to CREATE_COMPLETE status and the Pipeline gets created.

This probably wouldn't be an issue if you're using a pre-existing ECR repository with at least 1 artifact.

Quick questions

Great reference arch!

Some questions about it

  • where should other services (RDS, SQS etc) be added?
  • how will the service be affected by updates in infrastructure (ecs-cluster.yaml, load-balancer.yaml). Will changing cluster instance type mean downtime for the service?

How to connect to a repo owned by a Github organization?

Thanks so much for this project. I am trying to adapt it to a project at work, and I'm having trouble getting CodePipeline to read from a repo owned by my company's Github org. Is there an organization-level equivalent of the personal access token? If that needs to be an OAuth token, where do I find it?

Ensure long IAM names do not cause failed deployments

[05/10/17 12:26 PM] Pierre: one thing: the first time I ran, I called the whole stack john-ecs-cd
[05/10/17 12:27 PM] Pierre: and this made CodeDeploy fail because the deployment CFn stack failed because the IAM role name was longer than 64 chars

Outdated S3 template file for service

Hello guys, there is a difference between the service template file in the S3 bucket referenced by the ecs-refarch-continuous-deployment.yaml file and the service template in the repo. The S3 bucket template file is looking for a Repsitory parameter you removed in the repo version. If you try to launch the stack you will get an error...

Version Control for Templates

How should one go about implementing version control for CF templates? For example, would it be possible to create a CodePipeline that connects to a GitHub repo where the templates are stored and then push files to an S3 bucket?

What do I do here? RocketShip is not intuitive...

On the Running the Example, Step Number 2 Create the CloudFormation stack what to do isn't totally intuitive. (I'm sitting in a class of folks who are this very minute going thru this example.)

image

<a href="https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/create/review?stackName=ECS-ContinuousDeployment&amp;templateURL=https://s3.amazonaws.com/ecs-refarch-continuous-deployment/ecs-refarch-continuous-deployment.yaml&amp;param_LaunchType=Fargate" rel="nofollow"><g-emoji class="g-emoji" alias="rocket" fallback-src="https://assets-cdn.github.com/images/icons/emoji/unicode/1f680.png" ios-version="6.0">πŸš€</g-emoji></a>

(with perfect hindsight, the answer is to right click on the rocketship then chose open in new tab..., but that's not intuitive...)

Recommend that the Rocketship icon be displayed includes the words click here πŸš€

Additionally recommend that target="_blank" be added to those series of links....

Reference architecture should be deployable to any region

#Feedback from Joshua:

I experimented with the code on GitHub. I’d suggest making more clear that the code work in us-east-1. There is a comment about launching the template in that region, but it wasn’t obvious to me it was a requirements until I launched it somewhere else and did some troubleshooting.

We should deploy the necessary template bucket to every region where all necessary services are available so a user could deploy this to regions outside of US East (N. Virginia).

Image tagging method cannot be used with container repository lifecycle policies

I am trying to setup a stack using you method of tagging images but adding in a container lifecycle policy on the repository to delete old images. Most images get tags so in order to delete them I am required to add a "tagPrefixList". adding a tag prefix list ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"] causes an "Internal Server Error" and timeout in cloudformation...

Here's a excerpt from my .yaml file:

ContainerRepository:
    Type: "AWS::ECR::Repository"
    Properties:
      RepositoryName: test-repository
      LifecyclePolicy:
        LifecyclePolicyText: |
          {
              "rules": [
                  {
                      "rulePriority": 1,
                      "description": "Keep only 20 untagged image, expire all others",
                      "selection": {
                          "tagStatus": "untagged",
                          "countType": "imageCountMoreThan",
                          "countNumber": 20
                      },
                      "action": {
                          "type": "expire"
                      }
                  },
                  {
                      "rulePriority": 2,
                      "description": "Keep only 20 tagged image, expire all others",
                      "selection": {
                          "tagStatus": "tagged",
                          "tagPrefixList": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"],
                          "countType": "imageCountMoreThan",
                          "countNumber": 20
                      },
                      "action": {
                          "type": "expire"
                      }
                  }
              ]
          }

no dockerfile

Is the intention that whoever consumes this example provide his/her own source code and dockerfile? I understood that it was a working example that could be modified.

It doesn't work when it's first forked as there is no code to build nor is there a dockerfile

template files in ap-northeast-1

Hi,

Thanks for the great material. We are from the ap-northeast-1 proserv.

SInce codebuild and codepipe are already available in ap-northeast-1 I was wondering if the templates files can be uploaded to the bucket in this region.

We would love to leverage this reference architecture with our customers. Having been asked by customers more and more regarding CICD and Container with managed services recently.

Thanks,
Lei Xu

How to update container environment variables

I'm switching my application's deployment to CodePipeline and the ECS. Is there a way using this API to update the container's environment variables? Previously I was using the CLI to register the task definition as follows:

export ENVIRONMENT=$(<environment.json)
aws ecs register-task-definition --family <family_name> --task-role-arn <iam_role> --container-definitions "$ENVIRONMENT"
aws ecs update-service --cluster <cluster_name> --service <service_name> --task-definition <family_name> --region us-west-2

And whatever variables were set in environment.json would be loaded into the container. I can't find any documentation describing how to set this using CloudFormation. Any ideas?

SSH login to the ec2 container instance.

Hi there,

Sorry for this stupid question...
I've successfully deployed ecs-demo-php-simple-app with these templates.

The ec2 container instance launched doesn't seem to have key-pair settings so I cannot login to the instance. ( I want to login and check log files in it. )

How can I modify templates so that the ec2 container instance gets its key-pair setting and I can login ?

Cheers

Is AssignPublicIp required for Fargate?

Hi there,

I'm new to ECS Fargate, and your template works great if I leave everything as default. However, I can't seem to bring up the Fargate task if I update this line to AssignPublicIp: DISABLED https://github.com/awslabs/ecs-refarch-continuous-deployment/blob/master/templates/service.yaml#L66

From my understanding, ALB uses the VPC internal IP for forwarding traffic. Why do we have to AssignPublicIp for the Fargate task? Or am I missing something else here?

Thanks!

Git parameters superfluous when image is hard coded

Hi,

Template very useful Thanks.

One issue when trying to re-use

  1. ecs-refarch-continuous-deployment.yaml has a bunch of parameters to supply your own repository. But .... within templates/service.yaml the amazon image is hard coded. When you switch to providing your own github project as parameters it actually has no effect (the amazon namespace is universally available in docker-hub. So what happens is you build your own project then use the amazon image at the last stage =) )
ContainerDefinitions:
        - Name: simple-app
          Image: amazon/amazon-ecs-sample
          EntryPoint:

I think it needs to be a parameter

  1. Second suggestion is not to override the entry point as part of the task def and allow the entry point provided as part of docker image to run by default

G

Wrong "path" in Launchconfiguration in /etc/cfn/hooks.d/cfn-auto-reloader.conf

Hello, I'm kind of new into the Cloudformation helper-scripts. Correct me if i'm wrong, but i realized that in the conf file "/etc/cfn/hooks.d/cfn-auto-reloader.conf" the path should point to the actual resource logical id (LaunchConfiguration) and it should look like this: path=Resources.LaunchConfiguration.Metadata.AWS::CloudFormation::Init

Thank you for uploading this project, it has helped me a lot.

Sorry for my English.

Regards from Chile.

<Cluster> | <Service Name> already exits

In the Deploy stage of my CD pipeline creates a TaskDefinition and Service in the ECS. I expect it recreates a TaskDefinition and update the Service when a new image has been pushed to ECR. However, the TaskDefinition was created but the Service failed to create and update because of the error.

| already exits

I haven't specify Service Name in the template. Just leave the Stack to figure out. So the Service Name is like -Service-XXXXXXX. Not sure what's wrong with it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.