我使用运行时Python 3.7使用main.py
和入口点handler
函数为AWS Lambda创建了一个zip文件。
使用3.7.3 python将zip文件打包在EC2上的Amazon Linux映像中。
我在AWS lambda上运行时遇到一些错误,因此决定是否可以在本地运行该功能。
我的main.py在下面:
import datetime
import logging
import os
import re
import subprocess
import boto3
import certbot.main
import raven
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def list_files(folder_path):
onlyfiles = [f for f in listdir(folder_path) if path.isfile(path.join(folder_path, f))]
logger.info('## path')
logger.info(onlyfiles)
def read_and_delete_file(path):
with open(path, 'r') as file:
contents = file.read()
os.remove(path)
return contents
def provision_cert(email, domains):
certbot.main.main([
'certonly', # Obtain a cert but don't install it
'-n', # Run in non-interactive mode
'--agree-tos', # Agree to the terms of service,
'--email', email, # Email
'--dns-route53', # Use dns challenge with route53
'-d', domains, # Domains to provision certs for
# Override directory paths so script doesn't have to be run as root
'--config-dir', '/tmp/config-dir/',
'--work-dir', '/tmp/work-dir/',
'--logs-dir', '/tmp/logs-dir/',
])
first_domain = domains.split(',')[0]
first_domain_cert_folder = re.sub('\*\.', '', first_domain)
path = '/tmp/config-dir/live/' + first_domain_cert_folder + '/'
logger.info('## path')
logger.info(path)
list_files(path)
return {
'certificate': read_and_delete_file(path + 'cert.pem'),
'private_key': read_and_delete_file(path + 'privkey.pem'),
'certificate_chain': read_and_delete_file(path + 'fullchain.pem')
}
def should_provision(domains):
existing_cert = find_existing_cert(domains)
if existing_cert:
now = datetime.datetime.now(datetime.timezone.utc)
not_after = existing_cert['Certificate']['NotAfter']
return (not_after - now).days <= 30
else:
return True
def find_existing_cert(domains):
domains = frozenset(domains.split(','))
client = boto3.client('acm')
paginator = client.get_paginator('list_certificates')
iterator = paginator.paginate(PaginationConfig={'MaxItems':1000})
for page in iterator:
for cert in page['CertificateSummaryList']:
cert = client.describe_certificate(CertificateArn=cert['CertificateArn'])
sans = frozenset(cert['Certificate']['SubjectAlternativeNames'])
if sans.issubset(domains):
return cert
return None
def notify_via_sns(topic_arn, domains, certificate):
process = subprocess.Popen(['openssl', 'x509', '-noout', '-text'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, encoding='utf8')
stdout, stderr = process.communicate(certificate)
client = boto3.client('sns')
client.publish(TopicArn=topic_arn,
Subject='Issued new LetsEncrypt certificate',
Message='Issued new certificates for domains: ' + domains + '\n\n' + stdout,
)
def upload_cert_to_acm(cert, domains):
existing_cert = find_existing_cert(domains)
certificate_arn = existing_cert['Certificate']['CertificateArn'] if existing_cert else None
client = boto3.client('acm')
acm_response = client.import_certificate(
CertificateArn=certificate_arn,
Certificate=cert['certificate'],
PrivateKey=cert['private_key'],
CertificateChain=cert['certificate_chain']
)
return None if certificate_arn else acm_response['CertificateArn']
def handler(event, context):
try:
domains = os.environ['LETSENCRYPT_DOMAINS']
if should_provision(domains):
cert = provision_cert(os.environ['LETSENCRYPT_EMAIL'], domains)
upload_cert_to_acm(cert, domains)
notify_via_sns(os.environ['NOTIFICATION_SNS_ARN'], domains, cert['certificate'])
except:
client = raven.Client(os.environ['SENTRY_DSN'], transport=raven.transport.http.HTTPTransport)
client.captureException()
raise
zip文件约为20mb。我在AWS上发现resources关于本地调试的信息,但是坦率地说,我对如何入门感到迷茫。
尽管我对Python相当满意,但总体上我对AWS和Lambda不太熟悉。
我正在使用macOS操作系统,并使用Visual Studio代码作为编辑器。如果可以的话,我可以在Mac上创建virtualenv。
如何在本地macbook pro上调试lambda?
答案 0 :(得分:1)
您已经发现,可以使用AWS SAM(与Docker)在本地进行调试。
下面是逐步入门指南:
先决条件
创建示例项目
可帮助您了解结构并在本地进行调试-然后,您可以用示例代码代替自己的代码。
sam init --runtime python3.7
添加依赖项
pipenv shell
pipenv install package-names
在本地运行和调试
pipenv lock -r > requirements.txt
sam build --manifest requirements.txt
sam local invoke HelloWorldFunction --event event.json
部署到AWS Lambda
根据需要制作一个新存储桶,以在其中存储功能代码:
aws s3 mb s3://bucket-name
创建并运行.sh脚本:
#!/bin/bash
pipenv lock -r > requirements.txt && sam build --manifest requirements.txt
sam package \
--output-template-file packaged.yaml \
--s3-bucket bucket-name
sam deploy \
--template-file packaged.yaml \
--stack-name name-of-lambda-stack \
--capabilities CAPABILITY_IAM \
--region us-east-1
替换:
bucket-name
,带有用于存储功能代码的S3存储桶的名称name-of-lambda-stack
,其名称为要部署到的AWS Lambda Stack us-east-1
和另一个region(如果需要)您的功能现在已部署到AWS Lambda。