Commit 5caffe2b authored by tlorreyte's avatar tlorreyte
Browse files

upload rules md

parent 83203d95
image: alpine:latest
pages:
stage: deploy
script:
- echo 'Create Gitlab Pages...'
artifacts:
paths:
- public
expire_in: 1 day
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
# Gameday Rules
Si vous arrivez ici c'est que nous essayons de corriger des problèmes techniques.
Nous faisons de notre mieux pour rétablir le jeu.
Pour patienter, vous trouverez ici les règles des différentes étapes.
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="GitLab Pages">
<title>GitLab Pages</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hello World!</h1>
<p>
This is a GitLab Pages test.
</p>
</body>
</html>
## Avant de commencer
**La région utilisée est l'Irlande : EU-WEST-1**
*Il vous est conseillé de mettre la console web AWS en anglais pour mieux suivre les indications.*
Vous disposez d'un VPC ouvert via une gateway internet, de 3 public subnets (un par Availability Zone), ainsi que d'une Route Table publique associée à votre VPC.
Vous possédez une application web qui tourne sur un EC2 grâce à deux conteneurs Docker gérés par docker-compose au démarrage de l'instance (script user_data que vous ré-utiliserez par la suite) :
- Un serveur web sur le port 80 (HTTP)
- Une base MySQL sur le port 3306
L'exécution du script user-data peut durer jusqu'à quelques minutes au démarrage puis l'app sera disponible sur l'adresse IP publique de l'EC2.
Cependant, elle ne fonctionnera pas si l'accès à la base MySQL est refusé (mauvaises règles security group, panne subite de votre fournisseur d'image MySQL... ).
Un security group accepte les entrées sur les ports 22 (SSH), 80 (HTTP) et 3306 (MySQL) pour votre application, n'hésitez pas à vous en servir !
Un rôle IAM (instance profile) nommé *<NOM_EQUIPE>-serverInstanceProfile* vous est fourni et sera nécessaire pour permettre
à votre EC2 d'accéder aux ressources AWS nécessaires.
Un mot de passe pour votre base de donnée vous a été généré dans le Secrets Manager avec le nom suivant : *<NOM_EQUIPE>-mysql-password*
![alt text](static/schema-init-01.jpg "Architecture AWS init")
> ## Objectif
>
> Votre entreprise décide de migrer son service vers le cloud pour des raisons de coûts et de performances.
> La direction technique vous demande de mettre en place une architecture la plus résiliente à la panne possible.
## Première étape
Vous pouvez démarrer votre web app en créant une nouvelle instance via EC2.
*Configuration nécessaire* :
- Amazon Linux 2 AMI
- t2.micro
- VPC : `<NOM_EQUIPE>-vpc`
- Public IP : enable
- IAM Role : `<NOM_EQUIPE>-serverInstanceProfile`
- User Data : copiez-collez le script User Data plus bas en *remplaçant UNIQUEMENT les valeurs `<NOM_EQUIPE>`*
- Security group : "existing security group" `<NOM_EQUIPE>-sg`
- Lancez ensuite l'EC2 sans key pair, vous pouvez également en créer une (pensez bien à la télécharger).
Après une minute environ, votre EC2 exposera sur le port 80 (HTTP) votre web app (adresse visible via l'ip publique). Il vous suffira de mettre à jour votre entrypoint dans le dashboard !
> ### TIPS 1
>
> Il vous est possible de vous connecter en SSH à vos instances pour débugger, utilisez "ec2 instant connect" (clic droit sur l'instance > Connect > EC2 Instance Connect) directement depuis AWS puis éxecutez la commande suivante dans l'EC2 pour voir les logs de votre container applicatif: `sudo docker logs server`.
> Le fichier de configuration docker-compose.yaml se trouve à la racine de la machine.
## Seconde étape
Une première solution proposée consiste à créer un *auto scaling group* qui permettrait de scaler horizontalement vos EC2. On estime qu'un nombre de 3 instances sera suffisant pour répondre aux demandes.
Cet ASG sera placé derrière un *application load balancer* qui permettra de rediriger l'ensemble des requêtes vers les instances marquées "Healthy". N'oubliez pas de mettre à jour votre *entrypoint* dans le dashboard !
Veillez à respecter les ressources nécessaires au fonctionnement de votre application sur EC2 listées dans *l'architecture fournie*.
> ### TIPS 2
>
> Sous "Advanced Details", renseigner le script user_data depuis la création de la launch configuration et le target group depuis la création de l'asg
### Architecture de la solution proposée
![alt text](static/archi-01.jpg "Architecture AWS solution")
> ### Reminder
>
> Votre web app utilise les ports HTTP 80 et MySQL 3306 pour fonctionner, ainsi que le profile d'instance EC2 : /NOM_EQUIPE\-serverInstanceProfile.
> N'oubliez pas d'investiguer les logs du container en cas de problèmes.
### Script User Data
```bash
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
sudo yum update -y
sudo yum install docker jq -y
service docker start
chkconfig docker on
# Docker-compose install
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# Login to ecr
$(aws ecr get-login --no-include-email --registry-ids 864169518175 --region eu-west-1)
# empty file if exists
:> ./docker-compose.yaml
# Docker compose file
cat <<'EOF' >>docker-compose.yaml
version: '3'
services:
server:
image: 864169518175.dkr.ecr.eu-west-1.amazonaws.com/team-server:latest
container_name: 'server'
depends_on:
- mysql
restart: always
ports:
- 80:3000
environment:
MYSQL_HOST: CONTAINER_IP
MYSQL_PASSWORD: 'HIDDEN_PASSWORD'
MYSQL_DATABASE: <NOM_EQUIPE>DB
MYSQL_USER: <NOM_EQUIPE>_user
mysql:
image: 864169518175.dkr.ecr.eu-west-1.amazonaws.com/mysql-57-centos7:latest
container_name: 'mysql'
restart: always
environment:
MYSQL_PASSWORD: 'HIDDEN_PASSWORD'
MYSQL_DATABASE: <NOM_EQUIPE>DB
MYSQL_USER: <NOM_EQUIPE>_user
ports:
- 3306:3306
EOF
# Get EC2 public ipv4 & sed into docker-compose
export IP_ADDRESS="$(curl http://169.254.169.254/latest/meta-data/public-ipv4)"
sed -i "s/CONTAINER_IP/$IP_ADDRESS/g" docker-compose.yaml
# Get secret value from secret ID & sed into docker-compose to avoid clear pwds in user-data.sh
export MYSQL_PASSWORD="$(aws secretsmanager get-secret-value --secret-id <NOM_EQUIPE>-mysql-password --region eu-west-1 | jq -r '.SecretString')"
sed -i "s/HIDDEN_PASSWORD/$MYSQL_PASSWORD/g" docker-compose.yaml
# Pull (fetch latest in case of reboot) & start service
sudo docker-compose pull && docker-compose up
--//
```
> ## Objectif
>
> Votre provider d'image Docker MySQL vous informe que cette dernière a été corrompue !
> Il vous conseille alors de mettre en place une base RDS directement sur AWS et d'actualiser le script 'user_data' de vos instances EC2 avec celui qu'il vous fournit [(voir plus bas)](#script-user-data-).
> La direction vous impose de placer votre base dans un DB subnet group qui sera situé dans des subnets privés de votre VPC (2 suffiront), à créer en amont de la base.
[Cet outil vous facilite le calcul de vos CIDR.](http://www.davidc.net/sites/default/subnets/subnets.html)
Votre provider vous rappelle de bien renseigner les champs suivants lors de la création de votre base RDS avec les valeurs suivantes :
- Base MySQL Free Tier en version 5.7.XX, vous n'êtes autorisé qu'à utiliser une db.t2.micro
- Master username: \<NOM>_user
- Master password: secret value de votre password généré depuis AWS secretsmanager
- Initial database name (visible depuis additional configuration): \<NOM>DB
> ### ATTENTION
>
> Pensez à bien remplacer les valeurs dans le script user_data :
>
> - \<NOM> (l.49, l.50 & l.55)
> - <ENDPOINT_DE_VOTRE_BASE_RDS> (l.48)
> ### TIPS
>
> Le security group RDS créé par AWS n'accepte que les entrées depuis votre IP, penser à ouvrir le CIDR du port 3306
### Architecture solution
![alt text](static/archi-02.jpg "Architecture AWS solution")
### Script user data
```shell
Content-Type: multipart/mixed; boundary="//"
MIME-Version: 1.0
--//
Content-Type: text/cloud-config; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="cloud-config.txt"
#cloud-config
cloud_final_modules:
- [scripts-user, always]
--//
Content-Type: text/x-shellscript; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="userdata.txt"
#!/bin/bash
sudo yum update -y
sudo yum install docker jq -y
sudo service docker start
sudo chkconfig docker on
# Docker-compose install
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# Login to ecr
$(aws ecr get-login --no-include-email --registry-ids 864169518175 --region eu-west-1)
# empty file if exists
:> ./docker-compose.yaml
# Docker compose file
cat <<'EOF' >>docker-compose.yaml
version: '3'
services:
server:
image: 864169518175.dkr.ecr.eu-west-1.amazonaws.com/team-server:latest
container_name: 'server'
restart: always
ports:
- 80:3000
environment:
MYSQL_HOST: <ENDPOINT_DE_VOTRE_BASE_RDS>
MYSQL_USER: <NOM_EQUIPE>_user
MYSQL_DATABASE: <NOM_EQUIPE>DB
MYSQL_PASSWORD: 'HIDDEN_PASSWORD'
EOF
# Get secret value from secret ID & sed into docker-compose to avoid clear pwds in user-data.sh
export MYSQL_PASSWORD="$(aws secretsmanager get-secret-value --secret-id <NOM_EQUIPE>-mysql-password --region eu-west-1 | jq -r '.SecretString')"
sed -i "s/HIDDEN_PASSWORD/$MYSQL_PASSWORD/g" docker-compose.yaml
# Start service
sudo docker-compose up
--//
```
> ## Objectif
>
> Les security groups fournis possèdent des règles ouvertes à tous qui peuvent entraîner de potentielles intrusions.
> Votre expert sécurité vous avise de modifier votre architecture pour satisfaire les normes de sécurité que recommande AWS.
Vous placerez donc votre auto scaling group dans des subnets privés et seul le load balancer sera placé dans des subnets publics spour permettre l'accès au port 80 (HTTP) depuis 0.0.0.0/0.
Vos instances EC2 nécessitent un accès internet pour récupérer les images docker, pensez à ajouter une NAT gateway reliée à un de vos subnet public qui fournira l'accès à la route table de vos subnets privés.
### Architecture solution
![alt text](static/archi-03.jpg "Architecture AWS solution")
> ## Objectif
>
> La direction technique se rend compte que la solution mise en place avec des EC2 est trop coûteuse et souhaiterait utiliser des containers avec Fargate, un service de Elastic Container Service (ECS).
> On vous demande alors de mettre en place un cluster ECS "networking only", un service avec une task associée qui vous permettra d'éxecuter l'image contenue dans le repository ECR nommé "864169518175.dkr.ecr.eu-west-1.amazonaws.com/team-server".
Les équipes techniques vous conseillent une task definition avec :
- 1024 RAM
- 0.5 vCPU
- Container definition sur le port 3000
Vous souhaitez également conserver les normes de sécurité que vous avez mises en place auparavant, cependant, on vous informe
que les subnets privés où résideront vos containers doivent avoir un accès internet pour tirer l'image docker du repository.
Pensez à avoir une NAT gateway (si ce n'est pas déjà fait) pour avoir cet accès internet.
Vous devez renseigner les variables d'environment suivantes lors de la création de la task de votre service :
- MYSQL_HOST: endpoint de votre base RDS
- MYSQL_USER: \<NOM>_user
- MYSQL_DATABASE: \<NOM>DB
- MYSQL_PASSWORD: secret value de votre mdp dans AWS secrets manager
> ### TIPS
>
> Créer un target group qui pointe sur les IP et non sur les instances, sur le port du container
### Architecture solution
![alt text](static/archi-04.jpg "Architecture AWS solution")
> ## Objectif
>
> La direction technique souhaiterait se lancer dans le serverless avec des lambdas.
On vous demande de mettre en place une API REST publique avec deux routes :
- GET api/requests : pour obtenir un json listant depuis la base RDS les requêtes précédemment traitées
- POST api/requests : pour enregistrer une nouvelle requête dans la base RDS
A chaque route est associée une lambda :
- GET api/requests : appelle la fonction get_requests
- POST api/requests : appelle la fonction post_requests
Vous devez renseigner les variables d'environment suivantes lors de la création de la lambda :
- MYSQL_HOST: endpoint de votre base RDS
- MYSQL_USER: /NOM_EQUIPE\_user
- MYSQL_DATABASE: /NOM_EQUIPE\db
- SECRET_MANAGER_SECRET_ID: le secret id qui permet de retrouver le mot de passe de la base de données
### Architecture de la solution
![alt text](static/archi-05.jpg "Architecture AWS solution")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment