Running Certbot on AWS Lambda and upload certs to AWS Secrets Manager.
Inspired by kingsoftgames/certbot-lambda and Deploying EFF's Certbot in AWS Lambda.
- Supports wildcard certificates (Let's Encrypt ACME v2).
- Uploads certificates to AWS Secrets Manager.
- Runs on AWS Lambda.
- Supports automatic rotation.
- Supports 14 DNS providers.
Download latest version of certbot-lambda.zip
from releases.
- Create new lambda in Google Dashboard with
Python 3.11
runtime. - Upload
certbot-lambda.zip
atCode
>Code source
>Upload from
>.zip file
. - Update handler to
main.handler
atCode
>Runtime settings
>Handler
. - Create new
Execution role
atConfiguration
>Execution role
>Edit
>Create a new role from AWS policy templates
with namelambda-certbot
. - Go to created role by clicking on the name and
Attach policies
:SecretsManagerReadWrite
AmazonRoute53FullAccess
- Increase execution timeout in
Configuration
>General configuration
to 10 minutes and memory limit to 150Mb. - Add ENV variables at
Configuration
>Environment variables
(check bellow for required ENV variables). - Run lambda manually one time to create a secret by going to
Test
and executinghello-wold
template.
AWS secret can run created lambda periodically to generate new certs, for example, every month.
For that to work, update lambda and add new Resource-based policy
at Configuration
> Permissions
-> Add permissions
:
* AWS Service: Secrets Manager
* Statement ID: SecretsManagerAccess
* Principal: secretsmanager.amazonaws.com
* Action: lambda:InvokeFunction
Then go to AWS Secrets dashboard and create a rotation rule for created secrets - it should execute created lambda.
- Create new function in Google Cloud dashboard.
- Set trigger
Cloud Pub/Sub
(create new topic). - Add runtime environment variables according your needs (check configuration section and examples bellow).
- Increase timeout to
540
seconds. - Select
Python 3.11
runtime. - Select
Zip upload
source code type and uploadcertbot-lambda.zip
(you may need to create storage bucket where zip will be stored). - Deploy function.
Name | Description | Default/required |
---|---|---|
CERTBOT_EMAILS | Email used for registration and recovery contact. Use comma to register multiple emails, eg: u1@example.com,u2@example.com . |
required |
CERTBOT_DOMAINS | One or more domains that require certs generation. | required |
CERTBOT_DNS_PLUGIN | DNS provider plugin name for acme challenge. E.g. dns-cloudflare , find plugin list here. |
required |
CERTBOT_CREDENTIALS | Credentials file content depending on CERTBOT_DNS_PLUGIN . E. g. {\n"type": "service_account",\n...} for dns-google plugin. |
required except for route53 |
CERTBOT_SERVER | Letsencrypt API url. | https://acme-v02.api.letsencrypt.org/directory |
CERTBOT_DIR | Temporary certbot directory where logs and generated certs will be stored. | /tmp/certbot |
CERTBOT_PREFERRED_CHAIN | Force to use specified cert chain, e.g. ISRG Root X1 |
|
AWS_SECRET_NAME | AWS secret name template, {domain} will be replaced with domain name. | certbot-{domain} |
AWS_SECRET_DESCRIPTION | AWS secret name description text. | Auto generated SSL certificate by lambda-certbot |
CERTBOT_PROPAGATION_SECONDS | The number of seconds to wait for DNS to propagate before asking the ACME server to verify the DNS record. | Depends on dns plugin |
CERTBOT_EXTRA_ARGS | Additional arguments that will be passed to certbot. |
Each DNS challenge plugin requires different configuration, check documentation for more information.
Due to a bug in some versions of OpenSSL (1.0.0 - 1.0.2), GnuTLS (< 3.6.14), LibreSSL (< 3.2.0) and perhaps other TLS/SSL libraries as well, Let's Encrypt's certificates will be seen as invalid as a result of this invalid DST Root CA X3 certificate still being included.
To solve this issue, you can disable Root CA X3
certificate that is still included due to legacy support (mostly Android) by providing CERTBOT_PREFERRED_CHAIN=ISRG Root X1
environment variable.
Source: Laravel: Let's Encrypt Compatibility Changes
CERTBOT_EMAILS=name@example.com
CERTBOT_DOMAINS=*.example.com,example.com
CERTBOT_DNS_PLUGIN=dns-route53
In the lambda aws credentials are provided by default. Make sure lambda role has access to AWS Secrets and Route 53. Or you can configure them manually.
CERTBOT_EMAILS=name@example.com
CERTBOT_DOMAINS=*.example.com,example.com
CERTBOT_DNS_PLUGIN=dns-cloudflare
CERTBOT_CREDENTIALS="dns_cloudflare_api_token = 0123456789abcdef0123456789abcdef01234567"
In the lambda aws credentials are provided by default. Make sure lambda role has access to AWS Secrets. Or you can configure them manually.