GNU/Linux >> LINUX-Kenntnisse >  >> Panels >> Docker

Terraform – Bereitstellen von Python Lambda (Container-Image)

Ende 2020 kündigte AWS die Unterstützung von Container-Images für Lambda an. Mit dieser Funktion können Sie Lambda-Funktionen als Container-Images mit einer Größe von bis zu 10 GB verpacken und bereitstellen. In diesem Artikel wird beschrieben, wie Sie mit Terraform Python-Lambda-Funktionen bereitstellen können, die durch das Container-Image unterstützt werden. In diesem Artikel behandeln wir, wie Sie Terraform verwenden können, um Python-Lambda-Funktionen bereitzustellen, die durch das Container-Image unterstützt werden.

Eine der häufigsten Aufgaben in der Cloud-Welt ist das Replizieren von Quellcode-Repositories von On-Premises in die Cloud oder zwischen Cloud-Umgebungen. Um den Ansatz zu veranschaulichen, haben wir uns entschieden, der Lambda-Funktion Git- und GitPython-Unterstützung hinzuzufügen.

Projektstruktur

Hier ist eine Projektstruktur, die wir während dieser Demo verwenden werden:

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

2 directories, 4 files
  • lambdas – der Ordner, in dem wir den Quellcode der Lambda-Funktionen abgelegt haben
  • main.tf – Terraform-Democode, der den Docker-Container für die git_client-Lambda-Funktion erstellt und die Funktion anschließend bereitstellt

Dockerfile

Lassen Sie uns einen Docker-Container beschreiben, der alle Abhängigkeiten für unsere Lambda-Funktionen hostet. Hier ist das Dockerfile Inhalt:

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" ]

Wir nehmen das öffentliche Docker-Image von Python 3.8 von Amazon als Basis. Dann installieren wir Git, bereinigen die yum-Caches, um den Container kleiner zu machen, und installieren die erforderlichen Abhängigkeiten, die es uns ermöglichen, Git mit CodeCommit unter Verwendung von IAM zur Authentifizierung zu verwenden.

Als nächstes kopieren wir die index.py Datei in den Ordner, in dem sich der Lambda-Funktionscode befinden sollte. Weitere Informationen finden Sie unter Verwenden von AWS Lambda-Umgebungsvariablen.

Schließlich geben wir an, dass die Handler-Methode aus der Datei index.py beim Containerstart ausgeführt werden soll.

Lambda-Code

Sobald die Deklaration des Lambda-Containers abgeschlossen ist, können wir eine Lambda-Funktion schreiben, die sie verwendet. Hier ist ein Codebeispiel, das zeigt, wie man ein Git-Repository klont. Ich bin sicher, Sie können dieses Beispiel an Ihre persönlichen Bedürfnisse anpassen:

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()

In diesem Code deklarieren wir erforderliche Python-Bibliotheken, einige Konstanten, den Logger und einige Funktionen:

  • def clone(branch='master') – diese Funktion zeigt, wie man ein Git-Repository klont
  • def handler(event, context) – Diese Funktion ist der Haupteinstiegspunkt zur Lambda-Funktion, sie protokolliert das eingehende Ereignis und ruft clone auf Funktion

Terraform-Code

Sobald wir Lambda-Code haben und seinen Container deklarieren, können wir etwas Terraform-Code schreiben, um die Bereitstellung zu automatisieren. Hier ist es:

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
}

Dieser Terraform-Code wurde mit Terraform Version 0.14.8 getestet.

In diesem Beispiel verwenden wir die folgenden Terraform-Ressourcen:

  • aws_ecr_repository – Erstellt eine ECR-Registrierung, in der Terraform das Docker-Container-Image speichert, das später von unserer Lambda-Funktion verwendet wird
  • null_resource – wird verwendet, um Docker-Container zu erstellen und in die ECR-Registrierung zu übertragen, löst Prüfungen von Änderungen im Lambda-Funktionscode und in der Docker-Datei aus und ermöglicht es Terraform zu verstehen, wann das Image neu erstellt und die Lambda-Funktion aktualisiert werden muss
  • aws_ecr_image – ermöglicht es uns, Informationen über veröffentlichte Docker-Images abzufragen
  • aws_iam_role , aws_iam_policy_document und aws_iam_policy – deklariert eine Berechtigung (Protokolle an CloudWatch senden, CodeCommit-Zugriff) für die Lambda-Funktion
  • aws_lambda_function – Deklaration der Lambda-Funktion selbst

Bereitstellung

Um die Lösung zu testen, müssen Sie zuerst Terraform-Code bereitstellen:

terraform init
terraform apply -auto-approve

Dann müssen Sie die Lambda-Funktion ausführen:

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

Hier ist eine erwartete Ausgabe:

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

Aufräumen

Um alles zu bereinigen, führen Sie den folgenden Befehl aus:

terraform destroy

Zusammenfassung

Dieser Artikel hat einen Docker-Container für die AWS Lambda-Funktion erstellt und die gesamte Lösung mit Terraform bereitgestellt. Wir hoffen, Sie fanden diesen Artikel hilfreich. Wenn ja, helfen Sie uns bitte, es in der Welt zu verbreiten. Wenn Sie Fragen haben, können Sie diese gerne im Chat-Bereich unten stellen.


Docker
  1. So erstellen Sie einen Anaconda Python Data Science Docker-Container

  2. Datei aus Docker-Image extrahieren?

  3. So stellen Sie einen Nginx-Container mit Docker auf Linode bereit

  4. Aktualisieren eines bereitgestellten Containers basierend auf einem Docker-Image

  5. So erstellen Sie ein Docker-Image aus einem Container und einer Docker-Datei

So erstellen Sie ein Docker-Image aus einem laufenden Container

Stellen Sie eine Produktions-Docker-MariaDB-Installation bereit

So stellen Sie einen Docker-Container in AWS Elastic Beanstalk bereit

So stellen Sie eine Python Flask-API-Anwendung auf Docker bereit

So stellen Sie einen Docker-MongoDB-Container bereit und verwalten ihn

So verwenden Sie Docker Commit zum Ändern von Container-Images