GNU/Linux >> Belajar Linux >  >> Panels >> Docker

Terraform – Menyebarkan Python Lambda (gambar kontainer)

Pada akhir tahun 2020, AWS mengumumkan dukungan image container untuk Lambda. Fitur ini memungkinkan Anda untuk mengemas dan menerapkan fungsi Lambda sebagai gambar kontainer berukuran hingga 10 GB. Artikel ini akan membahas bagaimana Anda dapat menggunakan Terraform untuk menerapkan fungsi Python Lambda yang didukung oleh image container. Dalam artikel ini, kami membahas bagaimana Anda dapat menggunakan Terraform untuk men-deploy fungsi Python Lambda yang didukung oleh image container.

Salah satu tugas umum di dunia cloud adalah mereplikasi repositori kode sumber dari lokal ke cloud atau antara lingkungan cloud. Jadi, untuk mengilustrasikan pendekatannya, kami memutuskan untuk menambahkan dukungan Git dan GitPython ke fungsi Lambda.

Struktur proyek

Berikut adalah struktur proyek yang akan kita gunakan selama demo ini:

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

2 directories, 4 files
  • lambdas – folder tempat kita meletakkan kode sumber fungsi Lambda
  • main.tf – Kode demo Terraform, yang akan membangun wadah Docker untuk fungsi git_client Lambda dan menerapkan fungsi setelahnya

Dockerfile

Mari kita jelaskan wadah Docker yang akan menampung semua dependensi untuk fungsi lambda kita. Berikut Dockerfile konten:

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

Kami mengambil gambar Docker publik Python 3.8 dari Amazon sebagai basis. Kemudian kami menginstal Git, membersihkan cache yum untuk membuat wadah lebih kecil, dan menginstal dependensi yang diperlukan, yang memungkinkan kami menggunakan Git dengan CodeCommit menggunakan IAM untuk otentikasi.

Selanjutnya, kita menyalin index.py file ke folder tempat kode fungsi Lambda harus berada. Periksa Menggunakan variabel lingkungan AWS Lambda untuk informasi tambahan.

Terakhir, kami menetapkan untuk menjalankan metode handler dari file index.py pada peluncuran container.

Kode Lambda

Segera setelah deklarasi wadah Lambda diselesaikan, kita dapat menulis fungsi Lambda, yang akan menggunakannya. Berikut adalah contoh kode, yang akan menunjukkan cara mengkloning repositori Git. Saya yakin, Anda dapat menyesuaikan contoh ini untuk kebutuhan pribadi Anda:

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

Dalam kode ini, kami mendeklarasikan pustaka Python yang diperlukan, beberapa konstanta, logger konfigurasi, dan beberapa fungsi:

  • def clone(branch='master') – fungsi ini menunjukkan cara mengkloning repositori Git
  • def handler(event, context) – fungsi ini adalah titik masuk utama ke fungsi Lambda, ia mencatat peristiwa yang masuk dan memanggil clone fungsi

Kode terraform

Segera setelah kami memiliki kode Lambda dan mendeklarasikan wadahnya, kami dapat menulis beberapa kode Terraform untuk mengotomatiskan penerapan. Ini dia:

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
}

Kode Terraform ini diuji menggunakan Terraform versi 0.14.8.

Dalam contoh ini, kami menggunakan sumber daya terraform berikut:

  • aws_ecr_repository – membuat registri ECR tempat Terraform akan menyimpan image container Docker, yang nantinya akan digunakan oleh fungsi Lambda
  • null_resource – digunakan untuk membangun wadah Docker dan mendorongnya ke registri ECR, memicu pemeriksaan perubahan dalam kode fungsi Lambda dan Dockerfile dan memungkinkan Terraform memahami kapan harus membangun kembali gambar dan memperbarui fungsi Lambda
  • aws_ecr_image – memungkinkan kami untuk menanyakan informasi tentang gambar Docker yang dipublikasikan
  • aws_iam_role , aws_iam_policy_document dan aws_iam_policy – mendeklarasikan izin (mengirim log ke CloudWatch, akses CodeCommit) untuk fungsi Lambda
  • aws_lambda_function – Deklarasi fungsi Lambda itu sendiri

Penerapan

Untuk menguji solusi, Anda perlu menerapkan kode Terraform terlebih dahulu:

terraform init
terraform apply -auto-approve

Maka Anda perlu menjalankan fungsi Lambda:

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

Inilah hasil yang diharapkan:

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

Membersihkan

Untuk membersihkan semuanya, jalankan perintah berikut:

terraform destroy

Ringkasan

Artikel ini membuat container Docker untuk fungsi AWS Lambda dan menerapkan seluruh solusi menggunakan Terraform. Kami harap Anda menemukan artikel ini bermanfaat. Jika demikian, tolong, bantu kami untuk menyebarkannya ke seluruh dunia. Jika Anda memiliki pertanyaan, jangan ragu untuk menanyakannya di bagian obrolan di bawah.


Docker
  1. Bagaimana membangun wadah Docker Ilmu Data Anaconda Python

  2. Cara Menyebarkan PostgreSQL sebagai Wadah Docker

  3. Memperbarui container yang di-deploy berdasarkan image Docker

  1. Cara Menyebarkan Wadah nginx dengan Docker di Linode

  2. Cara membuat Gambar Docker dari Wadah dan File Docker

  3. Komit data dalam wadah mysql

  1. Cara Menyebarkan PostgreSQL di Docker Container

  2. Ekstrak File Dari Gambar Docker?

  3. Cara menginstal Docker dan menyebarkan LAMP Stack