Git Product home page Git Product logo

cdk-ecs-two-fargate-services's Introduction

ECS with two Fargate services using Spot

This repository contains the CDK project as a reference to deploy two services in Amazon Container Service using Fargate and Fargate Spot.

ECS with two Fargate services using Spot

Requirements for development environment

Work inside your AWS Cloud9 environment - Create an EC2 Environment

Install the latest version of CDK.

npm install -g aws-cdk --force

Install the Amazon ECS CLI, will be used to push the image docker to an Amazon ECR repository with the ecs-cli push command.

sudo curl -o /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-linux-amd64-latest
sudo chmod +x /usr/local/bin/ecs-cli
ecs-cli --version

Install OpenJDK 8.

sudo yum -y install java-1.8.0-openjdk-devel

Switch or upgrade the default Java development toolset to OpenJDK 8.

sudo update-alternatives --config java
sudo update-alternatives --config javac

For CodeCommit configuration, your AWS Cloud9 development environment already have IAM credentiales configured, use these credentials with the AWS CLI credential helper. Enable the credential helper by running the following two commands in the terminal of your Cloud9 environment.

git config --global credential.helper '!aws codecommit credential-helper $@'
git config --global credential.UseHttpPath true

Create the image containers for each service and push to Amazon ECR

Create a demo project only with Java 8 and "Spring Web" dependency. https://start.spring.io/

Modify the main Java application for demo (API: /)

package com.example.demo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class DemoApplication {
	
  @Value("${TARGET:World}")
  String target;

  @RestController
  class HelloworldController {
    @GetMapping("/")
    String hello() {
      System.out.println("Request...");
      return "Hello " + target + "!";
    }
  }

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

Build your application.

./mvnw package

Create a Dockerfile inside the project with the following content.

FROM openjdk:8-jdk-alpine
COPY target/demo-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

Build the docker image.

docker build -t workshop-api-1 .

Push the image to Amazon Elastic Container Registry. Before you need to have the repositories created by the CDK project.

ecs-cli push workshop-api-1

Create a buildspec.yml file as follows modifying the REPOSITORY_URI and CONTAINER_NAME with you own values.

version: 0.2
phases:
  install:
    runtime-versions:
      docker: 18
      java: openjdk8
    commands:
      - docker --version
      # Upgrade AWS CLI to the latest version
      - pip install --upgrade awscli
      - aws --version
      - java -version
  pre_build:
    commands:
      # Discover and run unit tests in the 'tests' directory
      - $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
      - REPOSITORY_URI=000000846002.dkr.ecr.us-west-2.amazonaws.com/workshop-api-1
      - CONTAINER_NAME=workshop-api-1
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      # Build
      - ls -la
      - mvn package -DskipTests
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      # Post Build
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - echo Write the image definitions file for ECS
      - printf '[{"name":"%s","imageUri":"%s"}]' $CONTAINER_NAME $REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
      - cat imagedefinitions.json
artifacts:
  files: imagedefinitions.json

Push the project to your CodeCommit repository.

Repeat the steps above the second service changing the service path and name services.

Update ECS cluster capacity provider to take advantage of Spot

# update your existing cluster with capacity providers support
CLUSTER_NAME=fargate
SERVICE1_NAME=service1
SERVICE2_NAME=service2
FARGATE_WEIGHT=1
FARGATE_SPOT_WEIGHT=1
FARGATE_BASE=1
FARGATE_SPOT_BASE=0

# update the existing cluster
aws ecs put-cluster-capacity-providers --cluster ${CLUSTER_NAME}  \
--capacity-providers FARGATE FARGATE_SPOT \
--default-capacity-provider-strategy capacityProvider=FARGATE_SPOT,weight=${FARGATE_SPOT_WEIGHT},base=${FARGATE_SPOT_BASE} \
capacityProvider=FARGATE,weight=${FARGATE_WEIGHT},base=${FARGATE_BASE}

# update existing service 1
aws ecs update-service --cluster ${CLUSTER_NAME} --service ${SERVICE1_NAME} \
--capacity-provider-strategy capacityProvider=FARGATE_SPOT,weight=${FARGATE_SPOT_WEIGHT},base=${FARGATE_SPOT_BASE} \
capacityProvider=FARGATE,weight=${FARGATE_WEIGHT},base=${FARGATE_BASE} --force-new-deployment

# update existing service 2
aws ecs update-service --cluster ${CLUSTER_NAME} --service ${SERVICE2_NAME} \
--capacity-provider-strategy capacityProvider=FARGATE_SPOT,weight=${FARGATE_SPOT_WEIGHT},base=${FARGATE_SPOT_BASE} \
capacityProvider=FARGATE,weight=${FARGATE_WEIGHT},base=${FARGATE_BASE} --force-new-deployment

# describe the service1 to see its capacityProviderStrategy
aws ecs describe-services --cluster ${CLUSTER_NAME} --service ${SERVICE1_NAME} --query 'services[0].capacityProviderStrategy'

# describe the service2 to see its capacityProviderStrategy
aws ecs describe-services --cluster ${CLUSTER_NAME} --service ${SERVICE2_NAME} --query 'services[0].capacityProviderStrategy'

cdk-ecs-two-fargate-services's People

Contributors

aurbac avatar

Watchers

James Cloos avatar

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.