{"id":15013938,"url":"https://github.com/voxpupuli/puppet-letsencrypt","last_synced_at":"2026-04-04T12:57:51.723Z","repository":{"id":38049778,"uuid":"47354137","full_name":"voxpupuli/puppet-letsencrypt","owner":"voxpupuli","description":"A Puppet module to install the Letsencrypt client and request certificates.","archived":false,"fork":false,"pushed_at":"2026-03-27T19:01:46.000Z","size":823,"stargazers_count":90,"open_issues_count":17,"forks_count":139,"subscribers_count":48,"default_branch":"master","last_synced_at":"2026-04-04T12:57:43.813Z","etag":null,"topics":["bsd-puppet-module","centos-puppet-module","debian-puppet-module","fedora-puppet-module","freebsd-puppet-module","hacktoberfest","linux-puppet-module","openbsd-puppet-module","puppet","redhat-puppet-module","ubuntu-puppet-module"],"latest_commit_sha":null,"homepage":"https://forge.puppet.com/puppet/letsencrypt","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/voxpupuli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"open_collective":"vox-pupuli","github":"voxpupuli"}},"created_at":"2015-12-03T19:12:34.000Z","updated_at":"2026-03-27T19:01:50.000Z","dependencies_parsed_at":"2023-02-10T03:45:36.685Z","dependency_job_id":"28ba0eab-a18c-479f-a059-65be57785db2","html_url":"https://github.com/voxpupuli/puppet-letsencrypt","commit_stats":{"total_commits":419,"total_committers":85,"mean_commits":4.929411764705883,"dds":0.6897374701670644,"last_synced_commit":"779531bd1dbc39412a3b7cf5d12fd3e4c0352a5e"},"previous_names":["danzilio/puppet-letsencrypt"],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/voxpupuli/puppet-letsencrypt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-letsencrypt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-letsencrypt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-letsencrypt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-letsencrypt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voxpupuli","download_url":"https://codeload.github.com/voxpupuli/puppet-letsencrypt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-letsencrypt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31400460,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bsd-puppet-module","centos-puppet-module","debian-puppet-module","fedora-puppet-module","freebsd-puppet-module","hacktoberfest","linux-puppet-module","openbsd-puppet-module","puppet","redhat-puppet-module","ubuntu-puppet-module"],"created_at":"2024-09-24T19:44:58.574Z","updated_at":"2026-04-04T12:57:51.718Z","avatar_url":"https://github.com/voxpupuli.png","language":"Ruby","funding_links":["https://opencollective.com/vox-pupuli","https://github.com/sponsors/voxpupuli"],"categories":[],"sub_categories":[],"readme":"# Let's Encrypt\n\n[![Build Status](https://github.com/voxpupuli/puppet-letsencrypt/actions/workflows/ci.yml/badge.svg)](https://github.com/voxpupuli/puppet-letsencrypt/actions/workflows/ci.yml)\n[![Puppet Forge](https://img.shields.io/puppetforge/v/puppet/letsencrypt.svg)](https://forge.puppetlabs.com/puppet/letsencrypt)\n[![Puppet Forge - downloads](https://img.shields.io/puppetforge/dt/puppet/letsencrypt.svg)](https://forge.puppetlabs.com/puppet/letsencrypt)\n[![Puppet Forge - endorsement](https://img.shields.io/puppetforge/e/puppet/letsencrypt.svg)](https://forge.puppetlabs.com/puppet/letsencrypt)\n[![Puppet Forge - scores](https://img.shields.io/puppetforge/f/puppet/letsencrypt.svg)](https://forge.puppetlabs.com/puppet/letsencrypt)\n[![Documentation Status](http://img.shields.io/badge/docs-puppet--strings-ff69b4.svg?style=flat)](http://voxpupuli.github.io/puppet-letsencrypt)\n\nThis module installs the Let's Encrypt client (certbot) and allows you to request certificates.\n\n## Support\n\nThis module is currently only written to work on Debian and RedHat based\noperating systems, although it may work on others. The supported Puppet\nversions are defined in the [metadata.json](metadata.json).\n\nThe [python3-certbot-dns-linode](https://tracker.debian.org/pkg/python-certbot-dns-linode) package does not exist for Debian 13, so `letsencrypt::plugin::dns_linode` will not work on Debian 13 unless you provide your own package.\n\n## Dependencies\n\nOn EL (Red Hat, CentOS etc.) systems, the EPEL repository needs to be enabled\nfor the Let's Encrypt client package.\n\nThe module can integrate with [puppet/epel](https://forge.puppetlabs.com/puppet/epel)\nto set up the repo by setting the `configure_epel` parameter to `true` (the default for RedHat) and\ninstalling the module.\n\n## Usage\n\n### Setting up the Let's Encrypt client\n\nTo install the Let's Encrypt client with the default configuration settings you\nmust provide your email address to register with the Let's Encrypt servers:\n\n```puppet\nclass { 'letsencrypt':\n  email =\u003e 'foo@example.com',\n}\n```\n\nYou can enforce upgrade of package to the latest available version (in your repositories):\n\n```puppet\nclass { 'letsencrypt':\n  email          =\u003e 'foo@example.com',\n  package_ensure =\u003e 'latest',\n}\n```\n\nIf using EL7 without EPEL-preconfigured, add `configure_epel`:\n\n```puppet\nclass { 'letsencrypt':\n  configure_epel =\u003e true,\n  email          =\u003e 'foo@example.com',\n}\n```\n\n(If you manage epel some other way, disable it with `configure_epel =\u003e false`.)\n\nThis will install the Let's Encrypt client and its dependencies, agree to the\nTerms of Service, initialize the client, and install a configuration file for\nthe client.\n\nAlternatively, you can specify your email address in the $config hash:\n\n```puppet\nclass { 'letsencrypt':\n  config =\u003e {\n    email  =\u003e 'foo@example.com',\n    server =\u003e 'https://acme-v01.api.letsencrypt.org/directory',\n  }\n}\n```\n\nDuring testing, you probably want to direct to the staging server instead with\n`server =\u003e 'https://acme-staging-v02.api.letsencrypt.org/directory'`\n\nIf you don't wish to provide your email address, you can set the\n`unsafe_registration` parameter to `true` (this is not recommended):\n\n```puppet\nclass { 'letsencrypt':\n  unsafe_registration =\u003e true,\n}\n```\n\nTo request a wildcard certificate, you must use the ACME v2 endpoint and use\na DNS-01 challenge. See\nhttps://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578\n\n```puppet\nclass { 'letsencrypt':\n  config =\u003e {\n    email  =\u003e 'foo@example.com',\n    server =\u003e 'https://acme-v02.api.letsencrypt.org/directory',\n  }\n}\n```\n\n### Issuing certificates\n\nCreate `letsencrypt::certonly` defines. See the `letsencrypt::certonly` examples in the REFERENCE.md for more details.\n\n\n### Renewing certificates\n\nThere are two ways to automatically renew certificates with cron using this module.\n\n#### cron using certbot renew\n\nAll installed certificates will be renewed using `certbot renew` using their\noriginal settings, including any not managed by Puppet.\n\n* `renew_cron_ensure` manages the cron resource. Set to `present` to enable. Default: `absent`\n* `renew_cron_minute` sets minute(s) to run the cron job. Default: Seeded random minute\n* `renew_cron_hour` sets hour(s) to run the cron job. Default: Seeded random hour\n* `renew_cron_monthday` sets month day(s) to run the cron job. Default: Every day\n\n```puppet\nclass { 'letsencrypt':\n  config =\u003e {\n    email  =\u003e 'foo@example.com',\n    server =\u003e 'https://acme-v01.api.letsencrypt.org/directory',\n  },\n  renew_cron_ensure =\u003e 'present',\n}\n```\n\nWith Hiera, at 6 AM (roughly) every other day:\n\n```yaml\n---\nletsencrypt::renew_cron_ensure: 'present'\nletsencrypt::renew_cron_minute: 0\nletsencrypt::renew_cron_hour: 6\nletsencrypt::renew_cron_monthday: '1-31/2'\n```\n\n#### cron using certbot certonly\n\nOnly specific certificates will be renewed using `certbot certonly`.\n\n* `manage_cron` can be used to automatically renew the certificate\n* `cron_success_command` can be used to run a shell command on a successful renewal\n* `cron_before_command` can be used to run a shell command before a renewal\n* `cron_monthday` can be used to specify one or multiple days of the month to run the cron job (defaults to every day)\n* `cron_hour` can be used to specify hour(s) to run the cron job (defaults to a seeded random hour)\n* `cron_minute` can be used to specify minute(s) to run the cron job (defaults to a seeded random minute)\n* `cron_output` can be used to disable output (and resulting emails) generated by the cron command\n\n```puppet\nletsencrypt::certonly { 'foo':\n  domains              =\u003e ['foo.example.com', 'bar.example.com'],\n  manage_cron          =\u003e true,\n  cron_hour            =\u003e [0,12],\n  cron_minute          =\u003e '30',\n  cron_before_command  =\u003e 'service nginx stop',\n  cron_success_command =\u003e '/bin/systemctl reload nginx.service',\n  cron_output          =\u003e 'suppress',\n}\n```\n\n#### Deprovisioning\n\nIf a domain needs to be removed for any reason this can be done by setting\n`ensure` to 'absent', this will remove the certificates for this domain from\nthe server. If `manage_cron` is set to true, the certificate renewal cronjob\nand shell scripts for the domain will also be removed.\n\n```puppet\nletsencrypt::certonly { 'foo':\n  ensure      =\u003e 'absent',\n  domains     =\u003e ['foo.example.com', 'bar.example.com'],\n  manage_cron =\u003e true,\n}\n```\n\n## Hooks\n\nCertbot supports hooks since certbot v0.5.0, however this module uses the newer\n`--deploy-hook` replacing the deprecated `--renew-hook`. Because of this the\nminimum version you will need to manage hooks with this module is v0.17.0.\n\nAll hook command parameters support both string and array.\n\n**Note on certbot hook behavior:** Hooks created by `letsencrypt::certonly` will be\nconfigured in the renewal config file of the certificate by certbot (stored in\nCONFIG_DIR/renewal/), which means all hooks created this way are used when running\n`certbot renew` without hook arguments. This allows you to easily create individual\nhooks for each certificate with just one cron job for renewal. HOWEVER, when running\n`certbot renew` with any of the hook arguments (setting any of the\n`letsencrypt::renew_*_hook_commands` parameters), hooks of the corresponding\ntypes in all renewal configs will be ignored by certbot. It's recommended to keep\nthese two ways of using hooks mutually exclusive to avoid confusion. Cron jobs\ncreated by `letsencrypt::certonly` are unaffected as they renew certificates\ndirectly using `certbot certonly`.\n\n### certbot certonly\n\nHooks created with `letsencrypt::certonly` will behave the following way:\n\n* `pre` hooks will be run before each certificate is attempted issued or renewed,\neven if the action fails.\n* `post` hooks will be run after each certificate is attempted issued or renewed,\neven if the action fails.\n* `deploy` hooks will be run after successfully issuing or renewing each certificate.\nIt will not be run if no action is taken or if the action fails.\n\n```puppet\nletsencrypt::certonly { 'foo':\n  domains               =\u003e ['foo.example.com', 'bar.example.com'],\n  pre_hook_commands     =\u003e ['...'],\n  post_hook_commands    =\u003e ['...'],\n  deploy_hook_commands  =\u003e ['...'],\n}\n```\n\n### certbot renew\n\nHooks passed to `certbot renew` will behave the following way:\n\n* `pre` hook will be run once total before any certificates are attempted issued\nor renewed. It will not be run if no actions are taken. Overrides all pre hooks\ncreated by `letsencrypt::certonly`.\n* `post` hook will be run once total after all certificates are issued or renewed.\nIt will not be run if no actions are taken. Overrides all post hooks created by\n`letsencrypt::certonly`.\n* `deploy` hook will be run once for each successfully issued or renewed certificate.\nIt will not be run otherwise. Overrides all deploy hooks created by\n`letsencrypt::certonly`.\n\n```puppet\nclass { 'letsencrypt':\n  config =\u003e {\n    email  =\u003e 'foo@example.com',\n    server =\u003e 'https://acme-v01.api.letsencrypt.org/directory',\n  },\n  renew_pre_hook_commands: [...],\n  renew_post_hook_commands: [...],\n  renew_deploy_hook_commands: [...],\n}\n```\n\nWith Hiera:\n\n```yaml\n---\nletsencrypt::renew_pre_hook_commands:\n  - '...'\nletsencrypt::renew_post_hook_commands:\n  - '...'\nletsencrypt::renew_deploy_hook_commands:\n  - '...'\n```\n\n## Facts\n\n* [certbot_version](#fact-certbotversion)\n* [letsencrypt_directory](#fact-letsencryptdirectory)\n\n### Fact: certbot_version\n\nA fact that contains the current version of certbot installed on your operating system/distribution.\n\n### Fact: letsencrypt_directory\n\nFacts about your live certificates are available through facter. You can query the list of live certificates from puppet using `$facts['letsencrypt_directory']` in your puppet code, hiera data or from the command line.\n\n```\nfacter -p letsencrypt_directory\n{\n  legacyfiles.ijc.org =\u003e \"/etc/letsencrypt/live/legacyfiles.ijc.org\",\n  static.ijc.org =\u003e \"/etc/letsencrypt/live/static.ijc.org\",\n  ijc.org =\u003e \"/etc/letsencrypt/live/ijc.org\",\n  new.ijc.org =\u003e \"/etc/letsencrypt/live/new.ijc.org\",\n  www.ijc.org =\u003e \"/etc/letsencrypt/live/ijc.org\",\n  training.ijc.org =\u003e \"/etc/letsencrypt/live/training.ijc.org\"\n}\n```\n\n## Puppet Functions\n\nThis module profiles a custom puppet function `letsencrypt::letsencrypt_lookup` which allows you to load information about your certificates into puppet.\nThis returns the same information as in the facts but for a particular domain. It accepts a single argument for your domain or wildcard domain.\n\n## Development\n\n1. Fork it\n2. Create a feature branch\n3. Write a failing test\n4. Write the code to make that test pass\n5. Refactor the code\n6. Submit a pull request\n\nWe politely request (demand) tests for all new features. Pull requests that contain new features without a test will not be considered. If you need help, just ask!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpupuli%2Fpuppet-letsencrypt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoxpupuli%2Fpuppet-letsencrypt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpupuli%2Fpuppet-letsencrypt/lists"}