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 Lambdamain.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 Gitdef handler(event, context)
– fungsi ini adalah titik masuk utama ke fungsi Lambda, ia mencatat peristiwa yang masuk dan memanggilclone
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 Lambdanull_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 Lambdaaws_ecr_image
– memungkinkan kami untuk menanyakan informasi tentang gambar Docker yang dipublikasikanaws_iam_role
,aws_iam_policy_document
danaws_iam_policy
– mendeklarasikan izin (mengirim log ke CloudWatch, akses CodeCommit) untuk fungsi Lambdaaws_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.