Elastic Beanstalk est un service AWS gratuit (on ne paie que ce qu'on consomme sur les instances) qui permet de manager facilement un bout de cloud. Ce service s'adresse à ceux qui souhaitent deployer dans le cloud une application rapidement en laissant le soin du scaling à AWS (ça se se fait automatiquement). Donc si vous n'avez pas de besoin crucial de finesse de config sur vos environnements, EB est un bon choix.
Objectif de cet article : déployer un site web en quelques lignes de commande sur AWS - EB. Staging et Prod.
Je ne sais pas vous, mais d'habitude, pour lancer un POC ou un petit site rapide, je passe pas mal de temps à configurer et gérer mon environnement de production, et surtout mes déploiements. J'ai un VPS sur OVH qui me sert pour le moment de dev/prod (ce site étant sur ce serveur). Je passe par un classique sFTP pour uploader mes builds. J'ai toujours voulu automatiser ces tâches. C'est relativement facile depuis un mac ou linux, mais ça a longtemps été galère sur Windows. En ce qui concerne les outils en ligne de commande, j'y arrivais pas ou mal. De plus, mon VPS n'est pas du tout scalable. Du coup, j'ai mis un pied dans le cloud via Azure. Perso je trouve que c'est bien le bordel. Ca évolue régulièrement et j'ai pas de formation Azure. J'ai l'impression qu'il fait sortir l'artillerie lourde dès le début.
Pour un dev comme moi, j'ai besoin d'un accès gratuit ou peu cher avec maitrise des coûts dès le départ. Azure dispose d'une CLI, on peut jouer avec. J'ai testé la création de deux instances VM avec du kubernetes, du docker, et tout un tas de trucs qui au final me coute un bras. Ya bien une offre Azure avec qq crédits, mais pour le moment j'ai pas encore trouvé qq chose à moins de 20 balles/mois (et c'est déjà trop !). Moi développeur, je veux tester avant tout, lancer un produit, monter en charge facilement, maitriser mes coûts et ensuite commencer à réfléchir à une architecture/infra "long life".
Amazon propose une offre gratuite sur 12 mois pour tester ses services. En gros on a le droit à des services, mais pour savoir "combien, comment, où, avec qui, tout ça", c'est pas simple (faut attendre la fin du mois, perso j'ai 18$ en 14 jours juste a tester ce qui suit...). On peut monter ses VMs comme je l'ai fait sur Azure, avec une CLI AWS ou sur la Console AWS, mais c'est vraiment long et au départ on a pas besoin d'une armada de trucs. Elastic Beanstalk est la pour ça. AWS EB va s'occuper de tout ce que je ne maitrise pas ou mal. Ce que je veux, c'est deux environnements de staging et de prod. Un site web + une base de données SQL. On couvre l'essentiel de mes besoins pour le moment et à mon avis, les vôtres aussi.
Mise en bouche :
Avant de commencer à jouer avec la CLI je vous propose deux vidéos intéressantes qui m'ont mis le pied à l'étrier :
La première vidéo permet de créer un site web asp.net core mvc tout simple et de l'uploader sur AWS - EB en utilisant la console de management AWS. Cette dernière mal nommé car on pense à une console en ligne de commande. Il n'en est rien. C'est une interface web.
Il est intéressant de commencer à se former via celle ci car elle permet de se faire une idée des services et fonctionnalités disponibles. De plus, lorsque nous passerons sur la CLI, c'est un bon moyen de s'assurer du résultat de nos commandes. Faut savoir qu'on peut aussi passer via une API web, donc programmer des trucs avec...
La seconde vidéo nous montre comment connecter une base de données à notre site web. En gros le strict minimum pour un site web assez basique, le tout sur le cloud.
Il vous faudra bien sur un compte AWS et une carte bancaire. Il existe des offres gratuites sur 12 mois. Il faut faire attention à ce qu'on choisit pour rester dans le pack "gratos".
La CLI - eb
La commande line interface d'Elastic Beanstalk (doc officielle) permet d'administrer votre cloud EB comme si vous êtiez sur la console AWS, mais en ligne de commande... L'intérêt est d'automatiser certaines tâches. Le but est de pouvoir coder en dev sur une machine local et de deployer son code en 2 deux trois mouvements sur un environnement cloud Staging et Prod.
Je pars du principe que vous avez votre site web de prêt (pour moi ce sera un site asp.net core). On se met à la racine de celui ci via votre terminal préféré.
Ci dessus, la console AWS EB qui liste mes environnements et mes applications. Si vous avez fait les tutos des deux vidéos précédentes, vous allez reconnaitre Netcoredemo Le but est de refaire exactement la même chose en ligne de commande.
Première commande : eb init
Cette commande commence par créer un répertoire .elasticbeanstalk à la racine de votre projet (enfin si vous y êtiez lorsque vous l'avez taper). On y retrouvera quelques fichiers intéressant pour la suite. eb va vous demander les points suivant :
- Region : pour ma part eu-west-3
- Choix de l'app (une existante ou une nouvelle) : une nouvelle
- App name : DemoDevOps
- Platform : il y a le choix, pour moi .net core on linux
- SSH : pour le moment non (c'est à envisager par contre)
et biiimmmm :
On constate que notre application toute fraîche n'a pas d'environnement d'exécution. Nous allons le créer avec la prochaine commande.
Si on regarde dans le répertoire .elasticbeanstalk on y trouve un nouveau fichier config.yml. Il contient tout ce que nous venons de créer sous forme d'un fichier (manifest de deploiement). On verra plus tard qu'on passera via ce fichier pour aller encore plus vite.
Deuxième commande : eb create
Cette commande va créer un environnement pour notre application.
- Nom de l'environnement : EnvProd
- DNS CNAME : on va laisser par défaut
- LoadBalancer : application
- Spot Fleet : j'ai mis non mais je sais pas ce que c'est.
Eb va créer un build puis zipper de notre application et l'uploader automatiquement, puis effacer les fichiers localement. (c'est rapide mais on peut l'apercevoir dans .elasticbeanstalk). Ensuite il lance la création de l'environnement pour votre application, cela peut prendre quelques minutes.
J'ai une erreur ici. Mais mon environnement est quand même créé. J'ai refais les manip plusieurs fois. Il semblerait que eb create tente de faire un eb deploy. Ya deux modes pour l'eb deploy, un auto qui se sert de git pour builder une version et l'autre plus manuelle ou l'on spécifie le build zippé à deployer. En auto c'est la merde. Et je sais pas pourquoi, sans doute lié au repo Git qui n'est pas a la racine de mon projet, mais deux répertoires plus haut.
Todo : debuger ce truc un jour...
Pour ne pas rester bloqué, j'ai créé les environnements Staging et Prod manuellement via la Console AWS. On va commencer par l'environnement de prod, voici mon fichier yml :
A partir de là, la cli sait sur quelle environnement uploader votre build.
Deployer son code
Pour déployer son code on va sortir un build en release : dotnet publish -c Release /p:EnvironmentName=Production -o DevOps/deployProd
Ensuite on va le zipper (bash) : zip -r ../deployProd_bundle.zip *
On ajoute deux lignes au fichier config.yml
Et ensuite on va demander à eb de le deployer : eb deploy
Si tout ce se passe bien, votre code part en prod et se déploie tout seul.
Pour faire ca en une fois, j'ai crée un script bash executable (chmod +x votrefichier), localiser dans un répertoire DevOps, que je lance depuis la racine du site.
dotnet publish -c Release /p:EnvironmentName=Production -o DevOps/deployProd
cd DevOps/deployProd
zip -r ../deployProd_bundle.zip *
cd ../..
eb deploy
Mission accomplie, je mets à jour ma prod en une seule ligne de commande !
Pensez à virer le répertoire DevOps de votre build, sans ça, à chaque publish, il va recopier celui ci, qui contient le deploy, qui contient le /devops qui etc... Et il pourrait contenir des infos sensibles.
Staging et variable d'environnement
Lorsque vous allez créez l'environnement staging et déployez votre code, vous allez rencontrer un souci. La variable d'environnement ASPNETCORE_ENVIRONMENT de votre environnement est par défaut Production. Pour la changer il faut se rendre dans la configuration de l'environnement puis logiciel, en bas se trouve une liste editable.
Lors du build staging on va spécifier son environnement comme suit : dotnet publish -c Release /p:EnvironmentName=Staging -o DevOps/deployStaging
Si on vérifie le web.config de notre build, on aura ceci :
Pour vérifier visuellement dans une page web notre environnement, coller ceci sur votre page d'accueil (Asp.net core):
@inject Microsoft.AspNetCore.Hosting.IHostingEnvironment env@using Microsoft.Extensions.Configuration@inject IConfiguration Configuration
@{ ViewData["Title"] = "Home Page";}
<h2>HostingEnvironment : @env.EnvironmentName</h2>
<h2>Settings env name : @Configuration["EnvName"]</h2>
J'ai ajouté dans mes appSettings.[Production/Staging].json une entrée EnvName qui porte le nom de l'environnement, histoire devoir quel fichier de conf est pris en compte. Ensuite pensez à changer votre config dans .elasticbeanstalk
Et la on lance notre script :
dotnet publish -c Release /p:EnvironmentName=Staging -o DevOps/deployStaging
cd DevOps/deployStaging
zip -r ../deployStaging_bundle.zip *
cd ../..
eb deploy
Et biiiim, notre staging est updaté !
On constate que c'est marqué production donc on va modifier notre variable d'environnement :
Après modif de la variable d'environnement ASPNETCORE_ENVIRONMENT = Staging sur EnvStaging (ca peut prendre quelques minutes...)
Double biiiiiim
Pour info, voila à quoi ressemble mon projet et mon repertoire DevOps. J'ai mis dans mon .gitignore la sortie des répertoires de build et les zips de builds. Ya pas de raison que ca parte sur le repo.
One to rules them all
On a vu ici grace à quelques commandes réunies dans un fichier bash qu’on peut facilement deployer son code sur Staging et Prod. Le souci ici c’est qu’on doit encore modifier à la main le fichier de config.yml pour basculer sur le Staging ou la Prod. Voyons comment améliorer cela.
On commence par virer le .elasticbeanstalk à la racine, on vire tout ce qu’on a fait précédemment dans le rep /DevOps pour plus de clarté et on va créer deux répertoires Staging et Prod dedans, puis on va lancer un eb init dans chacun d’eux. Ceci va donc créer un .elasticbeanstalk avec un fichier config dans chacun des répertoires. Vous la voyez l’astuce ?
Pour info : Eb créer un fichier .gitignore a chaque fois et n’inclu pas les fichiers de config. Moi je le vire et ainsi mon codel yml part sur le repo. Par contre j’ajoute dans le .gitignore du projet a la racine ceci :
/DevOps/Prod/deploy
/DevOps/Prod/deploy_bundle.zip
/DevOps/Staging/deploy
/DevOps/Staging/deploy_bundle.zip
Il nous reste plus qu’à remettre nos scripts précédents dans chacun des répertoires (avec qq modif de nom et de path) et de créer un fichier executable deployAllBash qui se charge d’appeler :
./DevOps/Staging/deployStagingBash
./DevOps/Prod/deployProdBash
Ainsi, en une ligne de commande, je deploie sur Staging et Prod. A ce jeu la on peut ajouter d’autre environnement avec d’autre application. Tout en ligne de commande. Venant du monde .Net, c’est pas quelque chose qui est habituel. Avec .Net Core et EB Cli, ça devient possible.
Le déploiement en prod
Bon on va pas se le cacher, déployer en prod comme je viens de le faire, c’est un peu old school. On fera pas ça avec une grosse app et des centaines d’utilisateurs en cours. Mais pour du dev sur un projet « fresh », et à 4h du mat, ça passe crème !
Pour aller plus loin, on pourrait faire du déploiement automatique basé sur des repos Gits. C’est beaucoup plus pro. Hummm..peut être le sujet d’un prochain article ça…
Et pour aller encore plus loin ya cette vidéo avec un mec en chemise qui sourit :