Let’s Encrypt with OCI Certificates Service
Mar 05, 2025I do a fair about of lab work in my OCI Tenancy. A lot of this work involves things like web servers, load balancers and other things that require X.509 certificates for TLS. For this work, I like to use the Let’s Encrypt CA, because you can’t beat the price and ease of use. This was working fine, but I found my normal process too manual. I often found myself configuring a lab with a new certificate, TLS would be working, and then when I came back to the lab a few months later everything would be expired! With certificate expiration dates getting shorter and shorter, I was looking for a way to fully automate renewals.
I came across a few blog posts from the Oracle A-Team, talking about Let’s Encrypt and using a certbot DNS plugin that works with OCI directly. Following these examples, I was able to generate Let’s Encrypt certificates for my labs in a fully automated process. However, this still left me manually renewing the certificates in services that used them for TLS. I had a few areas in my lab using nginx and the certbot handled that well enough, but what about my OCI Load Balancers that leveraged the OCI Certificates service? This brought me to the certbot renew --deploy-hook
functionality.
In the steps below I will walk through the full process of generating a new certificate, adding it to the OCI Certificates service, configuring an OCI Load Balancer to use it, and finally renewing the certificate while automatically deploying to OCI.
Creating Certificate
-
Follow the OCI and Certbot configuration steps via Christopher Johnson’s blog post.
- His post does a great job of walking you through the basic setup to get his certbot plugin working.
- For this demo, I will be using
~/certs
as a base directory for things like thecertbot-dns-oci
plugin, logs, work and config directories.
-
Now that
certbot
is configured, use it to generate a new certificate locally.export domain=certlab.psadmin.cloud cd ~/certs certbot certonly \ --logs-dir logs --work-dir work --config-dir config \ --dns-oci-instance-principal=y \ --authenticator dns-oci \ --email [email protected] \ --agree-tos \ --no-eff-email \ -d $domain
-
We now have a certificate! Let’s use
oci-cli
to create it in the OCI Certificates service.-
Get the OCID of the Compartment you want to manage certificates in and set some other variables.
# Variables ## OCI Certificate Compartment comp_id="ocid1.compartment.oc1..aaaaa<YOUR_CERT_COMP_ID>" ## Certbot Certificate config cert_dir="/home/opc/certs" cert_name="certlab.psadmin.cloud" chain="$(cat $cert_dir/config/live/$cert_name/chain.pem)" cert="$(cat $cert_dir/config/live/$cert_name/cert.pem)" privkey="$(cat $cert_dir/config/live/$cert_name/privkey.pem)"
-
Create the Certificate in OCI
# Create Certificate - Imported oci certs-mgmt certificate create-by-importing-config \ --auth instance_principal \ --compartment-id $comp_id \ --name $cert_name \ --cert-chain-pem "$chain" \ --certificate-pem "$cert" \ --private-key-pem "$privkey"
-
Validate the Certificate was created in OCI
# Validate Certificate oci certs-mgmt certificate list \ --auth instance_principal \ --compartment-id $comp_id \ --name $cert_name \ --output table --all \ --query "data.items[*].{Name:name,OCID:id}"
+-----------------------+----------------------------------------------------------------------------------------+ | Name | OCID | +-----------------------+----------------------------------------------------------------------------------------+ | certlab.psadmin.cloud | ocid1.certificate.oc1.iad.amaaaaaaha7drbiagvmy32yvpugesvbe6ca4ywf7treg3w6a44zrbvbeme5a | +-----------------------+----------------------------------------------------------------------------------------+
-
-
Now that we have a managed certificate, we can configure an OCI Load Balancer Listener to use it.
Renewing Certificate
-
Before we use
certbot
to renew our certificate, let’s create arenewal-hooks
script to deploy any updated certificates to the OCI Certificates service.-
Set variables and create a new renewal hooks script file.
cert_dir="/home/opc/certs" touch $cert_dir/config/renewal-hooks/deploy/oci_deploy.sh chmod a+x $cert_dir/config/renewal-hooks/deploy/oci_deploy.sh
-
Update the
oci_deploy.sh
script with the code below.# oci_deploy.sh - Deploy script for deploying renewed certs to OCI ### # Variables ## OCI Certificate Compartment comp_id="ocid1.compartment.oc1..<YOUR_COMP_OCID>" ## Assume single domain that shares OCI Certificate name cert_name="${RENEWED_DOMAINS?}" # certbot deploy-hook env var ## Certbot Certificate config cert_dir="${RENEWED_LINEAGE?}" # certbot deploy-hook env var chain="$(cat $cert_dir/chain.pem)" cert="$(cat $cert_dir/cert.pem)" privkey="$(cat $cert_dir/privkey.pem)" # Get Certificate OCID cert_id=$(oci certs-mgmt certificate list \ --auth instance_principal \ --compartment-id $comp_id \ --name $cert_name \ --all \ --query "data.items[0].id" \ --raw-output ) # Update Certificate oci certs-mgmt certificate \ update-certificate-by-importing-config-details \ --auth instance_principal \ --certificate-id "$cert_id" \ --certificate-pem "$cert" \ --private-key-pem "$privkey" \ --cert-chain-pem "$chain"
-
If you want to test this before using from
certbot
, run this script directly.# NOTE: A new certificate version should show in OCI with the same certificate. # Variables that can be used for testing outside of certbot
cert_dir="/home/opc/certs" export RENEWED_DOMAINS=certlab.psadmin.cloud export RENEWED_LINEAGE=$cert_dir/config/live/$RENEWED_DOMAINS $cert_dir/config/renewal-hooks/deploy/oci_deploy.sh -
Use
oci-cli
or the OCI Console to validate the new versions(same certificate).
-
-
Now that we validated our deploy hook script, let’s use
certbot
to renew our certificate and pass the--deploy-hook
argument.- This will generate a new certificate for us locally, as well as deploy it to OCI Certificates service.
- NOTE: By default,
certbot
will not renew a certificate unless it expires soon. For the purposes of this demo, I am passing the--force-renew
flag. In general this flag should be skipped so this command can be scheduled daily and it will only take action if needed.
cert_name=certlab.psadmin.cloud cd ~/certs certbot renew \ --logs-dir logs --work-dir work --config-dir config \ --dns-oci-instance-principal=y \ --authenticator dns-oci \ --cert-name $cert_name \ --deploy-hook config/renewal-hooks/deploy/oci_deploy.sh \ # --force-renew # Use for testing
-
Use
ocicli
or the OCI Console to validate the new versions(new certificate).
Conclusion
This was a pretty simple demo, using a very basic deploy hook script. It works great for my lab, but really needs additional validation and more flexibility built in to be useful beyond that. My goal was to demonstrate the power of the OCI Certificates service when tied to tools like the ACME client. Can you think of any other use cases, processes, plugins, etc. that would be worth exploring with OCI and certificate management?