https://chalice.readthedocs.io/en/latest/
AWS Chalice est un framework qui vous permet de créer un environnement sans serveur aussi facilement que Heroku en combinant AWS Lambda et API Gateway. Actuellement, seul Python est pris en charge en tant que langage de développement (on ne sait pas s'il le sera à l'avenir), mais si vous acceptez les restrictions, il semble qu'un environnement plus facile et plus facile à développer que les autres frameworks sans serveur soit fourni. Je pense. Même dans mon environnement, j'utilise souvent Chalice pour développer une gamme assez large de processus tels que la création d'API simples, de lots et de processus cron.
Je n'expliquerai pas ce que vous pouvez faire avec Chalice dans cet article.
Et comme M. Sutajio a écrit un article sur le test (https://qiita.com/studio3104/items/8a6b7e5f696e8453d97a), quel est l'environnement CI / CD lors du développement avec Chalice? Je souhaite écrire un article basé sur mon propre exemple. Ici, l'environnement CI utilisé est «Circle CI».
Il existe plusieurs thèmes, mais ici nous décrirons les thèmes suivants.
calice est un style dans lequel un échafaudage de projet est créé et développé sous la forme de `` calice new-project sada '' pour chaque fonction que vous souhaitez créer. La création d'un référentiel tel que GitHub pour chaque projet le rendra plus fragmenté. Je voudrais donc avoir une configuration monorepo, mais si je mets simplement plusieurs projets dans un référentiel, tous les projets peuvent être testés, vérifiés et déployés lors de la modification de certains projets pendant CI / CD. Il a tendance à fonctionner et ralentit le CI / CD.
Donc, en tant que stratégie de base, je voudrais prendre la forme de «exécuter uniquement CI / CD pour les projets qui ont changé dans le référentiel GitHub».
En réalisant cela, je me suis référé au contenu du blog suivant. Un script qui compare le contenu de la tête sur GitHub pour déterminer s'il existe des différences. https://blog.hatappi.me/entry/2018/10/08/232625
$ cat tools/is_changed
#!/bin/bash
if [ "${CIRCLE_BRANCH}" = "master" ]; then
DIFF_TARGET="HEAD^ HEAD"
else
DIFF_TARGET="origin/master"
fi
DIFF_FILES=(`git diff ${DIFF_TARGET} --name-only --relative=${1}`)
if [ ${#DIFF_FILES[@]} -eq 0 ]; then
exit 1
else
exit 0
fi
En préparant un script de cette manière et en passant le projet Chalice que vous souhaitez vérifier au moment de CI / CD à l'argument du script, vous pouvez vérifier la différence pour chaque projet, sauter le projet sans différence et ne suivre que celui avec différence Il est possible d'effectuer le traitement CI de.
$ cat tools/echo_changed
for dir in ${PROJECTS}; do \
if ${WORKDIR}/is_changed "${dir}"; then
echo "changed."
else
echo "nothing change."
fi
done
unit test / code coverage Je pense que M. Sutajio a décrit en détail comment rédiger le test, je vais donc omettre les détails ici.
Dans mon environnement, j'utilise une combinaison de «couverture» et «pytest». Nous effectuons des tests unitaires et mesurons la couverture de test obtenue en conséquence.
$ coverage run -m pytest
$ coverage report
Name Stmts Miss Cover
---------------------------------------
app.py 35 22 37%
tests/__init__.py 0 0 100%
tests/conftest.py 4 0 100%
tests/test_app.py 5 0 100%
---------------------------------------
TOTAL 44 22 50%
Si vous exécutez la couverture dans un environnement avec un test unitaire, vous pouvez générer un rapport comme celui ci-dessus. Vous pouvez enregistrer le rapport HTML en tant qu'artéfacts pour Circle CI et l'afficher à partir de l'écran des résultats de CI.
- run:
name: Run Tests
command: |
$HOME/.local/bin/coverage run -m pytest
$HOME/.local/bin/coverage report
$HOME/.local/bin/coverage html # open htmlcov/index.html in a browser
- store_artifacts:
path: htmlcov
Veuillez vous référer aux documents officiels suivants pour les paramètres détaillés.
https://circleci.com/docs/2.0/code-coverage/#python
Aussi, si vous voulez arrêter le test quand il tombe en dessous d'un certain taux de couverture, vous pouvez faire rapport de couverture --fail-number [num]
et il retournera return code = 2
si la couverture est inférieure ou égale au nombre. ..
En d'autres termes, vous pouvez arrêter CI lorsque le seuil n'est pas atteint.
Si vous écrivez le traitement de cette zone comme un shell, ce sera comme suit. De tous les projets dans monorepo, s'il y a une différence, une mesure de test unitaire / couverture est effectuée, et si le test échoue ou même une couverture est en dessous du seuil, CI s'arrêtera.
$ cat tools/coverage
ret=0
for dir in ${PROJECTS}; do
if ${WORKDIR}/is_changed "${dir}"; then
cd ${WORKDIR}/../${dir}/
sudo pip install -r requirements.txt
coverage run -m pytest
coverage report --fail-under=${THRESHOLD}
r=$?
coverage html -d ../htmlcov/${dir}
if [ $r != 0 ]; then ret=$r; fi
else
echo "nothing change."
fi
done
exit $ret
lint / code smells En plus des tests et des mesures de couverture, il est courant dans les flux CI / CD d'utiliser les outils Lint et Code Smells pour identifier de manière heuristique ** la «mauvaise écriture» **.
Je n'entrerai pas non plus dans les détails à ce sujet, mais dans mon environnement, j'utiliserai une combinaison de pep8 (pycodestyle)
et pyflakes
.
Les deux outils géreront le CI selon les besoins, comme return code = 1
lorsqu'il y a une indication.
Ce qui suit est un exemple de résultat de pyflakes, mais il est souligné que dans les cas suivants, la variable sada
est déclarée mais pas utilisée.
$ pyflakes app.py
app.py:32: local variable 'sada' is assigned to but never used
Cependant, dans chaque cas, si vous effectuez avec les paramètres par défaut, vous obtiendrez des points à signaler de manière assez détaillée, c'est donc une opération réaliste pour décrire le fichier de paramètres en fonction de l'environnement et l'ignorer, ou pour décrire les règles en fonction de l'environnement. Je pense.
Si vous écrivez le traitement de cette zone comme un shell, ce sera comme suit.
$ cat tools/lint
ret=0
for dir in ${PROJECTS}; do
if ${WORKDIR}/is_changed "${dir}"; then
cd ${WORKDIR}/../${dir}/
sudo pip install -r requirements.txt
pep8 ${WORKDIR}/../${dir}/*.py --config ${WORKDIR}/../.config/pep8
pyflakes ${WORKDIR}/../${dir}/*.py
r=$?
if [ $r != 0 ]; then ret=$r; fi
else
echo "nothing change."
fi
done
exit $ret
Avec le contenu ci-dessus, je pense que le CI général peut être implémenté, mais dans le cas de charice, il est nécessaire de préparer un fichier de paramétrage ** (config.json, deploy /) ** pour chaque étape, et ce paramètre Je souhaite également vérifier la validité du fichier.
Le moyen le plus simple de le faire est d'exécuter simplement la commande calice package
sur CI / CD et de voir si vous pouvez empaqueter calice correctement pour vérifier la validité du fichier de configuration.
$ cat tools/package
for dir in ${PROJECTS}; do
if ${WORKDIR}/is_changed "${dir}"; then
cd ${WORKDIR}/../${dir}/
sudo pip install -r requirements.txt
chalice package /tmp/${CIRCLE_SHA1}
else
echo "nothing change."
fi
done
De nos jours, il existe de nombreux cas sensibles concernant la sécurité des applications, je ne veux donc pas faire entrer le code le plus dérangeant possible dans l'application. Par conséquent, je voudrais vérifier à chaque fois au moment du CI pour voir si l'une des bibliothèques que j'utilise contient des vulnérabilités.
Je pense qu'il existe des solutions, mais ici nous utilisons le service d'une entreprise de sécurité appelée ** snyk ** (https://snyk.io/).
snyk est un SaaS qui offre la possibilité d'effectuer un test de vulnérabilité (diagnostic de vulnérabilité) dans le code source. Il prend en charge divers langages, mais bien sûr Python utilisé par Chalice est également pris en charge.
En gros, regardez le contenu de requirements.txt
pour comprendre la bibliothèque utilisée, et vérifiez si la version de la bibliothèque incluse dans la base de données de vulnérabilité est incluse.
Comme il est facile de se lier à GitHub, il est facile de l'incorporer dans le flux CI. Il est illimité pour les OSS publics et vous pouvez l'utiliser gratuitement jusqu'à 200 tests dans votre référentiel privé. https://snyk.io/plans/
Plutôt que d'écrire la définition dans circle.yml, snyk se présente sous la forme d'un lien avec GitHub. Je laisserai la méthode de réglage détaillée, etc. au document officiel. https://snyk.io/docs/github/
auto deploy Enfin, à propos de la partie CD de CI / CD. Puisque le calice peut être facilement déployé avec une commande telle que «calice deploy», il est facile de déployer automatiquement une source qui ne pose aucun problème en raison de CI.
Ce qui suit est le processus de déploiement de calice
au dernier état uniquement pour les projets avec des différences écrites en shell.
$ cat tools/deploy
for dir in ${PROJECTS}; do \
echo "${WORKDIR}/../${dir}/"
if ${WORKDIR}/is_changed "${dir}"; then
cd ${WORKDIR}/../${dir}/
sudo pip install -r requirements.txt
AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} chalice deploy --stage ${STAGE}
else
echo "nothing change."
fi
done
Je pense qu'il est controversé d'utiliser les outils CI pour le déploiement automatique dans les environnements de production. (Dans mon environnement, je n'effectue pas de déploiement automatique dans l'environnement de production, mais souvent uniquement dans l'environnement de vérification)
AWS Chalice est un framework qui vous permet d'écrire facilement un traitement sans serveur sous la forme d'Heroku, bien qu'il soit limité à Python, et je pense qu'il a l'avantage de pouvoir écrire un traitement Lambda comme une application normale. Et en raison de ses avantages, il est facile de l'intégrer dans le flux CI / CD comme décrit ci-dessus, même dans un environnement sans serveur tel que Lambda.
Alors utilisons tous aussi Chalice. Happy Chalice Life and Serverless Life!!