Introduction
Voici comment déployer le projet Terraforming Mars de bafolts/terraforming-mars sur AWS en utilisant le service ECS.
Pré-requis
- Compte AWS avec accès à
- ECR
- ECS (Fargate)
- IAM
- CloudFormation
- EC2 Security Group
- VPC (vous pouvez utiliser celui par défaut)
- Docker installé localement (et à jour)
- AWS CLI installé et configuré (et à jour)
Étapes
- Création du fichier CloudFormation
- Création du ECR
- Commande Docker locale
- Tester le tout
Étape 1 - Le CloudFormation
- Cette configuration crée un cluster ECS nommé
TerraformingMarsCLuster
, - Puis 2 Roles IAM sont ajoutés.
- Pour lancer le conteneur, il faut une TaskDefinition, celle-ci est très simple et est basée sur la configuration par défaut Docker Setup.
- Ensuite un Security Group est créé pour laisser passer tout le traffic du port 8080 -> 8080 du conteneur.
- La dernière étape est de créer un service pour exposer le port 8080 de notre conteneur.
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:
- Clone le projet localement et navigue dans le root.
- Build l’image docker en utilisant le
Dockerfile
- Tag l’image locale avec le nom du repository créé à l’étape #2
- 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.)
- 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.
- Cliquer sur votre service (TM-service) dans votre Cluster,
- Cliquer ensuite sur Update
- Changer le desired tasks pour 1.
- Cliquer sur Skip review puis Update service
- Ensuite aller dans l’onglet Task
- Cliquer sur la task pour voir votre IP Public
Vous devriez être en mesure de vous connecter à cette adresse en utilisant le port 8080.
Notes
- Le load-balancer n’est pas configuré car nous jouons seulement entre ami.
- Le DNS peut être configuré, par contre vous devrez modifier le CloudFormation pour adapter le tout.
- N’oubliez pas d’arrêter le conteneur / changer le desired tasks pour 0 quand vous avez terminé. Autrement la machine va continuer de rouler.
- La configuration du CloudFormation est basée sur : 1Strategy/fargate-cloudformation-example
- Acheter le vrai jeu !
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