Webux Lab

Par Studio Webux

Déployez Terraforming Mars sur AWS avec Fargate

TG
Tommy Gingras Studio Webux S.E.N.C 2021-02-21

Introduction

Voici comment déployer le projet Terraforming Mars de bafolts/terraforming-mars sur AWS en utilisant le service ECS.

Pré-requis

Étapes

Étape 1 - Le CloudFormation

Cette configuration simpliste permet de lancer le conteneur de Terraforming Mars facilement pour jouer une partie entre ami.

Pour les paramètres, voir ci-dessous

ecs.yaml

AWSTemplateFormatVersion: '2010-09-09'

Parameters:
  ClusterName:
    Type: String
    Default: TerraformingMarsCluster

  ContainerPort:
    Type: Number
    Default: 8080

  ServiceName:
    Type: String
    Default: TM-service

  VPC:
    Type: AWS::EC2::VPC::Id
  SubnetA:
    Type: AWS::EC2::Subnet::Id
  SubnetB:
    Type: AWS::EC2::Subnet::Id

Resources:
  Cluster:
    Type: 'AWS::ECS::Cluster'
    Properties:
      ClusterName: !Ref ClusterName
      CapacityProviders:
        - FARGATE
        - FARGATE_SPOT
      DefaultCapacityProviderStrategy:
        - CapacityProvider: FARGATE
          Weight: 1
        - CapacityProvider: FARGATE_SPOT
          Weight: 1

  ExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Join ['', [!Ref ServiceName, ExecutionRole]]
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy'

  TaskRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: !Join ['', [!Ref ServiceName, TaskRole]]
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: 'sts:AssumeRole'

  TaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      RequiresCompatibilities:
        - 'FARGATE'
      Family: Terraforming-mars
      NetworkMode: awsvpc
      ExecutionRoleArn: !Ref ExecutionRole
      TaskRoleArn: !Ref TaskRole
      Cpu: '1024'
      Memory: '2048'
      ContainerDefinitions:
        - Name: 'terraforming-mars'
          MountPoints:
            - SourceVolume: 'tm-db'
              ContainerPath: '/usr/src/app/db'
          Image: !Sub '${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/terraforming-mars/boardgame:latest'

          PortMappings:
            - ContainerPort: !Ref ContainerPort
          LogConfiguration:
            LogDriver: awslogs
            Options:
              awslogs-region: !Ref AWS::Region
              awslogs-group: !Ref LogGroup
              awslogs-stream-prefix: ecs
      Volumes:
        - Name: 'tm-db'

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Join ['', [/ecs/, !Ref ServiceName, TaskDefinition]]

  ContainerSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Join ['', [!Ref ServiceName, ContainerSecurityGroup]]
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: !Ref ContainerPort
          ToPort: !Ref ContainerPort
          CidrIp: : 0.0.0.0/0

  Service:
    Type: AWS::ECS::Service
    Properties:
      ServiceName: !Ref ServiceName
      Cluster: !Ref Cluster
      TaskDefinition: !Ref TaskDefinition
      DesiredCount: 1
      LaunchType: FARGATE
      NetworkConfiguration:
        AwsvpcConfiguration:
          AssignPublicIp: ENABLED
          Subnets:
            - !Ref SubnetA
            - !Ref SubnetB
          SecurityGroups:
            - !Ref ContainerSecurityGroup

Étape 2 - Création du ECR

Pour pouvoir stocker l’image docker, il faut créer un repository en utilisant le service ECR.

aws ecr create-repository \
  --repository-name "terraforming-mars/boardgame"

Cette commande va créer un repository pouvant être utilisé de cette façon : ACCOUNT_ID.dkr.ecr.REGION.amazonaws.com/terraforming-mars/boardgame:latest

Étape 3 - Préparer l’image

Sur votre machine locale, vous devez cloner le projet Github et lancer les commandes suivantes,

Veuillez changer celles-ci pour vos informations.

ACCOUNT_ID=""
REGION=""
git clone https://github.com/bafolts/terraforming-mars.git

cd terraforming-mars/

docker build -t terraforming-mars .

docker tag terraforming-mars:latest $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/terraforming-mars/boardgame:latest

aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com

docker push $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/terraforming-mars/boardgame:latest

Ces commandes font:

  1. Clone le projet localement et navigue dans le root.
  2. Build l’image docker en utilisant le Dockerfile
  3. Tag l’image locale avec le nom du repository créé à l’étape #2
  4. Ce connecte au repository de AWS avec nos informations stocker (Cette étape nécessite le AWS CLI et bien sur, il doit être configuré. De plus si vous avez une erreur avec cette commande, assurez-vous de mettre à jour le AWS CLI et Docker.)
  5. L’image docker est poussé vers ECR.

Étape 4 - Déployer le tout sur AWS

Il suffit de lancer cette commande pour déployer nos resources:

Ce déploiement est nommé terraforming-mars-stack et il va déployer tout ce qui a été défini dans le fichier ecs.yaml

Vous devez bien sur changer le VPC id ainsi que les deux subnets pour vos informations.

aws cloudformation deploy \
  --template-file ./ecs.yaml \
  --stack-name terraforming-mars-stack \
  --capabilities CAPABILITY_NAMED_IAM \
  --parameter-overrides \
    VPC="vpc-12345678" \
    SubnetA="subnet-12323454" \
    SubnetB="subnet-12323453"

Changer la région de AWS pour la votre

Pour trouver l’information du VPC: https://ca-central-1.console.aws.amazon.com/vpc/home?region=ca-central-1#vpcs:
Pour trouver l’information de vos Subnets: https://ca-central-1.console.aws.amazon.com/vpc/home?region=ca-central-1#subnets:

Voici quelques captures d’écran,

ECS Cluster

ECS Service

Task Definition

Étape 5 - Lancer le conteneur

Il suffit de configurer le Desired tasks du service à 1.
De cette façon, une task va être lancée.
Vous allez être en mesure de vous connecter sur l’adresse IP public qui vous sera fourni.

Vous devriez être en mesure de vous connecter à cette adresse en utilisant le port 8080.

Notes


Ajout 2021-11-13

ACCOUNT_ID := YOUR_ACCOUNT_ID
REGION := YOUR_REGION
REPO_NAME := terraforming-mars
IMAGE_NAME := boardgame
VPC_ID := YOUR_VPC_ID
SUBNET_A := YOUR_SUBNET_ID
SUBNET_B := YOUR_SUBNET_ID

create_ecr:
	aws ecr create-repository \
  		--repository-name "${REPO_NAME}/${IMAGE_NAME}"

build:
	docker build --no-cache -t ${REPO_NAME} .

push:
	docker tag ${REPO_NAME}:latest ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${REPO_NAME}/${IMAGE_NAME}:latest
	aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com
	docker push ${ACCOUNT_ID}.dkr.ecr.${REGION}.amazonaws.com/${REPO_NAME}/${IMAGE_NAME}:latest

deploy_ecs_cluster:
	aws cloudformation deploy \
	--template-file ./ecs.yaml \
	--stack-name terraforming-mars-stack \
	--capabilities CAPABILITY_NAMED_IAM \
	--parameter-overrides \
		VPC="${VPC_ID}" \
		SubnetA="${SUBNET_A}" \
		SubnetB="${SUBNET_B}"

J’ai du changer le Dockerfile

node:14-alpine & python3

FROM node:14-alpine

EXPOSE 8080

LABEL maintainer="bafolts" \
      name="terraforming-mars" \
      Version="1.0"

RUN mkdir -p /usr/src/app/db \
   && addgroup -S tfm \
   && adduser -S -D -h /usr/src/app tfm tfm \
   && apk add --no-cache --virtual .gyp git python3 make g++

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY --chown=tfm:tfm . .

RUN npm run build  \
   && rm -rf .git \
   && apk del git .gyp

USER tfm

CMD [ "npm", "run", "start" ]

J’ai aussi du mettre à jour la version de sqlite3 dans le package.json à ^5.0.2


Recherche