Na konci roku 2020 společnost AWS oznámila podporu obrázků kontejnerů pro Lambda. Tato funkce vám umožňuje zabalit a nasadit funkce Lambda jako obrazy kontejnerů o velikosti až 10 GB. Tento článek se bude zabývat tím, jak můžete použít Terraform k nasazení funkcí Python Lambda podporovaných obrázkem kontejneru. V tomto článku se zabýváme tím, jak můžete použít Terraform k nasazení funkcí Python Lambda podporovaných obrázkem kontejneru.
Jedním z běžných úkolů v cloudovém světě je replikace úložišť zdrojového kódu z místního prostředí do cloudu nebo mezi cloudovými prostředími. Abychom tento přístup ilustrovali, rozhodli jsme se přidat do funkce Lambda podporu Git a GitPython.
Struktura projektu
Zde je struktura projektu, kterou budeme používat během této ukázky:
$ tree lambda_container
lambda_container
├── README.md
├── lambdas
│ └── git_client
│ ├── Dockerfile
│ └── index.py
└── main.tf
2 directories, 4 files
lambdas
– složka, kam jsme umístili zdrojový kód funkcí Lambdamain.tf
– Demo kód Terraform, který vytvoří kontejner Docker pro funkci git_client Lambda a poté funkci nasadí
Dockerfile
Pojďme si popsat kontejner Docker, který bude hostit všechny závislosti pro naše funkce lambda. Zde je Dockerfile
obsah:
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" ]
Jako základ bereme veřejný obrázek Dockeru Python 3.8 od Amazonu. Potom nainstalujeme Git, vyčistíme mezipaměti yum, aby se kontejner zmenšil, a nainstalujeme požadované závislosti, které nám umožňují používat Git s CodeCommit pomocí IAM pro ověřování.
Dále zkopírujeme index.py
do složky, kde by měl být kód funkce Lambda. Další informace naleznete v části Používání proměnných prostředí AWS Lambda.
Nakonec určíme, že se má při spuštění kontejneru spustit metoda handler ze souboru index.py.
Kód lambda
Jakmile je deklarace kontejneru Lambda dokončena, můžeme napsat funkci Lambda, která ji použije. Zde je příklad kódu, který ukáže, jak klonovat úložiště Git. Jsem si jistý, že tento příklad budete moci upravit pro své osobní potřeby:
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()
V tomto kódu deklarujeme požadované knihovny Pythonu, některé konstanty, konfigurační logger a několik funkcí:
def clone(branch='master')
– tato funkce ukazuje, jak klonovat úložiště Gitdef handler(event, context)
– tato funkce je hlavním vstupním bodem do funkce Lambda, zaznamenává příchozí událost a voláníclone
funkce
Kód Terraform
Jakmile máme kód Lambda a deklarujeme jeho kontejner, můžeme napsat nějaký kód Terraform pro automatizaci nasazení. Tady to je:
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
}
Tento kód Terraform byl testován pomocí Terraform verze 0.14.8.
V tomto příkladu používáme následující zdroje terraform:
aws_ecr_repository
– vytvoří registr ECR, kde Terraform uloží image kontejneru Docker, který bude později použit funkcí Lambdanull_resource
– používá se k sestavení kontejneru Docker a jeho odeslání do registru ECR, spouští kontroly změn v kódu funkce Lambda a Dockerfile a umožňuje společnosti Terraform pochopit, kdy znovu sestavit obraz a aktualizovat funkci Lambdaaws_ecr_image
– umožňuje nám dotazovat se na informace o publikovaném obrázku Dockeraws_iam_role
,aws_iam_policy_document
aaws_iam_policy
– deklaruje oprávnění (odesílat protokoly do CloudWatch, přístup CodeCommit) pro funkci Lambdaaws_lambda_function
– Samotná deklarace funkce lambda
Nasazení
Chcete-li řešení otestovat, musíte nejprve nasadit kód Terraform:
terraform init
terraform apply -auto-approve
Poté musíte provést funkci Lambda:
aws lambda invoke --function-name git-lambda out --log-type Tail --query 'LogResult' --output text | base64 -d
Zde je očekávaný výstup:
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
Úklid
Chcete-li vše vyčistit, spusťte následující příkaz:
terraform destroy
Shrnutí
Tento článek vytvořil kontejner Docker pro funkci AWS Lambda a nasadil celé řešení pomocí Terraformu. Doufáme, že vám tento článek byl užitečný. Pokud ano, pomozte nám to rozšířit do světa. Máte-li nějaké dotazy, neváhejte se je zeptat v sekci chatu níže.