[PYTHON] La fonction Lambda déploie les meilleures pratiques avec CircleCI + Lamvery

Préface

AWS Lambda est basé sur les événements et peut exécuter autant de code que nécessaire en cas de besoin sans instance EC2, et cela coûte de l'argent juste pour lancer la facturation. Contrairement à EC2, c'est un service très puissant et attrayant qui ne facture que ce que vous utilisez complètement.

Cependant, j'estime que ce service est souvent gênant et ennuyeux, probablement parce qu'il existe de nombreux concepts uniques qui n'existaient pas dans le passé, contrairement à son concept léger et simple.

C'est pourquoi je crée un outil appelé Lamvery parce que je veux l'utiliser plus facilement et pratiquement. Dans la partie du déploiement qui me paraissait problématique, j'ai pu créer un flux qui peut être considéré comme la meilleure pratique pour moi pour le moment, je voudrais donc le présenter.

Trois défis dans le déploiement de la fonction Lambda

① Créer un package de déploiement

② Gestion des versions

--Spécifications spéciales de versionnage de Lambda http://dev.classmethod.jp/cloud/aws/lambda-versioning/ --Association d'opérations de branche telles que Git avec l'environnement Lambda (staging et production, etc.)

③ Développement du flux de déploiement

Il n'y a pas encore de bonnes pratiques, ou je n'ai presque rien vu ici. [^ 1]

Ce qui peut être résolu par cette méthode

① Créer un package de déploiement Python (Node.js devrait également fonctionner)

Premièrement, Lamvery lui-même a la capacité de créer facilement un package de déploiement dans virtauluenv et de le déployer. Donc, tout ce que vous avez à faire est de créer un environnement virutalenv propre dans l'environnement Python de CircleCI, d'y installer et de déployer les bibliothèques requises. Vous pouvez simplement déployer le répertoire actuel et ci-dessous dans un zip, donc Node.js devrait être capable de faire de même si vous incluez package.json dans le référentiel et appuyez sur npm install. [^ 2]

(2) Liaison avec la branche Git en utilisant les spécifications de versionnage spéciales de Lambda

En utilisant l'alias attaché à la version de Lambda et en tirant parti de la caractéristique que la fonction peut être exécutée en spécifiant l'alias individuellement, il fournit un environnement d'exécution individuel lié à la branche.

③ Flux de déploiement basé sur la demande d'extraction

Ce qu'on appelle un tel gars → http://d.hatena.ne.jp/naoya/20140502/1399027655 C'est une histoire que si vous pouvez faire ②, vous pouvez la faire.

Méthodes et procédures

En passant, voici la vérification réelle de ce contenu. https://github.com/marcy-terui/lamvery-circleci-deploy

L'endroit pour activer le référentiel correspondant dans CircleCI est le même que d'habitude, je vais donc l'omettre.

1. Paramètres IAM

Non seulement le rôle IAM attribué à la fonction Lambda, mais également le jeu d'utilisateurs IAM dans CircleCI est requis.

Stratégie de rôle IAM attribuée à la fonction Lambda

Cela dépend de ce que vous voulez que la fonction fasse, mais si vous souhaitez transférer des informations confidentielles à l'aide de KMS, qui est une fonction unique de Lamvery, l'autorité minimale est la suivante.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt"
            ],
            "Resource": [
                "arn:aws:kms:<region>:<account-number>:key/<key-id>"
            ]
        }
    ]
}

Remplacez «<région>», «<numéro de compte>», «<id-clé>» selon le cas. Cliquez ici pour savoir comment créer une clé KMS (émettre un identifiant de clé) ↓ https://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/create-keys.html

** Notez l'ARN [^ 3] car ce rôle sera utilisé dans les chapitres suivants. ** **

Stratégie utilisateur IAM à définir dans CircleCI

Je ne pense pas qu'il y ait beaucoup de changement ici. S'il est gênant de définir une par une, lambda: * autorise toutes les ressources (" Resource ":" * "), mais dans certains cas, cela peut être ant, mais ʻiam: PassRole` autorise toutes les ressources C'est très dangereux, vous devriez donc l'arrêter. [^ 4]

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:*",
                "iam:PassRole"
            ],
            "Resource": [
                "arn:aws:lambda:<region>:<account-number>:function:<function-name>",
                "arn:aws:lambda:<region>:<account-number>:function:<function-name>:*",
                "<function-role-arn>"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "lambda:CreateFunction",
                "lambda:ListFunctions",
                "lambda:ListVersionsByFunction"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}

Remplacez «<région>», «<numéro de compte>», «» selon le cas. Le «» contient l'ARN de rôle [^ 3] créé précédemment.

** Notez les informations d'identification de cet utilisateur, car nous les utiliserons dans le chapitre suivant. ** **

Obtenez les informations d'identification de l'utilisateur IAM et définissez-les dans CircleCI

  1. Ouvrez les paramètres du projet image
  2. Sélectionnez Autorisation AWS image
  3. Entrez les informations d'identification image

2. Installation et configuration de Lamvery

Installez Lamvery et générez le fichier de configuration

$ pip install lamvery
$ lamvery init
lamvery: Output initial file: .lamvery.yml
lamvery: Output initial file: .lamvery.exclude.yml
lamvery: Output initial file: .lamvery.event.yml
lamvery: Output initial file: .lamvery.secret.yml

Modifier le fichier de paramètres

Remplacez chaque paramètre sous «région» et «configuration» selon le cas. Si la partie de {{env ['AWS_LAMBDA_ROLE']}} est un dépôt privé, je pense que ce n'est pas grave si l'ARN du rôle est dans le dépôt. Si vous souhaitez passer de la variable d'environnement de la même manière, vous pouvez la définir dans "Paramètres du projet" -> "Variables d'environnement" sur CircleCI.

yaml:.lamvery.yml


profile: null
region: us-east-1
versioning: false
default_alias: master
configuration:
  name: lamvery-deploy-sample
  runtime: python2.7
  role: {{ env['AWS_LAMBDA_ROLE'] }}
  handler: lambda_function.lambda_handler
  description: This is a sample lambda function.
  timeout: 10
  memory_size: 128

Points de réglage

Implémenter la fonction et énumérer les bibliothèques requises

L'implémentation de la fonction n'est que du codage Python, je vais donc l'omettre. Dans l'exemple ci-dessus, «handler» est «lambda_function.lambda_handler», donc le fichier sera comme suit.

lambda_function.py


import lamvery


def lambda_handler(event, context):
    print(lamvery.secret.get('foo'))

Dans les projets Python, je l'écris souvent dans requirements.txt, donc cette fois je le fais. Il est recommandé d'installer les bibliothèques nécessaires dans virtualenv comme indiqué ci-dessous, puis de les écrire dans un fichier.

pip install flake8
pip freeze > requirements.txt

En faisant cela, vous pouvez installer la même bibliothèque en exécutant ce qui suit sur CircleCI.

pip install -r requirements.txt

Décrivez les paramètres CircleCI

Décrivez comme suit.

circle.yml


---
machine:
  python:
    version: 2.7

dependencies:
  pre:
    - |
      virtualenv .venv
      source .venv/bin/activate
      pip install -r requirements.txt

test:
  override:
    - |
      source .venv/bin/activate
      flake8 lambda_function.py

deployment:
  master-head:
    branch: master
    commands:
      - |
        source .venv/bin/activate
        lamvery deploy
  staging:
    branch: staging
    commands:
      - |
        source .venv/bin/activate
        lamvery deploy -a staging -p
  production:
    branch: production
    commands:
      - |
        source .venv/bin/activate
        lamvery deploy -a production -p

Points de réglage

--Créez un environnement virtauluenv propre avec dependencies.pre et installez-y les bibliothèques nécessaires Lamvery est également inclus (si vous ne transmettez pas d'informations confidentielles, Lamvery n'est pas nécessaire pour la fonction elle-même, vous pouvez donc l'installer séparément)

Let's deploy! Faites une demande d'extraction et essayez de fusionner.

image

Voyons le résultat du déploiement.

image

Si vous regardez les journaux colorés, vous pouvez voir qu'une nouvelle version appelée «4» a été publiée et a été renommée en «production».

Au fait, je pense que l'alias production-pre est défini en même temps, mais c'est pour la restauration, et vous pouvez revenir en arrière en cas d'urgence comme suit. Vous pouvez le frapper à portée de main, ou vous pouvez le frapper avec ChatBot.

$ lamvery rollback -a production
lamvery: [Function] Previous version: 2
lamvery: [Alias] production: 4 -> 2

À propos de l'exécution de la fonction déployée

Lors de l'exécution à partir de divers événements, veuillez noter que chaque alias a un ARN individuel [^ 3]. Il sera précisé comme suit. Dans le cas de l'API, l'alias peut être spécifié par le paramètre «Qualifier». arn:aws:lambda:<region>:<account-number>:function:<function-name>:<alias>

Résumé

L'un des objectifs de la création d'un outil appelé Lamvery était de créer un flux de déploiement de fonction Lambda que je pensais être "ceci!" Alors je l'ai présenté. Jusqu'à présent, il n'y a pas de grande différence par rapport à la méthode utilisée dans EC2, etc.

https://github.com/marcy-terui/lamvery

TODO: Créer un modèle CloudFormation qui s'automatise jusqu'à l'avant de CircleCI

[^ 1]: La seule chose que j'ai trouvée était ceci. C'est très bien fait, mais cette fois c'est plus spécifique au déploiement et la direction est différente. [^ 2]: Node.js n'a pas été vérifié, donc je serais heureux si vous pouviez l'essayer et rapporter les résultats (Java ...?) [^ 3]: Abréviation de Amazon Resource Name [^ 4]: Vous pourrez attribuer n'importe quel rôle → Vous pouvez spécifier si vous avez un rôle avec des privilèges Admin ou PowerUser → Vous pouvez faire ce que vous voulez via Lambda [^ 5]: C'est une expression difficile, mais je ne peux penser à rien d'autre. .. ..

Recommended Posts

La fonction Lambda déploie les meilleures pratiques avec CircleCI + Lamvery
Déployer Django sans serveur avec Lambda
Développement AWS Lambda Mes meilleures pratiques
Meilleures pratiques personnelles lors de la mise au point avec Chainer
Meilleures pratiques pour manipuler les données avec les pandas
[Piyopiyokai # 1] Jouons avec Lambda: création d'une fonction Lambda
python3x: fonction lambda
Créer une fonction Lambda de version Python (+ couche Lambda) avec Serverless Framework
Déployez en toute sécurité des fonctions Lambda à l'aide de Python construit avec les mêmes options qu'Amazon Linux