1659993060
Dans ce didacticiel, nous allons parcourir le processus de déploiement d'une application Flask sur AWS Elastic Beanstalk.
À la fin de ce didacticiel, vous serez en mesure de :
AWS Elastic Beanstalk (EB) est un service facile à utiliser pour le déploiement et la mise à l'échelle des applications Web. Il connecte plusieurs services AWS, comme les instances de calcul ( EC2 ), les bases de données ( RDS ), les équilibreurs de charge ( Application Load Balancer ) et les systèmes de stockage de fichiers ( S3 ), pour n'en nommer que quelques-uns. EB vous permet de développer et de déployer rapidement votre application Web sans vous soucier de l'infrastructure sous-jacente. Il prend en charge les applications développées en Go, Java, .NET, Node.js, PHP, Python et Ruby. EB prend également en charge Docker si vous avez besoin de configurer votre propre pile logicielle ou de déployer une application développée dans un langage (ou une version) qu'EB ne prend pas actuellement en charge.
Configuration typique d'Elastic Beanstalk :
Il n'y a pas de frais supplémentaires pour AWS Elastic Beanstalk. Vous ne payez que les ressources consommées par votre application.
Pour en savoir plus sur Elastic Beanstalk, consultez Qu'est-ce qu'AWS Elastic Beanstalk ? à partir de la documentation officielle d'AWS Elastic Beanstalk .
Avant de plonger dans le didacticiel lui-même, examinons quelques concepts clés liés à Elastic Beanstalk :
Ces termes seront utilisés tout au long du didacticiel.
Nous allons déployer une application Flask simple appelée flask-movies dans ce didacticiel.
Vérifiez votre compréhension en déployant votre propre application tout en suivant le didacticiel.
Tout d'abord, récupérez le code du référentiel sur GitHub :
$ git clone git@github.com:duplxey/flask-movies.git
$ cd flask-movies
Créez un nouvel environnement virtuel et activez-le :
$ python3 -m venv venv && source venv/bin/activate
Installez la configuration requise et initialisez la base de données :
(venv)$ pip install -r requirements.txt
(venv)$ python init_db.py
Exécutez le serveur :
(venv)$ flask run
Ouvrez votre navigateur Web préféré et accédez à :
Assurez-vous de créer un compte AWS avant de continuer. En créant un compte, vous pouvez également être éligible à l' offre gratuite d'AWS .
L' interface de ligne de commande Elastic Beanstalk (EB CLI) vous permet d'effectuer diverses opérations pour déployer et gérer vos applications et environnements Elastic Beanstalk.
Il existe deux manières d'installer l'interface de ligne de commande EB :
Il est recommandé d'installer l'interface de ligne de commande EB globalement (en dehors de tout environnement virtuel spécifique) à l'aide du programme d'installation (première option) pour éviter d'éventuels conflits de dépendance. Reportez-vous à cette explication pour plus de détails.
Après avoir installé l'interface de ligne de commande EB, vous pouvez vérifier la version en exécutant :
$ eb --version
EB CLI 3.20.3 (Python 3.10.)
Si la commande ne fonctionne pas, vous devrez peut-être ajouter l'interface de ligne de commande EB à $PATH
.
Une liste des commandes EB CLI et leurs descriptions se trouvent dans la référence des commandes EB CLI .
Une fois que l'interface de ligne de commande EB est en cours d'exécution, nous pouvons commencer à interagir avec Elastic Beanstalk. Initialisons un nouveau projet avec un environnement EB.
Dans la racine du projet ("flask-movies"), exécutez :
$ eb init
Un certain nombre de questions vous seront posées.
La région AWS de votre environnement (et ressources) Elastic Beanstalk. Si vous n'êtes pas familier avec les différentes régions AWS, consultez Régions et zones de disponibilité AWS . En règle générale, vous devez choisir la région la plus proche de vos clients. Gardez à l'esprit que les prix des ressources varient d'une région à l'autre.
Il s'agit du nom de votre application Elastic Beanstalk. Je recommande simplement d'appuyer sur Entrée et d'utiliser la valeur par défaut : "flask-movies".
L'interface de ligne de commande EB détectera que vous utilisez un environnement Python. Après cela, il vous donnera différentes versions Python et versions Amazon Linux avec lesquelles vous pourrez travailler. Choisissez "Python 3.8 s'exécutant sur Amazon Linux 2 64 bits".
CodeCommit est un service de contrôle de code source sécurisé, hautement évolutif et géré qui héberge des référentiels Git privés. Nous ne l'utiliserons pas car nous utilisons déjà GitHub pour le contrôle des sources. Alors dites "non".
Pour nous connecter ultérieurement aux instances EC2, nous devons configurer SSH. Dites "oui" lorsque vous y êtes invité.
Pour se connecter aux instances EC2, nous aurons besoin d'une paire de clés RSA. Allez-y et générez-en un, qui sera ajouté à votre dossier "~/.ssh".
Après avoir répondu à toutes les questions, vous remarquerez un répertoire caché à l'intérieur de la racine de votre projet nommé ".elasticbeanstalk". Le répertoire doit contenir un fichier config.yml , avec toutes les données que vous venez de fournir.
.elasticbeanstalk
└── config.yml
Le fichier doit contenir quelque chose de similaire à :
branch-defaults:
master:
environment: null
group_suffix: null
global:
application_name: flask-movies
branch: null
default_ec2_keyname: aws-eb
default_platform: Python 3.8 running on 64bit Amazon Linux 2
default_region: us-west-2
include_git_submodules: true
instance_profile: null
platform_name: null
platform_version: null
profile: eb-cli
repository: null
sc: git
workspace_type: Application
Ensuite, créons l'environnement Elastic Beanstalk et déployons l'application :
$ eb create
Encore une fois, vous serez invité à poser quelques questions.
Ceci représente le nom de l'environnement EB. Je vous recommande de vous en tenir à la valeur par défaut : "flask-movies-env".
Il est recommandé d'ajouter
└-env
ou└-dev
de suffixer à vos environnements afin de pouvoir différencier facilement les applications EB des environnements.
Votre application Web sera accessible à l'adresse %cname%.%region%.elasticbeanstalk.com
. Encore une fois, utilisez la valeur par défaut.
Un équilibreur de charge répartit le trafic entre les instances de votre environnement. Sélectionnez "candidature".
Si vous souhaitez en savoir plus sur les différents types d'équilibreur de charge, consultez Équilibreur de charge pour votre environnement Elastic Beanstalk .
Les requêtes Spot Fleet vous permettent de lancer des instances à la demande en fonction de vos critères. Nous ne les utiliserons pas dans ce didacticiel, alors dites "non".
--
Avec cela, l'environnement sera animé :
Une nouvelle application sera également déployée.
Cela prendra environ trois minutes, alors n'hésitez pas à prendre une tasse de café.
Une fois le déploiement terminé, l'interface de ligne de commande EB modifiera .elasticbeanstalk/config.yml .
La structure de votre projet devrait maintenant ressembler à ceci :
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Une fois que vous avez déployé votre application, vous pouvez vérifier son état en exécutant :
$ eb status
Environment details for: flask-movies-env
Application name: flask-movies
Region: us-west-2
Deployed Version: app-82fb-220311_171256090207
Environment ID: e-nsizyek74z
Platform: arn:aws:elasticbeanstalk:us-west-2::platform/Python 3.8 running on 64bit Amazon Linux 2/3.3.11
Tier: WebServer-Standard-1.0
CNAME: flask-movies-env.us-west-2.elasticbeanstalk.com
Updated: 2022-03-11 23:16:03.822000+00:00
Status: Launching
Health: Red
Vous pouvez voir que la santé actuelle de notre environnement est Red
, ce qui signifie que quelque chose s'est mal passé. Ne vous en faites pas pour l'instant, nous y remédierons dans les prochaines étapes.
Vous pouvez également voir qu'AWS nous a attribué un CNAME qui est le nom de domaine de notre environnement EB. Nous pouvons accéder à l'application Web en ouvrant un navigateur et en naviguant vers le CNAME.
$ eb open
Cette commande ouvrira votre navigateur par défaut et naviguera vers le domaine CNAME. Vous verrez 502 Bad Gateway
, que nous allons corriger ici sous peu
$ eb console
Cette commande ouvrira la console Elastic Beanstalk dans votre navigateur par défaut :
Encore une fois, vous pouvez voir que la santé de l'environnement est "sévère", ce que nous corrigerons à l'étape suivante.
À l'étape précédente, nous avons essayé d'accéder à notre application et celle-ci a renvoyé 502 Bad Gateway
. Il y a deux raisons derrière cela :
PYTHONPATH
pour trouver des modules dans notre application.Par défaut, Elastic Beanstalk sert les applications Python avec Gunicorn . EB installe automatiquement Gunicorn dans le processus de déploiement, nous n'avons donc pas à l'ajouter à requirements.txt . Si vous souhaitez échanger Gunicorn avec autre chose, jetez un œil à Configuration du serveur WSGI avec un Procfile .
Corrigeons ces erreurs.
Créez un nouveau dossier à la racine du projet appelé ".ebextensions". Dans le dossier nouvellement créé, créez un fichier nommé 01_flask.config :
# .ebextensions/01_flask.config
option_settings:
aws:elasticbeanstalk:application:environment:
PYTHONPATH: "/var/app/current:$PYTHONPATH"
aws:elasticbeanstalk:container:python:
WSGIPath: "app:app"
Remarques:
PYTHONPATH
chemin Python sur notre instance EC2 ( docs ).WSGIPath
par notre application WSGI ( docs ).Comment fonctionnent les fichiers EB .config ?
- Vous pouvez en avoir autant que vous le souhaitez.
- Ils sont chargés dans l'ordre suivant : 01_x, 02_x, 03_x, etc.
- Vous n'avez pas besoin de mémoriser ces paramètres ; vous pouvez répertorier tous vos paramètres environnementaux en exécutant
eb config
.Si vous souhaitez en savoir plus sur la personnalisation avancée de l'environnement, consultez Personnalisation avancée de l'environnement avec les fichiers de configuration .
Ensuite, nous devons indiquer à Elastic Beanstalk d'initialiser la base de données lorsqu'une nouvelle version de l'application est déployée. Ajoutez ce qui suit à la fin de .ebextensions/01_flask.config :
# .ebextensions/01_flask.config
container_commands:
01_initdb:
command: "source /var/app/venv/*/bin/activate && python3 init_db.py"
leader_only: true
L'environnement EB exécutera désormais la commande ci-dessus chaque fois que nous déployons une nouvelle version de l'application. Nous avons utilisé leader_only
, donc seule la première instance EC2 les exécute (au cas où notre environnement EB exécute plusieurs instances EC2).
Les configurations Elastic Beanstalk prennent en charge deux sections de commande différentes, les commandes et les conteneur_commands . La principale différence entre eux réside dans le moment où ils sont exécutés dans le processus de déploiement :
commands
exécuté avant que l'application et le serveur Web ne soient configurés et que le fichier de version de l'application ne soit extrait.container_commands
exécuté après la configuration de l'application et du serveur Web et l'extraction de l'archive de la version de l'application, mais avant le déploiement de la version de l'application (avant que les fichiers ne soient déplacés du dossier intermédiaire vers leur emplacement final).
À ce stade, la structure de votre projet devrait ressembler à ceci :
|-- .ebextensions
| └-- 01_flask.config
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Validez les modifications sur git et déployez :
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Vous remarquerez qu'Elastic Beanstalk ne détectera pas les modifications si vous ne vous engagez pas. En effet, EB s'intègre à git et ne détecte que les fichiers validés (modifiés).
Une fois le déploiement terminé, exécutez eb open
pour voir si tout a fonctionné. Après cela, ajoutez /api/movies
à l'URL pour voir si les films sont toujours affichés.
Yay! La première version de notre application est maintenant déployée.
Si vous déployez flask-movies , vous remarquerez qu'il utilise une base de données SQLite par défaut. Bien que cela soit parfait pour le développement, vous souhaiterez généralement passer à une base de données plus robuste, comme Postgres ou MySQL, pour la production. Voyons comment échanger SQLite contre Postgres .
Tout d'abord, lançons Postgres en local. Vous pouvez soit le télécharger à partir des téléchargements PostgreSQL , soit créer un conteneur Docker :
$ docker run --name flask-movies-postgres -p 5432:5432 \
-e POSTGRES_USER=flask-movies -e POSTGRES_PASSWORD=complexpassword123 \
-e POSTGRES_DB=flask-movies -d postgres
Vérifiez si le conteneur est en cours d'exécution :
$ docker ps -f name=flask-movies-postgres
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c05621dac852 postgres "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp flask-movies-postgres
Maintenant, essayons de nous y connecter avec notre application Flask.
Changez à l' SQLALCHEMY_DATABASE_URI
intérieur de app.py comme ceci :
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username='flask-movies',
password='complexpassword123',
host='localhost',
port='5432',
database='flask-movies',
)
Ensuite, installez psycopg2-binary , qui est requis pour Postgres :
(venv)$ pip install psycopg2-binary==2.9.3
Ajoutez-le à requirements.txt :
Flask==2.0.3
Flask-SQLAlchemy==2.5.1
psycopg2-binary==2.9.3
Supprimez la base de données existante, default.db , puis initialisez la nouvelle base de données :
(venv)$ python init_db.py
Exécutez le serveur :
(venv)$ flask run
Assurez-vous que les films sont toujours correctement diffusés en consultant http://localhost:5000/api/movies .
Pour configurer Postgres pour la production, commencez par exécuter la commande suivante pour ouvrir la console AWS :
$ eb console
Cliquez sur "Configuration" dans la barre de gauche, faites défiler jusqu'à "Base de données", puis cliquez sur "Modifier".
Créez une BD avec les paramètres suivants et cliquez sur "Appliquer":
Si vous souhaitez rester dans l' offre gratuite d'AWS, assurez-vous de choisir db.t2.micro. Les prix RDS augmentent de manière exponentielle en fonction de la classe d'instance que vous choisissez. Si vous ne souhaitez pas utiliser,
micro
assurez-vous de consulter la tarification AWS PostgreSQL .
Une fois la mise à jour environnementale effectuée, EB transmettra automatiquement les informations d'identification DB suivantes à notre application flask :
RDS_DB_NAME
RDS_USERNAME
RDS_PASSWORD
RDS_HOSTNAME
RDS_PORT
Nous pouvons maintenant utiliser ces variables dans app.py pour nous connecter à notre base de données :
if 'RDS_DB_NAME' in os.environ:
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username=os.environ['RDS_USERNAME'],
password=os.environ['RDS_PASSWORD'],
host=os.environ['RDS_HOSTNAME'],
port=os.environ['RDS_PORT'],
database=os.environ['RDS_DB_NAME'],
)
else:
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username='flask-movies',
password='complexpassword123',
host='localhost',
port='5432',
database='flask-movies',
)
N'oubliez pas d'importer le os
package en haut de app.py :
import os
Validez les modifications sur git et déployez :
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Attendez que le déploiement se termine. Une fois cela fait, exécutez eb open
pour ouvrir votre application dans un nouvel onglet du navigateur. Assurez-vous que tout fonctionne toujours correctement en répertoriant les films sur /api/movies
.
Cette partie du tutoriel nécessite que vous disposiez d'un nom de domaine.
Besoin d'un domaine pas cher pour vous entraîner ? Plusieurs bureaux d'enregistrement de domaine ont des promotions sur les domaines '.xyz'. Alternativement, vous pouvez créer un domaine gratuit chez Freenom . Si vous ne possédez pas de nom de domaine, mais souhaitez tout de même utiliser HTTPS, vous pouvez créer et signer avec un certificat X509 .
Pour servir votre application via HTTPS, nous devrons :
Accédez à la console AWS Certificate Manager . Cliquez sur "Demander un certificat". Définissez le type de certificat sur "Public" et cliquez sur "Suivant". Entrez votre nom de domaine complet dans la saisie du formulaire, définissez la "Méthode de validation" sur "Validation DNS", puis cliquez sur "Demander".
Vous serez alors redirigé vers une page où vous pourrez voir tous vos certificats. Le certificat que vous venez de créer doit avoir le statut "En attente de validation".
Pour qu'AWS délivre un certificat, vous devez d'abord prouver que vous êtes le propriétaire du domaine. Dans le tableau, cliquez sur le certificat pour afficher les "Détails du certificat". Notez le "nom CNAME" et la "valeur CNAME". Pour valider la propriété du domaine, vous devrez créer un "enregistrement CNAME" dans les paramètres DNS de votre domaine. Utilisez le "nom CNAME" et la "valeur CNAME" pour cela. Une fois cela fait, il faudra quelques minutes à Amazon pour récupérez les modifications de domaine et émettez le certificat. Le statut doit passer de "En attente de validation" à "Émis".
Ensuite, vous devez faire pointer votre domaine (ou sous-domaine) vers votre environnement EB CNAME. De retour dans les paramètres DNS de votre domaine, ajoutez un autre enregistrement CNAME avec la valeur correspondant à votre EB CNAME -- par exemple, flask-movies-dev.us-west-2.elasticbeanstalk.com
.
Attendez quelques minutes que votre DNS se rafraîchisse avant de tester les choses à partir de la http://
saveur de votre nom de domaine dans votre navigateur.
De retour dans la console Elastic Beanstalk, cliquez sur « Configuration ». Ensuite, dans la catégorie "Load balancer", cliquez sur "Edit". Cliquez sur "Ajouter un écouteur" et créez un écouteur avec les détails suivants :
Cliquez sur "Ajouter". Ensuite, faites défiler vers le bas de la page et cliquez sur "Appliquer". La mise à jour de l'environnement prendra quelques minutes.
Ensuite, nous devons apporter quelques modifications à notre application Flask.
Nous devons rediriger tout le trafic de HTTP vers HTTPS. Il existe plusieurs façons de procéder, mais la plus simple consiste à configurer Apache en tant qu'hôte proxy. Nous pouvons y parvenir par programmation en ajoutant ce qui suit à la fin de option_settings
in .ebextensions/01_flask.config :
# .ebextensions/01_flask.config
option_settings:
# ...
aws:elasticbeanstalk:environment:proxy: # new
ProxyServer: apache # new
Votre fichier final 01_flask.config devrait maintenant ressembler à ceci :
# .ebextensions/01_flask.config
option_settings:
aws:elasticbeanstalk:application:environment:
PYTHONPATH: "/var/app/current:$PYTHONPATH"
aws:elasticbeanstalk:container:python:
WSGIPath: "app:app"
aws:elasticbeanstalk:environment:proxy:
ProxyServer: apache
container_commands:
01_initdb:
command: "source /var/app/venv/*/bin/activate && python3 init_db.py"
leader_only: true
Créez ensuite un dossier ".platform" à la racine du projet et ajoutez les fichiers et dossiers suivants :
└-- .platform
└-- httpd
└-- conf.d
└-- ssl_rewrite.conf
ssl_rewrite.conf :
# .platform/httpd/conf.d/ssl_rewrite.conf
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
La structure de votre projet devrait maintenant ressembler à ceci :
|-- .ebextensions
| └-- 01_flask.config
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- .platform
| └-- httpd
| └-- conf.d
| └-- ssl_rewrite.conf
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Validez les modifications sur git et déployez :
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Maintenant, dans votre navigateur, la https://
saveur de votre application devrait fonctionner. Essayez d'aller à la http://
saveur. Vous devriez être redirigé vers la https://
saveur. Assurez-vous également que le certificat est correctement chargé :
En production, il est préférable de stocker la configuration spécifique à l'environnement dans des variables d'environnement . Avec Elastic Beanstalk, vous pouvez définir des variables d'environnement personnalisées de deux manières différentes.
Transformons notre flacon SECRET_KEY
en une variable environnementale.
Commencez par exécuter :
$ eb setenv FLASK_SECRET_KEY='<replace me with your own secret key>'
Vous pouvez définir plusieurs variables d'environnement avec une seule commande en les séparant par des espaces. Il s'agit de l'approche recommandée car elle n'entraîne qu'une seule mise à jour de l'environnement EB.
Modifiez app.pySECRET_KEY
en conséquence :
# app.py
app.config['SECRET_KEY'] = os.environ.get(
'FLASK_SECRET_KEY',
'<replace me with your own fallback secret key>'
)
Validez les modifications sur git et déployez :
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Accédez à la console Elastic Beanstalk via eb open
. Accédez à "Configuration" > "Logiciel" > "Modifier". Ensuite, faites défiler jusqu'aux "Propriétés de l'environnement".
Une fois que vous avez terminé, cliquez sur "Appliquer" et votre environnement sera mis à jour.
Vous pouvez ensuite accéder à ces variables dans votre environnement Python via os.environ
.
Par exemple:
VARIABLE_NAME = os.environ['VARIABLE_NAME']
Lorsque vous travaillez avec Elastic Beanstalk, il peut être assez frustrant de comprendre ce qui ne va pas si vous ne savez pas comment accéder aux fichiers journaux. Dans cette section, nous n'examinerons que cela.
Il existe deux façons d'accéder aux journaux :
Par expérience personnelle, j'ai pu résoudre tous les problèmes avec la première approche.
CLI :
$ eb logs
Cette commande récupère les 100 dernières lignes des fichiers suivants :
/var/log/web.stdout.log
/var/log/eb-hooks.log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/eb-engine.log
L'exécution
eb logs
équivaut à se connecter à la console EB et à naviguer vers "Journaux".
Je recommande de diriger les journaux vers CloudWatch . Exécutez la commande suivante pour l'activer :
$ eb logs --cloudwatch-logs enable
Vous trouverez généralement des erreurs Flask dans /var/log/web.stdout.log ou /var/log/eb-engine.log .
Pour en savoir plus sur les journaux Elastic Beanstalk, consultez Affichage des journaux des instances Amazon EC2 .
Pour vous connecter à une instance EC2 sur laquelle votre application Flask est en cours d'exécution, exécutez :
$ eb ssh
Vous serez invité à ajouter l'hôte à vos hôtes connus la première fois. Dis oui. Avec cela, vous aurez désormais un accès complet à votre instance EC2. N'hésitez pas à vérifier certains des fichiers journaux mentionnés dans la section précédente.
Gardez à l'esprit qu'Elastic Beanstalk met automatiquement à l'échelle et déploie de nouvelles instances EC2. Les modifications que vous apportez à cette instance EC2 spécifique ne seront pas répercutées sur les instances EC2 nouvellement lancées. Une fois cette instance EC2 spécifique remplacée, vos modifications seront effacées.
Dans ce didacticiel, nous avons parcouru le processus de déploiement d'une application Flask sur AWS Elastic Beanstalk. Vous devriez maintenant avoir une bonne compréhension du fonctionnement d'Elastic Beanstalk. Effectuez une auto-vérification rapide en passant en revue les objectifs au début du didacticiel.
Prochaines étapes:
dev
et production
).Pour supprimer toutes les ressources AWS que nous avons créées tout au long du didacticiel, arrêtez d'abord l'environnement Elastic Beanstalk :
$ eb terminate
Vous devrez supprimer manuellement le certificat SSL.
Enfin, vous pouvez trouver la version finale du code dans le référentiel flask-elastic-beanstalk sur GitHub.
Source : https://testdrive.io
1619205540
In this piece, I’ll be demonstrating how AWS Elastic Beanstalk can simplify deployments by doing all the hard work for you – and with no risk of downtime – by employing a Blue/Green deployment strategy.
Using AWS means combining a large number of tools to complete projects. Personally, I choose to streamline this process by using Elastic Beanstalk, as it enables me and the rest of the dev team to control the AWS resources which power the applications we support and gives us full access to the underlying resources at any time.
#cloud #aws #elastic beanstalk #aws tools #aws elastic beanstalk
1659993060
Dans ce didacticiel, nous allons parcourir le processus de déploiement d'une application Flask sur AWS Elastic Beanstalk.
À la fin de ce didacticiel, vous serez en mesure de :
AWS Elastic Beanstalk (EB) est un service facile à utiliser pour le déploiement et la mise à l'échelle des applications Web. Il connecte plusieurs services AWS, comme les instances de calcul ( EC2 ), les bases de données ( RDS ), les équilibreurs de charge ( Application Load Balancer ) et les systèmes de stockage de fichiers ( S3 ), pour n'en nommer que quelques-uns. EB vous permet de développer et de déployer rapidement votre application Web sans vous soucier de l'infrastructure sous-jacente. Il prend en charge les applications développées en Go, Java, .NET, Node.js, PHP, Python et Ruby. EB prend également en charge Docker si vous avez besoin de configurer votre propre pile logicielle ou de déployer une application développée dans un langage (ou une version) qu'EB ne prend pas actuellement en charge.
Configuration typique d'Elastic Beanstalk :
Il n'y a pas de frais supplémentaires pour AWS Elastic Beanstalk. Vous ne payez que les ressources consommées par votre application.
Pour en savoir plus sur Elastic Beanstalk, consultez Qu'est-ce qu'AWS Elastic Beanstalk ? à partir de la documentation officielle d'AWS Elastic Beanstalk .
Avant de plonger dans le didacticiel lui-même, examinons quelques concepts clés liés à Elastic Beanstalk :
Ces termes seront utilisés tout au long du didacticiel.
Nous allons déployer une application Flask simple appelée flask-movies dans ce didacticiel.
Vérifiez votre compréhension en déployant votre propre application tout en suivant le didacticiel.
Tout d'abord, récupérez le code du référentiel sur GitHub :
$ git clone git@github.com:duplxey/flask-movies.git
$ cd flask-movies
Créez un nouvel environnement virtuel et activez-le :
$ python3 -m venv venv && source venv/bin/activate
Installez la configuration requise et initialisez la base de données :
(venv)$ pip install -r requirements.txt
(venv)$ python init_db.py
Exécutez le serveur :
(venv)$ flask run
Ouvrez votre navigateur Web préféré et accédez à :
Assurez-vous de créer un compte AWS avant de continuer. En créant un compte, vous pouvez également être éligible à l' offre gratuite d'AWS .
L' interface de ligne de commande Elastic Beanstalk (EB CLI) vous permet d'effectuer diverses opérations pour déployer et gérer vos applications et environnements Elastic Beanstalk.
Il existe deux manières d'installer l'interface de ligne de commande EB :
Il est recommandé d'installer l'interface de ligne de commande EB globalement (en dehors de tout environnement virtuel spécifique) à l'aide du programme d'installation (première option) pour éviter d'éventuels conflits de dépendance. Reportez-vous à cette explication pour plus de détails.
Après avoir installé l'interface de ligne de commande EB, vous pouvez vérifier la version en exécutant :
$ eb --version
EB CLI 3.20.3 (Python 3.10.)
Si la commande ne fonctionne pas, vous devrez peut-être ajouter l'interface de ligne de commande EB à $PATH
.
Une liste des commandes EB CLI et leurs descriptions se trouvent dans la référence des commandes EB CLI .
Une fois que l'interface de ligne de commande EB est en cours d'exécution, nous pouvons commencer à interagir avec Elastic Beanstalk. Initialisons un nouveau projet avec un environnement EB.
Dans la racine du projet ("flask-movies"), exécutez :
$ eb init
Un certain nombre de questions vous seront posées.
La région AWS de votre environnement (et ressources) Elastic Beanstalk. Si vous n'êtes pas familier avec les différentes régions AWS, consultez Régions et zones de disponibilité AWS . En règle générale, vous devez choisir la région la plus proche de vos clients. Gardez à l'esprit que les prix des ressources varient d'une région à l'autre.
Il s'agit du nom de votre application Elastic Beanstalk. Je recommande simplement d'appuyer sur Entrée et d'utiliser la valeur par défaut : "flask-movies".
L'interface de ligne de commande EB détectera que vous utilisez un environnement Python. Après cela, il vous donnera différentes versions Python et versions Amazon Linux avec lesquelles vous pourrez travailler. Choisissez "Python 3.8 s'exécutant sur Amazon Linux 2 64 bits".
CodeCommit est un service de contrôle de code source sécurisé, hautement évolutif et géré qui héberge des référentiels Git privés. Nous ne l'utiliserons pas car nous utilisons déjà GitHub pour le contrôle des sources. Alors dites "non".
Pour nous connecter ultérieurement aux instances EC2, nous devons configurer SSH. Dites "oui" lorsque vous y êtes invité.
Pour se connecter aux instances EC2, nous aurons besoin d'une paire de clés RSA. Allez-y et générez-en un, qui sera ajouté à votre dossier "~/.ssh".
Après avoir répondu à toutes les questions, vous remarquerez un répertoire caché à l'intérieur de la racine de votre projet nommé ".elasticbeanstalk". Le répertoire doit contenir un fichier config.yml , avec toutes les données que vous venez de fournir.
.elasticbeanstalk
└── config.yml
Le fichier doit contenir quelque chose de similaire à :
branch-defaults:
master:
environment: null
group_suffix: null
global:
application_name: flask-movies
branch: null
default_ec2_keyname: aws-eb
default_platform: Python 3.8 running on 64bit Amazon Linux 2
default_region: us-west-2
include_git_submodules: true
instance_profile: null
platform_name: null
platform_version: null
profile: eb-cli
repository: null
sc: git
workspace_type: Application
Ensuite, créons l'environnement Elastic Beanstalk et déployons l'application :
$ eb create
Encore une fois, vous serez invité à poser quelques questions.
Ceci représente le nom de l'environnement EB. Je vous recommande de vous en tenir à la valeur par défaut : "flask-movies-env".
Il est recommandé d'ajouter
└-env
ou└-dev
de suffixer à vos environnements afin de pouvoir différencier facilement les applications EB des environnements.
Votre application Web sera accessible à l'adresse %cname%.%region%.elasticbeanstalk.com
. Encore une fois, utilisez la valeur par défaut.
Un équilibreur de charge répartit le trafic entre les instances de votre environnement. Sélectionnez "candidature".
Si vous souhaitez en savoir plus sur les différents types d'équilibreur de charge, consultez Équilibreur de charge pour votre environnement Elastic Beanstalk .
Les requêtes Spot Fleet vous permettent de lancer des instances à la demande en fonction de vos critères. Nous ne les utiliserons pas dans ce didacticiel, alors dites "non".
--
Avec cela, l'environnement sera animé :
Une nouvelle application sera également déployée.
Cela prendra environ trois minutes, alors n'hésitez pas à prendre une tasse de café.
Une fois le déploiement terminé, l'interface de ligne de commande EB modifiera .elasticbeanstalk/config.yml .
La structure de votre projet devrait maintenant ressembler à ceci :
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Une fois que vous avez déployé votre application, vous pouvez vérifier son état en exécutant :
$ eb status
Environment details for: flask-movies-env
Application name: flask-movies
Region: us-west-2
Deployed Version: app-82fb-220311_171256090207
Environment ID: e-nsizyek74z
Platform: arn:aws:elasticbeanstalk:us-west-2::platform/Python 3.8 running on 64bit Amazon Linux 2/3.3.11
Tier: WebServer-Standard-1.0
CNAME: flask-movies-env.us-west-2.elasticbeanstalk.com
Updated: 2022-03-11 23:16:03.822000+00:00
Status: Launching
Health: Red
Vous pouvez voir que la santé actuelle de notre environnement est Red
, ce qui signifie que quelque chose s'est mal passé. Ne vous en faites pas pour l'instant, nous y remédierons dans les prochaines étapes.
Vous pouvez également voir qu'AWS nous a attribué un CNAME qui est le nom de domaine de notre environnement EB. Nous pouvons accéder à l'application Web en ouvrant un navigateur et en naviguant vers le CNAME.
$ eb open
Cette commande ouvrira votre navigateur par défaut et naviguera vers le domaine CNAME. Vous verrez 502 Bad Gateway
, que nous allons corriger ici sous peu
$ eb console
Cette commande ouvrira la console Elastic Beanstalk dans votre navigateur par défaut :
Encore une fois, vous pouvez voir que la santé de l'environnement est "sévère", ce que nous corrigerons à l'étape suivante.
À l'étape précédente, nous avons essayé d'accéder à notre application et celle-ci a renvoyé 502 Bad Gateway
. Il y a deux raisons derrière cela :
PYTHONPATH
pour trouver des modules dans notre application.Par défaut, Elastic Beanstalk sert les applications Python avec Gunicorn . EB installe automatiquement Gunicorn dans le processus de déploiement, nous n'avons donc pas à l'ajouter à requirements.txt . Si vous souhaitez échanger Gunicorn avec autre chose, jetez un œil à Configuration du serveur WSGI avec un Procfile .
Corrigeons ces erreurs.
Créez un nouveau dossier à la racine du projet appelé ".ebextensions". Dans le dossier nouvellement créé, créez un fichier nommé 01_flask.config :
# .ebextensions/01_flask.config
option_settings:
aws:elasticbeanstalk:application:environment:
PYTHONPATH: "/var/app/current:$PYTHONPATH"
aws:elasticbeanstalk:container:python:
WSGIPath: "app:app"
Remarques:
PYTHONPATH
chemin Python sur notre instance EC2 ( docs ).WSGIPath
par notre application WSGI ( docs ).Comment fonctionnent les fichiers EB .config ?
- Vous pouvez en avoir autant que vous le souhaitez.
- Ils sont chargés dans l'ordre suivant : 01_x, 02_x, 03_x, etc.
- Vous n'avez pas besoin de mémoriser ces paramètres ; vous pouvez répertorier tous vos paramètres environnementaux en exécutant
eb config
.Si vous souhaitez en savoir plus sur la personnalisation avancée de l'environnement, consultez Personnalisation avancée de l'environnement avec les fichiers de configuration .
Ensuite, nous devons indiquer à Elastic Beanstalk d'initialiser la base de données lorsqu'une nouvelle version de l'application est déployée. Ajoutez ce qui suit à la fin de .ebextensions/01_flask.config :
# .ebextensions/01_flask.config
container_commands:
01_initdb:
command: "source /var/app/venv/*/bin/activate && python3 init_db.py"
leader_only: true
L'environnement EB exécutera désormais la commande ci-dessus chaque fois que nous déployons une nouvelle version de l'application. Nous avons utilisé leader_only
, donc seule la première instance EC2 les exécute (au cas où notre environnement EB exécute plusieurs instances EC2).
Les configurations Elastic Beanstalk prennent en charge deux sections de commande différentes, les commandes et les conteneur_commands . La principale différence entre eux réside dans le moment où ils sont exécutés dans le processus de déploiement :
commands
exécuté avant que l'application et le serveur Web ne soient configurés et que le fichier de version de l'application ne soit extrait.container_commands
exécuté après la configuration de l'application et du serveur Web et l'extraction de l'archive de la version de l'application, mais avant le déploiement de la version de l'application (avant que les fichiers ne soient déplacés du dossier intermédiaire vers leur emplacement final).
À ce stade, la structure de votre projet devrait ressembler à ceci :
|-- .ebextensions
| └-- 01_flask.config
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Validez les modifications sur git et déployez :
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Vous remarquerez qu'Elastic Beanstalk ne détectera pas les modifications si vous ne vous engagez pas. En effet, EB s'intègre à git et ne détecte que les fichiers validés (modifiés).
Une fois le déploiement terminé, exécutez eb open
pour voir si tout a fonctionné. Après cela, ajoutez /api/movies
à l'URL pour voir si les films sont toujours affichés.
Yay! La première version de notre application est maintenant déployée.
Si vous déployez flask-movies , vous remarquerez qu'il utilise une base de données SQLite par défaut. Bien que cela soit parfait pour le développement, vous souhaiterez généralement passer à une base de données plus robuste, comme Postgres ou MySQL, pour la production. Voyons comment échanger SQLite contre Postgres .
Tout d'abord, lançons Postgres en local. Vous pouvez soit le télécharger à partir des téléchargements PostgreSQL , soit créer un conteneur Docker :
$ docker run --name flask-movies-postgres -p 5432:5432 \
-e POSTGRES_USER=flask-movies -e POSTGRES_PASSWORD=complexpassword123 \
-e POSTGRES_DB=flask-movies -d postgres
Vérifiez si le conteneur est en cours d'exécution :
$ docker ps -f name=flask-movies-postgres
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c05621dac852 postgres "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp flask-movies-postgres
Maintenant, essayons de nous y connecter avec notre application Flask.
Changez à l' SQLALCHEMY_DATABASE_URI
intérieur de app.py comme ceci :
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username='flask-movies',
password='complexpassword123',
host='localhost',
port='5432',
database='flask-movies',
)
Ensuite, installez psycopg2-binary , qui est requis pour Postgres :
(venv)$ pip install psycopg2-binary==2.9.3
Ajoutez-le à requirements.txt :
Flask==2.0.3
Flask-SQLAlchemy==2.5.1
psycopg2-binary==2.9.3
Supprimez la base de données existante, default.db , puis initialisez la nouvelle base de données :
(venv)$ python init_db.py
Exécutez le serveur :
(venv)$ flask run
Assurez-vous que les films sont toujours correctement diffusés en consultant http://localhost:5000/api/movies .
Pour configurer Postgres pour la production, commencez par exécuter la commande suivante pour ouvrir la console AWS :
$ eb console
Cliquez sur "Configuration" dans la barre de gauche, faites défiler jusqu'à "Base de données", puis cliquez sur "Modifier".
Créez une BD avec les paramètres suivants et cliquez sur "Appliquer":
Si vous souhaitez rester dans l' offre gratuite d'AWS, assurez-vous de choisir db.t2.micro. Les prix RDS augmentent de manière exponentielle en fonction de la classe d'instance que vous choisissez. Si vous ne souhaitez pas utiliser,
micro
assurez-vous de consulter la tarification AWS PostgreSQL .
Une fois la mise à jour environnementale effectuée, EB transmettra automatiquement les informations d'identification DB suivantes à notre application flask :
RDS_DB_NAME
RDS_USERNAME
RDS_PASSWORD
RDS_HOSTNAME
RDS_PORT
Nous pouvons maintenant utiliser ces variables dans app.py pour nous connecter à notre base de données :
if 'RDS_DB_NAME' in os.environ:
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username=os.environ['RDS_USERNAME'],
password=os.environ['RDS_PASSWORD'],
host=os.environ['RDS_HOSTNAME'],
port=os.environ['RDS_PORT'],
database=os.environ['RDS_DB_NAME'],
)
else:
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username='flask-movies',
password='complexpassword123',
host='localhost',
port='5432',
database='flask-movies',
)
N'oubliez pas d'importer le os
package en haut de app.py :
import os
Validez les modifications sur git et déployez :
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Attendez que le déploiement se termine. Une fois cela fait, exécutez eb open
pour ouvrir votre application dans un nouvel onglet du navigateur. Assurez-vous que tout fonctionne toujours correctement en répertoriant les films sur /api/movies
.
Cette partie du tutoriel nécessite que vous disposiez d'un nom de domaine.
Besoin d'un domaine pas cher pour vous entraîner ? Plusieurs bureaux d'enregistrement de domaine ont des promotions sur les domaines '.xyz'. Alternativement, vous pouvez créer un domaine gratuit chez Freenom . Si vous ne possédez pas de nom de domaine, mais souhaitez tout de même utiliser HTTPS, vous pouvez créer et signer avec un certificat X509 .
Pour servir votre application via HTTPS, nous devrons :
Accédez à la console AWS Certificate Manager . Cliquez sur "Demander un certificat". Définissez le type de certificat sur "Public" et cliquez sur "Suivant". Entrez votre nom de domaine complet dans la saisie du formulaire, définissez la "Méthode de validation" sur "Validation DNS", puis cliquez sur "Demander".
Vous serez alors redirigé vers une page où vous pourrez voir tous vos certificats. Le certificat que vous venez de créer doit avoir le statut "En attente de validation".
Pour qu'AWS délivre un certificat, vous devez d'abord prouver que vous êtes le propriétaire du domaine. Dans le tableau, cliquez sur le certificat pour afficher les "Détails du certificat". Notez le "nom CNAME" et la "valeur CNAME". Pour valider la propriété du domaine, vous devrez créer un "enregistrement CNAME" dans les paramètres DNS de votre domaine. Utilisez le "nom CNAME" et la "valeur CNAME" pour cela. Une fois cela fait, il faudra quelques minutes à Amazon pour récupérez les modifications de domaine et émettez le certificat. Le statut doit passer de "En attente de validation" à "Émis".
Ensuite, vous devez faire pointer votre domaine (ou sous-domaine) vers votre environnement EB CNAME. De retour dans les paramètres DNS de votre domaine, ajoutez un autre enregistrement CNAME avec la valeur correspondant à votre EB CNAME -- par exemple, flask-movies-dev.us-west-2.elasticbeanstalk.com
.
Attendez quelques minutes que votre DNS se rafraîchisse avant de tester les choses à partir de la http://
saveur de votre nom de domaine dans votre navigateur.
De retour dans la console Elastic Beanstalk, cliquez sur « Configuration ». Ensuite, dans la catégorie "Load balancer", cliquez sur "Edit". Cliquez sur "Ajouter un écouteur" et créez un écouteur avec les détails suivants :
Cliquez sur "Ajouter". Ensuite, faites défiler vers le bas de la page et cliquez sur "Appliquer". La mise à jour de l'environnement prendra quelques minutes.
Ensuite, nous devons apporter quelques modifications à notre application Flask.
Nous devons rediriger tout le trafic de HTTP vers HTTPS. Il existe plusieurs façons de procéder, mais la plus simple consiste à configurer Apache en tant qu'hôte proxy. Nous pouvons y parvenir par programmation en ajoutant ce qui suit à la fin de option_settings
in .ebextensions/01_flask.config :
# .ebextensions/01_flask.config
option_settings:
# ...
aws:elasticbeanstalk:environment:proxy: # new
ProxyServer: apache # new
Votre fichier final 01_flask.config devrait maintenant ressembler à ceci :
# .ebextensions/01_flask.config
option_settings:
aws:elasticbeanstalk:application:environment:
PYTHONPATH: "/var/app/current:$PYTHONPATH"
aws:elasticbeanstalk:container:python:
WSGIPath: "app:app"
aws:elasticbeanstalk:environment:proxy:
ProxyServer: apache
container_commands:
01_initdb:
command: "source /var/app/venv/*/bin/activate && python3 init_db.py"
leader_only: true
Créez ensuite un dossier ".platform" à la racine du projet et ajoutez les fichiers et dossiers suivants :
└-- .platform
└-- httpd
└-- conf.d
└-- ssl_rewrite.conf
ssl_rewrite.conf :
# .platform/httpd/conf.d/ssl_rewrite.conf
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
La structure de votre projet devrait maintenant ressembler à ceci :
|-- .ebextensions
| └-- 01_flask.config
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- .platform
| └-- httpd
| └-- conf.d
| └-- ssl_rewrite.conf
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Validez les modifications sur git et déployez :
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Maintenant, dans votre navigateur, la https://
saveur de votre application devrait fonctionner. Essayez d'aller à la http://
saveur. Vous devriez être redirigé vers la https://
saveur. Assurez-vous également que le certificat est correctement chargé :
En production, il est préférable de stocker la configuration spécifique à l'environnement dans des variables d'environnement . Avec Elastic Beanstalk, vous pouvez définir des variables d'environnement personnalisées de deux manières différentes.
Transformons notre flacon SECRET_KEY
en une variable environnementale.
Commencez par exécuter :
$ eb setenv FLASK_SECRET_KEY='<replace me with your own secret key>'
Vous pouvez définir plusieurs variables d'environnement avec une seule commande en les séparant par des espaces. Il s'agit de l'approche recommandée car elle n'entraîne qu'une seule mise à jour de l'environnement EB.
Modifiez app.pySECRET_KEY
en conséquence :
# app.py
app.config['SECRET_KEY'] = os.environ.get(
'FLASK_SECRET_KEY',
'<replace me with your own fallback secret key>'
)
Validez les modifications sur git et déployez :
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Accédez à la console Elastic Beanstalk via eb open
. Accédez à "Configuration" > "Logiciel" > "Modifier". Ensuite, faites défiler jusqu'aux "Propriétés de l'environnement".
Une fois que vous avez terminé, cliquez sur "Appliquer" et votre environnement sera mis à jour.
Vous pouvez ensuite accéder à ces variables dans votre environnement Python via os.environ
.
Par exemple:
VARIABLE_NAME = os.environ['VARIABLE_NAME']
Lorsque vous travaillez avec Elastic Beanstalk, il peut être assez frustrant de comprendre ce qui ne va pas si vous ne savez pas comment accéder aux fichiers journaux. Dans cette section, nous n'examinerons que cela.
Il existe deux façons d'accéder aux journaux :
Par expérience personnelle, j'ai pu résoudre tous les problèmes avec la première approche.
CLI :
$ eb logs
Cette commande récupère les 100 dernières lignes des fichiers suivants :
/var/log/web.stdout.log
/var/log/eb-hooks.log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/eb-engine.log
L'exécution
eb logs
équivaut à se connecter à la console EB et à naviguer vers "Journaux".
Je recommande de diriger les journaux vers CloudWatch . Exécutez la commande suivante pour l'activer :
$ eb logs --cloudwatch-logs enable
Vous trouverez généralement des erreurs Flask dans /var/log/web.stdout.log ou /var/log/eb-engine.log .
Pour en savoir plus sur les journaux Elastic Beanstalk, consultez Affichage des journaux des instances Amazon EC2 .
Pour vous connecter à une instance EC2 sur laquelle votre application Flask est en cours d'exécution, exécutez :
$ eb ssh
Vous serez invité à ajouter l'hôte à vos hôtes connus la première fois. Dis oui. Avec cela, vous aurez désormais un accès complet à votre instance EC2. N'hésitez pas à vérifier certains des fichiers journaux mentionnés dans la section précédente.
Gardez à l'esprit qu'Elastic Beanstalk met automatiquement à l'échelle et déploie de nouvelles instances EC2. Les modifications que vous apportez à cette instance EC2 spécifique ne seront pas répercutées sur les instances EC2 nouvellement lancées. Une fois cette instance EC2 spécifique remplacée, vos modifications seront effacées.
Dans ce didacticiel, nous avons parcouru le processus de déploiement d'une application Flask sur AWS Elastic Beanstalk. Vous devriez maintenant avoir une bonne compréhension du fonctionnement d'Elastic Beanstalk. Effectuez une auto-vérification rapide en passant en revue les objectifs au début du didacticiel.
Prochaines étapes:
dev
et production
).Pour supprimer toutes les ressources AWS que nous avons créées tout au long du didacticiel, arrêtez d'abord l'environnement Elastic Beanstalk :
$ eb terminate
Vous devrez supprimer manuellement le certificat SSL.
Enfin, vous pouvez trouver la version finale du code dans le référentiel flask-elastic-beanstalk sur GitHub.
Source : https://testdrive.io
1668681618
In this tutorial, we'll walk through the process of deploying a Flask application to AWS Elastic Beanstalk.
By the end of this tutorial, you'll be able to:
AWS Elastic Beanstalk (EB) is an easy-to-use service for deploying and scaling web applications. It connects multiple AWS services, like compute instances (EC2), databases (RDS), load balancers (Application Load Balancer), and file storage systems (S3), to name a few. EB allows you to quickly develop and deploy your web application without thinking about the underlying infrastructure. It supports applications developed in Go, Java, .NET, Node.js, PHP, Python, and Ruby. EB also supports Docker if you need to configure your own software stack or deploy an application developed in a language (or version) that EB doesn't currently support.
Typical Elastic Beanstalk setup:
There's no additional charge for AWS Elastic Beanstalk. You only pay for the resources that your application consumes.
To learn more about Elastic Beanstalk, check out What is AWS Elastic Beanstalk? from the official AWS Elastic Beanstalk documentation.
Before diving into tutorial itself, let's look at a few key concepts related to Elastic Beanstalk:
These terms will be used throughout the tutorial.
We'll be deploying a simple Flask application called flask-movies in this tutorial.
Check your understanding by deploying your own application as you follow along with the tutorial.
First, grab the code from the repository on GitHub:
$ git clone git@github.com:duplxey/flask-movies.git
$ cd flask-movies
Create a new virtual environment and activate it:
$ python3 -m venv venv && source venv/bin/activate
Install the requirements and initialize the database:
(venv)$ pip install -r requirements.txt
(venv)$ python init_db.py
Run the server:
(venv)$ flask run
Open your favorite web browser and navigate to:
Be sure to register for an AWS account before continuing. By creating an account you might also be eligible for the AWS Free Tier.
The Elastic Beanstalk command line interface (EB CLI) allows you to perform a variety of operations to deploy and manage your Elastic Beanstalk applications and environments.
There are two ways of installing EB CLI:
It's recommended to install the EB CLI globally (outside any specific virtual environment) using the installer (first option) to avoid possible dependency conflicts. Refer to this explanation for more details.
After you've installed the EB CLI, you can check the version by running:
$ eb --version
EB CLI 3.20.3 (Python 3.10.)
If the command doesn't work, you may need to add the EB CLI to $PATH
.
A list of EB CLI commands and their descriptions can be found in the EB CLI command reference.
Once we have the EB CLI running we can start interacting with Elastic Beanstalk. Let's initialize a new project along with an EB Environment.
Within the project root ("flask-movies"), run:
$ eb init
You'll be prompted with a number of questions.
The AWS region of your Elastic Beanstalk environment (and resources). If you're not familiar with the different AWS regions, check out AWS Regions and Availability Zones. Generally, you should pick the region that's closest to your customers. Keep in mind that resource prices vary from region to region.
This is the name of your Elastic Beanstalk application. I recommend just pressing enter and going with the default: "flask-movies".
The EB CLI will detect that you're using a Python environment. After that, it'll give you different Python versions and Amazon Linux versions you can work with. Pick "Python 3.8 running on 64bit Amazon Linux 2".
CodeCommit is a secure, highly scalable, managed source control service that hosts private Git repositories. We won't be using it since we're already using GitHub for source control. So say "no".
To connect to the EC2 instances later we need to set up SSH. Say "yes" when prompted.
To connect to EC2 instances, we'll need an RSA keypair. Go ahead and generate one, which will be added to your "~/.ssh" folder.
After you answer all the questions, you'll notice a hidden directory inside your project root named ".elasticbeanstalk". The directory should contain a config.yml file, with all the data you've just provided.
.elasticbeanstalk
└── config.yml
The file should contain something similar to:
branch-defaults:
master:
environment: null
group_suffix: null
global:
application_name: flask-movies
branch: null
default_ec2_keyname: aws-eb
default_platform: Python 3.8 running on 64bit Amazon Linux 2
default_region: us-west-2
include_git_submodules: true
instance_profile: null
platform_name: null
platform_version: null
profile: eb-cli
repository: null
sc: git
workspace_type: Application
Next, let's create the Elastic Beanstalk environment and deploy the application:
$ eb create
Again, you'll be prompted with a few questions.
This represents the name of the EB environment. I'd recommend sticking with the default: "flask-movies-env".
It's considered good practice to add
└-env
or└-dev
suffix to your environments so you can easily differentiate EB apps from environments.
Your web application will be accessible at %cname%.%region%.elasticbeanstalk.com
. Again, use the default.
A load balancer distributes traffic amongst your environment's instances. Select "application".
If you want to learn about the different load balancer types, review Load balancer for your Elastic Beanstalk Environment.
Spot Fleet requests allow you to launch instances on-demand based on your criteria. We won't be using them in this tutorial, so say "no".
--
With that, the environment will be spun up:
A new application will be deployed as well.
This will take about three minutes so feel free to grab a cup of coffee.
After the deployment is done, the EB CLI will modify .elasticbeanstalk/config.yml.
Your project structure should now look like this:
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Once you've deployed your app you can check its status by running:
$ eb status
Environment details for: flask-movies-env
Application name: flask-movies
Region: us-west-2
Deployed Version: app-82fb-220311_171256090207
Environment ID: e-nsizyek74z
Platform: arn:aws:elasticbeanstalk:us-west-2::platform/Python 3.8 running on 64bit Amazon Linux 2/3.3.11
Tier: WebServer-Standard-1.0
CNAME: flask-movies-env.us-west-2.elasticbeanstalk.com
Updated: 2022-03-11 23:16:03.822000+00:00
Status: Launching
Health: Red
You can see that our environment's current health is Red
, which means that something went wrong. Don't worry about this just yet, we'll fix it in the next steps.
You can also see that AWS assigned us a CNAME which is our EB environment's domain name. We can access the web application by opening a browser and navigating to the CNAME.
$ eb open
This command will open your default browser and navigate to the CNAME domain. You'll see 502 Bad Gateway
, which we'll fix here shortly
$ eb console
This command will open the Elastic Beanstalk console in your default browser:
Again, you can see that the health of the environment is "Severe", which we'll fix in the next step.
In the previous step, we tried accessing our application and it returned 502 Bad Gateway
. There are two reasons behind it:
PYTHONPATH
in order to find modules in our application.By default Elastic Beanstalk serves Python applications with Gunicorn. EB automatically installs Gunicorn in the deployment process, hence we do not have to add it to requirements.txt. If you want to swap Gunicorn with something else, take a look at Configuring the WSGI server with a Procfile.
Let's fix these errors.
Create a new folder in the project root called ".ebextensions". Within the newly created folder create a file named 01_flask.config:
# .ebextensions/01_flask.config
option_settings:
aws:elasticbeanstalk:application:environment:
PYTHONPATH: "/var/app/current:$PYTHONPATH"
aws:elasticbeanstalk:container:python:
WSGIPath: "app:app"
Notes:
PYTHONPATH
to the Python path on our EC2 instance (docs).WSGIPath
to our WSGI application (docs).How do EB .config files work?
- You can have as many as you want.
- They are loaded in the following order: 01_x, 02_x, 03_x, etc.
- You do not have to memorize these settings; you can list all your environmental settings by running
eb config
.If you want to learn more about advanced environment customization check out Advanced environment customization with configuration files.
Next, we have to tell Elastic Beanstalk to initialize the database when a new application version gets deployed. Add the following to the end of .ebextensions/01_flask.config:
# .ebextensions/01_flask.config
container_commands:
01_initdb:
command: "source /var/app/venv/*/bin/activate && python3 init_db.py"
leader_only: true
The EB environment will now execute the above command every time we deploy a new application version. We used leader_only
, so only the first EC2 instance executes them (in case our EB environment runs multiple EC2 instances).
Elastic Beanstalk configs support two different command sections, commands and container_commands. The main difference between them is when they are run in the deployment process:
commands
run before the application and web server are set up and the application version file is extracted.container_commands
run after the application and web server have been set up and the application version archive has been extracted, but before the application version is deployed (before the files are moved from the staging folder to their final location).
At this point your project structure should look like this:
|-- .ebextensions
| └-- 01_flask.config
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Commit the changes to git and deploy:
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
You'll notice that Elastic Beanstalk won't detect the changes if you don't commit. That's because EB integrates with git and only detects the committed (changed) files.
After the deployment is done, run eb open
to see if everything worked. After that, append /api/movies
to the URL to see if the movies still get displayed.
Yay! The first version of our app is now deployed.
If you're deploying flask-movies, you'll notice that it uses a SQLite database by default. While this is perfect for development, you'll typically want to move to a more robust database, like Postgres or MySQL, for production. Let's look at how to swap SQLite for Postgres.
First, let's get Postgres running locally. You can either download it from PostgreSQL Downloads or spin up a Docker container:
$ docker run --name flask-movies-postgres -p 5432:5432 \
-e POSTGRES_USER=flask-movies -e POSTGRES_PASSWORD=complexpassword123 \
-e POSTGRES_DB=flask-movies -d postgres
Check if the container is running:
$ docker ps -f name=flask-movies-postgres
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c05621dac852 postgres "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp flask-movies-postgres
Now, let's try connecting to it with our Flask app.
Change SQLALCHEMY_DATABASE_URI
inside app.py like so:
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username='flask-movies',
password='complexpassword123',
host='localhost',
port='5432',
database='flask-movies',
)
Next, install psycopg2-binary, which is required for Postgres:
(venv)$ pip install psycopg2-binary==2.9.3
Add it to requirements.txt:
Flask==2.0.3
Flask-SQLAlchemy==2.5.1
psycopg2-binary==2.9.3
Remove the existing database, default.db, and then initialize the new database:
(venv)$ python init_db.py
Run the server:
(venv)$ flask run
Make sure the movies still get served correctly by checking out http://localhost:5000/api/movies.
To set up Postgres for production, start by running the following command to open the AWS console:
$ eb console
Click "Configuration" on the left side bar, scroll down to "Database", and then click "Edit".
Create a DB with the following settings and click on "Apply":
If you want to stay within the AWS Free Tier make sure you pick db.t2.micro. RDS prices increase exponentially based on the instance class you pick. If you don't want to go with
micro
make sure to review AWS PostgreSQL pricing.
After the environmental update is done, EB will automatically pass the following DB credentials to our flask app:
RDS_DB_NAME
RDS_USERNAME
RDS_PASSWORD
RDS_HOSTNAME
RDS_PORT
We can now use these variables in app.py to connect to our database:
if 'RDS_DB_NAME' in os.environ:
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username=os.environ['RDS_USERNAME'],
password=os.environ['RDS_PASSWORD'],
host=os.environ['RDS_HOSTNAME'],
port=os.environ['RDS_PORT'],
database=os.environ['RDS_DB_NAME'],
)
else:
app.config['SQLALCHEMY_DATABASE_URI'] = \
'postgresql://{username}:{password}@{host}:{port}/{database}'.format(
username='flask-movies',
password='complexpassword123',
host='localhost',
port='5432',
database='flask-movies',
)
Don't forget to import the os
package at the top of app.py:
import os
Commit the changes to git and deploy:
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Wait for the deployment to finish. Once done, run eb open
to open your app in a new browser tab. Make sure everything still works correctly by listing the movies at /api/movies
.
This part of the tutorial requires that you have a domain name.
Need a cheap domain to practice with? Several domain registrars have specials on '.xyz' domains. Alternatively, you can create a free domain at Freenom. If you don't own a domain name, but would still like to use HTTPS you can create and sign with an X509 certificate.
To serve your application via HTTPS, we'll need to:
Navigate to the AWS Certificate Manager console. Click "Request a certificate". Set the certificate type to "Public" and click "Next". Enter your fully qualified domain name into the form input, set the "Validation method" to "DNS validation", and click "Request".
You'll then be redirected to a page where you can see all your certificates. The certificate that you just created should have a status of "Pending validation".
For AWS to issue a certificate, you first have to prove that you're the owner of the domain. In the table, click on the certificate to view the "Certificate details". Take note of the "CNAME name" and "CNAME value". To validate the ownership of the domain, you'll need to create a CNAME Record" in your domain's DNS settings. Use the "CNAME name" and "CNAME value" for this. Once done, it will take a few minutes for Amazon to pick up the domain changes and issue the certificate. The status should change from "Pending validation" to "Issued".
Next, you need to point your domain (or subdomain) to your EB environment CNAME. Back in your domain's DNS settings, add another CNAME record with the value being your EB CNAME -- e.g., flask-movies-dev.us-west-2.elasticbeanstalk.com
.
Wait a few minutes for your DNS to refresh before testing things out from the http://
flavor of your domain name in your browser.
Back in the Elastic Beanstalk console, click "Configuration". Then, within the "Load balancer" category, click "Edit". Click "Add listener" and create a listener with the following details:
Click "Add". Then, scroll to the bottom of the page and click "Apply". It will take a few minutes for the environment to update.
Next, we need to make a few changes to our Flask application.
We need to redirect all traffic from HTTP to HTTPS. There are multiple ways of doing this, but the easiest way is to set up Apache as a proxy host. We can achieve this programmatically by adding the following to the end of the option_settings
in .ebextensions/01_flask.config:
# .ebextensions/01_flask.config
option_settings:
# ...
aws:elasticbeanstalk:environment:proxy: # new
ProxyServer: apache # new
Your final 01_flask.config file should now look like this:
# .ebextensions/01_flask.config
option_settings:
aws:elasticbeanstalk:application:environment:
PYTHONPATH: "/var/app/current:$PYTHONPATH"
aws:elasticbeanstalk:container:python:
WSGIPath: "app:app"
aws:elasticbeanstalk:environment:proxy:
ProxyServer: apache
container_commands:
01_initdb:
command: "source /var/app/venv/*/bin/activate && python3 init_db.py"
leader_only: true
Next, create a ".platform" folder in the project root and add the following files and folders:
└-- .platform
└-- httpd
└-- conf.d
└-- ssl_rewrite.conf
ssl_rewrite.conf:
# .platform/httpd/conf.d/ssl_rewrite.conf
RewriteEngine On
<If "-n '%{HTTP:X-Forwarded-Proto}' && %{HTTP:X-Forwarded-Proto} != 'https'">
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</If>
Your project structure should now look like this:
|-- .ebextensions
| └-- 01_flask.config
|-- .elasticbeanstalk
| └-- config.yml
|-- .gitignore
|-- .platform
| └-- httpd
| └-- conf.d
| └-- ssl_rewrite.conf
|-- README.md
|-- app.py
|-- default.db
|-- init_db.py
└-- requirements.txt
Commit the changes to git and deploy:
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Now, in your browser, the https://
flavor of your application should work. Try going to the http://
flavor. You should be redirected to the https://
flavor. Ensure the certificate is loaded properly as well:
In production, it's best to store environment-specific config in environment variables. With Elastic Beanstalk you can set custom environmental variables two different ways.
Let's turn our Flask SECRET_KEY
into an environmental variable.
Start by running:
$ eb setenv FLASK_SECRET_KEY='<replace me with your own secret key>'
You can set multiple environmental variables with one command by separating them with spaces. This is the recommended approach as it results in only a single update to the EB environment.
Change SECRET_KEY
in app.py accordingly:
# app.py
app.config['SECRET_KEY'] = os.environ.get(
'FLASK_SECRET_KEY',
'<replace me with your own fallback secret key>'
)
Commit the changes to git and deploy:
$ git add .
$ git commit -m "updates for eb"
$ eb deploy
Enter the Elastic Beanstalk console via eb open
. Navigate to "Configuration" > "Software" > "Edit". Then, scroll down to the "Environment properties".
After you're done, click "Apply" and your environment will update.
You can then access these variables in your Python environment via os.environ
.
For example:
VARIABLE_NAME = os.environ['VARIABLE_NAME']
When working with Elastic Beanstalk, it can be pretty frustrating to figure out what went wrong if you don't know how to access the log files. In this section we will look at just that.
There are two ways to access the logs:
From personal experience, I've been able to solve all issues with the first approach.
CLI:
$ eb logs
This command will fetch the last 100 lines from the following files:
/var/log/web.stdout.log
/var/log/eb-hooks.log
/var/log/nginx/access.log
/var/log/nginx/error.log
/var/log/eb-engine.log
Running
eb logs
is equivalent to logging into the EB console and navigating to "Logs".
I recommend piping the logs to CloudWatch. Run the following command to enable this:
$ eb logs --cloudwatch-logs enable
You'll typically find Flask errors in /var/log/web.stdout.log or /var/log/eb-engine.log.
To learn more about Elastic Beanstalk logs check out Viewing logs from Amazon EC2 instances.
To connect to an EC2 instance where your Flask application is running, run:
$ eb ssh
You'll be prompted to add the host to your known hosts the first time. Say yes. With that, you'll now have full access to your EC2 instance. Feel free to check some of the log files mentioned in the previous section.
Keep in mind that Elastic Beanstalk automatically scales and deploys new EC2 instances. The changes you make on this specific EC2 instance won't be reflected on newly launched EC2 instances. Once this specific EC2 instance is replaced, your changes will be wiped.
In this tutorial, we walked through the process of deploying a Flask application to AWS Elastic Beanstalk. By now you should have a fair understanding of how Elastic Beanstalk works. Perform a quick self-check by reviewing the objectives at the beginning of the tutorial.
Next steps:
dev
and production
).To remove all the AWS resources we created throughout the tutorial, first terminate the Elastic Beanstalk environment:
$ eb terminate
You'll need to manually remove the SSL certificate.
Finally, you can find the final version of the code in the flask-elastic-beanstalk repo on GitHub.
Original article source at: https://testdriven.io/
1598319758
At the end of 2019 Deeplearning.ai reported that only 22% of companies that use machine learning actually deployed a model. Most companies do not get beyond a proof of concept, often by means of a model in a Jupyter Notebooks. As a result, numerous companies are hiring machine learning engineers who can build machine learning models and put them in production as well.
Data scientists should be at least familiar with some methods of productionizing models. The most important tool in a data scientists toolbox for this purpose is Docker. Docker is a container service that enables you to deploy a model or application beyond your local machine. For example, running it on Amazon Web Services (AWS) or on Google Cloud Platform (GCP). Several frameworks exist to build applications and serve your models within these Docker containers. As many data scientist already know Python, Flask is easy to start with. In addition, Flask provides you with the opportunity to build a (simple) user-interface so your users will be able to interact with your models without having to learn how to use the command line interface or make an API request.
In this hands-on tutorial I will show you how to deploy a simple Flask application in a Docker container on AWS Elastic Beanstalk and how to add a logging functionality, so your users will be able to see what’s happening behind the scenes. The application will not contain any machine learning models, but you can easily extend it on your own. When I first deployed this solution, I had some trouble with getting it to work, as I had to configure the (reverse) proxy server on AWS. In the last part of this tutorial I will show you how to do this.
#aws-elastic-beanstalk #docker #logging #flask #nginx
1598408880
The Basics
AWS KMS is a Key Management Service that let you create Cryptographic keys that you can use to encrypt and decrypt data and also other keys. You can read more about it here.
Important points about Keys
Please note that the customer master keys(CMK) generated can only be used to encrypt small amount of data like passwords, RSA key. You can use AWS KMS CMKs to generate, encrypt, and decrypt data keys. However, AWS KMS does not store, manage, or track your data keys, or perform cryptographic operations with data keys.
You must use and manage data keys outside of AWS KMS. KMS API uses AWS KMS CMK in the encryption operations and they cannot accept more than 4 KB (4096 bytes) of data. To encrypt application data, use the server-side encryption features of an AWS service, or a client-side encryption library, such as the AWS Encryption SDK or the Amazon S3 encryption client.
Scenario
We want to create signup and login forms for a website.
Passwords should be encrypted and stored in DynamoDB database.
What do we need?
Lets Implement it as Serverless Application Model (SAM)!
Lets first create the Key that we will use to encrypt and decrypt password.
KmsKey:
Type: AWS::KMS::Key
Properties:
Description: CMK for encrypting and decrypting
KeyPolicy:
Version: '2012-10-17'
Id: key-default-1
Statement:
- Sid: Enable IAM User Permissions
Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${AWS::AccountId}:root
Action: kms:*
Resource: '*'
- Sid: Allow administration of the key
Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${AWS::AccountId}:user/${KeyAdmin}
Action:
- kms:Create*
- kms:Describe*
- kms:Enable*
- kms:List*
- kms:Put*
- kms:Update*
- kms:Revoke*
- kms:Disable*
- kms:Get*
- kms:Delete*
- kms:ScheduleKeyDeletion
- kms:CancelKeyDeletion
Resource: '*'
- Sid: Allow use of the key
Effect: Allow
Principal:
AWS: !Sub arn:aws:iam::${AWS::AccountId}:user/${KeyUser}
Action:
- kms:DescribeKey
- kms:Encrypt
- kms:Decrypt
- kms:ReEncrypt*
- kms:GenerateDataKey
- kms:GenerateDataKeyWithoutPlaintext
Resource: '*'
The important thing in above snippet is the KeyPolicy. KMS requires a Key Administrator and Key User. As a best practice your Key Administrator and Key User should be 2 separate user in your Organisation. We are allowing all permissions to the root users.
So if your key Administrator leaves the organisation, the root user will be able to delete this key. As you can see **KeyAdmin **can manage the key but not use it and KeyUser can only use the key. ${KeyAdmin} and **${KeyUser} **are parameters in the SAM template.
You would be asked to provide values for these parameters during SAM Deploy.
#aws #serverless #aws-sam #aws-key-management-service #aws-certification #aws-api-gateway #tutorial-for-beginners #aws-blogs