GNU/Linux >> Tutoriels Linux >  >> Panels >> Docker

Terraform – Déployer Python Lambda (image conteneur)

Fin 2020, AWS a annoncé la prise en charge des images de conteneurs pour Lambda. Cette fonctionnalité vous permet de regrouper et de déployer des fonctions Lambda en tant qu'images de conteneur d'une taille maximale de 10 Go. Cet article explique comment vous pouvez utiliser Terraform pour déployer des fonctions Python Lambda basées sur l'image du conteneur. Dans cet article, nous expliquons comment vous pouvez utiliser Terraform pour déployer des fonctions Python Lambda basées sur l'image du conteneur.

L'une des tâches courantes dans le monde du cloud consiste à répliquer les référentiels de code source sur site vers le cloud ou entre les environnements cloud. Ainsi, pour illustrer l'approche, nous avons décidé d'ajouter la prise en charge de Git et GitPython à la fonction Lambda.

Structure du projet

Voici une structure de projet que nous utiliserons au cours de cette démo :

$ tree lambda_container
lambda_container
├── README.md
├── lambdas
│   └── git_client
│       ├── Dockerfile
│       └── index.py
└── main.tf

2 directories, 4 files
  • lambdas – le dossier où nous mettons le code source des fonctions Lambda
  • main.tf – Code de démonstration Terraform, qui construira le conteneur Docker pour la fonction Lambda git_client et déploiera la fonction par la suite

Fichier Docker

Décrivons un conteneur Docker qui hébergera toutes les dépendances de nos fonctions lambda. Voici le Dockerfile contenu :

FROM public.ecr.aws/lambda/python:3.8

RUN yum update -y && \
  yum install -y git && \
  rm -Rf /var/cache/yum && \
  pip install git-remote-codecommit boto3 GitPython awscli

COPY index.py ${LAMBDA_TASK_ROOT}

CMD [ "index.handler" ]

Nous prenons l'image Docker publique Python 3.8 d'Amazon comme base. Ensuite, nous installons Git, nettoyons les caches yum pour réduire la taille du conteneur et installons les dépendances requises, ce qui nous permet d'utiliser Git avec CodeCommit en utilisant IAM pour l'authentification.

Ensuite, nous copions le index.py fichier dans le dossier où le code de la fonction Lambda doit résider. Consultez Utilisation des variables d'environnement AWS Lambda pour plus d'informations.

Enfin, nous spécifions d'exécuter la méthode du gestionnaire à partir du fichier index.py au lancement du conteneur.

Code lambda

Dès que la déclaration du conteneur Lambda est finalisée, nous pouvons écrire une fonction Lambda, qui l'utilisera. Voici un exemple de code, qui montrera comment cloner le référentiel Git. Je suis sûr que vous pourrez adapter cet exemple à vos besoins personnels :

import logging
import os
import git
 
TMP_DIR = "/tmp"
REPO_DIR = 'aws-config-rules'
REPO_URL = f'https://github.com/andreivmaksimov/{REPO_DIR}'
CLONE_PATH = os.path.join(TMP_DIR, REPO_DIR)
 
LOGGER = logging.getLogger(__name__)
LOGGER.setLevel(logging.INFO)
 
def clone(branch='master'):
   repo = git.Repo.clone_from(REPO_URL, CLONE_PATH, branch=branch)
 
   with repo.config_writer() as git_config:
       git_config.set_value('user', 'email', '[email protected]')
       git_config.set_value('user', 'name', 'Git Lambda')
  
def handler(event, context):
   LOGGER.info('Event: %s', event)
 
   LOGGER.info('Cloning repo: %s', REPO_URL)
   clone()

Dans ce code, nous déclarons les bibliothèques Python requises, certaines constantes, la configuration de l'enregistreur et quelques fonctions :

  • def clone(branch='master') – cette fonction montre comment cloner le dépôt Git
  • def handler(event, context) – cette fonction est le point d'entrée principal de la fonction Lambda, elle enregistre l'événement entrant et appelle clone fonction

Code Terraform

Dès que nous avons du code Lambda et que nous déclarons son conteneur, nous pouvons écrire du code Terraform pour automatiser le déploiement. Le voici :

variable region {
 default = "us-east-1"
}
 
provider aws {
 region = var.region
}
 
data aws_caller_identity current {}
 
locals {
 prefix = "git"
 account_id          = data.aws_caller_identity.current.account_id
 ecr_repository_name = "${local.prefix}-demo-lambda-container"
 ecr_image_tag       = "latest"
}
 
resource aws_ecr_repository repo {
 name = local.ecr_repository_name
}
 
resource null_resource ecr_image {
 triggers = {
   python_file = md5(file("${path.module}/lambdas/git_client/index.py"))
   docker_file = md5(file("${path.module}/lambdas/git_client/Dockerfile"))
 }
 
 provisioner "local-exec" {
   command = <<EOF
           aws ecr get-login-password --region ${var.region} | docker login --username AWS --password-stdin ${local.account_id}.dkr.ecr.${var.region}.amazonaws.com
           cd ${path.module}/lambdas/git_client
           docker build -t ${aws_ecr_repository.repo.repository_url}:${local.ecr_image_tag} .
           docker push ${aws_ecr_repository.repo.repository_url}:${local.ecr_image_tag}
       EOF
 }
}
 
data aws_ecr_image lambda_image {
 depends_on = [
   null_resource.ecr_image
 ]
 repository_name = local.ecr_repository_name
 image_tag       = local.ecr_image_tag
}
 
resource aws_iam_role lambda {
 name = "${local.prefix}-lambda-role"
 assume_role_policy = <<EOF
{
   "Version": "2012-10-17",
   "Statement": [
       {
           "Action": "sts:AssumeRole",
           "Principal": {
               "Service": "lambda.amazonaws.com"
           },
           "Effect": "Allow"
       }
   ]
}
 EOF
}
 
data aws_iam_policy_document lambda {
   statement {
     actions = [
         "logs:CreateLogGroup",
         "logs:CreateLogStream",
         "logs:PutLogEvents"
     ]
     effect = "Allow"
     resources = [ "*" ]
     sid = "CreateCloudWatchLogs"
   }
 
   statement {
     actions = [
         "codecommit:GitPull",
         "codecommit:GitPush",
         "codecommit:GitBranch",
         "codecommit:ListBranches",
         "codecommit:CreateCommit",
         "codecommit:GetCommit",
         "codecommit:GetCommitHistory",
         "codecommit:GetDifferences",
         "codecommit:GetReferences",
         "codecommit:BatchGetCommits",
         "codecommit:GetTree",
         "codecommit:GetObjectIdentifier",
         "codecommit:GetMergeCommit"
     ]
     effect = "Allow"
     resources = [ "*" ]
     sid = "CodeCommit"
   }
}
 
resource aws_iam_policy lambda {
   name = "${local.prefix}-lambda-policy"
   path = "/"
   policy = data.aws_iam_policy_document.lambda.json
}
 
resource aws_lambda_function git {
 depends_on = [
   null_resource.ecr_image
 ]
 function_name = "${local.prefix}-lambda"
 role = aws_iam_role.lambda.arn
 timeout = 300
 image_uri = "${aws_ecr_repository.repo.repository_url}@${data.aws_ecr_image.lambda_image.id}"
 package_type = "Image"
}
 
output "lambda_name" {
 value = aws_lambda_function.git.id
}

Ce code Terraform a été testé avec Terraform version 0.14.8.

Dans cet exemple, nous utilisons les ressources terraform suivantes :

  • aws_ecr_repository – crée un registre ECR où Terraform enregistrera l'image du conteneur Docker, qui sera ensuite utilisée par notre fonction Lambda
  • null_resource - est utilisé pour créer un conteneur Docker et le pousser vers le registre ECR, déclenche des vérifications des modifications dans le code de la fonction Lambda et Dockerfile et permet à Terraform de comprendre quand reconstruire l'image et mettre à jour la fonction Lambda
  • aws_ecr_image – nous permet de demander des informations sur l'image Docker publiée
  • aws_iam_role , aws_iam_policy_document et aws_iam_policy – déclare une autorisation (envoyer des journaux à CloudWatch, accéder à CodeCommit) pour la fonction Lambda
  • aws_lambda_function – Déclaration de la fonction Lambda elle-même

Déploiement

Pour tester la solution, vous devez d'abord déployer le code Terraform :

terraform init
terraform apply -auto-approve

Ensuite, vous devez exécuter la fonction Lambda :

aws lambda invoke --function-name git-lambda out --log-type Tail --query 'LogResult' --output text |  base64 -d

Voici une sortie attendue :

START RequestId: b8b742d6-5bd6-4098-90e3-5e30f5c6e816 Version: $LATEST
[INFO]  2021-03-16T02:10:28.064Z        b8b742d6-5bd6-4098-90e3-5e30f5c6e816    Event: {}
[INFO]  2021-03-16T02:10:28.064Z        b8b742d6-5bd6-4098-90e3-5e30f5c6e816    Cloning repo: https://github.com/andreivmaksimov/aws-config-rules
END RequestId: b8b742d6-5bd6-4098-90e3-5e30f5c6e816
REPORT RequestId: b8b742d6-5bd6-4098-90e3-5e30f5c6e816  Duration: 4069.15 ms    Billed Duration: 6131 ms        Memory Size: 128 MB     Max Memory Used: 83 MB  Init Duration: 2061.73 ms

Nettoyage

Pour tout nettoyer, exécutez la commande suivante :

terraform destroy

Résumé

Cet article a créé un conteneur Docker pour la fonction AWS Lambda et déployé l'intégralité de la solution à l'aide de Terraform. Nous espérons que vous avez trouvé cet article utile. Si oui, s'il vous plaît, aidez-nous à le diffuser dans le monde. Si vous avez des questions, n'hésitez pas à les poser dans la section de chat ci-dessous.


Docker
  1. Comment créer un conteneur Anaconda Python Data Science Docker

  2. Extraire le fichier de l'image Docker ?

  3. Comment déployer un conteneur nginx avec Docker sur Linode

  4. Comment déployer PostgreSQL en tant que conteneur Docker

  5. Valider les données dans un conteneur mysql

Comment créer une image Docker à partir d'un conteneur en cours d'exécution

Déployer une installation de production Docker MariaDB

Comment déployer un conteneur Docker sur AWS Elastic Beanstalk

Comment déployer une application API Python Flask sur Docker

Comment déployer et gérer un conteneur Docker MongoDB

Comment utiliser Docker Commit pour modifier les images de conteneur